You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
refactor(protocols)!: group each protocol's protocol, schema and data into one package #2534
Owner ruling on #2529 (2026-11-01), paraphrased: replace the three parallel trees (protocols/<layer>/<proto>.py, protocols/schema/<layer>/<proto>.py, protocols/data/<layer>/<proto>.py) with one package per protocol, protocols/<layer>/<proto>/{protocol,schema,data}.py.
Delivered as one codemod change after the current wave lands, piloted on one family first to measure import cycles and the docs build.
Pilot: the VLAN family (vlan, c_tag, s_tag), dispatched now as a local experiment, not a PR.
Blocked: the full move waits for the open PRs that touch pcapkit/protocols (#2528#2527#2523#2522#2521#2519#2509#2483) and the streams in flight. It unblocks when those have merged or closed.
Pilot done on the VLAN family (local f52b9808d, not for push). After the codemod and four kinds of hand edit, all 588 modules import cleanly, 36 test modules pass, and a nitpicky docs build adds no warnings. A dry run over the whole tree touches 56 packages, makes 142 file moves, rewrites 699 files and about 10k dotted references. The codemod is kept, ready for the real run. Decisions needed first:
Framework import cycle:protocol.py imports Raw's and NoPayload's schema/data at the top, and in the new layout those cycle back through misc into protocol.py. Options: (a) defer those imports; (b) keep Raw/NoPayload at the top level as framework; (c) make the layer __init__ files lazy. Recommendation: (a), measured in the full run.
The schema=/data= fallback in __init_subclass__ reads the aggregators that are going away. Only L2TP relies on it. Options: look in the class's own package for sibling schema/data modules, or make the keywords mandatory. Recommendation: sibling lookup.
The shared ipv6_option schema/data, used by HOPOPT and IPv6_Opts, goes into the family base's package: ipv6_ext's schema/data, per your ruling 1. Recommendation: that.
Framework paths:schema/schema.py → protocols/schema.py, data/data.py and data/protocol.py → protocols/data.py, and the layer bases stay at <layer>/<layer>.py. Recommendation: as listed.
Released changelogs: rewrite only ~ cross-reference targets, which leaves the rendered text unchanged and keeps the links resolving. Recommendation: yes.
Docs: keep one page per protocol at its current URL and add the package's .. module::, rather than a directory per package. Recommendation: keep the URLs.
(a): protocol.py defers its Raw/NoPayload schema and data imports.
Sibling lookup: __init_subclass__ finds schema/data in the class's own package, and an explicit schema=/data= class keyword still overrides it.
Yes: a package __init__ exports its class, so protocols.link.vlan.VLAN still resolves.
Yes: the shared ipv6_option schema and data go into ipv6_ext's package.
As listed: protocols/schema.py and protocols/data.py; layer bases stay at <layer>/<layer>.py.
Yes: released changelogs get only their ~ targets rewritten.
Keep the URLs: one page per protocol, with the protocol class first, then its schema, then its data.
Back to blocked: the codemod runs once no open PR or in-flight stream touches pcapkit/protocols.
Activity
JarryShaw commentedon Nov 1, 2026
Pilot done on the VLAN family (local
f52b9808d, not for push). After the codemod and four kinds of hand edit, all 588 modules import cleanly, 36 test modules pass, and a nitpicky docs build adds no warnings. A dry run over the whole tree touches 56 packages, makes 142 file moves, rewrites 699 files and about 10k dotted references. The codemod is kept, ready for the real run. Decisions needed first:protocol.pyimports Raw's and NoPayload's schema/data at the top, and in the new layout those cycle back throughmiscintoprotocol.py. Options: (a) defer those imports; (b) keep Raw/NoPayload at the top level as framework; (c) make the layer__init__files lazy. Recommendation: (a), measured in the full run.schema=/data=fallback in__init_subclass__reads the aggregators that are going away. Only L2TP relies on it. Options: look in the class's own package for siblingschema/datamodules, or make the keywords mandatory. Recommendation: sibling lookup.__init__export its class, so thatprotocols.link.vlan.VLANstill resolves? refactor!: remove every surviving re-export of a moved name or module #1744's D3 allows a package__init__to aggregate its own submodules. Recommendation: yes, which also makes most imports non-breaking.ipv6_optionschema/data, used by HOPOPT and IPv6_Opts, goes into the family base's package:ipv6_ext'sschema/data, per your ruling 1. Recommendation: that.schema/schema.py→protocols/schema.py,data/data.pyanddata/protocol.py→protocols/data.py, and the layer bases stay at<layer>/<layer>.py. Recommendation: as listed.~cross-reference targets, which leaves the rendered text unchanged and keeps the links resolving. Recommendation: yes... module::, rather than a directory per package. Recommendation: keep the URLs.JarryShaw commentedon Nov 1, 2026
JarryShaw commentedon Nov 1, 2026
Owner rulings on the pilot, paraphrased:
protocol.pydefers its Raw/NoPayload schema and data imports.__init_subclass__findsschema/datain the class's own package, and an explicitschema=/data=class keyword still overrides it.__init__exports its class, soprotocols.link.vlan.VLANstill resolves.ipv6_optionschema and data go intoipv6_ext's package.protocols/schema.pyandprotocols/data.py; layer bases stay at<layer>/<layer>.py.~targets rewritten.Back to
blocked: the codemod runs once no open PR or in-flight stream touchespcapkit/protocols.