pint icon indicating copy to clipboard operation
pint copied to clipboard

TypeError when calling `to_base_units()` for temperature.

Open biagiodistefano opened this issue 11 months ago • 0 comments

Steps to reproduce

from decimal import Decimal
from pint import UnitRegistry

ureg = UnitRegistry()

qt = ureg.Quantity(Decimal(10.0), "°C")  # <Quantity(10, 'degree_Celsius')>
qt.ito_base_units()

Causes:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File ".venv/lib/python3.11/site-packages/pint/facets/plain/quantity.py", line 555, in to_base_units
    magnitude = self._convert_magnitude_not_inplace(other)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.11/site-packages/pint/facets/plain/quantity.py", line 462, in _convert_magnitude_not_inplace
    return self._REGISTRY.convert(self._magnitude, self._units, other)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.11/site-packages/pint/facets/plain/registry.py", line 961, in convert
    return self._convert(value, src, dst, inplace)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.11/site-packages/pint/facets/context/registry.py", line 403, in _convert
    return super()._convert(value, src, dst, inplace)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.11/site-packages/pint/facets/nonmultiplicative/registry.py", line 266, in _convert
    value = self._units[src_offset_unit].converter.to_reference(value, inplace)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.11/site-packages/pint/facets/nonmultiplicative/definitions.py", line 33, in to_reference
    value = value * self.scale + self.offset
            ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~
TypeError: unsupported operand type(s) for +: 'decimal.Decimal' and 'float'

Same with "°F".

Ideas

In ScaleConverter, scale: float, but the method to_reference() accepts value: Magnitude, and Magnitude = Union[Scalar, Array], Scalar: TypeAlias = Union[float, int, Decimal, Fraction].

My suggestion would be: instead of using self.offset for the operations in the methods, use a typecasted version of it that matches value's type.

If you find this okay, I will make a PR as soon as I have time.

For now the workaround is to just pass float instead of decimal when working with temperature units.

EDIT: ~scale~ -> offset

biagiodistefano avatar Mar 08 '24 10:03 biagiodistefano