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

Should bool(Unit()) be False ? #405

Open
neutrinoceros opened this issue Apr 1, 2023 · 3 comments
Open

Should bool(Unit()) be False ? #405

neutrinoceros opened this issue Apr 1, 2023 · 3 comments

Comments

@neutrinoceros
Copy link
Member

  • unyt version: 2.9.5
  • Python version: any
  • Operating System: any

Description

Given how most builtin types implement "truthiness" (where 0 or empty objects evaluate to False), I'd expect bool(Unit()) to evaluate to False, though currently every unit, even empty ones, evaluate to True.

Such a change might be considered breaking (though it's probably very niche ?), so I wonder if there's any objections to changing this for unyt 3.0 ?

What I Did

from unyt import Unit
assert not Unit()
@neutrinoceros
Copy link
Member Author

neutrinoceros commented Apr 2, 2023

Just to give a little more context, I think this would allow to write more idiomatic code in situations where we need to grab some unit from a pair of arrays that might be pure ndarrays:

NULL_UNIT = Unit()
units = getattr(a, "units", NULL_UNIT) or getattr(b, "units", NULL_UNIT)

(currently b.units would never be evaluated in this code, because NULL_UNIT is truthy)

The following patch is sufficient to allow this:

diff --git a/unyt/unit_object.py b/unyt/unit_object.py
index 2b13e46..e55e891 100644
--- a/unyt/unit_object.py
+++ b/unyt/unit_object.py
@@ -513,6 +513,8 @@ class Unit:
     def __deepcopy__(self, memodict=None):
         return self.copy(deep=True)
 
+    def __bool__(self):
+        return self != NULL_UNIT
     #
     # End unit operations
     #

and I checked that it doesn't break any existing test

@ngoldbaum
Copy link
Member

Hmm, I'm not sure about this. Have you tried running the tests against yt with this change? On the one hand, since units have never been falsy, it's unlikely people have been using them in a situation where this change to sometimes being falsey would matter. On the other hand, it's a common enough thing to do and it might subtly impact the behavior of a complex expression. Unfortunately I don't think it's possible to deprecate this behavior so we can't shake it out in the wild either.

Just to be on the safe side, I would prefer to not do this. However if you can come up with a more compelling story than making some internal code in unyt a bit simpler than I might be persuaded.

Also wrt to the proposed implementation, I would also prefer to keep this logic in __ne__ and __eq__ if possible rather than adding a new dunder method implementation people might have to be aware of if they want to fully understand how unit equality works.

@neutrinoceros
Copy link
Member Author

Have you tried running the tests against yt with this change?

just did. No error in sight.

Just to be on the safe side, I would prefer to not do this. However if you can come up with a more compelling story than making some internal code in unyt a bit simpler then I might be persuaded.

Honestly, I don't have much of a case here. Feel free to close.

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

No branches or pull requests

2 participants