PEP 671: Quick pass over wording and settle some things from discussion
This commit is contained in:
parent
745bfda492
commit
45cf9e5250
53
pep-0671.rst
53
pep-0671.rst
|
@ -80,29 +80,27 @@ implementations, it should be considered dubious::
|
|||
def spaminate(sausage=>eggs + 1, eggs=>sausage - 1): # Confusing, may fail
|
||||
def frob(n=>len(items), items=[]): # May fail, may succeed
|
||||
|
||||
Moreover, even if syntactically and semantically legal, this kind of construct
|
||||
is highly confusing to other programmers, and should be avoided.
|
||||
|
||||
|
||||
Choice of spelling
|
||||
------------------
|
||||
|
||||
Our chief syntax proposal is ``name=>expression`` -- our two syntax proposals
|
||||
... ahem. Amongst our potential syntaxes are::
|
||||
While this document specifies a single syntax ``name=>expression``, alternate
|
||||
spellings are similarly plausible. Open for consideration are the following:
|
||||
|
||||
# Preferred options: adorn the equals sign (approximate preference order)
|
||||
def bisect(a, hi=>len(a)):
|
||||
def bisect(a, hi=:len(a)):
|
||||
def bisect(a, hi:=len(a)):
|
||||
def bisect(a, hi?=len(a)):
|
||||
def bisect(a, hi!=len(a)):
|
||||
def bisect(a, hi=\len(a)):
|
||||
def bisect(a, hi=@len(a)):
|
||||
# Less preferred option: adorn the variable name
|
||||
|
||||
An alternative reference implementation is under consideration, which would
|
||||
use this syntax::
|
||||
|
||||
def bisect(a, @hi=len(a)):
|
||||
# Less preferred option: adorn the expression
|
||||
def bisect(a, hi=`len(a)`):
|
||||
|
||||
Since default arguments behave largely the same whether they're early or late
|
||||
bound, the preferred syntax is very similar to the existing early-bind syntax.
|
||||
The alternatives offer little advantage over the preferred one.
|
||||
bound, the syntax is deliberately similar to the existing early-bind syntax.
|
||||
|
||||
How to Teach This
|
||||
=================
|
||||
|
@ -117,6 +115,12 @@ bound arguments are broadly equivalent to code at the top of the function::
|
|||
def add_item(item, target=<OPTIONAL>):
|
||||
if target was omitted: target = []
|
||||
|
||||
A simple rule of thumb is: "target=expression" is evaluated when the function
|
||||
is defined, and "target=>expression" is evaluated when the function is called.
|
||||
Either way, if the argument is provided at call time, the default is ignored.
|
||||
While this does not completely explain all the subtleties, it is sufficient to
|
||||
cover the important distinction here (and the fact that they are similar).
|
||||
|
||||
|
||||
Interaction with other open PEPs
|
||||
================================
|
||||
|
@ -132,13 +136,15 @@ be defined by the function. Additionally, dedicated sentinel objects can be
|
|||
used as dictionary lookup keys, where PEP 671 does not apply.
|
||||
|
||||
|
||||
Open Issues
|
||||
===========
|
||||
Interaction with annotations
|
||||
============================
|
||||
|
||||
- Annotations go before the default, so in all syntax options, it must be
|
||||
unambiguous (both to the human and the parser) whether this is an annotation,
|
||||
a default, or both. The worst offender is the ``:=`` notation, as ``:int=``
|
||||
would be a valid annotation and early-bound default.
|
||||
Annotations go before the default, so in all syntax options, it must be
|
||||
unambiguous (both to the human and the parser) whether this is an annotation,
|
||||
a default, or both. The alternate syntax ``target:=expr`` runs the risk of
|
||||
being misinterpreted as ``target:int=expr`` with the annotation omitted in
|
||||
error, and may thus mask bugs. The preferred syntax ``target=>expr`` does not
|
||||
have this problem.
|
||||
|
||||
|
||||
Implementation details
|
||||
|
@ -159,10 +165,13 @@ needs to be queried. If it is ``None``, then the default is indeed the value
|
|||
``Ellipsis``; otherwise, it is a descriptive string and the true value is
|
||||
calculated as the function begins.
|
||||
|
||||
When a parameter with a late-bound default is omitted, the
|
||||
function will begin with the parameter unbound. The function begins by testing
|
||||
for each parameter with a late-bound default, and if unbound, evaluates the
|
||||
original expression.
|
||||
When a parameter with a late-bound default is omitted, the function will begin
|
||||
with the parameter unbound. The function begins by testing for each parameter
|
||||
with a late-bound default using a new opcode QUERY_FAST, and if unbound,
|
||||
evaluates the original expression. This opcode (available only for fast locals
|
||||
and not for other types of variable) pushes True onto the stack if the given
|
||||
local has a value, and False if not - meaning that it pushes False if LOAD_FAST
|
||||
would raise UnboundLocalError and True if it would succeed.
|
||||
|
||||
Out-of-order variable references are permitted as long as the referent has a
|
||||
value from an argument or early-bound default.
|
||||
|
|
Loading…
Reference in New Issue