Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unit checking for unfilled default argument #439

Open
zplizzi opened this issue Sep 29, 2016 · 4 comments
Open

Unit checking for unfilled default argument #439

zplizzi opened this issue Sep 29, 2016 · 4 comments

Comments

@zplizzi
Copy link

zplizzi commented Sep 29, 2016

I'd like to use the unit checking functionality in the following situation:

@ureg.check('[length]')
def test(a = 10 * ureg.meters):
    print(a)

test()

However, this fails with the error 'NoneType' object has no attribute 'dimensionality'.

Is there a way to handle such a situation elegantly? Ie, check the parameter if it is supplied, otherwise use the default argument.

@hgrecco
Copy link
Owner

hgrecco commented Nov 17, 2016

I agree. It would be nice to have support for optional values.

@onealj
Copy link
Contributor

onealj commented Nov 17, 2016

03332fa doesn't check default arguments of the wrapped function. It's a good idea to check this, but the most likely time this error would come up would be when the decorator type does not agree with the default argument in the function defined on the following line. For simple code, this error would be quick to spot. For complex code, this check would be critical.

@ureg.check('[time]')
def dfunc(a=10 * ureg.meters):
    return a

dfunc(10*ureg.seconds) should pass
dfunc(10*ureg.meters) should fail
dfunc() should fail

See onealj@c8cac87

I don't know if it will be possible to process the default parameters.
The decorator will need to inspect the wrapped function for the default arguments and figure out which are missing from the supplied invocation of the decorator-wrapped function. The order of default arguments is undefined, so unless ureg.check had matching positional and keyword arguments to check the dimension, it wouldn't be possible to implement this.

Consider def dfunc(a, b, c, d=1*ureg.kilograms, e=2*ureg.meters, f=3*ureg.seconds, *arg, **kwargs).
In CPython 2.7.6, dfunc.__defaults__ = (1*ureg.kilograms, 2*ureg.meters, 3*ureg.seconds)
In CPython 3.4.3, dfunc.__kwdefaults__ = {'d': 1*ureg.kilograms, 'f': 3*ureg.seconds, 'e': 2*ureg.meters}

@hgrecco
Copy link
Owner

hgrecco commented Nov 18, 2016

Won't this work: https://docs.python.org/3.6/library/inspect.html#inspect.Signature.bind ?

If not, at least we should raise an error on decoration like 'Default values are not supported'

@bilderbuchi
Copy link
Contributor

Maybe some clues could be found in the way functools.partial or functools.wraps work/are implemented? (Just a hunch)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants