Skip to content

tests: the nameless-enum sweep probes 65536 against a 16-bit flag registry, so main fails without showing red #702

Description

@JarryShaw

tests/dumpkit/test_nameless_enum_rendering_unit.py fails on main today, on every Python it has been
observed on, and it is not caused by any open PR. It surfaced on PR #694 — a docs-only change
touching nothing but docs/source/**/*.rst and CONTRIBUTING.md — which is what makes it worth filing
rather than fixing in place.

The failure

SUBFAILED(library='aenum', value=65536)
  tests/dumpkit/test_nameless_enum_rendering_unit.py::NamelessEnumRenderingTests::test_scalar_return_renders_a_nameless_member_as_its_value
  ValueError: 65536 is not a valid Flags
  pcapkit/const/tcp/flags.py:91: ValueError

1 failed, 1420 passed, 117 skipped, 3958 subtests passed on the CI job; 1 failed, 5 passed, 16 subtests passed when the single file is run.

Why it happens

tests/dumpkit/test_nameless_enum_rendering_unit.py:18 sweeps a fixed set of values across every flag
enumeration in the library:

NAMELESS_VALUES = (0, 1, 8, 9, 65536)

65536 is 0x10000. But pcapkit/const/tcp/flags.py:90-91 deliberately bounds its _missing_ to a
16-bit field:

if not (isinstance(value, int) and 0 <= value <= 0xFFFF):
    raise ValueError('%r is not a valid %s' % (value, cls.__name__))
return super()._missing_(value)

The TCP flags field is 16 bits, so that guard is correct and 65536 is genuinely not a valid value
for this registry. The test asks every flag enum to mint a nameless pseudo-member for a value that one
of them is right to reject. The library='aenum' subtest is the one that fails; library='enum' is a
separate subtest.

Scope, measured not assumed

Why it has gone unnoticed

main's own Unit Tests run for 9d7890db4 is still queued — every job reads queued — and the
runner backlog has been deep for hours. So main has been failing without ever displaying a red mark.
Any PR whose Unit Tests job actually reaches this test will fail for reasons that have nothing to do
with that PR, which is exactly what happened to a docs-only change.

The fix is a judgement call, hence an issue rather than a drive-by

Two defensible directions, and the choice is the owner's:

  1. Narrow the sweep per registry. 65536 is out of range for a 16-bit flag field; derive the
    out-of-range probe from each enumeration's own width instead of using one literal for all of them.
    This keeps the intent — "an unknown value renders as its value" — while respecting each registry's
    declared width.
  2. Exempt the width-guarded registries. If the point of 65536 is specifically to probe
    beyond any declared width, then registries whose _missing_ bounds themselves are legitimately
    outside the sweep and should be skipped with the reason recorded.

Direction 1 looks right to me because the guard at flags.py:90-91 is not a defect — a 16-bit field
rejecting 0x10000 is correct behaviour, and weakening it to satisfy a test would be the wrong trade.
But whether other flag registries carry the same width bound, and whether any of them should, wants a
sweep before committing to either direction.

Note there may be more than one affected registry: the failure aborts at the first one, so a fix should
re-run the whole sweep rather than assume TCP Flags is the only registry with a width guard.

Activity

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

    bugtestPull requests that add or correct tests (test: subject prefix)

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions