PEP 501: named field attrs, update keyword arg discussion

This commit is contained in:
Nick Coghlan 2015-08-23 07:34:57 +10:00
parent ea53115841
commit 150cb59734
1 changed files with 54 additions and 29 deletions

View File

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