From 8e3760c5b80b550c1522bc029e3ed5f09ae4c54b Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Thu, 10 Apr 2025 16:01:42 -0500 Subject: [PATCH] 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). --- scripts/codemap.py | 18 +++++++++--------- scripts/codemapd3.py | 18 +++++++++--------- scripts/csv.py | 18 +++++++++--------- scripts/dbgbmap.py | 18 +++++++++--------- scripts/dbgbmapd3.py | 18 +++++++++--------- scripts/plot.py | 18 +++++++++--------- scripts/plotmpl.py | 18 +++++++++--------- scripts/tracebd.py | 19 +++++++++---------- scripts/treemap.py | 18 +++++++++--------- scripts/treemapd3.py | 18 +++++++++--------- 10 files changed, 90 insertions(+), 91 deletions(-) diff --git a/scripts/codemap.py b/scripts/codemap.py index 4b5f7818..fe871299 100755 --- a/scripts/codemap.py +++ b/scripts/codemap.py @@ -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,9 +392,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': @@ -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 diff --git a/scripts/codemapd3.py b/scripts/codemapd3.py index b924bdac..e4149290 100755 --- a/scripts/codemapd3.py +++ b/scripts/codemapd3.py @@ -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,9 +284,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': @@ -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) diff --git a/scripts/csv.py b/scripts/csv.py index 63a4fa4c..16edb7cc 100755 --- a/scripts/csv.py +++ b/scripts/csv.py @@ -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,9 +1285,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': @@ -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(): diff --git a/scripts/dbgbmap.py b/scripts/dbgbmap.py index e0cb0813..dad03c07 100755 --- a/scripts/dbgbmap.py +++ b/scripts/dbgbmap.py @@ -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,9 +3915,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': @@ -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 diff --git a/scripts/dbgbmapd3.py b/scripts/dbgbmapd3.py index 7cb94ac3..5c74b6ec 100755 --- a/scripts/dbgbmapd3.py +++ b/scripts/dbgbmapd3.py @@ -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,9 +3825,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': @@ -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) diff --git a/scripts/plot.py b/scripts/plot.py index 99a05dd4..36f5d05d 100755 --- a/scripts/plot.py +++ b/scripts/plot.py @@ -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 diff --git a/scripts/plotmpl.py b/scripts/plotmpl.py index dce9cdf1..44372e21 100755 --- a/scripts/plotmpl.py +++ b/scripts/plotmpl.py @@ -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,9 +476,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': @@ -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) diff --git a/scripts/tracebd.py b/scripts/tracebd.py index bac94b94..e8540aff 100755 --- a/scripts/tracebd.py +++ b/scripts/tracebd.py @@ -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,9 +414,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': @@ -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 diff --git a/scripts/treemap.py b/scripts/treemap.py index ac1e8fea..5ffa3259 100755 --- a/scripts/treemap.py +++ b/scripts/treemap.py @@ -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,9 +461,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': @@ -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 diff --git a/scripts/treemapd3.py b/scripts/treemapd3.py index 3ffb9eb1..47b16121 100755 --- a/scripts/treemapd3.py +++ b/scripts/treemapd3.py @@ -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,9 +352,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': @@ -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)