On Fri, Mar 30, 2018 at 1:08 AM, Chris Angelico <ros...@gmail.com> wrote: > On Thu, Mar 29, 2018 at 11:28 PM, Steven D'Aprano <st...@pearwood.info> wrote: >> On Wed, Mar 28, 2018 at 06:27:19PM +0300, Serhiy Storchaka wrote: >> >>> The optimizer already changes >>> semantic. Non-optimized "if a and True:" would call bool(a) twice, but >>> optimized code calls it only once. >> >> I don't understand this. Why would bool(a) be called twice, and when did >> this change? Surely calling it twice would be a bug. >> >> I just tried the oldest Python 3 I have on this computer, 3.2, and bool >> is only called once. > > Technically not bool() itself, but the equivalent. Here's some similar code:
Wow, I'm good. Premature send much? Nice going, Chris. Let's try that again. Here's some similar code: >>> def f(a): ... if a and x: ... print("Yep") ... >>> class Bool: ... def __bool__(self): ... print("True?") ... return True ... >>> x = 1 >>> f(Bool()) True? Yep This is, however, boolifying a, then boolifying x separately. To bool a twice, you'd need to write this instead: >>> def f(a): ... if a or False: ... print("Yep") ... In its optimized form, this still only boolifies a once. But we can defeat the optimization: >>> def f(a): ... cond = a or False ... if cond: ... print("Yep") ... >>> f(Bool()) True? True? Yep The "or False" part implies a booleanness check on its left operand, and the 'if' statement performs a boolean truthiness check on its result. That means two calls to __bool__ in the unoptimized form. But it gets optimized, on the assumption that __bool__ is a pure function. The version assigning to a temporary variable does one check before assigning, and then another check in the 'if'; the same thing without the temporary skips the second check, and just goes ahead and enters the body of the 'if'. Technically that's a semantic change. But I doubt it'll hurt anyone. ChrisA _______________________________________________ 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