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:
+7
-7
@@ -375,13 +375,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..'
|
||||
@@ -396,10 +392,13 @@ 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] == '(':
|
||||
if attrs is not None:
|
||||
try:
|
||||
v = attrs(m.group('field'))
|
||||
v = attrs[m.group('field')]
|
||||
except KeyError:
|
||||
return m.group()
|
||||
else:
|
||||
return m.group()
|
||||
f = m.group('format')
|
||||
if f[-1] in 'dboxX':
|
||||
if isinstance(v, str):
|
||||
@@ -415,6 +414,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
|
||||
|
||||
@@ -267,13 +267,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..'
|
||||
@@ -288,10 +284,13 @@ 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] == '(':
|
||||
if attrs is not None:
|
||||
try:
|
||||
v = attrs(m.group('field'))
|
||||
v = attrs[m.group('field')]
|
||||
except KeyError:
|
||||
return m.group()
|
||||
else:
|
||||
return m.group()
|
||||
f = m.group('format')
|
||||
if f[-1] in 'dboxX':
|
||||
if isinstance(v, str):
|
||||
@@ -307,6 +306,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)
|
||||
|
||||
|
||||
|
||||
+7
-7
@@ -1268,13 +1268,9 @@ class RExpr:
|
||||
|
||||
|
||||
# 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..'
|
||||
@@ -1289,10 +1285,13 @@ 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] == '(':
|
||||
if attrs is not None:
|
||||
try:
|
||||
v = attrs(m.group('field'))
|
||||
v = attrs[m.group('field')]
|
||||
except KeyError:
|
||||
return m.group()
|
||||
else:
|
||||
return m.group()
|
||||
f = m.group('format')
|
||||
if f[-1] in 'dboxX':
|
||||
if isinstance(v, str):
|
||||
@@ -1308,6 +1307,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)
|
||||
|
||||
def punescape_help():
|
||||
|
||||
+7
-7
@@ -3898,13 +3898,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..'
|
||||
@@ -3919,10 +3915,13 @@ 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] == '(':
|
||||
if attrs is not None:
|
||||
try:
|
||||
v = attrs(m.group('field'))
|
||||
v = attrs[m.group('field')]
|
||||
except KeyError:
|
||||
return m.group()
|
||||
else:
|
||||
return m.group()
|
||||
f = m.group('format')
|
||||
if f[-1] in 'dboxX':
|
||||
if isinstance(v, str):
|
||||
@@ -3938,6 +3937,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
|
||||
|
||||
@@ -3808,13 +3808,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..'
|
||||
@@ -3829,10 +3825,13 @@ 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] == '(':
|
||||
if attrs is not None:
|
||||
try:
|
||||
v = attrs(m.group('field'))
|
||||
v = attrs[m.group('field')]
|
||||
except KeyError:
|
||||
return m.group()
|
||||
else:
|
||||
return m.group()
|
||||
f = m.group('format')
|
||||
if f[-1] in 'dboxX':
|
||||
if isinstance(v, str):
|
||||
@@ -3848,6 +3847,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)
|
||||
|
||||
|
||||
|
||||
+7
-7
@@ -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,10 +569,13 @@ 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] == '(':
|
||||
if attrs is not None:
|
||||
try:
|
||||
v = attrs(m.group('field'))
|
||||
v = attrs[m.group('field')]
|
||||
except KeyError:
|
||||
return m.group()
|
||||
else:
|
||||
return m.group()
|
||||
f = m.group('format')
|
||||
if f[-1] in 'dboxX':
|
||||
if isinstance(v, str):
|
||||
@@ -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
|
||||
|
||||
+7
-7
@@ -459,13 +459,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..'
|
||||
@@ -480,10 +476,13 @@ 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] == '(':
|
||||
if attrs is not None:
|
||||
try:
|
||||
v = attrs(m.group('field'))
|
||||
v = attrs[m.group('field')]
|
||||
except KeyError:
|
||||
return m.group()
|
||||
else:
|
||||
return m.group()
|
||||
f = m.group('format')
|
||||
if f[-1] in 'dboxX':
|
||||
if isinstance(v, str):
|
||||
@@ -499,6 +498,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)
|
||||
|
||||
|
||||
|
||||
+7
-8
@@ -397,14 +397,9 @@ class Attr:
|
||||
return len(self.keyed)
|
||||
|
||||
# parse %-escaped strings
|
||||
#
|
||||
# attrs can override __getitem__ for lazy attr generation
|
||||
def punescape(s, attrs=None):
|
||||
# TODO punescape should just take something that provides __getitem__
|
||||
if attrs is None:
|
||||
attrs = {}
|
||||
if isinstance(attrs, dict):
|
||||
attrs_ = attrs
|
||||
attrs = lambda k: attrs_[k]
|
||||
|
||||
pattern = re.compile(
|
||||
'%[%n]'
|
||||
'|' '%x..'
|
||||
@@ -419,10 +414,13 @@ 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] == '(':
|
||||
if attrs is not None:
|
||||
try:
|
||||
v = attrs(m.group('field'))
|
||||
v = attrs[m.group('field')]
|
||||
except KeyError:
|
||||
return m.group()
|
||||
else:
|
||||
return m.group()
|
||||
f = m.group('format')
|
||||
if f[-1] in 'dboxX':
|
||||
if isinstance(v, str):
|
||||
@@ -438,6 +436,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
|
||||
|
||||
+7
-7
@@ -444,13 +444,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..'
|
||||
@@ -465,10 +461,13 @@ 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] == '(':
|
||||
if attrs is not None:
|
||||
try:
|
||||
v = attrs(m.group('field'))
|
||||
v = attrs[m.group('field')]
|
||||
except KeyError:
|
||||
return m.group()
|
||||
else:
|
||||
return m.group()
|
||||
f = m.group('format')
|
||||
if f[-1] in 'dboxX':
|
||||
if isinstance(v, str):
|
||||
@@ -484,6 +483,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
|
||||
|
||||
@@ -335,13 +335,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..'
|
||||
@@ -356,10 +352,13 @@ 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] == '(':
|
||||
if attrs is not None:
|
||||
try:
|
||||
v = attrs(m.group('field'))
|
||||
v = attrs[m.group('field')]
|
||||
except KeyError:
|
||||
return m.group()
|
||||
else:
|
||||
return m.group()
|
||||
f = m.group('format')
|
||||
if f[-1] in 'dboxX':
|
||||
if isinstance(v, str):
|
||||
@@ -375,6 +374,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)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user