diff --git a/docs/source/pcapkit/utilities/exceptions.rst b/docs/source/pcapkit/utilities/exceptions.rst index a3cf222a22..c4cbe8875d 100644 --- a/docs/source/pcapkit/utilities/exceptions.rst +++ b/docs/source/pcapkit/utilities/exceptions.rst @@ -3,9 +3,9 @@ User Defined Exceptions .. module:: pcapkit.utilities.exceptions -:mod:`pcapkit.utilities.exceptions` refined built-in exceptions. -Make it possible to show only user error stack information [*]_, -when exception raised on user's operation. +:mod:`pcapkit.utilities.exceptions` holds refined built-in exceptions, +which make it possible to show only user error stack information [*]_ +when an exception is raised on user's operation. Loud and Quiet Errors --------------------- diff --git a/docs/source/pcapkit/utilities/warnings.rst b/docs/source/pcapkit/utilities/warnings.rst index be37430db3..ebca95270b 100644 --- a/docs/source/pcapkit/utilities/warnings.rst +++ b/docs/source/pcapkit/utilities/warnings.rst @@ -3,7 +3,7 @@ User Defined Warnings .. module:: pcapkit.utilities.warnings -:mod:`pcapkit.utilities.warnings` refined built-in warnings. +:mod:`pcapkit.utilities.warnings` holds refined built-in warnings. .. versionremoved:: 1.5.0 diff --git a/pcapkit/foundation/engines/dpkt.py b/pcapkit/foundation/engines/dpkt.py index 2f5fcfe71a..a95e04ae02 100644 --- a/pcapkit/foundation/engines/dpkt.py +++ b/pcapkit/foundation/engines/dpkt.py @@ -206,9 +206,9 @@ def _read_packet(self, buf: 'bytes', block_type: 'int', Returns: Timestamp in seconds since the UNIX epoch, and the packet data. The - timestamp is a :class:`~pcapkit.toolkit.dpkt.Timestamp`: the - :obj:`float` this reader always yielded, which also carries the exact - value, the interface's resolution and the packet's original length, + timestamp is a :class:`~pcapkit.toolkit.dpkt.Timestamp`: a + :obj:`float` that also carries the exact value, the interface's + resolution and the packet's original length, for the PCAP frame record of the packet (:issue:`1507`). Raises: diff --git a/pcapkit/foundation/engines/pcap_ct.py b/pcapkit/foundation/engines/pcap_ct.py index dbbc2782fa..e221a41911 100644 --- a/pcapkit/foundation/engines/pcap_ct.py +++ b/pcapkit/foundation/engines/pcap_ct.py @@ -55,8 +55,8 @@ class PCAP_CT(EngineBase['RawFrame']): apart, and :doc:`the engine documentation ` for which one to install. - It exists because upstream `PyPCAP`_ cannot be installed on a current - interpreter: it ships no wheels and its ``pcap.c`` was pre-generated by + It exists because upstream `PyPCAP`_ cannot be installed on Python 3.12 or + newer: it ships no wheels and its ``pcap.c`` was pre-generated by Cython 0.29.32, which does not compile against the Python 3.12+ C API. `pcap-ct`_ and `libpcap`_ both publish ``py3-none-any`` wheels, so **installing** this engine needs no compiler and no ``pcap.h``. diff --git a/pcapkit/foundation/engines/scapy.py b/pcapkit/foundation/engines/scapy.py index 59f1492896..e6571b7f05 100644 --- a/pcapkit/foundation/engines/scapy.py +++ b/pcapkit/foundation/engines/scapy.py @@ -128,7 +128,7 @@ def _reader_type() -> 'Type[PcapReader]': PCAP-NG specification defines a section: an interface ID counts the Interface Description Blocks of its own section only. `Scapy`_'s reader keeps appending to one table across Section Header Blocks, so a later section's interface 0 - resolved to the first section's, with its link type and resolution (:issue:`1522`). + resolves to the first section's, with its link type and resolution (:issue:`1522`). And it dates packets that `Scapy`_ misdates. A Simple Packet Block has no timestamp, and `Scapy`_ leaves its packet with the time it was @@ -182,7 +182,7 @@ def close(self) -> 'None': class _Uncapped(PcapReader): # ``sniff`` calls ``recv()``, and Scapy's default ``size`` of ``MTU`` - # cut every record to 65,535 octets (#1717); an explicit one is kept + # cuts every record to 65,535 octets (#1717); an explicit one is kept def recv(self, size: 'int' = _CAPLEN_MAX, **kwargs: 'Any') -> 'ScapyPacket': # type: ignore[override] return super().recv(size, **kwargs) diff --git a/pcapkit/foundation/extraction.py b/pcapkit/foundation/extraction.py index 2a7e09c8f0..8e1922c477 100644 --- a/pcapkit/foundation/extraction.py +++ b/pcapkit/foundation/extraction.py @@ -1114,7 +1114,7 @@ def _open_output(self, **kwargs: 'Any') -> 'None': The built-in engines call this at their global-header step. The PCAP engine passes the header's fields as ``protocol``, ``byteorder``, - ``nanosecond``, ``thiszone``, ``sigfigs`` and ``snaplen``: + ``nanosecond``, ``version``, ``thiszone``, ``sigfigs`` and ``snaplen``: :class:`~pcapkit.dumpkit.pcap.PCAPIO` writes its own global header from them, and the other writers ignore them. The PCAP-NG engine passes none. :meth:`run` calls it again, without arguments, after the engine has @@ -1621,7 +1621,7 @@ def __exit__(self, exc_type: 'Type[BaseException] | None', exc_value: 'BaseExcep class owns it* -- the rule of :issue:`610`, as :meth:`_owns_input` writes it down and :meth:`_cleanup` and the backstops already follow. A stream the caller supplied stays open for the caller to close, so leaving the - block no longer closes it behind the caller's back (:issue:`1999`). + block does not close it behind the caller's back (:issue:`1999`). For a caller's non-seekable stream, the stream this class owns is the :class:`~pcapkit.corekit.io.SeekableReader` wrapped around it, and that @@ -1776,10 +1776,10 @@ def _note_eof_progress(self) -> 'bool': being appended to ends at the data present when it got there, rather than following the writer. That is a deliberate narrowing, and it is measured: a file gaining its last record 0.6s in yields five of its six frames here, - where the unbounded retry of ``6c3d1b0d9`` yielded all six. Unbounded - retrying is the defect :issue:`620` reports, so *some* stopping rule had - to be chosen, and a timed grace period would only make the cut-off - intermittent rather than absent. + where an unbounded retry yields all six. Unbounded retrying is the defect + :issue:`620` reports, so *some* stopping rule had to be chosen, and a + timed grace period would only make the cut-off intermittent rather than + absent. Following a growing file wants a deliberate policy of its own; see the note in :file:`docs/source/changelog/1.5.0.rst`. diff --git a/pcapkit/foundation/reassembly/ip.py b/pcapkit/foundation/reassembly/ip.py index eb89c9eefe..4a148f70f1 100644 --- a/pcapkit/foundation/reassembly/ip.py +++ b/pcapkit/foundation/reassembly/ip.py @@ -160,8 +160,8 @@ def reassembly(self, info: 'Packet[_AT]') -> 'None': # initialise buffer with BUFID; ``RCVBT`` holds one entry per 8-octet # block of the data buffer, its partial last block included -- 8191 - # covered octets 0 to 65527 only, so a fragment reaching octet 65528, - # e.g. at the largest Fragment Offset, indexed past it (#1565) + # would cover octets 0 to 65527 only, so a fragment reaching octet 65528, + # e.g. at the largest Fragment Offset, would index past it (#1565) if BUFID not in self._buffer: self._buffer[BUFID] = Buffer( TDL=-1, # Total Data Length diff --git a/pcapkit/foundation/reassembly/ipv4.py b/pcapkit/foundation/reassembly/ipv4.py index 3d11aa74a8..9161baae88 100644 --- a/pcapkit/foundation/reassembly/ipv4.py +++ b/pcapkit/foundation/reassembly/ipv4.py @@ -70,8 +70,8 @@ class IPv4(IP): #: up to the 4.25-minute TTL ceiling, not a 15-second deadline. It is ruled #: out here: the recommendation is superseded, and TTL is not in #: :class:`~pcapkit.foundation.reassembly.data.ip.Packet` at all, so the - #: fragment model would have to grow a field to express a scheme the current - #: requirement asks implementations not to use. + #: fragment model would have to grow a field to express a scheme RFC 1122 + #: asks implementations not to use. #: #: 60 seconds is the low end of RFC 1122's range, and it makes IPv4 agree #: with the 60 seconds :rfc:`8200#section-4.5` mandates for IPv6 -- so one diff --git a/pcapkit/foundation/reassembly/reassembly.py b/pcapkit/foundation/reassembly/reassembly.py index 24f497166a..1a7d49d107 100644 --- a/pcapkit/foundation/reassembly/reassembly.py +++ b/pcapkit/foundation/reassembly/reassembly.py @@ -21,8 +21,8 @@ from pcapkit.utilities.logging import get_logger # NB: declared above the ``TYPE_CHECKING`` block, not below it, so that -# ``CallbackFn`` can name ``_DT`` outright. As a quoted forward reference it was -# resolvable only from this module's namespace, and every module that spells +# ``CallbackFn`` can name ``_DT`` outright. As a quoted forward reference it would +# resolve only from this module's namespace, and every module that spells # ``CallbackFn`` in an annotation -- ``pcapkit.foundation.registry.foundation`` # does -- has to evaluate the alias in its own. # packet diff --git a/pcapkit/foundation/reassembly/tcp.py b/pcapkit/foundation/reassembly/tcp.py index 7adf3f71c4..97cbb11f97 100644 --- a/pcapkit/foundation/reassembly/tcp.py +++ b/pcapkit/foundation/reassembly/tcp.py @@ -733,7 +733,7 @@ def submit(self, buf: 'Buffer', *, bufid: 'BufferID', # type: ignore[override] # if this buffer is complete -- or if it is not, and ``strict`` # asked for one contiguous payload rather than the received runs # - # NOTE: ``strict=False`` deliberately keeps reporting the whole + # NOTE: ``strict=False`` deliberately reports the whole # payload buffer with its holes zero-filled, which is what # :func:`~pcapkit.interface.misc.follow_tcp_stream` wants of a stream # it is reconstructing best-effort. ``completed`` says so, rather than diff --git a/pcapkit/foundation/registry/foundation.py b/pcapkit/foundation/registry/foundation.py index 881721e2d2..97e8020976 100644 --- a/pcapkit/foundation/registry/foundation.py +++ b/pcapkit/foundation/registry/foundation.py @@ -118,7 +118,7 @@ def register_dumper(format: 'str', module: 'ModuleDescriptor[Dumper] | Type[Dump The function will register the given dumper class to the :data:`pcapkit.foundation.traceflow.traceflow.TraceFlow.__output__` and - :data:`pcapkit.foundation.extraction.Extractor.__output__` registry. + :data:`pcapkit.foundation.extraction.Extractor.__output__` registries. Arguments: format: format name diff --git a/pcapkit/foundation/traceflow/tcp.py b/pcapkit/foundation/traceflow/tcp.py index 3d78846cec..6a2553fafb 100644 --- a/pcapkit/foundation/traceflow/tcp.py +++ b/pcapkit/foundation/traceflow/tcp.py @@ -129,7 +129,7 @@ class TCP(TraceFlowBase[BufferID, Buffer[_AT], Index, Packet[_AT]], Generic[_AT] It is **off by default** because buffering every traced payload is a cost tracing does not otherwise pay, and tracing's per-packet cost is something - this package has deliberately driven down. Nothing is reassembled, parsed + this package deliberately keeps low. Nothing is reassembled, parsed or retained unless it is asked for. """ @@ -255,8 +255,8 @@ def trace(self, packet: 'Packet[_AT]', *, output: 'bool' = False) -> 'Dumper | s # A SYN arriving on a flow whose teardown has already been observed is a # *new* connection reusing the endpoints, and the only signal that proves # the previous one can receive nothing further. It is what finalises a - # bidirectional flow mid-capture; everything else is flushed by - # :meth:`submit` at the end of the capture. + # bidirectional flow mid-capture; everything else is finalised by + # :meth:`finish` at the end of the capture. # # The state test matters. A SYN alone does not mean "new connection" -- # the peer's SYN-ACK carries the flag too, and it belongs to the flow the @@ -465,10 +465,11 @@ def _finalise(self, bufid: 'BufferID') -> 'Index': Returns: The flow's :term:`index ` entry. - Called once per flow, from the one place that can prove a flow is over -- - a new connection superseding it, or :meth:`submit` at the end of the - capture. Registering the flow here rather than at teardown is what keeps - the acknowledgement that completes a close inside the flow it belongs to. + Called once per flow, from where a flow can be proved over -- a new + connection superseding it, or :meth:`finish` at the end of the capture -- + or, tracing unidirectionally, on that direction's FIN. Registering a + bidirectional flow here rather than at teardown is what keeps the + acknowledgement that completes a close inside the flow it belongs to. """ buf = self._buffer.pop(bufid) diff --git a/pcapkit/foundation/traceflow/traceflow.py b/pcapkit/foundation/traceflow/traceflow.py index 7bcd259ac6..ed43aa60fa 100644 --- a/pcapkit/foundation/traceflow/traceflow.py +++ b/pcapkit/foundation/traceflow/traceflow.py @@ -34,8 +34,8 @@ logger = get_logger(__name__) # NB: declared above the ``TYPE_CHECKING`` block, not below it, so that -# ``CallbackFn`` can name ``_IT`` outright. As a quoted forward reference it was -# resolvable only from this module's namespace, and every module that spells +# ``CallbackFn`` can name ``_IT`` outright. As a quoted forward reference it would +# resolve only from this module's namespace, and every module that spells # ``CallbackFn`` in an annotation -- ``pcapkit.foundation.registry.foundation`` # does -- has to evaluate the alias in its own. _DT = TypeVar('_DT') diff --git a/pcapkit/interface/misc.py b/pcapkit/interface/misc.py index a66de11322..ef23f37ecc 100644 --- a/pcapkit/interface/misc.py +++ b/pcapkit/interface/misc.py @@ -98,7 +98,7 @@ def follow_tcp_stream(fin: 'Optional[str]' = None, verbose: 'bool' = False, as one stream, which is the default -- a stream then holds the frames and the reassembled payload of *both* directions, which is what "following a TCP stream" means elsewhere. :data:`False` - restores one stream per direction. + gives one stream per direction. trace_analyse: whether each traced flow reassembles its application layer, so that :attr:`Index.packet ` can be read off :attr:`Extractor.trace `. diff --git a/pcapkit/toolkit/dpkt.py b/pcapkit/toolkit/dpkt.py index bc9eced492..1a4a4e24cf 100644 --- a/pcapkit/toolkit/dpkt.py +++ b/pcapkit/toolkit/dpkt.py @@ -76,7 +76,7 @@ class RecordTimestamp: resolution and its original length would be lost between the reader and :func:`packet2frame`. The engine's readers yield a :class:`Timestamp` or a :class:`DecimalTimestamp` instead, which *is* the value `DPKT`_ yields -- - so a stored frame's timestamp is exactly what it was before -- and also + so a stored frame's timestamp is unchanged by it -- and also carries what would otherwise be lost. Reassembly and flow tracing are handed a plain :obj:`float` of it (:issue:`1501`): of its exact value, since `DPKT`_'s own for a microsecond PCAP rounds twice (:issue:`1668`; see @@ -303,8 +303,9 @@ def packet2frame(packet: 'Packet', timestamp: 'float | Decimal', *, ts_sec = int(epoch) ts_usec = int((epoch - ts_sec) * RESOLUTION[resolution > RESOLUTION[False]]) - # the mapping is exactly the one reported before #1507, plain value types - # included, so that the dict-capable trace formats write the same bytes + # the mapping carries plain value types rather than the timestamp subclasses, + # so that the dict-capable trace formats write the same bytes as for a plain + # timestamp (#1507) if isinstance(timestamp, float): timestamp = float(timestamp) elif isinstance(timestamp, decimal.Decimal): @@ -725,8 +726,8 @@ def _tcp_flags(tcp: 'TCP') -> 'tuple[bool, bool, bool]': Each flag is masked out of :attr:`dpkt.tcp.TCP.flags` by its ``TH_*`` value, so it is read from the flags octet alone. `DPKT`_ 1.9.8 makes that field nine bits wide, its top bit the NS bit (:rfc:`3540`): read by - its position among the field's binary digits, every flag was one bit low - with NS set, a SYN reading as a FIN (:issue:`1618`). + its position among the field's binary digits, every flag would be one bit + low with NS set, a SYN reading as a FIN (:issue:`1618`). """ from dpkt.tcp import TH_FIN, TH_RST, TH_SYN # isort:skip diff --git a/pcapkit/toolkit/pyshark.py b/pcapkit/toolkit/pyshark.py index 4e609afb59..09e7519f9e 100644 --- a/pcapkit/toolkit/pyshark.py +++ b/pcapkit/toolkit/pyshark.py @@ -319,7 +319,7 @@ #: PyShark's text for a boolean field -> its value. tshark 4.x spells one ``'True'``/``'False'`` #: (measured for ``tcp.flags_syn``, ``tcp.flags_fin`` and ``tcp.flags_reset`` with PyShark 0.6 -#: on tshark 4.6.9); ``'1'``/``'0'`` is the spelling this module first parsed (:issue:`1514`). +#: on tshark 4.6.9); ``'1'``/``'0'`` is accepted as well (:issue:`1514`). _BOOLEAN_FIELD = {'1': True, '0': False, 'True': True, 'False': False} # type: dict[str, bool] @@ -518,8 +518,8 @@ def _has_addresses(ip: 'Any') -> 'bool': Note: tshark reports no ``ip.dst`` behind an LSRR or SSRR option whose route data is no whole number of addresses ("Suboption would go past end of - option"), measured with tshark 4.6.9. Reading it raised a bare - :exc:`AttributeError` out of :func:`tcp_traceflow`, which ended the + option"), measured with tshark 4.6.9. Reading it unchecked raises a bare + :exc:`AttributeError` out of :func:`tcp_traceflow`, which would end the extraction (:issue:`1671`). """ diff --git a/pcapkit/utilities/compat.py b/pcapkit/utilities/compat.py index f501c73111..b2b76c093d 100644 --- a/pcapkit/utilities/compat.py +++ b/pcapkit/utilities/compat.py @@ -33,7 +33,8 @@ # ``_common`` binds a ``NoneType`` of its own only on a ``NameError``, so there it # binds none, and the ``from ._common import *`` in aenum's ``__init__`` fails on # the name ``__all__`` lists: ``AttributeError: module 'aenum._common' has no -# attribute 'NoneType'``. That left pcapkit unimportable on PyPy 8.0 (#1958). +# attribute 'NoneType'``. Unhandled, that leaves pcapkit unimportable on PyPy 8.0 +# (#1958). # ``aenum._common`` itself ran to its end and stays in :data:`sys.modules`, so # binding the name there and importing aenum again completes it, leaving # :mod:`builtins` as PyPy has it. This module runs before any of pcapkit's that diff --git a/pcapkit/utilities/datetime.py b/pcapkit/utilities/datetime.py index 7f44c93c63..1efade3a33 100644 --- a/pcapkit/utilities/datetime.py +++ b/pcapkit/utilities/datetime.py @@ -56,7 +56,7 @@ # December 31, 1969, UTC, gives ``0.5``, not ``-0.5`` (#2134, measured on # GraalPy 25.4.4). ``TimestampNode`` takes ``ChronoUnit.SECONDS.between`` of the # epoch and the instant, which truncates (graalpython, DateTimeBuiltins.java, at -# graal-25.4.4; no upstream issue is filed yet). CPython and PyPy compute +# graal-25.4.4, with no upstream issue filed). CPython and PyPy compute # ``(dt - epoch).total_seconds()`` for an aware datetime, which is right, so # there :func:`totimestamp` is the stdlib call itself. _TIMESTAMP_TRUNCATES = sys.implementation.name == 'graalpy' diff --git a/pcapkit/utilities/exceptions.py b/pcapkit/utilities/exceptions.py index 24b45680fa..5d4f99c5b5 100644 --- a/pcapkit/utilities/exceptions.py +++ b/pcapkit/utilities/exceptions.py @@ -4,9 +4,9 @@ .. module:: pcapkit.utilities.exceptions -:mod:`pcapkit.utilities.exceptions` refined built-in exceptions. -Make it possible to show only user error stack information [*]_, -when exception raised on user's operation. +:mod:`pcapkit.utilities.exceptions` holds refined built-in exceptions, +which make it possible to show only user error stack information [*]_ +when an exception is raised on user's operation. .. [*] See |tbtrim|_ project for Pythonic implementation. @@ -388,7 +388,7 @@ def _excepthook(etype: 'Type[BaseException]', value: 'BaseException', # A generic, external marker -- "some pcapkit instance's hook is active" -- for # a caller that only has :func:`sys.excepthook` and no reference to a particular # loaded copy of this module. Diagnostic only: :func:`_install_excepthook`'s own -# guard below does *not* use this, and must not go back to doing so. The marker +# guard below does *not* use this, and must not. The marker # is a plain :obj:`True`, identical on every reloaded copy of this function, so # it cannot tell "my own instance's hook" from "some *other* instance's" -- # which is exactly the distinction the guard needs and a shared value cannot @@ -748,9 +748,9 @@ class StreamEOFError(BaseError, EOFError): of a schema's read was derived by measuring what is actually left in the stream -- rather than declared by the caller -- and that measurement came back zero. This is the frame reader's "no more packets" signal, so it - subclasses :exc:`EOFError` rather than replacing it: existing ``except - (EOFError, StopIteration)`` handlers keep working unchanged, and a caller - that wants to be more specific can catch this instead. + subclasses :exc:`EOFError` rather than replacing it: an ``except + (EOFError, StopIteration)`` handler catches it, and a caller that wants to + be more specific can catch this instead. A *declared* zero length -- a nested schema legitimately sized to have nothing to read -- is a different situation and does not raise this. @@ -805,8 +805,8 @@ class EnumKeyError(BaseError, KeyError): the in-library call sites catch :meth:`~pcapkit.corekit.enum.EnumLookup.get`'s name miss as :exc:`KeyError` -- :class:`~pcapkit.const.http.method.Method`'s ``get`` catches it in order to build an unregistered member, so for that one - a failed name lookup is part of a successful call -- and every one of them - keeps catching. + a failed name lookup is part of a successful call -- so every one of them + catches this as well. Note: Distinct from :exc:`~pcapkit.utilities.exceptions.MissingKeyError`, diff --git a/pcapkit/utilities/warnings.py b/pcapkit/utilities/warnings.py index 1364fd812b..1ce2333b1a 100644 --- a/pcapkit/utilities/warnings.py +++ b/pcapkit/utilities/warnings.py @@ -4,7 +4,7 @@ .. module:: pcapkit.utilities.warnings -:mod:`pcapkit.utilities.warnings` refined built-in warnings. +:mod:`pcapkit.utilities.warnings` holds refined built-in warnings. Every warning :mod:`pcapkit` reports goes through :func:`warn`, which reports it **exactly once on each channel**: