PEP 501: named field attrs, update keyword arg discussion
This commit is contained in:
parent
ea53115841
commit
150cb59734
83
pep-0501.txt
83
pep-0501.txt
|
@ -43,6 +43,7 @@ Some examples of the proposed syntax::
|
|||
myquery = sql$"SELECT $column FROM $table;"
|
||||
mycommand = sh$"cat $filename"
|
||||
mypage = html$"<html><body>${response.body}</body></html>"
|
||||
callable = defer$ "$x + $y"
|
||||
|
||||
Proposal
|
||||
========
|
||||
|
@ -101,11 +102,11 @@ It also has the effect of introducing yet another syntax for substitution
|
|||
expressions into Python, when we already have 3 (``str.format``,
|
||||
``bytes.__mod__`` and ``string.Template``)
|
||||
|
||||
This PEP proposes to handle the latter issue by always specifying an explicit
|
||||
interpolator for interpolation operations, and the former by adopting the
|
||||
This PEP proposes to handle the former issue by always specifying an explicit
|
||||
interpolator for interpolation operations, and the latter by adopting the
|
||||
``string.Template`` substitution syntax defined in PEP 292.
|
||||
|
||||
The interpolation syntax devised for PEP 292 is deliberately simple so that the
|
||||
The substitution syntax devised for PEP 292 is deliberately simple so that the
|
||||
template strings can be extracted into an i18n message catalog, and passed to
|
||||
translators who may not themselves be developers. For these use cases, it is
|
||||
important that the interpolation syntax be as simple as possible, as the
|
||||
|
@ -120,7 +121,7 @@ that flexibility to the ``${ref}`` construct in PEP 292, and allows translation
|
|||
tools the option of rejecting usage of that more advanced syntax at runtime,
|
||||
rather than categorically rejecting it at compile time. The proposed permitted
|
||||
expressions, conversion specifiers, and format specifiers inside ``${ref}`` are
|
||||
exactly as defined in PEP 498.
|
||||
exactly as defined for ``{ref}`` substituion in PEP 498.
|
||||
|
||||
The specific proposal in this PEP is also deliberately close in both syntax
|
||||
and semantics to the general purpose interpolation syntax introduced to
|
||||
|
@ -156,7 +157,7 @@ expression.
|
|||
|
||||
These components are then organised into a tuple of tuples, and passed to the
|
||||
``__interpolate__`` method of the interpolator identified by the given
|
||||
name::
|
||||
name along with the runtime values of any expressions to be interpolated::
|
||||
|
||||
DOTTED_NAME.__interpolate__(TEMPLATE_STRING,
|
||||
<parsed_fields>,
|
||||
|
@ -172,15 +173,29 @@ containing:
|
|||
* the substitution conversion specifier (as defined by str.format)
|
||||
* the substitution format specifier (as defined by str.format)
|
||||
|
||||
If a given substition field has no leading literal section, format specifier
|
||||
or conversion specifier, then the corresponding elements in the tuple are the
|
||||
empty string. If the final part of the string has no trailing substitution
|
||||
field, then the field number, format specifier
|
||||
and conversion specifier will all be ``None``.
|
||||
This field ordering is defined such that reading the parsed field tuples from
|
||||
left to right will have all the subcomponents displayed in the same order as
|
||||
they appear in the original template string.
|
||||
|
||||
The expression text is simply the text of each interpolated expression, as it
|
||||
For ease of access the sequence elements will be available as attributes in
|
||||
addition to being available by position:
|
||||
|
||||
* ``leading_text``
|
||||
* ``field_position``
|
||||
* ``expression``
|
||||
* ``conversion``
|
||||
* ``format``
|
||||
|
||||
The expression text is simply the text of the substitution expression, as it
|
||||
appeared in the original string, but without the leading and/or surrounding
|
||||
expression markers.
|
||||
expression markers. The conversion specifier and format specifier are separated
|
||||
from the substition expression by ``!`` and ``:`` as defined for ``str.format``.
|
||||
|
||||
If a given substition field has no leading literal section, coversion specifier
|
||||
or format specifier, then the corresponding elements in the tuple are the
|
||||
empty string. If the final part of the string has no trailing substitution
|
||||
field, then the field position, field expression, conversion specifier and
|
||||
format specifier will all be ``None``.
|
||||
|
||||
The substitution field values tuple is created by evaluating the interpolated
|
||||
expressions in the exact runtime context where the interpolation expression
|
||||
|
@ -360,9 +375,10 @@ would delegate interpolation calls to ``string.Template``::
|
|||
|
||||
And would could then be invoked as::
|
||||
|
||||
# _ = i18n at top of module or injected into the builtins module
|
||||
print(_$"This is a $translated $message")
|
||||
|
||||
Any actual implementation would need to address other issues (most notably
|
||||
Any actual i18n implementation would need to address other issues (most notably
|
||||
message catalog extraction), but this gives the general idea of what might be
|
||||
possible.
|
||||
|
||||
|
@ -406,6 +422,28 @@ Discussion
|
|||
Refer to PEP 498 for additional discussion, as several of the points there
|
||||
also apply to this PEP.
|
||||
|
||||
Using call syntax to support keyword-only parameters
|
||||
----------------------------------------------------
|
||||
|
||||
The logging examples raise the question of whether or not it may be desirable
|
||||
to allow interpolators to accept arbitrary keyword arguments, and allow folks
|
||||
to write things like::
|
||||
|
||||
logging.critical$"Error: $error; Details: $data"(exc_info=True)
|
||||
|
||||
in order to pass additional keyword only arguments to the interpolator.
|
||||
|
||||
With the current PEP, such code would attempt to call the result of the
|
||||
interpolation operation. If interpolation keyword support was added, then
|
||||
calling the result of an interpolation operation directly would require
|
||||
parentheses for disambiguation::
|
||||
|
||||
(defer$ "$x + $y")()
|
||||
|
||||
("defer" here would be an interpolator that compiled the supplied string as
|
||||
a piece of Python code with eagerly bound references to the containing
|
||||
namespace)
|
||||
|
||||
Determining relative precedence
|
||||
-------------------------------
|
||||
|
||||
|
@ -457,22 +495,9 @@ worth fixing it in for the customer interpolator API, since the tuple already
|
|||
has other differences (like including both the field position number *and* the
|
||||
text of the expression).
|
||||
|
||||
Using call syntax to support keyword-only parameters
|
||||
----------------------------------------------------
|
||||
|
||||
The logging examples could potentially be better written as::
|
||||
|
||||
!logging.debug("Event: $event; Details: $data")
|
||||
!logging.critical("Error: $error; Details: $data")
|
||||
|
||||
The key benefit this would provide is access to keyword arguments, so you
|
||||
could write:
|
||||
|
||||
!logging.critical("Error: $error; Details: $data", exc_info=True)
|
||||
|
||||
In this version, an interpolation expression would largely be syntactically
|
||||
equivalent to a normal function call, except that it would be restricted to
|
||||
accepting a single string literal as its sole position argument.
|
||||
This PEP also makes the parsed field attributes available by name, so it's
|
||||
possible to write interpolators without caring about the precise field order
|
||||
at all.
|
||||
|
||||
References
|
||||
==========
|
||||
|
|
Loading…
Reference in New Issue