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
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ name: "Lint"
# have been deleted, not because the code changed. Already superseded the
# same day it was measured, too: a cross-review measured `R0801
# duplicate-code` alone moving 400 -> 573 on `merge(f31e5114f, 83b58ebda)` --
# this branch merged onto the `main` it was rebased against before #769
# this branch merged onto the `main` it was rebased against before #768
# landed there -- taking R to 823 and the total to 6220 on that merge. Still
# true of `main` itself today, since this PR touches no `pcapkit/` file, but
# named for the tree it was actually measured on rather than asserted of
Expand All @@ -62,7 +62,7 @@ name: "Lint"
# actually unchanged between them, despite what an earlier revision of this
# comment claimed: four files moved (`pcapkit/const/reg/apptype/apptype.py`,
# `pcapkit/foundation/extraction.py`, `pcapkit/protocols/schema/schema.py`,
# `pcapkit/vendor/reg/apptype/apptype.py`; tree 7270ad50 -> 2b9ac808), #764's
# `pcapkit/vendor/reg/apptype/apptype.py`; tree 7270ad50 -> 2b9ac808), #758's
# port-validation logic among them. E, W and C read identically either side of
# that diff -- 90/4765/542 both times -- but 1a852698b is the tree actually
# re-measured for this line, so that is what it is pinned to now, rather than
Expand Down
19 changes: 10 additions & 9 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ jobs:
# `python_version < '3.12'` marker lets it install), installing it turned
# 7 of the 10 HAS_PYPCAPFILE-gated methods this comment used to count
# into failures, against a real bug in pcapkit/toolkit/pypcapfile.py's
# handling of pypcapfile 0.12.0's `IP.src`/`IP.dst`. #747 and #748 fixed
# handling of pypcapfile 0.12.0's `IP.src`/`IP.dst`. #743 and #746 fixed
# that bug, and #751 gave the now-safe extra a home: the dedicated
# `engine-tests` and `pypcap-parity` jobs below install it (15
# HAS_PYPCAPFILE-gated methods between them), deliberately apart from
Expand Down Expand Up @@ -169,7 +169,7 @@ jobs:
# PyPCAPFile is NOT added here either, even though this job's selection
# also reaches test_new_engine_parity_runtime.py's 6 HAS_PYPCAPFILE
# methods -- see the `test` job's comment above for the bug that used to
# make installing it here a regression, now fixed by #747/#748. #751's
# make installing it here a regression, now fixed by #743/#746. #751's
# `pypcap-parity` job below covers those 6 methods instead, on the same
# fixture-tier selection as this job but in a venv of its own.
- name: Install package, test and generator dependencies
Expand Down Expand Up @@ -251,7 +251,7 @@ jobs:
# jobs is textually part of the one above it, and that guard's pytest_jobs()
# requires exactly one such literal per job section -- a second one here,
# even in a comment, makes it think this job has two install lines and
# cannot tell which extras the run would have. See #849's cross-review.),
# cannot tell which extras the run would have. See #845's cross-review.),
# so "Engines Python 3.12/3.13/3.14" reported
# green while never exercising PyPCAPFile at all on three of five legs --
# yet all three were promoted to ruleset 23497679's required checks anyway
Expand Down Expand Up @@ -482,7 +482,7 @@ jobs:
# comment here would make that guard think this section holds two
# baseline install lines), and running them unchecked used to mean a
# broken base install on a `not-installable` cell read as "expected"
# while the job had installed and run nothing at all (#849's
# while the job had installed and run nothing at all (#845's
# cross-review). They now run under this step's own explicit `set -eu`
# below -- not "the shell's default", since GitHub's default for a
# Linux `run:` step is plain `bash -e {0}` with no `pipefail`, and
Expand Down Expand Up @@ -546,7 +546,7 @@ jobs:
# bare "5xx or 429" number scan: pip prints a "(NNN kB)" download
# size on essentially every sdist fetch, and a Cython-generated
# .c file runs to thousands of lines, so an unanchored bare-number
# match (#849's cross-review) fires on ordinary download-size
# match (#845's cross-review) fires on ordinary download-size
# lines and on compiler diagnostics quoting a line number in that
# range -- e.g. "Downloading pypcap-1.3.0.tar.gz (500 kB)" and
# "pcap.c:501:24: error: ..." both matched, while the actual
Expand Down Expand Up @@ -596,8 +596,9 @@ jobs:
# those files themselves assert once they see this interpreter's
# version, e.g. PyPCAPFile's own
# test_unsupported_reason_tracks_the_running_interpreter and PyShark's
# test_the_reason_tracks_the_running_interpreter (added in #846) both
# branch on sys.version_info against the engine's own PYTHON_CEILING.
# test_the_reason_tracks_the_running_interpreter (added for PyShark's
# real-capture coverage) both branch on sys.version_info against the
# engine's own PYTHON_CEILING.
# That is what proves the decline actually fired and named the
# interpreter, rather than this job asserting it from the outside.
# Skipped entirely for `not-installable` cells -- see the install step.
Expand Down Expand Up @@ -958,7 +959,7 @@ jobs:
# above, which each cover only the subset their own selection reaches.
# PyPCAPFile is deliberately NOT added here -- see the `test` job's
# comment above for the bug that used to make installing it a
# regression, now fixed by #747/#748. This job runs on 3.14 only, where
# regression, now fixed by #743/#746. This job runs on 3.14 only, where
# PyPCAPFile's marker resolves to nothing regardless, so adding it here
# would be a no-op that misleadingly suggests the extra is exercised by
# `gate`; #751's `engine-tests` and `pypcap-parity` jobs cover it for
Expand Down Expand Up @@ -1129,7 +1130,7 @@ jobs:
# keeps that visibility, but means duplicating this job's system-package
# install, per-engine install logic, and test invocation -- measured at
# 182 raw lines across those three steps, and GitHub Actions has no YAML
# anchors to shrink that with -- into a second job immediately after #849
# anchors to shrink that with -- into a second job immediately after #845
# rebuilt this one, to close a single unverified edge. Flagging the risk
# here instead: if a `required-checks` run ever goes red with only a 3.15
# `engine-tests` leg failing underneath it, that is this exact gap and not
Expand Down
2 changes: 1 addition & 1 deletion pcapkit/const/ftp/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class FEATCode(EnumRegistry, StrEnum):
:meth:`~pcapkit.vendor.ftp.command.Command.process`) -- rather than
minting the per-command ones at import time as an incidental side
effect of building :class:`Command`'s own rows. GitHub issue #860:
that import-time mutation was the same defect shape #861 removed
that import-time mutation was the same defect shape #775 removed
from :class:`~pcapkit.const.pcapng.filter_type.FilterType`, just not
previously noticed here. ``_missing_`` still unmints for a keyword
that turns up on the wire but names none of these -- the
Expand Down
81 changes: 42 additions & 39 deletions pcapkit/const/reg/apptype/apptype.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ class TransportProtocol(EnumLookup, IntEnum):
# ``undefined`` is declared explicitly as ``0`` and every other member
# is ``auto()``, which continues from the preceding explicit value
# rather than needing its own ``_start_ = 0`` to begin there; the
# owner's own ruling on this issue (#860) is explicit that
# a ruling given in review of the work for #860 is explicit that
# ``undefined`` stays a direct ``0`` for that reason: "undefined
# direct uses 0. then other real transport use auto. so we don't have
# to define a _start_ and the undefined declaration is explicit."
# GitHub issue #808 already dropped the ``IntFlag`` base once
# nothing built a composite, and GitHub PR #836's ruling later
# GitHub issue #808 already dropped the ``IntFlag`` base once nothing
# built a composite, and a ruling given in review of that work later
# retired ``|``-composite decoding entirely: "since it's no longer a
# Flag, `|` joined values are no longer parsed and accepted, we will
# treat it as a whole, instead of splitting." With no decoding left to
Expand All @@ -61,7 +61,7 @@ class TransportProtocol(EnumLookup, IntEnum):
# bare -- into anything narrower than the whole value it already is, on
# either numbering; a plain ``dict.get`` lookup cannot tell a composed
# ``int`` from any other one that happens to equal it. Treating every
# int as a whole is exactly what #836's ruling above asks for, and it
# int as a whole is exactly what that ruling above asks for, and it
# is also why this renumbering changes what specific ints mean, not
# only what composed ones do:
# ``tcp | udp`` (``3``) used to name no registry and now resolves as
Expand Down Expand Up @@ -108,22 +108,23 @@ def get(cls, key: 'int | str', default: 'Any' = NO_DEFAULT) -> 'TransportProtoco
on these circumstances."* A stdlib ``E['nosuch']`` raises
:exc:`KeyError`, and #923's census of the 127 concrete
:class:`~pcapkit.corekit.enum.EnumLookup` subclasses -- taken before
#921 re-parented this class, so this class is not among them -- found
119 already answering a name miss that way against 5 answering with
:exc:`ValueError`. Those 5 are :class:`AppType` and its four transport
registries, and they land there only because their own ``get()`` takes
an :class:`int` port and never accepts a name at all, rather than from
any name-miss policy. So there was no policy here to preserve, and a
name miss now reaches the caller as
the phase-2 re-parenting moved this class, so it is not among them --
found 119 already answering a name miss that way against 5 answering
with :exc:`ValueError`. Those 5 are :class:`AppType` and its four
transport registries, and they land there only because their own
``get()`` takes an :class:`int` port and never accepts a name at all,
rather than from any name-miss policy. So there was no policy here
to preserve, and a name miss now reaches the caller as
:exc:`~pcapkit.utilities.exceptions.EnumKeyError` from the base.
Maintainer ruling on GitHub PR #836 -- "Do not allow extension of
TransportProtocol at all" -- is untouched by that: the refusal is still
a refusal and still mints nothing, only its exception class moved.
Maintainer ruling given in review of the work for #808 -- "Do not
allow extension of TransportProtocol at all" -- is untouched by
that: the refusal is still a refusal and still mints nothing, only
its exception class moved.

The base is a :class:`classmethod`
(:meth:`~pcapkit.corekit.enum.EnumLookup.get`), so this override
moves from :class:`staticmethod` to :class:`classmethod` to
delegate at all -- the same move GitHub issue #908 and #915 made for
delegate at all -- the same move GitHub issue #908 made for
:meth:`~pcapkit.const.http.method.Method.get`. Grepped every call
site in this tree for GitHub issue #877: all call this method by
name, none take it as a bare callable or introspect ``__func__``,
Expand Down Expand Up @@ -163,19 +164,20 @@ def get(cls, key: 'int | str', default: 'Any' = NO_DEFAULT) -> 'TransportProtoco
"""
if isinstance(key, str):
return super().get(key.lower(), default)
# NOTE: maintainer ruling on this PR (#836): "Do not allow extension
# of TransportProtocol at all." A name that is not a declared member
# used to mint a brand-new one here, at ``max_val + 1`` (before that,
# ``max_val * 2``) -- an unbounded, ever-growing set of transport
# protocols nothing ever asked for. There is nothing left to walk
# now: it is simply refused, exactly like any other unrecognised
# name -- including one spelling a composite, e.g. ``'tcp|udp'``.
# NOTE: maintainer ruling given in review of the work for #808: "Do
# not allow extension of TransportProtocol at all." A name that is
# not a declared member used to mint a brand-new one here, at
# ``max_val + 1`` (before that, ``max_val * 2``) -- an unbounded,
# ever-growing set of transport protocols nothing ever asked for.
# There is nothing left to walk now: it is simply refused, exactly
# like any other unrecognised name -- including one spelling a
# composite, e.g. ``'tcp|udp'``.
# ``'|'`` used to be intercepted here on its own, so a composite in
# disguise never got minted into a member whose own name lied about
# being a single transport; the owner's further ruling on this PR
# retired that special case along with the rest of the composite
# handling once TransportProtocol stopped being a Flag at all:
# "since it's no longer a Flag, `|` joined values are no longer
# being a single transport; a further ruling given in review of the
# work for #808 retired that special case along with the rest of the
# composite handling once TransportProtocol stopped being a Flag at
# all: "since it's no longer a Flag, `|` joined values are no longer
# parsed and accepted, we will treat it as a whole, instead of
# splitting." A ``'|'``-joined name is therefore not special any
# more -- it is simply not the name of a declared member, and gets
Expand Down Expand Up @@ -2524,10 +2526,10 @@ def _dispatch(cls, key: 'int', proto: 'TransportProtocol | str | int') -> 'Type[
the same as any caller passing a literal port-transport bitmask
-- falls through to ``int.__or__`` and returns a bare
:class:`int` rather than a member. Never split back into the
transports its bits would each name -- owner ruling on this PR
(#836) -- so it is looked up as the one whole value it
already is, exactly like any other bare int: refused when
that whole value names no registry, resolved when it
transports its bits would each name -- a ruling given in review
of the work for #808 -- so it is looked up as the one whole
value it already is, exactly like any other bare int: refused
when that whole value names no registry, resolved when it
happens to equal one instead. Since GitHub issue #860 moved
this class off power-of-two spacing, a hand-built composite
is no longer guaranteed to be the former -- see
Expand Down Expand Up @@ -2575,11 +2577,12 @@ def _dispatch(cls, key: 'int', proto: 'TransportProtocol | str | int') -> 'Type[
# either numbering. A genuine member reaching this point is
# ``undefined`` -- the four real transports would already have
# resolved above, and :meth:`TransportProtocol.get` cannot mint
# anything else, per this PR's own maintainer ruling against
# extending TransportProtocol at all -- and a bare :class:`int`
# reaches here whenever it matches no real member's value, e.g. a
# stray bit like ``17``. A composite built by hand used to reach
# here just as reliably, since no combination of the old power-of-
# anything else, per the maintainer ruling given in review of the
# work for #808, against extending TransportProtocol at all -- and
# a bare :class:`int` reaches here whenever it matches no real
# member's value, e.g. a stray bit like ``17``. A composite built by
# hand used to reach here just as reliably, since no combination of
# the old power-of-
# two bits ever equalled a single real member's value; that is no
# longer true under this class's current sequential numbering --
# ``TransportProtocol.tcp | TransportProtocol.udp`` (``3``) is
Expand All @@ -2590,10 +2593,10 @@ def _dispatch(cls, key: 'int', proto: 'TransportProtocol | str | int') -> 'Type[
# and naming every transport whose bit was set -- the fix for
# GitHub issue #759, where resolving a composite by picking its
# lowest set bit dispatched every one containing ``tcp`` into the
# TCP registry regardless of what else it named. The owner's
# further ruling on this PR (#836) retired that decoding along with
# the rest of the composite handling: "since it's no longer a Flag,
# `|` joined values are no longer parsed and accepted, we will
# TCP registry regardless of what else it named. A further ruling
# given in review of the work for #808 retired that decoding along
# with the rest of the composite handling: "since it's no longer a
# Flag, `|` joined values are no longer parsed and accepted, we will
# treat it as a whole, instead of splitting." So a composite's bits
# are never decoded looking for a partial answer any more, on
# either numbering -- it is looked up as the one whole value it
Expand Down
18 changes: 10 additions & 8 deletions pcapkit/corekit/enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@
the base above was deliberately behaviour-preserving on its own, so that it
could land while other work was still in flight on the files the re-parent
touches, and the phase itself landed in two pull requests for exactly that
reason -- #921 for the 17 enumerations that were free to move at once, and
`#930 <https://github.com/JarryShaw/PyPCAPKit/issues/930>`__ for the
reason -- the first for the 17 enumerations that were free to move at
once, and the second, `#930
<https://github.com/JarryShaw/PyPCAPKit/issues/930>`__, for the
remaining seven once the files holding them freed up.

The registry tier's own shape is the earlier ruling on GitHub issue #842,
Expand Down Expand Up @@ -340,12 +341,13 @@ def get(cls, key: 'Any', default: 'Any' = NO_DEFAULT) -> 'Self':
on the same terms; the ``str`` path does not call the hook, for the reason
given on :meth:`_validate_value` itself.

Both failure paths raise from :mod:`pcapkit.utilities.exceptions` rather
than a builtin, per the owner's ruling on GitHub issue #923: *"Either
``ValueError`` or ``KeyError``, that's depending on how stdlib's
``Enum`` would raise on these circumstances. And we should raise one
from ``pcapkit.utilities.exceptions`` rather builtin exceptions."* The
*shape* is unchanged by that ruling and deliberately so -- a name miss
Both failure paths raise from :mod:`pcapkit.utilities.exceptions`
rather than a builtin, per a ruling recorded on GitHub issue #923,
verbatim: *"Either ``ValueError`` or ``KeyError``, that's depending on
how stdlib's ``Enum`` would raise on these circumstances. And we
should raise one from ``pcapkit.utilities.exceptions`` rather builtin
exceptions."* The *shape* is unchanged by that ruling and
deliberately so -- a name miss
stays :exc:`KeyError`-derived and a value miss :exc:`ValueError`-derived,
matching ``E['nosuch']`` and ``E(999)`` on a stdlib
:class:`~enum.Enum`, and matching the 119 of this tree's 127 concrete
Expand Down
Loading
Loading