fix(corekit): stop EnumRegistry.get's default from minting - #868
Conversation
|
NEEDS CHANGES on
#584's promise survives intact — a registered default still resolves. What changes is exactly the two things the ruling named as its cost: an unresolvable default now raises the original key's error rather than one naming the default, and a default in a declared-but-unassigned range ( Two Scope extended to Note the 5 other |
|
The 6 red marks here are two causes, not one — recording the split so the author's remaining work is not confused with inherited breakage. #868's own, the 5 already under #866's, inherited from So Note the last of #868's five is in |
7aff71f to
1607126
Compare
|
NEEDS CHANGES on
A prediction of mine was wrong, and it matters here. On #864 I wrote that It becomes true of the Also inapplicable, and my earlier verification was of the wrong proposition: the hazard paragraph cites Confirmed alongside: option 1 implemented and nothing more (both
One non-blocking nit: |
|
Unblocked — #867 merged at 00:10:35Z as Verified on merged So the |
Both `get`'s `cls(default)` sites -- the `str` branch's and the value branch's -- reached `_missing_` for a `default` that fell inside a still-minting registry's own range, growing the registry as a side effect of resolving `default` rather than `key`. - Replace both `cls(default)` calls with a plain `_value2member_map_` lookup (owner's ruling, option 1): `default` can no longer mint by construction, and a `default` naming no registered member now falls through to the same lookup error `key` itself would have raised. - `key` resolution is unchanged: `EtherType.get(0x0888)` still mints `Xyplex_0x0888` through `_missing_`, per the ruling's own exception -- landing in both lookup tables, exactly as `register` would leave it, since that is #775's own deliberately-kept-minting exception, not something `get` itself does. - Update the docstring's "It never mints" caveat (now qualified: true for `default`, not for `key` on the three still-minting registries), the now-false claim that an unregistered default still reaches `cls(default)`, and the Args/Raises text to match. - Add `GetDefaultNoMintTests` pinning the issue's own repro, the preserved key-path mint, default resolving to a registered value (int and str), and the exception type per path. Update two `NoDefaultSentinelTests` assertions that asserted the old `cls(default)` failure mode for an unregistered `-1`/`-1.0` default -- their docstrings now say plainly that they coincidentally pass on the pre-#857 tree too, and point at the test that still discriminates it. - Update four assertions in `test_const_enum_get.py` and `test_const_enum_builtin_parity.py` that encoded the superseded contract (an unresolvable/unregistered default failing with its own named error, or resolving into a declared-but-unassigned range) -- each retargeted to the new contract rather than weakened. The FilterType test's three dropped resolve/identity assertions are restored through its unaffected `key` path and the method renamed to match; it and its comment cross-reference are updated together. Owner's rulings, verbatim: - "Take (b). Only register can mint. get should not mint unless it falls through the _missing_'s minted ranges." - Choosing option 1 of three proposed: "I think 1 is correct mechanism we'd like." Build/tests, under plain unittest, methods not subTest records: test_const_registry_protocol.py 74/74, test_const_enum_get.py 8/8, test_const_enum_builtin_parity.py 33/33, tests/vendor/ 86/86 -- no regressions. tests/const/ as a whole carries 6 records: 3 methods inherited from #866 (fixed in #867) plus 1 further out-of-scope failure in test_const_enum_no_mint.py (contended with #865, handed over rather than edited here).
61a68ed to
8cb69d2
Compare
|
Round 3 pushed — head All three items applied, verified by me at the pushed sha:
One side effect to flag, because it is the opposite of what I did on #865. The remote branch had picked up a merge commit ( Counts, methods not subTest records: Label back to |
|
GOOD TO GO on The round-3 The exhaustiveness claim I asked about holds, and I reproduced it independently on merged Same three by a second method — measured Both round-2 findings properly taken. The pre-#857 docstrings now lead with the true fact and state plainly "This test no longer discriminates that defect", naming the pin — verified accurate in all three parts: The Counts as methods: 74 / 8 / 33 / 92 (
|
…ertion tests/const/test_const_enum_no_mint.py's GetNoLongerMintsTests.test_unresolvable_string_key_with_default_in_unassigned_range was contended with #865 (both touched pcapkit/corekit/enum.py-adjacent const/vendor territory) and deferred to this follow-up commit; #865 has now merged, so it lands here rather than being applied separately. Hardware.get('Definitely-Not-A-Member', 40) used to resolve 40 -- a value in Hardware's declared-but-unassigned 39-255 range, not a registered member -- via cls(default) -> _missing_ to an unregistered pseudo-member. #864 restricts default to a plain _value2member_map_ lookup, so it no longer resolves: the original KeyError for the key propagates instead, exactly the accepted cost the owner's ruling names. Re-measured fresh on the current tree (after #866/#867 and #862/#865 both landed): Hardware.get('Definitely-Not-A-Member', 40) raises KeyError: 'Definitely-Not-A-Member', members unchanged at 42 before and after. Checked for overlap with #865's own additions to this file (ETHERTYPE_UNASSIGNED_PROBES, EtherTypeMixedMintTests, the retired test_masked_old_xerox_row_converts_by_source) -- none: those are all EtherType key-path minting-order probes, unrelated to Hardware's default-path resolution this test covers. GetNoLongerMintsTests remains the right class.
|
Round 4 added the one test that #865's merge un-contended: result = Hardware.get('Definitely-Not-A-Member', 40)
self.assertEqual(result.value, 40)to asserting Why the verdict carries without a fifth review round, verified by me:
The author measured On the redundancy question I asked: no collision with #865's work.
Note the branch carries three commits (the fix, a |
isort/pylintclean onpcapkit/corekit/enum.py;mypyshows one pre-existing, unrelated error there -- confirmed identical on unmodifiedmain)make testpasses, and a test case covers the changeWhat is the purpose of your pull request?
fix— corrects a defectDescription of your pull request and other information
Fixes #864.
EnumRegistry.get's docstring claimed "It never mints", but bothcls(default)sites reached_missing_for adefaultthat fell inside astill-minting registry's own range, growing the registry as a side effect of
resolving
defaultrather thankey.Owner's rulings, verbatim:
("1" of three proposed implementation options:
defaultresolves through aplain
_value2member_map_lookup only, nevercls(default).)Both
cls(default)sites are replaced accordingly.keyresolution isunchanged:
EtherType.get(0x0888)still mintsXyplex_0x0888through itsown
_missing_, exactly as the ruling permits -- landing in both lookuptables, exactly as
registerwould leave it, since that is #775's owndeliberately-kept-minting exception rather than something
getitselfdoes. A
defaultnaming no registered member now falls through to thesame lookup error
keyitself would have raised, rather than a fresh errorabout the default -- the accepted cost the ruling names explicitly.
Docstring updated to match: "It never mints" is now qualified (true for
default;keymay still mint on the three still-minting registries), theparagraph claiming an unregistered default "can mint there just the same"
is corrected, and Args/Raises reflect the new propagation.
New
GetDefaultNoMintTestspins the issue's own repro on the real shippedEtherTyperegistry (with member count asserted unchanged), the preservedkey-path mint as a no-change guard, default resolving to a registered value
on both an
intand astrregistry, and the exception type per path. TwoNoDefaultSentinelTestsassertions that encoded the oldcls(default)failure mode for an unregistered
-1/-1.0default are retargeted to thenew contract, with docstrings noting they now coincidentally pass on the
pre-#857 tree too and pointing at the test that still discriminates that
defect (
test_no_default_is_not_equal_to_any_plausible_caller_value).Round 2: the fix also broke four pre-existing assertions in
tests/const/test_const_enum_get.pyandtests/const/test_const_enum_builtin_parity.pythat encoded the oldcontract (an unresolvable/unregistered default failing with its own named
error, or resolving into a declared-but-unassigned range/an unregistered
IntFlagcomposite). Each is retargeted rather than weakened -- aregistered-default check is added back wherever the old assertion's only
remaining job was proving "a default is genuinely consulted".
Round 3: three review findings, all addressed. (1) Two
NoDefaultSentinelTestsdocstrings claimed to fail on the pre-#857 treewhen they now coincidentally pass there too -- fixed, and each now names
the test that still discriminates #857 itself. (2) The renamed
test_filter_type_default_never_resolves_but_key_path_still_uses_an_uncached_memberrestores the three resolve/identity assertions dropped in round 2 by
demonstrating them through
FilterType'skeypath (FilterType.get(0)),which #864 does not touch, alongside the
default-never-resolves assertionalready added. (3)
enum.py's docstring is corrected: "It never mints" isqualified to apply to
defaultonly (keymay still mint onEtherType/Socket/CGAType, #775's deliberate exception), and the claim that adeclared-but-unassigned value is "deliberately absent from the lookup
tables" is qualified to exclude those same three registries, where it lands
in both tables -- measured:
EtherType.get(0x0888)grows_value2member_map_,_member_map_and_member_names_alike.tests/const/test_const_registry_protocol.py: 74/74 under plainunittest(methods, not subTest records).tests/const/test_const_enum_get.py:8/8.
tests/const/test_const_enum_builtin_parity.py: 33/33.tests/vendor/:92/92 (grown from 86 by #867's own new test module, unrelated to this
change). No regressions. Rebased onto current
main(3173c4fb0, #867)after the remote branch picked up a merge commit from a branch-sync action;
replaced with a clean rebase, still one commit.
Not in scope, reported rather than fixed:
tests/const/test_const_enum_no_mint.py::test_unresolvable_string_key_with_default_in_unassigned_rangealso fails for the same reason (
Hardware.get('Definitely-Not-A-Member', 40)used to resolve via the declared-but-unassigned-range pseudo-member path;
40is not a registeredHardwarevalue, so it now raisesKeyError: 'Definitely-Not-A-Member'instead, member count unchanged) -- left alonebecause that file is contended with #865.
Round 4:
tests/const/test_const_enum_no_mint.pyis no longer contended(#865 merged). Applied the deferred change from round 2 to
GetNoLongerMintsTests.test_unresolvable_string_key_with_default_in_unassigned_range:Hardware.get('Definitely-Not-A-Member', 40)(40is inHardware'sdeclared-but-unassigned
39-255range, not a registered member) now assertsKeyErrornaming the original key, member count unchanged -- re-measuredfresh (
before/afterboth42) after #866/#867 and #862/#865 bothlanded. Checked for overlap with #865's own additions to that file
(
ETHERTYPE_UNASSIGNED_PROBES,EtherTypeMixedMintTests, the retiredtest_masked_old_xerox_row_converts_by_source): none -- those are allEtherTypekey-path minting-order probes (#862), unrelated toHardware'sdefault-path resolution this test covers.
GetNoLongerMintsTestsremainsthe right class. Added as a new commit on top of the existing merge commit
rather than amending, since the round-4 target commit was no longer the
branch tip.
tests/const/as a whole: 203/203, zero failures -- the onedeferred failure from round 3 is gone.