Updates to PEP 505 (#697)
This commit is contained in:
parent
33877f7ac3
commit
e89685036f
|
@ -3,7 +3,7 @@ Title: None-aware operators
|
|||
Version: $Revision$
|
||||
Last-Modified: $Date$
|
||||
Author: Mark E. Haase <mehaase@gmail.com>, Steve Dower <steve.dower@python.org>
|
||||
Status: Deferred
|
||||
Status: Draft
|
||||
Type: Standards Track
|
||||
Content-Type: text/x-rst
|
||||
Created: 18-Sep-2015
|
||||
|
@ -60,18 +60,22 @@ Grammar changes
|
|||
|
||||
The following rules of the Python grammar are updated to read::
|
||||
|
||||
power: coalesce_expr ['**' factor]
|
||||
coalesce_expr: atom_expr ['??' atom_expr]
|
||||
atom_expr: ['await'] atom trailer*
|
||||
trailer: '(' [arglist] ')' |
|
||||
'[' subscriptlist ']' |
|
||||
'?[' subscriptlist ']' |
|
||||
'.' NAME |
|
||||
'?.' NAME
|
||||
augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' |
|
||||
'<<=' | '>>=' | '**=' | '//=' | '??=')
|
||||
term: coalesce (('*'|'@'|'/'|'%'|'//') coalesce)*
|
||||
coalesce: factor ('??' factor)*
|
||||
|
||||
Inserting the ``coalesce_expr`` rule in this location ensures that
|
||||
expressions resulting in ``None`` are natuarlly coalesced before they are used
|
||||
in operations that would typically raise ``TypeError``. Like ``and`` and ``or``
|
||||
# factor eventually resolved to atom_expr
|
||||
atom_expr: ['await'] atom trailer*
|
||||
trailer: ('(' [arglist] ')' |
|
||||
'[' subscriptlist ']' |
|
||||
'?[' subscriptlist ']' |
|
||||
'.' NAME |
|
||||
'?.' NAME)
|
||||
|
||||
Inserting the ``coalesce`` rule in this location ensures that expressions
|
||||
resulting in ``None`` are natuarlly coalesced before they are used in
|
||||
operations that would typically raise ``TypeError``. Like ``and`` and ``or``
|
||||
the right-hand expression is not evaluated until the left-hand side is
|
||||
determined to be ``None``. For example::
|
||||
|
||||
|
@ -79,16 +83,31 @@ determined to be ``None``. For example::
|
|||
def c(): return None
|
||||
def ex(): raise Exception()
|
||||
|
||||
(a ?? 2 ** b ?? 3) == (a ?? 2) ** (b ?? 3)
|
||||
(a ?? 2 ** b ?? 3) == a ?? (2 ** b) ?? 3
|
||||
(a * b ?? c // d) == (a * b) ?? (c // d)
|
||||
(a ?? True and b ?? False) == (a ?? True) and (b ?? False)
|
||||
(c() ?? c() ?? True) == True
|
||||
(True ?? ex()) == True
|
||||
(c ?? ex)() == c()
|
||||
|
||||
Augmented coalescing assignment only rebinds the name if its current value is
|
||||
``None``. If the target name already has a value, the right-hand side is not
|
||||
evaluated. For example::
|
||||
|
||||
a = None
|
||||
b = ''
|
||||
|
||||
a ??= 'value'
|
||||
b ??= undefined_name
|
||||
|
||||
assert a == 'value'
|
||||
assert b == ''
|
||||
|
||||
Adding new trailers for the other ``None``-aware operators ensures that they
|
||||
may be used in all valid locations for the existing equivalent operators.
|
||||
However, as the existing evaluation rules are not directly embedded in the
|
||||
grammar, we specify the required changes here.
|
||||
may be used in all valid locations for the existing equivalent operators,
|
||||
including as part of an assignment target (more details below). As the existing
|
||||
evaluation rules are not directly embedded in the grammar, we specify the
|
||||
required changes here.
|
||||
|
||||
Assume that the ``atom`` is always successfully evaluated. Each ``trailer`` is
|
||||
then evaluated from left to right, applying its own parameter (either its
|
||||
|
@ -143,6 +162,14 @@ transformation. For example, ``(a?.b ?? c).d?.e`` is evaluated as::
|
|||
if _v is not None:
|
||||
_v = _v.e
|
||||
|
||||
When used as an assignment target, the ``None``-aware operations may only be
|
||||
used in a "load" context. That is, ``a?.b = 1`` and ``a?[b] = 1`` will raise
|
||||
``SyntaxError``. Use earlier in the expression (``a?.b.c = 1``) is permitted,
|
||||
though unlikely to be useful unless combined with a coalescing operation::
|
||||
|
||||
(a?.b ?? d).c = 1
|
||||
|
||||
|
||||
Examples
|
||||
========
|
||||
|
Loading…
Reference in New Issue