Ethan Furman <et...@stoneleaf.us> added the comment:
Serhiy: ------ > First, it is impossible. nb_bool and PyObject_IsTrue() can return > only three value: 1 for true, 0 for false, and -1 for error. Huh. How is -1 interpreted? Does it become a TypeError? > It is not possible to represent NotImplemented without breaking all > extensions. > > Currently > > if not a: > b() > else: > c() > > is equivalent to > > if a: > c() > else: > b() > > If a is NotImplemented, what branch be executed in every case? Side-stepping to other __dunder__ methods for a moment: if, for example, both __add__ and __radd__ return NotImplemented then the interpreter will convert that into a TypeError. So my thinking is that when the interpreter gets the `NotImplemented` returned by either `if a` or by `if not a` that it would be converted to a `TypeError`, meaning none of the branches would be executed as an exception would be raised instead. > Second, it would not help. Because real-world examples are not always so > trivial as "return not self.__lt__(other)". It may be a part of more > complex expression, e.g.: > > return super().__eq__(other) and self.attr == other.attr I don't see the problem -- breaking it down: return super().__eq__(other) and self.attr == other.attr becomes return NotImplemented and ... and the `and` machinery sees it has a `NotImplemented` and raises a `TypeError`. The same would be true if the `__eq__` operation returned `NotImplemented`. So to make that work, `and` and `or` would have to check if one of the operands is `NotImplemented`. Are there others that would need to have that check? The reason I would prefer this solution is that if it could behave as I described above, the `TypeError` would point at the user's line of code as being the problem, and not inside the __dunder__: class NoAdd: # def __add__(self, other): return NotImplemented # def __radd__(self, other): # fake a NotImplemented TypeError from bool(NotImplemented) raise TypeError("cannot boolean NotImplemented") # what we should see, since the error is in the users' code --> NoAdd() + 7 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for +: 'NoAdd' and 'int' # what we will see -- a leaky implementation detail --> 7 + NoAdd() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 6, in __radd__ TypeError: cannot boolean NotImplemented ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue35712> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com