diff --git a/tests/_dependency_gates.py b/tests/_dependency_gates.py index 034c5190ea..4edc8a56f6 100644 --- a/tests/_dependency_gates.py +++ b/tests/_dependency_gates.py @@ -1392,7 +1392,7 @@ def pytest_jobs(workflow: 'Optional[pathlib.Path]' = None) -> 'tuple[Job, ...]': def job_reaches(job: 'Job', gate: 'Gate') -> 'bool': """Whether ``job``'s selection would collect the tests ``gate`` guards. - The five selection shapes are answered five ways, and none of them + Each selection shape is answered its own way, and none of them reimplements the workflow's own list: * ``'whole-suite'`` reaches everything under :file:`tests/`. diff --git a/tests/_tiers.py b/tests/_tiers.py index 8b96f151f8..87a7c7ed7e 100644 --- a/tests/_tiers.py +++ b/tests/_tiers.py @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- """The test suite's tier rule, and the machinery that enforces it. -The suite runs in two tiers, and the split is a property of a module's *path* -rather than of the command that happens to collect it: +The suite is split into tiers by what a module may read, and the split is a +property of a module's *path* rather than of the command that happens to collect +it: =================================== ========================================== Tier Modules @@ -50,8 +51,8 @@ ``ALL``, on every leg, or ``LATEST``, on ``latest`` alone? ``ALL`` is opt-in: a module is in it only when it says so with ``__tier__ = 'ALL'`` (:func:`declared_tier`), and :data:`DEFAULT_TIER`, ``LATEST``, otherwise. - :func:`all_tier_paths` and :func:`latest_tier_paths` list the two tiers; every - leg but ``latest`` leaves the second out. See "The curated ``ALL`` tier" below + :func:`all_tier_paths` and :func:`latest_tier_paths` list them; every + leg but ``latest`` leaves the ``LATEST`` one out. See "The curated ``ALL`` tier" below for which modules opt in. * :func:`is_project_pin` and :func:`project_pin_paths` -- which :file:`tests/project` modules give one answer on every interpreter, and so run @@ -68,7 +69,7 @@ its own copy of the selection: the job calls this module at run time (``python -c "from tests._tiers import fixture_tier_paths; ..."``, see :data:`FIXTURE_TIER_SELECTOR`) instead of spelling out ``tests/integration`` -and the two globs itself. That closes the same gap :data:`UNIT_TIER_SELECTION` +and the globs itself. That closes the same gap :data:`UNIT_TIER_SELECTION` leaves open in the other direction: a workflow that asks this module for the answer cannot drift from it, whereas one that repeats the answer as literal flags always can. See :func:`fixture_tier_paths`'s docstring for why the diff --git a/tests/conftest.py b/tests/conftest.py index a182d567bc..cc54cbaaf0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -253,8 +253,8 @@ def restore_module_table() -> 'Iterator[None]': Issue #660 is what that costs. A stand-in ``ProtocolBase`` that is not :class:`~typing.Generic` stayed bound after the test that installed it, and the next test to import :mod:`pcapkit` died on ``TypeError: type - 'ProtocolBase' is not subscriptable`` at - ``pcapkit/protocols/misc/pcap/frame.py:69`` -- a run of tests in + 'ProtocolBase' is not subscriptable`` at the :class:`Frame` class statement + in :mod:`pcapkit.protocols.misc.pcap.frame` -- a run of tests in :mod:`tests.project`, and only when the polluting file happened to be collected first. Several files turned out to leak this way, one of which -- :mod:`tests.cli.test_main` -- did not import :mod:`tests._support` @@ -523,7 +523,7 @@ def pytest_collection_modifyitems(session: 'pytest.Session', config: 'pytest.Con #: shared hold (spanning the whole test, including the blocking #: ``subprocess.run``) would wait on an inner exclusive request that cannot be #: granted until the outer test finishes: the same deadlock shape as above, one -#: level removed. Today it never selects either; a future change to that +#: level removed. It selects neither; a future change to that #: selection should keep it that way, or add the module in question here too. #: The nested run's own *shared* holds are a different matter, and #: :data:`TIER_GUARD_HELD_ENV` covers them. diff --git a/tests/const/test_const_apptype_split_unit.py b/tests/const/test_const_apptype_split_unit.py index bbf1c14a38..10117d2dc7 100644 --- a/tests/const/test_const_apptype_split_unit.py +++ b/tests/const/test_const_apptype_split_unit.py @@ -674,7 +674,7 @@ def test_every_transport_named_span_is_claimed_by_one_registry(self) -> None: ``cls.__transport__`` claims nothing, since IANA's unassigned and reserved markers belong to whichever registry was asked. Such a branch answered ``undefined`` until GitHub issue #2048, which made it answer with the - asking registry's own transport, so none answers ``undefined`` now. + asking registry's own transport, so none answers ``undefined``. "Every branch" is checked against the same source parsed with :mod:`ast`: the pattern has to find one branch per ``_unregistered_member`` call in diff --git a/tests/const/test_const_ethertype_862_unit.py b/tests/const/test_const_ethertype_862_unit.py index a5d3b0acd6..5592b4dbbe 100644 --- a/tests/const/test_const_ethertype_862_unit.py +++ b/tests/const/test_const_ethertype_862_unit.py @@ -195,7 +195,7 @@ def test_both_ranges_still_render_with_their_own_body(self) -> None: class EtherTypeGeneratorGeneralOrderingTests(unittest.TestCase): """Pins :meth:`~pcapkit.vendor.reg.ethertype.EtherType._insert_range` itself. - #862's own pair is the only containment among the 56 ranges in today's + #862's own pair is the only containment among the ranges in the committed file, so this exercises the general rule -- narrower range before any wider range that contains it -- against synthetic nested ranges the live registry does not (yet) happen to contain. diff --git a/tests/const/test_const_linktype_209_unit.py b/tests/const/test_const_linktype_209_unit.py index 959613417e..71a84904e0 100644 --- a/tests/const/test_const_linktype_209_unit.py +++ b/tests/const/test_const_linktype_209_unit.py @@ -86,8 +86,8 @@ #: ``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:238``, and the note at ``:325-332`` saying so -#: deliberately). +#: parser (their entries in :file:`pyproject.toml`, and the ``test`` extra's comment +#: on ``beautifulsoup4`` saying so deliberately). VENDOR_DEPS = ('requests', 'bs4', 'html5lib') #: Whether all of :data:`VENDOR_DEPS` are importable. Guarded the way diff --git a/tests/corekit/test_fields_bytearray_pack_2004_unit.py b/tests/corekit/test_fields_bytearray_pack_2004_unit.py index 8849409e2d..2658fb45e0 100644 --- a/tests/corekit/test_fields_bytearray_pack_2004_unit.py +++ b/tests/corekit/test_fields_bytearray_pack_2004_unit.py @@ -5,7 +5,7 @@ the ``s`` and ``p`` formats, but PyPy's takes :obj:`bytes` alone and raises ``TypeError: expected bytes, got bytearray object``, so a :obj:`bytearray` value packed by :meth:`Field.pack ` failed on -PyPy. The field now hands :func:`struct.pack` a :obj:`bytes` copy. +PyPy. The field hands :func:`struct.pack` a :obj:`bytes` copy. The PyPy behaviour is reproduced on any interpreter with a :mod:`struct` stand-in that refuses a :obj:`bytearray`, as PyPy's does. The real @@ -114,7 +114,7 @@ def test_bytearray_output_matches_bytes(self) -> None: def test_refused_values_stay_refused(self) -> None: # CPython raises struct.error for these and PyPy TypeError; neither may - # start packing because a bytearray now does. + # start packing because a bytearray does. for label, field in self._fields().items(): for value in (memoryview(OCTETS), True, OCTETS.decode('latin-1'), list(OCTETS)): with self.subTest(field=label, value=type(value).__name__): diff --git a/tests/corekit/test_fields_copy_dispatch_unit.py b/tests/corekit/test_fields_copy_dispatch_unit.py index 364d791f47..75ee23a10c 100644 --- a/tests/corekit/test_fields_copy_dispatch_unit.py +++ b/tests/corekit/test_fields_copy_dispatch_unit.py @@ -89,7 +89,7 @@ def assertCallReachesCopyDunderOnly(self, field: 'FieldBase[Any]') -> None: self.assertIsInstance(new_field, type(field)) def test_field_base_call_field_py_294(self) -> None: - """:meth:`FieldBase.__call__` (``field.py:274``), reached via :class:`NoValueField`. + """:meth:`FieldBase.__call__`, reached via :class:`NoValueField`. :class:`~pcapkit.corekit.fields.misc.NoValueField` is the one concrete class in this package that never overrides ``__call__``, so it is the @@ -102,19 +102,19 @@ class in this package that never overrides ``__call__``, so it is the self.assertCallReachesCopyDunderOnly(NoValueField()) def test_field_call_field_py_579(self) -> None: - """:meth:`Field.__call__` (``field.py:580``).""" + """:meth:`Field.__call__`.""" from pcapkit.corekit.fields.field import Field self.assertCallReachesCopyDunderOnly(Field(length=4)) def test_list_field_call_collections_py_84(self) -> None: - """:meth:`ListField.__call__` (``collections.py:124``).""" + """:meth:`ListField.__call__`.""" from pcapkit.corekit.fields.collections import ListField self.assertCallReachesCopyDunderOnly(ListField(length=4)) def test_conditional_field_call_misc_py_148(self) -> None: - """:meth:`ConditionalField.__call__` (``misc.py:150``).""" + """:meth:`ConditionalField.__call__`.""" from pcapkit.corekit.fields.field import Field from pcapkit.corekit.fields.misc import ConditionalField @@ -122,13 +122,13 @@ def test_conditional_field_call_misc_py_148(self) -> None: self.assertCallReachesCopyDunderOnly(field) def test_payload_field_call_misc_py_299(self) -> None: - """:meth:`PayloadField.__call__` (``misc.py:351``).""" + """:meth:`PayloadField.__call__`.""" from pcapkit.corekit.fields.misc import PayloadField self.assertCallReachesCopyDunderOnly(PayloadField(length=4)) def test_switch_field_call_misc_py_427(self) -> None: - """:meth:`SwitchField.__call__` (``misc.py:479``).""" + """:meth:`SwitchField.__call__`.""" from pcapkit.corekit.fields.field import Field from pcapkit.corekit.fields.misc import SwitchField @@ -136,7 +136,7 @@ def test_switch_field_call_misc_py_427(self) -> None: self.assertCallReachesCopyDunderOnly(field) def test_schema_field_call_misc_py_650(self) -> None: - """:meth:`SchemaField.__call__` (``misc.py:694``).""" + """:meth:`SchemaField.__call__`.""" from pcapkit.corekit.fields.misc import SchemaField from pcapkit.corekit.fields.numbers import UInt8Field from pcapkit.protocols.schema.schema import Schema, schema_final @@ -148,7 +148,7 @@ class OneField(Schema): self.assertCallReachesCopyDunderOnly(SchemaField(schema=OneField)) def test_forward_match_field_call_misc_py_782(self) -> None: - """:meth:`ForwardMatchField.__call__` (``misc.py:849``).""" + """:meth:`ForwardMatchField.__call__`.""" from pcapkit.corekit.fields.field import Field from pcapkit.corekit.fields.misc import ForwardMatchField diff --git a/tests/corekit/test_fields_misc_packet_context.py b/tests/corekit/test_fields_misc_packet_context.py index aabe5a2b6a..1a5d87b70f 100644 --- a/tests/corekit/test_fields_misc_packet_context.py +++ b/tests/corekit/test_fields_misc_packet_context.py @@ -179,10 +179,10 @@ def test_nested_schema_reads_enclosing_field_by_name_and_does_not_leak_writes(se def test_pcapng_byteorder_consumer_still_works_with_both_shapes(self) -> None: """The one existing, hand-rolled ``__packet__`` fallback is unaffected. - ``packet_byteorder`` (``pcapkit/corekit/fields/byteorder.py:33``) + ``packet_byteorder`` (:mod:`pcapkit.corekit.fields.byteorder`) is called both with a plain dict built by hand -- as several tests and :func:`~pcapkit.foundation.engines.pcapng` construct -- and with what - ``SchemaField`` now actually builds. Both must keep working, and + ``SchemaField`` actually builds. Both must keep working, and neither is expected to change: the site already implements the fallback itself and does not route through :func:`~pcapkit.corekit.fields.misc.nested_packet_context`. diff --git a/tests/corekit/test_fields_numbers_negative_length.py b/tests/corekit/test_fields_numbers_negative_length.py index bec60ef69e..e4f0774733 100644 --- a/tests/corekit/test_fields_numbers_negative_length.py +++ b/tests/corekit/test_fields_numbers_negative_length.py @@ -88,7 +88,7 @@ def test_the_real_callable_shape_from_hip_py_also_raises_protocolerror(self) -> """``lambda pkt: pkt['len'] - 4`` against a truncated ``len``, verbatim. This is the exact shape at ``pcapkit/protocols/schema/internet/ - hip.py``'s ``PuzzleParameter.random`` field (line 734 as of + hip.py``'s ``PuzzleParameter.random`` field (as of ``21e9588af``): a wire ``len`` of ``3`` -- one octet short of the 4-octet header this parameter always carries -- resolves the remaining ``random`` payload to ``-1`` octets, negative because the @@ -181,7 +181,7 @@ class NegativeBitLengthTests(unittest.TestCase): whenever one is supplied, and shifts by it immediately: ``(1 << bit_length) - 1``. #829 guarded the *resolved-length* shift in :meth:`~pcapkit.corekit.fields.numbers.NumberField.__call__` but left this - one, at ``pcapkit/corekit/fields/numbers.py:88`` on ``5576708d4``, open -- + one, in ``NumberField.__init__`` on ``5576708d4``, open -- a negative ``bit_length`` still raised a bare, uncatchable :exc:`ValueError` (``negative shift count``) rather than a :class:`~pcapkit.utilities.exceptions.ProtocolError`. @@ -261,7 +261,7 @@ def test_a_positive_bit_length_is_unaffected(self) -> None: """The control: the ordinary, well-formed case is not touched. The exact shape at ``pcapkit/protocols/schema/link/vlan.py``'s - ``TCI.pcp``/``dei``/``vid`` fields (lines 47, 49, 51 on + ``TCI.pcp``/``dei``/``vid`` fields (on ``5576708d4``): a positive literal ``bit_length`` alongside a fixed byte ``length``. diff --git a/tests/corekit/test_graalpy_semantics_1963_unit.py b/tests/corekit/test_graalpy_semantics_1963_unit.py index 8431ab6576..37765ce62b 100644 --- a/tests/corekit/test_graalpy_semantics_1963_unit.py +++ b/tests/corekit/test_graalpy_semantics_1963_unit.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -"""GraalPy behaviours :mod:`pcapkit.corekit` no longer depends on (#1963). +"""GraalPy behaviours :mod:`pcapkit.corekit` does not depend on (#1963). Each was measured on GraalPy 25.4 and does not happen on CPython, so each class here stands in for GraalPy's behaviour and checks the module does not lean on diff --git a/tests/corekit/test_sentinel_py_abc_1960_unit.py b/tests/corekit/test_sentinel_py_abc_1960_unit.py index 75b5e6416c..992bb3e584 100644 --- a/tests/corekit/test_sentinel_py_abc_1960_unit.py +++ b/tests/corekit/test_sentinel_py_abc_1960_unit.py @@ -6,7 +6,7 @@ ``_abc_negative_cache_version`` on the class once any ABC has registered a virtual subclass since the class was built. :class:`~pcapkit.corekit.sentinels.SentinelMeta` refused every write to a built sentinel type, so ``isinstance(1, NullType)`` -raised :exc:`TypeError` there. It now lets those two names through, and no +raised :exc:`TypeError` there. It lets those two names through, and no other. :class:`PyABCFallbackTests` runs the checks in a child interpreter that really diff --git a/tests/dumpkit/test_common_unit.py b/tests/dumpkit/test_common_unit.py index aeebb79064..9879c4b616 100644 --- a/tests/dumpkit/test_common_unit.py +++ b/tests/dumpkit/test_common_unit.py @@ -266,7 +266,7 @@ def test_make_dumper_escapes_strings_only_for_plist_like_output(self) -> None: def test_make_dumper_escapes_mapping_keys_for_plist_like_output(self) -> None: """GitHub issue #772, the half the hook above cannot reach. - ``dictdumper/plist.py:202`` writes a key as + ``PLIST._append_dict`` in :mod:`dictdumper.plist` writes a key as ``'{item}'.format(item=item)`` and calls ``_encode_value`` on the *value* two lines down, never on the key -- so :meth:`object_hook` is handed every value the writer interpolates and no diff --git a/tests/dumpkit/test_make_dumper_subclass_2144_unit.py b/tests/dumpkit/test_make_dumper_subclass_2144_unit.py index 3134b822c5..a509447fe7 100644 --- a/tests/dumpkit/test_make_dumper_subclass_2144_unit.py +++ b/tests/dumpkit/test_make_dumper_subclass_2144_unit.py @@ -6,7 +6,7 @@ ``super(type(self), self).object_hook(o)``. In a subclass of the class it returns, ``type(self)`` is the subclass, so the call resolved back to that same ``object_hook`` and recursed until :exc:`RecursionError`. A value no branch -recognises now falls through to the output class's own ``object_hook``. +recognises falls through to the output class's own ``object_hook``. :mod:`pcapkit` is imported inside each test, after :func:`~tests._support.reimport_once_per_class`. diff --git a/tests/foundation/engines/test_engine_base.py b/tests/foundation/engines/test_engine_base.py index 78e798ce82..7b1240e3e1 100644 --- a/tests/foundation/engines/test_engine_base.py +++ b/tests/foundation/engines/test_engine_base.py @@ -77,16 +77,16 @@ def test_engine_subclass_registration_is_opt_in(self) -> None: The ``Default`` case is the load-bearing half: it sets ``__engine_name__``, so under the old fallback it registered under - ``'defaultengine'``. A class attribute is not a registry key, and now it + ``'defaultengine'``. A class attribute is not a registry key, and it registers nothing. No version guard, and that is the point of the rename. The keyword was ``name`` when opt-in registration landed, which made this half of the test - unrunnable on Python 3.10 -- ``mcls``/``name``/``bases``/``namespace`` + unrunnable below Python 3.11 -- ``mcls``/``name``/``bases``/``namespace`` collide with :meth:`abc.ABCMeta.__new__`'s own parameters, which are positional-or-keyword before 3.11 and positional-only from 3.11, so the class statement failed in the metaclass before ``__init_subclass__`` ran. - ``engine`` is outside that set, so this now runs everywhere. Verified on + ``engine`` is outside that set, so this runs everywhere. Verified on 3.10.21 and 3.14.7. """ @@ -129,13 +129,13 @@ def test_engine_subclass_rejects_unrecognised_keyword(self) -> None: would instead skip registration silently, which is quieter still. Unguarded by version on purpose: ``protocol`` is not one of the four - names that collide with :meth:`abc.ABCMeta.__new__` on Python 3.10, so + names that collide with :meth:`abc.ABCMeta.__new__` below Python 3.11, so the guard is reached on every supported version. Verified against this tree on 3.10.21, where it raises ``UnsupportedCall`` as it does on 3.14. - ``name`` is now an unrecognised keyword here too, and is checked + ``name`` is an unrecognised keyword here too, and is checked separately below because it is the one typo whose exception *type* is - version-dependent: on 3.10 the metaclass collision fires before the + version-dependent: below 3.11 the metaclass collision fires before the guard, so it is a :exc:`TypeError` rather than an :exc:`~pcapkit.utilities.exceptions.UnsupportedCall`. Loud either way, which is why the rename did not need to chase it. @@ -156,9 +156,9 @@ def read_frame(self) -> str: register.assert_not_called() self.assertIn('protocol', str(caught.exception)) - # ``name=`` is no longer the registry keyword, so it is a typo now. It is + # ``name=`` is not the registry keyword, so it is a typo. It is # the one whose exception type is version-dependent: the metaclass - # collision fires before the guard on 3.10. + # collision fires before the guard below 3.11. expected = UnsupportedCall if sys.version_info >= (3, 11) else TypeError with mock.patch('pcapkit.foundation.extraction.Extractor.register_engine') as register: with self.assertRaises(expected): diff --git a/tests/foundation/engines/test_pcap_backend.py b/tests/foundation/engines/test_pcap_backend.py index 2b1bc8466b..d15d9fa16f 100644 --- a/tests/foundation/engines/test_pcap_backend.py +++ b/tests/foundation/engines/test_pcap_backend.py @@ -191,7 +191,7 @@ def test_finds_a_dist_info_without_reading_its_metadata(self) -> None: # From Python 3.15 ``importlib.metadata.distribution`` parses every # candidate's METADATA, which ran on each pcap_ct extraction (#2110). - # Existence is all that is asked, so a METADATA read is now an error. + # Existence is all that is asked, so here a METADATA read is an error. def unread(self, filename): raise AssertionError(f'read {filename} of {self}') diff --git a/tests/foundation/engines/test_pypcap_unusable_module_2132_unit.py b/tests/foundation/engines/test_pypcap_unusable_module_2132_unit.py index afe144b8de..945d20096f 100644 --- a/tests/foundation/engines/test_pypcap_unusable_module_2132_unit.py +++ b/tests/foundation/engines/test_pypcap_unusable_module_2132_unit.py @@ -6,7 +6,7 @@ ` lets that through, so the engine's ``unsupported_reason()`` has to report it. ``PCAP_CT`` did and ``PyPCAP`` did not, so ``extract(engine='pypcap')`` raised the loader's error where -``engine='pcap_ct'`` warned and fell back. Both now ask +``engine='pcap_ct'`` warned and fell back. Both ask :func:`pcapkit.foundation.engines._pcap_backend.engine_reason`. """ @@ -31,7 +31,7 @@ #: What the fake ``pcap`` package raises on import: the libpcap loader's message. LOADER_ERROR = 'Cannot find libpcap.so library' -#: The verdict ``PCAP_CT`` already gave on that failure, which ``PyPCAP`` now shares. +#: The verdict ``PCAP_CT`` already gave on that failure, which ``PyPCAP`` shares. REASON = f'the `pcap` module is installed but unusable -- OSError: {LOADER_ERROR}' #: Hang guard for the child interpreter, in seconds. TIMEOUT = 120 diff --git a/tests/foundation/engines/test_pyshark_non_packet_unit.py b/tests/foundation/engines/test_pyshark_non_packet_unit.py index 70d006a650..eb86763185 100644 --- a/tests/foundation/engines/test_pyshark_non_packet_unit.py +++ b/tests/foundation/engines/test_pyshark_non_packet_unit.py @@ -72,7 +72,7 @@ def _record(number: int, frame: 'tuple[str, ...] | None', root: str) -> types.Si 'custom block (4.6.9)': ('DATA', ('section_number', 'interface_id', 'time', 'number', 'len')), 'sysdig event (4.6.9)': ('sysdig', RECORD_FRAME), # 4.2.2 roots a Sysdig event at ``syscall`` and a Netflix custom block at - # ``bblog`` instead of ``frame`` (epan/dissectors/packet-frame.c:858-869, :884-890). + # ``bblog`` instead of ``frame`` (``dissect_frame`` in epan/dissectors/packet-frame.c). 'sysdig event (4.2.2)': ('syscall', None), 'black box log (4.2.2)': ('bblog', None), } diff --git a/tests/foundation/reassembly/test_reassembly_base.py b/tests/foundation/reassembly/test_reassembly_base.py index 4d63c2197b..a45b5c283a 100644 --- a/tests/foundation/reassembly/test_reassembly_base.py +++ b/tests/foundation/reassembly/test_reassembly_base.py @@ -188,8 +188,8 @@ def test_reassembly_subclass_rejects_unrecognised_keyword(self) -> None: The keyword used here is deliberately *not* ``name``. Four class keyword names -- ``mcls``, ``name``, ``bases`` and ``namespace`` -- collide with :meth:`abc.ABCMeta.__new__`'s own parameters, which are - positional-or-keyword on Python 3.10 and positional-only from 3.11. On - 3.10 the collision therefore raises :exc:`TypeError` from the metaclass + positional-or-keyword before Python 3.11 and positional-only from 3.11. + Below 3.11 the collision therefore raises :exc:`TypeError` from the metaclass *before* ``__init_subclass__`` is reached, so testing the guard with ``name=`` would only exercise it on 3.11+. Measured on 3.10.21, 3.11.15 and 3.14.7. The colliding case is pinned separately below. @@ -227,7 +227,7 @@ def submit(self, buf: DummyBuffer, **kwargs: object) -> list[DummyDatagram]: # ``name=`` is the mistake a user actually makes, by analogy with # ``Engine``, and it is one of the four colliding names -- so which # exception surfaces is version-dependent. Pinned rather than skipped, so - # the 3.10 behaviour is recorded rather than merely untested. + # the behaviour below 3.11 is recorded rather than merely untested. expected = UnsupportedCall if sys.version_info >= (3, 11) else TypeError with mock.patch('pcapkit.foundation.extraction.Extractor.register_reassembly') as register: with self.assertRaises(expected): diff --git a/tests/foundation/test_extraction_no_eof.py b/tests/foundation/test_extraction_no_eof.py index c56892b79f..245231273a 100644 --- a/tests/foundation/test_extraction_no_eof.py +++ b/tests/foundation/test_extraction_no_eof.py @@ -94,7 +94,7 @@ The timeout bounds the extraction, not the interpreter's warm-up (#2085). On GraalPy 25.4.4 a child spends 4-8s importing :mod:`pcapkit` and 7-13s on its -first extraction, which imports five more modules and is otherwise cold code: +first extraction, which imports more modules and is otherwise cold code: about 21 CPU-seconds before the case under test begins, after which every case here takes 0.02-0.06s. CPython takes 0.9s in all. A single 30s timeout over the whole child therefore failed four of eleven GraalPy runs on ``main``, the other diff --git a/tests/project/test_actionlint_in_lint_1967.py b/tests/project/test_actionlint_in_lint_1967.py index bc7ca75fdc..1c222954fb 100644 --- a/tests/project/test_actionlint_in_lint_1967.py +++ b/tests/project/test_actionlint_in_lint_1967.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """#1967: Lint runs actionlint, pinned to a checksum-verified release. -Nothing ran actionlint over the workflows before #1967. Lint's ``lint`` job now +Nothing ran actionlint over the workflows before #1967. Lint's ``lint`` job has an ``actionlint`` step that downloads one release, named by ``ACTIONLINT_VERSION``, checks it against ``ACTIONLINT_SHA256`` before unpacking it, and runs it over every workflow. The version is 1.7.12 or newer: the diff --git a/tests/project/test_actions_pinned_1968.py b/tests/project/test_actions_pinned_1968.py index 04992cec97..90bc2426c3 100644 --- a/tests/project/test_actions_pinned_1968.py +++ b/tests/project/test_actions_pinned_1968.py @@ -22,7 +22,7 @@ either; and the root job's ``exclude-paths`` skips :file:`conda/requirements.txt`, which it would otherwise read. * :class:`TestDependabotCanBuildTheEditable` checks :file:`pyproject.toml` - declares its readme statically, as Dependabot now fetches that file in place + declares its readme statically, as Dependabot fetches that file in place of :file:`setup.py` and passes it through unstubbed. * :class:`TestPyUpOpensNoUpdates` checks :file:`.pyup.yml` turns PyUp's update pull requests off, as Dependabot opens them. diff --git a/tests/project/test_annotation_names.py b/tests/project/test_annotation_names.py index 546bc9b9bd..a30518889a 100644 --- a/tests/project/test_annotation_names.py +++ b/tests/project/test_annotation_names.py @@ -64,7 +64,7 @@ def annotation_strings(tree: 'ast.AST') -> 'Iterator[tuple[str, int]]': in this package: a variable annotation, a parameter annotation, a return annotation, and the first argument of :func:`typing.cast`. The ``cast`` case is the one that is easiest to miss and is exactly where - ``ipv6_route.py:271``'s ``Optional`` hid -- :func:`typing.cast` never + the ``Optional`` in ``RPL.post_process`` of ``ipv6_route.py`` hid -- :func:`typing.cast` never evaluates that argument, so an unresolvable name there is invisible to every test that runs the line. diff --git a/tests/project/test_conda_dist_keeps_release_notes_1657.py b/tests/project/test_conda_dist_keeps_release_notes_1657.py index c7c6240f2a..850fca8ddc 100644 --- a/tests/project/test_conda_dist_keeps_release_notes_1657.py +++ b/tests/project/test_conda_dist_keeps_release_notes_1657.py @@ -3,14 +3,16 @@ ``conda-dist`` in :file:`.github/workflows/cron-conda.yml` attaches each build bump's packages with ``ncipollo/release-action@v1.21.0`` and ``allowUpdates: -true``, which calls Update a release before uploading (``src/Action.ts:107-120``). -That request sends ``name``, ``body``, ``prerelease`` and ``draft`` whether or not -the step sets them, and unset they are the tag, ``""`` and ``false`` -(``src/Inputs.ts:70-92,128-135,210-240``). ``v1.3.5.post42``, ``v1.4.1``, +true``, which calls Update a release before uploading (``Action.updateRelease`` +in ``src/Action.ts``). That request sends ``name``, ``body``, ``prerelease`` and +``draft`` whether or not the step sets them, and unset they are the tag, ``""`` +and ``false`` (``CoreInputs``'s ``body`` and ``name`` getters and its +``updated*`` ones, in ``src/Inputs.ts``). ``v1.3.5.post42``, ``v1.4.1``, ``v1.4.1.post2`` and ``v1.5.0a1`` read name-is-tag and a 0-character body that -way. Each ``omit*DuringUpdate`` input makes its field ``undefined`` -(``:210-252``), which Octokit drops from the request body -(``dist/index.js:38369-38388``), so the release keeps what Create Release wrote. +way. Each ``omit*DuringUpdate`` input makes its field ``undefined`` (the +``updated*`` getters), which Octokit drops from the request body +(``removeUndefinedProperties``, which the bundled ``merge`` calls in +``dist/index.js``), so the release keeps what Create Release wrote. The step is read with the scanner of ``test_release_tags_the_run_sha_1634.py``, which runs without PyYAML; :meth:`TestTheUploadKeepsTheRelease.test_yaml_reads_the_same` @@ -41,7 +43,8 @@ #: Every input the step sets. Another one changes what the update sends -- a #: ``makeLatest``, say, whose ``legacy`` default is already sent as -#: ``make_latest`` (``action.yml:58-61``, ``src/Releases.ts:168``) -- so adding +#: ``make_latest`` (the ``makeLatest`` input in ``action.yml``, and +#: ``GithubReleases.update`` in ``src/Releases.ts``) -- so adding #: one means reading the action again before adding it here. INPUTS = {'allowUpdates', 'artifacts', 'commit', 'tag', 'token', *OMITTED} diff --git a/tests/project/test_conda_intel_cli_upload_2044.py b/tests/project/test_conda_intel_cli_upload_2044.py index 1f7e0c7d1f..820051e8f3 100644 --- a/tests/project/test_conda_intel_cli_upload_2044.py +++ b/tests/project/test_conda_intel_cli_upload_2044.py @@ -5,7 +5,7 @@ ``anaconda.sh/releases/stable/v0.2.1/ana-darwin-x86_64``, which returns 404, so the step "Upload conda packages to Anaconda" failed on every Intel leg of ``conda-dist`` in :file:`.github/workflows/cron-conda.yml` and would on ``conda`` -in :file:`.github/workflows/create-release.yml`. That step now skips the Intel +in :file:`.github/workflows/create-release.yml`. That step skips the Intel leg, and "Upload conda packages to Anaconda (Intel)" runs there alone, making the action's own ``anaconda --token … upload --user …`` call from conda-forge's anaconda-client, with ``--skip-existing``. diff --git a/tests/project/test_conda_intel_miniforge_2044.py b/tests/project/test_conda_intel_miniforge_2044.py index 4b1780663f..a7396b1d37 100644 --- a/tests/project/test_conda_intel_miniforge_2044.py +++ b/tests/project/test_conda_intel_miniforge_2044.py @@ -6,7 +6,7 @@ :file:`.github/workflows/create-release.yml` named no installer, so on the Intel runner setup-miniconda downloaded ``Miniconda3-latest-MacOSX-x86_64.sh``. That installer is frozen at conda 25.7.0, which conflicts with conda-forge's -conda-content-trust plugin and has no py314 build. The Intel legs now pass +conda-content-trust plugin and has no py314 build. The Intel legs pass ``miniforge-version: latest``; every other leg passes an empty string, which names no installer, so it keeps the bundled or downloaded Miniconda. @@ -19,7 +19,7 @@ #2123: with Miniforge, the Intel legs broke twice more. Installing the matrix Python into base rebuilt conda-forge's libmambapy at 2.10.0, which -conda-libmamba-solver 26.10.0 cannot drive, so the Intel legs now leave base's +conda-libmamba-solver 26.10.0 cannot drive, so the Intel legs leave base's Python alone, as 3.15 does everywhere; :class:`TestTheIntelLegsKeepBasesPython` pins that. And conda-build 26.9's rpath relocation failed on the vendored chardet extensions, so :file:`conda/pypcapkit/meta.yaml` turns it off on osx-64 alone; diff --git a/tests/project/test_conda_no_windows_steps_1967.py b/tests/project/test_conda_no_windows_steps_1967.py index 81419e73e7..3fe8b19aef 100644 --- a/tests/project/test_conda_no_windows_steps_1967.py +++ b/tests/project/test_conda_no_windows_steps_1967.py @@ -2,8 +2,8 @@ """#1967: the conda jobs keep no step or ``case`` arm for a runner they have no leg on. ``conda`` in :file:`.github/workflows/create-release.yml` and ``conda-dist`` in -:file:`.github/workflows/cron-conda.yml` have had no ``windows-latest`` leg since -2023, yet carried ``Install and Setup (Windows)``, ``Setup Conda Distribution +:file:`.github/workflows/cron-conda.yml` had no ``windows-latest`` leg from 2023 +until #2060, yet carried ``Install and Setup (Windows)``, ``Setup Conda Distribution (Windows)``, the ``matrix.os != 'windows-latest'`` guards on their twins, and a ``windows-latest`` arm in each ``case "${{ matrix.os }}"``: code no run reached. diff --git a/tests/project/test_conda_publish_dispatch_2060.py b/tests/project/test_conda_publish_dispatch_2060.py index 6c57dc6227..a47486f399 100644 --- a/tests/project/test_conda_publish_dispatch_2060.py +++ b/tests/project/test_conda_publish_dispatch_2060.py @@ -340,7 +340,7 @@ def test_push_changes_and_the_report_are_told_it_was_forced(self) -> None: self.assertEqual(step('conda-update', label)['env']['FORCED'], '${{ steps.bump.outputs.forced }}') -#: Push Changes' three "not pushed" notices, and the warning each becomes on a forced bump. +#: Push Changes' "not pushed" notices, and the warning each becomes on a forced bump. MOVED_PAST = ('::notice title=Not pushed as main moved past this checkout::', '::warning title=Nothing published as main moved past this checkout::') MOVED_DURING = ('::notice title=Not pushed as main moved during the push::', diff --git a/tests/project/test_conda_windows_leg_2060.py b/tests/project/test_conda_windows_leg_2060.py index 8fa844c4e9..1790dad837 100644 --- a/tests/project/test_conda_windows_leg_2060.py +++ b/tests/project/test_conda_windows_leg_2060.py @@ -5,7 +5,7 @@ non-blocking ``windows-latest`` leg that published nothing. Once its Conda Update runs were green, phase 2 gave ``conda`` in :file:`.github/workflows/create-release.yml` the leg too, made both blocking, and -uploads from both with the anaconda-client CLI, as the Intel legs do (#2044). +uploaded from both with the anaconda-client CLI, as the Intel legs do (#2044). * :class:`TestTheWindowsLegPublishes`: on ``windows-latest`` each job runs one upload, "Upload conda packages to Anaconda (Windows)", evaluated with diff --git a/tests/project/test_docs_engines_page_unit.py b/tests/project/test_docs_engines_page_unit.py index de296af326..4df9c13be2 100644 --- a/tests/project/test_docs_engines_page_unit.py +++ b/tests/project/test_docs_engines_page_unit.py @@ -5,7 +5,7 @@ tables -- moved off the root document, which keeps a summary and a link. * :class:`PlacementTests` -- the page is in a toctree, the root document links it - and no longer carries the tables, and the prerequisites label is on the page. + and does not carry the tables, and the prerequisites label is on the page. * :class:`FootnoteTests` -- the benchmark tables mark their rows with reStructuredText footnotes rather than literal symbols and a hand legend. * :class:`ProvenanceTests` -- the page says where its figures come from. diff --git a/tests/project/test_experimental_shellcheck_1967.py b/tests/project/test_experimental_shellcheck_1967.py index 69664c228f..828f1dc643 100644 --- a/tests/project/test_experimental_shellcheck_1967.py +++ b/tests/project/test_experimental_shellcheck_1967.py @@ -2,7 +2,8 @@ """#1967: every ``run:`` block of experimental.yml passes shellcheck. Lint's ``actionlint`` step runs shellcheck over every workflow's ``run:`` blocks, -but is advisory, so this test keeps experimental.yml clean. It checks each +and a finding fails Lint. This test keeps experimental.yml clean without waiting +for a Lint run: it checks each ``run:`` block of a ``bash`` or ``sh`` step as actionlint does: each ``${{ ... }}`` expression replaced by underscores of the same length, the shell's ``set -e`` line above it, and the checks actionlint disables left out. diff --git a/tests/project/test_gnu_timeout_2020.py b/tests/project/test_gnu_timeout_2020.py index d07fd44355..fd95984565 100644 --- a/tests/project/test_gnu_timeout_2020.py +++ b/tests/project/test_gnu_timeout_2020.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """#2020: every workflow ``timeout`` that needs GNU's semantics runs GNU's. -Ubuntu 26.04, which ``ubuntu-latest`` now serves, ships uutils coreutils 0.10.0 +Ubuntu 26.04, which ``ubuntu-latest`` serves, ships uutils coreutils 0.10.0 as ``timeout`` and GNU coreutils 9.7 as ``gnutimeout``. uutils' ``--kill-after`` sends SIGKILL with the first signal, and to its child alone: in ``ubuntu:26.04``, ``timeout --signal=INT --kill-after=3s 1 sleep 30`` exits 137 after 1 s where diff --git a/tests/project/test_graalpy_shards_1963.py b/tests/project/test_graalpy_shards_1963.py index 11f12c2000..5f3408528c 100644 --- a/tests/project/test_graalpy_shards_1963.py +++ b/tests/project/test_graalpy_shards_1963.py @@ -37,7 +37,7 @@ SHARDS = ('tests/const tests/corekit/test_fields_n* tests/corekit/test_[a-h]* tests/corekit/test_i* tests/corekit ' 'tests/foundation tests/protocols/internet tests/protocols/[a-m]* tests/protocols tests/toolkit') SCRIPT = ROOT / 'util' / 'pytest_shards.py' -#: The three lines that build the command the step's caps run, in order. +#: The lines that build the command the step's caps run, in order. PYTEST = 'set -- python -m pytest "$@"\n' SHARDED = 'set -- /usr/bin/python3 util/pytest_shards.py "$SHARDS" -- "$@"\n' CAPPED = 'set -- prlimit --fsize=2147483648 "$gnu_timeout" --signal=INT --kill-after=3m 110m "$@"\n' diff --git a/tests/project/test_isort_clean.py b/tests/project/test_isort_clean.py index 99c92ca686..28486aaa04 100644 --- a/tests/project/test_isort_clean.py +++ b/tests/project/test_isort_clean.py @@ -36,7 +36,7 @@ :file:`tests/protocols/test_option_generator_tcp_base_unit.py`, :file:`tests/protocols/test_option_coverage_runtime.py`, and :file:`tests/protocols/test_option_roundtrip_unit.py`. - :file:`examples/generators/dispatch.py:20` and + :file:`examples/generators/dispatch.py`'s module docstring and :file:`docs/source/changelog/1.5.0.rst` both name it directly, too. diff --git a/tests/project/test_ktlo_jobs_gate_nothing_1738.py b/tests/project/test_ktlo_jobs_gate_nothing_1738.py index 1e1b25a3df..7c063c2c72 100644 --- a/tests/project/test_ktlo_jobs_gate_nothing_1738.py +++ b/tests/project/test_ktlo_jobs_gate_nothing_1738.py @@ -158,7 +158,7 @@ def test_each_runs_its_twins_steps_on_ktlo_legs_only(self) -> None: self.assertEqual((spec['runs-on'], spec['timeout-minutes']), (gate['runs-on'], gate['timeout-minutes'])) self.assertEqual(spec['env']['ANNOTATION_LEVEL'], gate['env']['ANNOTATION_LEVEL']) self.assertTrue(all(leg.get('ktlo') is True for leg in matrix_legs(twin))) - # #2030: last but the two that name and upload the job's summary. + # #2030: last but the steps that name and upload the job's summary. self.assertEqual([step['name'] for step in spec['steps'][-3:]], ['KTLO summary', 'Name the job summary', 'Upload the job summary']) self.assertEqual(spec['steps'][-3]['continue-on-error'], KTLO_GUARD) diff --git a/tests/project/test_ktlo_legs_stay_green_1672.py b/tests/project/test_ktlo_legs_stay_green_1672.py index 804e2af43e..d301eb838a 100644 --- a/tests/project/test_ktlo_legs_stay_green_1672.py +++ b/tests/project/test_ktlo_legs_stay_green_1672.py @@ -12,7 +12,7 @@ step that needs an earlier one waits on that step's ``outcome``; the last step, ``KTLO summary``, reports each failed ``outcome`` as a warning and a job-summary line; and a step's own annotations take the job's ``ANNOTATION_LEVEL``. #2030: -only the two steps that name and upload the job's copy of its summary, +only the steps that name and upload the job's copy of its summary, :data:`JOB_SUMMARY_STEPS`, follow a summary, masked on every leg. :func:`run_leg` steps through a job the way the runner does -- the implicit @@ -790,7 +790,8 @@ class TestASlowExperimentalLegTimesOutAStepNotTheJob(unittest.TestCase): A job past its ``timeout-minutes`` is cancelled, which no step-level ``continue-on-error`` contains, and docs.github.com does not say whether the job-level one does. A step past its own is failed instead, and ``continue-on-error`` then applies to it as to any failure - (actions/runner src/Runner.Worker/StepsRunner.cs:322-353, at 5f0b3ddcc) -- + (``StepsRunner.RunStepAsync`` in actions/runner src/Runner.Worker/StepsRunner.cs, + at 5f0b3ddcc) -- the path :class:`TestAnExperimentalLegIsNonBlockingTheSameWay` runs. """ diff --git a/tests/project/test_lint_pages_reports_2030.py b/tests/project/test_lint_pages_reports_2030.py index ba96703330..0f6349db25 100644 --- a/tests/project/test_lint_pages_reports_2030.py +++ b/tests/project/test_lint_pages_reports_2030.py @@ -219,7 +219,7 @@ class TestTheLintReport(_ReportStep): """``lint``'s report: each tool's outcome, then the summary blocks.""" workflow, job, file = LINT, 'lint', 'lint-report.md' - #: A run where every advisory tool found something, as each does today. + #: A run where every advisory tool found something. FOUND = {'BANDIT': 'failure', 'MYPY': 'failure', 'VERMIN': 'failure', 'PYLINT': 'failure', 'ACTIONLINT': 'success'} diff --git a/tests/project/test_memory_error_count_1962.py b/tests/project/test_memory_error_count_1962.py index 857569ebe8..2433bc035c 100644 --- a/tests/project/test_memory_error_count_1962.py +++ b/tests/project/test_memory_error_count_1962.py @@ -5,7 +5,7 @@ was ``grep -cw MemoryError``, which also matched a test's docstring that a traceback printed (``fail with :exc:`MemoryError```), so every GraalPy run that timed out warned of a ``MemoryError`` none of its tests raised (job -118149195212). The step now counts the lines that ``MemoryError`` heads, as an +118149195212). The step counts the lines that ``MemoryError`` heads, as an exception's own line: at the line's start, or after pytest's ``E``, an ``INTERNALERROR>`` or an exception group's ``|``. The lines below are the experimental logs' own, the raised one from job 116172356218 (#1753). diff --git a/tests/project/test_module_isolation.py b/tests/project/test_module_isolation.py index 92ee1e0df5..a5134d6daf 100644 --- a/tests/project/test_module_isolation.py +++ b/tests/project/test_module_isolation.py @@ -4,9 +4,9 @@ Issue #660: three files, run in one order, gave ``12 failed, 5 passed``; the same three in the opposite order gave ``17 passed``. The cause was a test that bound a non-generic ``ProtocolBase`` stand-in into :data:`sys.modules` and finished -without removing it, so the next test to import :mod:`pcapkit` died at -``pcapkit/protocols/misc/pcap/frame.py:69`` with ``TypeError: type 'ProtocolBase' -is not subscriptable``. +without removing it, so the next test to import :mod:`pcapkit` died at the +:class:`Frame` class statement in :mod:`pcapkit.protocols.misc.pcap.frame` with +``TypeError: type 'ProtocolBase' is not subscriptable``. The tests here run :program:`pytest` in a subprocess over the exact selections that failed. That is the only way to state this invariant: it is a property of diff --git a/tests/project/test_pip_install_1967.py b/tests/project/test_pip_install_1967.py index 8f511f65ee..b607c11a08 100644 --- a/tests/project/test_pip_install_1967.py +++ b/tests/project/test_pip_install_1967.py @@ -6,8 +6,8 @@ and the arguments and levels it refuses. * :class:`TestTheFormerShellAgrees` runs the shell the steps held before the script against the same stand-in and requires the same output, log and status; - for the steps that had no annotation, the same except for the annotation a - failed install now writes; and for an indented ``ERROR:`` line, the same + for the steps that had no annotation, the same except for the annotation the + script writes on a failed install; and for an indented ``ERROR:`` line, the same except for the reason the shell missed (#2041). * :class:`TestTheStepsRunTheScript` pins each covered step to the script, with its guards and environment, and every other ``pip install`` in diff --git a/tests/project/test_pylint_pragma_names_1923_unit.py b/tests/project/test_pylint_pragma_names_1923_unit.py index cf43ffa6a2..c85ee3d60f 100644 --- a/tests/project/test_pylint_pragma_names_1923_unit.py +++ b/tests/project/test_pylint_pragma_names_1923_unit.py @@ -4,7 +4,7 @@ A pragma that misspells its message, as ``import-outside-top-level`` did for ``import-outside-toplevel``, suppresses nothing. pylint reports ``W0012 unknown-option-value`` on it and still reports the message it was meant to -silence, but the lint job is advisory, so nothing noticed. +silence, but Lint's pylint step is advisory, so nothing noticed. :data:`KNOWN_MESSAGES` pins the names the package's pragmas use, and every pragma name has to be on it, so that check runs on every leg with nothing diff --git a/tests/project/test_python_matrix_tiers_1633.py b/tests/project/test_python_matrix_tiers_1633.py index f64a3aa297..08b4d89c71 100644 --- a/tests/project/test_python_matrix_tiers_1633.py +++ b/tests/project/test_python_matrix_tiers_1633.py @@ -539,9 +539,10 @@ def runner_parse(line: 'str') -> 'Optional[tuple[str, dict[str, str], str]]': A port of ``ActionCommand.TryParseV2`` and its un-escaping, from ``src/Runner.Common/ActionCommand.cs`` in actions/runner at 5f0b3ddcc. The - properties end at the first ``::`` after the leading one (``:69``), and are - split on every ``,`` (``:100``, ``propertiesStr.Split(new[] { ',' }, ...)``) - *before* ``%2C`` becomes a comma (``:30``, ``:106``). A piece holding no + properties end at the first ``::`` after the leading one + (``message.IndexOf(_commandKey, _commandKey.Length)``), and are split on every + ``,`` (``propertiesStr.Split(new[] { ',' }, ...)``) *before* ``%2C`` becomes a + comma (``_escapePropertyMappings``, which ``UnescapeProperty`` applies). A piece holding no ``=`` is dropped without a word, so ``title=on 3.8 (KTLO, non-blocking)`` renders as "on 3.8 (KTLO". diff --git a/tests/project/test_python_versions_1660.py b/tests/project/test_python_versions_1660.py index b706969010..47d098e4b1 100644 --- a/tests/project/test_python_versions_1660.py +++ b/tests/project/test_python_versions_1660.py @@ -345,9 +345,9 @@ 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 (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. +#: Runtime" in images/ubuntu/Ubuntu2404-Readme.md (what ``ubuntu-latest`` named then), +#: Ubuntu2604-Readme.md (from 2026-10-19) and images/macos/macos-26-arm64-Readme.md +#: (``macos-latest``). Ubuntu2204-Readme.md's is 3.10.12, which has no tomllib. RUNNER_PYTHON3 = {'ubuntu-latest': ((3, 12), (3, 14)), 'macos-latest': ((3, 14),)} @@ -1031,11 +1031,11 @@ def test_each_claim_about_the_latest_leg_names_latest(self) -> None: #: The two builds as setup-python spells them, at actions/setup-python 3892123fb: a -#: free-threaded CPython as ``3.14t`` (src/find-python.ts:240, +#: free-threaded CPython as ``3.14t`` (src/find-python.ts's ``desugarFreeThreadedVersion``, #: ``/^(\d+\.\d+(\.\d+)?)(t)$/``), and GraalPy as ``graalpy-`` -#: (src/find-graalpy.ts:115-125; README.md:55, ``graalpy-24.0``), the version being -#: a GraalPy release line, matched as a semver range against oracle/graalpython's -#: release tags (src/install-graalpy.ts:213-248). +#: (src/find-graalpy.ts's ``parseGraalPyVersion``; README.md's "Basic usage", +#: ``graalpy-24.0``), the version being a GraalPy release line, matched as a semver +#: range against oracle/graalpython's release tags (src/install-graalpy.ts's ``findRelease``). SETUP_PYTHON = {'cpython': re.compile(r'3\.\d+t'), 'graalpy': re.compile(r'graalpy-\d+\.\d+')} #: :data:`TIERS_AT_MAIN` with one experimental build of each, listed last as the file lists them. EXPERIMENTAL_LEGS = [{'python-version': '3.14t', 'experimental': True}, diff --git a/tests/project/test_regenerate_samples_1967.py b/tests/project/test_regenerate_samples_1967.py index 89ab25c4e2..3b0b98a6a2 100644 --- a/tests/project/test_regenerate_samples_1967.py +++ b/tests/project/test_regenerate_samples_1967.py @@ -32,7 +32,7 @@ #: The jobs whose step runs the script, and the level each takes from where. LEVELLED_JOBS = ('integration', 'pypcap-parity') GATE = 'gate' -#: Text only the old inline step held, which no workflow may hold now. +#: Text only the old inline step held, which no workflow may hold. INLINE = ('make_samples.py', 'make-samples.log', '(download unavailable)', 'Sample fixture generation failed') FAILED = ('title=Sample fixture generation failed::examples/generators/make_samples.py could not rebuild ' diff --git a/tests/project/test_release_conda_scripts_1967.py b/tests/project/test_release_conda_scripts_1967.py index 034d0aafd1..61ba73d65c 100644 --- a/tests/project/test_release_conda_scripts_1967.py +++ b/tests/project/test_release_conda_scripts_1967.py @@ -399,7 +399,7 @@ def upload_env(self, case: 'tuple[object, ...]') -> 'dict[str, str]': return self.env(extra, PCAPKIT_CONDA_LABELS=labels, PCAPKIT_CONDA_PACKAGES=packages) # type: ignore[arg-type] -#: Each step, as ``(workflow, job, step name)``, and the ``run:`` it now holds. +#: Each step, as ``(workflow, job, step name)``, and the ``run:`` it holds. STEPS = { ('create-release.yml', 'conda', 'Check whether this leg is already on Anaconda'): 'python3 util/release_conda.py leg /tmp/anaconda_release.json', diff --git a/tests/project/test_release_gates.py b/tests/project/test_release_gates.py index 3e74d1a8d4..c512b06293 100644 --- a/tests/project/test_release_gates.py +++ b/tests/project/test_release_gates.py @@ -4006,7 +4006,7 @@ def test_removing_the_status_check_reproduces_the_defect(self) -> None: """ pre_fix = self._pre_fix_jobs() - # #1967: the gate is a job of `head` now, and a row reports a call one + # #1967: the gate is a job of `head`, and a row reports a call one # of whose jobs ran as `success` (see `head_result`). `skipped` is the # shape #1632 found, a skipped job ahead of the chain. context = conda_context(head='skipped') diff --git a/tests/project/test_release_scripts_1967.py b/tests/project/test_release_scripts_1967.py index f1e01d4e03..b1034cce3b 100644 --- a/tests/project/test_release_scripts_1967.py +++ b/tests/project/test_release_scripts_1967.py @@ -157,7 +157,7 @@ done <<< "$PCAPKIT_ASSETS" ''').lstrip() -#: Each step, as ``(job, step name)``, and the ``run:`` it now holds. +#: Each step, as ``(job, step name)``, and the ``run:`` it holds. STEPS = { ('version_check', "Check which commit the version's tag names"): 'python3 util/release_tags.py owner', ('github', "Check the release tags name this run's commit"): 'python3 util/release_tags.py check', diff --git a/tests/project/test_release_status_scripts_1967.py b/tests/project/test_release_status_scripts_1967.py index ae559cfa89..4443eb7211 100644 --- a/tests/project/test_release_status_scripts_1967.py +++ b/tests/project/test_release_status_scripts_1967.py @@ -235,7 +235,7 @@ esac ''').lstrip() -#: Each job, the step its script runs as, the ``run:`` it now holds, and its +#: Each job, the step its script runs as, the ``run:`` it holds, and its #: permissions. JOBS = { 'release_status': ('Report why this run did or did not release anything', 'python3 util/release_status.py', diff --git a/tests/project/test_release_tags_the_run_sha_1634.py b/tests/project/test_release_tags_the_run_sha_1634.py index 699cd4e542..1ea75c6280 100644 --- a/tests/project/test_release_tags_the_run_sha_1634.py +++ b/tests/project/test_release_tags_the_run_sha_1634.py @@ -319,7 +319,7 @@ def test_only_github_runs_the_release_action(self) -> None: """``pypi`` and ``conda`` used it to upload, which re-checked the target. ``action-gh-release`` 3.0.2 calls Update a release on an existing - release before uploading anything (``src/github.ts:631-683``), passing + release before uploading anything (``release`` in ``src/github.ts``), passing the release's own ``target_commitish`` when the input is unset, and GitHub's REST docs apply the workflow-file rule there to "the new value of target_commitish if you are changing it, otherwise the existing @@ -356,8 +356,8 @@ def test_a_refused_tag_is_explained(self) -> None: with self.subTest(status=status): self.assertIn(status, step['run']) # A final release is created as a draft and published by Update a release - # in the same step (``src/github.ts:1025``); a re-run would find a draft - # left behind and keep its target (``:636-647``). + # in the same step (``createRelease`` in ``src/github.ts``); a re-run would + # find a draft left behind and keep its target (``release``). self.assertIn('delete any draft release', step['run']) self.assertGreater(self.index('github', EXPLAIN_STEP), self.steps['github'].index(next( @@ -374,12 +374,15 @@ class TestTheReleaseAppToken(WorkflowMixin, unittest.TestCase): authorized for this". ``actions/create-github-app-token`` v3.3.0, which ``v3`` names: ``client-id`` "GitHub App Client ID", ``private-key`` required, one ``permission-`` input each, ``permission-workflows`` - "Can be set to 'write'" (``action.yml:8-17,51-52,147-148``), and output + "Can be set to 'write'" (the ``client-id``, ``private-key``, + ``permission-contents`` and ``permission-workflows`` inputs of + ``action.yml``), and output ``token``. With no ``owner`` or ``repositories``, "access will be scoped to only the current repository", and the token "is revoked in the ``post`` step of the action, which means it cannot be passed to another job" - (``README.md:389,436``). Without a ``permission-*`` input "the token - inherits all of the installation's permissions" (``:402``), so both are + (README.md's ``repositories`` and "How it works" sections). Without a + ``permission-*`` input "the token inherits all of the installation's + permissions" (its ``permission-`` section), so both are named and nothing else is. """ @@ -400,7 +403,7 @@ def test_it_is_minted_straight_before_create_release(self) -> None: def test_only_create_release_spends_it(self) -> None: """The ``token:`` input, with no ``env:`` beside it: 3.0.2's ``parseToken`` prefers a non-empty ``INPUT_TOKEN`` and falls back to ``GITHUB_TOKEN`` - (``src/util.ts:107-113``), so an ``env:`` token would only ever be a + (``src/util.ts``), so an ``env:`` token would only ever be a second credential handed to the action.""" step = self.create_release() self.assertEqual(step.get('with', {}).get('token'), RELEASE_TOKEN) @@ -609,9 +612,10 @@ class TestUploadsStayOffUpdateARelease(WorkflowMixin, unittest.TestCase): GitHub's REST docs state the workflow-file rule for Create a release and Update a release, and none for Upload a release asset. ``gh release upload`` reads the release, then POSTs each file to its ``upload_url`` - (cli/cli 2.102.0, ``pkg/cmd/release/upload/upload.go:89-116``). Without - ``--clobber`` it refuses a name the release already has (``:94-108``); with - it, it deletes that asset first (``pkg/cmd/release/shared/upload.go:141-146``), + (cli/cli 2.102.0, ``uploadRun`` in ``pkg/cmd/release/upload/upload.go``). + Without ``--clobber`` it refuses a name the release already has; with it, it + deletes that asset first (``uploadWithDelete`` in + ``pkg/cmd/release/shared/upload.go``), which Delete a release asset's docs state no workflow-file rule for either. """ @@ -1345,7 +1349,7 @@ class TestTheCountsAreOfTheReleasedPlatforms(ScratchRepository): """``version_check`` counts the conda platforms a tagged version was released for (#2060). ``pre`` is tagged before util/release_published.py existed, as every tag up to - v1.5.0b14 is; ``added`` adds it with the three platforms #1967 transcribed + v1.5.0b14 is; ``added`` adds it with the platforms #1967 transcribed from the step's shell; ``windows`` adds win-64, as #2060 did; the run is on ``windows``. Counting this run's platforms for a version tagged earlier read v1.5.0b14 as lacking win-64, and Release status warned that it was unfinished @@ -1638,7 +1642,7 @@ def test_a_new_release_gets_every_file_in_order(self) -> None: def test_a_pattern_matching_nothing_fails(self) -> None: """A change from the action, which only warned: ``fail_on_unmatched_files`` - is unset here, so 3.0.2's ``src/run.ts:15-20`` logs "🤔 Pattern '…' does + is unset here, so 3.0.2's ``run`` in ``src/run.ts`` logs "🤔 Pattern '…' does not match any files." and carries on.""" self.published() result = self.upload('pypi') @@ -1648,8 +1652,8 @@ def test_a_pattern_matching_nothing_fails(self) -> None: def test_a_missing_release_fails_before_any_upload(self) -> None: """A change from the action, which made one: with no release for the tag, - 3.0.2 calls ``createRelease`` (``src/github.ts:617-628``) with no notes - and ``target_commitish`` unset (``:1026``, ``src/util.ts:133``), which + 3.0.2 calls ``createRelease`` (from ``release`` in ``src/github.ts``) with + no notes and ``target_commitish`` unset (``parseConfig`` in ``src/util.ts``), which Create a release defaults to "the repository's default branch". Making the release is ``github``'s job, at the run's commit.""" self.build(self.WHEEL) @@ -1688,22 +1692,25 @@ class TestCondaUpdateNeverMakesTheRelease(CondaDistMixin, unittest.TestCase): ``conda-dist`` attaches its packages with ``ncipollo/release-action@v1.21.0`` and ``allowUpdates: true``, kept so #1632's ``test_cron_conda_really_does_publish`` - still finds it. That action's ``createOrUpdateRelease`` (``src/Action.ts:53-70``) + still finds it. That action's ``createOrUpdateRelease`` (``src/Action.ts``) reads the release by tag, which GitHub's REST docs give as "a published release"; on a 404 it updates a draft of that tag or else calls - ``createRelease`` (``:72-92``), both with ``target_commitish: commit`` - (``:107-120``, ``src/Releases.ts:76-99,150-174``). With no release, a bump + ``createRelease`` (``checkForMissingReleaseError`` and + ``updateDraftOrCreateRelease``), both with ``target_commitish: commit`` + (``updateRelease``, and ``GithubReleases.create`` and ``GithubReleases.update`` in + ``src/Releases.ts``). With no release, a bump made while Create Release waits on its approval -- 1.5.0b9 waited three days, and cron-conda bumped three times meanwhile -- would put ``v`` on ``main``'s tip, and Create Release's tag check would then - fail. A draft stays a draft (``omitDraftDuringUpdate``, - ``src/Inputs.ts:210-213``) but is retargeted at ``commit``; Create Release's + fail. A draft stays a draft (``omitDraftDuringUpdate``, through + ``CoreInputs.updatedDraft`` in ``src/Inputs.ts``) but is retargeted at ``commit``; Create Release's ``workflow_run`` run finds the draft and resets its target to the run's sha - (``action-gh-release`` 3.0.2's ``src/github.ts:636-646,832-866``), so + (``action-gh-release`` 3.0.2's ``release`` and ``findTagFromReleases`` in + ``src/github.ts``), so skipping a draft is a precaution against retargeting a release Create Release owns. On an existing release it calls Update a release with - ``target_commitish: commit`` (``src/Action.ts:107-120``, - ``src/Releases.ts:150-174``), and GitHub's REST docs check "the new value of + ``target_commitish: commit`` (``Action.updateRelease`` in ``src/Action.ts``, + ``GithubReleases.update`` in ``src/Releases.ts``), and GitHub's REST docs check "the new value of target_commitish if you are changing it, otherwise the existing target" against the workflow-file rule, which since #1634 is the run's commit. """ diff --git a/tests/project/test_release_version_check_scripts_1967.py b/tests/project/test_release_version_check_scripts_1967.py index 1aa41ae5e9..a20d7c69cc 100644 --- a/tests/project/test_release_version_check_scripts_1967.py +++ b/tests/project/test_release_version_check_scripts_1967.py @@ -296,7 +296,7 @@ def bash_version() -> 'str': echo "PCAPKIT_CONDA_COMPLETE=$complete" >> "$GITHUB_OUTPUT" ''').lstrip() -#: Each step, its id, the ``run:`` it now holds, and the former shell, the +#: Each step, its id, the ``run:`` it holds, and the former shell, the #: ``/tmp`` file it wrote standing for where the cases write it. STEPS = { 'Read the released Python versions': ('released', 'python3 util/release_tiers.py', FORMER_TIERS), diff --git a/tests/project/test_requires_python_floor_2051.py b/tests/project/test_requires_python_floor_2051.py index 86cf54a4af..a5491a9c36 100644 --- a/tests/project/test_requires_python_floor_2051.py +++ b/tests/project/test_requires_python_floor_2051.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -"""#2051: 1.5.0 requires Python 3.8, and nothing converts the sources any more. +"""#2051: 1.5.0 requires Python 3.8, and nothing converts the sources. The owner's ruling on #2040 raised ``requires-python`` to ``>=3.8`` and dropped the ``bpc-*`` backport tools, which are no longer maintained. Pinned here: diff --git a/tests/project/test_resource_monitor_1740.py b/tests/project/test_resource_monitor_1740.py index 79179e16e8..0670431d74 100644 --- a/tests/project/test_resource_monitor_1740.py +++ b/tests/project/test_resource_monitor_1740.py @@ -548,7 +548,7 @@ def test_only_the_experimental_job_runs_it(self) -> None: with self.subTest(workflow=path.name): self.assertNotIn('resource-monitor', path.read_text(encoding='utf-8')) self.assertIs(job(*EXPERIMENTAL).get('continue-on-error'), True) - # #2030: last but the two that name and upload the job's summary. + # #2030: last but the steps that name and upload the job's summary. self.assertEqual([entry['name'] for entry in steps()[-3:]], ['Experimental summary', 'Name the job summary', 'Upload the job summary']) diff --git a/tests/project/test_rfc_anchor_fragments.py b/tests/project/test_rfc_anchor_fragments.py index a75fe6ed20..7d0bf77a4c 100644 --- a/tests/project/test_rfc_anchor_fragments.py +++ b/tests/project/test_rfc_anchor_fragments.py @@ -25,9 +25,9 @@ The sweep this test is built on also turned up a **second** instance of the same defect: ``:rfc:`5797#secion-2.2``` in the ``feat`` attribute docstring of -the ``Command`` class (not ``FEATCode``), at -:file:`pcapkit/vendor/ftp/command.py:296` and its generated copy -:file:`pcapkit/const/ftp/command.py:284`. Same missing ``t``, same two files, +the ``Command`` class (not ``FEATCode``), in +:file:`pcapkit/vendor/ftp/command.py` and its generated copy +:file:`pcapkit/const/ftp/command.py`. Same missing ``t``, same two files, same one-character fix -- fixed alongside #942's rather than carried as a documented exception. @@ -40,13 +40,13 @@ ``id="3.1"`` -- so accepting that shape blessed exactly the defect class this test exists to catch, the same mistake as the allowlist above one layer down. The generators that produce them, -:file:`pcapkit/vendor/tcp/mp_tcp_option.py:59` and -:file:`pcapkit/vendor/reg/apptype/apptype.py:1200` (both parsing IANA's +``MPTCPOption.process`` in :file:`pcapkit/vendor/tcp/mp_tcp_option.py` and +``AppType.records`` in :file:`pcapkit/vendor/reg/apptype/apptype.py` (both parsing IANA's ``RFC8684, Section 3.1`` with the same ``re.fullmatch(r'RFC(?P\\d+)(, Section (?P.*?))?', ...)``, which discards the literal word ``Section`` and keeps only the number), are fixed to emit ``#section-{sec}``, and the ten already-generated lines are fixed to match -- exactly what a regeneration -would now produce, verified by reading the generators rather than by running +would produce, verified by reading the generators rather than by running 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 diff --git a/tests/project/test_superseded_containment_summary_2077.py b/tests/project/test_superseded_containment_summary_2077.py index 5e0cde7a8a..3bb77ecbe6 100644 --- a/tests/project/test_superseded_containment_summary_2077.py +++ b/tests/project/test_superseded_containment_summary_2077.py @@ -5,7 +5,7 @@ ``watch`` stopped pytest 61 s in, ``main`` having moved on, and exited 0 as it does for every stop. ``Containment summary`` read that status and closed on ``tests exited 0 after 61 s``, which reads as a pass. #2076 has the watcher -write ``stopped=true`` to ``Run unit tests``'s outputs, so the summary now +write ``stopped=true`` to ``Run unit tests``'s outputs, so the summary reads it and says the tests were stopped as superseded. It adds no warning for the stop, as the watcher's ``Superseded`` notice already says why, and keeps every warning it gives for a real cause. diff --git a/tests/project/test_superseded_junit_upload_2073.py b/tests/project/test_superseded_junit_upload_2073.py index d451a7ed2f..50e55def69 100644 --- a/tests/project/test_superseded_junit_upload_2073.py +++ b/tests/project/test_superseded_junit_upload_2073.py @@ -7,7 +7,7 @@ /home/runner/work/_temp/junit*.xml``: pytest, stopped, writes no JUnit file, and ``Upload test timings`` ran on as for any finished run. The watcher's ``Superseded`` notice already says why the file is missing, so the watcher -now writes ``stopped=true`` to the step's outputs and the upload reads it. +writes ``stopped=true`` to the step's outputs and the upload reads it. """ diff --git a/tests/project/test_superseded_summary_copy_2078.py b/tests/project/test_superseded_summary_copy_2078.py index bef8fadec9..a37dae7ba0 100644 --- a/tests/project/test_superseded_summary_copy_2078.py +++ b/tests/project/test_superseded_summary_copy_2078.py @@ -5,7 +5,7 @@ legs were stopped as superseded, and the one line their job summaries held was util/superseded.py's, which went to ``$GITHUB_STEP_SUMMARY`` alone, so ``job-summary.md`` was never written and ``Upload the job summary`` found nothing. -The watcher now takes the copy's path as ``--summary-copy``, which ``Run unit +The watcher takes the copy's path as ``--summary-copy``, which ``Run unit tests`` passes it, and the tests it runs never see. * :class:`TestTheSteps` runs ``Run unit tests`` and ``Name the job summary`` as diff --git a/tests/project/test_sweeps_on_latest_only_1732.py b/tests/project/test_sweeps_on_latest_only_1732.py index 100c8f66c0..c8fbea21ab 100644 --- a/tests/project/test_sweeps_on_latest_only_1732.py +++ b/tests/project/test_sweeps_on_latest_only_1732.py @@ -527,7 +527,7 @@ def test_a_failure_never_turns_the_run_red(self) -> None: spec = self.own['jobs']['experimental'] self.assertIs(spec.get('continue-on-error'), True) self.assertEqual(spec['env'], {'ANNOTATION_LEVEL': 'warning'}) - # #2030: the last step but the two that name and upload the job's summary. + # #2030: the last step but the steps that name and upload the job's summary. self.assertEqual([entry['name'] for entry in spec['steps'][-3:]], ['Experimental summary', 'Name the job summary', 'Upload the job summary']) # #2060: the Windows leg's job, as tests/project/test_windows_test_leg_2060.py pins. diff --git a/tests/project/test_unit_tests_push_reports_2030.py b/tests/project/test_unit_tests_push_reports_2030.py index fd864db0e6..aa085ef196 100644 --- a/tests/project/test_unit_tests_push_reports_2030.py +++ b/tests/project/test_unit_tests_push_reports_2030.py @@ -11,7 +11,7 @@ its ``if:`` and its scopes; each ``discussion`` takes the events it posts and is the one job holding ``discussions: write``; a relayed run's concurrency group is its own; the checkout is the default branch's scripts, never the run's head; - and the two relays' steps are one. + and both relays' steps are one. * :class:`TestTheScriptsWorkflows` holds the script's :data:`WORKFLOWS` to the workflow files: their names, file stems, by-design lists and gated legs. * :class:`TestTheJobSummaries` pins how each job keeps a copy of its summary and @@ -85,7 +85,7 @@ NEEDS = {'python-versions': {'outputs': {'latest': '3.15'}}} #: The step outputs ``Write the run report`` hands on. OUTPUTS = ('post', 'title', 'mode', 'status') -#: The job summary's copy, and the two steps that end each job that writes one. +#: The job summary's copy, and the steps that end each job that writes one. COPY = '${{ runner.temp }}/job-summary.md' SAVE, UPLOAD = 'Name the job summary', 'Upload the job summary' #: Each job that writes its summary, as ``(workflow, job)``: the KTLO summaries, diff --git a/tests/project/test_unit_tests_queue.py b/tests/project/test_unit_tests_queue.py index 14fb191ef9..294883783f 100644 --- a/tests/project/test_unit_tests_queue.py +++ b/tests/project/test_unit_tests_queue.py @@ -496,7 +496,7 @@ def test_no_ktlo_cell_is_a_passing_no_op(self) -> None: self.assertEqual(status, 0) -#: The two apt steps, as (job, step name, extra env), each with its job's ``APT_PACKAGES``. +#: The apt steps, as (job, step name, extra env), each with its job's ``APT_PACKAGES``. APT_STEPS: 'tuple[tuple[str, str, dict[str, str]], ...]' = ( ('engine-tests', "Install this engine's system packages", {'ENGINE': 'PyShark', 'APT_PACKAGES': 'tshark'}), ('pypcap-parity', 'Install libpcap headers, a C toolchain, and tshark', diff --git a/tests/project/test_windows_test_leg_2060.py b/tests/project/test_windows_test_leg_2060.py index 1c7c8bf004..25c9357e67 100644 --- a/tests/project/test_windows_test_leg_2060.py +++ b/tests/project/test_windows_test_leg_2060.py @@ -165,7 +165,7 @@ def test_no_step_can_fail_the_leg(self) -> None: self.assertEqual(conclusion, 'success') def test_the_summary_sees_every_failure(self) -> None: - """Last but the job summary's two steps, after any failure, and every step it reports has an ``id``.""" + """Last but the job summary's steps, after any failure, and every step it reports has an ``id``.""" self.assertEqual([label(entry) for entry in self.spec['steps'][self.position + 1:]], list(JOB_SUMMARY_STEPS)) self.assertEqual(self.summary['if'], '${{ !cancelled() }}') self.assertEqual(self.summary['shell'], 'bash') diff --git a/tests/project/test_workflow_hardening_1968.py b/tests/project/test_workflow_hardening_1968.py index 1a0816c14d..d9e8703cb9 100644 --- a/tests/project/test_workflow_hardening_1968.py +++ b/tests/project/test_workflow_hardening_1968.py @@ -292,7 +292,7 @@ def test_the_built_site_reaches_the_publish_job_whole(self) -> None: self.assertEqual(deploy['with']['folder'], 'docs/build/html') -#: A ``gh`` that answers the two ``gh api`` calls the check makes from the +#: A ``gh`` that answers the ``gh api`` calls the check makes from the #: environment, and logs each call. ``$2`` is the endpoint. GH_STUB = '''#!/bin/sh printf '%s\\n' "$*" >> "$STUB_LOG" diff --git a/tests/project/test_workflow_run_verdict.py b/tests/project/test_workflow_run_verdict.py index a3e1e49a6a..6a300dbcdd 100644 --- a/tests/project/test_workflow_run_verdict.py +++ b/tests/project/test_workflow_run_verdict.py @@ -412,7 +412,7 @@ def test_the_harness_git_runs_no_maintenance(self) -> None: def head_result(unit_tests: 'str', verdict: 'str') -> 'str': - """What the caller's ``needs.head.result`` is taken to be, from the two jobs of + """What the caller's ``needs.head.result`` is taken to be, from the jobs of :data:`HEAD` (#1967). A failure in either is a failure, which is what the acting jobs' ``!= @@ -436,7 +436,7 @@ def _context(event_name: 'str' = 'workflow_run', conclusion: 'str' = 'success', verified: 'object' = 'true', cancelled: bool = False) -> 'dict[str, object]': """One run's ``github``/``needs`` context; the defaults are a verdict that covers its checkout. - ``unit_tests`` and ``verdict`` are the results of :data:`HEAD`'s two jobs, + ``unit_tests`` and ``verdict`` are the results of :data:`HEAD`'s jobs, which make the caller's ``head`` result through :func:`head_result`. ``verified=NULL`` is a ``verdict`` job that wrote no output, which is what a skipped or failed one leaves, and the call passes it on as it is. diff --git a/tests/protocols/application/test_http_unit.py b/tests/protocols/application/test_http_unit.py index fb39439ba2..cb42561e37 100644 --- a/tests/protocols/application/test_http_unit.py +++ b/tests/protocols/application/test_http_unit.py @@ -217,10 +217,10 @@ def test_http_construction_reaches_the_versioned_make_callee(self) -> None: ``protocol.make(**kwargs)`` dispatch this issue is actually about. The real, supported entry point is construction: - :meth:`ProtocolBase.__init__` (``protocol.py:1203``, the ``**kwargs``- - only overload at ``:1201``) calls ``self.pack(**kwargs)``, through + :meth:`ProtocolBase.__init__` (the implementation behind its + ``**kwargs``-only overload) calls ``self.pack(**kwargs)``, through :meth:`~ProtocolBase.__post_init__`, when built with no ``file``, and - :meth:`ProtocolBase.pack` (``protocol.py:761``) calls + :meth:`ProtocolBase.pack` calls ``target.make(**kwargs)`` on :meth:`~ProtocolBase._packing_target`, which while constructing is the instance itself -- a *bound* call on the outer ``HTTP`` instance, which is what actually reaches the inner, @@ -2086,7 +2086,7 @@ def test_httpv2_read_validates_common_frame_header_rules(self) -> None: def test_httpv2_truncated_frame_is_rejected_uniformly_regardless_of_declared_length(self) -> None: """#799: a buffer of four real octets must refuse *every* declared length. - ``httpv2.py:223`` used to read ``if schema.length < 9:`` -- the declared + ``HTTP.read`` in ``httpv2.py`` used to read ``if schema.length < 9:`` -- the declared 24-bit length off the wire, never the buffer's -- so a frame whose real buffer held only four octets still parsed whenever the declared value happened to clear nine and (for ``SETTINGS``) land on a multiple of six @@ -2711,7 +2711,7 @@ def test_a_flagless_frame_seeds_its_flags_as_an_enum(self) -> None: # made a memberless ``enum.Flag`` subclass refuse ``Flags(0)`` # outright, where earlier interpreters handed back a pseudo-member -- # ``Enum.__new__`` gained ``if not cls._member_map_: raise TypeError`` - # (3.11's ``enum.py:1117``), which runs *before* the ``_missing_`` hook + # in 3.11, which runs *before* the ``_missing_`` hook # that used to manufacture one. Measured either side of the boundary # rather than taken from a changelog: # diff --git a/tests/protocols/application/test_httpv2_payload_length_unit.py b/tests/protocols/application/test_httpv2_payload_length_unit.py index 41df878b87..1ac828f289 100644 --- a/tests/protocols/application/test_httpv2_payload_length_unit.py +++ b/tests/protocols/application/test_httpv2_payload_length_unit.py @@ -233,7 +233,7 @@ def parse(self, raw: 'bytes') -> 'Any': @unittest.skipUnless(HAS_RUNTIME, 'runtime dependencies not installed') class HTTPv2DataFramePayloadLengthUnitTests(FramePayloadMixin, unittest.TestCase): - """``DATA`` -- ``pcapkit/protocols/schema/application/httpv2.py:235``.""" + """``DATA`` -- ``DataFrame`` in ``pcapkit/protocols/schema/application/httpv2.py``.""" #: ``DATA``, :rfc:`9113#section-6.1`. TYPE = 0x00 @@ -297,7 +297,7 @@ def test_a_padded_data_frame_of_only_padding_reads_an_empty_payload(self) -> Non @unittest.skipUnless(HAS_RUNTIME, 'runtime dependencies not installed') class HTTPv2HeadersFramePayloadLengthUnitTests(FramePayloadMixin, unittest.TestCase): - """``HEADERS`` -- ``pcapkit/protocols/schema/application/httpv2.py:284``.""" + """``HEADERS`` -- ``HeadersFrame`` in ``pcapkit/protocols/schema/application/httpv2.py``.""" #: ``HEADERS``, :rfc:`9113#section-6.2`. TYPE = 0x01 @@ -409,7 +409,7 @@ def test_a_padded_priority_headers_frame_of_only_padding_is_empty_too(self) -> N @unittest.skipUnless(HAS_RUNTIME, 'runtime dependencies not installed') class HTTPv2PushPromiseFramePayloadLengthUnitTests(FramePayloadMixin, unittest.TestCase): - """``PUSH_PROMISE`` -- ``pcapkit/protocols/schema/application/httpv2.py:382``.""" + """``PUSH_PROMISE`` -- ``PushPromiseFrame`` in ``pcapkit/protocols/schema/application/httpv2.py``.""" #: ``PUSH_PROMISE``, :rfc:`9113#section-6.6`. TYPE = 0x05 @@ -488,14 +488,14 @@ class HTTPv2PlainLengthFormControlUnitTests(FramePayloadMixin, unittest.TestCase """ def test_continuation_frame_carries_its_fragment(self) -> None: - """``CONTINUATION`` -- ``httpv2.py:453``, the plain form.""" + """``CONTINUATION`` -- ``ContinuationFrame``, the plain form.""" raw = http2_frame_bytes(0x09, 0x04, 1, FRAGMENT) info = self.parse(raw) self.assertEqual(info.fragment, FRAGMENT) def test_goaway_frame_carries_its_debug_data(self) -> None: - """``GOAWAY`` -- ``httpv2.py:423``, the plain form.""" + """``GOAWAY`` -- ``GoawayFrame``, the plain form.""" from pcapkit.const.http.error_code import ErrorCode payload = ((5).to_bytes(4, 'big') @@ -509,7 +509,7 @@ def test_goaway_frame_carries_its_debug_data(self) -> None: self.assertEqual(info.error, ErrorCode.ENHANCE_YOUR_CALM) def test_unassigned_frame_carries_its_data(self) -> None: - """An unregistered frame type -- ``httpv2.py:199``, the plain form. + """An unregistered frame type -- ``UnassignedFrame``, the plain form. ``0xF0`` is in the range :rfc:`9113#section-5.5` leaves for extensions, so this is expected traffic; the reader warns about it, which is why the diff --git a/tests/protocols/internet/test_ipv4_unit.py b/tests/protocols/internet/test_ipv4_unit.py index ea08cfe1a6..e18ec2c82d 100644 --- a/tests/protocols/internet/test_ipv4_unit.py +++ b/tests/protocols/internet/test_ipv4_unit.py @@ -226,7 +226,7 @@ def test_ipv4_make_accepts_a_protocol_instance_as_payload(self) -> None: # defect. Asserting the negative matters because the branch was not # uncovered before the fix -- it was covered by the only class in the # tree that satisfied it, ``DummyProtocol`` in - # tests/protocols/schema/test_schema_unit.py:168, which subclasses + # tests/protocols/schema/test_schema_unit.py, which subclasses # ``Protocol`` and so packed happily while every protocol in the # library raised. Without this line the same hole could be reopened # by making a protocol subclass ``Protocol`` rather than by fixing diff --git a/tests/protocols/internet/test_ipv6_ext_unit.py b/tests/protocols/internet/test_ipv6_ext_unit.py index 3f7e7e75ec..13dc954250 100644 --- a/tests/protocols/internet/test_ipv6_ext_unit.py +++ b/tests/protocols/internet/test_ipv6_ext_unit.py @@ -576,7 +576,7 @@ def test_every_subclass_index_returns_a_real_transtype(self) -> None: def test_every_subclass_alias_survives_the_packet_dict_key_computation(self) -> None: """:meth:`IPv6._decode_next_layer ` keys its - packet dict by ``alias.lstrip('IPv6-').lower()`` (``ipv6.py:455``, in ``_exthdr_key``). + packet dict by ``alias.lstrip('IPv6-').lower()`` (in ``_exthdr_key``). :meth:`str.lstrip` strips a character *set*, so the hyphen in ``IPv6-Route``/``IPv6-Frag``/``IPv6-Opts`` is what lets ``IPv6`` fall away cleanly, where the underscore of a class-name default like diff --git a/tests/protocols/internet/test_mh_unit.py b/tests/protocols/internet/test_mh_unit.py index 0735fe6d1d..3625f2ed78 100644 --- a/tests/protocols/internet/test_mh_unit.py +++ b/tests/protocols/internet/test_mh_unit.py @@ -1840,8 +1840,8 @@ def wrap_in_ipv4(mh_payload: bytes) -> IPv4: with self.subTest('over IPv6, the raise now costs only the MH slot (GitHub issue #891)'): # Mobility Header is *also* one of IPv6's own chained extension - # headers (``Enum_ExtensionHeader.Mobility_Header``, value 135 -- - # ``pcapkit/const/ipv6/extension_header.py:55``), so IPv6 never + # headers (``Enum_ExtensionHeader.Mobility_Header``, value 135, in + # ``pcapkit/const/ipv6/extension_header.py``), so IPv6 never # reaches the fallback through the base ``_import_next_layer`` at # all -- it walks its own ``@beholder``-decorated override # (``pcapkit/protocols/internet/ipv6.py:_import_next_layer``). @@ -2942,8 +2942,8 @@ def test_mh_bool_is_still_a_valid_value_for_an_integer_field(self) -> None: """#508 must not spread to fields where a :obj:`bool` legitimately means 0/1. ``NonceIndicesOption.home`` is a - :class:`~pcapkit.corekit.fields.numbers.UInt16Field` at - ``pcapkit/protocols/schema/internet/mh.py:708`` -- a nonce *index* rather + :class:`~pcapkit.corekit.fields.numbers.UInt16Field` in + :mod:`pcapkit.protocols.schema.internet.mh` -- a nonce *index* rather than an address -- so ``home=True`` packing as ``1`` is correct, not a defect. ``BindingRevocationMessage.code`` makes the same point through a :class:`~pcapkit.corekit.fields.misc.SwitchField`, which is why the guard diff --git a/tests/protocols/misc/test_fromtimestamp_windows_range_2099_unit.py b/tests/protocols/misc/test_fromtimestamp_windows_range_2099_unit.py index 8c6e4f7733..3a6d482282 100644 --- a/tests/protocols/misc/test_fromtimestamp_windows_range_2099_unit.py +++ b/tests/protocols/misc/test_fromtimestamp_windows_range_2099_unit.py @@ -55,7 +55,7 @@ #: Java ``LocalDateTime``, which has no year-1 floor, and its constructor then #: raises ``ValueError: year 0 is out of range`` (#2134, measured on GraalPy #: 25.4.4; graalpython ``TimeZoneBuiltins.java`` and ``DatetimeModuleBuiltins -#: .addOffsetToDateTime`` at graal-25.4.4, no upstream issue filed yet). Its +#: .addOffsetToDateTime`` at graal-25.4.4, no upstream issue filed). Its #: ``datetime + timedelta`` still raises :exc:`OverflowError`. ZONE_OVERFLOW = ValueError if sys.implementation.name == 'graalpy' else OverflowError diff --git a/tests/protocols/misc/test_pcapng_dsb_secrets_overrun_1980_unit.py b/tests/protocols/misc/test_pcapng_dsb_secrets_overrun_1980_unit.py index c4a42c8eb8..4d76c25a84 100644 --- a/tests/protocols/misc/test_pcapng_dsb_secrets_overrun_1980_unit.py +++ b/tests/protocols/misc/test_pcapng_dsb_secrets_overrun_1980_unit.py @@ -5,7 +5,7 @@ that many octets as secrets: the trailing Block Total Length and the blocks after it went with them, and past the zero-pad ceiling the read raised :exc:`~pcapkit.utilities.exceptions.FieldValueError` from inside the block's -schema, which ended the whole extraction. The secrets are now bounded by the +schema, which ended the whole extraction. The secrets are bounded by the block, as an Enhanced Packet Block's packet data is (#1405): the declared ``secrets_length`` is kept, a :class:`~pcapkit.utilities.warnings.ProtocolWarning` reports the overrun, and extraction carries on to the next block. diff --git a/tests/protocols/misc/test_pcapng_unit.py b/tests/protocols/misc/test_pcapng_unit.py index ea496cd415..012428bd8d 100644 --- a/tests/protocols/misc/test_pcapng_unit.py +++ b/tests/protocols/misc/test_pcapng_unit.py @@ -1407,8 +1407,8 @@ def test_tls_key_label_tracks_rfc_9850_plus_documented_rsa_exception(self) -> No self.assertEqual(len(TLSKeyLabel.__members__), 11) # Every member's value pinned exactly -- this is a value-matched - # registry (``TLSKeyLabel(label.upper())`` at - # pcapkit/protocols/schema/misc/pcapng.py:2249), so the value, not + # registry (``TLSKeyLabel(label.upper())`` in + # ``TLSKeyLog.post_process``), so the value, not # merely the name, is what callers depend on. for name in expected: with self.subTest(name=name): diff --git a/tests/protocols/misc/test_pcapng_zigbee_key_width_1986_unit.py b/tests/protocols/misc/test_pcapng_zigbee_key_width_1986_unit.py index 164cb7c66b..0614a9da81 100644 --- a/tests/protocols/misc/test_pcapng_zigbee_key_width_1986_unit.py +++ b/tests/protocols/misc/test_pcapng_zigbee_key_width_1986_unit.py @@ -5,7 +5,7 @@ ``secrets_length`` may declare fewer octets or more. A key shorter than the width parsed, but its data model rebuilt it at full width: the key zero-padded, ``secrets_length`` rewritten and the block grown. Octets past the width were -dropped, by the parse itself. The data model now keeps the Secrets Data octets +dropped, by the parse itself. The data model keeps the Secrets Data octets as the block holds them, the schema keeps those past the fixed fields, and both rebuild byte for byte. diff --git a/tests/protocols/schema/test_schema_metaclass_abc_cache_unit.py b/tests/protocols/schema/test_schema_metaclass_abc_cache_unit.py index 009040f0fb..eadac36299 100644 --- a/tests/protocols/schema/test_schema_metaclass_abc_cache_unit.py +++ b/tests/protocols/schema/test_schema_metaclass_abc_cache_unit.py @@ -254,8 +254,7 @@ def test_the_pcapng_1248_symptom_no_longer_reproduces(self) -> None: :meth:`NameResolutionBlock.post_process ` - asks ``isinstance(record, (IPv4Record, IPv6Record))`` at - :file:`pcapkit/protocols/schema/misc/pcapng.py:1876` and then reads + asks ``isinstance(record, (IPv4Record, IPv6Record))`` and then reads ``record.names``. Before #439 was fixed, every schema class shared one ``_abc_impl``, so that question answered ``True`` for the block's *terminating* ``EndRecord`` -- which has no ``names`` -- provided diff --git a/tests/protocols/test_construction_keyword_check_unit.py b/tests/protocols/test_construction_keyword_check_unit.py index c85367a90c..4d3ca55f2d 100644 --- a/tests/protocols/test_construction_keyword_check_unit.py +++ b/tests/protocols/test_construction_keyword_check_unit.py @@ -292,11 +292,9 @@ def test_the_exception_is_the_one_the_library_already_uses(self) -> None: Not a new exception type: the library already answers "you passed a keyword I do not accept" with - :exc:`~pcapkit.utilities.exceptions.UnsupportedCall`, in five places with - this exact message shape -- ``protocol.py:1469``, - ``dumpkit/common.py:169``, ``foundation/reassembly/reassembly.py:594``, - ``foundation/engines/engine.py:321`` and - ``foundation/traceflow/traceflow.py:563``. Reusing it keeps one answer to + :exc:`~pcapkit.utilities.exceptions.UnsupportedCall`, with this exact + message shape, in the ``__init_subclass__`` of ``ProtocolBase``, + ``Dumper``, ``Reassembly``, ``Engine`` and ``TraceFlow``. Reusing it keeps one answer to one question rather than adding a second. The honest caveat, recorded so it is a decision rather than an oversight: diff --git a/tests/protocols/test_lookup_by_name_2003_unit.py b/tests/protocols/test_lookup_by_name_2003_unit.py index 1f3bd7f9d3..fd4898490e 100644 --- a/tests/protocols/test_lookup_by_name_2003_unit.py +++ b/tests/protocols/test_lookup_by_name_2003_unit.py @@ -3,14 +3,14 @@ GitHub issue #2003: on PyPy, an :class:`~pcapkit.corekit.infoclass.Info` lays its keys out as an earlier instance of the same class did, so its key -order is not CPython's. Two lookups of a rebuild from ``to_dict()`` read +order is not CPython's. Lookups of a rebuild from ``to_dict()`` read structure off that order: the payload was taken to be the *last* nested key, and the IPv6 extension header chain was walked in key order. A cut frame rebuilt short, and so did a Hop-by-Hop, Destination, Destination chain once ``hopopt`` had moved past the upper layer. The order of an :class:`~pcapkit.corekit.infoclass.Info` is not part of its -contract, so nothing is read off it any more: ``to_dict()`` carries the +contract, so nothing is read off it: ``to_dict()`` carries the ``__next_type__`` and ``__next_name__`` metadata the payload is dispatched on, and ``__exthdr__``, the extension header chain as a tuple of parser and info pairs in wire order. A dict without the metadata is not guessed at. These tests reorder an diff --git a/tests/protocols/test_to_dict_payload_roundtrip_1447_unit.py b/tests/protocols/test_to_dict_payload_roundtrip_1447_unit.py index afb72a88bd..54c2f88151 100644 --- a/tests/protocols/test_to_dict_payload_roundtrip_1447_unit.py +++ b/tests/protocols/test_to_dict_payload_roundtrip_1447_unit.py @@ -8,7 +8,7 @@ its 14-octet header. IPv6 lost its extension headers the same way, with ``__exthdr__``, and HTTP raised ``ProtocolError('invalid HTTP data: Raw')``. -``to_dict`` now carries both keys, so the dict rebuild dispatches exactly as +``to_dict`` carries both keys, so the dict rebuild dispatches exactly as the info's, and the dumps leave every dunder key out (#2003). A dict without them is not guessed at: no payload is rebuilt. diff --git a/tests/protocols/transport/test_tcp_mptcp_addaddr_unit.py b/tests/protocols/transport/test_tcp_mptcp_addaddr_unit.py index f04fbe8ef7..db1e109575 100644 --- a/tests/protocols/transport/test_tcp_mptcp_addaddr_unit.py +++ b/tests/protocols/transport/test_tcp_mptcp_addaddr_unit.py @@ -4,7 +4,7 @@ Filed measurement: ``t._make_mptcp_addaddr(MPTCPOption.ADD_ADDR, addr_id=1, addr='1.2.3.4')`` warned ``UnknownFieldWarning`` twice -- once for ``kind``, once for ``length`` -- then constructed a schema whose ``.pack()`` raised ``KeyError: 'length'`` from the ``port`` -field's condition at (what was then) ``pcapkit/protocols/schema/transport/tcp.py:792``: +field's condition in :class:`~pcapkit.protocols.schema.transport.tcp.MPTCPAddAddress`: .. code-block:: python diff --git a/tests/protocols/transport/test_tcp_mptcp_error_message_unit.py b/tests/protocols/transport/test_tcp_mptcp_error_message_unit.py index c37e85310d..6ac307c25e 100644 --- a/tests/protocols/transport/test_tcp_mptcp_error_message_unit.py +++ b/tests/protocols/transport/test_tcp_mptcp_error_message_unit.py @@ -23,10 +23,12 @@ passes both before and after it, so the two places that already exercise these messages could not have caught this, and needed no edit -- -* ``test_tcp_mptcp_join_flag_ordering_unit.py:423``, which asserts +* ``TCPMPTCPJoinFlagOrderingUnitTests.test_neither_syn_nor_ack_raises_protocol_error`` + in ``test_tcp_mptcp_join_flag_ordering_unit.py``, which asserts ``assertIn('invalid flags combination', str(caught.exception))`` against ``_make_mptcp_join``, and -* ``test_tcp_udp_unit.py:1632``, which asserts +* ``TCPUDPUnitTests.test_a_flagless_segment_seeds_its_connection_flags_as_an_enum`` + in ``test_tcp_udp_unit.py``, which asserts ``assertRaisesRegex(ProtocolError, 'invalid flags combination')`` against ``_read_mptcp_join``. diff --git a/tests/protocols/transport/test_tcp_mptcp_join_flag_ordering_unit.py b/tests/protocols/transport/test_tcp_mptcp_join_flag_ordering_unit.py index 6253404aa0..97d56a7c40 100644 --- a/tests/protocols/transport/test_tcp_mptcp_join_flag_ordering_unit.py +++ b/tests/protocols/transport/test_tcp_mptcp_join_flag_ordering_unit.py @@ -13,9 +13,9 @@ .. code-block:: python - options_value, total_length = self._make_tcp_options(options) # tcp.py:547 + options_value, total_length = self._make_tcp_options(options) ... - self._flags = _flag # tcp.py:567 + self._flags = _flag but :meth:`TCP._make_mptcp_join `, reached from @@ -26,8 +26,8 @@ AttributeError: 'TCP' object has no attribute '_flags' The parse path has the identical pair of branches in ``_read_mptcp_join`` and is fine, -because :meth:`~pcapkit.protocols.transport.tcp.TCP.read` assigns ``self._flags`` at -``tcp.py:535``, before it parses the options at ``tcp.py:555``. Only the make path was +because :meth:`~pcapkit.protocols.transport.tcp.TCP.read` assigns ``self._flags`` +before it parses the options. Only the make path was inverted. The fix is the hoist: the ``flags`` dict and the ``_flag`` accumulation move above the @@ -104,7 +104,7 @@ The read path was checked for the same shape of problem and does **not** have it: :func:`~pcapkit.protocols.schema.transport.tcp.mptcp_data_selector` guards the flagless -case at ``schema/transport/tcp.py:242-250`` and raises +case and raises :exc:`~pcapkit.utilities.exceptions.FieldError` before ``_read_mptcp_join`` is reached at all, so its own closing ``ProtocolError`` stays unreachable and its ``cast('Enum_Flags', 0)`` is left alone. Changing it would alter the ``connection`` value diff --git a/tests/test_support_helpers.py b/tests/test_support_helpers.py index 5ac115d724..eb00ccfaef 100644 --- a/tests/test_support_helpers.py +++ b/tests/test_support_helpers.py @@ -787,7 +787,8 @@ def test_protochain_leaves_no_fake_protocol_module_behind(self) -> None: def test_the_real_protocol_base_still_subscripts_afterwards(self) -> None: """The failure mode itself, rather than the table it came from. - ``pcapkit/protocols/misc/pcap/frame.py:69`` is the line that raised + The :class:`Frame` class statement in + :mod:`pcapkit.protocols.misc.pcap.frame` is what raised ``TypeError: type 'ProtocolBase' is not subscriptable``, so importing it after the polluting test case has run is the most direct statement of what #660 was. diff --git a/tests/test_tier_guard.py b/tests/test_tier_guard.py index 5515cc2827..c0ebd6c2a3 100644 --- a/tests/test_tier_guard.py +++ b/tests/test_tier_guard.py @@ -513,7 +513,7 @@ def tier_of(self, source: 'str', name: 'str' = 'test_probe.py') -> 'str': return _tiers.module_tier(path) def test_every_module_resolves_to_exactly_one_tier(self) -> None: - """The two tiers partition the test modules, and the ``LATEST`` list is the one tier.""" + """The tiers partition the test modules, and the ``LATEST`` list is the one tier.""" modules = _tiers.suite_modules() self.assertEqual(list(modules), sorted(set(modules))) tiers = {} # type: dict[str, list[str]] @@ -831,7 +831,7 @@ def test_skip_idiom_modules_matches_a_grep_based_scan(self) -> None: def test_every_handled_call_names_a_literal_capture(self) -> None: """A computed name inside a handler would be invisible to the scan above. - Pins today's fact that no unit-tier module needs the computed case, so + Pins the fact that no unit-tier module needs the computed case, so that the day one does, this fails loudly instead of that module's fixture-backed coverage silently dropping out of :func:`~tests._tiers.fixture_tier_paths` -- see @@ -1503,7 +1503,7 @@ def test_the_extras_read_back_what_pyproject_declares(self) -> None: """Spot checks on the extras the rest of this suite reasons about.""" declared = _dependency_gates.declared_requirements() - # Two lines since #2040: the second caps PyPy below 3.11. + # Since #2040 a second line caps PyPy below 3.11. self.assertEqual( [requirement.text for requirement in declared['crypto']], ["cryptography>=3.4; platform_python_implementation != 'PyPy' or python_version >= '3.11'", @@ -1879,15 +1879,15 @@ def test_job_sections_agrees_with_the_single_job_slice(self) -> None: self.assertEqual(section, job_section(text, name)) def test_each_job_selection_is_one_of_the_three_recognised_shapes(self) -> None: - """A sixth shape has to fail here rather than be guessed at. + """A new shape has to fail here rather than be guessed at. - Five are recognised: subtract ``--ignore`` flags from the whole suite + These are recognised: subtract ``--ignore`` flags from the whole suite (``test``), ask :func:`~tests._tiers.fixture_tier_paths` (``integration``), pass no selection at all (``gate``), name literal test-file paths (``engine-tests``, one :class:`Job` per ``matrix.engine`` cell, #849), or run what :func:`~tests._tiers.project_pin_paths` prints (``project-tests``, - #1954). A new job selecting some sixth way would otherwise be + #1954). A new job selecting some other way would otherwise be classified ``'whole-suite'`` by the fallback and credited with reaching gates it does not run. diff --git a/tests/test_tier_guard_xdist.py b/tests/test_tier_guard_xdist.py index 75bc61b6a5..c6bb3cb9ee 100644 --- a/tests/test_tier_guard_xdist.py +++ b/tests/test_tier_guard_xdist.py @@ -48,7 +48,7 @@ A fifth (#1977): GraalPy holds the GIL inside a blocking :func:`fcntl.flock`, so :class:`ProbeWriteLockTests` deadlocked its own process and every worker queued -behind it. The lock now polls with ``LOCK_NB``, and :class:`ProbeLockNonBlockingTests` +behind it. There the lock polls with ``LOCK_NB``, and :class:`ProbeLockNonBlockingTests` pins that it never makes a blocking call. Kept separate from :mod:`tests.test_tier_guard`, which another change is already @@ -754,7 +754,7 @@ def _held(self, suffix: 'str', operation: 'int') -> 'bool': return False def test_a_nested_run_does_not_queue_behind_a_waiting_writer(self) -> None: - """Fails on the code before this change: the child times out at the gate.""" + """Fails on the code before #2082: the child times out at the gate.""" order = [] # type: list[str] def writer() -> None: diff --git a/tests/toolkit/test_scapy_unit.py b/tests/toolkit/test_scapy_unit.py index a81cd7410b..ce33377add 100644 --- a/tests/toolkit/test_scapy_unit.py +++ b/tests/toolkit/test_scapy_unit.py @@ -128,8 +128,8 @@ def _make_ether_raw(self): return Ether(bytes(Ether(**self._ether_kwargs()) / Raw(b'raw'))) def _make_ip_rooted_tcp_packet(self): - # No Ether layer, so ``packet.name`` (what #775's tier 1 fix at - # scapy.py:716 feeds ``Enum_LinkType.get()``) is ``'IP'`` -- not a + # No Ether layer, so ``packet.name`` (what #775's tier 1 fix in + # ``tcp_traceflow`` feeds ``Enum_LinkType.get()``) is ``'IP'`` -- not a # LinkType member name, unlike the Ether-rooted packets above whose # name is ``'Ethernet'``. from scapy.layers.inet import IP, TCP diff --git a/tests/utilities/test_compat.py b/tests/utilities/test_compat.py index 1e8c63c343..e151d54746 100644 --- a/tests/utilities/test_compat.py +++ b/tests/utilities/test_compat.py @@ -22,7 +22,7 @@ -- the branch the *real* interpreter takes is ``from enum import StrEnum`` -- so the faked load performs the first ``import aenum`` of the process. Every :mod:`aenum` enumeration built afterwards -- including -``pcapkit/const/reg/apptype.py:26``'s ``TransportProtocol`` -- then took the +``TransportProtocol``, at the time in ``pcapkit/const/reg/apptype.py`` -- took the ``pyver < PY3_6`` path in ``aenum/_enum.py`` and died with ``AttributeError: 'TransportProtocol' object has no attribute '__set_name__'``, so a later ``import pcapkit`` failed outright. @@ -122,7 +122,7 @@ #: running the test until it stopped complaining, and that distinction is the #: point of having it. Every module imported at ``(3, 8)``: :mod:`builtins`, #: :mod:`collections.abc`, :mod:`functools`, :mod:`pathlib` and :mod:`typing`, -#: which no version gate guards any more (#2051), and, behind the gates that +#: which no version gate guards (#2051), and, behind the gates that #: remain, :mod:`urllib.parse`, :mod:`aenum`, :mod:`typing_extensions`, #: :mod:`contextlib`, :mod:`decimal`, :mod:`enum` and :mod:`_thread`. #: :mod:`threading` stays on the list because :meth:`CompatTests.load_compat_as` @@ -199,7 +199,7 @@ def aenum_pyver_readings() -> 'dict[str, tuple[int, ...]]': module of the package takes a **copy** through ``from ._common import *``. The copies can disagree with the original -- reloading ``aenum._common`` repairs it and leaves all of them -- and it is ``aenum._enum``'s copy that - ``aenum/_enum.py:1640`` branches on when it decides whether to call + ``EnumType.__new__`` in ``aenum/_enum.py`` branches on when it decides whether to call :meth:`~object.__set_name__` by hand. Sweeping covers ``_py3``, ``_tuple`` and ``_constant`` too, without this file having to keep a list of which of :mod:`aenum`'s private modules hold one. @@ -462,7 +462,7 @@ def test_faking_the_version_leaves_aenum_reading_the_real_one(self) -> None: The closing lines are the symptom rather than a proxy for it. Building an :class:`aenum.IntFlag` subclass is exactly what - ``pcapkit/const/reg/apptype.py:26`` did for ``TransportProtocol`` when + ``pcapkit/const/reg/apptype.py`` did for ``TransportProtocol`` when #687 was found, and it is the statement that raised ``AttributeError: 'TransportProtocol' object has no attribute '__set_name__'`` for tests of :mod:`tests.project.test_public_api` diff --git a/tests/vendor/test_crawler_reachability_unit.py b/tests/vendor/test_crawler_reachability_unit.py index 9ecfa68b61..f3e6581792 100644 --- a/tests/vendor/test_crawler_reachability_unit.py +++ b/tests/vendor/test_crawler_reachability_unit.py @@ -7,9 +7,9 @@ .. code-block:: python - # pcapkit/vendor/__main__.py:228, the `--target ` path + # pcapkit.vendor.__main__.main, the `--target ` path target_list.extend(getattr(module, name) for name in module.__all__) - # pcapkit/vendor/__main__.py:236, the default path, i.e. a bare `pcapkit-vendor` + # pcapkit.vendor.__main__.main, the default path, i.e. a bare `pcapkit-vendor` target_list.extend(getattr(vendor_module, name) for name in vendor_module.__all__) :attr:`pcapkit.vendor.__all__` listed ``'MH_HandoverACKStatus'`` *twice* and had @@ -173,7 +173,7 @@ def _defined_crawlers(self) -> 'dict[str, Any]': def _reachable_from(self, module: 'Any') -> 'dict[str, Any]': """The crawlers ``pcapkit-vendor`` would collect from ``module``. - The expression at :file:`pcapkit/vendor/__main__.py` lines 79 and 87, + The expression :func:`pcapkit.vendor.__main__.main` uses on both paths, reproduced -- ``getattr(module, name) for name in module.__all__`` -- keyed by defining module and class name so the result is comparable with :meth:`_defined_crawlers` regardless of the alias each is exported under. diff --git a/tests/vendor/test_ipx_socket_unit.py b/tests/vendor/test_ipx_socket_unit.py index 4e27dd739c..7128ab9abf 100644 --- a/tests/vendor/test_ipx_socket_unit.py +++ b/tests/vendor/test_ipx_socket_unit.py @@ -209,9 +209,8 @@ def _vendor(self) -> 'Any': ``Vendor.__init__`` regenerates and *writes* the constant file as a side effect of construction, which a test has no business doing to the - working tree, so the three attributes it sets -- ``NAME``, ``DOCS`` and - ``record``, at :file:`pcapkit/vendor/default.py` lines 338, 340 and 343 - -- are set here instead. + working tree, so the attributes it sets -- ``NAME``, ``DOCS`` and + ``record`` -- are set here instead. """ vendor = self.vendor_module.Socket.__new__(self.vendor_module.Socket) diff --git a/tests/vendor/test_re_sub_positional_flag_unit.py b/tests/vendor/test_re_sub_positional_flag_unit.py index 1866757c1c..aef4cef6b3 100644 --- a/tests/vendor/test_re_sub_positional_flag_unit.py +++ b/tests/vendor/test_re_sub_positional_flag_unit.py @@ -221,8 +221,8 @@ class RuntimeDeprecationWarningTests(unittest.TestCase): PATTERN = r'\r*\n' #: The CPython version that began emitting a ``DeprecationWarning`` when - #: ``count``/``maxsplit`` is passed positionally. The module docstring at - #: line 25 already states "a live DeprecationWarning on Python 3.13+"; + #: ``count``/``maxsplit`` is passed positionally. The module docstring + #: already states "a live DeprecationWarning on Python 3.13+"; #: this constant is what turns that prose into a fact both branches of #: :meth:`test_positional_flag_shape_warns_only_from_the_version_that_added_it` #: are checked against (GitHub issue #819). @@ -382,7 +382,7 @@ def _assert_no_deprecation(self, module_name: 'str', class_name: 'str', instance.process(rows) # type: ignore[attr-defined] def test_default_process_no_deprecation(self) -> None: - # pcapkit/vendor/default.py:376 -- the shared base implementation, + # pcapkit.vendor.default.Vendor.process -- the shared base implementation, # inherited by every crawler that does not override process(), e.g. # pcapkit.vendor.arp.hardware.Hardware. self._assert_no_deprecation( @@ -411,8 +411,8 @@ def test_http_status_code_process_no_deprecation(self) -> None: def test_ipv4_router_alert_process_no_deprecation(self) -> None: # No header row here -- ipv4-router-alert-option-values ships with - # none of its own (see the comment at - # pcapkit/vendor/ipv4/router_alert.py:39-42, GitHub issue #492). + # none of its own (see the comment in + # pcapkit.vendor.ipv4.router_alert.RouterAlert.process, GitHub issue #492). self._assert_no_deprecation( 'pcapkit.vendor.ipv4.router_alert', 'RouterAlert', ['0,TestName,desc [RFC1234]']) diff --git a/tests/vendor/test_vendor_apptype_get_template_agreement_2048_unit.py b/tests/vendor/test_vendor_apptype_get_template_agreement_2048_unit.py index bea487c268..28a3ed9ad0 100644 --- a/tests/vendor/test_vendor_apptype_get_template_agreement_2048_unit.py +++ b/tests/vendor/test_vendor_apptype_get_template_agreement_2048_unit.py @@ -2,12 +2,12 @@ """The AppType generator and its committed base module agree on #2048's rule. GitHub issue #2048. Every in-range port answers with the asking registry's own -transport. That lives in two places: ``get``'s ``unknown`` fallback for a port -``_missing_`` holds no span for, and the span branches the generator renders +transport. That lives in ``get``'s ``unknown`` fallback for a port +``_missing_`` holds no span for, and in the span branches the generator renders into ``_missing_``. Regenerating :mod:`pcapkit.const.reg.apptype.apptype` needs IANA's live CSV, so an edit to the template in :mod:`pcapkit.vendor.reg.apptype.apptype` is made to the committed module by -hand. These render the template offline and check the two agree. +hand. These render the template offline and check it against the committed module. """ from __future__ import annotations @@ -24,7 +24,7 @@ ROOT = pathlib.Path(__file__).resolve().parents[2] #: Every distribution importing :mod:`pcapkit.vendor` needs -- see -#: :mod:`tests.vendor.test_ipx_packet_unit` for why all three are checked. +#: :mod:`tests.vendor.test_ipx_packet_unit` for why each is checked. VENDOR_DEPS = ('requests', 'bs4', 'html5lib') #: Whether the crawlers are importable at all. diff --git a/tests/vendor/test_vendor_dest_path_unit.py b/tests/vendor/test_vendor_dest_path_unit.py index 4e8cb0b7f5..cf9d196469 100644 --- a/tests/vendor/test_vendor_dest_path_unit.py +++ b/tests/vendor/test_vendor_dest_path_unit.py @@ -94,8 +94,8 @@ ``bs4.BeautifulSoup(text, 'html5lib')`` calls at actual crawl time, which nothing here reaches -- no test in this file calls :meth:`Vendor.__init__` or :meth:`~Vendor.context`. ``requests`` and ``beautifulsoup4`` both ship in the -``test`` extra precisely so vendor tests can run (:file:`pyproject.toml`, -around line 321), so both classes below run on ``test`` and ``gate`` -- the +``test`` extra precisely so vendor tests can run (the comment on them in +:file:`pyproject.toml`), so both classes below run on ``test`` and ``gate`` -- the only pytest jobs of :file:`.github/workflows/unit-tests.yml` that collect anything under :file:`tests/vendor/` at all, since ``integration`` and ``pypcap-parity`` never reach it and ``engine-tests`` runs only each engine's diff --git a/tests/vendor/test_vendor_exit_code_unit.py b/tests/vendor/test_vendor_exit_code_unit.py index ef0a15f245..0bc7f56483 100644 --- a/tests/vendor/test_vendor_exit_code_unit.py +++ b/tests/vendor/test_vendor_exit_code_unit.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- """``python -m pcapkit.vendor`` must fail its exit code when a crawler raises. -GitHub issue #872. Before this change, :func:`pcapkit.vendor.__main__.run` +GitHub issue #872. Before the fix, :func:`pcapkit.vendor.__main__.run` swallowed every exception a crawler raised -- filed as a merely-filterable :class:`~pcapkit.utilities.warnings.VendorRuntimeWarning` -- and -:func:`pcapkit.vendor.__main__.main` always ``return 0`` (line 93 pre-fix), with +:func:`pcapkit.vendor.__main__.main` always ended on ``return 0``, with no accounting of whether any target had failed. Because :meth:`pcapkit.vendor.default.Vendor.__init__` runs its network fetch and render *before* the ``open(const_file, 'w')`` on its last line, a failed diff --git a/tests/vendor/test_vendor_missing_body_unit.py b/tests/vendor/test_vendor_missing_body_unit.py index dcc29f87f8..f402767698 100644 --- a/tests/vendor/test_vendor_missing_body_unit.py +++ b/tests/vendor/test_vendor_missing_body_unit.py @@ -21,8 +21,7 @@ The invariant is deliberately not "every emitted line returns": the base crawler itself emits legitimate non-returning lines for a range-guarded body. -:meth:`pcapkit.vendor.default.Vendor.process` (see -:file:`pcapkit/vendor/default.py:424-426`) renders such a body as three +:meth:`pcapkit.vendor.default.Vendor.process` renders such a body as three lines -- an ``if`` header, a ``#:`` comment, then an indented ``return`` -- and only the third of the three returns:: diff --git a/tests/vendor/test_vendor_reg_apptype_generator_unit.py b/tests/vendor/test_vendor_reg_apptype_generator_unit.py index 95e0fc38a0..5b85b105d0 100644 --- a/tests/vendor/test_vendor_reg_apptype_generator_unit.py +++ b/tests/vendor/test_vendor_reg_apptype_generator_unit.py @@ -7,7 +7,8 @@ -- which put one forward-ref string per member into the class's ``__annotations__``. Sphinx's default autodoc calls ``sphinx.util.typing.get_type_hints(parent, ...)`` once per member -(``sphinx/ext/autodoc/_dynamic/_loader.py:367`` and ``:419`` -- the wrapper +(from ``_make_props_from_imported_object`` in +``sphinx/ext/autodoc/_dynamic/_loader.py`` -- the wrapper around :func:`typing.get_type_hints` that catches the ``NameError`` a ``TYPE_CHECKING``-only forward ref would otherwise raise), each call re-resolving the *whole* class, which is what made documenting this one @@ -107,7 +108,7 @@ which #766 carries for the sibling isort check. What the gate is worth has not changed. mypy is a :file:`Pipfile` -``[dev-packages]`` entry (line 54) and is in no :file:`pyproject.toml` extra, +``[dev-packages]`` entry and is in no :file:`pyproject.toml` extra, so no ``pytest`` job in :file:`.github/workflows/unit-tests.yml` -- every one installs ``.[test,...]`` -- ever has it importable, and this test skips on all of them; it runs where mypy is installed, which is a developer checkout and