diff --git a/docs/source/conf.py b/docs/source/conf.py index 9d43243b69..fba4a980d4 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -115,8 +115,9 @@ ] # Opt-in roles for the tracker references that the prose cites constantly. A bare -# ``#NNN`` renders as literal text -- nothing in Sphinx resolves it -- so every -# citation in a docstring or an ``.rst`` page is unclickable in the built docs. +# ``#NNN`` renders as literal text -- nothing in Sphinx resolves it -- so a +# citation written that way in a docstring or an ``.rst`` page is unclickable in +# the built docs. # # These are deliberately opt-in per site rather than an automatic ``#NNN`` rule, # because no digit-keyed pattern can tell a citation from a packet-diagram label: @@ -472,13 +473,14 @@ def bind_type_checking_names(app: 'Sphinx', env: 'BuildEnvironment', # pylint: here. Autodoc reads a class attribute's type with :func:`typing.get_type_hints`, and a single unresolvable name makes that raise :exc:`NameError` for the *whole class*; Sphinx then falls back to the raw - ``__annotations__`` strings. So ``pre: 'ToSPrecedence'`` was rendered as the - bare word ``ToSPrecedence``, which the Python domain has to resolve by - suffix-matching -- and both :class:`pcapkit.const.ipv4.tos_pre.ToSPrecedence` - and its generator :class:`pcapkit.vendor.ipv4.tos_pre.ToSPrecedence` end in - it. That is where the bulk of the ``more than one target found`` warnings came - from, and roughly half of the links Sphinx picked went to the vendor crawler - rather than to the enumeration the attribute actually holds. + ``__annotations__`` strings. So, without the binding, ``pre: 'ToSPrecedence'`` + renders as the bare word ``ToSPrecedence``, which the Python domain has to + resolve by suffix-matching -- and both + :class:`pcapkit.const.ipv4.tos_pre.ToSPrecedence` and its generator + :class:`pcapkit.vendor.ipv4.tos_pre.ToSPrecedence` end in it. That is the bulk + of the ``more than one target found`` warnings, and roughly half of the links + Sphinx picks then go to the vendor crawler rather than to the enumeration the + attribute actually holds. Binding the guarded names into each module up front lets :func:`typing.get_type_hints` succeed, so the annotation is stringified from @@ -676,11 +678,12 @@ def save_enum_member_docstring(app: 'Sphinx', what: str, name: str, # pylint: d Napoleon takes the first line of every attribute docstring as Google's inline ``type: description`` form and splits it at the first colon. A registry member's docstring is the registry's own text, so the colon is - usually a URL's: ``H.323 [http://standard.pictel.com/...]`` rendered as - *Type:* ``H.323 [http`` above the description ``//standard.pictel.com/...``, - and every member whose first docstring line holds a colon split the same - way. The bogus type was also parsed as a cross-reference, which is where the - ``http`` and ``Echo`` ``more than one target found`` warnings came from. + usually a URL's: left to napoleon, ``H.323 [http://standard.pictel.com/...]`` + renders as *Type:* ``H.323 [http`` above the description + ``//standard.pictel.com/...``, and every member whose first docstring line + holds a colon splits the same way. The bogus type is also parsed as a + cross-reference, which is where the ``http`` and ``Echo`` ``more than one + target found`` warnings come from. Args: app: Sphinx application. diff --git a/docs/source/contributing/conventions/protocol-layer-placement.rst b/docs/source/contributing/conventions/protocol-layer-placement.rst index d05261c44b..af955e2ba6 100644 --- a/docs/source/contributing/conventions/protocol-layer-placement.rst +++ b/docs/source/contributing/conventions/protocol-layer-placement.rst @@ -137,9 +137,12 @@ the MRO, so whichever base owns it *earliest* wins: (True, False) :class:`~pcapkit.protocols.misc.raw.Raw` does **not** own ``__layer__`` -- it inherits -:obj:`None` from :class:`~pcapkit.protocols.protocol.ProtocolBase` -- so -:class:`~pcapkit.protocols.application.ftp.FTP_DATA` would report ``'Application'`` in -either base order. :class:`~pcapkit.protocols.link.arp.ARP`'s chain reaches +:obj:`None` from :class:`~pcapkit.protocols.protocol.ProtocolBase` -- so a class +naming both :class:`~pcapkit.protocols.application.application.Application` and +:class:`~pcapkit.protocols.misc.raw.Raw` reports ``'Application'`` in either base order. +:class:`~pcapkit.protocols.application.ftp.FTP_DATA` names +:class:`~pcapkit.protocols.misc.raw.Raw` alone, so its ``__layer__`` is :obj:`None`. +:class:`~pcapkit.protocols.link.arp.ARP`'s chain reaches :class:`~pcapkit.protocols.link.link.Link`, which **does** own it, so ``class RARP(ARP, Application)`` would report ``'Link'`` and be wrong. diff --git a/docs/source/contributing/conventions/registry-protocol.rst b/docs/source/contributing/conventions/registry-protocol.rst index 0197970f88..17a66d448d 100644 --- a/docs/source/contributing/conventions/registry-protocol.rst +++ b/docs/source/contributing/conventions/registry-protocol.rst @@ -446,12 +446,11 @@ That leaves the classes with something to decide: RFC 5797 §2 above is. Note also that the §2 sentence is wrapped across a line break in the RFC's text file, at ``case-`` / ``insensitive``, so a line-oriented grep for the phrase finds nothing. - - **case-insensitive** -- was a defect; ``get`` folds + - **case-insensitive** -- ``get`` folds (:issue:`903`) * - :class:`~pcapkit.const.http.method.Method` - :rfc:`9110#section-9.1` - *"The method token is case-sensitive."* Explicitly the opposite of limb 1. - - **case-sensitive** -- was a defect, fixed by - :issue:`896` + - **case-sensitive** -- ``get`` does not fold (:issue:`896`) * - :class:`~pcapkit.const.pcapng.option_type.OptionType` - ``draft-tuexen-opsawg-pcapng`` - Nothing states a rule; the draft never discusses option-name case. diff --git a/docs/source/contributing/conventions/test-coverage.rst b/docs/source/contributing/conventions/test-coverage.rst index 1d3388e676..00951743a5 100644 --- a/docs/source/contributing/conventions/test-coverage.rst +++ b/docs/source/contributing/conventions/test-coverage.rst @@ -55,9 +55,9 @@ The rules those tables carry: entry records the status, a failure-detail fragment narrow enough to match one site, and the defect: the function, class or method that causes it, by name, and the issue that tracks it. - Routing a case around a defect hides it: the generator's ``HIP_COPIES`` once put two - parameters in every HIP packet, so the unrepresentable length of a lone one - (:issue:`651`) was never constructed. + Routing a case around a defect hides it: a generator that puts two parameters in + every HIP packet never constructs the unrepresentable length of a lone one + (:issue:`651`), which is why the generator's ``HIP_COPIES`` is one. ``KNOWN_DEGRADED`` entries have a different shape -- the fragments of the probe's ``'error'`` value the entry accepts, any one of which may match, and a reason -- and they record why the probe's placeholder payload cannot reach the target, not a diff --git a/docs/source/contributing/workflows.rst b/docs/source/contributing/workflows.rst index c46ccb2bad..520654e75b 100644 --- a/docs/source/contributing/workflows.rst +++ b/docs/source/contributing/workflows.rst @@ -804,7 +804,7 @@ permission to the reusable workflow. ``!cancelled()``, so the cells still run when ``test`` fails, and a red cell still fails the push run that GitHub Pages, Conda Update and Vendor Update (and so Create Release) wait on. The cost is wall time: the push run, and those workflows, finish - about one slowest cell later, about 6 min before any queue wait (estimate). + about one slowest cell later, plus any queue wait. * ``engine-tests`` has no ``DPKT`` cell. Its only path would be :file:`tests/toolkit/test_dpkt_unit.py`, which ``test`` runs with ``DPKT`` installed on every leg. What that gives up is the file in a venv holding only ``test`` and @@ -854,7 +854,8 @@ Anything else, and a diff the script cannot list, is code: ``code: true`` and - skipped - skipped * - ``unit-tests.yml``: ``project-tests`` - - the project pins' plain-unittest run and the docs readers + - :file:`tests/project` and the root-level modules under plain unittest, a half + per step, and the docs readers - the project pins * - ``experimental.yml``: ``experimental``, ``windows`` - skipped @@ -1407,7 +1408,9 @@ that import ``pcapkit`` are no pins either; those the tiers send to ``latest`` r on ``test``'s ``latest`` leg, under coverage. ``project-tests`` runs the pins under pytest, with ``test``'s flags, on ``latest``, -on every pull request and every push to ``main``, and ``required-checks`` needs it. +on every push to ``main`` and every pull request but a docs-only one, which runs +:file:`tests/project` under plain unittest instead (see `Light Pull Requests +(#2243)`_), and ``required-checks`` needs it. Every ``test``, ``test-ktlo`` and ``experimental`` leg passes each pin as an ``--ignore``, ``latest``'s coverage leg included, which measures only ``pcapkit``. ``latest`` asks ``project_pin_paths()`` at run time, and every other leg @@ -1602,8 +1605,8 @@ before theirs, and :file:`util/release_upload.py` on the leg's, after it. setup-python. :file:`util/release_conda.py` runs ``leg`` on the image's ``python3``, before setup-python, ``build`` on conda's base ``python`` under the login shell, from :file:`conda/pypcapkit`, and ``upload`` on setup-python's. A project -pin runs each on the cases the shell it replaced handled and requires the same -status, output and calls. +pin runs each, and the step's inline shell form it must match, on the same cases +and requires the same status, output and calls. :file:`util/_actions.py` is standard library only, and keeps to 3.8's syntax, since the scripts on ``/usr/bin/python3`` and on every leg's interpreter import it. Their project tests parse these scripts and the helper with ``ast.parse(..., @@ -1638,8 +1641,8 @@ script not listed here is CI-only. - ``python util/changelog_md.py`` after editing the newest changelog entry, to regenerate :file:`CHANGELOG.md`. * - :file:`util/run_unittest_leg.py` - - ``unit-tests.yml``'s ``unittest-ordering``, once per leg, and - ``project-tests``. + - ``unit-tests.yml``'s ``unittest-ordering``, once per cell, and + ``project-tests``, once per half of :file:`tests/project`. - ``python util/run_unittest_leg.py `` over the :file:`tests/` directory a change touches, when it moves imports or module state (see :doc:`conventions/test-coverage`). @@ -1844,10 +1847,10 @@ and cannot be the source of a data flow. by CodeQL's `sensitive-data heuristics `__. The tests that build a pcapng Decryption Secrets Block call its bytes -``secrets``. Through :func:`~pcapkit.interface.core.extract` those bytes reached +``secrets``. Through :func:`~pcapkit.interface.core.extract` those bytes reach ``logger`` calls in :mod:`pcapkit.foundation.extraction` and the buffer file's -write in :mod:`pcapkit.corekit.io`, and each alert's dismissal was lost whenever -a pull request moved the line it named. The alert on the ``logger`` call in +write in :mod:`pcapkit.corekit.io`, and with :file:`tests` analysed, a dismissal of +each such alert is lost whenever a pull request moves the line it names. The alert on the ``logger`` call in :mod:`pcapkit.utilities.warnings` begins in :mod:`pcapkit` itself, at the block's ``secrets_length`` field, the spec's name for it, so it is still raised and still dismissed by hand. :file:`tests/project/test_codeql_config_2130.py` pins the