diff --git a/tests/_dependency_gates.py b/tests/_dependency_gates.py index f2f5f7308..42705ecf7 100644 --- a/tests/_dependency_gates.py +++ b/tests/_dependency_gates.py @@ -45,9 +45,9 @@ One thing this deliberately does not model, recorded here rather than left to be discovered: **environment markers.** ``PyPCAPFile = [ "pypcapfile; -python_version < '3.12'" ]`` resolves to nothing on four of the five supported -legs (3.12-3.15), so an install line carrying that extra would satisfy this module -while only 3.11 and the KTLO legs ran the tests. :func:`requirement_key` +python_version < '3.12'" ]`` resolves to nothing on every leg from 3.12 up, +so an install line carrying that extra would satisfy this module while only the +legs below 3.12 ran the tests. :func:`requirement_key` strips the marker and :func:`provided_by` ignores it; the marker text is kept on :class:`Requirement` so a diagnostic can say so. @@ -195,7 +195,7 @@ # generated constants on a schedule rather than as a check -- so excluding # this flag would have left `make isort`'s verdict unverified everywhere, # which is the #766 complaint. Cost does not argue the other way either: - # isort is a pure-Python wheel and all four Makefile lines together measure + # isort is a pure-Python wheel and the Makefile's isort lines together measure # about 1.5s, against the ~238 MB and licence questions that keep ``NGAP`` # out of ``all``. 'isort': ('isort',), @@ -1153,7 +1153,7 @@ def module_flag_requirements(path: 'pathlib.Path') -> 'dict[str, frozenset[str]] Public for the same reason :func:`module_gates` is: the shapes it has to understand are best pinned against source written to exercise them one at a - time, rather than against whichever of them the suite happens to use today. + time, rather than against whichever of them the suite happens to use. """ try: @@ -1535,7 +1535,7 @@ def pytest_jobs(workflow: 'Optional[pathlib.Path]' = None) -> 'tuple[Job, ...]': # `integration` job's names `fixture_tier_paths()`, so classifying on # the whole job section reads `gate` as an ignore-selection job and # credits it with reaching only the unit tier. Matching on the step name - # would work today and break the day a step is renamed. + # would work only until a step is renamed. steps = re.findall(r'(?ms)^ - name: [^\n]*\n(.*?)(?=^ - name:|\Z)', section) running = [step for step in steps if 'python -m pytest' in step] if len(running) != 1: diff --git a/tests/_support.py b/tests/_support.py index 67378cfaa..0edc4a27c 100644 --- a/tests/_support.py +++ b/tests/_support.py @@ -794,8 +794,8 @@ def restore_modules_after(test: 'unittest.TestCase', Registered **once per test** however many times this is called, and the snapshot kept is the first one -- the only one taken before any of the loads wrote anything. That is what lets :func:`bootstrap_core_modules` announce - itself and then make seven :func:`load_module` calls without registering - eight cleanups to eight successively more polluted snapshots. + itself and then make a run of :func:`load_module` calls without registering + a cleanup per call, each to a successively more polluted snapshot. Registered with :meth:`~unittest.TestCase.addCleanup` rather than done in a ``tearDown``, for the reasons :func:`isolate_modules` gives: it runs even @@ -1008,7 +1008,7 @@ def purge_modules(prefixes: Iterable[str]) -> None: test. Take the two together rather than reading the paragraph above as a promise that a purge leaves no trace -- under a runner that loads no ``conftest``, it does. Measured on ``b337cdbc2``: ``python -m unittest discover -s tests/corekit`` - fails 5 of that class's identity subtests, because ``test_module`` sorts first + fails that class's identity subtests, because ``test_module`` sorts first and purges, while the same file alone passes and :program:`pytest` -- the supported runner, and what :file:`.github/workflows/unit-tests.yml` invokes -- passes either way. diff --git a/tests/_tiers.py b/tests/_tiers.py index 8a7ded351..a7e5aa108 100644 --- a/tests/_tiers.py +++ b/tests/_tiers.py @@ -74,9 +74,9 @@ What neither catches, deliberately: a unit-tier module that opens a capture without going through :func:`~tests._support.sample_path` at all, e.g. by joining -:file:`examples/captures/` and a name itself. No *unit-tier* module does this -today -- :file:`tests/protocols/misc/test_pcapng_unit.py` was the last one and -now reads ``sample_path('dhcp_big_endian.pcapng')`` inside the ``try``/``except +:file:`examples/captures/` and a name itself. No *unit-tier* module does this: +:file:`tests/protocols/misc/test_pcapng_unit.py` was the last one, and +reads ``sample_path('dhcp_big_endian.pcapng')`` inside the ``try``/``except FileNotFoundError`` idiom :func:`explain` recommends. Only the *unit* tier is claimed there, deliberately: fixture-tier modules join the directory freely and are entitled to, e.g. :file:`tests/protocols/test_option_coverage_runtime.py`, @@ -734,7 +734,7 @@ def skip_idiom_modules() -> 'tuple[pathlib.Path, ...]': :func:`audit_module` carries and for the same reason: a name computed at call time, e.g. ``sample_path(sample)`` in a parametrised loop, is invisible to a static pass. No module in the suite does this inside a - handled call today -- see ``test_every_handled_call_names_a_literal_capture`` + handled call -- see ``test_every_handled_call_names_a_literal_capture`` in :file:`tests/test_tier_guard.py`, which exists to catch the day one does, since such a call would silently drop out of this function's result and its fixture-backed coverage would quietly stop running anywhere. @@ -771,12 +771,12 @@ def _enclosing_scope(tree: 'ast.Module', lineno: 'int') -> 'Optional[tuple[Optio carry that context as it goes. "Most tightly" is decided by span, so a helper function defined inside a test method and containing the line in question would win over the test method itself; nothing in this suite's - skip idiom does that today, but the rule is stated so a future one is + skip idiom does that, but the rule is stated so a future one is handled the same way :func:`sample_path_calls` already treats nesting. Returns: :data:`None` if no function definition contains ``lineno`` at all -- - a module-level call, which does not happen in this suite today. + a module-level call, which does not happen in this suite. """ best = None # type: Optional[tuple[Optional[str], str, int]] @@ -822,8 +822,8 @@ def skip_idiom_test_ids() -> 'tuple[str, ...]': Falls back to the *module* path when a handled call cannot be resolved to one enclosing function -- :func:`_enclosing_scope` returns :data:`None` for - a module-level call, which is not a shape this suite's skip idiom uses - today, but a fallback that still runs the file is safer than one that + a module-level call, which is not a shape this suite's skip idiom uses, + but a fallback that still runs the file is safer than one that drops the call's coverage entirely. Returns: diff --git a/tests/conftest.py b/tests/conftest.py index 86a591e9f..62b62cd7e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,11 @@ # -*- coding: utf-8 -*- """Suite-wide :program:`pytest` configuration. -Holds three things. The first is :func:`restore_module_table`, the guard that +Besides session hooks documented where they are defined -- the warm import +and coverage flush in :func:`pytest_sessionstart` and +:func:`pytest_sessionfinish`, and the timer release in +:func:`pytest_timeout_cancel_timer` -- it holds the following. The first is +:func:`restore_module_table`, the guard that puts the :mod:`pcapkit` region of :data:`sys.modules` back after every test; see its own docstring for why it is here rather than left to each test file. diff --git a/tests/const/test_const_apptype_split_unit.py b/tests/const/test_const_apptype_split_unit.py index d4f9e1c25..17449f811 100644 --- a/tests/const/test_const_apptype_split_unit.py +++ b/tests/const/test_const_apptype_split_unit.py @@ -669,7 +669,7 @@ def test_every_transport_named_span_is_claimed_by_one_registry(self) -> None: :mod:`pcapkit.vendor.reg.apptype.apptype` stops emitting the test -- and it returns silently, because a shadowed branch is unreachable rather than wrong. This asserts the invariant over every branch instead of over the two - spans that happen to collide today: a branch minting a member for a named + spans that happen to collide: a branch minting a member for a named transport protocol is claimed by that registry, and one minting for ``undefined`` claims nothing, since IANA's unassigned and reserved markers belong to whichever registry was asked. diff --git a/tests/const/test_const_enum_builtin_parity.py b/tests/const/test_const_enum_builtin_parity.py index 7c2900f6d..3d7fa7c57 100644 --- a/tests/const/test_const_enum_builtin_parity.py +++ b/tests/const/test_const_enum_builtin_parity.py @@ -432,11 +432,17 @@ def test_the_exception_is_not_an_in_library_one(self) -> None: """Explicitly *not* ``EnumError``, and explicitly not loud. :class:`~pcapkit.utilities.exceptions.BaseError` logs at CRITICAL from - its constructor, so it fires even for an exception that is caught and - discarded -- which the ``except ValueError`` fallback in every generated - ``get()`` does on purpose. A guard raising a + its constructor unless it is quiet, so it fires even for an exception + that is caught and discarded. The base + :meth:`~pcapkit.corekit.enum.EnumLookup.get` constructs its lookup inside + a ``_CaughtByCaller(ValueError)`` block (#1845), which quiets a + :exc:`ValueError` subclass there, but a direct ``cls(value)`` caught by + its caller has no such block: a guard raising a :class:`~pcapkit.utilities.exceptions.BaseError` subclass would log once - per discarded default. + per value discarded that way. And + :class:`~pcapkit.utilities.exceptions.EnumError`, not being a + :exc:`ValueError`, would escape its ``except ValueError`` fallback + altogether. """ from pcapkit.utilities.exceptions import BaseError, EnumError diff --git a/tests/const/test_const_enum_no_mint.py b/tests/const/test_const_enum_no_mint.py index a8ab5a89e..c1d1d9c29 100644 --- a/tests/const/test_const_enum_no_mint.py +++ b/tests/const/test_const_enum_no_mint.py @@ -14,12 +14,12 @@ never reverses for the life of the process, and that a long-running capture walking many such values would accumulate without bound. -Tier 1 touches exactly two sites in :mod:`pcapkit.vendor.default`: the shared -``get()`` template and the ``_missing_`` range-branch :meth:`~pcapkit.vendor. -default.Vendor.process` assembles -- see that module for the two hunks. It is +Tier 1 touches only the shared ``get()`` template in :mod:`pcapkit.vendor.default` +and the ``_missing_`` range-branch :meth:`~pcapkit.vendor. +default.Vendor.process` assembles -- see that module for those hunks. It is scoped to the registries that inherit both unmodified, which this module's :data:`REGISTRIES_WITH_UNASSIGNED_RANGES` and :data:`ALL_REGISTRIES` enumerate; -the 12 vendor files that replace the shared template wholesale (and whatever +the vendor files that replace the shared template wholesale (and whatever they generate) are out of scope and untouched. Tier 1 fixed the *mechanism* (a lookup should never mint); it did not decide, @@ -32,13 +32,13 @@ something assigns them -- so its placeholder is notation, not a name worth registering. Applied registry by registry to every ``_missing_`` that still called :func:`~aenum.extend_enum` -- measured -at exactly 89 modules by an AST walk over ``pcapkit/const/*.py`` (not the -"~92" an earlier pass in this programme estimated) -- the ruling converted 82 -of them outright (172 branches, :data:`RULING_CONVERTED_REGISTRIES` below), +by an AST walk over ``pcapkit/const/*.py`` rather than estimated, as an earlier +pass in this programme had -- the ruling converted most +of them outright (:data:`RULING_CONVERTED_REGISTRIES` below), left :class:`~pcapkit.const.reg.ethertype.EtherType` and :class:`~pcapkit.const.ipx.socket.Socket` *mixed* (each keeps some branches minting and converts others -- see :data:`ETHERTYPE_UNASSIGNED_PROBES` and -:data:`IPX_SOCKET_UNASSIGNED_PROBES`), and left 9 classes across 6 files +:data:`IPX_SOCKET_UNASSIGNED_PROBES`), and left the bespoke classes untouched because they do not inherit :class:`~pcapkit.corekit.enum. EnumRegistry` and so have no ``_unregistered_member`` to convert to until GitHub issue #860 lands (blocked on #859); :class:`~pcapkit.const.reg. @@ -47,25 +47,26 @@ for a different reason: its ``Tag_`` mint is not an IANA-style range at all (see its own module for why), so the ruling never touched it. -GitHub issue #860 (step 2, PR 1) has now brought 8 of those 9 classes onto +GitHub issue #860 (step 2, PR 1) brought every one of those classes except +:class:`~pcapkit.const.reg.apptype.apptype.AppType` onto :class:`~pcapkit.corekit.enum.EnumRegistry` and converted their branches -- -15 in total, see :data:`BESPOKE_UNMINT_CONVERTED_REGISTRIES` and +see :data:`BESPOKE_UNMINT_CONVERTED_REGISTRIES` and :class:`BespokeOpenVocabularyUnmintConvertedTests` below. Two distinct shapes: -Five range-bounded registries whose old mint used a manufactured +Range-bounded registries whose old mint used a manufactured placeholder label (``Unassigned``, ``Unknown_%d``, ``opt_unknown_%d``): -:class:`~pcapkit.const.http.status_code.StatusCode` (8), +:class:`~pcapkit.const.http.status_code.StatusCode`, :class:`~pcapkit.const.ftp.return_code.ReturnCode`, -:class:`~pcapkit.const.ftp.return_code.ResponseKind` and -:class:`~pcapkit.const.ftp.return_code.GroupingInformation` (1 each), and -:class:`~pcapkit.const.pcapng.option_type.OptionType` (1) -- 12 branches, +:class:`~pcapkit.const.ftp.return_code.ResponseKind`, +:class:`~pcapkit.const.ftp.return_code.GroupingInformation` and +:class:`~pcapkit.const.pcapng.option_type.OptionType`, unambiguous under the mint/unmint criterion from the first measurement. Each carries a custom ``__new__`` with extra per-member attributes (unlike -any of the 82 tier-2 registries above), so each needed its own +any of the tier-2 registries above), so each needed its own ``_unregistered_member`` override reconstructing those attributes rather -than the shared base's generic one, and two of the five -(:class:`StatusCode`, :class:`ReturnCode`) had their own hand-written +than the shared base's generic one, and :class:`StatusCode` and +:class:`ReturnCode` had their own hand-written ``get()`` replaced by the base's -- see :class:`BespokeGetReplacementTests` for the ``default == -1`` -> ``NO_DEFAULT`` behaviour change that implies. :class:`OptionType` keeps its own ``get()`` (genuine multi-namespace @@ -80,16 +81,16 @@ test_optiontype_get_int_path_no_longer_mints`, ``..._namespace_path_...`` and ``..._str_path_...``. -Three open-vocabulary registries whose old mint used the exact, unmodified +Open-vocabulary registries whose old mint used the exact, unmodified observed value as its own name rather than any manufactured label: :class:`~pcapkit.const.ftp.command.FEATCode`, :class:`~pcapkit.const.ftp.command.Command` and -:class:`~pcapkit.const.http.method.Method` -- 1 ``_missing_`` branch each, +:class:`~pcapkit.const.http.method.Method` -- a single ``_missing_`` branch each, initially left minting pending the owner's ruling (this measurement's own report flagged them as genuinely ambiguous under the criterion, since nothing about them is a manufactured placeholder). GitHub issue #860 is where the owner settled it: ``get()`` must not mint, because only -``register()`` creates a new registry entry -- for these three registries +``register()`` creates a new registry entry -- for these registries only IANA-registered values are legitimate, and ``get()`` does not have enough information to construct one itself. That rule is about ``get()`` in its own right, and it extends just as much to @@ -103,7 +104,7 @@ case-insensitive ``get`` per :rfc:`5797#section-2` -- but that override never calls ``cls(key)``, so it added no mint site to this file's concern.) -GitHub issue #860 step 2's PR 2 has now converted the last of the 9: +GitHub issue #860 step 2's PR 2 converted the last of those classes: :class:`~pcapkit.const.reg.apptype.apptype.AppType` and its four per-transport registries (:class:`~pcapkit.const.reg.apptype.tcp.TCP`, :class:`~pcapkit.const.reg.apptype.udp.UDP`, @@ -131,7 +132,7 @@ later drew the further consequence once nothing decoded a composite any more: the power-of-two spacing existed only for the ``tcp | udp``-style code that composition served, and since the new logic does not accept that piping, ``auto()`` -is the expected numbering. So it now numbers its five members sequentially from +is the expected numbering. So it numbers its members sequentially from 0 -- ``undefined`` a direct, explicit ``0``, the rest continuing from it via ``auto()`` with no ``_start_`` needed, per the owner's own further ruling settling the declaration shape -- rather than by the power-of-two @@ -144,7 +145,7 @@ raise. None of the tests below pin that, per the same ruling. GitHub issue #775's final round closes the two mixed registries themselves: -every one of :class:`~pcapkit.const.reg.ethertype.EtherType`'s 52 +every one of :class:`~pcapkit.const.reg.ethertype.EtherType`'s still-minting range branches, and :class:`~pcapkit.const.ipx.socket.Socket`'s one (``Registered by Xerox``), now convert to :meth:`~pcapkit.corekit.enum.EnumRegistry._unregistered_member` too -- PR #878 @@ -152,7 +153,7 @@ is about not registering rather than renaming. So each keeps the hex-suffixed name it always rendered (``Xyplex_0x0888``, not a bare ``Xyplex``) even though it no longer registers -- neither is "mixed" any more, both are wholly -converted like the 82 in :data:`RULING_CONVERTED_REGISTRIES`, and +converted like those in :data:`RULING_CONVERTED_REGISTRIES`, and :class:`EtherTypeMixedMintTests`/:class:`IPXSocketMixedMintTests` below are retitled in place to prove the formerly-kept probe no longer mints rather than that it still does. The one consequence worth naming: this reintroduces the @@ -161,8 +162,8 @@ never registers regardless of what its ``name`` argument looks like -- see :func:`_is_hex_suffixed_unregistered_name` in :class:`UnregisteredMemberNameIsBareTests` for the scoped exemption this -required, keyed on the ``name`` argument's own shape rather than on the two -files it happens to live in today. +required, keyed on the ``name`` argument's own shape rather than on the +files it happens to live in. """ from __future__ import annotations @@ -182,7 +183,7 @@ if TYPE_CHECKING: from typing import Optional -#: (module, class name) for every one of tier 1's 22 registries whose vendor +#: (module, class name) for every one of tier 1's registries whose vendor #: crawler inherits :mod:`pcapkit.vendor.default`'s ``process()`` unmodified, #: so their ``_missing_`` range branches are in scope for the mint fix too -- #: not just their ``get()``. Derived by AST from pcapkit/vendor/*.py: these are @@ -223,13 +224,13 @@ ('pcapkit.const.hip.transport', 'Transport'), ) -#: Every one of tier 1's 105 registries -- every generated ``const/`` module +#: Every one of tier 1's registries -- every generated ``const/`` module #: whose vendor crawler inherits the shared ``get()``/``register()``/ #: ``_unregistered_member()`` template from :mod:`pcapkit.vendor.default` #: unmodified. Derived the same way as :data:`ALL_REGISTRIES` above, just -#: without narrowing to the 22 with an unassigned range: every vendor file -#: under :mod:`pcapkit.vendor` that is not one of the 12 which replace the -#: shared template wholesale (and not one of the four ``AppType`` transport +#: without narrowing to those with an unassigned range: every vendor file +#: under :mod:`pcapkit.vendor` that is not one of those which replace the +#: shared template wholesale (and not one of the ``AppType`` transport #: subclasses that inherit *that* bespoke template instead). ALL_105_REGISTRIES = ( ('pcapkit.const.arp.hardware', 'Hardware'), @@ -355,19 +356,19 @@ def _first_unassigned_value(cls: 'type') -> 'int': return int(match.group(1)) -#: (module, class name) for every one of the 82 registries the owner's +#: (module, class name) for every one of the registries the owner's #: #775/#847 ruling converted outright: every ``_missing_`` branch that used #: to mint via :func:`~aenum.extend_enum` now returns :meth:`~pcapkit.corekit. #: enum.EnumRegistry._unregistered_member` instead, because what it minted was #: a bare status word (``Unassigned``, ``Reserved [...]``, ``Reserved for #: Private/Experimental Use``, ``Unspecified in the IANA registry``, and #: similar) rather than a name anyone assigned. Derived from the same AST walk -#: that measured 89 modules still minting on ``main`` before this change: 82 -#: of the 89 are here, including the two *mixed* registries (:class:`~pcapkit. +#: that measured the modules still minting on ``main`` before this change: +#: most of them are here, including the *mixed* registries (:class:`~pcapkit. #: const.reg.ethertype.EtherType` and :class:`~pcapkit.const.ipx.socket. #: Socket`, which convert some branches and keep minting others -- see #: :data:`ETHERTYPE_UNASSIGNED_PROBES` and :data:`IPX_SOCKET_UNASSIGNED_ -#: PROBES`). The other 7 of the 89 are untouched: 6 files on classes that do +#: PROBES`). The rest are untouched: the files whose classes do #: not inherit :class:`EnumRegistry` yet and so have no ``_unregistered_ #: member`` to convert to (:class:`~pcapkit.const.reg.apptype.apptype. #: AppType`, :class:`~pcapkit.const.http.status_code.StatusCode`, :mod: @@ -485,8 +486,8 @@ def _first_unassigned_value(cls: 'type') -> 'int': #: demonstrates in this list below. EtherType has therefore joined this set; #: see :data:`ETHERTYPE_UNASSIGNED_PROBES`'s comment for the probe itself, #: still covered explicitly by :class:`EtherTypeMixedMintTests` as well. -#: Neither registry is actually mixed any more as of #775's final round -- -#: see that class's own updated docstring. +#: #775's final round left neither registry actually mixed -- see that +#: class's own docstring. #: #: Derived the same way as :data:`RULING_CONVERTED_REGISTRIES`: computed once #: by walking each candidate's own bounds for a gap, not hand-picked. @@ -872,8 +873,8 @@ def test_register_is_present_on_every_tier_1_registry(self) -> None: def test_register_actually_mints_on_every_one_of_the_105_registries(self) -> None: """Exercise :meth:`register` for real -- not just ``callable()`` -- - on every one of tier 1's 105 registries, the full set the shared - template now reaches (:data:`ALL_105_REGISTRIES`), not only the 22 + on every one of tier 1's registries, the full set the shared + template reaches (:data:`ALL_105_REGISTRIES`), not only those with a bounded-unassigned range. A high, fixed value is deliberately outside any registry's assigned codes, so this cannot collide with anything either the CSV seeded or a sibling test minted. @@ -913,8 +914,8 @@ def test_register_actually_mints_on_every_one_of_the_105_registries(self) -> Non class UnregisteredMemberHelperTests(unittest.TestCase): - """:meth:`_unregistered_member` in isolation, on every one of the 105 - registries -- not only the 22 whose own ``_missing_`` happens to call it. + """:meth:`_unregistered_member` in isolation, on every one of tier 1's + registries -- not only those whose own ``_missing_`` happens to call it. It is part of the shared template regardless, so every registry carries it whether or not its own ``_missing_`` uses it yet (the other 83 keep their own bespoke ``process()``-driven ``_missing_``, out of tier 1's @@ -948,10 +949,10 @@ def test_builds_an_absent_member_on_every_registry(self) -> None: def _combining_operands(expr: 'ast.expr') -> 'Optional[list[ast.expr]]': """Every sub-expression ``expr`` *combines* with other, fixed text to - build a new string, for the five shapes this tree's ``name`` arguments + build a new string, for the shapes this tree's ``name`` arguments are ever manufactured from: ``%``-formatting, string concatenation, an f-string, ``str.format``, and ``sep.join([...])``. :obj:`None` if - ``expr`` is not one of those five combining shapes *at its own top + ``expr`` is not one of those combining shapes *at its own top level* -- callers that want to see through a wrapping call (``.upper()``, ``str(...)``) around one of these do that separately; this function only recognises the combination itself. @@ -1055,7 +1056,7 @@ def is_manufactured(name_arg: 'Optional[ast.expr]') -> 'bool': conventional ``value``/``key`` parameter name, which this function has no way to recognise without hardcoding attribute names as well as parameter names -- a broader heuristic than round 5 asked for. Nothing - under :mod:`pcapkit.const` writes a ``name`` argument this way today. + under :mod:`pcapkit.const` writes a ``name`` argument this way. """ if name_arg is None: @@ -1132,7 +1133,7 @@ def is_manufactured(name_arg: 'Optional[ast.expr]') -> 'bool': #: expected)`` where ``source`` is a full ``return cls._unregistered_member( #: value, )`` statement parsed for its own ``name`` argument. IS_MANUFACTURED_FIXTURES = ( - # The four manufactured shapes the round-2 review named explicitly -- + # The manufactured shapes the round-2 review named explicitly -- # each embeds ``value``, the thing being looked up, into the label. ('percent-s-value', "cls._unregistered_member(value, 'x_%s' % value)", True), ('percent-x-value', "cls._unregistered_member(value, 'x_%x' % value)", True), @@ -1153,7 +1154,7 @@ def is_manufactured(name_arg: 'Optional[ast.expr]') -> 'bool': # treated as exempt the same way ``value`` alone is at the top level -- # which missed the value being glued in as *data* to a call rather than # merely transformed. None of these nine exists under pcapkit/const/ - # today (latent, not live), but the census that found them is exactly + # (latent, not live), but the census that found them is exactly # what this fixture set exists to keep honest. ('join-set-with-value', "cls._unregistered_member(value, ''.join({'x_', str(value)}))", True), ('join-genexp-with-value', @@ -1197,8 +1198,8 @@ def test_self_check(self) -> None: f'{label}: {source!r}') -#: The one call-chain every hex-suffixed manufactured name shares, on all 53 -#: branches #775's final round deliberately kept unrenamed rather than +#: The one call-chain every hex-suffixed manufactured name shares, on every +#: branch #775's final round deliberately kept unrenamed rather than #: converting to the bare placeholder every other converted registry uses #: (``Xyplex_0x0888``, ``Registered by Xerox_0x0010``, ...; see that #: sweep's own docstring, and the module docstring's closing paragraph, for @@ -1216,7 +1217,7 @@ def test_self_check(self) -> None: def _is_hex_suffixed_unregistered_name(name_arg: 'Optional[ast.expr]') -> bool: """Whether ``name_arg`` is *exactly* the one shape #775's final round preserved unrenamed on :class:`~pcapkit.const.reg.ethertype.EtherType`'s - 52 range branches and :class:`~pcapkit.const.ipx.socket.Socket`'s one -- + range branches and :class:`~pcapkit.const.ipx.socket.Socket`'s one -- a ``%``-format :class:`~ast.BinOp` whose left operand is a string constant ending in the literal ``'_0x%s'``, and whose right operand is structurally identical (by :func:`ast.dump`, so source-text formatting @@ -1224,7 +1225,7 @@ def _is_hex_suffixed_unregistered_name(name_arg: 'Optional[ast.expr]') -> bool: :data:`_HEX_SUFFIX_SHAPE`. Deliberately narrower than :func:`is_manufactured`'s own - combining-operand check: it exists only to pick these 53 already- + combining-operand check: it exists only to pick these already- manufactured calls -- the ones #775's ruling explicitly asked to keep exactly as rendered -- out from every *other* manufactured call :func:`is_manufactured` still (correctly) flags, not to re-decide what @@ -1267,9 +1268,9 @@ class UnregisteredMemberNameIsBareTests(unittest.TestCase): *manufactured* numeric-suffixed label: a bare string constant containing ``%`` (the old ``'Unassigned_%d' % value`` shape, spelled out as a literal), or an equivalent ``%``-formatted :class:`~ast.BinOp` or - f-string. It therefore covers all 49 call sites tier 1's follow-up - touched, the 172 tier 2's #775/#847 ruling added, and -- since #860 - step 2's PR 1 -- the 15 more across :class:`~pcapkit.const.http. + f-string. It therefore covers every call site tier 1's follow-up + touched, every one tier 2's #775/#847 ruling added, and those #860 + step 2's PR 1 added across :class:`~pcapkit.const.http. status_code.StatusCode`, :class:`~pcapkit.const.ftp.return_code. ReturnCode`, :class:`~pcapkit.const.ftp.return_code.ResponseKind`, :class:`~pcapkit.const.ftp.return_code.GroupingInformation`, @@ -1279,16 +1280,16 @@ class UnregisteredMemberNameIsBareTests(unittest.TestCase): :class:`~pcapkit.const.http.method.Method` (see :data:`BESPOKE_UNMINT_CONVERTED_REGISTRIES` above), plus every ``super()._unregistered_member(value, name)`` forwarding call each of - those five ``__new__``-carrying overrides makes internally -- not a + those ``__new__``-carrying overrides makes internally -- not a fresh call site with a label of its own, just relaying whatever the true call site already passed, so it is walked and counted here too rather - than specially excluded -- plus 2 more round 2 review found still + than specially excluded -- plus the sites round 2 review found still minting on :class:`OptionType`'s own ``get()`` (its int/namespace path - and its ``str`` path, both independent of ``_missing_``), for 244 total - as of PR 1. PR 2 then added the 766 ``_missing_`` branches on + and its ``str`` path, both independent of ``_missing_``). PR 2 then added + the ``_missing_`` branches on :class:`~pcapkit.const.reg.apptype.apptype.AppType` itself, the one more inside its own ``get()``, and the one ``super()._unregistered_member(...)`` - forward its own override makes -- 768 more, for 1012 total; see + forward its own override makes; see :class:`AppTypeUnmintConvertedTests` below. ``'%s_unknown' % namespace`` on the first of those two is deliberately *not* flagged as manufactured despite being a ``%``-formatted @@ -1297,7 +1298,7 @@ class UnregisteredMemberNameIsBareTests(unittest.TestCase): carries none of the numeric-suffix collision risk the check exists to catch -- see :func:`is_manufactured`'s own docstring below. - The last three of those fifteen are a genuinely different shape from + The open-vocabulary ones among those are a genuinely different shape from every other converted registry: the ``name`` argument (the identifier each is looked up by, canonicalised to upper case for all three -- matching how every *registered* member of :class:`Command`/ @@ -1324,13 +1325,13 @@ class UnregisteredMemberNameIsBareTests(unittest.TestCase): there is the explicit, caller-named path the sweep is not about. (Corrected from an earlier draft of this docstring, which estimated - "~92 registries still mint" and named ``pcapkit.const.mh`` and + the still-minting registries rather than measuring them and named ``pcapkit.const.mh`` and ``BlockType`` as examples -- both were converted by tier 2 and no longer apply; the AST walk in the module docstring above measured the real - figure at 89.) + set.) - GitHub issue #775's final round converts the last 53 minting branches -- - all 52 of :class:`~pcapkit.const.reg.ethertype.EtherType`'s and + GitHub issue #775's final round converts the last minting branches -- + every one of :class:`~pcapkit.const.reg.ethertype.EtherType`'s and :class:`~pcapkit.const.ipx.socket.Socket`'s one -- and deliberately keeps each one's hex-suffixed name unchanged (PR #878 scoped it this way: keeping the existing hex-suffixed name, since this change is about not @@ -1340,7 +1341,7 @@ class UnregisteredMemberNameIsBareTests(unittest.TestCase): ``value``, via ``hex(value)[2:].upper().zfill(4)``. Flagging it anyway would be a false positive in the sense that matters: the collision this check protects against is two *minted* members sharing a name at different - values, and neither of these 53 calls ever mints, so nothing can collide + values, and none of these calls ever mints, so nothing can collide regardless of what the ``name`` argument looks like. :func:`_is_hex_suffixed_unregistered_name` below is the scoped fix -- an exemption keyed on the ``name`` argument's own AST shape, not on which @@ -1380,23 +1381,18 @@ def test_every_unregistered_member_call_passes_a_non_manufactured_name(self) -> segment = ast.get_source_segment(source, node) offenders.append(f'{path.relative_to(repo_root)}:{node.lineno}: {segment}') - # Sanity: the sweep itself must actually be exercising something -- - # tier 1's follow-up touched exactly 49 call sites across 21 files, - # tier 2's #775/#847 ruling added 172 more across 82 files, and - # #860 step 2's PR 1 added 11 more (true call sites plus each - # override's own ``super()`` forward, plus the 2 round-2 review found - # still minting on OptionType.get()'s own two paths) across 2 files, - # for 244 total. #860 step 2's PR 2 then added the 766 ``_missing_`` - # branches on AppType itself, the one more inside its own ``get()``, - # and the one ``super()._unregistered_member(...)`` forward its own - # override makes -- 768 more, in one file, for 1012 total. #775's - # final round then added the 52 on EtherType and the 1 on Socket -- - # 53 more, for 1065 total when that round landed. + # Sanity: the sweep itself must actually be exercising something. + # The floor is the call-site total when #775's final round landed -- + # the sites tier 1's follow-up touched, those tier 2's #775/#847 + # ruling added, those #860 step 2's PR 1 added (true call sites, each + # override's own ``super()`` forward, and OptionType.get()'s own + # paths), AppType's from PR 2, and that final round's on EtherType + # and Socket -- so a walk that silently stops finding sites fails. self.assertGreaterEqual(call_count, 1065, f'expected at least 1065 _unregistered_member call sites, found {call_count}') # And that the exemption is actually earning its keep, rather than a - # dead carve-out nothing reaches any more: exactly 53, matching the - # 52 EtherType range branches plus Socket's one. + # dead carve-out nothing reaches: one per EtherType range + # branch, plus Socket's one. self.assertEqual(exempt_hits, 53, f'expected exactly 53 hex-suffixed-name exemptions to fire, found {exempt_hits}') self.assertEqual(offenders, [], @@ -1408,9 +1404,9 @@ class RulingConversionDoesNotMintTests(unittest.TestCase): """Tier 2's #775/#847 ruling, behaviourally: a value that used to mint a bare status word must now come back as a throwaway pseudo-member instead, the same regression :class:`UnassignedRangeDoesNotMintTests` above proves - for tier 1's 21. Swept across :data:`RULING_CONVERTED_WITH_REACHABLE_GAP` - -- the 69 of the 82 converted registries whose branch a real lookup can - actually reach; the other 13 are proved by source instead, in + for tier 1's registries. Swept across :data:`RULING_CONVERTED_WITH_REACHABLE_GAP` + -- the converted registries whose branch a real lookup can + actually reach; the rest are proved by source instead, in :class:`RulingConversionSourceTests` below.""" if TYPE_CHECKING: @@ -1477,22 +1473,22 @@ def test_repeated_lookup_does_not_grow_members(self) -> None: class RulingConversionSourceTests(unittest.TestCase): - """Source-level proof for the 13 of :data:`RULING_CONVERTED_REGISTRIES` + """Source-level proof for those of :data:`RULING_CONVERTED_REGISTRIES` with no reachable gap (every in-bounds value already names a real member, so no lookup can exercise the branch either before or after this change) - -- and, as a completeness check, for the 80 wholly-converted registries: - none of their ``_missing_`` bodies may call :func:`~aenum.extend_enum` - any more. :data:`_MIXED_REGISTRIES` is empty as of #775's final round, so - nothing is excluded here any more -- see its own docstring.""" + -- and, as a completeness check, for the wholly-converted registries: + none of their ``_missing_`` bodies may call :func:`~aenum.extend_enum`. + :data:`_MIXED_REGISTRIES` is empty, #775's final round having + converted both, so nothing is excluded here -- see its own docstring.""" def test_no_reachable_gap_registries_no_longer_call_extend_enum(self) -> None: - # EtherType now belongs to RULING_CONVERTED_WITH_REACHABLE_GAP: its + # EtherType belongs to RULING_CONVERTED_WITH_REACHABLE_GAP: its # masked-branch exclusion (Old Xerox shadowed by the wider IEEE802.3 # range) was fixed under GitHub issue #862, and its first converted # branch by source order is directly probeable like any other - # reachable-gap registry now. The `_MIXED_REGISTRIES` subtraction - # below is a defensive no-op today -- neither mixed registry needs - # removing from `RCR - RG` any more (EtherType is already in RG; + # reachable-gap registry. The `_MIXED_REGISTRIES` subtraction + # below is a defensive no-op -- neither mixed registry needs + # removing from `RCR - RG` (EtherType is already in RG; # Socket never appeared in RULING_CONVERTED_REGISTRIES to begin with) # -- kept so a mixed registry that regains a masked or absent branch # in the future does not silently inflate this count. @@ -1653,11 +1649,11 @@ def test_registered_by_xerox_no_longer_mints(self) -> None: self.assertIsNot(member, second) -#: The 5 (of #860's original 9 bespoke) classes step 2's PR 1 brought onto +#: The range-bounded ones of #860's bespoke classes step 2's PR 1 brought onto #: :class:`~pcapkit.corekit.enum.EnumRegistry` and converted: (module, class #: name, a probe value inside the converted range, the bare label the -#: conversion uses). Every one of these five has a custom ``__new__`` with -#: extra per-member attributes, unlike any of the 82 tier-2 registries in +#: conversion uses). Every one of these has a custom ``__new__`` with +#: extra per-member attributes, unlike any of the tier-2 registries in #: :data:`RULING_CONVERTED_REGISTRIES` above, which is exactly why each needed #: its own ``_unregistered_member`` override rather than the shared generic #: one -- see :class:`BespokeUnmintConvertedRegistriesTests`. @@ -1671,9 +1667,9 @@ def test_registered_by_xerox_no_longer_mints(self) -> None: class BespokeUnmintConvertedRegistriesTests(unittest.TestCase): - """GitHub issue #860 step 2, PR 1: 5 of the 9 bespoke, non- + """GitHub issue #860 step 2, PR 1: the range-bounded bespoke, non- :class:`~pcapkit.corekit.enum.EnumRegistry` classes brought onto the base - and converted. Unlike every registry above, each of these five carries a + and converted. Unlike every registry above, each of these carries a custom ``__new__`` setting extra attributes (``message``; ``description``/``kind``/``group``; ``opt_name``/``opt_value``), so the base's generic :meth:`~pcapkit.corekit.enum.EnumRegistry. @@ -1996,7 +1992,7 @@ def test_command_rows_reference_declared_featcode_members(self) -> None: self.assertIs(Command.MLSD.feat, Command.MLST.feat) # type: ignore[attr-defined] def test_featcode_missing_no_longer_mints(self) -> None: - """The convention pinned across all three open-vocabulary classes: + """The convention pinned across every open-vocabulary class: an unregistered member's *value* is the caller's own casing, unchanged -- ``FEATCode`` never minted any other way, and :class:`~pcapkit.const.ftp.command.Command`/:class:`~pcapkit.const. @@ -2077,7 +2073,7 @@ def test_method_missing_no_longer_mints(self) -> None: content. This test used to also pin a genuine asymmetry with every *registered* member of this class, tracked as GitHub issue #870: :meth:`Method.__new__` called ``str.__new__(cls)`` with no argument - at all, so all 40 declared members' own :class:`str` payload was + at all, so every declared member's own :class:`str` payload was permanently empty regardless of value (``str(Method.GET) == ''``, ``Method.GET == 'GET'`` was :obj:`False`) -- true on ``main`` at ``60b85e3a4`` as well as when this test was first written. #870 @@ -2195,8 +2191,8 @@ def test_commandtype_is_untouched(self) -> None: class BespokeGetReplacementTests(unittest.TestCase): """:class:`~pcapkit.const.http.status_code.StatusCode` and - :class:`~pcapkit.const.ftp.return_code.ReturnCode` are the two of the - five converted classes whose hand-written ``get()`` -- on the + :class:`~pcapkit.const.ftp.return_code.ReturnCode` are the + converted classes whose hand-written ``get()`` -- on the ``default == -1`` convention #857/#859 already retired everywhere else -- was removed in favour of the base's :meth:`~pcapkit.corekit.enum. EnumRegistry.get`, which uses :data:`~pcapkit.corekit.sentinels.NO_DEFAULT` diff --git a/tests/const/test_const_ethertype_862_unit.py b/tests/const/test_const_ethertype_862_unit.py index fe8792cb9..a5d3b0acd 100644 --- a/tests/const/test_const_ethertype_862_unit.py +++ b/tests/const/test_const_ethertype_862_unit.py @@ -26,7 +26,7 @@ every range test in the committed, generated file (measured directly against ``main`` at ``70fa92010``, the #861 merge commit this issue was blocked on) found this to be the *only* containment pair among them -- no other subsumed -range exists in :class:`~pcapkit.const.reg.ethertype.EtherType` today, so +range exists in :class:`~pcapkit.const.reg.ethertype.EtherType`, so :class:`EtherTypeGeneratorGeneralOrderingTests` below pins the algorithm itself against synthetic nested ranges rather than a second real-world pair. diff --git a/tests/const/test_const_linktype_209_unit.py b/tests/const/test_const_linktype_209_unit.py index 3bd82b8f3..c772ec921 100644 --- a/tests/const/test_const_linktype_209_unit.py +++ b/tests/const/test_const_linktype_209_unit.py @@ -83,7 +83,7 @@ #: ``html5lib`` is the one that is actually missing on ``test``: ``requests`` and #: ``bs4`` have shipped in the ``test`` extra since #507, but only #: ``beautifulsoup4[html5lib]`` -- the ``vendor`` and ``dev`` extras -- provides a -#: parser (``pyproject.toml:234``, and the note at ``:313-320`` saying so +#: parser (``pyproject.toml:238``, and the note at ``:325-332`` saying so #: deliberately). VENDOR_DEPS = ('requests', 'bs4', 'html5lib') @@ -93,7 +93,8 @@ #: #: Consequence worth knowing: :class:`LinkTypeGeneratorLegacyOrderingTests` is the #: root-cause pin, and it runs only where the ``vendor`` extra is installed, -#: which no CI job does since #849 -- so locally only. +#: which no ``unit-tests.yml`` job does (#849) -- so locally, and in +#: ``cron-vendor.yml`` only when a crawl changed a constant module (#1853). #: :class:`LinkType209ConstResolutionTests` #: needs no parser and so still guards the reported symptom everywhere. HAS_VENDOR_DEPS = all(importlib.util.find_spec(name) is not None for name in VENDOR_DEPS) diff --git a/tests/const/test_const_method_case_sensitive_896_unit.py b/tests/const/test_const_method_case_sensitive_896_unit.py index cc00385b6..4d3f77b16 100644 --- a/tests/const/test_const_method_case_sensitive_896_unit.py +++ b/tests/const/test_const_method_case_sensitive_896_unit.py @@ -60,7 +60,7 @@ :mod:`pcapkit.vendor.http.method` itself (its own ``LINE`` lambda), not from the shared one in :mod:`pcapkit.vendor.default` -- so the parity check here renders that module's own template with a CSV fixture reconstructed from the -40 members the committed file already declares, offline, and compares the +members the committed file already declares, offline, and compares the result against the committed file byte for byte, rather than against a synthetic single-member sample. diff --git a/tests/const/test_const_method_value_lookup_908_unit.py b/tests/const/test_const_method_value_lookup_908_unit.py index ab1a26a16..d0a0bda72 100644 --- a/tests/const/test_const_method_value_lookup_908_unit.py +++ b/tests/const/test_const_method_value_lookup_908_unit.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- """``Method.get`` must consult ``_value2member_map_``, not only ``_member_map_``. -GitHub issue #908. :class:`~pcapkit.const.http.method.Method` has 40 members, -and exactly two of them -- ``BASELINE_CONTROL`` (value ``'BASELINE-CONTROL'``) -and ``VERSION_CONTROL`` (value ``'VERSION-CONTROL'``) -- have a member *name* +GitHub issue #908. Of :class:`~pcapkit.const.http.method.Method`'s members, +only ``BASELINE_CONTROL`` (value ``'BASELINE-CONTROL'``) +and ``VERSION_CONTROL`` (value ``'VERSION-CONTROL'``) have a member *name* that differs from their *value*, because a hyphen cannot appear in a Python identifier. The override's own ``get`` checked only ``_member_map_`` (names) and fell straight through to building an *unregistered* member on any miss, @@ -52,7 +52,7 @@ would therefore be caller-visible (a non-``None`` ``default`` on an unknown ``key`` would start resolving to an *existing* registered member instead of minting a new one carrying that string), even though nothing in this tree -currently calls ``get`` with a non-``None`` ``default`` to notice -- +calls ``get`` with a non-``None`` ``default`` to notice -- confirmed by grepping every call site under ``pcapkit/`` and ``tests/``. So the signature and the default's meaning are left exactly as they were; :class:`DefaultSignatureTests` below pins that explicitly. diff --git a/tests/const/test_const_registry_protocol.py b/tests/const/test_const_registry_protocol.py index 1dec8245a..4c80a95fc 100644 --- a/tests/const/test_const_registry_protocol.py +++ b/tests/const/test_const_registry_protocol.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- """Tests for :class:`pcapkit.corekit.enum.EnumRegistry`, tier 2 of issue #775. -Tier 1 (#838) removed the mint from the two sites in -:data:`pcapkit.vendor.default.LINE` that the 107 default-template registries -inherit. It could not reach the eleven crawlers that replace that template with +Tier 1 (#838) removed the mint from the sites in +:data:`pcapkit.vendor.default.LINE` that the default-template registries +inherit. It could not reach the crawlers that replace that template with their own, because each of those carries a hand-copied ``get()`` -- and none of them carries ``register``, ``register_alias`` or ``get_all`` at all. @@ -676,7 +676,7 @@ class _Str(EnumRegistry, StrEnum): self.assertNotIn('unit_test_absent', _Str.__members__) -#: Sample of the 107 default-template registries GitHub issue #775's tier 3 +#: Sample of the default-template registries GitHub issue #775's tier 3 #: moved onto :class:`~pcapkit.corekit.enum.EnumRegistry`, chosen to cover #: the two shapes the census turned up in ``pcapkit/vendor/default.py``'s #: ``LINE`` template: a registry whose own ``_missing_`` mints directly via @@ -714,9 +714,9 @@ class _Str(EnumRegistry, StrEnum): #: custom ``__new__`` needed one. They stay excluded from *this* file's #: tier-3 sweep regardless, because the exclusion here is about their #: bespoke ``process()``/``get()`` shape not sharing the generated template, -#: which conversion onto the base does not change -- unlike the 107 -#: :data:`GENERATED_SAMPLE` registries below, each of these five classes' -#: (nine files') own ``_missing_`` stays bespoke rather than sharing the +#: which conversion onto the base does not change -- unlike the +#: default-template registries :data:`GENERATED_SAMPLE` samples above, each +#: of these classes' own ``_missing_`` stays bespoke rather than sharing the #: generated template, and several also keep a bespoke #: ``_unregistered_member`` (``Command``, ``Method``, ``OptionType``, #: ``ReturnCode``, ``StatusCode``) or a bespoke ``get`` of their own @@ -796,7 +796,7 @@ class _Str(EnumRegistry, StrEnum): class GeneratedTemplateSourceInheritsTests(unittest.TestCase): - """The 107 default-template registries must inherit the protocol too, + """The default-template registries must inherit the protocol too, not just the six bespoke ones :class:`GeneratedSourceInheritsTests` above (tier 2) already covers.""" @@ -976,7 +976,7 @@ def test_transtype_no_longer_mints_its_declared_unassigned_range(self) -> None: class RegisterAlreadyRegisteredNowRaisesOnAGeneratedRegistryTests(unittest.TestCase): """The residue #855 disclosed and this tier's own instructions name: ``register()`` on an already-registered value used to silently alias - rather than mint or raise, on every one of the 107 generated registries + rather than mint or raise, on every one of the generated registries (they had no guard of their own -- only the six bespoke ones tier 2 already fixed did). Measured directly, before and after, in the docstring below rather than only asserted. @@ -1314,7 +1314,7 @@ class NoDefaultSentinelTests(unittest.TestCase): Before #857, ``default == NO_DEFAULT`` read a caller-supplied ``-1`` -- or, worse, ``-1.0``, since ``-1.0 == -1`` -- as if no default had been supplied at all, so the caller's own fallback silently never took effect. - There is no live defect in :mod:`pcapkit.const` today (no registry's + There is no live defect in :mod:`pcapkit.const` (no registry's domain reaches ``-1``), so this batch pins the *clarity* fix: ``-1`` and ``-1.0`` are ordinary defaults now, indistinguishable from any other value a caller might pass. diff --git a/tests/corekit/test_fields_copy_dispatch_runtime.py b/tests/corekit/test_fields_copy_dispatch_runtime.py index 11e3a430e..c2e871dca 100644 --- a/tests/corekit/test_fields_copy_dispatch_runtime.py +++ b/tests/corekit/test_fields_copy_dispatch_runtime.py @@ -8,7 +8,7 @@ matters -- that swapping the dispatch did not move a single byte of what :func:`~pcapkit.interface.core.extract` produces. -Every field of every protocol is copied through one of the eight call sites +Every field of every protocol is copied through one of the call sites #730 named, once per field per packet, so a mistake in any of them is not confined to one protocol -- it is exactly the kind of change that wants a broad, mechanical check rather than a handful of hand-picked assertions. Each diff --git a/tests/corekit/test_fields_copy_dispatch_unit.py b/tests/corekit/test_fields_copy_dispatch_unit.py index 45ec9b4cd..658941c58 100644 --- a/tests/corekit/test_fields_copy_dispatch_unit.py +++ b/tests/corekit/test_fields_copy_dispatch_unit.py @@ -3,7 +3,7 @@ Every field's :meth:`~pcapkit.corekit.fields.field.FieldBase.__call__` made a defensive copy of ``self`` once per field per packet, via -``copy.copy(self)`` at eight call sites across +``copy.copy(self)`` at call sites across :mod:`pcapkit.corekit.fields.field`, :mod:`pcapkit.corekit.fields.collections` and :mod:`pcapkit.corekit.fields.misc`. Profiling ``extract()`` on ``examples/captures/http.pcap`` attributed 55,846 ``getattr`` calls (~1.7% of @@ -16,7 +16,7 @@ ``copier = getattr(cls, '__copy__', None); copier(x)`` is exactly ``x.__copy__()``, so calling it directly does not change *when* a field is copied or what the copy contains -- only the redundant lookup is removed. This -module proves that: every one of the eight call sites now reaches +module proves that: every one of those call sites reaches :meth:`FieldBase.__copy__` without ever calling :func:`copy.copy`. On the tree before this fix, every test below fails: each ``__call__`` diff --git a/tests/corekit/test_fields_ipaddress.py b/tests/corekit/test_fields_ipaddress.py index 406c4ae98..03e620952 100644 --- a/tests/corekit/test_fields_ipaddress.py +++ b/tests/corekit/test_fields_ipaddress.py @@ -347,7 +347,7 @@ def test_parse_ip_address_malformed_value_raises_in_library_error(self) -> None: def test_parse_ip_address_pins_the_family_when_version_is_given(self) -> None: """``version=4`` and ``version=6`` each select a *different* stdlib constructor. - Worth stating on its own because **no caller passes ``version=4`` today** -- + Worth stating on its own because **no caller passes ``version=4``** -- only the HIP locator passes a version at all, and it passes ``6`` -- so nothing else in the suite pins what ``version=4`` does. An unexercised parameter is one that can be broken without a failure, and the widening it diff --git a/tests/corekit/test_fields_misc_packet_context.py b/tests/corekit/test_fields_misc_packet_context.py index a53d6e8bd..aabe5a2b6 100644 --- a/tests/corekit/test_fields_misc_packet_context.py +++ b/tests/corekit/test_fields_misc_packet_context.py @@ -212,7 +212,7 @@ def test_pcapng_block_type_mismatch_consumer_still_works_with_both_shapes(self) Mirrors ``tests/protocols/misc/test_pcapng_unit.py``'s own ``UnknownBlock(...).post_process({'__packet__': {...}})`` call, and additionally checks it still resolves the enclosing block's type when - handed what ``SchemaField`` builds today. + handed what ``SchemaField`` builds. """ from pcapkit.corekit.fields.misc import nested_packet_context diff --git a/tests/corekit/test_fields_numbers.py b/tests/corekit/test_fields_numbers.py index 792d1a76f..185af5068 100644 --- a/tests/corekit/test_fields_numbers.py +++ b/tests/corekit/test_fields_numbers.py @@ -158,7 +158,7 @@ def test_a_class_fixing_a_sign_without_a_template_parses_with_that_sign(self) -> template was built from the raw ``signed`` *argument*. A subclass that fixes ``__signed__`` and leaves ``__template__`` unset -- which the base class explicitly allows, and which nothing in ``pcapkit`` happens - to do today -- therefore declared itself signed and then unpacked + to do -- therefore declared itself signed and then unpacked unsigned: ``>I`` for a class saying ``__signed__ = True``, so ``b'\\xff\\xff\\xff\\xff'`` parsed as ``4294967295`` instead of ``-1``. diff --git a/tests/corekit/test_fields_numbers_port_option_no_mint_unit.py b/tests/corekit/test_fields_numbers_port_option_no_mint_unit.py index 9c0f37bb1..dbdff0dd7 100644 --- a/tests/corekit/test_fields_numbers_port_option_no_mint_unit.py +++ b/tests/corekit/test_fields_numbers_port_option_no_mint_unit.py @@ -262,7 +262,7 @@ def test_an_in_library_rejection_is_not_absorbed(self) -> None: Patches the TCP registry's ``_missing_`` to reject with one of :mod:`pcapkit.utilities.exceptions`, which a blanket ``except ValueError: pass`` would have swallowed. Nothing under - :mod:`pcapkit.const` actually raises one here today -- this is the + :mod:`pcapkit.const` actually raises one here -- this is the stand-in the fallback still has to respect regardless. """ diff --git a/tests/dumpkit/test_capture_dump_runtime.py b/tests/dumpkit/test_capture_dump_runtime.py index ccc6f7d7a..041752784 100644 --- a/tests/dumpkit/test_capture_dump_runtime.py +++ b/tests/dumpkit/test_capture_dump_runtime.py @@ -48,7 +48,7 @@ class Gap(NamedTuple): - """One check that fails today, and the defect that stops it.""" + """One check that fails, and the defect that stops it.""" #: Tracking issue, or :data:`None` while the defect is not yet filed. issue: 'Optional[int]' @@ -58,7 +58,7 @@ class Gap(NamedTuple): defect: 'str' -#: Every check that fails today, by test method; each applies to every capture. +#: Every check that fails, by test method; each applies to every capture. KNOWN_FAILURES = {} # type: dict[str, Gap] diff --git a/tests/dumpkit/test_nameless_enum_rendering_unit.py b/tests/dumpkit/test_nameless_enum_rendering_unit.py index 6d99bf4f7..09ec2eae7 100644 --- a/tests/dumpkit/test_nameless_enum_rendering_unit.py +++ b/tests/dumpkit/test_nameless_enum_rendering_unit.py @@ -220,7 +220,7 @@ def test_addon_branch_renders_a_nameless_member(self) -> None: Reached when the member carries public instance attributes, which for a pseudo-member takes a :meth:`~enum.Enum._missing_` override. No registry under :mod:`pcapkit.const` is both a flag enumeration and an annotated - one today, so this branch is not reachable from a capture on ``main`` -- + one, so this branch is not reachable from a capture on ``main`` -- but the interpolation was character-for-character the same as the other two, so it is guarded with them rather than left as the one place the literal ``None`` survives. diff --git a/tests/foundation/_roundtrip.py b/tests/foundation/_roundtrip.py index a7ceadffa..56768405d 100644 --- a/tests/foundation/_roundtrip.py +++ b/tests/foundation/_roundtrip.py @@ -2,7 +2,7 @@ """Shared harness for the foundation round-trip modules. C.f. #1202. The owner's rule is that every round trip the library promises passes and -matches exactly. Three foundation paths make such a promise, and each has a +matches exactly. Each foundation path that makes such a promise has a module beside this one that enumerates its cases: * reassembly recovers the payload its fragments or segments were cut from diff --git a/tests/project/test_bump_version.py b/tests/project/test_bump_version.py index a75dc9ede..b4ac857c9 100644 --- a/tests/project/test_bump_version.py +++ b/tests/project/test_bump_version.py @@ -255,8 +255,8 @@ def test_only_the_two_fields_change(self) -> None: ], f'unexpected lines moved: {moved!r}') def test_the_comment_header_survives(self) -> None: - # The real file opens with sixteen lines explaining why it omits ``doi`` - # and ``orcid``. A YAML load-and-dump round trip would drop all of them, + # The real file opens with a comment block explaining why it omits ``doi`` + # and ``orcid``. A YAML load-and-dump round trip would drop all of it, # which is why the rewrite is line-oriented. rewritten = bump_version.plan_citation(FIXTURE, '1.5.0b5', '2026-09-22') diff --git a/tests/project/test_capture_tracking.py b/tests/project/test_capture_tracking.py index fce869df1..dc82b55d3 100644 --- a/tests/project/test_capture_tracking.py +++ b/tests/project/test_capture_tracking.py @@ -91,7 +91,7 @@ def test_every_tracked_file_is_an_input_capture(self) -> None: def test_no_rendered_report_is_tracked(self) -> None: """:data:`RENDERED_REPORTS` by name, in case the suffix rule is relaxed. - Redundant with :meth:`test_every_tracked_file_is_an_input_capture` today + Redundant with :meth:`test_every_tracked_file_is_an_input_capture` and deliberately so: that test's reach depends on :data:`~tests._tiers.CAPTURE_SUFFIXES`, and a future ``.txt`` capture format would widen the suffix list and quietly let these back in. diff --git a/tests/project/test_changelog_md.py b/tests/project/test_changelog_md.py index bc82b61b7..cb566a468 100644 --- a/tests/project/test_changelog_md.py +++ b/tests/project/test_changelog_md.py @@ -6,8 +6,8 @@ the ``Create Release`` workflow's release body and the source distribution get Markdown without a second copy of the history to keep in step by hand. -The conversion is six mechanical rules over a small reStructuredText subset, and -there is one test per rule. Each asserts both halves -- that the Markdown form +The conversion is a set of mechanical rules over a small reStructuredText subset, +and there is one test per rule. Each asserts both halves -- that the Markdown form arrived *and* that the reStructuredText form is gone -- because a rule that fires in the wrong place and a rule that does not fire at all both leave markup in a published release body, and only checking for the new spelling would miss the @@ -67,7 +67,7 @@ def _load_generator(): changelog_md = _load_generator() -#: One entry exercising all six rules at once: a setext heading, a wrapped +#: One entry exercising every rule at once: a setext heading, a wrapped #: paragraph, ``*`` bullets whose text wraps, an ``:rfc:`` role, a double-backtick #: literal, and a footnote reference with its definition. ENTRY = """\ diff --git a/tests/project/test_ci_timing.py b/tests/project/test_ci_timing.py index 609755c5e..f79f23def 100644 --- a/tests/project/test_ci_timing.py +++ b/tests/project/test_ci_timing.py @@ -954,7 +954,7 @@ def test_a_blocking_leg_stays_hard(self) -> 'None': self.assertFalse(ci_timing.non_blocking(workflow, 'Python 3.14t (experimental) extra')) def run_report(self, workflow: 'str', name: 'str', took: 'float') -> 'tuple[int, str]': - """``_report`` on five runs of one job taking ``took`` minutes, against the real file.""" + """``_report`` on ``ci_timing.MIN_SAMPLES`` runs of one job taking ``took`` minutes, against the real file.""" start = datetime.datetime(2026, 10, 9, 10, tzinfo=datetime.timezone.utc) runs = [] for number in range(ci_timing.MIN_SAMPLES): diff --git a/tests/project/test_experimental_concurrency_1903.py b/tests/project/test_experimental_concurrency_1903.py index 4be394b3d..fd16c5c3e 100644 --- a/tests/project/test_experimental_concurrency_1903.py +++ b/tests/project/test_experimental_concurrency_1903.py @@ -80,8 +80,8 @@ def setUp(self) -> None: self.own = Concurrency('experimental.yml') def test_the_cases_below_cover_every_trigger(self) -> None: - # Pushes to `main` and pull requests are all experimental.yml runs on - # today; the other events below are the guard for a trigger added later. + # Pushes to `main` and pull requests are all experimental.yml runs on; + # the other events below are the guard for a trigger added later. with open(WORKFLOWS / 'experimental.yml', encoding='utf-8') as file: spec = yaml.safe_load(file) on = spec.get('on', spec.get(True)) diff --git a/tests/project/test_isort_clean.py b/tests/project/test_isort_clean.py index a11189596..99c92ca68 100644 --- a/tests/project/test_isort_clean.py +++ b/tests/project/test_isort_clean.py @@ -88,7 +88,7 @@ needed for this, and none is set). If only *one* of the two came back empty, though, the other's files would still reach ``isort`` in that same invocation, which would exit 0 having quietly sorted half the tree. Neither -case is reachable today -- no path under :file:`pcapkit/const/` or +case is reachable -- no path under :file:`pcapkit/const/` or :file:`pcapkit/vendor/` contains whitespace to break the expansion, and neither directory can be absent where ``make isort`` runs -- but it is the same shape of latent gap #765 itself was, so the third fix, now in place, is diff --git a/tests/project/test_pyshark_encap_map.py b/tests/project/test_pyshark_encap_map.py index 7af1b9e6b..7edf90238 100644 --- a/tests/project/test_pyshark_encap_map.py +++ b/tests/project/test_pyshark_encap_map.py @@ -661,7 +661,7 @@ class VersionIndependentInvariantTests(unittest.TestCase): """Properties of a real sweep that hold on any Wireshark, not only 4.6.9. Where :class:`RealSweepTests` skips -- any Wireshark that is not - :data:`MEASURED_WIRESHARK_VERSION`, which is every CI leg today -- this + :data:`MEASURED_WIRESHARK_VERSION`, which is every CI leg -- this still runs the real sweep against whatever :program:`editcap`/ :program:`tshark` *is* on ``PATH`` (224 accepted on CI's Ubuntu noble 4.2.2, not the 226 :class:`RealSweepTests` requires) and checks structure diff --git a/tests/project/test_python_versions_1660.py b/tests/project/test_python_versions_1660.py index 8090782f7..d0ae271f8 100644 --- a/tests/project/test_python_versions_1660.py +++ b/tests/project/test_python_versions_1660.py @@ -329,7 +329,7 @@ def write_tiers(directory: 'pathlib.Path', data: 'dict[str, Any]') -> 'pathlib.P TOMLLIB_FLOOR = (3, 11) #: The ``python3`` each runner label a job runs the script on puts on ``PATH``, every #: image it may mean: actions/runner-images at 2c421200c (2026-10-12), "Language and -#: Runtime" in images/ubuntu/Ubuntu2404-Readme.md:28 (``ubuntu-latest`` today), +#: Runtime" in images/ubuntu/Ubuntu2404-Readme.md:28 (what ``ubuntu-latest`` named then), #: Ubuntu2604-Readme.md:27 (from 2026-10-19) and images/macos/macos-26-arm64-Readme.md:28 #: (``macos-latest``). Ubuntu2204-Readme.md:30's is 3.10.12, which has no tomllib. RUNNER_PYTHON3 = {'ubuntu-latest': ((3, 12), (3, 14)), 'macos-latest': ((3, 14),)} diff --git a/tests/project/test_python_versions_update_1660.py b/tests/project/test_python_versions_update_1660.py index 42e9e7a67..562ec49ae 100644 --- a/tests/project/test_python_versions_update_1660.py +++ b/tests/project/test_python_versions_update_1660.py @@ -101,7 +101,7 @@ def workflow() -> 'dict[str, Any]': def snapshot() -> 'dict[str, Any]': - """The four sources as saved on 2026-10-13, parsed.""" + """The sources as saved on 2026-10-13, parsed.""" return copy.deepcopy(updater().parse_sources(updater().read_sources(FIXTURES))) @@ -203,7 +203,7 @@ def scratch(test: 'unittest.TestCase', regenerate: 'bool' = True) -> 'pathlib.Pa def save_sources(test: 'unittest.TestCase', sources: 'dict[str, Any]') -> 'pathlib.Path': - """``sources`` written as the four files ``update --sources`` reads.""" + """``sources`` written as the files ``update --sources`` reads.""" tmp = tempfile.TemporaryDirectory(prefix='pcapkit-1660b-sources-') # pylint: disable=consider-using-with test.addCleanup(tmp.cleanup) directory = pathlib.Path(tmp.name) diff --git a/tests/project/test_rfc_anchor_fragments.py b/tests/project/test_rfc_anchor_fragments.py index 98025f4ea..a75fe6ed2 100644 --- a/tests/project/test_rfc_anchor_fragments.py +++ b/tests/project/test_rfc_anchor_fragments.py @@ -50,7 +50,7 @@ them. The third shape is dropped from :data:`ACCEPTED_FRAGMENT` entirely. :data:`ACCEPTED_FRAGMENT`'s set is not a survey of shapes this tree happens to -use today -- it is Sphinx's own. ``sphinx.roles._format_rfc_target`` titles +use -- it is Sphinx's own. ``sphinx.roles._format_rfc_target`` titles exactly three anchor prefixes, ``{'appendix', 'page', 'section'}``, and :file:`tests/project/test_changelog_md.py` already exercises ``#page-N`` as a correctly-rendered citation (``793#page-5``); confirmed real against RFC @@ -67,8 +67,8 @@ than a shape check. A bare ``section`` with no number is indistinguishable from a citation that dropped its number, the same incompleteness this test exists to catch -- Sphinx happening not to error on it is not the same claim -as it being a well-formed citation. Neither shape appears under :mod:`pcapkit` -today, so this changes nothing here; rejecting is the more conservative +as it being a well-formed citation. Neither shape appears under :mod:`pcapkit`, +so this changes nothing here; rejecting is the more conservative default should either turn up later. One thing the shape check above does not catch: whether the anchor actually @@ -166,8 +166,8 @@ #: #: The bounded question is a different size. Rather than classifying every literal in #: the tree -- **23,869** spans across **926** files, every one of which had to be got -#: right -- it asks only where a *denylisted fragment* appears, which is **2** -#: occurrences today, and classifies each against this list. Adding a form means one +#: right -- it asks only where a *denylisted fragment* appears, which is a +#: handful of occurrences, and classifies each against this list. Adding a form means one #: reviewed entry, the same scrutiny :data:`KNOWN_DEAD_ANCHORS` entries already get. QUOTED_FORMS: 'tuple[tuple[str, str], ...]' = ( ('``', '``'), diff --git a/tests/project/test_workflow_apt_timeouts.py b/tests/project/test_workflow_apt_timeouts.py index fcb80edd7..bbeb96b2d 100644 --- a/tests/project/test_workflow_apt_timeouts.py +++ b/tests/project/test_workflow_apt_timeouts.py @@ -20,7 +20,7 @@ workflow whose script invokes ``apt-get`` must declare a ``timeout-minutes``, and that value must be below its job's own budget.** Stated that way it also catches a *new* apt-installing step added later without a bound, in a workflow -that has none today. +that has none. The second half of the rule matters as much as the first. A step timeout at or above the job's budget is decorative -- the job's own timer fires first and the @@ -70,14 +70,14 @@ #: Every workflow, rather than only the one #974 was filed against. The hazard is #: a property of invoking apt unbounded, not of a particular file, and scanning -#: the directory is what lets a new apt step in a workflow that has none today be +#: the directory is what lets a new apt step in a workflow that has none be #: caught by this module rather than by a stalled run. WORKFLOW_DIR = ROOT / '.github' / 'workflows' #: What counts as invoking apt. A substring of the comment-stripped step script, #: coarse on purpose: ``sudo apt-get``, ``DEBIAN_FRONTEND=noninteractive #: apt-get`` and a bare ``apt-get`` all match, as does an invocation this -#: repository does not currently write. +#: repository does not write. #: #: It does not match :program:`apt`, :program:`aptitude`, or a package manager #: reached some other way. That is the same allowlist limitation @@ -87,7 +87,7 @@ #: means adding its marker here. APT_MARKER = 'apt-get' -#: The steps known to invoke apt today, as ``(workflow name, step name)``. Quoted +#: The steps known to invoke apt, as ``(workflow name, step name)``. Quoted #: so :class:`TestTheScannerIsNotBlind` can tell "the rule holds everywhere" from #: "the scanner found nothing to check", which look identical in a passing run. KNOWN_APT_STEPS = { diff --git a/tests/protocols/application/test_http_unit.py b/tests/protocols/application/test_http_unit.py index 7981a5db8..370baf632 100644 --- a/tests/protocols/application/test_http_unit.py +++ b/tests/protocols/application/test_http_unit.py @@ -1470,7 +1470,7 @@ def test_guess_version_does_not_suppress_struct_error_on_the_http1_arm(self) -> ``ProtocolError`` rather than a bare :exc:`struct.error`), but neither retired the suppression: it stays as defence in depth for any ``__length__``-keyed field #805 did not individually verify, across - the ten schema modules that share the pattern. See + the schema modules that share the pattern. See ``test_guess_version_reports_unknown_version_for_a_short_payload`` for the outer-header case #799 closed, and ``test_guess_version_no_longer_leaks_a_bare_struct_error_for_an_inner_field_shortfall`` @@ -1525,7 +1525,7 @@ def test_guess_version_no_longer_leaks_a_bare_struct_error_for_an_inner_field_sh Pre-#805, that raised a bare :exc:`struct.error` straight through ``httpv2.HTTP``; #805 closed the actual root, generic ``FieldBase.length`` (``struct.calcsize`` on a negative-count template), - shared by at least ten schema modules, not something httpv2-specific -- + shared by many schema modules, not something httpv2-specific -- so direct construction now raises :exc:`ProtocolError` too. ``_guess_version``'s last arm keeps suppressing :exc:`struct.error` @@ -1533,7 +1533,7 @@ def test_guess_version_no_longer_leaks_a_bare_struct_error_for_an_inner_field_sh revision of this fix did, regressed the direct ``HTTP()`` guess path for a *different* input class (the sub-nine-octet outer-header one), and #805 does not touch every ``__length__``-keyed field in every one - of those ten modules, so the suppression stays as defence in depth. + of those modules, so the suppression stays as defence in depth. This test drives real wire bytes through the actual guess path -- no ``mock.patch`` -- specifically because a mocked fault cannot see a regression in the *un-mocked* route the fault is meant to stand in for. diff --git a/tests/protocols/application/test_layer_placement_unit.py b/tests/protocols/application/test_layer_placement_unit.py index f5abc2cdc..ffd10ae42 100644 --- a/tests/protocols/application/test_layer_placement_unit.py +++ b/tests/protocols/application/test_layer_placement_unit.py @@ -197,12 +197,12 @@ def test_dispatch_keys_did_not_move_with_the_modules(self) -> None: self.assertIs(getattr(importlib.import_module(entry.module), entry.name), cls) def test_ospf_leaves_links_registry_behind_and_rarp_keeps_it(self) -> None: - """``Link`` sets ten names of its own; OSPF loses four of them. + """``Link`` sets names of its own; OSPF loses its EtherType machinery. ``__proto__``, its shipped copy ``_shipped_proto``, ``register`` and - ``_read_protos`` are ``Link``'s EtherType machinery, and OSPF takes all - four from ``ProtocolBase`` instead. The first assertion pins seven of the - ten. The loss is inert because a ``-1`` lookup misses in either + ``_read_protos`` are ``Link``'s EtherType machinery, and OSPF takes each + of them from ``ProtocolBase`` instead. The first assertion pins a subset + of ``Link``'s own names. The loss is inert because a ``-1`` lookup misses in either registry and falls back to :class:`~pcapkit.protocols.misc.raw.Raw`. """ from pcapkit.protocols.application.ospf import OSPF diff --git a/tests/protocols/application/test_ospf_unit.py b/tests/protocols/application/test_ospf_unit.py index d68660b3e..085d17d9c 100644 --- a/tests/protocols/application/test_ospf_unit.py +++ b/tests/protocols/application/test_ospf_unit.py @@ -155,7 +155,7 @@ def test_ospf_id_numbers_rejects_a_bool(self) -> None: """A :obj:`bool` router/area ID must not be silently packed. See #540. Latent rather than live: nothing in this module calls ``_make_id_numbers`` - today -- ``OSPF.make`` builds ``router_id``/``area_id`` from its own + -- ``OSPF.make`` builds ``router_id``/``area_id`` from its own arguments rather than through this helper -- so only a unit test (this one, and the pre-existing one above) reaches it. It is fixed alongside the three live sites anyway, so that it does not resurface the moment a future caller diff --git a/tests/protocols/internet/test_hip_unit.py b/tests/protocols/internet/test_hip_unit.py index 5d83ab421..8662d077c 100644 --- a/tests/protocols/internet/test_hip_unit.py +++ b/tests/protocols/internet/test_hip_unit.py @@ -2835,7 +2835,7 @@ def test_hip_puzzle_lifetime_guard_raises_an_in_library_error(self) -> None: readers raise for a malformed ``PUZZLE`` or ``SOLUTION``, and it is declared ``ProtocolError(BaseError, ValueError)`` -- so it joins the family *and* stays catchable by any caller already written around the - :exc:`ValueError` that escapes today. Both halves are asserted below, + :exc:`ValueError` that escapes. Both halves are asserted below, because the second is what makes this a non-breaking change. :class:`~pcapkit.utilities.exceptions.EnumError` would not do: it is ``EnumError(BaseError, TypeError)``, so it would silently stop being caught. @@ -3160,7 +3160,7 @@ def rfc_total(length: int) -> int: return 11 + length - (length + 3) % 8 def pre_651_total(length: int) -> int: - """What every one of the 95 padding sites computed before #651.""" + """What every padding site computed before #651.""" return 4 + length + (8 - (length % 8)) % 8 for length in range(64): @@ -3339,8 +3339,8 @@ def test_hip_parameter_records_are_eight_octet_aligned_on_the_wire(self) -> None """#651: the octets a real parameter packs, not just the arithmetic. :func:`~pcapkit.protocols.schema.internet.hip.parameter_total_len` being - right is necessary but not sufficient -- all 46 padding sites in the - schema module have to *use* it. So this packs real parameter schemas, + right is necessary but not sufficient -- every padding site in the + schema module has to *use* it. So this packs real parameter schemas, chosen to cover the residues that discriminate, and measures the octets. ``SEQ`` is the one to read first. It carries a single four-octet Update @@ -3423,7 +3423,7 @@ def test_hip_parameter_records_are_eight_octet_aligned_on_the_wire(self) -> None for copy in copies: self.assertEqual(copy.id, 0x01020304) # the record length the data model reports is the RFC total, not the - # contents-aligned one -- this is the 49 sites in the protocol module + # contents-aligned one -- this is the protocol module's sites self.assertEqual(copy.length, 8) # and the header's own ``len`` is now exact rather than exact-in-pairs: diff --git a/tests/protocols/internet/test_ipv4_unit.py b/tests/protocols/internet/test_ipv4_unit.py index 92950da2c..a800ddac3 100644 --- a/tests/protocols/internet/test_ipv4_unit.py +++ b/tests/protocols/internet/test_ipv4_unit.py @@ -564,7 +564,7 @@ def test_ipv4_make_opt_sec_sizes_the_bitmap_from_the_bit_count(self) -> None: of eight, which is checked here too. No shipped enumeration member has value ``8``, so that half was latent rather than reachable -- and it is the half that would have corrupted an option instead of raising, so it is - worth pinning even though nothing reaches it today. + worth pinning even though nothing reaches it. """ from pcapkit.const.ipv4.option_number import OptionNumber diff --git a/tests/protocols/internet/test_ipv6_ext_unit.py b/tests/protocols/internet/test_ipv6_ext_unit.py index 4c22fda02..3f7e7e75e 100644 --- a/tests/protocols/internet/test_ipv6_ext_unit.py +++ b/tests/protocols/internet/test_ipv6_ext_unit.py @@ -391,8 +391,8 @@ class IPv6ExtSharedBaseContractTests(unittest.TestCase): the shared base of every IPv6 extension header, *and* the concrete fallback parser for one this package does not implement. - That merge removes a safety net. Before it, each of the eight implemented - headers inherited :class:`~pcapkit.protocols.internet.internet.Internet` + That merge removes a safety net. Before it, each implemented + header inherited :class:`~pcapkit.protocols.internet.internet.Internet` directly, whose ``name``/``alias``/``protocol``/``length`` are generic or abstract and whose ``__index__`` is :func:`abc.abstractmethod` -- so forgetting one was loud. After it, the same omission silently inherits this @@ -401,10 +401,10 @@ class IPv6ExtSharedBaseContractTests(unittest.TestCase): reads its length off a data model that is not its own, and ``__index__`` raises instead of returning its IANA number. - The eight are correct today only because all eight happen to shadow every + The implemented headers are correct only because each happens to shadow every one of those members. Nothing in the language enforces that, so this class does -- over every subclass discovered at runtime rather than a hard-coded - list, so a ninth added later is held to the same contract without anyone + list, so one added later is held to the same contract without anyone remembering to come back here. """ diff --git a/tests/protocols/internet/test_ipv6_option_helpers_1519_unit.py b/tests/protocols/internet/test_ipv6_option_helpers_1519_unit.py index 472b998cd..674b2b001 100644 --- a/tests/protocols/internet/test_ipv6_option_helpers_1519_unit.py +++ b/tests/protocols/internet/test_ipv6_option_helpers_1519_unit.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """The IPv6 option helpers HOPOPT and IPv6-Opts share. -GitHub issue #1519. The nine field helpers of the HOPOPT and IPv6-Opts option +GitHub issue #1519. The field helpers of the HOPOPT and IPv6-Opts option schemas were two copies differing only in the error prefix and in which module's option schemas the selectors return. They now live once, in :mod:`pcapkit.protocols.schema.internet.ipv6_option`, and each header module diff --git a/tests/protocols/internet/test_mh_unit.py b/tests/protocols/internet/test_mh_unit.py index f8fbab360..b72d8ae2a 100644 --- a/tests/protocols/internet/test_mh_unit.py +++ b/tests/protocols/internet/test_mh_unit.py @@ -103,7 +103,7 @@ def test_unregistered_mh_codes_do_not_mutate_the_class_registries(self) -> None: sizes its extension area from ``pkt['length']`` -- a key the nested packet context does not carry -- so :meth:`~pcapkit.protocols.internet.mh.MH._read_cga_extensions` is - unreachable from bytes today. The sibling read site in + unreachable from bytes. The sibling read site in :meth:`~pcapkit.protocols.internet.mh.MH._make_cga_extensions` had the identical defect. @@ -1665,10 +1665,11 @@ def test_mh_get_default_works_uniformly_through_the_inherited_method(self) -> No from pcapkit.utilities.exceptions import EnumKeyError, EnumValueError def _drop_tracebacklimit() -> None: - # The int-value-miss subTest below reaches the loud - # ``_missing_`` on ``key`` itself, which sets this process-wide - # -- restore it so a later test in the same run does not read - # truncated tracebacks because of what this one did. + # The int-value-miss subTests below reach ``_missing_`` on + # ``key`` itself, whose error is quiet inside ``get``'s + # ``_CaughtByCaller`` block (#1845), and no pcapkit error sets + # this (#362). Restored anyway, so a later test in the + # same run cannot read truncated tracebacks because of this one. if hasattr(sys, 'tracebacklimit'): del sys.tracebacklimit diff --git a/tests/protocols/link/test_l2tp_version_unit.py b/tests/protocols/link/test_l2tp_version_unit.py index d12495932..b2c96e5e1 100644 --- a/tests/protocols/link/test_l2tp_version_unit.py +++ b/tests/protocols/link/test_l2tp_version_unit.py @@ -241,7 +241,7 @@ def test_l2tpv3_over_udp_1701_no_longer_parses_as_l2tpv2(self) -> None: """:rfc:`3931` §4.1.2 puts L2TPv3 on port 1701 too, and that is a live capture. This is the part of the change that fixes a real dissection rather than - guarding a hypothetical registration: port 1701 is bound today, so + guarding a hypothetical registration: port 1701 is bound, so before the version guard a v3 datagram arriving on it was dissected as L2TPv2 and reported ``tunnelid=0x1234``/``sessionid=0x5678`` read out of v3's Control Connection ID. :rfc:`3931` §3.2.1 requires ``Ver`` to diff --git a/tests/protocols/test_capture_roundtrip_runtime.py b/tests/protocols/test_capture_roundtrip_runtime.py index cb7f85b00..a23b567d1 100644 --- a/tests/protocols/test_capture_roundtrip_runtime.py +++ b/tests/protocols/test_capture_roundtrip_runtime.py @@ -16,7 +16,7 @@ ``from_dict``. Finally each capture is rebuilt whole, header and records or blocks, and compared with the file. -A case that does not close today is listed in :data:`LAYER_GAPS` or +A case that does not close is listed in :data:`LAYER_GAPS` or :data:`DICT_GAPS` with the issue that tracks it. Both tables are asserted in both directions: a listed case must still fail in the recorded way, a case not listed must pass, and every entry must name a case that exists. diff --git a/tests/protocols/test_construction_keyword_check_unit.py b/tests/protocols/test_construction_keyword_check_unit.py index 0cd0ad26f..b4ef5e8b7 100644 --- a/tests/protocols/test_construction_keyword_check_unit.py +++ b/tests/protocols/test_construction_keyword_check_unit.py @@ -182,7 +182,7 @@ class RejectionTests(unittest.TestCase): def test_the_three_misspellings_of_the_defect_are_each_refused(self) -> None: """Each key of #602, put back one at a time, raises and is named. - ``TCP_BASE`` is correct today, so reproducing the report means + ``TCP_BASE`` is correct, so reproducing the report means reintroducing the misspelling. Before the fix each of these built a segment whose field kept its default -- ``seq=1`` giving ``info.seq == 0`` -- and captured no warning at all. diff --git a/tests/protocols/test_dispatch_registry_unit.py b/tests/protocols/test_dispatch_registry_unit.py index 298397264..cf60d7f79 100644 --- a/tests/protocols/test_dispatch_registry_unit.py +++ b/tests/protocols/test_dispatch_registry_unit.py @@ -3,12 +3,12 @@ GitHub issue #496: the ``__proto__`` dispatch registries decide which :class:`~pcapkit.protocols.protocol.Protocol` subclass parses the next layer. -#496 named seven of them; #904 took them to 39 entries by adding -``Internet.__proto__[TransType.Shim6]``, and #1574 to 47 across eight tables by -adding the loopback one. Nothing walked all of them. +#496 named the original tables; #904 added +``Internet.__proto__[TransType.Shim6]``, and #1574 added the loopback table. +Nothing walked all of them. :file:`test_registry_runtime.py` checks that a table entry *resolves* to the right class object, and -:file:`test_dispatch_bindings_unit.py` checks that eleven hand-picked codes +:file:`test_dispatch_bindings_unit.py` checks that a hand-picked set of codes actually parse a packet into the class the table names -- the property that matters, since a resolvable entry whose target cannot parse a packet is exactly what shipped once: :class:`~pcapkit.protocols.application.ospf.OSPF` was @@ -16,8 +16,8 @@ This module closes the gap the same way :file:`test_option_roundtrip_unit.py` closed it for the option/parameter -registries: :func:`examples.generators.dispatch.cases` walks the eight -``__proto__`` tables directly, so a code registered tomorrow gets a case here +registries: :func:`examples.generators.dispatch.cases` walks every +``__proto__`` table directly, so a code registered tomorrow gets a case here tomorrow -- or fails :meth:`DispatchRegistryTests .test_every_registered_code_has_a_case`, which is what makes the coverage self-maintaining rather than a snapshot of today's registries. @@ -49,7 +49,7 @@ class Degrade(NamedTuple): - """One code known to degrade to :class:`~pcapkit.protocols.misc.raw.Raw` today.""" + """One code known to degrade to :class:`~pcapkit.protocols.misc.raw.Raw`.""" #: Substring the ``'error'`` value :func:`~examples.generators.dispatch.probe` #: found must contain, or ``''`` to assert only that dispatch is degraded. @@ -92,7 +92,7 @@ def _load_generator() -> 'types.ModuleType': @unittest.skipUnless(HAS_RUNTIME, 'runtime dependencies not installed') class DispatchRegistryTests(unittest.TestCase): - """One dispatch probe per entry across all seven ``__proto__`` registries.""" + """One dispatch probe per entry across every ``__proto__`` registry.""" #: The generator module, loaded once for the whole class. Loading it #: imports :mod:`pcapkit`, so it must happen after the purge in @@ -105,7 +105,7 @@ def setUpClass(cls) -> None: purge_modules(['pcapkit']) cls.dispatch = _load_generator() - #: Every case whose dispatch does not reach its registered target today, + #: Every case whose dispatch does not reach its registered target, #: and the recorded reason -- kept in the test rather than only in the #: generator so that a change to either is a change a reviewer sees next #: to the assertion it affects. @@ -145,7 +145,7 @@ def test_every_registered_code_has_a_case(self) -> None: """No registry entry is left without a case. This is what makes the coverage self-maintaining: registering a new - protocol against one of the seven tables and forgetting to add a case + protocol against one of the tables and forgetting to add a case for it fails here, rather than going unnoticed until the entry turns out not to be able to parse a packet. @@ -213,7 +213,7 @@ def test_registry_currently_matches_pinned_target(self) -> None: ) def test_cases_cover_every_table_named_in_the_issue(self) -> None: - """The enumeration finds all 47 entries, across the seven tables of #496 and #1574's loopback table. + """The enumeration finds every entry, across the tables of #496 and #1574's loopback table. A guard on the shape of the result rather than on any one case: if the registries grow or shrink without this module noticing, the per-family diff --git a/tests/protocols/test_option_coverage_runtime.py b/tests/protocols/test_option_coverage_runtime.py index bbb7d5090..7480c1527 100644 --- a/tests/protocols/test_option_coverage_runtime.py +++ b/tests/protocols/test_option_coverage_runtime.py @@ -3,7 +3,7 @@ :file:`examples/generators/options.py` constructs one item of every option-like code the library registers, and writes the ones that survive a construct -> -parse -> construct cycle into five captures. This module reads them back through +parse -> construct cycle into a set of captures. This module reads them back through the public extraction interface. The point is not to re-assert the round trip -- diff --git a/tests/protocols/test_option_generator_tcp_base_unit.py b/tests/protocols/test_option_generator_tcp_base_unit.py index 5fb983863..5341db204 100644 --- a/tests/protocols/test_option_generator_tcp_base_unit.py +++ b/tests/protocols/test_option_generator_tcp_base_unit.py @@ -283,7 +283,7 @@ def test_an_undeclared_keyword_is_now_refused_rather_than_absorbed(self) -> None def test_the_three_keys_of_the_defect_are_each_refused(self) -> None: """Each misspelling of #602 raises, named, rather than being dropped. - ``TCP_BASE`` is correct today, so the mapping itself can no longer + ``TCP_BASE`` is correct, so the mapping itself cannot demonstrate the defect. Putting the three keys back one at a time is what keeps the original report reproducible: before the fix every one of them built a segment whose field kept its default -- ``seq=1`` produced diff --git a/tests/protocols/test_option_roundtrip_unit.py b/tests/protocols/test_option_roundtrip_unit.py index e8ef155ca..8ce6103bc 100644 --- a/tests/protocols/test_option_roundtrip_unit.py +++ b/tests/protocols/test_option_roundtrip_unit.py @@ -22,7 +22,7 @@ enumeration is registry-driven and how the per-code arguments were chosen. What this module adds is the *judgement*: :data:`EXPECTED_FAILURES` records, case -by case, which cycles do not close today and which defect stops each one. A case +by case, which cycles do not close and which defect stops each one. A case absent from that table has to come back ``'OK'``. That table can only speak about cycles that *fail*, though, and a defect can diff --git a/tests/protocols/test_protocol_code_registration_unit.py b/tests/protocols/test_protocol_code_registration_unit.py index 00a6a9e2e..1b3530a28 100644 --- a/tests/protocols/test_protocol_code_registration_unit.py +++ b/tests/protocols/test_protocol_code_registration_unit.py @@ -13,7 +13,7 @@ :class:`~pcapkit.dumpkit.common.Dumper` (#557 renamed ``Engine``'s from ``name=``): omitting ``code`` leaves the subclass unregistered, which is exactly what every built-in protocol class -does today, since the built-in dispatch tables are populated by literal +does, since the built-in dispatch tables are populated by literal assignment in each layer module rather than by ``__init_subclass__``. Most tests here mock the destination classes' ``register`` classmethod (or diff --git a/tests/protocols/transport/test_tcp_mptcp_length_arithmetic_unit.py b/tests/protocols/transport/test_tcp_mptcp_length_arithmetic_unit.py index 402b3dc73..75e6bf553 100644 --- a/tests/protocols/transport/test_tcp_mptcp_length_arithmetic_unit.py +++ b/tests/protocols/transport/test_tcp_mptcp_length_arithmetic_unit.py @@ -87,7 +87,7 @@ 40)`` raised ``struct.error: required argument is not an integer``. #576 left that to :mod:`pcapkit.corekit.fields.numbers`, and **#598 has since fixed it** by recomputing ``_need_process`` from the width in force rather than once from the placeholder, so a callable -length packs and unpacks both widths today. The schema keeps selecting between +length packs and unpacks both widths. The schema keeps selecting between :class:`~pcapkit.corekit.fields.numbers.UInt32Field` and :class:`~pcapkit.corekit.fields.numbers.UInt64Field`, which each fix ``__template__`` at class level, through a :class:`~pcapkit.corekit.fields.misc.SwitchField` -- the pattern diff --git a/tests/test_docstring_contract.py b/tests/test_docstring_contract.py index 45e8ee4e7..58c6448f9 100644 --- a/tests/test_docstring_contract.py +++ b/tests/test_docstring_contract.py @@ -167,8 +167,8 @@ #: does not verify the RFC. What it verifies is the *pairing*: that wherever one #: of these sentences is quoted, the citation introducing it names the section #: the sentence came from. That is the invariant #517 and #530 both broke, and -#: it is checked at every site rather than pinned at the two that are currently -#: wrong, so the next copy-paste of one of these paragraphs into a third module +#: it is checked at every site rather than pinned at the sites those issues +#: found, so the next copy-paste of one of these paragraphs into another module #: is checked when it lands rather than being read past. #: #: Verified against https://www.rfc-editor.org/rfc/rfc8200.txt on 2026-09-20: diff --git a/tests/test_final_enforcement.py b/tests/test_final_enforcement.py index 810134dab..c59db390d 100644 --- a/tests/test_final_enforcement.py +++ b/tests/test_final_enforcement.py @@ -35,7 +35,7 @@ :class:`Info` side, and *silently returned bookkeeping attributes* on the :class:`~pcapkit.protocols.schema.schema.Schema` side. -What the rule costs is nothing today and everything later, which is why it needs +What the rule costs is nothing up front and everything later, which is why it needs tests rather than a measurement. Measured at ``110381b63``: of :class:`Info`'s 488 descendants 455 carry ``__final__`` in their own ``__dict__`` and **none is subclassed**; of :class:`~pcapkit.protocols.schema.schema.Schema`'s 445, 408 do diff --git a/tests/test_tier_guard.py b/tests/test_tier_guard.py index 07fd55cab..df22e8415 100644 --- a/tests/test_tier_guard.py +++ b/tests/test_tier_guard.py @@ -275,7 +275,7 @@ class EnclosingScopeTests(unittest.TestCase): :mod:`ast` tree and a line number, so it is pinned the same way :class:`AuditTests` pins :func:`~tests._tiers.audit_module`: against source written for the purpose, not against whatever the suite happens to - contain today. + contain. """ @@ -306,7 +306,7 @@ def test_it(self): def test_the_innermost_function_wins_over_its_enclosing_method(self) -> None: """A nested helper's line belongs to the helper, not the test method. - Not a shape the suite's own skip idiom uses today, but + Not a shape the suite's own skip idiom uses, but :func:`~tests._tiers.skip_idiom_test_ids` documents that "most tightly wrapping" is the rule, and this is what pins it. @@ -1689,7 +1689,7 @@ def test_the_mypy_gate_is_visible_and_dark_on_every_job_that_reaches_it(self) -> # collect tests/vendor/ at all -- the same reason they are absent from # HAS_VENDOR_DEPS above. engine-tests (#849) no longer reaches it # either: each matrix.engine cell now runs an explicit TEST_PATHS list - # and none of the five names tests/vendor/ -- see the HAS_MYPY + # and none of those lists names tests/vendor/ -- see the HAS_MYPY # exclusion's own reason for why that is a real, disclosed change # rather than a mistake here. for job in ('integration', 'pypcap-parity', 'engine-tests'): @@ -1960,7 +1960,7 @@ class DependencyGateFalsifiabilityTests(unittest.TestCase): """Break the install lines on a copy, and watch the guard fire. These are the only tests here that prove the guard is capable of failing at - all: every assertion in :class:`DependencyGateCoverageTests` passes today on + all: every assertion in :class:`DependencyGateCoverageTests` passes on a tree that is correct, and a wrong analysis would pass just as quietly on one that had been broken. @@ -2439,7 +2439,7 @@ def test_describe_ambiguous_satisfaction_names_residual_ambiguity_too(self) -> N Both real findings above are the "resolved to something illegitimate" shape. The other shape -- resolved to more than one distribution even after narrowing to the legitimate set -- has no real workflow state - that produces it today (the legitimate set for both watched flags is + that produces it (the legitimate set for both watched flags is always a singleton), so it needs its own construction to reach. """ @@ -2546,7 +2546,7 @@ def test_a_workflow_with_no_jobs_block_fails_loudly(self) -> None: def test_a_flag_no_extra_could_satisfy_is_not_reported_as_a_gap(self) -> None: """:data:`~tests._dependency_gates.NON_DISTRIBUTION_FLAGS`, exercised. - No flag in the suite is *gated* on something pip cannot install today -- + No flag in the suite is *gated* on something pip cannot install -- ``HAS_PROC_FD`` asks whether :file:`/proc/self/fd` exists and is consulted inline rather than through a decorator -- so this stands a real gated flag in for one, to pin that naming a flag there suppresses its gap instead of diff --git a/tests/vendor/test_request_prompt_unit.py b/tests/vendor/test_request_prompt_unit.py index 1539e6bec..ac9e42eae 100644 --- a/tests/vendor/test_request_prompt_unit.py +++ b/tests/vendor/test_request_prompt_unit.py @@ -653,7 +653,7 @@ def test_the_prompt_still_repeats_until_the_page_appears(self) -> None: def test_a_successful_fetch_never_consults_stdin(self) -> None: # The quiet direction, and the cheapest regression to introduce: a # precondition evaluated too early would make every crawler depend on - # having a terminal, breaking the CI job that works today. + # having a terminal, breaking the CI job, which has none. crawler = self._crawler() prompt, calls = _fake_input(_Runaway('input() was called on the happy path')) diff --git a/tests/vendor/test_vendor_exit_code_unit.py b/tests/vendor/test_vendor_exit_code_unit.py index db4f828f9..2674f3024 100644 --- a/tests/vendor/test_vendor_exit_code_unit.py +++ b/tests/vendor/test_vendor_exit_code_unit.py @@ -34,10 +34,10 @@ target list itself is stubbed too, by patching the ``pcapkit.vendor.__main__.vendor_module`` name :func:`main` reads its ``__all__`` from -- so this suite never imports, runs, or writes anything -under the real 117 crawlers, and touches no file under :file:`pcapkit/const/`. +under the real crawlers, and touches no file under :file:`pcapkit/const/`. Run against the pre-fix code (``run()`` ending on a bare ``return None`` and -``main()`` ending on a bare ``return 0``), all 5 methods below fail: +``main()`` ending on a bare ``return 0``), every method below fails: :meth:`~ExitCodeTests.test_run_returns_false_for_a_raising_crawler` (``run()`` returns :data:`None`, not the exact value :data:`False` -- :meth:`~unittest.TestCase.assertIs` is what makes this one discriminate: a diff --git a/tests/vendor/test_vendor_missing_body_unit.py b/tests/vendor/test_vendor_missing_body_unit.py index 75d8742bc..ec4c45e9b 100644 --- a/tests/vendor/test_vendor_missing_body_unit.py +++ b/tests/vendor/test_vendor_missing_body_unit.py @@ -89,15 +89,13 @@ #: never covered joins invisibly, because nothing here shrinks when one is #: added. #: -#: Measured on ``main`` at ``946b84e83``: 96 crawler modules define -#: ``process()``. Of those, 35 assign ``miss`` as a list literal of string -#: constants -- the ones this test can see -- 53 build it by ``.append()`` -#: instead, and 8 never return an ``(enum, miss)`` pair at all. That leaves -#: **61 of the 96 invisible to this guard**, not merely the two crawlers used -#: as an example in :func:`_constant_miss_lines`'s docstring below. A crawler -#: that assigns ``miss`` from a comprehension, from a variable, or under a -#: different variable name entirely is skipped by construction too, same as -#: one built by ``.append()``. All 61 are covered behaviourally, not +#: Only those crawlers are visible to this guard. Every other crawler that +#: defines ``process()`` -- one that builds ``miss`` by ``.append()``, or never +#: returns an ``(enum, miss)`` pair at all -- is invisible to it, not merely the +#: crawlers named as examples in :func:`_constant_miss_lines`'s docstring +#: below. A crawler that assigns ``miss`` from a comprehension, from a variable, +#: or under a different variable name entirely is skipped by construction too, +#: same as one built by ``.append()``. Those are covered behaviourally, not #: statically, by :file:`tests/const/test_const_enum_lookup.py`. EXPECTED_CRAWLERS_WITH_CONSTANT_MISS_LINES = 35 @@ -110,11 +108,11 @@ def _constant_miss_lines() -> 'dict[str, list[str]]': ``miss`` by ``.append()``, assigns it from a comprehension or a variable, or never returns an ``(enum, miss)`` pair at all, is absent from the returned mapping entirely -- not present with an empty list. That is - **61 of the 96** crawler modules defining ``process()``, not just the two - examples this docstring used to single out + every other crawler module defining ``process()``, not just the + examples this docstring names (:mod:`pcapkit.vendor.reg.ethertype`, :mod:`pcapkit.vendor.ipx.socket`); - see :data:`EXPECTED_CRAWLERS_WITH_CONSTANT_MISS_LINES` for the full - breakdown. All 61 are covered behaviourally, not statically, by + see :data:`EXPECTED_CRAWLERS_WITH_CONSTANT_MISS_LINES` for the + breakdown. They are covered behaviourally, not statically, by :file:`tests/const/test_const_enum_lookup.py`. """