[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Python-Dev] Subtle difference between f-strings and str.format()

On 30 March 2018 at 21:16, Nathaniel Smith <njs at pobox.com> wrote:
> On Fri, Mar 30, 2018 at 3:29 AM, Serhiy Storchaka <storchaka at gmail.com> wrote:
>> 29.03.18 18:06, Terry Reedy ????:
>>> On 3/28/2018 11:27 AM, 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.
>>> Perhaps Ref 3.3.1 object.__bool__ entry, after " should return False or
>>> True.", should say something like "Should not have side-effects, as
>>> redundant bool calls may be optimized away (bool(bool(ob)) should have the
>>> same result as bool(ob))."
>> Do you meant that it should be idempotent operation? Because bool(bool(ob))
>> always have the same result as bool(ob)) if bool(ob) returns True or False.
> 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)
    >>> bool(toggle)
    >>> bool(toggle)
    >>> bool(toggle) and bool(toggle)
    >>> toggle and toggle
    <__main__.FlipFlop object at 0x7f35293604e0>
    >>> bool(toggle and toggle)

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.


Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia