Describe the bug
Thirteen re.sub call sites in pcapkit/vendor/ pass a regex flag where the fourth positional parameter is count. Enumerated by AST rather than grep, on 2d1c8675d:
pcapkit/vendor/default.py:343 pcapkit/vendor/ipv6/router_alert.py:55
pcapkit/vendor/hip/eddsa_curve.py:59 pcapkit/vendor/ipv6/tagger_id.py:55
pcapkit/vendor/http/frame.py:64 pcapkit/vendor/reg/ethertype.py:95
pcapkit/vendor/http/method.py:144 pcapkit/vendor/tcp/flags.py:139
pcapkit/vendor/http/status_code.py:148 pcapkit/vendor/tcp/mp_tcp_option.py:65
pcapkit/vendor/ipv4/router_alert.py:58 pcapkit/vendor/tcp/option.py:78
pcapkit/vendor/ipv6/option.py:89
re.sub(pattern, repl, string, count=0, flags=0) — so re.MULTILINE, which is 8, is read as "replace at most 8 occurrences". Measured:
>>> re.MULTILINE
8
>>> re.sub(r'\r*\n', ' ', 'a\n' * 12, re.MULTILINE) # flag as positional
'a a a a a a a a a\na\na\na\n' # <- stops after 8
>>> re.sub(r'\r*\n', ' ', 'a\n' * 12, flags=re.MULTILINE)
'a a a a a a a a a a a a '
Two defects in one line:
- The count is a real limit. Any IANA description with more than eight newlines keeps its ninth onward, so the generated
const module gets embedded newlines where it should have spaces. That output is committed to the tree, so the damage is visible rather than theoretical.
- The flag never applies. For
r'\r*\n' that happens not to matter — no ^/$ in the pattern — so the intent was already a no-op. Check each site; if any pattern uses an anchor, its behaviour is wrong today too.
Also a deprecation: DeprecationWarning: 'count' is passed as positional argument fires on 3.13+, and it becomes a TypeError in a later release, so these break on a future interpreter regardless of semantics.
Expected behavior
flags=re.MULTILINE, or drop the flag where the pattern has no anchor — cleaner than passing one that does nothing.
Additional context
Correcting this issue's own first version, which said "six". A single-line grep found five; the other eight put the flag on a continuation line (), re.MULTILINE))) and were invisible to it. The AST sweep above is the reliable count.
Found by the cross-review on #789, which had just fixed the same shape in re.split at httpv1.py:310/:346. A re-grep found zero remaining re.split sites, so these are the rest of the family.
Two notes for whoever takes it: eight of the thirteen sit on lines also carrying '%s %s' % and a # pylint: disable=consider-using-f-string, so it overlaps #792's convention work — coordinate or sequence them. And regenerating to show the consequence will fetch live IANA registries and move unrelated rows; #792 records the hand-edit-plus-prove-equivalence route around that.
Describe the bug
Thirteen
re.subcall sites inpcapkit/vendor/pass a regex flag where the fourth positional parameter iscount. Enumerated by AST rather than grep, on2d1c8675d:re.sub(pattern, repl, string, count=0, flags=0)— sore.MULTILINE, which is 8, is read as "replace at most 8 occurrences". Measured:Two defects in one line:
constmodule gets embedded newlines where it should have spaces. That output is committed to the tree, so the damage is visible rather than theoretical.r'\r*\n'that happens not to matter — no^/$in the pattern — so the intent was already a no-op. Check each site; if any pattern uses an anchor, its behaviour is wrong today too.Also a deprecation:
DeprecationWarning: 'count' is passed as positional argumentfires on 3.13+, and it becomes aTypeErrorin a later release, so these break on a future interpreter regardless of semantics.Expected behavior
flags=re.MULTILINE, or drop the flag where the pattern has no anchor — cleaner than passing one that does nothing.Additional context
Correcting this issue's own first version, which said "six". A single-line grep found five; the other eight put the flag on a continuation line (
), re.MULTILINE))) and were invisible to it. The AST sweep above is the reliable count.Found by the cross-review on #789, which had just fixed the same shape in
re.splitathttpv1.py:310/:346. A re-grep found zero remainingre.splitsites, so these are the rest of the family.Two notes for whoever takes it: eight of the thirteen sit on lines also carrying
'%s %s' %and a# pylint: disable=consider-using-f-string, so it overlaps #792's convention work — coordinate or sequence them. And regenerating to show the consequence will fetch live IANA registries and move unrelated rows; #792 records the hand-edit-plus-prove-equivalence route around that.