[Python-Dev] PEP 292 for Python 2.4

Raymond Hettinger python at rcn.com
Tue Jun 15 17:10:17 EDT 2004


> 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.

-1

The inclusion of string.py breathes life into something that needs to
disappear.  One of the reasons for deprecating these functions is to
reduce the number of things you need to learn and remember.
Interspersing a handful of new functions and classes is contrary to that
goal.  It becomes hard to introduce simplified substitutions without
talking about all the other string functions that you're better off not
knowing about.

A separate module is preferable.  Also, I don't see any benefit into
rolling a package with safedict and nsdict in a separate module from
dstring and astring.



> 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

>>> fmtstr = '$who owes me $$${what}.'
>>> mapping = dict(who='Guido', what='money'))
>>> print subst(fmtstr, mapping)
Guido owes me $money.
    
  

Raymond




More information about the Python-Dev mailing list