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
1 change: 0 additions & 1 deletion .github/python-versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
latest = "3.15"

[versions.cpython]
"3.7" = { tier = "ktlo", runner = "ubuntu-22.04" }
"3.8" = { tier = "ktlo", runner = "ubuntu-24.04" }
"3.9" = { tier = "ktlo", runner = "ubuntu-24.04" }
"3.10" = { tier = "ktlo" }
Expand Down
22 changes: 3 additions & 19 deletions .github/workflows/coverage-comment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -210,25 +210,9 @@ jobs:
# the step that failed. Matched on the title, not the message, which
# #2041 rewords. Anything else in these jobs, a failed tests step
# among it, still makes a green run `warning`.
EXPECTED = {
# #1633, #1672: no pytest>=8 for 3.7, so its KTLO legs stop at install.
'Python 3.7 (KTLO)': (
('WARNING', 'install failed on Python 3.7 (KTLO, non-blocking)'),
('FAILURE', ''),
('WARNING', 'pcapkit did not install on Python 3.7 (KTLO, non-blocking)'),
),
'Integration Python 3.7 (KTLO)': (
('WARNING', 'install failed on Python 3.7 (KTLO, non-blocking)'),
('FAILURE', ''),
('WARNING', 'pcapkit did not install on Python 3.7 (KTLO, non-blocking)'),
),
# #1633, #1672: pypy3.10's KTLO leg stops at install too, until #2040.
'Python pypy3.10 (KTLO)': (
('WARNING', 'install failed on Python pypy3.10 (KTLO, non-blocking)'),
('FAILURE', ''),
('WARNING', 'pcapkit did not install on Python pypy3.10 (KTLO, non-blocking)'),
),
}
# None today: the 3.7 legs that stopped at install went with #2051, and
# pypy3.10's installs since #2040's cryptography cap.
EXPECTED = {}

def expected(job, note):
"""Whether ``note``, an annotation of ``job``, is one :data:`EXPECTED` lists."""
Expand Down
10 changes: 6 additions & 4 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,12 @@ jobs:
# `vermin-ci`, not `vermin`: that target redirects the report into temp/,
# out of this log. Same flags, via $(VERMIN_FLAGS).
#
# Blocking needs a decision, not a cleanup, and not CI's: vermin.ini's
# `targets = 3.6` and `requires-python`'s `>=3.6, <4` both sit below the
# code's real floor, 3.11 (`enum.StrEnum`, `enum.show_flag_values`).
# Raising either belongs in its own change.
# Blocking needs a decision, not a cleanup, and not CI's. vermin.ini's
# `targets = 3.8` matches `requires-python` (#2051), but vermin still
# reports 3.11: `--no-parse-comments` ignores the `# novermin` markers on
# compat.py's version-gated imports (`enum.StrEnum`,
# `enum.show_flag_values`), and evaluated annotations put some
# `pcapkit.foundation` modules at 3.9.
- name: vermin
continue-on-error: true
run: |
Expand Down
11 changes: 5 additions & 6 deletions .github/workflows/python-compatibility.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,8 @@ jobs:
# 23497679's required contexts. A KTLO leg is suffixed ` (KTLO)`, so no
# required context can match it, and its steps carry `continue-on-error`,
# as in unit-tests.yml's `test` job: job-level, a failed leg's check run
# concluded `failure`, so every commit showed red (#1672). 3.7 fails "Verify
# package" by design. No 3.6: setup-python builds it only for retired
# Ubuntu images.
# concluded `failure`, so every commit showed red (#1672). Nothing below
# `requires-python`'s 3.8 runs (#2051).
name: Compat Python ${{ matrix.python-version }}${{ matrix.ktlo && ' (KTLO)' || '' }}
needs: [python-versions]
runs-on: ${{ matrix.os || 'ubuntu-latest' }}
Expand Down Expand Up @@ -87,9 +86,9 @@ jobs:
LEG: Python ${{ matrix.python-version }}${{ matrix.ktlo && ' (KTLO, non-blocking)' || '' }}
run: python util/pip_install.py -e .

# One annotation saying why, so a failed leg -- such as 3.7's, where the
# install succeeds and the sources do not compile -- is legible from the
# run summary; a warning on a KTLO leg (#1672). Each title escapes `,` as
# One annotation saying why, so a failed leg -- an install that succeeds
# with sources that do not compile -- is legible from the run summary; a
# warning on a KTLO leg (#1672). Each title escapes `,` as
# `%2C`: the runner splits a command's properties on `,`, so the KTLO
# title would stop at "(KTLO" (actions/runner
# src/Runner.Common/ActionCommand.cs:100, at 5f0b3ddcc).
Expand Down
12 changes: 5 additions & 7 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ jobs:
# PyPCAPFile is not here either: #751's `engine-tests` and
# `pypcap-parity` jobs cover its gated methods.
#
# #1633: a KTLO leg that cannot install -- such as 3.7 -- fails fast and
# once: util/pip_install.py writes one annotation naming pip's last ERROR
# #1633: a KTLO leg that cannot install fails fast and once:
# util/pip_install.py writes one annotation naming pip's last ERROR
# line, and every later step needs `steps.install.outcome == 'success'`,
# so it is skipped rather than failing against a missing package. The
# install needs its own interpreter: if setup-python failed, the image's
Expand Down Expand Up @@ -309,11 +309,9 @@ jobs:
# rest, so the Unit Tests run its `workflow_run` consumers read stays green.
#
# A version `ubuntu-latest` cannot provide carries its `runner` from the
# file as `os`: 3.8 and 3.9 need ubuntu-24.04, and 3.7 ubuntu-22.04, the
# newest image setup-python builds them for. 3.7 cannot install -- the `test`
# extra's `pytest>=8` needs 3.8 -- so the leg stops at its install step.
# ubuntu-22.04 is deprecated (actions/runner-images#14254); a brownout fails
# the leg before any step runs, which only the job-level guard contains.
# file as `os`: 3.8 and 3.9 need ubuntu-24.04, the newest image
# setup-python builds them for. A brownout of a deprecated image fails the
# leg before any step runs, which only the job-level guard contains.
test-ktlo:
name: Python ${{ matrix.python-version }} (KTLO)
if: ${{ inputs.gate-only != true && needs.changes.outputs.code != 'false' }}
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ This resolves [#548](https://github.com/JarryShaw/PyPCAPKit/issues/548), which r

- `pcapkit` no longer configures logging at import. It installs a `NullHandler` and sets no level, so verbosity is inherited from the application instead of being seized by whichever library was imported second; the old stderr handler stays as the `PCAPKIT_DEVMODE` opt-in. Consequences: the previous behaviour is `configure(logging.INFO, stream=sys.stderr)`; the registry and extractor `info` calls became `debug`, so those messages are invisible even at `INFO`; and the handler is no longer `logger.handlers[0]`. `verbose=` output stays on stdout and is not logging ([#384](https://github.com/JarryShaw/PyPCAPKit/pull/384)).
- each warning is reported once per channel, and `pcapkit` no longer inserts a `simplefilter('ignore', ...)` at the front of the process-global `warnings.filters` ([#362](https://github.com/JarryShaw/PyPCAPKit/issues/362)--[#364](https://github.com/JarryShaw/PyPCAPKit/issues/364), [#390](https://github.com/JarryShaw/PyPCAPKit/pull/390)). The application's own filter therefore wins, which is the point and also the sharp edge: under `-W error`, or pytest's `filterwarnings = error`, a pcapkit warning that used to be suppressed will raise. Suppress them deliberately with `warnings.filterwarnings('ignore', category=BaseWarning)`. `quiet=True` now means no record at any level and no longer sets `sys.tracebacklimit`, and the `pcapkit.utilities.warnings.DEVMODE` re-export is gone; its home is `pcapkit.utilities.logging`.
- `pcapkit.utilities.compat` exports `pathlib`, `ModuleNotFoundError`, `collections.abc.Collection` and `functools.cached_property()` as the standard library has them: their fallbacks for interpreters below 3.8 are removed with that floor ([#2051](https://github.com/JarryShaw/PyPCAPKit/issues/2051), [#2053](https://github.com/JarryShaw/PyPCAPKit/pull/2053)).

#### Fixed

Expand Down Expand Up @@ -397,6 +398,7 @@ This resolves [#548](https://github.com/JarryShaw/PyPCAPKit/issues/548), which r

#### Changed

- **a breaking change to** `requires-python`: it is `>=3.8`, so pip refuses an older interpreter at install, as "requires a different Python". The sources use 3.8 syntax, and the `bpc-*` backport tools that converted it for 3.6 and 3.7 are no longer maintained, so the conversion goes: the `bpc-*` requirements, `refactor()` and the `setup.py` build commands that ran it. The 3.7 KTLO (*keep the lights on*) legs go with it, and `coverage-comment.yml` lists no install failure as by design any more, which closes [#2040](https://github.com/JarryShaw/PyPCAPKit/issues/2040) ([#2051](https://github.com/JarryShaw/PyPCAPKit/issues/2051), [#2053](https://github.com/JarryShaw/PyPCAPKit/pull/2053)).
- renames with no compatibility alias left behind: `examples/sample` and `examples/samples` -- one letter apart, holding different things -- are now `examples/captures` and `examples/generators`.
- the README is a landing page now, and Markdown rather than reStructuredText. `README.rst` became a much shorter `README.md`, keeping what a reader arriving from PyPI or a search result needs (what the library is, why it exists rather than Scapy or DPKT, how to install it, a worked example, where the documentation lives). **Module Structure**, **Engine Comparison**, **Engine support by Python version**, **Test Environment**, **Test Results** and **Installation Notes** were already duplicated in fuller form in `docs/source/index.rst`, so they are linked rather than restated; the blocks that existed nowhere else moved: **Testing** is now `docs/source/contributing/testing.rst`, and the `pipenv` and `make setup` block joined the Installation section of `docs/source/index.rst`. Requested by the project owner, and a deliberate exception to the reStructuredText convention, for the README only, since its renderers are GitHub and PyPI rather than Sphinx. `setup.py` reads `README.md` and declares `text/markdown`, and `MANIFEST.in` gains `include README.md`, which is belt-and-braces rather than load-bearing: setuptools' `sdist` ships a `README.md` regardless. Of the `include` lines only `CHANGELOG.md` is load-bearing, measured in the [#631](https://github.com/JarryShaw/PyPCAPKit/pull/631) entry below. `examples/benchmark/Dockerfile` copies `README.md`, while the `README.md` that `examples/benchmark/benchmark.py` names is the benchmark suite's own ([#619](https://github.com/JarryShaw/PyPCAPKit/pull/619)).
- `CODE_OF_CONDUCT.md` moves from Contributor Covenant 1.4 to 3.0, at the owner's request. The text is the canonical 3.0 Markdown fetched from https://www.contributor-covenant.org/version/3/0/code_of_conduct/code_of_conduct.md rather than transcribed. Some things needed deciding. 3.0's `[NOTE` placeholders are filled or removed: the reporting channel names `jarryshaw@icloud.com` (the contact 1.4 carried and `SECURITY.md` uses as email fallback) plus GitHub's report-abuse form for a report about the maintainer, which a single-maintainer project cannot otherwise cover; the enforcement placeholder is an instruction to the adopter and is removed. 3.0's plural "Community Moderators" become the singular maintainer, this repository having no moderators. The enforcement ladder (Warning, Temporarily Limited Activities, Temporary Suspension, Permanent Ban) is a suggestion and is **kept**, each rung mapping to a lever one person holds on GitHub. 3.0 is CC BY-SA 4.0 where 1.4 carried no licence notice, so the attribution names version 3.0, links the permanent `version/3/0/` URL, carries the CC BY-SA 4.0 notice, indicates changes were made as BY requires, and says the share-alike term covers this document only (the code remains BSD-3-Clause, `LICENSE` untouched). The ladder renders as nested list items, checked against GitHub's Markdown API; [#613](https://github.com/JarryShaw/PyPCAPKit/pull/613) had to repair the 1.4 file when a stray list marker collapsed it into one nested item ([#624](https://github.com/JarryShaw/PyPCAPKit/pull/624)).
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ rewrites the regenerated constants, not as a check, so nothing verifies import o
request.

One trap: `make vermin` redirects its report into `temp/vermin.txt` rather than to your terminal,
and vermin exits 1 because `vermin.ini` sets `targets = 3.6` against the 3.11 minimum it detects.
and vermin exits 1 because `vermin.ini` sets `targets = 3.8` against the 3.11 minimum it detects.
Make gives up at the redirect with `make: *** [vermin] Error 1`, the report left in the file and the line
that would have opened it never reached. `make vermin-ci` runs the same flags to stdout, which is why
CI uses it and why it is easier to read at a desk. Running the lot before you push still saves a
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,8 @@ vermin:
# Make at the redirect, with the report left unread in the file and the line
# that would have opened it never reached -- useless as a log.
# This one writes to stdout and lets vermin's failure propagate, which is what
# `targets = 3.6` in vermin.ini is for: vermin exits non-zero when the target is
# not met, and the code's real floor is 3.11.
# `targets = 3.8` in vermin.ini is for: vermin exits non-zero when the target is
# not met, and it detects 3.11.
vermin-ci:
$(RUN) vermin pcapkit $(VERMIN_FLAGS) pcapkit

Expand Down
4 changes: 2 additions & 2 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ tbtrim = "~=0.3.1"
pypcapkit = {editable = true,path = "."}
pyshark = "*"
dpkt = "*"
# The floor and marker match the Scapy extra in pyproject.toml (#1572).
scapy = {version = ">=2.6.0",markers = "python_version >= '3.7'"}
# The floor matches the Scapy extra in pyproject.toml (#1572).
scapy = ">=2.6.0"
cryptography = "*"
# NB: ``pypcap`` is deliberately absent. It builds a C extension against
# libpcap, so listing it here would break ``pipenv install --dev`` -- and even
Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ Unlike popular PCAP extractors such as [Scapy](https://scapy.net),
Where that depth is not needed, the same interface also drives third-party extraction
engines.

The whole project declares **Python 3.6** or later. CI supports 3.11 to 3.15, and
still tests the end-of-life 3.7 to 3.10 without letting a failure block anything;
3.7 cannot import the package yet.
The whole project requires **Python 3.8** or later. CI supports 3.11 to 3.15, and
still tests the end-of-life 3.8 to 3.10 without letting a failure block anything.

## Installation

Expand Down
8 changes: 3 additions & 5 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ lines are not patched -- upgrading is the fix.
| 0.x | :x: | no longer patched |

Supported interpreters are the test matrix's blocking tier: CPython 3.11
through 3.15. `pyproject.toml` declares `requires-python = ">=3.6, <4"` through the
`bpc-*` source conversion, but 3.7 to 3.10 are best-effort (tested, never blocking)
and below 3.8 is intent rather than something that works -- see the note above
`requires-python` in `pyproject.toml`. A report that only reproduces outside the tested range is still
welcome; it may be fixed by raising the floor rather than by patching.
through 3.15. `pyproject.toml` declares `requires-python = ">=3.8"`, but 3.8 to 3.10 are
best-effort (tested, never blocking). A report that only reproduces outside the tested range is
still welcome; it may be fixed by raising the floor rather than by patching.

## Reporting a Vulnerability

Expand Down
13 changes: 0 additions & 13 deletions conda/pypcapkit/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,12 @@ requirements:
- pip
- setuptools>=62.3.0

# # version compatibility
# - bpc-f2format
# - bpc-poseur
# - bpc-walrus

# - dictdumper~=0.8.0 # for formatted output
# - chardet # for bytes decode
# - aenum # for const types
# - tbtrim>=0.2.1 # for refined exceptions

# # version compatibility
# - pathlib2>=2.3.2
# - typing-extensions

# - emoji
Expand All @@ -51,18 +45,12 @@ requirements:
- pip
- setuptools>=62.3.0

# # version compatibility
# - bpc-f2format
# - bpc-poseur
# - bpc-walrus

# - dictdumper~=0.8.0 # for formatted output
# - chardet # for bytes decode
# - aenum # for const types
# - tbtrim>=0.2.1 # for refined exceptions

# # version compatibility
# - pathlib2>=2.3.2
# - typing-extensions

# - emoji
Expand All @@ -80,7 +68,6 @@ requirements:
# - tbtrim>=0.2.1 # for refined exceptions

# # version compatibility
# - pathlib2>=2.3.2
# - typing-extensions

# - emoji
Expand Down
12 changes: 12 additions & 0 deletions docs/source/changelog/1.5.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2741,6 +2741,10 @@ Changed
means no record at any level and no longer sets ``sys.tracebacklimit``, and the
``pcapkit.utilities.warnings.DEVMODE`` re-export is gone; its home is
:mod:`pcapkit.utilities.logging`.
* :mod:`pcapkit.utilities.compat` exports :mod:`pathlib`, :exc:`ModuleNotFoundError`,
:class:`collections.abc.Collection` and :func:`functools.cached_property` as the
standard library has them: their fallbacks for interpreters below 3.8 are removed
with that floor (:issue:`2051`, :pr:`2053`).

Fixed
~~~~~
Expand Down Expand Up @@ -2951,6 +2955,14 @@ Added
Changed
~~~~~~~

* **a breaking change to** ``requires-python``: it is ``>=3.8``, so pip refuses an
older interpreter at install, as "requires a different Python". The sources use 3.8
syntax, and the ``bpc-*`` backport tools that converted it for 3.6 and 3.7 are no
longer maintained, so the conversion goes: the ``bpc-*`` requirements,
``refactor()`` and the ``setup.py`` build commands that ran it. The 3.7 KTLO (*keep
the lights on*) legs go with it, and ``coverage-comment.yml`` lists no install
failure as by design any more, which closes :issue:`2040` (:issue:`2051`,
:pr:`2053`).
* renames with no compatibility alias left behind: ``examples/sample`` and
``examples/samples`` -- one letter apart, holding different things -- are now
``examples/captures`` and ``examples/generators``.
Expand Down
4 changes: 1 addition & 3 deletions docs/source/contributing/conventions/documentation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,6 @@ Format and Mechanics
:ref:`sentinel-convention`'s table names it rather than any of the modules that
use them, which do not re-export them (:issue:`1744`).
* **A verbatim upstream port is exempt from these conventions.**
:ref:`sentinel-convention` already carries the case that settled it, the
:class:`~pcapkit.utilities.compat.cached_property` backport in
:file:`pcapkit/utilities/compat.py`: the value of a
:ref:`sentinel-convention` carries the reason: the value of a
vendored copy is that it can still be diffed against upstream, and a house-style
rewrite destroys that in exchange for nothing a reader ever sees.
15 changes: 7 additions & 8 deletions docs/source/contributing/conventions/sentinel-convention.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,13 @@ appears in a signature, in :func:`help` output and in a traceback. Compare what
identity ``__eq__`` and is exactly as safe as ``object()``. That argument appeared
in an early draft of :mod:`pcapkit.corekit.enum` and was wrong.

**Ported code is exempt.** ``_NOT_FOUND = object()`` at
:file:`pcapkit/utilities/compat.py`, line 73, sits inside the
:class:`~pcapkit.utilities.compat.cached_property`
backport taken for interpreters below 3.8, which tracks CPython's own
:mod:`functools` implementation down to that name. It is **not** to be converted: the
value of a vendored backport is that it can still be diffed against upstream, and a
house-style rewrite destroys that in exchange for a sentinel nobody outside the backport
ever sees. The rule above is for sentinels this package writes itself.
**Ported code is exempt.** A verbatim upstream port keeps its upstream's sentinels
as written: the value of a vendored copy is that it can still be diffed against
upstream, and a house-style rewrite destroys that in exchange for a sentinel nobody
outside the port ever sees. The rule above is for sentinels this package writes
itself. The case that settled it, ``_NOT_FOUND = object()`` in the
:class:`~pcapkit.utilities.compat.cached_property` backport for interpreters below
3.8, went with that backport when 1.5.0 raised the floor to 3.8 (:issue:`2051`).

Per-Sentinel Dunder Methods
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
Loading
Loading