http://docs.python.org/2/library/string.html#template-strings ## Original Idea stdlib lacks the most popular basic variable extension syntax "{{ variable }}" that can be found in Django [1], Jinja2 [2] and other templating engines [3]. ## stdlib Analysis string.Template syntax is ancient (dates back to Python 2.4 from 9 years ago). I haven't seen a template like this for a long time. ## Scope of Enhancement st = 'Hello {{world}}.' world = 'is not enough' t = Template(string, style='brace') t.render(locals()) ## Links 1. https://docs.djangoproject.com/en/dev/topics/templates/#variables 2. http://jinja.pocoo.org/docs/templates/#variables 3. http://mustache.github.io/ ## Feature Creeping # Allow to override {{ }} symbols to make it more generic. # `foo.bar` attribute lookup for 2D (nested) structures. Questions is it has to be supported: `foo.bar` in Django does dictionary lookup first, then attribute lookup `foo.bar` in Jinja2 does attribute lookup first I am not sure which is better. I definitely don't want some method or property on a dict passed to render() method to hide dict value. -- anatoly t.
2013/11/28 anatoly techtonik <techtonik@gmail.com>:
## Scope of Enhancement
st = 'Hello {{world}}.' world = 'is not enough' t = Template(string, style='brace') t.render(locals())
I'm not sure that I understood correctly your proposition. Do you suggest to add a new module to the Python module or to enhance the existing string.Template class? In my opinion, string.Template alone is almost useless (it's probably why it is not used). Templates engines are much more powerful: cache results, loops, apply functions on variables, escape HTML, etc. IMO it's better to continue to develop templates outside Python stdlib. When a module enters the Python stdlib, its API is almost frozen during many years and you must keep the backward compatibility. It can be a blocker point if you want to enhance your module. It looks like template engines are moving fast, at least faster than the CPython stdlib. Template engines are also specific to a domain, especially to the web. You may need a different template engines for a different domain. Tell me if I'm wrong. Well, that's just my opinion. Others may like to enhance string.Template class to support the "{{name}}" syntax. -- If you want to include a whole template engine into the Python stdlib, the proposition should come from the maintainer of the module. We don't want to have a split (different API, different behaviour) between the version available in CPython and the version maintained on PyPI. And the proposition must be a full PEP describing the API, explain why it's better to get the engine into the stdlib, rationale, compare with other engines, etc. Victor
On Thu, Nov 28, 2013 at 06:53:07PM +0100, Victor Stinner wrote:
In my opinion, string.Template alone is almost useless (it's probably why it is not used).
I've used it. In my opinion, string.Template is not aimed at the programmer, but at the end-user. As a programmer, string.Template is very underpowered and much less convenient than either % string interpolation or str.format. But as an end-user, sometimes all I need is basic string templating without all the complicated features of % and {} formatting. For that simple use-case $name templates are all I want and a much nicer look than Anatoly's suggested {{name}}. If Anatoly wishes to create a new templating engine using {{}}, I encourage him to do so, but he should leave string.Template alone. (I'm not opposed to enhancements to Template, but I am opposed to radically overhauling it into something completely different.) -- Steven
On Nov 28, 2013, at 06:53 PM, Victor Stinner wrote:
In my opinion, string.Template alone is almost useless (it's probably why it is not used).
It *is* used, but IME more as a fundamental building block for higher level APIs. string.Template is very definitely not intended to be a templating engine on the order of the many powerful ones available in web frameworks. -Barry
Why not use string's .format? anatoly techtonik <techtonik@gmail.com> wrote:
http://docs.python.org/2/library/string.html#template-strings
## Original Idea
stdlib lacks the most popular basic variable extension syntax "{{ variable }}" that can be found in Django [1], Jinja2 [2] and other templating engines [3].
## stdlib Analysis
string.Template syntax is ancient (dates back to Python 2.4 from 9 years ago). I haven't seen a template like this for a long time.
## Scope of Enhancement
st = 'Hello {{world}}.' world = 'is not enough' t = Template(string, style='brace') t.render(locals())
## Links
1. https://docs.djangoproject.com/en/dev/topics/templates/#variables 2. http://jinja.pocoo.org/docs/templates/#variables 3. http://mustache.github.io/
## Feature Creeping
# Allow to override {{ }} symbols to make it more generic.
# `foo.bar` attribute lookup for 2D (nested) structures.
Questions is it has to be supported: `foo.bar` in Django does dictionary lookup first, then attribute lookup `foo.bar` in Jinja2 does attribute lookup first
I am not sure which is better. I definitely don't want some method or property on a dict passed to render() method to hide dict value. -- anatoly t. _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas
-- Sent from my Android phone with K-9 Mail. Please excuse my brevity.
On Thu, Nov 28, 2013 at 9:31 PM, Ryan <rymg19@gmail.com> wrote:
Why not use string's .format?
Good question. I'd say format language is too complicated. It is the same cryptic printf-like char-micromanagement language syntax, where every byte counts even if unreadable. I don't know why it was introduced. Perhaps there was no other way, but it looks more complicated than common templating engine conventions. I'd say it is not the best syntax, and its API is not common.
anatoly techtonik writes:
Good question. I'd say format language is too complicated. It is the same cryptic printf-like char-micromanagement language syntax, where every byte counts even if unreadable.
In fact, .format() is *not* complicated in its basic use: "I propose a fine of ${payment} for not reading the docs.".format(payment=100) (Note that this isn't Perl, the "$" is a literal. :-) But when you don't have a TABLE element available for formatting tables, width, precision, base, and the like are *necessary* information for nice output. Do you really think it's readable to write "I propose a fine of ${payment: type=float precision=2} for not reading the docs.".format(payment=100) vs. "I propose a fine of ${payment:.2f} for not reading the docs.".format(payment=100) .format() provides simple syntax for simple tasks, and more complex syntax for tasks requiring more precision of expression. It's true that the marshalling of substitution values (either as keyword arguments or in a **kw dictionary) is exposed here in the invocation of .format() itself, but you don't avoid marshalling in Django or other web frameworks, it's just in a different place with somewhat different requirements. Web framework templating languages do avoid "cryptic printf-like char-micromanagement", but they can do that because they delegate the styling to HTML and CSS. It's true that such template languages allow things like object attribute access, but there are severe restrictions, and deciding on the restrictions is a very subtle matter. It's generally agreed that separation of business logic from presentation is a Good Thing[tm], so allowing attribute access and filtering is *apparently* a step in the Wrong direction. Where "apparent" becomes "actual" is unclear, especially for the general-purpose facility that Python must provide. Although AFAIK attribute access and filter syntax are common features of popular templating languages, I don't think it's a good idea for Python to advocate a particular set of features in its format language when the set of commonly accepted features is quite restricted (eg, one level of object attribute access), so in practice templating languages are not going to go away. On the Python side, Python cannot assume that the output language will be a structured markup language with styling features; the low-level formatting syntax is still needed. -1 on adding more templating features to Python's stdlib; .format() already hits the sweet spot given current best practice IMO.
On 29 November 2013 11:13, Stephen J. Turnbull <stephen@xemacs.org> wrote:
Although AFAIK attribute access and filter syntax are common features of popular templating languages, I don't think it's a good idea for Python to advocate a particular set of features in its format language when the set of commonly accepted features is quite restricted (eg, one level of object attribute access), so in practice templating languages are not going to go away. On the Python side, Python cannot assume that the output language will be a structured markup language with styling features; the low-level formatting syntax is still needed.
-1 on adding more templating features to Python's stdlib; .format() already hits the sweet spot given current best practice IMO.
As is frequently the case, Anatoly has failed to do his research on what is already possible and the rationale for the status quo before proposing changes. This is in spite of repeated requests (over a number of years) that he stop wasting people's time on the core development lists. 1. The string.Template syntax is aimed at document translators and other non-developer string formatting use cases. It is not really intended for programmatic use. This is covered explicitly in PEP 292 (which added string.Template) 2. The str.format mini-language *is* designed for programmatic use, and already offers attribute and item access as part of element substitution (see PEP 3101 and the standard library documentation). There's essentially zero chance of a fourth approach to string formatting being added to the standard library - third party libraries remain free to do whatever they want, though. Regards, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
"Stephen J. Turnbull" <stephen@xemacs.org> writes:
But when you don't have a TABLE element available for formatting tables, width, precision, base, and the like are *necessary* information for nice output. Do you really think it's readable to write
"I propose a fine of ${payment: type=float precision=2} for not reading the docs.".format(payment=100)
vs.
"I propose a fine of ${payment:.2f} for not reading the docs.".format(payment=100)
The first is far more readable, because it is explicit and doesn't require special knowledge to know what the parameters are. An uninformed guess by a casual reader is much more likely to be right in the first case; I think that's an important criterion for readability. Which is not to say I *prefer* the first one. I think readability can be sacrificed in some cases where the benefit of concision is high, and a template paramter format is one of those cases IMO. But we need to acknowledge that concision and readability are sometimes conflicting goals. I think it's clear that your examples illustrate that conflict.
-1 on adding more templating features to Python's stdlib; .format() already hits the sweet spot given current best practice IMO.
Definitely agreed. -- \ “Always code as if the guy who ends up maintaining your code | `\ will be a violent psychopath who knows where you live.” —John | _o__) F. Woods | Ben Finney
Ben Finney writes:
"Stephen J. Turnbull" <stephen@xemacs.org> writes:
But when you don't have a TABLE element available for formatting tables, width, precision, base, and the like are *necessary* information for nice output. Do you really think it's readable to write
"I propose a fine of ${payment: type=float precision=2} for not reading the docs.".format(payment=100)
vs.
"I propose a fine of ${payment:.2f} for not reading the docs.".format(payment=100)
The first is far more readable, because it is explicit and doesn't require special knowledge to know what the parameters are.
Ah, but the example isn't really very good. In most cases in running text "everything default" is what you want, which I think we all agree is most readable. (Somebody wanted Perl-style $VARIABLE, but I don't see a big difference between that and {VARIABLE}, especially in cases where you want concatenation with trailing identifier characters and would have to spell it "${VARIABLE}" or something like that anyway.) Where you'd want precise control of formatting is a multicolumn table, which will add a "width=10" parameter for a total of 45 columns for the format for a single variable. As soon as it wraps (two columns ;-), it becomes unreadable. The "10.2f" in the idiom of .format() will take only 16 columns, so you can easily get 5 readable columns in an 80-column window, and in general about 3X as many columns in the same window as with the "locally" more readable explicit format. That's not at all inconsistent with your statement that "sometimes concise expression is important", of course, but I did want to point out that concise expression has important readability benefits.
An uninformed guess by a casual reader is much more likely to be right in the first case; I think that's an important criterion for readability.
I'd argue that the casual reader most likely doesn't actually care about the formatting, especially in in the running text case. YMMV, but I'd bet on that, and would take the current formatting with keyword arguments for content and short moderately mnemonic codes for style as "most readable" for the cases where the styling of presentation matters.
On Fri, Nov 29, 2013 at 3:55 PM, Stephen J. Turnbull <stephen@xemacs.org> wrote:
I'd argue that the casual reader most likely doesn't actually care about the formatting, especially in in the running text case. YMMV, but I'd bet on that, and would take the current formatting with keyword arguments for content and short moderately mnemonic codes for style as "most readable" for the cases where the styling of presentation matters.
Definitely. Focus should be on the overall string and its contents, it shouldn't be screaming at you "HEY LOOK I'M ABOUT TO PUT A FLOAT IN HERE WITH TWO DECIMALS". A simple, compact notation helps with that. Anyway, if you can't figure out what ".2f" means, you're going to have trouble in a lot of format languages that derive from printf. It's a handy notation, and no harder to figure out than a more verbose "type=float" is. After all, what does "float" mean? Will it render in exponential notation? Decimal notation? Presumably it won't output the IEEE binary representation, eg "40 49 0f db" (compacted into hex for convenience), though it's plausible there might be a way to emit that. So if you can learn the specifics of the "float" representation, you should be able to learn the specifics of the "f" renderer. Same thing, less keystrokes. ChrisA
Nah, format just takes getting used to, like anything else would. And you don't need to use half the language; Python comes with enough builtin attributes on strings. anatoly techtonik <techtonik@gmail.com> wrote:
On Thu, Nov 28, 2013 at 9:31 PM, Ryan <rymg19@gmail.com> wrote:
Why not use string's .format?
Good question. I'd say format language is too complicated. It is the same cryptic printf-like char-micromanagement language syntax, where every byte counts even if unreadable. I don't know why it was introduced. Perhaps there was no other way, but it looks more complicated than common templating engine conventions. I'd say it is not the best syntax, and its API is not common.
-- Sent from my Android device with K-9 Mail. Please excuse my brevity.
Why not use string's .format? anatoly techtonik <techtonik@gmail.com> wrote:
http://docs.python.org/2/library/string.html#template-strings
## Original Idea
stdlib lacks the most popular basic variable extension syntax "{{ variable }}" that can be found in Django [1], Jinja2 [2] and other templating engines [3].
## stdlib Analysis
string.Template syntax is ancient (dates back to Python 2.4 from 9 years ago). I haven't seen a template like this for a long time.
## Scope of Enhancement
st = 'Hello {{world}}.' world = 'is not enough' t = Template(string, style='brace') t.render(locals())
## Links
1. https://docs.djangoproject.com/en/dev/topics/templates/#variables 2. http://jinja.pocoo.org/docs/templates/#variables 3. http://mustache.github.io/
## Feature Creeping
# Allow to override {{ }} symbols to make it more generic.
# `foo.bar` attribute lookup for 2D (nested) structures.
Questions is it has to be supported: `foo.bar` in Django does dictionary lookup first, then attribute lookup `foo.bar` in Jinja2 does attribute lookup first
I am not sure which is better. I definitely don't want some method or property on a dict passed to render() method to hide dict value. -- anatoly t. _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas
-- Sent from my Android phone with K-9 Mail. Please excuse my brevity.
http://docs.python.org/2/library/string.html#template-strings
## Original Idea
stdlib lacks the most popular basic variable extension syntax "{{ variable }}" that can be found in Django [1], Jinja2 [2] and other templating engines [3]. Anatoly, you've been participating here long enough to know that an important question to answer is: why does the stdlib need this functionality? As you point out here, it is already available from
On 11/28/13 11:57 AM, anatoly techtonik wrote: popular third-party packages. Why not just let them provide the functionality, and leave it at that? --Ned.
## stdlib Analysis
string.Template syntax is ancient (dates back to Python 2.4 from 9 years ago). I haven't seen a template like this for a long time.
## Scope of Enhancement
st = 'Hello {{world}}.' world = 'is not enough' t = Template(string, style='brace') t.render(locals())
## Links
1. https://docs.djangoproject.com/en/dev/topics/templates/#variables 2. http://jinja.pocoo.org/docs/templates/#variables 3. http://mustache.github.io/
## Feature Creeping
# Allow to override {{ }} symbols to make it more generic.
# `foo.bar` attribute lookup for 2D (nested) structures.
Questions is it has to be supported: `foo.bar` in Django does dictionary lookup first, then attribute lookup `foo.bar` in Jinja2 does attribute lookup first
I am not sure which is better. I definitely don't want some method or property on a dict passed to render() method to hide dict value. -- anatoly t. _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas
On Thu, Nov 28, 2013 at 10:55 PM, Ned Batchelder <ned@nedbatchelder.com> wrote:
On 11/28/13 11:57 AM, anatoly techtonik wrote:
http://docs.python.org/2/library/string.html#template-strings
## Original Idea
stdlib lacks the most popular basic variable extension syntax "{{ variable }}" that can be found in Django [1], Jinja2 [2] and other templating engines [3].
Anatoly, you've been participating here long enough to know that an important question to answer is: why does the stdlib need this functionality? As you point out here, it is already available from popular third-party packages. Why not just let them provide the functionality, and leave it at that?
stdlib doesn't need the functionality provided by current string,Template, and if stdlib comes with batteries included, it is better to ship Alkaline than NiCd. Support for {{ }} syntax and attribute lookup is a way to provide something simple from the start, that can be later enhanced by using dependencies, but without rewriting everything to a new syntax. -- anatoly t.
On Nov 28, 2013, at 07:57 PM, anatoly techtonik wrote:
string.Template syntax is ancient (dates back to Python 2.4 from 9 years ago). I haven't seen a template like this for a long time.
string.Template syntax is defined in PEP 292 and was deliberately named "Simpler String Substitutions". The motivation for PEP 292 was the observation of many years of difficulty with translation of gettext message strings in highly i18n'd code. We saw countless errors where translators would leave off a trailing 's' in %(foo)s placeholders, breaking systems, or requiring them to be defensive to the point of being unreadable. $strings have a rich tradition in programming languages and translators seem to have a better time with such placeholders. It's might be useful to provide some flexibility in string.Template, but I don't want to lose the beauty of simplicity or sacrifice the original use case to try to support every possible variation. OTOH, string.Template is just one class in the stdlib. There's no reason other libraries can't provide different classes supporting different formats. FWIW, flufl.i18n builds on string.Template and PEP 292, as well as gettext, to provide a richer API for managing translations in Python programs. Cheers, -Barry
participants (10)
-
anatoly techtonik
-
Barry Warsaw
-
Ben Finney
-
Chris Angelico
-
Ned Batchelder
-
Nick Coghlan
-
Ryan
-
Stephen J. Turnbull
-
Steven D'Aprano
-
Victor Stinner