Skip to content

refactor(protocols): a protocol class takes its module's name (igmpv1.IGMPv1, httpv1.HTTPv1) #2529

Closed

Description

@JarryShaw

Owner ruling (2026-11-01, in session), paraphrased: a protocol class is named after its module, whatever its canonical name and id(). So igmp.IGMP stays the base, and the members become igmpv1.IGMPv1, igmpv2.IGMPv2 and igmpv3.IGMPv3. IGMPv1's id() stays ('IGMP',).

Protocol modules on main whose class does not match (AST audit at c43cd1a33, schema/ and data/ excluded):

  • internet/igmpv1.py, igmpv2.py, igmpv3.py: IGMP → IGMPv1, IGMPv2, IGMPv3. These are new in 1.6.0, so the change is not breaking. Dispatched now.
  • application/httpv1.py, httpv2.py: HTTP → HTTPv1, HTTPv2. These shipped in 1.5.1, so the change is breaking for from pcapkit.protocols.application.httpv1 import HTTP. It is folded into refactor(application): use the RFC names HTTP/1 and HTTP/2 in HTTP's id()? #2524's PR, which already changes HTTP's id() and carries the breaking label.
  • misc/null.py: NoPayload.

Decisions needed:

  1. Does the rule cover misc/null.NoPayload? Options: (a) exempt it, since it is the no-payload sentinel rather than a protocol, and record the exception; (b) rename the module to nopayload.py; (c) rename the class to Null. Both (b) and (c) are breaking. Recommendation: (a).
  2. Do schema/ and data/ modules follow the same rule for classes named after a module? Recommendation: yes, in the same PRs.

The rule is written onto protocol-family-grouping.rst's No Invented Suffixes section as part of the IGMP change.

Activity

  1. added
    refactorRestructuring for its own sake — neither a fix nor a new capability (refactor: prefix)
    wipWork in flight - a covering PR is open or an agent is actively on it
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Nov 1, 2026
  2. JarryShaw commented on Nov 1, 2026

    @JarryShaw
    OwnerAuthor

    Q3 (owner, in session): move a module's second protocol class into its own module? This is the counterpart of the naming rule: one protocol class per module, named after it. An introspection audit of main lists every module that exports more than one protocol class:

    • link/arp.py: ARP, InARP (both shipped in 1.5.1) → link/inarp.py.
    • application/rarp.py: RARP, DRARP (both shipped in 1.5.1) → application/drarp.py.
    • application/tls.py: TLS, SSLv3 (new in 1.6.0) → application/sslv3.py.
    • protocols/protocol.py: Protocol, ProtocolBase. These are the framework bases, not dissectors.

    Options: (a) move all three and exempt protocol.py; (b) move only SSLv3 (not breaking); (c) leave them. Recommendation: (a). Under the #1715/#1103 ruling, InARP and DRARP move with no re-export at the old path. That makes it breaking, with ! in the subject and versionremoved:: 1.6.0 for the old paths; the top-level pcapkit.protocols names are unchanged. SSLv3 moves with no directive.

    Sequencing if (a): DRARP can go at once. InARP waits for #2490's link reorder of arp.py, and SSLv3 for the #2517/#2525 PR, which is editing tls.py.

  3. JarryShaw commented on Nov 1, 2026

    @JarryShaw
    OwnerAuthor

    Owner ruling on Q3 (in session), paraphrased: take (a). A module holds one protocol class, named after it, and the conventions record that. So InARP moves to link/inarp.py, DRARP to application/drarp.py and SSLv3 to application/sslv3.py, and protocol.py's framework bases are exempt. InARP and DRARP move with no re-export (breaking, !, versionremoved:: 1.6.0 for the old paths); SSLv3 moves with no directive.

    Reconciled: both rules go onto protocol-family-grouping.rst's No Invented Suffixes section in the IGMP rename PR. DRARP is dispatched now. InARP waits for #2490's link reorder of arp.py, and SSLv3 for the #2517/#2525 PR. Q1 (misc/null.NoPayload) and Q2 (schema/ and data/ modules) are still open, with the recommendations above unchanged.

  4. JarryShaw commented on Nov 1, 2026

    @JarryShaw
    OwnerAuthor

    Q2 - yes, schema and data should keep consistency with the main protocol layout.

    on a side note, i'm considering move from protocols.schema/data.<layer>.<protocol> and protocols.<layer>.<protocol> pairing to protocols.<layer>.<protocol>.schema/data/protocol groups. what's your opinion from a repo structure perspective? (if not considering path and API breaking changes)

  5. JarryShaw commented on Nov 1, 2026

    @JarryShaw
    OwnerAuthor

    Q2, owner ruling: yes. schema/ and data/ modules keep the same layout as the protocol modules, covering both the naming rule and one class per module. It applies to the IGMP rename (already in its scope), the DRARP, InARP and SSLv3 moves, and HTTP's renames on #2524. Q1 (NoPayload) is still open.

    On grouping by protocol (protocols/<layer>/<proto>/{protocol,schema,data}.py instead of three parallel trees), setting breaking changes aside, I'd do it:

    • The trees always change together. Every protocol added this wave (FRAD, NETLINK, GRE, IGMPv3, SSLv2, Radiotap) added a file to each of the three trees, each re-deriving the same <layer>/<proto> path.
    • Locality: one directory per protocol to add, review, document and test. It also makes the per-module naming rules local to that directory.
    • It is the usual shape elsewhere: Scapy and dpkt keep a protocol's fields with its packet class, and Wireshark has one dissector per protocol.

    Costs to plan for:

    1. Families that share a schema or data model (IGMP v1/v2 share one) need a rule. The shared piece would live in the family base's package, and members import it.
    2. Framework pieces (schema/schema.py, data/data.py, protocol.py, shared field types) stay in a core location.
    3. protocols.schema and protocols.data would become pure aggregations, which refactor!: remove every surviving re-export of a moved name or module #1744 allows, or go away.
    4. The churn falls on lazy ModuleDescriptor path strings, the docs tree and the aggregators. That is a codemod: best done as one change after this wave lands, piloted on one family to measure import cycles and the docs build.

    Naming under it: the package takes the protocol's name, its modules take their role, and each module holds the class named after the package. That is #2529's rule, restated per package.

  6. JarryShaw commented on Nov 1, 2026

    @JarryShaw
    OwnerAuthor

    yea, then let's do the move.

    on the costs side,

    1. shared piece live in the family's base's pacakge, and mebers import it
    2. yes, stay in a core location, maybe just the protocols.{protocol,data,schema} top level
    3. yes, no re-exports.
    4. taking that recommendation
  7. JarryShaw commented on Nov 1, 2026

    @JarryShaw
    OwnerAuthor

    Q1 - rename it, i think the new name should be no_payload.py

  8. JarryShaw commented on Nov 1, 2026

    @JarryShaw
    OwnerAuthor

    Owner rulings, paraphrased and reconciled:

    Every question on this issue is now answered. Still to do here: the IGMP rename (ready locally, held for the queue), the HTTP renames with #2524, the DRARP move (in progress), and the InARP and SSLv3 moves after their files free up.

  9. removed
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Nov 1, 2026
  10. JarryShaw commented on Nov 1, 2026

    @JarryShaw
    OwnerAuthor

    Owner ruling (in session), paraphrased: IGMP's info_name follows the class. A parsed message sits under igmpv1, igmpv2 or igmpv3 in its enclosing layer's data, as ICMPv4/v6, IPv4/v6 and LinuxSLL1/2 do. The IGMP rename commit (92fd4ca9f, held for the queue) already does that, and a test pins it, so nothing changes.

  11. JarryShaw commented on Nov 1, 2026

    @JarryShaw
    OwnerAuthor

    Q4, from the IGMP rename's review: how does Q2 read for schema/ and data/ modules? A schema module legitimately holds several classes, one per sub-structure: schema/internet/igmpv3.py has five. So "a module holds one protocol class" cannot apply to it literally.

    1. A schema/data module's top-level class takes the module's name, and its sub-structure classes share the module.
    2. One class per schema/data module, splitting sub-structures out.

    Recommendation: 1. It keeps each schema next to its parts, and matches what #2534's per-protocol packages will hold. The page will also note that the remaining exceptions (HTTP, InARP, SSLv3, NoPayload) are pending under this issue, so its present-tense rule is not read as already true everywhere.

  12. added
    needs: decisionWaiting on the maintainer to decide — not blocked by other work
    on Nov 1, 2026
  13. moved this to Needs decision in PyPCAPKiton Nov 1, 2026
  14. 11 remaining items

  15. JarryShaw commented on Nov 2, 2026

    @JarryShaw
    OwnerAuthor

    #2602 has merged, so SSLv3 lives in application/sslv3.py. HTTP (#2544) and InARP (#2596) had already moved. The one exception left on this issue is NoPayload. Per Q1 and Q4, misc/null.py becomes misc/no_payload.py, and its schema/ and data/ modules move with it, with no re-export.

    Blocked: that rename rewrites import paths and cross-references across much of the tree, and #2561's whole-repo citation sweep is still being written over the same files. The rename is scripted, so running it after #2561 merges costs nothing, while running it now would force both to rebase. It is dispatched as soon as #2561 merges.

  16. added
    blockedDeferred pending another issue or decision; see the last comment for what unblocks it
    and removed
    wipWork in flight - a covering PR is open or an agent is actively on it
    on Nov 2, 2026
  17. moved this from WIP to Blocked in PyPCAPKiton Nov 2, 2026
  18. JarryShaw commented on Nov 2, 2026

    @JarryShaw
    OwnerAuthor

    #2561 has merged as #2626. Unblocked. A worker is moving NoPayload and its schema and data modules from misc/null.py to misc/no_payload.py, with no re-export. The move is breaking, since all three shipped in v1.5.1. The rename is done by a script, so a conflicting rebase is resolved by re-running the script. Once it lands, protocol-family-grouping.rst's pending list is empty.

  19. added
    wipWork in flight - a covering PR is open or an agent is actively on it
    and removed
    blockedDeferred pending another issue or decision; see the last comment for what unblocks it
    on Nov 2, 2026
  20. moved this from Blocked to WIP in PyPCAPKiton Nov 2, 2026
  21. removed
    wipWork in flight - a covering PR is open or an agent is actively on it
    on Nov 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    refactorRestructuring for its own sake — neither a fix nor a new capability (refactor: prefix)

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions