Message363969
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 |
|
Date |
User |
Action |
Args |
2020-03-11 20:49:03 | ethan.furman | set | recipients:
+ ethan.furman, gvanrossum, terry.reedy, steven.daprano, serhiy.storchaka, josh.r, veky, xtreak |
2020-03-11 20:49:03 | ethan.furman | set | messageid: <1583959743.33.0.0233307253173.issue35712@roundup.psfhosted.org> |
2020-03-11 20:49:03 | ethan.furman | link | issue35712 messages |
2020-03-11 20:49:03 | ethan.furman | create | |
|