scripts: Tweaked punescape to expect dict-like attrs

This simplifies attrs a bit, and scripts can always override
__getitem__ if they want to provide lazy attr generation.

The original intention of accepting functions was to make lazy attr
generation easier, but while tinkering around with the idea I realized
the actual attr mapping/generation would be complicated enough that
you'd probably want a full class anyways.

All of our scripts are only using dict attrs anyways. And lazy attr
generation is probably a premature optimization for the same reason
everyone's ok with Python's slices being O(n).
This commit is contained in:
Christopher Haster
2025-04-10 16:01:42 -05:00
parent 06bb34fd99
commit 8e3760c5b8
10 changed files with 90 additions and 91 deletions

View File

@@ -552,13 +552,9 @@ class Attr:
return len(self.keyed)
# parse %-escaped strings
#
# attrs can override __getitem__ for lazy attr generation
def punescape(s, attrs=None):
if attrs is None:
attrs = {}
if isinstance(attrs, dict):
attrs_ = attrs
attrs = lambda k: attrs_[k]
pattern = re.compile(
'%[%n]'
'|' '%x..'
@@ -573,9 +569,12 @@ def punescape(s, attrs=None):
elif m.group()[1] == 'u': return chr(int(m.group()[2:], 16))
elif m.group()[1] == 'U': return chr(int(m.group()[2:], 16))
elif m.group()[1] == '(':
try:
v = attrs(m.group('field'))
except KeyError:
if attrs is not None:
try:
v = attrs[m.group('field')]
except KeyError:
return m.group()
else:
return m.group()
f = m.group('format')
if f[-1] in 'dboxX':
@@ -592,6 +591,7 @@ def punescape(s, attrs=None):
# note we need Python's new format syntax for binary
return ('{:%s}' % f).format(v)
else: assert False
return re.sub(pattern, unescape, s)
# split %-escaped strings into chars