My first thought was that this is a job for string.Template, which has
always struck me as subclassing-friendly. Took about a half hour of
wrangling the regex to get here:
from string import Template, _sentinel_dict
class TemplateWithDefaults(Template):
braceidpattern = r'([_a-z][_a-z0-9]*))((:(?P<default>([^}]*)))?'
def substitute(self, mapping=_sentinel_dict, /, **kws):
if mapping is _sentinel_dict:
mapping = kws
elif kws:
mapping = _ChainMap(kws, mapping)
def convert(mo):
named = mo.group('named') or mo.group('braced')
if named is not None:
try:
return str(mapping[named])
except KeyError:
default = mo.group('default')
if not default:
raise
return default
if mo.group('escaped') is not None:
return self.delimiter
if mo.group('invalid') is not None:
self._invalid(mo)
raise ValueError('Unrecognized named group in pattern',
self.pattern)
return self.pattern.sub(convert, self.template)
template = TemplateWithDefaults('Where ${prep:was} my default? ${here}.')
options = {'prep':'is', 'here':'Nowhere'}
print(template.substitute(options))
print(template.substitute(here='Here'))
print(template.substitute()) # Should fail with key error on 'here'
On Fri, Apr 1, 2022 at 8:13 AM Brian McCall <[email protected]>
wrote:
> Oh, I didn't even know about `format_map`! Or `__format__` for that
> matter. This makes everything much easier. For my purposes, I don't even
> need to use `__format__` since I am not using format strings.
>
> In a show of appreciation, here is a URL to a GIF of James Corden bowing:
> https://media.giphy.com/media/l2R0eYcNq9rJUsVAA/giphy.gif
>
> ```
> class Options(UserDict):
> def __getitem__(self, key):
> if key in self:
> return super().__getitem__(key)
> key, *default = key.split('?')
> if key in self:
> return super().__getitem__(key)
> return ''.join(default)
>
> options = {'baud': 19200}
> result = 'BAUD: {baud?9600}'.format_map(Options(options))
> print(result)
>
> options = {}
> result = 'BAUD: {baud?9600}'.format_map(Options(options))
> print(result)
>
> ```
> _______________________________________________
> Python-ideas mailing list -- [email protected]
> To unsubscribe send an email to [email protected]
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/[email protected]/message/HPV3AJ4PUYDGVWAKLQQQL7EEHSRBP7N7/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/UM7BUM3N3UYC3KTMO7QIHACIMR2P5GCP/
Code of Conduct: http://python.org/psf/codeofconduct/