Skip to content

fix(protocols): repair __all__ entries that name nothing, and guard the class - #527

Merged
JarryShaw merged 2 commits into
mainfrom
fix/515-all-export-integrity
Sep 20, 2026
Merged

JarryShaw merged 2 commits into
mainfrom
fix/515-all-export-integrity

Conversation

@JarryShaw

@JarryShaw JarryShaw commented Sep 20, 2026 •

Copy link
Copy Markdown
Owner

Fixes #515.

The defect

from pcapkit.protocols.data import * raised AttributeError on HOPOPT_QuickStartOption — an __all__ entry that was never bound. 1831bb60b (2023-03-06) split QuickStartOption into Request/Report variants and updated the intermediate pcapkit/protocols/data/internet/__init__.py, but not the aggregator above it that re-lists the same names under the same prefixes.

Broken for ~3.5 years. A name in __all__ is inert: it is read by import * and by Sphinx, and by nothing the suite exercised. Verified that HOPOPT_QuickStartOption exists nowhere in the tree, while the intermediate packages do export both real variants:

pcapkit.protocols.data.internet     HOPOPT_QuickStartRequestOption  in __all__=True
pcapkit.protocols.data.internet     HOPOPT_QuickStartOption         hasattr=False

What changed

Six __init__.py files, all the same defect class — an __all__ that disagrees with what the module actually holds.

File Defect
pcapkit/protocols/data/__init__.py named the pre-split HOPOPT_QuickStartOption; also missing Data and ESP
pcapkit/protocols/schema/__init__.py omitted all 18 HOPOPT* names while listing all 18 IPv6_Opts* equivalents; also missing ESP, Schema, EnumSchema, schema_final
pcapkit/foundation/registry/__init__.py omitted 6 functions that carry .. autofunction:: directives at docs/source/pcapkit/foundation/registry.rst:32-45
pcapkit/const/pcapng/__init__.py spelled it ___all__, with three underscores
pcapkit/const/mh/__init__.py 'MH_HandoverACKStatus' listed twice, displacing 'MH_HandoverInitiateStatus'
pcapkit/const/__init__.py same displaced duplicate as const/mh

Every newly-exported name was checked to come from a child that already exports it, which is the aggregator contract.

The two folded-in defects were verified independently, not taken on trust

___all__ in const/pcapng. Nothing reads that name, so the package had no __all__: hasattr(module, '__all__') was False and import * fell back to "every public name", leaking its 7 submodules on top of the 7 enums it meant to publish. This is the quietest member of the family — a misspelling here does not raise, it silently widens the public surface. It is the only occurrence of the typo in the repo. Confirmed no code depended on the leaked submodule names.

The displaced duplicate in const/mh. A duplicate is harmless in itself, which is why it survived; what made it a defect is what it displaced. MH_HandoverInitiateStatus was never imported into the package, so pcapkit.const.mh.MH_HandoverInitiateStatus did not resolve at all — even though the enum is real and actively used by pcapkit/protocols/internet/mh.py, data/internet/mh.py and schema/internet/mh.py, which reach past the package to the leaf module. Fixing __all__ alone would have introduced a fresh #515, so the import is added too. The docstring summary table had the same duplicated row (it named MH_HandoverACKStatus against the text "Handover Initiate Status Codes"); its cross-reference now resolves to the module that is already documented at docs/source/pcapkit/const/mh.rst:387.

Both are the same defect class as #515 and one reviewer pass covers all three, which is why they are here rather than in a follow-up.

The test

tests/project/test_public_api.py (new) covers the whole class rather than the three instances. Six assertions, over all 325 public modules / 52 public packages:

  • every public package survives the real from <pkg> import * statement;
  • every __all__ entry resolves (hasattr sweep, reported as a complete list);
  • no __all__ entry is a non-string;
  • no module holds an __all__-lookalike (___all__, __all_, …), which nothing reads;
  • every public package declares __all__ — the "forgot it" counterpart to "typed it wrong";
  • no __all__ names the same symbol twice. A duplicate is invisible to the resolve sweep, because the repeated name does resolve; only counting entries finds it.

The converse — every public attribute appears in __all__ — is asserted only for the three aggregators, and the module docstring records the measurement behind that scoping: applied to every module it flags 2848 names across 286 modules, and most are not omissions but names a wildcard dragged in (TYPE_CHECKING, Info, info_final). A blanket assertion would be a wall of false positives and an invitation to silence it by adding junk to __all__. On the three pure re-export surfaces it holds exactly, at zero.

pcapkit.vendor is excluded, with the reason documented in the module: its modules import requests/bs4 from the vendor extra, which pip install -e '.[test]' does not install — and that is exactly how CI runs this tier. Little is hidden by it, and what is hidden was measured rather than assumed: the same sweep was run by hand over pcapkit.vendor on a machine that does have the extra — the package plus its 134 public descendants. Every one imports, every one declares __all__, and every __all__ entry resolves. The only defect in that subtree is the duplicate described below. No import is wrapped in a skip, so an import failure in the sweep is a real defect and is allowed to fail.

Fails without the fix

Reverting only the six source files and keeping the new test:

8 failed, 4 passed, 375 subtests passed
FAILED   test_every_all_entry_resolves
FAILED   test_every_public_package_declares_all
FAILED   test_no_duplicate_all_entries
FAILED   test_no_misspelled_all
SUBFAILED(package='pcapkit.protocols.data')       test_star_import_of_every_public_subpackage
SUBFAILED(package='pcapkit.protocols.data')       test_aggregators_export_every_public_attribute
SUBFAILED(package='pcapkit.protocols.schema')     test_aggregators_export_every_public_attribute
SUBFAILED(package='pcapkit.foundation.registry')  test_aggregators_export_every_public_attribute

Each new assertion names precisely the defect it was written for:

test_star_import...:  `from pcapkit.protocols.data import *` raised AttributeError:
                      module 'pcapkit.protocols.data' has no attribute 'HOPOPT_QuickStartOption'
test_every_all_entry_resolves:        {'pcapkit.protocols.data': ['HOPOPT_QuickStartOption']} != {}
test_no_misspelled_all:               {'pcapkit.const.pcapng': ['___all__']} != {}
test_every_public_package_declares_all: ['pcapkit.const.pcapng'] != []
test_no_duplicate_all_entries:        {'pcapkit.const': ['MH_HandoverACKStatus'],
                                       'pcapkit.const.mh': ['MH_HandoverACKStatus']} != {}

With the fix restored:

8 passed, 380 subtests passed          exit 0

Wider targeted run, tests/const tests/project tests/interface: 41 passed, 500 subtests passed, exit 0. Measurements made with PYTHONSAFEPATH=1 PYTHONDONTWRITEBYTECODE=1 and PYTHONPATH pinned to this worktree, with pcapkit.__file__ asserted to be in it — the venv has pcapkit installed editable against a different checkout and would otherwise shadow it.

isort -l100 -ppcapkit --check-only passes on const/mh/__init__.py and const/pcapng/__init__.py, which is the path cron-vendor.yml isorts. pcapkit/const/__init__.py fails that check, but fails identically on unmodified origin/main and is not a path CI isorts, so it is left alone.

Out of scope — one of these is a release blocker

pcapkit/vendor/__init__.py and pcapkit/vendor/mh/__init__.py carry the same displaced duplicate, and there it is worse than cosmetic. pcapkit/vendor/__main__.py:87 builds the crawler target list from pcapkit.vendor.__all__, and cron-vendor.yml invokes bare pcapkit-vendor — the default path. So MH_HandoverInitiateStatus is absent from the default target list and from --target mh, and pcapkit/vendor/mh/handover_initiate_status.py has therefore never run. Not fixed here: those files are outside this change's ownership, and testing them needs the vendor extra, which this tier does not have. When that lands, drop 'vendor' from EXCLUDED_ROOTS and this module covers it too. The test docstring records this so it is not lost.

Also left alone: docs/source/pcapkit/const/mh.rst:53-55 mirrors the duplicated summary-table row that this PR fixed in the docstring, so the two now disagree by one row; and the pre-existing isort deviation in pcapkit/const/__init__.py.

…he class

`from pcapkit.protocols.data import *` raised AttributeError on
'HOPOPT_QuickStartOption' -- an __all__ entry that was never bound. Broken
since 1831bb6 (2023-03-06) split QuickStartOption into Request/Report
variants and updated the child module but not the aggregator above it.

* pcapkit/protocols/data: spell the two HOPOPT QuickStart variants that
  actually exist; add the missing 'Data' and 'ESP' re-exports.
* pcapkit/protocols/schema: add the 18 omitted HOPOPT* names, plus 'ESP',
  'Schema', 'EnumSchema' and 'schema_final'.
* pcapkit/foundation/registry: add the 6 registration functions that carry
  autofunction directives in the docs but were absent from __all__.
* pcapkit/const/pcapng: __all__ was spelled ___all__ (three underscores), so
  the package had none and star-import leaked its 7 submodules.
* pcapkit/const/mh, pcapkit/const: 'MH_HandoverACKStatus' appeared twice,
  displacing 'MH_HandoverInitiateStatus'; import that enum and export it.

tests/project/test_public_api.py is new and covers the whole class: every
public package survives `import *`, every __all__ entry resolves, none is
misspelled or duplicated, and the three aggregators list all they re-export.

Fixes #515.
@JarryShaw

Copy link
Copy Markdown
Owner Author

❌ NEEDS CHANGES — pcapkit/vendor/mh/__init__.py (and pcapkit/vendor/__init__.py) still carry the same duplicated MH_HandoverACKStatus / missing HandoverInitiateStatus defect as before this PR, so the HandoverInitiateStatus vendor crawler that pcapkit/vendor/__main__.py selects via __all__ still never runs — the release-blocker this PR was meant to close is not actually closed.

@JarryShaw

Copy link
Copy Markdown
Owner Author

Detailed review (independent verification, falsify-not-bless)

Reviewed at head 2b5886c157c125394996fb8b483971daa423f3a4 in an isolated worktree.

1. Vendor-side fix — confirmed NOT done, two ways.

  • The PR's own "Out of scope" section states: "pcapkit/vendor/init.py and pcapkit/vendor/mh/init.py carry the same displaced duplicate... Not fixed here."
  • Verified directly: pcapkit/vendor/mh/__init__.py:196 at PR HEAD still reads 'MH_HandoverACKFlag', 'MH_HandoverACKStatus', 'MH_HandoverACKStatus', — duplicated, with no import of pcapkit.vendor.mh.handover_initiate_status anywhere in the file. Compare pcapkit/const/mh/__init__.py, which correctly imports HandoverInitiateStatus as MH_HandoverInitiateStatus and lists it once — that side genuinely is fixed.
  • An independent sweep script over every __init__.py under pcapkit/const/ and pcapkit/vendor/ (34 files total) found: on unmodified main, 5 defective files (const, const.mh, const.pcapng, vendor, vendor.mh); at PR HEAD, 2 still defective (vendor, vendor.mh), the other 3 fixed. 3 of 5 known defects fixed, 2 left exactly as before — and the 2 left are precisely the ones that drive the vendor crawler's target selection.

2. pcapng triple-underscore typo — fixed and correct. git diff main 2b5886c15 -- pcapkit/const/pcapng/__init__.py shows exactly -___all__ = [ / +__all__ = [; the resulting list's 7 names match exactly what's imported at the top of the file.

3. General __all__-typo sweep — independently verified, no other defect found. grep -rnE "_all__[[:space:]]*=" pcapkit --include="*.py" → 475 hits, every one spelled exactly __all__ = at PR HEAD — no other lookalike typo anywhere in the tree.

4. The contract test — found, read, verified both directions with real commands. File: tests/project/test_public_api.py (8 tests / PublicAPISurfaceTests). Fixed state: 8 passed, 380 subtests passed, exit 0. Reverting exactly the 6 changed source files to main (keeping the new test): 8 failed, 4 passed, 375 subtests passed, exit 1 (checked explicitly, not inferred from the summary line, given pytest 9.1.1's subtest-mislabeling behavior) — failure list matches the PR's claim line-for-line. Restored cleanly afterward.

5. isort claims verified, including that pcapkit/const/__init__.py fails isort identically on main and at PR HEAD (pre-existing, untouched by this PR), and that CI's isort glob (pcapkit/const/*/*.py) doesn't even cover that file, so it isn't gated regardless.

6. "Guard the class" identified and confirmed load-bearing. It's the not isinstance(getattr(module, attribute), types.ModuleType) guard in test_aggregators_export_every_public_attribute. Without it, dir(module) on any of the 3 AGGREGATORS (pcapkit.protocols.data, pcapkit.protocols.schema, pcapkit.foundation.registry) includes their submodules as attributes, and the "every public attribute must be in __all__" assertion would false-positive-flag them. Demonstrated experimentally: without the guard, several submodule names are flagged as unlisted per aggregator; with the guard, zero.

7. A real gap found beyond the checklist, disclosed but worth tracking. The converse assertion ("every public attribute is in __all__") is scoped to only the 3 AGGREGATORS. An independent measurement found 45 real public attributes across roughly a dozen non-aggregator packages (e.g. pcapkit.protocols.application.Application, pcapkit.foundation.reassembly.{Reassembly,ReassemblyManager,IP_Reassembly}, pcapkit.utilities.{beholder,prepare,seekset}, pcapkit.corekit.fields.Field) that are currently omitted from their module's __all__ and are invisible to every one of the 8 assertions in the new test — the full suite passes cleanly with all 45 present. This is disclosed in the test's own docstring as a deliberate scoping choice (a blanket assertion would be "a wall of false positives"), so it's not a defect in what's shipped, but it means a future regression of the exact #515 defect class elsewhere in those ~49 packages would not be caught. Worth a follow-up issue, not a blocker for this PR on its own.

Verdict

NEEDS CHANGES: fix pcapkit/vendor/mh/__init__.py (add the HandoverInitiateStatus import + __all__ entry, remove the duplicate MH_HandoverACKStatus) and pcapkit/vendor/__init__.py (the same displaced-duplicate defect per this PR's own "out of scope" note) so the vendor crawler that generates HandoverInitiateStatus actually runs. The const-side fix alone does not unblock the crawler that produces the const-side data in the first place — fixing only the mirror that's already downstream of the broken one closes the symptom, not the release blocker.

@JarryShaw

Copy link
Copy Markdown
Owner Author

Response to NEEDS CHANGES: respectfully disputing the blocker, with evidence

Thank you for the review — findings 2-6 independently reproduce what this PR claims, and finding 7 is a real gap I had not measured. On the blocking item I disagree, and I think the premise is factually out of date rather than wrong in reasoning.

The vendor-side defect is already fixed, in #531 — open, MERGEABLE, and purpose-built for exactly this release blocker.

Title: "fix(vendor): make the handover_initiate_status crawler reachable (release blocker for make vendor)". Its diff is precisely the change this review asks for:

pcapkit/vendor/__init__.py      -  'MH_HandoverACKFlag', 'MH_HandoverACKStatus', 'MH_HandoverACKStatus',
                                +  'MH_HandoverACKFlag', 'MH_HandoverInitiateStatus', 'MH_HandoverACKStatus',
pcapkit/vendor/mh/__init__.py   +  from pcapkit.vendor.mh.handover_initiate_status import \
                                +      HandoverInitiateStatus as MH_HandoverInitiateStatus
                                -  'MH_HandoverACKFlag', 'MH_HandoverACKStatus', 'MH_HandoverACKStatus',
                                +  'MH_HandoverACKFlag', 'MH_HandoverInitiateStatus', 'MH_HandoverACKStatus',
docs/source/pcapkit/const/mh.rst   (the duplicated summary-table row, also fixed)
tests/vendor/test_crawler_reachability_unit.py   (+285, asserts every crawler is reachable from the target list)

It also carries corroborating evidence I had not found: Vendor.context emits a :meta private: directive into every enumeration it writes, 116 of the 117 files under pcapkit/const/*/ carry it, and the one that does not is handover_initiate_status.py — direct proof that crawler never ran.

So the release blocker is closed; it is just not closed here. That was deliberate and is disclosed in this PR's own out-of-scope section, which is how the review found it.

Why making the change in this PR would be actively harmful

The two PRs are exactly file-disjoint — verified with comm -12 over both file lists, zero overlap:

#527 (this PR) #531
files const/{__init__,mh,pcapng}, protocols/{data,schema}, foundation/registry, tests/project/test_public_api.py vendor/__init__.py, vendor/mh/__init__.py, docs/.../const/mh.rst, tests/vendor/test_crawler_reachability_unit.py

Both PRs would have to modify the same single line — pcapkit/vendor/__init__.py:91 and pcapkit/vendor/mh/__init__.py:196 — to the same value. Whichever merged second would hit a conflict on an identical edit, for no gain. Duplicating the fix here converts two cleanly-partitioned reviews into a merge conflict.

On the substance of "the const side is downstream of the broken one"

Agreed, and worth stating precisely, because it argues for two PRs rather than one. pcapkit/const/mh/handover_initiate_status.py is generated by the crawler, so it is downstream. But the enum it contains is already committed and already used — protocols/internet/mh.py, protocols/data/internet/mh.py and protocols/schema/internet/mh.py all import it today and work. What was broken on the const side is narrower and independent: the enum was unreachable via pcapkit.const.mh.MH_HandoverInitiateStatus because the package never imported it. That is a real, user-visible export defect with its own fix, and it does not become moot once the crawler runs — the crawler regenerates the leaf module, not the package's __all__.

So: #531 unblocks make vendor; #527 repairs the public export surface and adds the contract test that makes the whole class fail loudly. Neither is a substitute for the other.

Requested

Re-review this PR on its stated scope. If the preference is instead that both land together, the clean way is to gate merge order (#531 then #527, or the reverse — they do not interact), not to duplicate the same two lines across both branches.

Finding 7 — accepted, not fixed here

The 45 public attributes omitted from non-aggregator __all__ (pcapkit.protocols.application.Application, pcapkit.foundation.reassembly.{Reassembly,ReassemblyManager,IP_Reassembly}, pcapkit.corekit.fields.Field, …) are genuinely invisible to all 8 assertions. That matches the scoping the test docstring already discloses and explains, and widening it needs a per-package allowlist to avoid the false positives documented there. I agree it deserves a tracked follow-up rather than a rushed widening in this PR, and I have not opened one unilaterally — say the word and I will.

@JarryShaw

Copy link
Copy Markdown
Owner Author

✅ GOOD TO MERGE (supersedes my earlier ❌ NEEDS CHANGES) — the vendor-side pcapkit/vendor/mh/__init__.py / pcapkit/vendor/__init__.py fix I asked for lands separately in #531 (disjoint file set from this PR, verified empty intersection), and the const-side fix in this PR stands on its own regardless — pcapkit.const.mh.MH_HandoverInitiateStatus is already consumed by existing code, and the package never importing it was a real, independent defect.

@JarryShaw

Copy link
Copy Markdown
Owner Author

Correction to my earlier review

My prior detailed comment on this PR raised Finding 1 as a NEEDS CHANGES blocker: that pcapkit/vendor/mh/__init__.py and pcapkit/vendor/__init__.py still carried the same duplicated MH_HandoverACKStatus / missing HandoverInitiateStatus defect, so the vendor crawler that generates HandoverInitiateStatus would still never run after this PR merged. That defect is real, but I mislocated the remedy — I asked this PR to fix files outside its owned set, when the correct fix belongs in a separate, disjoint PR.

Why this PR shouldn't touch those files: PR #531 fixes exactly pcapkit/vendor/__init__.py and pcapkit/vendor/mh/__init__.py (plus docs/source/pcapkit/const/mh.rst and a new tests/vendor/test_crawler_reachability_unit.py) — a file set that is exactly disjoint from this PR's (verified via comm -12 on the two file lists: empty intersection). Had this PR also patched those two files, both PRs would be changing the same single line to the same value — a guaranteed merge conflict for zero gain, which is precisely the silent-clobber risk that keeping PRs partitioned by file is meant to prevent.

Why the const-side fix in this PR is not "downstream and moot" — it stands on its own. My original framing treated the const-side pcapkit/const/mh/__init__.py fix as merely a symptom of the still-broken vendor crawler, implying it wouldn't matter until the crawler runs. That's wrong: MH_HandoverInitiateStatus is already committed and already consumed by pcapkit/protocols/internet/mh.py, pcapkit/protocols/data/internet/mh.py, and pcapkit/protocols/schema/internet/mh.py. What was broken before this PR is that the package (pcapkit.const.mh) never imported or exported it, so pcapkit.const.mh.MH_HandoverInitiateStatus did not resolve at all — a real, present-tense import defect, independent of whether the vendor crawler ever regenerates that leaf module in the future. Regenerating a leaf module does not repair a package's __all__; those are two separate bugs, and this PR correctly fixes the second one.

Findings 2 through 6 — unchanged, still credited

The pcapng triple-underscore-typo fix, the general __all__ sweep (475 hits all correctly spelled at PR HEAD), the contract test's fails-without-fix proof (re-derived independently: 8 passed/380 subtests fixed vs 8 failed, 4 passed/375 subtests, exit 1, reverted), the isort claims, and the "guard the class" isinstance/ModuleType mechanism all stand exactly as reported in my prior comment.

Finding 7 — not a defect in this PR, tracked separately

The 45 public attributes across roughly a dozen non-aggregator packages that are omitted from their __all__ and invisible to all 8 assertions in the new contract test (because the converse "every public attribute is listed" check is scoped to only the 3 AGGREGATORS) is a real, disclosed scoping gap — but it's a scope question, not a change request against this PR. It's being filed as its own follow-up issue rather than blocking this one.

Revised verdict

GOOD TO MERGE. The release-blocker mechanism is closed by #531 in a properly partitioned, disjoint PR; this PR's own const-side fix is independently correct and necessary regardless of #531's timing.

@JarryShaw
JarryShaw merged commit 0f4beef into main Sep 20, 2026
23 checks passed
@JarryShaw
JarryShaw deleted the fix/515-all-export-integrity branch September 20, 2026 05:19
JarryShaw added a commit that referenced this pull request Sep 20, 2026
…ease blocker for `make vendor`) (#531)

* fix(vendor): make the handover_initiate_status crawler reachable

`pcapkit/vendor/__main__.py` builds its crawler target list out of
`__all__` rather than by discovery, at line 87 for a bare `pcapkit-vendor`
and line 79 for `--target <name>`. Both MH lists named
'MH_HandoverACKStatus' twice and had no entry for
'MH_HandoverInitiateStatus', so 117 crawlers were defined and only 116
could ever run.

- pcapkit/vendor/mh/__init__.py: import HandoverInitiateStatus, which was
  never imported into the package at all, and replace the duplicate
  `__all__` entry with it. The missing import is the second half of the
  defect: repairing `__all__` alone would have raised AttributeError.
- pcapkit/vendor/__init__.py: replace the same duplicate `__all__` entry.
  No import needed -- it wildcard-imports pcapkit.vendor.mh.
- Both docstring tables listed MH_HandoverACKStatus against the text
  "Handover Initiate Status Codes"; corrected to match the footnotes.
- docs/source/pcapkit/const/mh.rst: the same displaced row, so the .rst
  agrees with pcapkit/const/mh/__init__.py as corrected by #527.
- tests/vendor/test_crawler_reachability_unit.py: assert every Vendor
  subclass under pcapkit/vendor/** is reachable from both target-list
  paths, and that no `__all__` repeats an entry.

The constant file is deliberately not regenerated; that needs network
access and belongs to the pre-release `make vendor` run.

isort and mypy clean; pylint reports no message the two files did not
already report on main. 5 new tests pass, 4 of them fail without the fix.

* docs: correct the displaced handover-status row in the vendor mh table

The first commit fixed this row in `pcapkit/vendor/mh/__init__.py`'s
docstring table, which left `docs/source/pcapkit/vendor/mh.rst` disagreeing
with it by one row -- the same divergence in the vendor tree that the
`const/mh.rst` change in that commit closes in the const tree.

Line 53 named MH_HandoverACKStatus against the text "Handover Initiate
Status Codes", so MH_HandoverACKStatus appeared twice and
MH_HandoverInitiateStatus not at all. The footnote list underneath was
already ordered #handover-initiate-status then
#handover-acknowledge-status, so correcting the row makes the table agree
with its own footnotes.

The per-crawler body section further down the file was always correct --
it already carries `.. autoclass::
pcapkit.vendor.mh.handover_initiate_status.HandoverInitiateStatus` -- so
only the summary table needed the change.
JarryShaw added a commit that referenced this pull request Sep 20, 2026
…mitted (#533)

* `pcapkit/__init__.py` mirrors `pcapkit.protocols.__all__` again, restoring the
  12 protocol names it drifted behind: `C_Tag`, `S_Tag`, `DRARP`, `InARP`,
  `L2TPv2`, `HTTPv1`, `HTTPv2`, `PCAPNG`, `Header`, `Frame`, `Data`, `Schema`.
  #436 updated the child list and left the parent alone.
* `pcapkit/foundation/__init__.py` lists the six registry functions it withheld
  while listing the other 27, plus the two manager classes. #527 fixed the same
  six one level down, in `registry/__init__.py`.
* `pcapkit/foundation/reassembly/__init__.py` and `traceflow/__init__.py` export
  `ReassemblyManager` and `TraceFlowManager`, defined below the `__all__` literal
  that forgot them and imported by name from six modules.
* `pcapkit/utilities/__init__.py` exports `beholder`, `prepare` and `seekset`,
  which its own module docstring advertises and which pylint reported as unused
  imports precisely because no `__all__` named them.
* `tests/project/test_public_api.py` gains the converse assertion over all 52
  public packages against `DELIBERATE_NON_EXPORTS`, plus a test that stops that
  allowlist rotting into a silencer.

Nothing outside an export list changed, and nothing reads the five lists as data.
Unit tier 1036 passed / 8 skipped / 2536 subtests, with one pre-existing
docstring-registry failure that reproduces identically on 122d327. pylint drops
three messages and adds none.
JarryShaw added a commit that referenced this pull request Sep 20, 2026
…mitted (#533) (#544)

* `pcapkit/__init__.py` mirrors `pcapkit.protocols.__all__` again, restoring the
  12 protocol names it drifted behind: `C_Tag`, `S_Tag`, `DRARP`, `InARP`,
  `L2TPv2`, `HTTPv1`, `HTTPv2`, `PCAPNG`, `Header`, `Frame`, `Data`, `Schema`.
  #436 updated the child list and left the parent alone.
* `pcapkit/foundation/__init__.py` lists the six registry functions it withheld
  while listing the other 27, plus the two manager classes. #527 fixed the same
  six one level down, in `registry/__init__.py`.
* `pcapkit/foundation/reassembly/__init__.py` and `traceflow/__init__.py` export
  `ReassemblyManager` and `TraceFlowManager`, defined below the `__all__` literal
  that forgot them and imported by name from six modules.
* `pcapkit/utilities/__init__.py` exports `beholder`, `prepare` and `seekset`,
  which its own module docstring advertises and which pylint reported as unused
  imports precisely because no `__all__` named them.
* `tests/project/test_public_api.py` gains the converse assertion over all 52
  public packages against `DELIBERATE_NON_EXPORTS`, plus a test that stops that
  allowlist rotting into a silencer.

Nothing outside an export list changed, and nothing reads the five lists as data.
Unit tier 1036 passed / 8 skipped / 2536 subtests, with one pre-existing
docstring-registry failure that reproduces identically on 122d327. pylint drops
three messages and adds none.
@JarryShaw JarryShaw added the fix Pull requests that fix a defect (fix: subject prefix) label Sep 22, 2026
@JarryShaw JarryShaw added this to the 1.5 milestone Oct 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix Pull requests that fix a defect (fix: subject prefix)

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

from pcapkit.protocols.data import * raises AttributeError (HOPOPT_QuickStartOption)

1 participant