> PEP 292 is slated for inclusion in Python 2.4, For completeness, perhaps update the PEP to specify what will happen with $ strings that do not fall under $$, $indentifier, or ${identifier}. For instance, what should happen with: "A dangling $" "A $!invalid_identifier" "A $identfier&followed_by_nonwhitespace_punctuation" > My new stuff provides two classes, dstring() as described in PEP 292 and > astring() as hinted at in the PEP. It also provides two dictionary > subclasses called safedict() and nsdict() which are not required, but > work nicely with dstring() and astring() -- safedict re-expands keys > instead of throwing exceptions, and nsdict does namespace lookup and > attribute path expansion. The names dstring(), astring(), safedict(), and nsdict() could likely be improved to be more suggestive of what they do. > Brett and I (I forget who else was there for this) talked about where to > situate the PEP 292 support. The interesting idea came up to turn the > string module into a package, providing backward support for the > existing string module API, then exporting my PEP 292 modules into this > namespace. This would make the 'import string' useful again since it > would be a place to collect future string related functionality without > having to claim some dumb name like 'stringlib'. I believe we can still > someday deprecate the old string module functions, retaining the useful > constants, as well as new string-y features. . > I also really want to include safedict.py if we're > including pep292.py because they're quite useful and complimentary, IMO, > and I can't think of a better place to put those classes either. Can safedict.safedict() be made more general so that it has value outside of string substitutions. Ideally, the default format would be customizable and would include an option to leave the entry unchanged. Right now, the implementation is specific to string substitution formats. It is not even useful with normal % formatting. > I'm open to suggestions. I have not yet written docs for these new > classes, but will do so once we agree on where they're getting added. > The code and test cases are in python/nondist/sandbox/string. Given the simplicity of the PEP, the sandbox implementation is surprisingly intricate. Is it possible to simplify it with a function based rather than class based approach? I can imagine alternatives which encapsulate the whole idea in something similar to this: import re nondotted = re.compile(r'(\${2})|\$([_a-z][_a-z0-9]*)|\$({[_a-z][_a-z0-9]*})', re.IGNORECASE) dotted= re.compile(r'(\${2})|\$([_a-z][_.a-z0-9]*)|\$({[_a-z][_.a-z0-9]*})', re.IGNORECASE) def _convert(m): 'Convert $ formats to % formats' escaped, straight, bracketed = m.groups() if escaped is not None: return '$' if straight is not None: return '%(' + straight + ')s' return '%(' + bracketed[1:-1] + ')s' def subst(fmtstr, mapping, fmtcode=nondotted, _cache={}): if fmtstr not in _cache: _cache[fmtstr] = _fmtcode.sub(_convert, fmtstr) return _cache[fmtstr] % mapping >>>>> mapping = dict(who='Guido', what='money')) >>> print subst(fmtstr, mapping) Guido owes me $money. Raymond