Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
# earns a warning. The typehint rendering comes from the third-party
# ``sphinx_autodoc_typehints`` below.
'sphinx.ext.autodoc',
'sphinx.ext.extlinks',
'sphinx.ext.napoleon',
'sphinx.ext.todo',

Expand All @@ -81,6 +82,38 @@
'sphinxcontrib.mermaid',
]

# 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.
#
# 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:
# ``#\d{3}`` will miss four-digit numbers once the tracker reaches them -- there are
# none yet -- and already misses 17 two-digit ones, while ``#\d+`` catches the 45
# one-digit RFC diagram labels across ``pcapkit/protocols/internet/hip.py`` (36),
# ``pcapkit/protocols/transport/sctp.py`` (7) and
# ``pcapkit/protocols/schema/internet/hip.py`` (2) -- ``DH GROUP ID #1``,
# ``Gap Ack Block #1`` and the like -- which are not references to anything. A role
# nobody writes cannot corrupt them.
#
# The caption is ``#%s`` for both ``:issue:`` and ``:pr:`` so that converting a bare
# citation or an explicit link changes the markup and not the rendered text. A
# citation written as an inline literal is the one exception: it rendered as monospace
# and now renders as a link in body font. The two roles exist separately because the
# issue-versus-pull-request distinction is itself a documented convention (see
# ``contributing/conventions/documentation.rst``), and a single role would flatten it
# in the source even though GitHub redirects between ``/issues/NNN`` and ``/pull/NNN``
# either way.
#
# ``:discussion:`` is needed because a handful of cited numbers are GitHub
# Discussions rather than issues -- the issues API returns 404 for them, so
# ``:issue:`` would link to a page that does not exist.
extlinks = {
'issue': ('https://github.com/JarryShaw/PyPCAPKit/issues/%s', '#%s'),
'pr': ('https://github.com/JarryShaw/PyPCAPKit/pull/%s', '#%s'),
'discussion': ('https://github.com/JarryShaw/PyPCAPKit/discussions/%s', '#%s'),
}

intersphinx_mapping = {
'python': ('https://docs.python.org/3', None),
'dictdumper': ('https://dictdumper.jarryshaw.me/en/latest/', None),
Expand Down
42 changes: 21 additions & 21 deletions docs/source/contributing/conventions/documentation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ reStructuredText under :file:`docs/source/` and the :mod:`pcapkit` docstrings th
reference renders from, since the owner named both when settling the first of these.

Nearly all of it was settled on
`#719 <https://github.com/JarryShaw/PyPCAPKit/issues/719>`__, the prose sweep, whose
:issue:`719`, the prose sweep, whose
thread was the only place most of it lived. As on :ref:`process`, every ruling here is
**paraphrased rather than quoted**, on the owner's standing instruction there; the
issue named beside a rule is where the original wording is.
Expand All @@ -20,12 +20,12 @@ Heading Case and Shape

**Title Case, and short.** Sentence case belongs only to a heading that genuinely is a
sentence -- a how-to question is the example the owner gave -- and that was ruled rare:
a sentence should generally not be used as a title at all. Settled on #719.
a sentence should generally not be used as a title at all. Settled on :issue:`719`.

Title Case here is the conventional kind rather than every-word capitalisation. The
short function words ``a``, ``an``, ``the``, ``and``, ``or``, ``of``, ``in``, ``for``
and ``to`` stay lowercase unless they lead, which was the reading put to the owner on
#719 and left standing. It is also what the tree does: *The* ``all`` *Extra* and
:issue:`719` and left standing. It is also what the tree does: *The* ``all`` *Extra* and
*Issue and Pull Request Labels* on :ref:`process` are both in it.

**The casing is the easy half.** A heading can be in Title Case already and still
Expand Down Expand Up @@ -80,7 +80,7 @@ the page for a string no longer on it.
Nothing in CI catches a reference a rename left behind. :file:`docs/source/conf.py`
sets no ``nitpicky`` and :file:`docs/Makefile` leaves ``SPHINXOPTS`` empty, so the
build runs with neither ``-n`` nor ``-W``: a dead reference renders as the plain text
it used to be, and the build still succeeds. ``#934`` found sixteen of them at once
it used to be, and the build still succeeds. :issue:`934` found sixteen of them at once
that way.

One thing a rename breaks that no tool checks at all is the prose around it. Turning a
Expand All @@ -92,17 +92,17 @@ Mermaid for Flows

Where the subject is a flow, prefer a Mermaid graph to the paragraph or the ASCII
diagram that would otherwise carry it -- a graph is read faster than its own
description. The owner ruled this on #719, asking for it where it is necessary and
description. The owner ruled this on :issue:`719`, asking for it where it is necessary and
helpful, which bounds it in three directions:

* **A short sequence does not earn a graph.** Two steps read perfectly well as a
sentence, and a diagram of them costs a reader a context switch for nothing.
* **A rationale stays prose.** A diagram carries structure and sequence; it cannot
carry *why* a choice was made, and that reasoning is what #719 protects rather than
compresses.
carry *why* a choice was made, and that reasoning is what :issue:`719` protects rather
than compresses.
* **Do not redraw a graph another page already has.** The owner's condition when
approving the navigation work on #719 was that nothing duplicate information already
shown, and a second copy of a flow is exactly that.
approving the navigation work on :issue:`719` was that nothing duplicate information
already shown, and a second copy of a flow is exactly that.

The style model is the set already in the tree, every one of which builds. The sweep
excludes this page, which writes the directive name three times in its own prose and
Expand Down Expand Up @@ -163,7 +163,7 @@ count itself:

Those root toctrees are ``:hidden:`` because, without it, each of the three captions
rendered twice on the root page -- once inline in the body, once in the sidebar -- which
is the duplication the owner ruled out on #719.
is the duplication the owner ruled out on :issue:`719`.

.. note::

Expand All @@ -182,8 +182,8 @@ Paraphrasing a Ruling
~~~~~~~~~~~~~~~~~~~~~

Write a ruling down in your own words. **Do not quote the owner verbatim** -- a
standing instruction on #719, and the one every page in this directory follows.
``#949`` went back over the five pages that then existed and replaced their quoted
standing instruction on :issue:`719`, and the one every page in this directory follows.
:issue:`949` went back over the five pages that then existed and replaced their quoted
rulings with paraphrase.

What a quotation costs is not style. A quoted sentence is pinned to the moment it was
Expand All @@ -198,7 +198,7 @@ describes what was true on the day it merged, and the next change past it can ma
citation wrong without touching it. The issue is the durable half -- where the ruling
was asked for and given -- and it survives the work that implemented it. So cite the
issue a rule was settled on, and describe a change by what it did rather than by its
number. Ruled on #719.
number. Ruled on :issue:`719`.

**The changelog and** :file:`tests/` **are both exempt, for related reasons.** A
changelog entry exists so a reader can find the change, and the pull-request number *is*
Expand All @@ -207,7 +207,7 @@ that pointer; converting it would delete the thing the entry is for --
A substantial share of the pull requests cited under :file:`tests/` close no issue at
all -- one credits a proposal to an external contributor and closes nothing -- and where
an issue does exist beside a citation, it frequently lacks the fact being cited, which
lives in the pull request's own body or review thread instead. Ruled on #719.
lives in the pull request's own body or review thread instead. Ruled on :issue:`719`.

The rule reaches the rest of this directory as well: a sibling page that cites a pull
request is unconverted, not a third exemption. The changelog and :file:`tests/` are the
Expand All @@ -217,8 +217,8 @@ Accuracy
~~~~~~~~

**Verify a claim against the code it describes, never against another document.** Where
prose and code disagree the code wins and the prose is what gets fixed -- #719's own
charter -- and a docstring outliving the thing it described is a demonstrated failure
prose and code disagree the code wins and the prose is what gets fixed -- :issue:`719`'s
own charter -- and a docstring outliving the thing it described is a demonstrated failure
mode here rather than a hypothetical one.

**Re-derive a count; do not copy one.** Better still, write down the command that
Expand All @@ -230,14 +230,14 @@ merge base, and re-measures the intersection. A tense-keyword grep misses a clai
phrased as a fraction of a total.

**Treat** ``every``, ``all``, ``each`` **and** ``none`` **as a claim about members, and
check the members one at a time.** Several of #719's findings were of exactly that
check the members one at a time.** Several of :issue:`719`'s findings were of exactly that
shape:

* A sweep asserted that every ``.. module::`` target in the documentation resolved.
One did not: :file:`docs/source/pcapkit/protocols/link/rarp.rst` declared
``pcapkit.protocols.data.link.rarp``, which has never existed, because RARP and
DRARP reuse ARP's data class. Fixed in ``68fbccd90``.
* ``#911``'s ruling -- export the sentinel objects and leave their types out -- was
* :issue:`911`'s ruling -- export the sentinel objects and leave their types out -- was
read as describing all three modules that then held a sentinel. One ran the other
way: :mod:`pcapkit.corekit.fields.field` exported neither, so applying the rule
there meant *adding* a name rather than removing one.
Expand All @@ -261,7 +261,7 @@ Resolvable Targets
**A** ``.. module::`` **target must name a file on disk.** A dangling one is worse than
no directive at all: it registers a module-index entry for a module that does not
exist, and gives cross-references a target that resolves to nothing. The sweep that
settled this on #719 found exactly one, and repeating it is cheap:
settled this on :issue:`719` found exactly one, and repeating it is cheap:

.. code-block:: shell

Expand All @@ -285,13 +285,13 @@ omits all of them.
When something is removed, its documentation entry goes with it -- carrying a
deprecation note where a user could have depended on the thing, and deleted outright
where it never shipped. The ``rarp`` entry above needed no note for that second reason.
Asked and ruled on #719.
Asked and ruled on :issue:`719`.

Format and Mechanics
~~~~~~~~~~~~~~~~~~~~

* **reStructuredText under** :file:`docs/source/`, **Markdown outside it.** The owner
ruled this on #719, correcting a blanket *always* ``.rst`` that had been in
ruled this on :issue:`719`, correcting a blanket *always* ``.rst`` that had been in
circulation until then: the Sphinx documentation is reST, and the other documents --
the READMEs included -- are Markdown where that applies. ``CONTRIBUTING.md``'s own
*Documentation* section records the same split. One trap arrived with the ruling:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Every IPv6 extension header in this package subclasses
:class:`~pcapkit.protocols.internet.ipv6_ext.IPv6_Ext`. Some name a **second** base
as well, and which ones do is a ruling rather than an accident. The owner ruled, in
review of the rename that made ``IPv6_Ext`` the shared base
(`#917 <https://github.com/JarryShaw/PyPCAPKit/issues/917>`__), that a header usable
(:issue:`917`), that a header usable
*only* as an extension header inherits ``IPv6_Ext`` and nothing else -- ``IPv6_Frag``
being the example -- while one that is usable as a standalone protocol in its own
right inherits both ``IPv6_Ext`` and ``Internet`` (or ``IPsec``), as ``ESP`` does.
Expand Down Expand Up @@ -106,7 +106,7 @@ class for it, so nothing implements the classification, but a future one inherit
Own-protocolhood on its own is **not** sufficient, and MH is the case that
settles it: the alternative reading -- that a protocol in its own right qualifies
whether or not it can appear under IPv4 -- was put to the owner explicitly in
review of `#917 <https://github.com/JarryShaw/PyPCAPKit/issues/917>`__ and not
review of :issue:`917` and not
taken, so MH and ``Shim6`` stay extension-only. A header that is a protocol in its
own right but structurally cannot be an IPv4 payload names ``IPv6_Ext`` alone.

Expand All @@ -133,8 +133,8 @@ The Retired ``IPv6_GenericExt`` Name
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The class arrived as ``IPv6_GenericExt``, a fallback parser for an unrecognised
extension header (`#891 <https://github.com/JarryShaw/PyPCAPKit/issues/891>`__), and
`#917 <https://github.com/JarryShaw/PyPCAPKit/issues/917>`__ merged that role with
extension header (:issue:`891`), and
:issue:`917` merged that role with
the shared-base role into one class under the shorter name. No compatibility alias
was left behind, and that was deliberate. The owner ruled that the
``IPv6_GenericExt`` name goes for good: it was an intermediate state, and it was never
Expand All @@ -160,7 +160,7 @@ Payload (ESP) is not considered an extension header"* -- but that sentence opens
*"For this purpose,"*, scoping it to the fragmentation discussion it sits in, and the
sentence after it lists ESP among *"examples of upper-layer headers"*. The library
follows the registry, on the owner's ruling for
`#895 <https://github.com/JarryShaw/PyPCAPKit/issues/895>`__, which is why ESP
:issue:`895`, which is why ESP
carries the same extension-mode contract as its siblings.

**And it terminates the chain walk.** :rfc:`4303` places ESP's Next Header byte
Expand Down
2 changes: 1 addition & 1 deletion docs/source/contributing/conventions/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ House Conventions
the page that covers it in the same change that implements it, rather than
left in the issue for the next contributor to find. That is the owner's
standing ask on
`#918 <https://github.com/JarryShaw/PyPCAPKit/issues/918>`__.
:issue:`918`.

.. toctree::
:maxdepth: 1
Expand Down
8 changes: 4 additions & 4 deletions docs/source/contributing/conventions/mint-criterion.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ the label as the final, concrete assigned name, or only as a notation for a huma
reading the table?

Settled in review of the ``Socket._missing_`` branch-order fix
(`#841 <https://github.com/JarryShaw/PyPCAPKit/issues/841>`__) and reaffirmed
on `#775 <https://github.com/JarryShaw/PyPCAPKit/issues/775>`__ as a core concept of
(:issue:`841`) and reaffirmed
on :issue:`775` as a core concept of
the ruling.

So the question to ask of a range is **what the upstream registry actually did**, not
Expand Down Expand Up @@ -98,9 +98,9 @@ Suffixed Company Names
~~~~~~~~~~~~~~~~~~~~~~

The ethertype case looks like an exception to the rule and is not. The maintainer's
reasoning, settled on `#775 <https://github.com/JarryShaw/PyPCAPKit/issues/775>`__ after
reasoning, settled on :issue:`775` after
being raised in review of the same ``Socket._missing_`` fix
(`#841 <https://github.com/JarryShaw/PyPCAPKit/issues/841>`__): a proprietary protocol
(:issue:`841`): a proprietary protocol
will never have a public name, so the company name is what serves that purpose in its
place.

Expand Down
Loading
Loading