pythonpython-decoratorspint

Unable to decorate a class method using Pint units


Here's a very simple example in an effort to decorate a class method using Pint,

from pint import UnitRegistry

ureg = UnitRegistry()
Q_ = ureg.Quantity

class Simple:
    def __init__(self):
    pass

@ureg.wraps('m/s', (None, 'm/s'), True)
def calculate(self, a, b):
    return a*b

if __name__ == "__main__":
    c = Simple().calculate(1, Q_(10, 'm/s'))
    print c

This code results in the below ValueError.

Traceback (most recent call last):
   c = Simple().calculate(1, Q_(10, 'm/s'))
   File "build/bdist.macosx-10.11-intel/egg/pint/registry_helpers.py",   line 167, in wrapper
   File "build/bdist.macosx-10.11-intel/egg/pint/registry_helpers.py", line 118, in _converter
   ValueError: A wrapped function using strict=True requires quantity for all arguments with not None units. (error found for m / s, 1)

It seems to me that the issue here may be with class instances being passed to the pint decorator. Would anyone have a solution for fixing this?


Solution

  • I think the error message is pretty clear. In strict mode all arguments have to be given as Quantity yet you only give the second argument as such.

    You either give the first argument as a Quantity too

    if __name__ == "__main__":
        c = Simple().calculate(Q_(1, 'm/s'), Q_(10, 'm/s'))
        print c
    

    or you disable strict mode, which I believe is what you are looking for.

        ...
        @ureg.wraps('m/s', (None, 'm/s'), False)
        def calculate(self, a, b):
            return a*b
    
    if __name__ == "__main__":
        c = Simple().calculate(1, Q_(10, 'm/s'))
        print c