
The fact of the matter is that a library like NumPy that creates its own versions of the things that are built-in to Python are going to run into these little corners of the language where things simply cannot be hooked into. Another example of this sort of thing is that 'and' and 'or' cannot be overridden, so you can't use them on arrays. It's just a fact of life that if you use NumPy you have to learn where these little gotchas are and avoid them. Maybe you could try to convince the CPython team that some issue is egregious enough to update the language somehow. But most of these things have been around for decades and the Python devs have more or less decided that it isn't worth the cost to do anything about them, but you could try. I honestly don't know why bool is unsubclassable, for instance, and it could be worth trying to change that for NumPy's sake (OTOH, it's highly unlikely that they would ever make it so that you could hook into 'is True'). On Fri, Jun 28, 2024 at 2:50 AM Stefano Miccoli via NumPy-Discussion <numpy-discussion@python.org> wrote:
On 27 Jun 2024, at 23:48, Aaron Meurer <asmeurer@gmail.com> wrote:
Apparently the reason this happens is that True, False, and None are compared using 'is' in structural pattern matching (see
Please let me stress that the ‘match/case’ snippet was only a concrete example of a situation in which, say ‘f(a)’ gives the correct result when ‘a’ is a ‘float’ instance and breaks down when ‘a’ is a ‘np.foat64’ instance. Now the fact that numpy floats are subclasses of python floats is quite a strong promise that this should never be the case… Realistically this can be solved in a couple of ways.
(i) Refactoring ‘f(a)’ so that it is aware of the numpy float quirks… not always possible, especially if ‘f(a)’ belongs to an external package.
(ii) Sanitizing numpy floats, lets say by ‘f(a.item())’ in the calling code.
(iii) Ensuring that scalar comparisons always return python bools and not ‘np.bool'
The issue with this proposal is that NumPy scalars are also supposed to be 0-D arrays. All the NumPy attributes like .shape are on them and they work in any context an ndarray would. For a NumPy operation to not return an ndarray would be far more surprising and problematic than np.bool_ not being a bool is.
(i) and (ii) are quite simple user-side workarouns, but sometimes the surprise factor is high, as in the given code snippet.
I would do any kind of user workaround as close to the "gotcha" as possible. In this case, the gotcha is that True doesn't compare with np.True_ in match statements, so you should either sanitize the expression right before calling match or use np.True_ | np.False_ in the case as I suggested before. Aaron Meurer
On the contrary (iii) is a radical solution on the library side, but I’m not sure if it’s worth implementing for a few edge cases. In fact ‘b is True’ is an anti-pattern in python, and probably the places in which this behaviour surfaces should be sparse.
Stefano _______________________________________________ NumPy-Discussion mailing list -- numpy-discussion@python.org To unsubscribe send an email to numpy-discussion-leave@python.org https://mail.python.org/mailman3/lists/numpy-discussion.python.org/ Member address: asmeurer@gmail.com