Updates to PEP 505 (#697)

This commit is contained in:
Steve Dower 2018-07-07 11:30:13 -07:00 committed by GitHub
parent 33877f7ac3
commit e89685036f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 43 additions and 16 deletions

View File

@ -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
========