<div dir="ltr"><div class="gmail_quote"><div dir="ltr">[Steve Dower <<a href="mailto:steve.dower@python.org">steve.dower@python.org</a>>]</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">... </blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">* The "``None``-aware attribute access" operator ``?.`` evaluates the <br>
complete expression if the left hand side evaluates to a value that is not <br>
``None``<br></blockquote><div><br>And if the LHS does evaluate to `None` ...?  I'll assume the result is also `None` then.<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">...<br>
 From ``inspect.py``::<br>
<br>
     for base in object.__bases__:<br>
         for name in getattr(base, "__abstractmethods__", ()):<br>
             value = getattr(object, name, None)<br>
             if getattr(value, "__isabstractmethod__", False):<br>
                 return True<br>
<br>
After updating to use the ``?.`` operator (and deliberately not <br>
converting to use ``any()``)::<br>
<br>
     for base in object.__bases__:<br>
         for name in base?.__abstractmethods__ ?? ():<br>
             if object?.name?.__isabstractmethod__:<br>
                 return True<br></blockquote><div> <br>I got lost on the `for` here.  The part following `in`:</div><div><br></div><div>

<span style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">    for name in getattr(base, "__abstractmethods__", ()):</span>

<br></div><div><br></div><div>looks in `base` (regardless of whether `base` is `None`) for an attribute named <span style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">"_abstractmethods__"..  If such an attribute exists, the value of the attribute is returned (`None` or not).  Else an AttributeError is swallowed and `()` is returned.  It's hard to see how<br><br>

<span style="text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">         for name in base?.__abstractmethods__ ?? ():</span><br style="text-decoration-style:initial;text-decoration-color:initial">

<br>does the same.  If `base` itself is `None`, I guess it returns `()`, or if  `base` has an <span style="text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">"_abstractmethods__" attribute then the value of that attribute is returned - unless its value is None, in which case `()` is again returned.  But if `base` is not `None` and the attribute does not exist, doesn't this raise AttributeError?  The later "<span style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">Exception-aware operators" section seemed to explicitly reject the idea that `?.` and `?[]` would suppress AttributeError and/or TypeError.<br><br>In short, the original getattr() didn't care at all whether `base` was `None`, or whether the value of its "<span style="text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">__abstractmethods__" attribute was `None`, but cared a whole lot about whether that attribute exists.  I just can't see how the updated code matches that in any of those respects.<br><br>Ignoring that and pressing on, I suffer the same kind of confusions on the `if` part.  What am I missing?  For example, do these operators swallow exceptions after all?<br><br></span></span></span></span></div></div></div>