From 891f85fa49014f80204f417f201e1d5b14b6673c Mon Sep 17 00:00:00 2001 From: Jarry Shaw Date: Wed, 28 Oct 2026 14:07:16 -0400 Subject: [PATCH] docs: prefer Protocol over ProtocolBase in plain cross-references (#1103) ProtocolBase is the internal hidden API and Protocol is the one exposing the attributes, so a plain "here is where this member is documented" link targets Protocol. The owner then refined this: "Use the last documented override." A docstring describing what a *specific* class overrides has to name the real ancestor in that class's own chain, which is never Protocol -- Protocol has no subclasses at all, so ProtocolBase is the last documented override for every class in the tree. * Plain documentation links go to Protocol.: the module-level prose and `#:` comments in protocol.py, register_protocol/_register_name in registry/protocols.py, the `register` Arguments and versionchanged clauses in internet.py, link.py, transport.py and sctp.py, and the unrelated-class references in sentinels.py, data/data.py, misc/pcap/{frame,header}.py, ipv6.py, utilities/config.py, conf.py and the mptcp test. * Override-describing links go to ProtocolBase.: Internet.{register, from_data,_make_payload}, Link.register, Transport.register, IPv6_Ext.protocol, the ipv6_ext module docstring and ipv6_ext.rst, the {AH,ESP,HOPOPT,MH}.alias MRO sentences, NoPayload.protochain, PCAPNG.{length,packet}, HTTP.from_data and HTTPv2's HTTP.unpack. Each of these says "As X", "the base", "the inherited", "narrows", "sits between ... in the MRO" or "the guard this shares with", and the surrounding sentences already name ProtocolBase. * The `Raises:` clause of each `register` keeps naming ProtocolBase, unchanged: #2316/#1016 ruled that it names the class the guard's `issubclass` actually tests while the raised message names Protocol, and tests/protocols/test_register_class_guard_unit.py asserts exactly that. * Class-attribute declaration pointers stay on Protocol -- Protocol.__data__ (declared on Protocol itself), Protocol.__keywords__ and Protocol.__own_make_keywords__ -- since they name where the knob is documented rather than a method a class overrides. * ProtocolBase.__init_subclass__ references are still left alone (l2tpv2.py, c_tag.py, protocol-layer-placement.rst): Protocol does override __init_subclass__, so those name the base implementation deliberately. Verified Protocol in no class's __mro__ but its own, and that ProtocolBase defines and documents every member involved while Protocol declares only __init_subclass__ and __data__. AST-structure guard (ast.dump with docstrings stripped) confirms all 12 touched .py files are prose-only against 27c797d35; ipv6_ext.rst carries no code. The mptcp test, test_docstring_contract.py, test_conventions_doc_claims.py, test_register_class_guard_unit.py and the docs xref suites pass (91 passed, 22 skipped, 444 subtests), as do tests/protocols, tests/foundation, tests/corekit and tests/utilities in full (3414 passed, 18 skipped, 60258 subtests). --- docs/source/conf.py | 2 +- .../pcapkit/protocols/internet/ipv6_ext.rst | 2 +- pcapkit/corekit/sentinels.py | 2 +- pcapkit/foundation/registry/protocols.py | 14 ++-- pcapkit/protocols/application/http.py | 6 +- pcapkit/protocols/application/httpv2.py | 4 +- pcapkit/protocols/data/data.py | 2 +- pcapkit/protocols/internet/internet.py | 2 +- pcapkit/protocols/internet/ipv6.py | 2 +- pcapkit/protocols/internet/ipv6_ext.py | 10 +-- pcapkit/protocols/link/link.py | 4 +- pcapkit/protocols/misc/null.py | 2 +- pcapkit/protocols/misc/pcap/frame.py | 2 +- pcapkit/protocols/misc/pcap/header.py | 2 +- pcapkit/protocols/protocol.py | 72 +++++++++---------- pcapkit/protocols/transport/sctp.py | 2 +- pcapkit/protocols/transport/transport.py | 4 +- pcapkit/utilities/config.py | 2 +- .../test_tcp_mptcp_join_flag_ordering_unit.py | 2 +- 19 files changed, 69 insertions(+), 69 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index fba4a980d4..45afcc9242 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -890,7 +890,7 @@ def sign_wrapped_function(app: 'Sphinx', obj: 'Any', bound_method: bool) -> None which for a decorated method is the wrapper. ``sphinx-autodoc-typehints`` stops unwrapping at a stated ``__signature__``, so it evaluated the annotations in the decorator's module. The ``@seekset`` overload of - :meth:`~pcapkit.protocols.protocol.ProtocolBase._read_packet` then rendered + :meth:`~pcapkit.protocols.protocol.Protocol._read_packet` then rendered its return as the bare alias ``Data_Packet``, which only the protocol module binds (:issue:`1917`). diff --git a/docs/source/pcapkit/protocols/internet/ipv6_ext.rst b/docs/source/pcapkit/protocols/internet/ipv6_ext.rst index ccb74198cd..72775bc357 100644 --- a/docs/source/pcapkit/protocols/internet/ipv6_ext.rst +++ b/docs/source/pcapkit/protocols/internet/ipv6_ext.rst @@ -141,7 +141,7 @@ This class is reached in these ways: ``IPv6-Route``, ``IPv6-Opts``, ``MH``, ``HIP``, ``IPv6-Frag`` and ``AH`` all have dedicated classes. When one of *those* raises, :func:`~pcapkit.corekit.decorators.beholder` - (:meth:`Protocol._import_next_layer `) + (:meth:`ProtocolBase._import_next_layer `) would substitute plain :class:`~pcapkit.protocols.misc.raw.Raw`, which loses ``next`` and crashes the walk as in path 1. :meth:`IPv6._import_next_layer ` catches diff --git a/pcapkit/corekit/sentinels.py b/pcapkit/corekit/sentinels.py index 379655bae6..80e12f6dc8 100644 --- a/pcapkit/corekit/sentinels.py +++ b/pcapkit/corekit/sentinels.py @@ -472,7 +472,7 @@ class with no ``__eq__`` of its own does; what it lacks is a readable The hazard is not theoretical elsewhere: reload staleness is a *tracked* defect class here for other constructs -- see - :meth:`pcapkit.protocols.protocol.ProtocolBase._lookup_next_layer`'s own + :meth:`pcapkit.protocols.protocol.Protocol._lookup_next_layer`'s own docstring note on why it declines to memoise a resolved class, and :mod:`tests.protocols.test_dispatch_default_resolution_unit`'s own ``test_no_stale_class_survives_a_module_reload``, which reloads a module diff --git a/pcapkit/foundation/registry/protocols.py b/pcapkit/foundation/registry/protocols.py index 7f6b7dd93e..459e2d03e5 100644 --- a/pcapkit/foundation/registry/protocols.py +++ b/pcapkit/foundation/registry/protocols.py @@ -166,11 +166,11 @@ def register_protocol(protocol: 'Type[ProtocolBase]') -> 'None': :class:`pcapkit.protocols.application.httpv2.HTTP` -- so they all compete for the single key ``'HTTP'``. Registering one of them replaces whichever was there, and the replacement is observable through every reader of the - registry, e.g. :meth:`ProtocolBase.expand_comp - `, which resolves a + registry, e.g. :meth:`Protocol.expand_comp + `, which resolves a bare protocol name through it. Per :issue:`675` the overwrite is reported, - matching :meth:`ProtocolBase.register - ` and the other + matching :meth:`Protocol.register + ` and the other overwrite-warning registries. The guard reads "key present **and** incumbent is a different class" -- @@ -194,8 +194,8 @@ class rather than supplied by a caller, and this function is the funnel readers outside this module cannot absorb on their own -- the registry is a documented public attribute, and its readers look a bare name up and then degrade *silently* on a miss rather than raising, so a re-keying would not - announce itself either. :meth:`ProtocolBase.expand_comp - ` falls back to the + announce itself either. :meth:`Protocol.expand_comp + ` falls back to the name as a plain string, and the ``protocol`` properties on :class:`~pcapkit.foundation.reassembly.reassembly.ReassemblyMeta` and :class:`~pcapkit.foundation.traceflow.traceflow.TraceFlowMeta` fall back to @@ -367,7 +367,7 @@ def _register_name(protocol: 'Type[ProtocolBase]', *targets: 'tuple[type, Any]') releasing whatever each target code held before, and followed by a lease when the write changed the name, so that registering the code back undoes it (:issue:`1505`). A name already showing ``protocol`` -- shipped, defined - by a :class:`~pcapkit.protocols.protocol.ProtocolBase` subclass, or + by a :class:`~pcapkit.protocols.protocol.Protocol` subclass, or registered directly -- is not leased, so no restore takes it away; one showing it through a lease extends that lease to ``targets``. diff --git a/pcapkit/protocols/application/http.py b/pcapkit/protocols/application/http.py index 5db536591a..d7942cff48 100644 --- a/pcapkit/protocols/application/http.py +++ b/pcapkit/protocols/application/http.py @@ -215,7 +215,7 @@ class HTTP(Application[_PT, _ST], Generic[_PT, _ST]): #: the 24-octet HTTP/2 connection preface, when :meth:`_guess_version` #: identified one and parsed the frame that follows it. They belong to this #: packet's header rather than to its payload, so :meth:`read` adds them to - #: :attr:`length`; otherwise :meth:`ProtocolBase.__init__ `'s + #: :attr:`length`; otherwise :meth:`Protocol.__init__ `'s #: ``self._info.__update__(packet=self.packet.payload)`` would slice the #: payload from octet 9 of a buffer whose frame starts at octet 24 and report #: the tail of the preface as packet payload. @@ -228,8 +228,8 @@ class HTTP(Application[_PT, _ST], Generic[_PT, _ST]): #: :meth:`HTTPv2.make ` #: according to that value, so the correct set of names depends on an #: argument. :obj:`None` therefore opts out of the construction keyword check - #: that :meth:`ProtocolBase.__init__ - #: ` performs; the + #: that :meth:`Protocol.__init__ + #: ` performs; the #: versioned classes are checked normally when constructed directly. __keywords__ = None diff --git a/pcapkit/protocols/application/httpv2.py b/pcapkit/protocols/application/httpv2.py index e2575d5e13..1b1b0b667a 100644 --- a/pcapkit/protocols/application/httpv2.py +++ b/pcapkit/protocols/application/httpv2.py @@ -234,7 +234,7 @@ def unpack(self, length: 'Optional[int]' = None, **kwargs: 'Any') -> 'Data_HTTP' ``length`` is resolved against :func:`len` only for *this* method's own check, and the *original* argument -- ``None`` - included -- is what is forwarded to :meth:`Protocol.unpack + included -- is what is forwarded to :meth:`ProtocolBase.unpack `. Collapsing ``None`` to a concrete ``0`` would change what :meth:`Schema.unpack `'s own @@ -251,7 +251,7 @@ def unpack(self, length: 'Optional[int]' = None, **kwargs: 'Any') -> 'Data_HTTP' if length is None: # ``0 < ... < 9`` rather than ``... < 9``: an exhausted stream # (``len(self) == 0``) is left alone, so ``length`` reaches - # :meth:`Protocol.unpack ` + # :meth:`ProtocolBase.unpack ` # still ``None`` and its ``prepare`` decorator raises # :exc:`StreamEOFError` as documented above; only a *non-empty* # short stream is rejected as malformed here. diff --git a/pcapkit/protocols/data/data.py b/pcapkit/protocols/data/data.py index 1f6ecebef3..f517a4e7be 100644 --- a/pcapkit/protocols/data/data.py +++ b/pcapkit/protocols/data/data.py @@ -19,7 +19,7 @@ class Data(Info): The ``__next_name__``, ``__next_type__`` and ``__short_read__`` keys are metadata, listed in :attr:`~pcapkit.corekit.infoclass.Info.__included__` and :attr:`~pcapkit.corekit.infoclass.Info.__excluded__`: - :meth:`Protocol.from_data ` + :meth:`Protocol.from_data ` dispatches the payload on the first two and on nothing else, and cuts a short read back on the third. :meth:`to_dict` carries them, so that ``from_data(info.to_dict())`` rebuilds as ``from_data(info)`` does, while diff --git a/pcapkit/protocols/internet/internet.py b/pcapkit/protocols/internet/internet.py index 5e986a7a83..a64b5c769e 100644 --- a/pcapkit/protocols/internet/internet.py +++ b/pcapkit/protocols/internet/internet.py @@ -182,7 +182,7 @@ def register(cls, code: 'Enum_TransType', protocol: 'ModuleDescriptor[ProtocolBa Arguments: code: protocol code as in :class:`~pcapkit.const.reg.transtype.TransType` protocol: module descriptor or a - :class:`~pcapkit.protocols.protocol.ProtocolBase` subclass + :class:`~pcapkit.protocols.protocol.Protocol` subclass Raises: pcapkit.utilities.exceptions.RegistryError: If ``protocol`` is not a diff --git a/pcapkit/protocols/internet/ipv6.py b/pcapkit/protocols/internet/ipv6.py index 60ee9a05c4..449721ddd7 100644 --- a/pcapkit/protocols/internet/ipv6.py +++ b/pcapkit/protocols/internet/ipv6.py @@ -447,7 +447,7 @@ def _exthdr_key(alias: 'str') -> 'str': """Key an extension header's info is written under in :class:`Data_IPv6`. Args: - alias: :attr:`~pcapkit.protocols.protocol.ProtocolBase.alias` of + alias: :attr:`~pcapkit.protocols.protocol.Protocol.alias` of the extension header's parser. Returns: diff --git a/pcapkit/protocols/internet/ipv6_ext.py b/pcapkit/protocols/internet/ipv6_ext.py index a79ed722a5..3c36e311c1 100644 --- a/pcapkit/protocols/internet/ipv6_ext.py +++ b/pcapkit/protocols/internet/ipv6_ext.py @@ -108,7 +108,7 @@ class for that code instead (see the bottom of the module), so dispatch ``IPv6-Route``, ``IPv6-Opts``, ``MH``, ``HIP``, ``IPv6-Frag`` and ``AH`` all have dedicated classes. When one of *those* raises, :func:`~pcapkit.corekit.decorators.beholder` - (:meth:`Protocol._import_next_layer `) + (:meth:`ProtocolBase._import_next_layer `) would substitute plain :class:`~pcapkit.protocols.misc.raw.Raw`, which loses ``next`` and crashes the walk as in path 1. :meth:`IPv6._import_next_layer ` @@ -299,7 +299,7 @@ def protocol(self) -> 'Optional[Enum_ExtensionHeader] | Optional[str]': In the *fallback* role (this instance parsed this module's own schema) this is **not** the base - :attr:`Protocol.protocol ` + :attr:`ProtocolBase.protocol ` meaning ("name of next layer protocol"). On the owner's ruling for GitHub issue :issue:`891` it is deliberately repointed at this instance's *own* identity, i.e. which header's format it parsed, such as @@ -324,7 +324,7 @@ class sits between them and data model with no such field (``AttributeError``). The discriminator is the *class-level* - :attr:`~pcapkit.protocols.protocol.ProtocolBase.__data__` rather than an + :attr:`~pcapkit.protocols.protocol.Protocol.__data__` rather than an :func:`isinstance` test on ``self._info``, because a ``make``-only instance has no ``_info`` at all. Reading it would turn :attr:`ProtocolBase.protocol `, @@ -510,8 +510,8 @@ def make(self, *, there is unioned down the MRO, so every subclass would accept these names and drop them. A ``make`` signature can be kept from subclasses instead: this class sets - :attr:`ProtocolBase.__own_make_keywords__ - `, + :attr:`Protocol.__own_make_keywords__ + `, so a subclass that overrides ``make`` accepts ``len`` or ``data`` only where its own ``make`` declares it (:issue:`2286`). diff --git a/pcapkit/protocols/link/link.py b/pcapkit/protocols/link/link.py index 228a38b71b..3b6a580571 100644 --- a/pcapkit/protocols/link/link.py +++ b/pcapkit/protocols/link/link.py @@ -138,7 +138,7 @@ def register(cls, code: 'Enum_EtherType', protocol: 'ModuleDescriptor[ProtocolBa Arguments: code: protocol code as in :class:`~pcapkit.const.reg.ethertype.EtherType` protocol: module descriptor or a - :class:`~pcapkit.protocols.protocol.ProtocolBase` subclass + :class:`~pcapkit.protocols.protocol.Protocol` subclass Raises: pcapkit.utilities.exceptions.RegistryError: If ``protocol`` is not a @@ -158,7 +158,7 @@ def register(cls, code: 'Enum_EtherType', protocol: 'ModuleDescriptor[ProtocolBa Takes the protocol as one ``protocol`` argument, a :class:`~pcapkit.corekit.module.ModuleDescriptor` or a - :class:`~pcapkit.protocols.protocol.ProtocolBase` subclass, in place of + :class:`~pcapkit.protocols.protocol.Protocol` subclass, in place of the ``module`` and ``class_`` names. """ diff --git a/pcapkit/protocols/misc/null.py b/pcapkit/protocols/misc/null.py index 4e57bbbc09..ef093cc18d 100644 --- a/pcapkit/protocols/misc/null.py +++ b/pcapkit/protocols/misc/null.py @@ -72,7 +72,7 @@ def protochain(self) -> 'None': # type: ignore[override] .. versionchanged:: 1.5.0 - Narrows :attr:`Protocol.protochain + Narrows :attr:`ProtocolBase.protochain `'s declared type from :class:`~pcapkit.corekit.protochain.ProtoChain` to :obj:`None`, the value ``self._protos`` already held here; the fix diff --git a/pcapkit/protocols/misc/pcap/frame.py b/pcapkit/protocols/misc/pcap/frame.py index 11028754f5..b8e52b8e10 100644 --- a/pcapkit/protocols/misc/pcap/frame.py +++ b/pcapkit/protocols/misc/pcap/frame.py @@ -583,7 +583,7 @@ def _make_data(cls, data: 'Data_Frame') -> 'dict[str, Any]': # type: ignore[ove Notes: The frame index and the global header are context of the PCAP file rather than fields of the frame, so they are not returned here: pass - them to :meth:`~pcapkit.protocols.protocol.ProtocolBase.from_data` as + them to :meth:`~pcapkit.protocols.protocol.Protocol.from_data` as ``num`` and ``header``. """ diff --git a/pcapkit/protocols/misc/pcap/header.py b/pcapkit/protocols/misc/pcap/header.py index 71da285923..00b33d4556 100644 --- a/pcapkit/protocols/misc/pcap/header.py +++ b/pcapkit/protocols/misc/pcap/header.py @@ -254,7 +254,7 @@ def __post_init__(self, file: 'Optional[IO[bytes] | bytes]' = None, Notes: A header the data ends inside keeps that in its :attr:`~pcapkit.protocols.protocol.Protocol.info`, so that - :meth:`~pcapkit.protocols.protocol.ProtocolBase.from_data` rebuilds only what was captured + :meth:`~pcapkit.protocols.protocol.Protocol.from_data` rebuilds only what was captured (:issue:`1470`). """ diff --git a/pcapkit/protocols/protocol.py b/pcapkit/protocols/protocol.py index 05f883e271..e17bc274a7 100644 --- a/pcapkit/protocols/protocol.py +++ b/pcapkit/protocols/protocol.py @@ -211,19 +211,19 @@ def _raw_where_parsed(made: 'Any', parsed: 'Any') -> 'bool': return False #: Keywords that configure the construction rather than naming a field, and are -#: therefore consumed by :meth:`ProtocolBase.__init__ -#: ` or by the schema layer +#: therefore consumed by :meth:`Protocol.__init__ +#: ` or by the schema layer #: instead of by a :meth:`make `. No #: signature declares them, so :func:`_declared_keywords` cannot find them and #: they are listed here. #: #: ``packet`` is here because the library puts it there itself: -#: :meth:`ProtocolBase.__init__ ` +#: :meth:`Protocol.__init__ ` #: injects ``packet=self.packet.payload`` into every parsed ``_info``, so the -#: default :meth:`ProtocolBase._make_data -#: ` (``data.to_dict()``) -#: carries it into the keywords that :meth:`ProtocolBase.from_data -#: ` reconstructs from. +#: default :meth:`Protocol._make_data +#: ` (``data.to_dict()``) +#: carries it into the keywords that :meth:`Protocol.from_data +#: ` reconstructs from. #: Refusing it would make ``from_data`` fail on any protocol whose ``make`` does #: not declare a ``packet``, starting with #: :class:`~pcapkit.protocols.misc.null.NoPayload`, the innermost layer of every @@ -242,8 +242,8 @@ def _raw_where_parsed(made: 'Any', parsed: 'Any') -> 'bool': _DECLARED_KEYWORDS = {} # type: dict[type, Optional[frozenset[str]]] #: Methods a construction keyword may be destined for. The keywords handed to -#: :class:`Protocol` reach all of them: :meth:`ProtocolBase.__post_init__ -#: ` passes the same +#: :class:`Protocol` reach all of them: :meth:`Protocol.__post_init__ +#: ` passes the same #: ``**kwargs`` to :meth:`pack ` (and #: through it to ``make``) *and* to :meth:`unpack #: ` (and through it to ``read``). @@ -259,18 +259,18 @@ def _declared_keywords(cls: 'type') -> 'Optional[frozenset[str]]': Returns: Names of every keyword-acceptable parameter declared by any of :data:`_KEYWORD_CONSUMERS` anywhere in the MRO of ``cls``, plus every - entry of :attr:`ProtocolBase.__keywords__ - ` found there, + entry of :attr:`Protocol.__keywords__ + ` found there, plus :data:`OUT_OF_BAND_KEYWORDS`. :obj:`None` if ``cls`` *itself* sets ``__keywords__`` to :obj:`None`, meaning its keywords cannot be enumerated and are not to be checked -- inherited :obj:`None` does not count, as - :attr:`ProtocolBase.__keywords__ - ` explains. + :attr:`Protocol.__keywords__ + ` explains. The union is deliberately wider than the signature of ``cls.make``, because a keyword reaching ``make`` is not necessarily *for* ``make``: - :meth:`ProtocolBase.__post_init__ - ` hands one + :meth:`Protocol.__post_init__ + ` hands one ``**kwargs`` to both the construction and the parse of the packet it has just constructed, so a keyword declared by ``read`` travels through ``make`` too. :class:`~pcapkit.protocols.internet.hip.HIP` is the live example: @@ -282,8 +282,8 @@ def _declared_keywords(cls: 'type') -> 'Optional[frozenset[str]]': The walk covers the whole MRO rather than the most derived override of each method, so that a subclass declaring its own keyword and forwarding the rest to its parent does not make the parent's keywords unreachable. The one - exception is a class that sets :attr:`ProtocolBase.__own_make_keywords__ - `: its + exception is a class that sets :attr:`Protocol.__own_make_keywords__ + `: its ``make`` counts only while it is the ``make`` of ``cls``, not once a subclass overrides it (:issue:`2286`). @@ -364,19 +364,19 @@ def _check_construction_keywords(cls: 'type', kwargs: 'dict[str, Any]', Args: cls: Protocol class being constructed. kwargs: Construction keywords to check, the out-of-band ones left out. - :meth:`ProtocolBase.__init__ - ` passes those - remaining after it has consumed them; :meth:`ProtocolBase.from_data - ` passes its + :meth:`Protocol.__init__ + ` passes those + remaining after it has consumed them; :meth:`Protocol.from_data + ` passes its caller's own, less ``_layer``, ``_protocol`` and ``__context__``, - before :meth:`ProtocolBase._make_data - ` adds to them. + before :meth:`Protocol._make_data + ` adds to them. strict: Whether an unexpected keyword is an error. :data:`True` for a caller's own construction; :data:`False` when the keywords were - generated by :meth:`ProtocolBase._make_data - ` rather than - written by anybody -- see :meth:`ProtocolBase.from_data - `. + generated by :meth:`Protocol._make_data + ` rather than + written by anybody -- see :meth:`Protocol.from_data + `. Raises: UnsupportedCall: If ``strict`` and any keyword is not among those @@ -690,7 +690,7 @@ def packet(self) -> 'Data_Packet': example -- its :attr:`~pcapkit.protocols.misc.pcapng.PCAPNG.length` is the wire's Block Total Length and the captured octets sit ahead of the option list and the trailing length field. The payload matters - because :meth:`ProtocolBase.__init__` injects it into every parsed + because :meth:`Protocol.__init__` injects it into every parsed ``_info``, which the dumpers write out. """ @@ -764,21 +764,21 @@ def make(self, **kwargs: 'Any') -> '_ST': Note: The ``**kwargs`` here absorbs the keywords that - :meth:`ProtocolBase.__post_init__ - ` hands to the + :meth:`Protocol.__post_init__ + ` hands to the parse as well as to the construction, so an implementation is not expected to declare every keyword it is called with. It is *not* a place for a caller to put a keyword no signature declares: building a protocol *through its constructor* with such a keyword raises :exc:`~pcapkit.utilities.exceptions.UnsupportedCall` from - :meth:`ProtocolBase.__init__ - ` (:issue:`617`). + :meth:`Protocol.__init__ + ` (:issue:`617`). Warning: **Calling this method directly is not checked**, and still discards an undeclared keyword in silence. The check lives in - :meth:`ProtocolBase.__init__ - `, so it covers + :meth:`Protocol.__init__ + `, so it covers ``SomeProtocol(...)`` and the :meth:`pack` it leads to, but not ``SomeProtocol.make(...)`` on an instance obtained some other way -- ``object.__new__(cls).make(**kwargs)`` is the idiom, used by this @@ -1039,7 +1039,7 @@ def register(cls, code: 'int', protocol: 'ModuleDescriptor | Type[ProtocolBase]' Arguments: code: protocol code protocol: module descriptor or a - :class:`~pcapkit.protocols.protocol.ProtocolBase` subclass + :class:`~pcapkit.protocols.protocol.Protocol` subclass Raises: pcapkit.utilities.exceptions.RegistryError: If ``protocol`` is not a @@ -2386,7 +2386,7 @@ def _parse_next_layer(klass: 'Type[ProtocolBase]', file_: 'bytes', length: 'int' :meth:`Schema.unpack ` zero-fills a field the stream ends inside, so a header parsed from too few octets is filled with values that were never on the wire, and - :meth:`from_data ` rebuilds them (:issue:`1170`). + :meth:`from_data ` rebuilds them (:issue:`1170`). Such a payload is kept as :class:`~pcapkit.protocols.misc.raw.Raw` instead, as an unparseable one is. diff --git a/pcapkit/protocols/transport/sctp.py b/pcapkit/protocols/transport/sctp.py index 45d217f73a..041411cfd1 100644 --- a/pcapkit/protocols/transport/sctp.py +++ b/pcapkit/protocols/transport/sctp.py @@ -734,7 +734,7 @@ def register(cls, code: 'Enum_PayloadProtocolIdentifier | int', protocol: 'Modul code: payload protocol identifier (PPID), as in :class:`~pcapkit.const.sctp.payload_protocol_identifier.PayloadProtocolIdentifier` protocol: module descriptor or a - :class:`~pcapkit.protocols.protocol.ProtocolBase` subclass + :class:`~pcapkit.protocols.protocol.Protocol` subclass Important: SCTP overrides :meth:`Transport.register diff --git a/pcapkit/protocols/transport/transport.py b/pcapkit/protocols/transport/transport.py index 0535c517a9..efb96647e1 100644 --- a/pcapkit/protocols/transport/transport.py +++ b/pcapkit/protocols/transport/transport.py @@ -79,7 +79,7 @@ def register(cls, code: 'int', protocol: 'ModuleDescriptor[ProtocolBase] | Type[ Arguments: code: port number protocol: module descriptor or a - :class:`~pcapkit.protocols.protocol.ProtocolBase` subclass + :class:`~pcapkit.protocols.protocol.Protocol` subclass Important: This method must be called from a non-abstract class, as the @@ -115,7 +115,7 @@ def register(cls, code: 'int', protocol: 'ModuleDescriptor[ProtocolBase] | Type[ Takes the protocol as one ``protocol`` argument, a :class:`~pcapkit.corekit.module.ModuleDescriptor` or a - :class:`~pcapkit.protocols.protocol.ProtocolBase` subclass, in place of + :class:`~pcapkit.protocols.protocol.Protocol` subclass, in place of the ``module`` and ``class_`` names. """ diff --git a/pcapkit/utilities/config.py b/pcapkit/utilities/config.py index 4b8ddf3d43..9f91206830 100644 --- a/pcapkit/utilities/config.py +++ b/pcapkit/utilities/config.py @@ -194,7 +194,7 @@ def read_flag(name: 'str', default: 'bool' = False) -> 'bool': #: Python's recursion limit falls, which depends on the interpreter. Each #: header is a layer, so :data:`FRAME_LAYER_LIMIT` applies as well. #: -#: Rebuilding a frame with :meth:`~pcapkit.protocols.protocol.ProtocolBase.from_data` +#: Rebuilding a frame with :meth:`~pcapkit.protocols.protocol.Protocol.from_data` #: stops where parsing it did, and warns once too (:issue:`1619`), cf. #: :meth:`Internet._make_payload #: `. 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 9adeacbb08..d23dbd0584 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 @@ -56,7 +56,7 @@ always exists -- is worse than the crash, and :class:`TCPMPTCPJoinStaleFlagsUnitTests` is the case that shows why. -:meth:`Protocol.pack ` is public and calls +:meth:`Protocol.pack ` is public and calls ``make``, so an instance that has already *parsed* a segment can be asked to build a different one. That instance's ``_flags`` is already set -- to the parsed segment's flags -- so a zero default never comes into play for it, and with the options built first it