Repository navigation
fix(protocols): a next-layer hit resolves its descriptor instead of memoising the class (#1559) - #1561
Merged
Conversation
…emoising the class (#1559) ProtocolBase._lookup_next_layer wrote the class a registered ModuleDescriptor resolved to back over the descriptor. After importlib.reload of the module, dispatch kept reaching the pre-reload class; parsing mutated registries shared by the whole process; and whether re-registering a shipped code warned depended on what had been parsed. - Every lookup now resolves through ModuleDescriptor.klass, which reads sys.modules, and nothing is written back. The docstring, which already said a memo would go stale, now matches the code. - Prose describing the write-back is corrected: the ethernet schema callback, ModuleDescriptor.klass (count re-measured), two test docstrings, and the 1.5.0 changelog entry, with CHANGELOG.md regenerated. - Six assertions that pinned the write-back now check the entry stays a ModuleDescriptor; test_layer_placement_unit drops the isolation it needed only because of it; a new test covers reload, registry immutability and the register warning. Cost: ~150 ns per hit, ~0.1% of extract() on http.pcap; not measurable in wall clock. Narrow test selections and the protocols unittest leg pass.
JarryShaw
force-pushed
the
fix/1559-next-layer-reload-stale
branch
from
October 10, 2026 04:01
2b075ca to
6c135cd
Compare
Owner
Author
|
Verdict: GOOD TO GO at
Non-blocking nits:
|
Contributor
|
Coverage: 90.02% (unit tier, Python 3.14,
Per-file detail: the |
5 of 13 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Please follow the guide below
You will be asked some questions, please read them carefully and answer honestly
Put an
xinto all the boxes [ ] relevant to your pull request (like that [x])Use Preview tab to see how your pull request will actually look like
Searched for similar pull requests
Followed the coding style (
make pylint,make mypy,make isort)make testpasses, and a test case covers the changeAdded a changelog entry under
docs/source/changelog/and regeneratedCHANGELOG.md, if the change is user-visible — N/A — centralised in docs(changelog): shared 1.5.0 changelog — long-lived, merges last (#610, #616, #617, #618, #620) #657What is the purpose of your pull request?
Tick the commit type your subject line carries.
fix— corrects a defectfeat— adds a featureperf— changes performance, not behaviourrefactor— changes neither behaviour nor performancetest— tests onlydocs— documentation onlyci— workflows or build toolingrelease— bumps the version or rolls up a distributionchore— anything elseDescription of your pull request and other information
Closes #1559.
ProtocolBase._lookup_next_layer(pcapkit/protocols/protocol.py:2183-2184) wrote the resolved class over a registeredModuleDescriptor. The fix resolves throughModuleDescriptor.klass, which readssys.modules, on every lookup and writes nothing back, as the docstring already said it should. Six assertions that pinned the write-back now check the entry stays a descriptor. All six, plus the new tests, fail with the fix reverted.Cost: a hit went from ~145 ns to ~294 ns.
http.pcapresolves 4695 descriptors perextract(), about 0.7 ms on ~700 ms (0.1%). Interleaved wall-clock medians (main → fix):http.pcap704.6 → 705.1 ms over 18 runs;tcp,ipv6,many_interfacesandtest.pcapstayed within ±1%.Behaviour change:
Internet.register(TransType.UDP, UDP)used to warn "already registered" before any parse but not after a parse had reached UDP. It now warns both times. Pinned bytest_registering_a_dispatched_code_warns_alike_before_and_after_a_parse.Prose corrected: the docstrings in
schema/link/ethernet.pyandcorekit/module.py(the count is re-measured: 296 resolutions onmany_interfaces.pcapng, 48 of them fallbacks),test_dispatch_default_resolution_unit.py, and the 1.5.0 changelog entry, withCHANGELOG.mdregenerated.test_layer_placement_unit.pydropsisolate_modules(self), which only the write-back needed. Run last after its class's other tests, the test passes under pytest and plain unittest, and fails on main'sprotocol.py.Known follow-ups, not fixed here: the same reload staleness exists at
pcapkit/foundation/extraction.py:1354-1461(__reassembly__/__traceflow__/__output__write-backs),pcapkit/protocols/protocol.py:986andpcapkit/protocols/misc/pcapng.py:1027-1035(register-time resolution).