Alternative Implementation for PEP 292: Simple String Substitutions

* doesn't force result to unicode
[Aahz]
This is the main reason I'm +0, pending further arguments.
Employing class logic for a function problem is my main reason. Any function can be wrapped in class logic and use an overloaded operator (string.template for example) -- it's invariably the wrong thing to do for reasons of complexity, separation of instantiation and application, and the issues that always arise when an operator is overloaded (a good technique that should only be applied sparingly). [Aahz]
The reasons center around the remoteness of instantiation from application, the differences from current uses of %, and an issue with the % operator itself. When application is remote from instantiation (for instance, when a template argument is supplied to a function), we get several problems. Given a line like "r = t % m", it is hard to verify that the code is correct. Should there be KeyError trapping? Can m be a tuple? Is t a %template, a safetemplate, or dollartemplate? Is the result a str or Unicode object? Should the decision of safe vs regular substitution be made at the point of instantiation or application? The temptation will be to reuse existing code that uses the % operator which unfortunately is not the same (especially with respect to applying tuples, return types, and auto-stringizing). The % operator is hard to search for in the docs and has precedence issues arising from its primary use for modulo arithemetic. Also, using a function makes it possible to use both % formatting and $ formatting (I do have use a case for this). Further, the % operator mnemonically only makes sense with % identifier tags -- it makes less sense with $ tags. Whatever answer is chosen, it should be forward looking and consider that others will want to add functionality (local namespace lookups for example) and that some poor bastards are going to waste time figuring out how to subclass the current implementation. In time, there will likely be more than two of these -- do you want more classes or more functions? Raymond

On Fri, Aug 27, 2004, Raymond Hettinger wrote:
All right, this moves me to +1, in the absence of any good arguments in favor of keeping the class-based system. -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ "To me vi is Zen. To use vi is to practice zen. Every command is a koan. Profound to the user, unintelligible to the uninitiated. You discover truth everytime you use it." --reddy@lion.austin.ibm.com

[Aahz]
FWIW, I've loaded the proposed improvements to the sandbox: \nondist\sandbox\string\alt292.py It includes a doctest section that illustrates all of the improvements in action (appropriate return type, error handling, commenting, code simplicity, keyword arguments, function API, etc). I'm not sure what to do next. Aside from Aahz, no one on python-dev seems to be interested and Barry appears to have been off-line for a few days. Ideally, I would like to get this in a few days ahead of the alpha release. Raymond

"Raymond Hettinger" <python@rcn.com> writes:
I'm not too worried either way, as I don't think that this will be something I use a lot (I may be wrong, though..) Having said that, I do feel that your points should be addressed. I haven't looked at either implementation, but I'd assume that the key benefit of a class-based implementation would be the ability to subclass to modify behaviour. If that isn't happening in practice, then I agree that a function is probably a better option. As a test case, how would I implement the case that has come up here recently, of supporting $obj.attr substitutions, in each of the two implementations? It would be interesting to see the relative simplicity. I'm assuming that the function-based case would require effectively a cut & paste reimplementation. [FX: Dives into source code...] The Template class is pretty trivial, but it doesn't seem to be designed for extension. Thus, the above test case would *still* need pretty much a rewrite. However, if the Template class was rewritten with overriding in mind, it probably could make things easier: 1. Split the match pattern into pieces, such that adding new syntax like $obj.attr is just a case of adding a new pattern to a list. 2. Make the __mod__ code more case-like, having separate actions based on group name. Then overriding code could just add actions for the groups it added, and call the base class for the rest. This isn't fully thought through, and may well not be worth it in practice, but it gives the sort of benefits I'd expect from a class-based approach. Paul. -- Home computers are being called upon to perform many new functions, including the consumption of homework formerly eaten by the dog -- Doug Larson

Subclassing is only one possibility. With the templating version, you could also write another class that implements the same interface -- very Pythonic. If Raymond's function approach were chosen, you're stuck with what that function can and can't do. -- --Guido van Rossum (home page: http://www.python.org/~guido/)

On Sun, 2004-08-29 at 09:48, Paul Moore wrote:
Attached is a demo using the 2.4a3 implementation of string.Template. Note that the only change in the Template subclass is the pattern, and there, it's just that the 'named' and 'braced' groups got a '.' in the second character class. -Barry

On Fri, Aug 27, 2004, Raymond Hettinger wrote:
All right, this moves me to +1, in the absence of any good arguments in favor of keeping the class-based system. -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ "To me vi is Zen. To use vi is to practice zen. Every command is a koan. Profound to the user, unintelligible to the uninitiated. You discover truth everytime you use it." --reddy@lion.austin.ibm.com

[Aahz]
FWIW, I've loaded the proposed improvements to the sandbox: \nondist\sandbox\string\alt292.py It includes a doctest section that illustrates all of the improvements in action (appropriate return type, error handling, commenting, code simplicity, keyword arguments, function API, etc). I'm not sure what to do next. Aside from Aahz, no one on python-dev seems to be interested and Barry appears to have been off-line for a few days. Ideally, I would like to get this in a few days ahead of the alpha release. Raymond

"Raymond Hettinger" <python@rcn.com> writes:
I'm not too worried either way, as I don't think that this will be something I use a lot (I may be wrong, though..) Having said that, I do feel that your points should be addressed. I haven't looked at either implementation, but I'd assume that the key benefit of a class-based implementation would be the ability to subclass to modify behaviour. If that isn't happening in practice, then I agree that a function is probably a better option. As a test case, how would I implement the case that has come up here recently, of supporting $obj.attr substitutions, in each of the two implementations? It would be interesting to see the relative simplicity. I'm assuming that the function-based case would require effectively a cut & paste reimplementation. [FX: Dives into source code...] The Template class is pretty trivial, but it doesn't seem to be designed for extension. Thus, the above test case would *still* need pretty much a rewrite. However, if the Template class was rewritten with overriding in mind, it probably could make things easier: 1. Split the match pattern into pieces, such that adding new syntax like $obj.attr is just a case of adding a new pattern to a list. 2. Make the __mod__ code more case-like, having separate actions based on group name. Then overriding code could just add actions for the groups it added, and call the base class for the rest. This isn't fully thought through, and may well not be worth it in practice, but it gives the sort of benefits I'd expect from a class-based approach. Paul. -- Home computers are being called upon to perform many new functions, including the consumption of homework formerly eaten by the dog -- Doug Larson

Subclassing is only one possibility. With the templating version, you could also write another class that implements the same interface -- very Pythonic. If Raymond's function approach were chosen, you're stuck with what that function can and can't do. -- --Guido van Rossum (home page: http://www.python.org/~guido/)

On Sun, 2004-08-29 at 09:48, Paul Moore wrote:
Attached is a demo using the 2.4a3 implementation of string.Template. Note that the only change in the Template subclass is the pattern, and there, it's just that the 'named' and 'braced' groups got a '.' in the second character class. -Barry
participants (5)
-
Aahz
-
Barry Warsaw
-
Guido van Rossum
-
Paul Moore
-
Raymond Hettinger