Skip to content

fix(const): make every registry's register reject what its get rejects (#1816) - #1823

Merged
JarryShaw merged 1 commit into
mainfrom
fix/1816-register-validates-every-registry
Oct 16, 2026
Merged

JarryShaw merged 1 commit into
mainfrom
fix/1816-register-validates-every-registry

Conversation

@JarryShaw

@JarryShaw JarryShaw commented Oct 16, 2026 •

Copy link
Copy Markdown
Owner

Please follow the guide below

What is the purpose of your pull request?

Tick the commit type your subject line carries.

  • fix — corrects a defect
  • feat — adds a feature
  • perf — changes performance, not behaviour
  • refactor — changes neither behaviour nor performance
  • test — tests only
  • docs — documentation only
  • ci — workflows or build tooling
  • release — bumps the version or rolls up a distribution
  • chore — anything else

Description

Closes #1816, and widens the scope to every enum per your note on #1818. Before this PR, EnumRegistry.register called the _validate_value hook, but only AppType overrode it. So Hardware.register(70000, 'x') would mint a member that Hardware.get(70000) then returned.

  • Generators: each vendor template now emits a _validate_value override. It runs the same check the template already writes into _missing_ and raises EnumValueError with the same message.
    • The check is the crawler's FLAG, or the template's own range: 0-999 for StatusCode/ReturnCode, 0-9 for ResponseKind/GroupingInformation, str for the string-valued ones.
    • TLSKeyLabel and ExtensionHeader have no _missing_, so they get a type check and the 8-bit Next Header range (RFC 8200).
  • Const files: re-rendered offline through each crawler's own template. An AST comparison against main shows that only the override, its imports and two docstrings changed, with no member data touched.
  • Tests: a new test walks every registry at runtime. It checks that register raises if and only if get rejects, that the hook agrees with _missing_ on boundary values, and that no registered value is refused. It fails on main. The no-mint sweep now mints inside each registry's range.

Behaviour note: get(out_of_range, default) still returns default, but now also logs one CRITICAL EnumValueError and installs pcapkit's excepthooks; on main it was silent. The cause is that the hook raises a loud EnumValueError before get falls back to default, as #1818 already does for AppType. Measured: no parse path triggers it. Over the sample captures there are 0 hook rejections, and none of the library's registry .get() call sites passes a default or a value wider than its hook allows. A quiet=True error on the get path would remove the noise, as a follow-up if wanted.

Left alone:

  • In-range gap values that get rejects but register may mint, such as CauseCode(0). These are documented in registry-protocol.rst.
  • A pre-existing Command.get defect, filed separately.

Narrow runs, all passing:

  • tests/const: 341 passed.
  • tests/vendor: 142 passed.
  • tests/corekit: 620 passed, 16 skipped.
  • tests/project: 949 passed, 1 skipped.

@JarryShaw JarryShaw added fix Pull requests that fix a defect (fix: subject prefix) const Regenerated IANA or vendor constant tables; members keep their numeric values review: running A cross-review is in flight against the current head - no verdict yet labels Oct 16, 2026
@JarryShaw JarryShaw moved this to In review in PyPCAPKit Oct 16, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

Verdict: NEEDS CHANGES at 020f2a92b. A Sonnet cross-review (the author was Opus) confirmed the substance:

  • No member data changed. An AST diff of every changed const file against main is identical once imports, the new hooks and docstrings are set aside.
  • Every crawler, re-run against live IANA data, renders byte-identical to the committed file.
  • Every hook matches its _missing_ guard, and get is unchanged on boundary probes across all registries.
  • The suites still pass.

Required: registry-protocol.rst:83 says "Two registries have no _missing_", which is a count in prose. The review also showed that the judgement-laden hooks are pinned by no test: ExtensionHeader's 255 bound, TLSKeyLabel's str check, and the 0..9 bound on ResponseKind and GroupingInformation. A fix round is under way.

@JarryShaw JarryShaw added review: needs-changes Cross-review at the current head says changes are required; see the verdict comment and removed review: running A cross-review is in flight against the current head - no verdict yet labels Oct 16, 2026
#1816)

EnumRegistry.register routes a new value through _validate_value, but only
AppType overrode that hook, so Hardware.register(70000, 'x') minted a member
that Hardware.get(70000) then returned, although get refuses the value.

- Every vendor template emits a _validate_value override with the check it
  already writes at the top of _missing_, raising EnumValueError with the
  same message: the crawler's FLAG, or a bespoke template's own range (0-999
  for StatusCode and ReturnCode, 0-9 for ResponseKind and
  GroupingInformation, str for the string-valued ones). TLSKeyLabel and
  ExtensionHeader have no _missing_, so they check the member type and the
  8-bit Next Header field.
- Const files re-rendered offline through each crawler's own template with
  member data untouched; Method.get and OptionType.register docstrings follow.
- registry-protocol.rst and EnumLookup._validate_value say every registry
  overrides the hook; line citations the change shifts are re-pointed.
- A new test walks every registry at runtime and fails on main, and pins the
  bounds no FLAG gives; the no-mint sweep now mints inside each range.

Closes #1816
@JarryShaw
JarryShaw force-pushed the fix/1816-register-validates-every-registry branch from 020f2a9 to 5ca7d2d Compare October 16, 2026 14:34
@JarryShaw JarryShaw added review: running A cross-review is in flight against the current head - no verdict yet and removed review: needs-changes Cross-review at the current head says changes are required; see the verdict comment labels Oct 16, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

Verdict: GOOD TO GO at 5ca7d2db2. A Sonnet re-check (author: Opus) verified the fix round:

  • The count is gone.
  • All eleven mutations to the bounds and the return value now fail the new pin test.
  • No parse path triggers a hook rejection, measured on this head against b7488c621:
    • Across the generated sample captures, 7057 hook calls produced 0 rejections and 0 new CRITICAL records.
    • The tests/protocols, foundation, interface, integration and toolkit suites log identical CRITICAL records on both trees.
    • None of the library's registry .get() call sites passes a default or a value wider than its hook.
  • tests/const, tests/vendor and tests/project all pass.

The loud fallback for explicit out-of-range calls with a default is noted in the PR body.

@JarryShaw JarryShaw added review: good-to-go Cross-review at the current head says ready; CI state is separate and removed review: running A cross-review is in flight against the current head - no verdict yet labels Oct 16, 2026
@JarryShaw
JarryShaw merged commit dbc28bc into main Oct 16, 2026
55 checks passed
@github-project-automation github-project-automation Bot moved this from In review to Done in PyPCAPKit Oct 16, 2026
@JarryShaw
JarryShaw deleted the fix/1816-register-validates-every-registry branch October 16, 2026 15:02
@JarryShaw JarryShaw removed the review: good-to-go Cross-review at the current head says ready; CI state is separate label Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

const Regenerated IANA or vendor constant tables; members keep their numeric values fix Pull requests that fix a defect (fix: subject prefix)

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

fix(corekit): registries' register accepts values their get rejects

1 participant