This question is spurred from the answers and discussions of this question. The following snippet shows the crux of the question:
>>> bool(NotImplemented)
True
The questions I have are the following:
- Why was it decided that the
bool
value ofNotImplemented
should beTrue
? It feels unpythonic. - Is there a good reason I am unaware of? The documentation seems to just say, "because it is".
- Are there any examples where this is used in a reasonable manner?
Reasoning behind why I believe it's unintuitive (please disregard the lack of best practice):
>>> class A:
... def something(self):
... return NotImplemented
...
>>> a = A()
>>> a.something()
NotImplemented
>>> if a.something():
... print("this is unintuitive")
...
this is unintuitive
It seems an odd behavior that something with such a negative connotation (lack of implementation) would be considered truthy.
Relevant text from:
NotImplemented
Special value which should be returned by the binary special methods (e.g.
__eq__()
,__lt__()
,__add__()
,__rsub__()
, etc.) to indicate that the operation is not implemented with respect to the other type; may be returned by the in-place binary special methods (e.g.__imul__()
,__iand__()
, etc.) for the same purpose. Its truth value is true.— From the Python Docs
Edit 1
To clarify my position, I feel that NotImplemented
being able to evaluate to a boolean is an anti-pattern by itself. I feel like an Exception makes more sense, but the prevailing idea is that the constant singleton was chosen for performance reasons when evaluating comparisons between different objects. I suppose I'm looking for convincing reasons as to why this is "the way" that was chosen.
True
is the default (bool(object())
isTrue
), and there isn't a compelling reason to change it. – RescriptNotImplemented
to not be truthy? – Dormant__eq__
onNone
is bad practice, but it just kind of made me wonder about whyNotImplemented
is truthy in the first place. – Blinkersif not a.something()
be any more intuitive than enteringif a.something()
? – Sixtyfourbool(NotImplented)
should raise an exception? numpy arrays do similar to avoid accidental ambiguity, but I'm not aware of any precedence for this in Python directly (and still not convinced on the use-case). – SixtyfourNotImplemented
should not exist and anywhere wereturn NotImplemented
we shouldraise NotImplementedError
or something similar. Unfortunately, that would be complex and difficult to achieve (while keeping compatibility). So that's where I went with making it falsy instead. Having it raise an exception might do the trick though...I'd need to think on it more. – BlinkersNotImplemented
didn't exist, how would__radd__
and all the other reflected operations in the datamodel work? They use this singleton to indicate "I don't support this operation, but the other operand might". – Sixtyfourraise NotImplementedError("We forgot to implement something, sorry")
or the like. – Adhamhbool(NotImplemented) == True
. Honestly, even if it was fasly, couldn't it still work as it is? Just rework some of the internal reflected operation logic inside the datamodel? – Blinkers