@@ -984,6 +984,46 @@ Furthermore, defining the short-circuiting behavior that way would have
984984been a deviation from the already established behavior in
985985languages like JS [#js_short_circuiting ]_ and C# [#csharp ]_.
986986
987+ Change ``primary `` rule to be right-recursive
988+ ---------------------------------------------
989+
990+ The ``primary `` grammar rule as it is defined [#py_grammar ]_ is
991+ left-recursive. This can make it difficult to reason about especially
992+ with regards to the `Short-circuiting `_ and `Grouping `_ behavior.
993+
994+ It was therefore proposed to make the ``None ``-aware access operators
995+ part of the ``primary `` rule right-recursive instead. The expression
996+ ``a.b?.c[0].func() `` would then roughly be parsed as:
997+
998+ .. code-block :: python
999+
1000+ NoneAwareAttribute(
1001+ base = Attribute(
1002+ expr = Name(identifier = " a" ),
1003+ identifier = " b"
1004+ )
1005+ tail = [
1006+ AttributeTail(identifier = " c" ),
1007+ SubscriptTail(slice = Constant(value = 0 )),
1008+ AttributeTail(identifier = " func" )
1009+ CallTail(args = [], keyword = [])
1010+ ]
1011+ )
1012+
1013+ While this approach would clearly define which parts of an expression
1014+ would be short-circuited, it has several drawbacks. To implement it at
1015+ least three additional AST nodes have to be added ``AttributeTail ``,
1016+ ``SubscriptTail `` and ``CallTail ``. As these are right-recursive now,
1017+ reusing code from the ``Attribute ``, ``Subscript `` and ``Call `` nodes
1018+ might prove difficult. Not to mention that the ``NoneAware* `` nodes
1019+ would contain parts that are both left- and right-recursive which
1020+ would be confusing.
1021+
1022+ In comparison the proposed `Grammar changes `_ are intentional kept to
1023+ a minimum. The ``None ``-aware access operators should behave more or
1024+ less like a drop-in replacement for ``. `` and ``[ ] ``, only with the
1025+ behavior outline in this PEP.
1026+
9871027
9881028Common objections
9891029=================
@@ -1069,6 +1109,38 @@ a match statement or data traversal libraries from PyPI.
10691109See the `Exception-aware operators `_ section for more details why
10701110this was rejected.
10711111
1112+ Short circuiting is difficult to understand
1113+ -------------------------------------------
1114+
1115+ Some have pointed the `Short-circuiting `_ behavior might be difficult
1116+ to understand and suggested to remove it in favor of a simplified
1117+ proposal.
1118+
1119+ It is true that using short-circuiting that way is new to Python and
1120+ as such unknown. That closest analogs would be boolean expressions like
1121+ ``a or b ``, ``a and b `` which do also short-circuit the expression if
1122+ the first value is truthy or falsy respectively. However, while
1123+ the details are complex, the behavior itself is rather intuitive.
1124+ To understand it, it is often enough to know that once a subexpression
1125+ for an ``optional `` value evaluates to ``None ``, the result will be
1126+ ``None `` as well. Any subsequent attribute access, subscript or call
1127+ will be skipped. In the example below, if ``a.b `` is ``None ``, so will
1128+ be ``a.b?.c ``:
1129+
1130+ ::
1131+
1132+ a.b?.c
1133+ ^^^
1134+
1135+ On a technical level, removing short-circuiting would make it difficult
1136+ to detect if ``not-optional `` attributes suddenly started to return
1137+ ``None `` as well. See `Remove short-circuiting `_ in the rejected ideas
1138+ section for more details on that.
1139+
1140+ Lastly, the short-circuiting behavior as proposed is identical to that
1141+ of other languages like TS [#ts ]_, JS [#js_short_circuiting ]_ and
1142+ C# [#csharp ]_.
1143+
10721144Just use ...
10731145------------
10741146
@@ -1233,6 +1305,8 @@ Footnotes
12331305 (https://pypi.org/project/nonesafe/)
12341306 .. [#pymaybe ] PyPI: pymaybe
12351307 (https://pypi.org/project/pymaybe/)
1308+ .. [#py_grammar ] Python documentation: Full Grammar specification
1309+ (https://docs.python.org/3/reference/grammar.html)
12361310
12371311
12381312 Copyright
0 commit comments