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
2 changes: 1 addition & 1 deletion docs/source/pcapkit/const/tcp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ which is automatically generated from :class:`pcapkit.vendor.tcp.flags.Flags`.
.. versionchanged:: 1.5.0

A value outside the 16-bit field raises :exc:`ValueError`, where
:mod:`aenum` composed a pseudo-member for any integer.
``aenum`` composed a pseudo-member for any integer.

.. autoclass:: pcapkit.const.tcp.flags.Flags
:members:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/pcapkit/dumpkit/common.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Common Utilities
.. module:: pcapkit.dumpkit.common

:mod:`pcapkit.dumpkit.common` holds the utilities shared by
:mod:`pcapkit.dumpkit`, chiefly customised hooks for :class:`dictdumper.Dumper`
:mod:`pcapkit.dumpkit`, chiefly customised hooks for :class:`dictdumper.dumper.Dumper`
classes.

.. autofunction:: pcapkit.dumpkit.common.make_dumper
Expand Down
14 changes: 7 additions & 7 deletions docs/source/pcapkit/foundation/engines/3rdparty.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ support, as is used by :class:`pcapkit.foundation.extraction.Extractor`.

.. note::

Constructing this engine imports :mod:`scapy.all`, which populates `Scapy`_'s
Constructing this engine imports ``scapy.all``, which populates `Scapy`_'s
layer registries -- ``conf.l2types`` and the ``bind_layers`` payload table,
both of which exist only as import side effects of the layer modules.
Importing a narrower submodule leaves them empty, and
Expand All @@ -26,9 +26,9 @@ support, as is used by :class:`pcapkit.foundation.extraction.Extractor`.
``Ethernet / IP / UDP / Raw``, and such a list would go stale silently as
`Scapy`_ gains layer types.

One side effect: :mod:`scapy.all` loads :mod:`scapy.layers.dcerpc`, which
One side effect: ``scapy.all`` loads :mod:`scapy.layers.dcerpc`, which
reaches `Scapy`_'s TLS layer and there triggers a
``CryptographyDeprecationWarning`` from :mod:`cryptography` about
``CryptographyDeprecationWarning`` from ``cryptography`` about
finite-field Diffie-Hellman. It concerns a key-exchange code path
:mod:`pcapkit` never executes, but it subclasses :exc:`UserWarning` rather
than :exc:`DeprecationWarning`, so Python's default filters show it.
Expand Down Expand Up @@ -193,7 +193,7 @@ support, as is used by :class:`pcapkit.foundation.extraction.Extractor`.

.. important::

`pcap-ct`_ installs the same top-level :mod:`pcap` module as `PyPCAP`_. This
`pcap-ct`_ installs the same top-level ``pcap`` module as `PyPCAP`_. This
engine therefore checks which of the two it got and raises
:exc:`~pcapkit.utilities.exceptions.UnsupportedCall` when it is `pcap-ct`_,
naming ``engine='pcap_ct'`` in the message. Running `pcap-ct`_ under the
Expand Down Expand Up @@ -308,8 +308,8 @@ support, as is used by :class:`pcapkit.foundation.extraction.Extractor`.
interface rather than 1.3.0.

Every attribute this engine touches -- the ``pcap.pcap(name=..., promisc=...)``
constructor, :meth:`~pcap.pcap.datalink`, ``snaplen``, iteration yielding
``(timestamp, bytes)``, and :meth:`~pcap.pcap.close` -- is present on both and
constructor, ``pcap.pcap.datalink``, ``snaplen``, iteration yielding
``(timestamp, bytes)``, and ``pcap.pcap.close`` -- is present on both and
behaves identically, byte for byte and timestamp for timestamp, on
``pcap-ct`` 1.3.0b3 against ``pypcap`` 1.3.0 -- a statement about those
versions, not a guarantee from upstream. ``PCAP_CT`` is therefore not
Expand Down Expand Up @@ -441,7 +441,7 @@ Backend Detection

.. module:: pcapkit.foundation.engines._pcap_backend

Unrelated PyPI distributions install a top-level module named :mod:`pcap` --
Unrelated PyPI distributions install a top-level module named ``pcap`` --
`PyPCAP`_, a Cython binding shipped as a single extension module, and `pcap-ct`_,
a :mod:`ctypes` reimplementation shipped as a package. They therefore collide,
and ``import pcap`` resolves to whichever the import system finds first.
Expand Down
2 changes: 2 additions & 0 deletions docs/source/pcapkit/protocols/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,8 @@ Internal Definitions
:no-members:
:show-inheritance:

.. autoproperty:: registry

.. autoclass:: pcapkit.protocols.schema.schema._EnumRegistry
:no-members:
:show-inheritance:
Expand Down
15 changes: 15 additions & 0 deletions docs/source/pcapkit/utilities/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,18 @@ following objects and functions:
- Python 3.10
* - :class:`types.UnionType`, or :data:`None` below it
- Python 3.10

.. function:: final(f)

:func:`typing.final` from Python 3.11 on, and ``typing_extensions.final``
below it. Both record ``__final__ = True`` on the decorated object at
runtime, which :class:`~pcapkit.corekit.infoclass.Info` and
:class:`~pcapkit.protocols.schema.schema.Schema` read to refuse a class
marked ``@final`` without :func:`~pcapkit.corekit.infoclass.info_final` or
:func:`~pcapkit.protocols.schema.schema.schema_final`. Plain
:func:`typing.final` records nothing below 3.11 (gh-90500).

.. versionchanged:: 1.5.0

Taken from ``typing_extensions`` below Python 3.11 rather than 3.8, so
that ``__final__`` is recorded on every supported version (:issue:`778`).
4 changes: 2 additions & 2 deletions docs/source/pcapkit/utilities/warnings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ channel**:
``pcapkit`` logger sees every complaint whatever the warning filters say;
2. the standard :mod:`warnings` machinery, via :func:`warnings.warn`, subject to
the filters -- so :func:`warnings.filterwarnings`,
:func:`warnings.catch_warnings`, :mod:`pytest`'s ``filterwarnings``,
:class:`warnings.catch_warnings`, :mod:`pytest`'s ``filterwarnings``,
:option:`-W` and :envvar:`PYTHONWARNINGS` govern :mod:`pcapkit` warnings
exactly as they govern any other library's (with one wrinkle in naming a
category on the command line, noted below).
Expand Down Expand Up @@ -91,7 +91,7 @@ configured separately, through the :mod:`logging` module::
the first snippet above restores the 1.4.x quiet. In 1.4.x, constructing a
:class:`~pcapkit.utilities.warnings.BaseWarning` installed an ``ignore``
filter for its own class, so a caller could not re-enable them. The filter
went at the *front* of the process-global :data:`warnings.filters`, so it
went at the *front* of the process-global ``warnings.filters``, so it
also overrode the host application's own configuration for those categories
and made unrelated warnings re-fire (:issue:`364`).

Expand Down
38 changes: 19 additions & 19 deletions pcapkit/corekit/enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,13 @@ class EnumLookup:
on top; a closed enumeration inherits this one directly and so is never
handed a ``register`` it would have to refuse.

This is a plain mix-in rather than an :class:`~aenum.Enum` subclass, because
This is a plain mix-in rather than an ``aenum.Enum`` subclass, because
an enumeration that already has members cannot be subclassed. Mixed in
*before* the member type -- ``class Foo(EnumRegistry, IntFlag)``, or
``class Bar(EnumLookup, IntEnum)`` -- it contributes methods only, so
:mod:`aenum` still resolves the member data type from the enumeration base:
``int`` for :class:`~aenum.IntEnum` and :class:`~aenum.IntFlag`, ``str`` for
:class:`~aenum.StrEnum`. That is what lets one base serve each of them, where a
``aenum`` still resolves the member data type from the enumeration base:
``int`` for ``aenum.IntEnum`` and ``aenum.IntFlag``, ``str`` for
``aenum.StrEnum``. That is what lets one base serve each of them, where a
generated template fragment would have needed a separate rendering per
member type.

Expand All @@ -134,20 +134,20 @@ class EnumLookup:
``class Foo(EnumRegistry, IntFlag)`` resolves as ``Foo -> EnumRegistry ->
EnumLookup -> IntFlag -> int -> ...``, so ``_member_type_`` still comes from
the enumeration base and not from anything in this module. Had this tier
subclassed :class:`~aenum.Enum` in order to "be an enum", it would have
subclassed ``aenum.Enum`` in order to "be an enum", it would have
become the member type itself and broken every one of these shapes at once.

The methods deliberately touch only ``_member_map_``, ``_member_names_`` and
``_value2member_map_``, which both :mod:`enum` and :mod:`aenum` maintain, so
nothing on this tier depends on :mod:`aenum` internals at all -- the
:func:`~aenum.extend_enum` call in this module belongs to
``_value2member_map_``, which both :mod:`enum` and ``aenum`` maintain, so
nothing on this tier depends on ``aenum`` internals at all -- the
``aenum.extend_enum`` call in this module belongs to
:class:`EnumRegistry`, which is the tier that mutates.

"""

if TYPE_CHECKING:
#: The enumeration machinery's own lookup tables and member data type,
#: declared here because they are contributed by the :class:`~aenum.Enum`
#: declared here because they are contributed by the ``aenum.Enum``
#: base this mix-in is combined with rather than by the mix-in itself.
_member_map_: 'dict[str, Self]'
_member_names_: 'list[str]'
Expand Down Expand Up @@ -303,7 +303,7 @@ def get(cls, key: 'Any', default: 'Any' = NO_DEFAULT) -> 'Self':
:class:`~pcapkit.const.pcapng.tls_key_label.TLSKeyLabel`) mints on
any path, so no live witness exists in this tree.
:class:`~pcapkit.const.mh.cga_type.CGAType`, which still mints directly
via :func:`~aenum.extend_enum`, is :class:`int`-valued, so
via ``aenum.extend_enum``, is :class:`int`-valued, so
a ``str`` name could not reach its mint branch even if this restriction
did not exist; it is not an exception to it, just not reachable by it.
This is about a future ``str``-valued registry (or a present one whose
Expand Down Expand Up @@ -390,7 +390,7 @@ def get(cls, key: 'Any', default: 'Any' = NO_DEFAULT) -> 'Self':
typically :exc:`~pcapkit.utilities.exceptions.EnumValueError` from a
subclass's :meth:`_validate_value` -- is re-raised as it stands rather
than wrapped, so the subclass's own message survives and no second
error is constructed. Only :mod:`aenum`'s and :mod:`enum`'s own "no
error is constructed. Only ``aenum``'s and :mod:`enum`'s own "no
member carries this value" is converted, into a quiet
:exc:`~pcapkit.utilities.exceptions.EnumValueError`. This is the same
discrimination :meth:`EnumField.post_process
Expand Down Expand Up @@ -520,8 +520,8 @@ def register(cls, value: 'Any', name: 'str') -> 'Self':
Contrast :meth:`get` and ``_missing_``, which resolve without naming anything.

Refuses a ``value`` that already has a member. Without this guard,
:func:`~aenum.extend_enum` does not mint anything for an already-taken
value -- :mod:`aenum` treats that as a request to *alias* the existing
``aenum.extend_enum`` does not mint anything for an already-taken
value -- ``aenum`` treats that as a request to *alias* the existing
member under the caller's ``name`` instead, silently: the call returns
the *existing* member, ``name`` becomes reachable in ``__members__``
pointing at it, and ``_member_names_`` does not grow. That is
Expand Down Expand Up @@ -565,7 +565,7 @@ def register(cls, value: 'Any', name: 'str') -> 'Self':
:meth:`~EnumLookup._validate_value` rejects ``value``. The base
implementation of that hook accepts everything, so this cannot
arise on a registry that does not override it.
ValueError: If ``name`` is already taken. :mod:`aenum` reports that
ValueError: If ``name`` is already taken. ``aenum`` reports that
as :exc:`TypeError`; it is translated so that the ways one call
can fail are one exception type.

Expand All @@ -583,7 +583,7 @@ def register(cls, value: 'Any', name: 'str') -> 'Self':

@classmethod
def _extend(cls, value: 'Any', name: 'str') -> 'Self':
"""The raw :func:`~aenum.extend_enum` call, shared by :meth:`register`
"""The raw ``aenum.extend_enum`` call, shared by :meth:`register`
and :meth:`register_alias`.

Neither public method calls the other: :meth:`register` refuses an
Expand All @@ -603,7 +603,7 @@ def _extend(cls, value: 'Any', name: 'str') -> 'Self':
The member now reachable under ``name``, new or existing.

Raises:
ValueError: If ``name`` is already taken. :mod:`aenum` reports that
ValueError: If ``name`` is already taken. ``aenum`` reports that
as :exc:`TypeError`; it is translated so that the ways one call
can fail are one exception type.

Expand Down Expand Up @@ -642,7 +642,7 @@ def register_alias(cls, value: 'Any', name: 'str') -> 'Self':
:meth:`register_alias` test ``value``'s membership for opposite
outcomes, so neither can be the other's implementation.
``AppType``'s override differs: it mints a real member through
:func:`~aenum.extend_enum`, so its iteration grows too.
``aenum.extend_enum``, so its iteration grows too.

Args:
value: Value of the existing member to alias.
Expand Down Expand Up @@ -674,7 +674,7 @@ def register_aliases(cls, value: 'Any', *names: 'str') -> 'tuple[Self, ...]':

Raises:
ValueError: As :meth:`register_alias`. Names before the failing one
stay registered -- :func:`~aenum.extend_enum` has no transaction
stay registered -- ``aenum.extend_enum`` has no transaction
to roll back, and undoing it by hand would mean reaching further
into enumeration internals than anything else here does.

Expand All @@ -691,7 +691,7 @@ def _unregistered_member(cls, value: 'Any', name: 'str') -> 'Self':
that does.

The member is constructed through ``cls._member_type_``, which
:mod:`aenum` sets from the enumeration base, so this serves ``int``- and
``aenum`` sets from the enumeration base, so this serves ``int``- and
``str``-valued registries alike without either having to say which it
is.

Expand Down
21 changes: 10 additions & 11 deletions pcapkit/corekit/fields/numbers.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ def post_process(self, value: 'int | bytes', packet: 'dict[str, Any]') -> 'Stdli
Notes:
The registry is consulted through its constructor, which raises for
a value no member and no ``_missing_`` rule accounts for. That raise
is :mod:`aenum`'s own bare :exc:`ValueError`: not one of
is ``aenum``'s own bare :exc:`ValueError`: not one of
:mod:`pcapkit.utilities.exceptions`, so a caller cannot tell it from
a bug of its own, and not an :exc:`EOFError`, so
:meth:`Extractor.record_frames
Expand All @@ -719,19 +719,19 @@ def post_process(self, value: 'int | bytes', packet: 'dict[str, Any]') -> 'Stdli
``<unassigned>`` never takes -- and one an :class:`int`-keyed
dispatch registry looks up by value like any declared member. It is
built per value rather than grafted onto
the registry with :func:`aenum.extend_enum`, for two reasons: a
the registry with ``aenum.extend_enum``, for two reasons: a
capture carrying many distinct unassigned codes would otherwise grow
a process-global registry without bound, which is the growth
:meth:`ProtocolBase._lookup_registry
<pcapkit.protocols.protocol.ProtocolBase._lookup_registry>` exists
to avoid; and a stdlib :class:`enum.IntEnum` registry is then
handled exactly like an :class:`aenum.IntEnum` one.
handled exactly like an ``aenum.IntEnum`` one.

Only a *foreign* rejection is absorbed. A registry rejecting a value
with one of :mod:`pcapkit.utilities.exceptions` has made a
deliberate decision that this layer -- which sees only that the value
arrived in a field of some width -- is in no position to overrule, so
an in-library error propagates unchanged and it is only :mod:`aenum`'s
an in-library error propagates unchanged and it is only ``aenum``'s
and :mod:`enum`'s "no member has this value" that becomes a
pseudo-member. That is what keeps the fallback from being an
unconditional ``except ValueError: pass``.
Expand Down Expand Up @@ -761,7 +761,7 @@ def post_process(self, value: 'int | bytes', packet: 'dict[str, Any]') -> 'Stdli
.. versionchanged:: 1.5.0

A value the registry has no member for resolves to a nameless
pseudo-member, where :mod:`aenum`'s bare :exc:`ValueError` escaped
pseudo-member, where ``aenum``'s bare :exc:`ValueError` escaped
(:issue:`701`).

"""
Expand Down Expand Up @@ -798,7 +798,7 @@ def _pseudo_member(self, value: 'int') -> 'StdlibEnum | AenumEnum':

Returns:
A single-member, throwaway :class:`enum.IntEnum` instance, built
fresh per call rather than :func:`~aenum.extend_enum`-ed onto
fresh per call rather than ``aenum.extend_enum``-ed onto
``self._namespace``, per this method's own docstring above.

"""
Expand Down Expand Up @@ -828,15 +828,14 @@ def _unregistered_member(namespace: 'Type[StdlibEnum] | Type[AenumEnum]',
``cls.__members_ns__[...] = ...`` line every registry in this package
uses to record a member it mints. No entry is added to
``_member_map_`` or ``_value2member_map_`` either, since those are
only ever touched by the metaclass machinery :func:`aenum.extend_enum`
only ever touched by the metaclass machinery ``aenum.extend_enum``
drives, which this bypasses completely.

Note:
Building a member this way, rather than as some other type
altogether, is why :meth:`PortEnumField.post_process` and
:meth:`OptionEnumField.post_process
<pcapkit.protocols.schema.misc.pcapng.OptionEnumField.post_process>`
need this rather than :meth:`_pseudo_member`:
``OptionEnumField.post_process`` (in
:mod:`pcapkit.protocols.schema.misc.pcapng`) need this rather than :meth:`_pseudo_member`:
the result answers ``isinstance(result, AppType)`` truthfully,
which :meth:`PortEnumField.pre_process` tests before reading
``.port`` off it, and ``Transport._make_port`` in
Expand Down Expand Up @@ -1035,7 +1034,7 @@ class PortEnumField(EnumField):

Important:
This class is specifically designed for :class:`~pcapkit.const.reg.apptype.apptype.AppType`
as it is actually a :class:`~aenum.StrEnum` class.
as it is actually an ``aenum.StrEnum`` class.

.. versionadded:: 1.5.0

Expand Down
4 changes: 2 additions & 2 deletions pcapkit/corekit/infoclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -588,8 +588,8 @@ def items(self, multi: 'bool' = False) -> 'ItemsView[str, VT] | Iterator[tuple[s
Args:
multi: If set to :obj:`True`, an iterator with a pair for each value
of each key, as :meth:`to_dict` writes them. Otherwise a view of
the pairs of the first value of each key, as
:meth:`Mapping.items <collections.abc.Mapping.items>` returns.
the pairs of the first value of each key, as the ``items``
method of :class:`collections.abc.Mapping` returns.

"""
if not multi:
Expand Down
2 changes: 1 addition & 1 deletion pcapkit/corekit/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,7 @@ def __getattr__(self, name: 'str') -> 'Any':
class NamedStream:
"""Read-only proxy that gives a stream the ``name`` attribute.

:func:`pcapfile.savefile.load_savefile` dereferences ``input_file.name``
``pcapfile.savefile.load_savefile`` dereferences ``input_file.name``
unconditionally, on the way into its trace helper. That is fine for the
:class:`~io.BufferedReader` :class:`~pcapkit.foundation.extraction.Extractor`
normally holds, but not for the :class:`~pcapkit.corekit.io.SeekableReader`
Expand Down
2 changes: 1 addition & 1 deletion pcapkit/corekit/sentinels.py
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ def __bool__(self) -> 'Literal[False]':


#: AbsentType: Absent-versus-:obj:`None` sentinel for
#: :func:`pcapkit.protocols.protocol._declared_keywords` to read a class's
#: ``pcapkit.protocols.protocol._declared_keywords()`` to read a class's
#: own ``__keywords__`` out of its :attr:`~object.__dict__`, where
#: :obj:`None` is itself a meaningful value -- the opt-out that says the
#: class cannot enumerate its keywords, cf.
Expand Down
Loading
Loading