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

[WIP] Addition of UnitOperationWarning and strict kwarg to UnitRegistry #166

Open
wants to merge 20 commits into
base: main
Choose a base branch
from

Conversation

mkhorton
Copy link

@mkhorton mkhorton commented Aug 5, 2020

As discussed in #165

This adds a UnitOperationWarning and a new strict kwarg to UnitRegistry, so that a custom UnitRegistry can be used that will gracefully fall-back to returning the output of an operation without units if a UnitOperationError would otherwise have been raised.

Currently have a demo working, however it's failing test_ufunc specifically, because it seems like the u0 or u1 in this case don't have a .registry or .dimensions attributes despite being a unyt_array. Suggestions here welcome, I'm not sure why this is the case.

Once it's working I can add some additional tests and check style.

@mkhorton
Copy link
Author

mkhorton commented Aug 5, 2020

The second aspect of this that would be nice to address:

As written, this PR will always issue a warning. Really, we only want the warning if units on one side of the operator are not specified and assumed dimensionless. If units are actually provided on both sides of the operator, it seems sensible to still raise the UnitOperationError and not the warning.

Unfortunately I can't see a way to figure out if the units are intended (i.e. a unyt_array that was intentionally created as dimensionless) or the units are dimensionless simply because they weren't specified and were assumed, i.e. as in:

# Nothing provided. Make dimensionless...

Edit: the only option that occurs to me here is a new unit, assumed_dimensionless, but that would be a major change, or an extra bit of metadata on Unit

@mkhorton
Copy link
Author

Would a unyt maintainer be willing to help me understand why test_ufunc is failing in this PR? Otherwise the functionality in this PR is fairly complete.

@ngoldbaum
Copy link
Member

Hey I’ll try to take a look at this soon. Sorry for the radio silence, it’s hard for me to focus on programming tasks these days...

@mkhorton
Copy link
Author

Many thanks @ngoldbaum, and no worries at all. Grateful for any feedback

@neutrinoceros
Copy link
Member

Hey @mkhorton, I can help you with this. Since there is a conflict and unyt's CI was migrated to a different system, I'd advise you rebase this branch if you still want to work on this PR. Sorry it's been a while !

@mkhorton
Copy link
Author

Hi @neutrinoceros, thanks for the offer to help! Would be very happy to see this functionality added.

I've resolved the current merge conflict and this branch is now up to date.

@neutrinoceros
Copy link
Member

Alright, seems like there are 3 failures, 2 of which are code-style-related. Can you run black + flake8 and fix the warnings you get from the latter ? Then all that should be left is the ufunc issue.

@neutrinoceros
Copy link
Member

Sorry the infrastructure isn't very well specified yet, it looks like you ran a different version of black that's conflicting with the latest. It'd be preferable to rebase and force push your branch now, to avoid tarnishing the history of files affected by cancelling changes. If you're not confortable with the process I can do it for you, just let me know.

@mkhorton
Copy link
Author

Ok, I rebased, by all means make changes directly to my fork if preferred. I don't mind installing a specific version of black if necessary too.

@neutrinoceros
Copy link
Member

We can always squash and rebase later to minimise disrupting your workflow. In the mean time I've pushed a single commit to fix the formatting issue. It is getting late in my timezone, I'll have a deeper look at the actual content tomorrow and hopefully we can move forward with this ufunc issue. Thank you so much for your patience.

Copy link
Member

@neutrinoceros neutrinoceros left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay I think I found the fix to your problem. I also have a couple suggestions about string formatting an other small nitpicks. I'd like to review this again after my suggestions are dealt with. Thanks again for your patience, really appreciate it.

unyt/array.py Outdated Show resolved Hide resolved
unyt/exceptions.py Outdated Show resolved Hide resolved
unyt/exceptions.py Outdated Show resolved Hide resolved
unyt/exceptions.py Outdated Show resolved Hide resolved
unyt/tests/test_unyt_array.py Outdated Show resolved Hide resolved
unyt/array.py Outdated Show resolved Hide resolved
unyt/unit_registry.py Outdated Show resolved Hide resolved
unyt/array.py Outdated Show resolved Hide resolved
Copy link
Member

@neutrinoceros neutrinoceros left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I must say I do not disapprove of the idea, but I have mixed feelings about the current implementation. I'm thinking that Python has a builtin mechanism to change warnings into errors (see https://docs.python.org/3/using/cmdline.html#cmdoption-w), so maybe it's worth considering an alternative implementation where we always raise warnings instead of errors for invalid operations, and so developers of projects that consume the unyt library can choose when they want to turn the -Werror flag on in their CI (note that pytest, ipython and other CI relevant interpreters have support for -W and pass it down to python). In my opinion this alternative is worth considering, but it needs further discussion.
@ngoldbaum @jzuhone @matthewturk please weigh in.

unyt/unit_registry.py Outdated Show resolved Hide resolved
@@ -166,6 +167,20 @@ def _iterable(obj):
return True


def _unit_operation_error_raise_or_warn(ufunc, u0, u1, func, *inputs):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am hesitant about how this function implements the proposed functionality. Specifically, it feels weird to replace a raise statement with a return statement (where this function is used).
Another comment is that the func argument is redundant (I think), since it can be obtained as func = ufunc.method.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I share this uneasiness but I'm not sure of a better solution. It seems clear to me that some users will want this to fail explicitly and raise, whereas others will just want the warning, so there has to be a conditional somewhere that switches between that behaviour?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To your second comment, makes sense, I'll remove the func argument.

neutrinoceros and others added 3 commits August 18, 2021 15:01
Make new argument keyword only

Co-authored-by: Clément Robert <[email protected]>
@neutrinoceros
Copy link
Member

neutrinoceros commented Aug 19, 2021

@mkhorton Looks like both of your latest commits broke some tests, can you revert back to the last working state ?
should be as simple as

git reset --hard HEAD~2
git push --force

@mkhorton
Copy link
Author

So I must say I do not disapprove of the idea, but I have mixed feelings about the current implementation. I'm thinking that Python has a builtin mechanism to change warnings into errors (see https://docs.python.org/3/using/cmdline.html#cmdoption-w), so maybe it's worth considering an alternative implementation where we always raise warnings instead of errors for invalid operations, and so developers of projects that consume the unyt library can choose when they want to turn the -Werror flag on in their CI (note that pytest, ipython and other CI relevant interpreters have support for -W and pass it down to python). In my opinion this alternative is worth considering, but it needs further discussion.
@ngoldbaum @jzuhone @matthewturk please weigh in.

Thanks @neutrinoceros, I was unaware of this functionality, I would also be in favour of this alternative since it's officially-supported by Python but will have to do some reading. Despite writing Python for quite a while, I feel like I'm still learning a lot :-)

I would also be grateful for any additional comments from other maintainers if anyone has thoughts on this functionality, especially if anyone has strong objections.

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