PEP 653: Fix example. Use get(key, sentinel) instead of __getitem__(key) for mappings. (#1902)

This commit is contained in:
Mark Shannon 2021-03-30 23:30:43 +01:00 committed by GitHub
parent 0a0e7a3045
commit c029c02e36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 21 additions and 14 deletions

View File

@ -53,7 +53,7 @@ By allowing classes to choose which kinds of pattern they match, other classes c
For example, using ``sympy``, we might want to write::
# a*a == a**2
case Mul(args=[a, b]) if a == b:
case Mul(args=[Symbol(a), Symbol(b)]) if a == b:
return Pow(a, 2)
Which requires the sympy class ``Symbol`` to "self" match.
@ -273,14 +273,16 @@ A pattern not including a double-star pattern::
translates to::
$sentinel = object()
$kind = type($value).__match_container__
if $kind & MATCH_MAPPING == 0:
FAIL
if not $value.keys() >= $KEYWORD_PATTERNS.keys():
FAIL
# $KEYWORD_PATTERNS is a meta-variable mapping names to variables.
for $KEYWORD in $KEYWORD_PATTERNS:
$KEYWORD_PATTERNS[$KEYWORD] = $value[QUOTE($KEYWORD)]
$tmp = $value.get(QUOTE($KEYWORD), $sentinel)
if $tmp is $sentinel:
FAIL
$KEYWORD_PATTERNS[$KEYWORD] = $tmp
Example: [4]_
@ -293,10 +295,10 @@ translates to::
$kind = type($value).__match_container__
if $kind & MATCH_MAPPING == 0:
FAIL
if not $value.keys() >= $KEYWORD_PATTERNS.keys():
FAIL:
# $KEYWORD_PATTERNS is a meta-variable mapping names to variables.
$tmp = dict($value)
if not $tmp.keys() >= $KEYWORD_PATTERNS.keys():
FAIL:
for $KEYWORD in $KEYWORD_PATTERNS:
$KEYWORD_PATTERNS[$KEYWORD] = $tmp.pop(QUOTE($KEYWORD))
$DOUBLE_STARRED_PATTERN = $tmp
@ -502,15 +504,14 @@ on the naive implementation.
When performing matching, implementations are allowed
to treat the following functions and methods as pure:
For any class supporting ``MATCH_SEQUENCE`` or ``MATCH_MAPPING``::
For any class supporting ``MATCH_SEQUENCE``::
* ``cls.__len__()``
* ``cls.__getitem__()``
For any class supporting ``MATCH_MAPPING``::
* ``cls.keys()``
* ``cls.__contains__()``
* ``cls.get()`` (Two argument form only)
Implementations are allowed to make the following assumptions:
@ -519,6 +520,8 @@ Implementations are allowed to make the following assumptions:
* Reading any of ``__match_container__``, ``__match_class__`` or ``__match_args__`` is a pure operation, and may be cached.
* Sequences, that is any class for which ``__match_container__&MATCH_SEQUENCE`` is not zero, are not modified by iteration, subscripting or calls to ``len()``.
Consequently, those operations can be freely substituted for each other where they would be equivalent when applied to an immutable sequence.
* Mappings, that is any class for which ``__match_container__&MATCH_MAPPING`` is not zero, will not capture the second argument of the ``get()`` method.
So, the ``$sentinel`` value may be freely re-used.
In fact, implementations are encouraged to make these assumptions, as it is likely to result in signficantly better performance.
@ -779,10 +782,14 @@ translates to::
$kind = type($value).__match_container__
if $kind & MATCH_MAPPING == 0:
FAIL
if $value.keys() != {"x", "y"}:
$tmp = $value.get("x", $sentinel)
if $tmp is $sentinel:
FAIL
x = $value["x"]
y = $value["y"]
x = $tmp
$tmp = $value.get("y", $sentinel)
if $tmp is $sentinel:
FAIL
y = $tmp
if not x > 2:
FAIL
@ -797,9 +804,9 @@ translates to::
$kind = type($value).__match_container__
if $kind & MATCH_MAPPING == 0:
FAIL
if not $value.keys() >= {"x", "y"}:
FAIL
$tmp = dict($value)
if not $tmp.keys() >= {"x", "y"}:
FAIL
x = $tmp.pop("x")
y = $tmp.pop("y")
z = $tmp