Open conversy opened 2 years ago
after some investigations, I ended up with this example of how to best use Pint
with mypy
:
import pint
ureg = pint.UnitRegistry()
class Human:
height: pint.Quantity = 0 * ureg.centimeter # initialize to a preferred unit/dimensionality
def __init__(self, height: pint.Quantity = 0 * ureg.centimeter): # idem for default value
height.check('[length]') # check dimensionality
# assert(height.dimensionality == self.height.dimensionality) # check dimensionality variant
self.height = height.to(ureg.centimeter) # optional call to .to, keep the field as centimeters
h1 = Human(180 * ureg.centimeter) # mypy ok, assertions ok
h2 = Human(6 * ureg.feet) # mypy ok, assertions still ok
print(h2.height)
h3 = Human(180) # mypy error: not a pint.Quantity
h4 = Human(180 * ureg.second) # mypy ok, assertions error: cannot convert units
rationale:
mypy
cannot check more that a parameter is at least a pint.Quantity
, hence its use in the method signaturepint.Quantity.to
pint.Quantity.to
, as it will raise an error if the quantities are not compatible.I hope this is helpful, I may be completely wrong though...
import pint
ureg = pint.UnitRegistry()
# raise DimensionalityError if not compatible
def assert_compatible_with(a,b):
b.to(a.units)
class Human:
def __init__(self, height: pint.Quantity = 0 * ureg.cm): # default value in a preferred unit/dimensionality
height.check('[length]') # check dimensionality
assert_compatible_with(height, 0 * ureg.cm) # variant
self.height = height.to(ureg.centimeter) # optional call to .to, keep the field as centimeters
h1 = Human(180 * ureg.centimeter) # mypy ok, assertions ok
h2 = Human(6 * ureg.feet) # mypy ok, assertions still ok
h3 = Human(180) # mypy error: not a pint.Quantity
h4 = Human(180 * ureg.second) # mypy ok, assertions error: cannot convert units
In this version, I use an assert
that raises the corresponding exceptions with a useful message.
Is there such an assert in the lib? I could not find one... Mine is costly since it converts values, and we only want to check dimensionality...
any news on this? I'm playing around trying to make mypy happy with my pint'ed code that works at runtime, but fails in mypy
Hi,
following this issue and this PR on typing/annotation, I could not find a documentation or a tutorial that would explain how to use
pint
withmypy
or other Python checkers, together with the limitations.Would it be possible to discuss here a few examples of code and usage, before creating a doc entry PR for this topic? That would be very useful!
Best,
Stéphane
PS: I first asked a similar question in the PR discussion, but I figured it would be best to submit a documentation issue.