PEP 671: Rewrite the implementation section
This commit is contained in:
parent
26f8641a15
commit
5c9ce152a1
43
pep-0671.rst
43
pep-0671.rst
|
@ -146,39 +146,44 @@ Implementation details
|
|||
The following relates to the reference implementation, and is not necessarily
|
||||
part of the specification.
|
||||
|
||||
An **argument default**, rather than being an arbitrary value, is now a tuple
|
||||
of 1-2 values. The first value is descriptive text and may be ``None``; the
|
||||
compiler is free to put the source code for the default here, or None, on any
|
||||
basis. (The reference implementation omits them from early-bound defaults, and
|
||||
retains them for late-bound ones.) If there is a second value, it is an early
|
||||
bound default value and will be used as the function parameter when none is
|
||||
given.
|
||||
Argument defaults (positional or keyword) have both their values, as already
|
||||
retained, and an extra piece of information. For positional arguments, the
|
||||
extras are stored in a tuple in ``__defaults_extra__``, and for keyword-only,
|
||||
a dict in ``__kwdefaults_extra__``. If this attribute is ``None``, it is
|
||||
equivalent to having ``None`` for every argument default.
|
||||
|
||||
When there is no second value in the tuple, and the parameter is omitted, the
|
||||
For each parameter with a late-bound default, the special value ``Ellipsis``
|
||||
is stored as the value placeholder, and the corresponding extra information
|
||||
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.
|
||||
|
||||
Inspecting the function (eg ``help()``) will use the provided description
|
||||
where available, falling back on the repr of the value, or if there is none,
|
||||
report "=> <calculated>".
|
||||
|
||||
Costs
|
||||
-----
|
||||
|
||||
Every function default argument must now be wrapped in a tuple. This adds 56
|
||||
bytes (CPython 3.11, 64-bit Linux), but where the same value is used in many
|
||||
places (eg ``None``), this tuple can be shared.
|
||||
When no late-bound argument defaults are used, the following costs should be
|
||||
all that are incurred:
|
||||
|
||||
Mapping arguments to parameters incurs the cost of tuple unpacking.
|
||||
* Function objects require two additional pointers, which will be NULL
|
||||
* Compiling code and constructing functions have additional flag checks
|
||||
* Using ``Ellipsis`` as a default value will require run-time verification
|
||||
to see if late-bound defaults exist.
|
||||
|
||||
Constructing functions manually using FunctionType requires additional checks.
|
||||
These costs are expected to be minimal (on 64-bit Linux, this increases all
|
||||
function objects from 152 bytes to 168), with virtually no run-time cost when
|
||||
late-bound defaults are not used.
|
||||
|
||||
Backward incompatibility
|
||||
------------------------
|
||||
|
||||
Inspecting ``spam.__defaults__`` shows a tuple of tuples rather than a tuple
|
||||
of values. Similarly, ``spam.__kwdefaults__`` is a dict of tuples.
|
||||
Where late-bound defaults are not used, behaviour should be identical. Care
|
||||
should be taken if Ellipsis is found, as it may not represent itself, but
|
||||
beyond that, tools should see existing code unchanged.
|
||||
|
||||
References
|
||||
==========
|
||||
|
|
Loading…
Reference in New Issue