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
10 changes: 5 additions & 5 deletions docs/source/pcapkit/const/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ Unrecognised Values
Nearly every :term:`registry` below departs from :mod:`enum` in one deliberate way, and it
is the behaviour to know about before using any of them: looking one up by a value
it does not define does **not** raise. Its ``_missing_`` override returns a
member-like object for a value inside the registry's valid range, named for the
unassigned or reserved band it falls in. Only a value outside that range, or of the
wrong type, raises :exc:`ValueError`.
member-like object for a value that falls in one of the registry's unassigned or
reserved bands, named for that band. Only a value no band covers, or of the wrong
type, raises :exc:`ValueError`.

In almost every registry that object is **not** installed: the registry does not
grow, and a second lookup of the same value returns an equal but distinct object.
Expand All @@ -38,15 +38,15 @@ Some behave otherwise, and :ref:`mint-criterion` gives the full split:

That is what makes the enumerations usable against live capture data, where a
protocol number assigned after this release was generated is a routine
occurrence rather than an error. It also means an enumeration member is not a
occurrence rather than an error. It also means an enumeration is not a
closed set: an unassigned value resolves to a member that is, apart from
:class:`~pcapkit.const.mh.cga_type.CGAType`, absent from iteration and ``__members__``,
and whether a repeat lookup returns the same object varies by registry, so compare such
members by value, not identity.

The common form of the override is generated -- see :mod:`pcapkit.vendor.default`,
whose template emits it -- while the valid range and the names of the unassigned
bands are per-registry, taken from that registry's own IANA data. The individual
bands are per-registry, taken from that registry's own source data. The individual
overrides are therefore not documented per class.

.. seealso::
Expand Down
2 changes: 1 addition & 1 deletion docs/source/pcapkit/const/pcapng.rst
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ which is automatically generated from :class:`pcapkit.vendor.pcapng.tls_key_labe

.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-standardized-block-type-cod
.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-options
.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-enhanced-packet-block-flags
.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-enhanced-packet-block-optio
.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-enhanced-packet-block
.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-name-resolution-block
.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-decryption-secrets-block
Expand Down
2 changes: 1 addition & 1 deletion docs/source/pcapkit/const/vlan.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ enumerations include:

.. list-table::

* - :const:`VLAN_PriorityLevel <pcapkit.const.vlan.priority_level.PriorityLevel>`
* - :class:`VLAN_PriorityLevel <pcapkit.const.vlan.priority_level.PriorityLevel>`
- Priority Levels [*]_

Priority levels defined in IEEE 802.1p
Expand Down
2 changes: 1 addition & 1 deletion docs/source/pcapkit/vendor/pcapng.rst
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ which is automatically generating :class:`pcapkit.const.pcapng.tls_key_label.TLS

.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-standardized-block-type-cod
.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-options
.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-enhanced-packet-block-flags
.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-enhanced-packet-block-optio
.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-enhanced-packet-block
.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-name-resolution-block
.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-decryption-secrets-block
Expand Down
4 changes: 2 additions & 2 deletions pcapkit/const/ftp/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ 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 :issue:`860`:
that import-time mutation was the same defect shape :issue:`775` removed
from :class:`~pcapkit.const.pcapng.filter_type.FilterType`. ``_missing_``
that import-time mutation is the same defect shape :issue:`775` rules
out on :class:`~pcapkit.const.pcapng.filter_type.FilterType`. ``_missing_``
still unmints for a keyword that
turns up on the wire but names none of these -- the extendability the
owner conditionally asked to keep on GitHub issue :issue:`860`: unsure what a
Expand Down
4 changes: 2 additions & 2 deletions pcapkit/const/http/method.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,8 @@ def get(cls, key: 'str', default: 'Optional[str]' = None) -> 'Method':
IANA methods whose member *name* differs from their *value* --
``BASELINE_CONTROL`` / ``'BASELINE-CONTROL'`` and
``VERSION_CONTROL`` / ``'VERSION-CONTROL'``, a hyphen being unusable
in a Python identifier -- which :meth:`_missing_` (and so the
constructor) also finds by value.
in a Python identifier -- which the constructor also finds by
value, before it falls back to :meth:`_missing_`.

It is a :class:`classmethod`, as the base is, because a
zero-argument ``super()`` needs a first argument to bind
Expand Down
2 changes: 1 addition & 1 deletion pcapkit/const/ospf/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# pylint: disable=unused-import
""":class:`~pcapkit.protocols.application.ospf.OSPF` Constant Enumerations
======================================================================
=======================================================================

.. module:: pcapkit.const.ospf

Expand Down
2 changes: 1 addition & 1 deletion pcapkit/const/pcapng/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-standardized-block-type-cod
.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-options
.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-enhanced-packet-block-flags
.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-enhanced-packet-block-optio
.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-enhanced-packet-block
.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-name-resolution-block
.. [*] https://www.ietf.org/archive/id/draft-tuexen-opsawg-pcapng-03.html#name-decryption-secrets-block
Expand Down
2 changes: 1 addition & 1 deletion pcapkit/const/reg/apptype/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@

#: Registries imported on first use rather than with this package, as submodule
#: name to class name -- GitHub issue :issue:`1538`. Generated from IANA's
#: registry, the two hold about 49,700 lines of members, about 30% of
#: registry, they hold about 49,700 lines of members, about 30% of
#: ``import pcapkit`` when imported eagerly, while SCTP's and DCCP's cost a few
#: milliseconds and stay eager.
_LAZY = {'tcp': 'TCP', 'udp': 'UDP'}
Expand Down
3 changes: 2 additions & 1 deletion pcapkit/const/reg/apptype/apptype.py
Original file line number Diff line number Diff line change
Expand Up @@ -2734,7 +2734,8 @@ def _sanitize_identifier(cls, name: 'str') -> 'str':
collapsed = '_'.join(stripped.split())
replaced = re.sub(r'\W', '_', collapsed)
identifier = '_'.join(filter(None, replaced.split('_')))
# NOTE: matches process()'s own keyword guard below -- a name that
# NOTE: matches the keyword guard AppType.process applies at generation
# time in pcapkit.vendor.reg.apptype.apptype -- a name that
# sanitises to a reserved word is not usable as an attribute as is,
# and a trailing underscore is the same fix the generator already
# applies to a statically declared member with the same problem.
Expand Down
2 changes: 1 addition & 1 deletion pcapkit/const/vlan/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

.. list-table::

* - :const:`VLAN_PriorityLevel <pcapkit.const.vlan.priority_level.PriorityLevel>`
* - :class:`VLAN_PriorityLevel <pcapkit.const.vlan.priority_level.PriorityLevel>`
- Priority Levels [*]_

.. [*] https://en.wikipedia.org/wiki/IEEE_P802.1p#Priority_levels
Expand Down
2 changes: 1 addition & 1 deletion pcapkit/corekit/enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ def get_all(cls, key: 'Any') -> 'tuple[Self, ...]':


class EnumRegistry(EnumLookup):
"""Registry protocol shared by every constant enumeration under
"""Registry protocol shared by every open constant enumeration under
:mod:`pcapkit.const`.

:class:`EnumLookup` above carries the read half -- :meth:`~EnumLookup.get`,
Expand Down
4 changes: 2 additions & 2 deletions pcapkit/corekit/fields/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,8 +433,8 @@ def unpack(self, buffer: 'bytes | IO[bytes]', packet: 'dict[str, Any]') -> '_T':
# NOTE: ``length`` is frequently wire-derived -- resolved by a
# ``_length_callback`` against the very packet being parsed, per
# :meth:`Field.__call__` below, or by a schema's own selector building a
# field from a value it just read off the wire (e.g. ``DecryptionSecretsBlock``'s
# ``secrets_data: BytesField(length=lambda pkt: pkt['__length__'])``) --
# field from a value it just read off the wire (e.g. HIP's
# ``host_id_hi_selector`` returning ``BytesField(length=pkt['hi_len'])``) --
# and is thus attacker-controlled: a corrupt or hostile capture can
# declare an arbitrarily large one. Past :data:`~pcapkit.utilities.config.MAX_ZERO_PAD_LENGTH`, a
# length that ``buffer`` falls short of is provably bogus: the padding
Expand Down
19 changes: 9 additions & 10 deletions pcapkit/corekit/fields/ipaddress.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,19 +158,18 @@ def parse_ip_address(value: 'IPv4Address | IPv6Address | bytes | int | str',
length is the only thing on the wire that carries the family -- must
convert the argument itself, and that conversion happens **before**
the schema, so it launders a :obj:`bool` into an
:class:`~ipaddress.IPv4Address` that the guard added for :issue:`491`
in :meth:`_IPAddressField.pre_process` can then only see as a
:class:`~ipaddress.IPv4Address` that the :issue:`491` guard in
:meth:`_IPAddressField.pre_process` can then only see as a
legitimate address: ``True`` / ``False`` become ``0.0.0.1`` /
``0.0.0.0`` -- or ``::1`` / ``::`` where the wire format fixes the
family as IPv6 -- without complaint.

Routing every one of them through here rather than giving each its own
:func:`isinstance` check is the whole point: :issue:`469` added
exactly such a check to :meth:`MH._make_opt_mn_id
<pcapkit.protocols.internet.mh.MH._make_opt_mn_id>`, and :issue:`491`
was the same defect surviving at every site that had not been thought
of. A guard that has to be remembered per call site is a guard that
will be forgotten at the next one.
:func:`isinstance` check is the whole point: :meth:`MH._make_opt_mn_id
<pcapkit.protocols.internet.mh.MH._make_opt_mn_id>` carries exactly
such a check (:issue:`469`), and :issue:`491` is the same defect at
every site that lacks one. A guard that has to be remembered per call
site is a guard that will be forgotten at the next one.

The :obj:`bool` rejection is the **first** statement here, ahead of any
dispatch on the value's type, for the placement reason :issue:`469`
Expand All @@ -195,8 +194,8 @@ def parse_ip_address(value: 'IPv4Address | IPv6Address | bytes | int | str',
exception classes derive from
:exc:`~pcapkit.utilities.exceptions.BaseError` *and* :exc:`ValueError`,
so the difference is invisible to ``except BaseError`` and ``except
ValueError``, and nothing in the library catches either one
specifically.
ValueError``, and no call of this function or of a ``_make_*`` in the
library sits inside an ``except`` for either one specifically.

.. versionadded:: 1.5.0

Expand Down
5 changes: 3 additions & 2 deletions pcapkit/corekit/infoclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -1272,8 +1272,9 @@ def _nested_types(cls: 'Type[Info]') -> 'dict[str, Type[Info]]':
forward reference whose target is defined only *after* the first
:meth:`Info.from_dict` call stays one-way for the life of the process.
That is accepted rather than fixed: :meth:`Info.from_dict` runs per
parsed packet (see :meth:`IPv4._read_ipv4_options
<pcapkit.protocols.internet.ipv4.IPv4._read_ipv4_options>`), and
parsed packet (see :meth:`IPv4.read
<pcapkit.protocols.internet.ipv4.IPv4.read>`, which builds its ToS
field with it), and
re-resolving the annotations on every call to catch a case that does
not arise in this package costs far more than it saves.

Expand Down
6 changes: 3 additions & 3 deletions pcapkit/corekit/sentinels.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,8 +457,8 @@ class with no ``__eq__`` of its own does; what it lacks is a readable
then reads :data:`False` where it once read :data:`True`.
:meth:`EnumLookup.get <pcapkit.corekit.enum.EnumLookup.get>` is such a
consumer but is not affected: its fallback is guarded by
``default not in cls._value2member_map_`` (added by GitHub issue
:issue:`864` to stop ``default`` minting a new member), and a
``default not in cls._value2member_map_`` (the GitHub issue
:issue:`864` guard that stops ``default`` minting a new member), and a
:class:`NoDefaultType` instance, stale or fresh, is never a registered
enum value, so the guard reads :data:`True` for it either way and ``get``
re-raises the original lookup error regardless of which
Expand All @@ -476,7 +476,7 @@ class with no ``__eq__`` of its own does; what it lacks is a readable
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
deliberately to pin the fix for exactly that class of bug. A *future*
deliberately to guard against exactly that class of bug. A *future*
comparison site written the vulnerable way -- a bare ``is NO_DEFAULT``
with no independent guard behind it -- would reproduce it. Nothing in
this package reloads :mod:`pcapkit.corekit.sentinels` after import, but
Expand Down
4 changes: 2 additions & 2 deletions pcapkit/vendor/ftp/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ 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 :issue:`860`:
that import-time mutation was the same defect shape :issue:`775` removed
from :class:`~pcapkit.const.pcapng.filter_type.FilterType`. ``_missing_``
that import-time mutation is the same defect shape :issue:`775` rules
out on :class:`~pcapkit.const.pcapng.filter_type.FilterType`. ``_missing_``
still unmints for a keyword that
turns up on the wire but names none of these -- the extendability the
owner conditionally asked to keep on GitHub issue :issue:`860`: unsure what a
Expand Down
4 changes: 2 additions & 2 deletions pcapkit/vendor/http/method.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ def get(cls, key: 'str', default: 'Optional[str]' = None) -> '{NAME}':
IANA methods whose member *name* differs from their *value* --
``BASELINE_CONTROL`` / ``'BASELINE-CONTROL'`` and
``VERSION_CONTROL`` / ``'VERSION-CONTROL'``, a hyphen being unusable
in a Python identifier -- which :meth:`_missing_` (and so the
constructor) also finds by value.
in a Python identifier -- which the constructor also finds by
value, before it falls back to :meth:`_missing_`.

It is a :class:`classmethod`, as the base is, because a
zero-argument ``super()`` needs a first argument to bind
Expand Down
1 change: 1 addition & 0 deletions pcapkit/vendor/ipv4/tos_thr.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
class ToSThroughput(Vendor):
"""ToS (DS Field) Throughput"""

#: Value limit checker.
FLAG = 'isinstance(value, int) and 0 <= value <= 1'

def request(self) -> 'dict[int, str]': # type: ignore[override] # pylint: disable=arguments-differ
Expand Down
26 changes: 12 additions & 14 deletions pcapkit/vendor/ipv6/extension_header.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,20 +85,18 @@ def _validate_value(cls, value: 'Any') -> 'None':
class ExtensionHeader(Vendor):
"""IPv6 Extension Header Types"""

#: Keyword-style names carried over from this crawler's *previous* data
#: source, keyed by protocol number. The Protocol Numbers registry
#: (``protocol-numbers-1.csv``, this crawler's :attr:`LINK` before GitHub
#: issue :issue:`925`) paired each of these headers with a short ``Keyword``
#: column value, e.g. ``IPv6-Route`` for header 43. The registry
#: :attr:`LINK` points at -- IANA's authoritative *IPv6 Extension
#: Header Types* registry -- has no such column, only a verbose
#: ``Description`` (``Routing Header for IPv6`` for the same header), so
#: deriving names the same way :meth:`process` does for every other
#: 3-column registry (see e.g.
#: :class:`~pcapkit.vendor.ipv6.router_alert.RouterAlert`)
#: would silently rename these members. This mapping keeps
#: the shorter names instead; any header not listed here falls back to a
#: name derived from its description.
#: Keyword-style names taken from the *Protocol Numbers* registry
#: (``protocol-numbers-1.csv``), keyed by protocol number. That registry
#: pairs each of these headers with a short ``Keyword`` column value, e.g.
#: ``IPv6-Route`` for header 43. The registry :attr:`LINK` points at --
#: IANA's authoritative *IPv6 Extension Header Types* registry -- has no
#: such column, only a verbose ``Description`` (``Routing Header for
#: IPv6`` for the same header), so deriving names the same way
#: :meth:`process` does for every other 3-column registry (see e.g.
#: :class:`~pcapkit.vendor.ipv6.router_alert.RouterAlert`) would give
#: these members long description-derived names (GitHub issue
#: :issue:`925`). This mapping keeps the shorter names instead; any header
#: not listed here falls back to a name derived from its description.
NAMES = {
0: 'HOPOPT',
43: 'IPv6-Route',
Expand Down
2 changes: 1 addition & 1 deletion pcapkit/vendor/ipv6/seed_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def request(self) -> 'dict[int, str]': # type: ignore[override] # pylint: disab
"""Fetch registry data.

Returns:
Registry data (:attr:`~pcapkit.vendor.ipv6.seed_id.DATA`).
Registry data (:data:`~pcapkit.vendor.ipv6.seed_id.DATA`).

"""
return DATA
Expand Down
Loading
Loading