From f134b2d0fa74dff4319e57a8daeb2ce671c70f37 Mon Sep 17 00:00:00 2001 From: Jarry Shaw Date: Sun, 4 Oct 2026 18:41:45 -0400 Subject: [PATCH] docs(const): state what _missing_ actually does instead of claiming it mints `docs/source/pcapkit/const/index.rst` told the reader that an unregistered value inside a registry's valid range is minted into a permanent member via ``aenum.extend_enum``, and that a minted member's identity is stable for the life of the process. Measured, there are **four** behaviours across the 127 `EnumRegistry` subclasses, not one: - **1 installs a permanent member** -- `CGAType`, so `__members__` and iteration grow. - **5 cache a composed object in the value table only** -- `tcp.flags.Flags` and the four Mobility Header flag registries. They are `aenum.IntFlag` subclasses, so `super()._missing_` reaches `aenum.Flag._create_pseudo_member_`, which ends in `cls._value2member_map_.setdefault(value, pseudo_member)`. A second lookup therefore returns the **same** object, while `__members__` and iteration do not change. - **117 return an uninstalled object** -- nothing grows, and a second lookup gives an equal but distinct object. This is the common case the page now describes. - **4 raise for any unknown value** -- `Transport`, `ExtensionHeader`, `TLSKeyLabel`, and the memberless `AppType` base. So the old identity claim was true of six registries rather than one, and false of the other 121. The page now leads with the warning that a lookup does not raise, states the common case, and lists the exceptions, deferring the full split to `mint-criterion` by `:ref:`. "The mechanism is uniform because it is generated" is corrected: only the common form of the override is generated. Closes #1013. `tests/project`: 268 passed, 1 skipped, 864 subtests passed. --- docs/source/pcapkit/const/index.rst | 46 ++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/docs/source/pcapkit/const/index.rst b/docs/source/pcapkit/const/index.rst index 861721242..92c5a498d 100644 --- a/docs/source/pcapkit/const/index.rst +++ b/docs/source/pcapkit/const/index.rst @@ -11,24 +11,42 @@ automatically generated from the :mod:`pcapkit.vendor` module. Unrecognised Values ------------------- -Every enumeration 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 -the registry does not define does **not** raise. Each class overrides -``_missing_`` so that a value inside the registry's valid range is minted into a -new member on the fly -- via ``aenum.extend_enum``, named for the unassigned or -reserved band it falls in -- and returned. Only a value outside that range, or of -the wrong type, raises :exc:`ValueError`. +Nearly every 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`. + +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. +A handful behave otherwise, and :ref:`mint-criterion` gives the full split: + +* :class:`~pcapkit.const.mh.cga_type.CGAType` installs a permanent member, so + ``__members__`` and iteration grow. +* :class:`~pcapkit.const.tcp.flags.Flags` and the four Mobility Header flag + registries, such as + :class:`~pcapkit.const.mh.binding_ack_flag.BindingACKFlag`, hand back to + ``aenum``'s flag base, which caches the composed object in the value lookup + table only: a second lookup returns the same object, while ``__members__`` + and iteration are unchanged. +* :class:`~pcapkit.const.hip.transport.Transport`, + :class:`~pcapkit.const.ipv6.extension_header.ExtensionHeader`, + :class:`~pcapkit.const.pcapng.tls_key_label.TLSKeyLabel` and the memberless + :class:`~pcapkit.const.reg.apptype.apptype.AppType` base raise + :exc:`ValueError` for any unknown value. 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 -closed set: the identity of a minted member is stable for the life of the -process, but it does not exist until something asks for it. - -The mechanism is uniform because it is generated -- see -:mod:`pcapkit.vendor.default`, whose template emits the ``_missing_`` override -for every registry -- while the valid range and the names of the unassigned bands -are per-registry, taken from that registry's own IANA data. The individual +closed set: an unassigned value resolves to a member that is, apart from +``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 overrides are therefore not documented per class. .. seealso::