On Fri, Mar 30, 2018 at 4:41 AM, Nick Coghlan <ncogh...@gmail.com> wrote: > On 30 March 2018 at 21:16, Nathaniel Smith <n...@pobox.com> wrote: >> And bool(obj) does always return True or False; if you define a >> __bool__ method that returns something else then bool rejects it and >> raises TypeError. So bool(bool(obj)) is already indistinguishable from >> bool(obj). >> >> However, the naive implementation of 'if a and True:' doesn't call >> bool(bool(a)), it calls bool(a) twice, and this *is* distinguishable >> by user code, at least in principle. > > For example: > > >>> class FlipFlop: > ... _state = False > ... def __bool__(self): > ... result = self._state > ... self._state = not result > ... return result > ... > >>> toggle = FlipFlop() > >>> bool(toggle) > False > >>> bool(toggle) > True > >>> bool(toggle) > False > >>> bool(toggle) and bool(toggle) > False > >>> toggle and toggle > <__main__.FlipFlop object at 0x7f35293604e0> > >>> bool(toggle and toggle) > True > > So the general principle is that __bool__ implementations shouldn't do > anything that will change the result of the next call to __bool__, or > else weirdness is going to result.
I don't think this way of stating it is general enough. For example, you could have a nondeterministic implementation of __bool__ that doesn't itself carry any state (e.g. flipping the result with some probability), but the next call could nevertheless still return a different result. So I think Nathaniel's way of stating it is probably better: > If we want to change the language spec, I guess it would be with text > like: "if bool(obj) would be called twice in immediate succession, > with no other code in between, then the interpreter may assume that > both calls would return the same value and elide one of them". --Chris _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com