docs(readme): trim to a landing page and convert to Markdown - #619
Conversation
fa4ebcf to
2af2300
Compare
|
✅ GOOD TO MERGE — head |
Cross-review appendix — PR #619Reviewer: Sonnet; PR authored on Opus 5. Reviewed at head Acceptance test — built it and ran
|
| with it. When that depth is not what you need, the same interface will also drive | ||
| six third-party extraction engines instead. | ||
|
|
||
| The whole project supports **Python 3.6** or later; CI covers 3.10 to 3.14, and |
There was a problem hiding this comment.
drop the part about CI and 3.15.
There was a problem hiding this comment.
Done. The clause after the semicolon is gone; the paragraph is now a single line:
The whole project supports Python 3.6 or later.
Grepped the rest of README.md for any other CI or 3.15 mention and there is none — this was the only site. Left docs/source/index.rst alone, where the CI matrix belongs, and pyproject.toml:47's comment on the same subject predates this PR and is untouched by it.
Also rebased onto current main (dfc23b8b8, which picked up #621). The only conflicts were the two changelog files, both at the usual shared anchor: docs/source/changelog/1.5.0.rst resolved by hand keeping every bullet from both sides with this PR's last, and CHANGELOG.md discarded and regenerated with util/changelog_md.py — --check exits 0. Re-verified the packaging: python -m build clean, twine check --strict PASSED on both sdist and wheel, and pypcapkit-1.5.0b4/README.md ships at the sdist root.
|
✅ GOOD TO MERGE — head |
Cross-review appendix — PR #619Reviewer: Sonnet; PR authored on Opus 5. Reviewed at head The acceptance test, reproduced rather than taken on reportBuilt from this worktree (not the shared checkout):
The failure mode that would actually have bitten: README.md must ship in the sdist
setup.py
Line counts and Markdown sanity
Content migration — seven duplicated, two movedThe seven blocks dropped as already-duplicated (Module Structure, Engine Comparison, Engine support by Python version, Test Environment, Test Results, Installation Notes, Engine prerequisites) were each located in The Dockerfile break it found and fixed
Correction:
|
Requested by the project owner: drop the technical detail from the README, and change it back to Markdown. * Trimmed `README.rst` (424 lines) to `README.md` (103). What stays is 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, and where the documentation is. Added the worked example, which the README did not have before; its output is from the committed `examples/captures/in.pcap` and every value in it was measured against this tree. * Removed seven blocks that `docs/source/index.rst` already carried in a fuller form, and linked them instead: Module Structure, Engine Comparison, Engine support by Python version, Test Environment, Test Results, Installation Notes, and Engine prerequisites. * Moved the two blocks that existed nowhere else rather than dropping them. The Testing section is now `docs/source/testing.rst`, registered in the index toctree; the pipenv and `make setup` local development block joined the Installation section of `docs/source/index.rst`. * `setup.py` reads `README.md` and declares `text/markdown`. The `include README.md` in `MANIFEST.in` is now load-bearing, since `global-include *.rst` no longer matches the README and `setup.py` reads it unguarded. * Updated the references to the renamed file, since a change that renames a file owns the references to it. `examples/benchmark/Dockerfile` copies `README.md`; a literal `COPY` of the old name failed the layer outright, taking `make bench`, `make bench-quick` and `run.sh` with it. The benchmark harness prose that named the root README as where its generated tables land now names `docs/source/index.rst`, which is where those tables went: the `Makefile` comment, `report.py`, `test_harness.py`, `run.sh` and the suite's own README. One of those had a reason that inverted rather than just a stale path -- the emitted markup stays parseable by plain docutils, but that is now a conservative choice rather than a hard requirement, because the page it lands on is rendered by Sphinx. This crosses the convention that documentation here is reStructuredText. It is deliberate and scoped to the README, which is the one documentation file rendered by GitHub and PyPI rather than by Sphinx. No other `.rst` file was converted. Left alone on purpose: `examples/benchmark/benchmark.py:25` still says `README.rst`, correctly, because it means the benchmark suite's own README in the same directory; and `tests/project/test_changelog_md.py:432` is a string fixture describing the historical `1.5.0b1` release failure. Verified: `twine check --strict` passes on a built sdist and wheel, the README ships in the sdist, and the metadata declares `text/markdown`. A `FROM scratch` build against the same context `run.sh` uses resolves the new `COPY` line and fails the old one with `"/README.rst": not found`. Tests pass -- `tests/project/test_setup.py` (4), `tests/project/test_changelog_md.py` (47) and `examples/benchmark/test_harness.py` (116) -- and `python util/changelog_md.py --check` exits 0.
2af2300 to
eae2f57
Compare
Cross-review reconciliation — PR #619, the
|
Requested by the owner; no issue is open for it. * `MANIFEST.in` had `include` lines for `README.md`, `LICENSE` and `CHANGELOG.md` but none for `CITATION.cff`, and its two `global-include` patterns are `*.rst` and `*.py`, neither of which matches a `.cff`. The file was therefore in the repository and in no source distribution. * The gap is invisible from the web UI, since GitHub renders the "Cite this repository" button from the repository. Citation managers, Zenodo and dependency inventories read the published artifact, which is the surface that was missing it. * It matters now because #625 has just taught `util/bump_version.py` to keep that file's `version` and `date-released` in step with the bump, so a release exercising that path would publish an sdist omitting the artefact under test. #615 flagged the omission when it added the file; #619 did not address it. * The new line carries a comment, as its neighbours do, saying why it is load-bearing rather than belt-and-braces. * Changelog bullet added; `CHANGELOG.md` regenerated with `util/changelog_md.py`, and `--check` exits 0. Measured both ways with `python -m build --sdist`: `tar tzf | grep -i citation` found nothing before and `pypcapkit-1.5.0b4/CITATION.cff` after; the two archive listings differ by that one entry and nothing else, 860 against 861; the shipped copy is byte-identical to the repository's; and `twine check --strict` reports PASSED on both. No tests were run -- one line of packaging configuration, nothing under `pcapkit/`.
Requested by the owner; no issue is open for it. * `MANIFEST.in` had `include` lines for `README.md`, `LICENSE` and `CHANGELOG.md` but none for `CITATION.cff`, and its two `global-include` patterns are `*.rst` and `*.py`, neither of which matches a `.cff`. The file was therefore in the repository and in no source distribution. * Nor was there a default to fall back on. Removing all three `include` lines and rebuilding shows `README.md` and `LICENSE` shipping regardless -- setuptools adds the latter from `license_files`, logging `adding license file 'LICENSE'` and recording `License-File: LICENSE` in `PKG-INFO` -- while `CHANGELOG.md` disappears. Of the three only `CHANGELOG.md` is load-bearing, and a citation file, which nothing outside `MANIFEST.in` knows about, is in the same position. * The gap is invisible from the web UI, since GitHub renders the "Cite this repository" button from the repository. Citation managers, Zenodo and dependency inventories read the published artifact, which is the surface that was missing it. * It matters now because #625 has just taught `util/bump_version.py` to keep that file's `version` and `date-released` in step with the bump, so a release exercising that path would publish an sdist omitting the artefact under test. #615 flagged the omission when it added the file; #619 did not address it. * Changelog bullet added; `CHANGELOG.md` regenerated with `util/changelog_md.py`, and `--check` exits 0. Measured both ways with `python -m build --sdist`: `tar tzf | grep -i citation` found nothing before and `pypcapkit-1.5.0b4/CITATION.cff` after; the two archive listings differ by that one entry and nothing else, 860 against 861; the shipped copy is byte-identical to the repository's; and `twine check --strict` reports PASSED on both. No tests were run -- one line of packaging configuration, nothing under `pcapkit/`.
Requested by the owner; no issue is open for it. * `MANIFEST.in` had `include` lines for `README.md`, `LICENSE` and `CHANGELOG.md` but none for `CITATION.cff`, and its two `global-include` patterns are `*.rst` and `*.py`, neither of which matches a `.cff`. The file was therefore in the repository and in no source distribution. * Nor was there a default to fall back on. Removing all three `include` lines and rebuilding shows `README.md` and `LICENSE` shipping regardless -- setuptools adds the latter from `license_files`, logging `adding license file 'LICENSE'` and recording `License-File: LICENSE` in `PKG-INFO` -- while `CHANGELOG.md` disappears. Of the three only `CHANGELOG.md` is load-bearing, and a citation file, which no packaging default covers at all, is in the same position. * The gap is invisible from the web UI, since GitHub renders the "Cite this repository" button from the repository. Citation managers, Zenodo and dependency inventories read the published artifact, which is the surface that was missing it. * It matters now because #625 has just taught `util/bump_version.py` to keep that file's `version` and `date-released` in step with the bump, so a release exercising that path would publish an sdist omitting the artefact under test. #615 flagged the omission when it added the file; #619 did not address it. * It also lets `RepositoryCitationTests` in `tests/project/test_bump_version.py` -- the gate #625 added for the hand-authored bumps that never run the script -- execute against an unpacked sdist, where today it skips itself with "CITATION.cff is not shipped in the source distribution". * Changelog bullet added; `CHANGELOG.md` regenerated with `util/changelog_md.py`, and `--check` exits 0. Rebased onto `cfb81d3f6` after #630 merged; the changelog conflict was resolved keeping both bullets and regenerating `CHANGELOG.md` rather than merging it. Measured both ways with `python -m build --sdist` against that base: `tar tzf | grep -i citation` found nothing before and `pypcapkit-1.5.0b4/CITATION.cff` after; the listings differ by that one entry and nothing else, 860 against 861; the shipped copy is byte-identical to the repository's; and `twine check --strict` reports PASSED on both. No tests were run -- one line of packaging configuration, nothing under `pcapkit/`.
…two false packaging claims (#642) Three names appeared in string annotations that their module never imported, and they were mypy's complete set of ``name-defined`` findings for the package: * ``pcapkit/utilities/logging.py:350`` used ``Any``; added to the ``TYPE_CHECKING`` block beside ``IO``, ``Optional`` and ``Union``. * ``pcapkit/protocols/schema/internet/ipv6_route.py:136`` used ``Protocol`` and ``:271`` used ``Optional``; added, ``Protocol`` as ``ProtocolBase as Protocol``. Twenty-one sibling schema modules already spell it that way, in the same ``payload:`` stub; this makes twenty-two. mypy 2.3.1 over ``pcapkit``: 3 ``name-defined`` errors before, 0 after; 115 total errors before, 112 after, so nothing else moved. ``MANIFEST.in:14-17`` asserted that ``include README.md`` was "the only thing that puts it in an sdist" and that an sdist without it "cannot be installed at all". Both halves are false, and the file had contradicted itself since #631 wrote the correct mechanism seven lines below without correcting this. Deleting the lines and rebuilding gives a byte-identical sdist listing -- empty diff -- that installs with exit 0: ``setuptools/command/sdist.py:59-60`` ships the README unconditionally and ``setuptools/dist.py:460``'s default ``license_files`` glob ships ``LICENSE``. Of the original three ``include`` lines only ``CHANGELOG.md`` is load-bearing. The comment now says that, and the same correction is applied to the #619 entry in ``docs/source/changelog/1.5.0.rst``, which carried the identical claim. Three changelog bullets gained the citation they were missing: ``(#619)`` for the README entry, ``(#570)`` for the ``code=`` keyword and ``(#577)`` for the ``StreamEOFError`` gaps. Two of the five remain uncited because no number could be recovered for them. ``CHANGELOG.md`` regenerated with ``util/changelog_md.py``; ``--check`` exits 0. New ``tests/project/test_annotation_names.py`` resolves every string annotation in the package -- following a nested forward reference such as ``'list["Nested"]'``, while treating ``Literal`` members and ``Annotated`` metadata as the values they are -- against the names its own module binds. It reports the same three findings as mypy on the unfixed tree and none after. 128 -> 132 passed over ``tests/project`` and ``tests/utilities/test_logging.py``, both exit 0, subtests unchanged at 487.
…two false packaging claims (#642) Three names appeared in string annotations that their module never imported, and they were mypy's complete set of ``name-defined`` findings for the package: * ``pcapkit/utilities/logging.py:350`` used ``Any``; added to the ``TYPE_CHECKING`` block beside ``IO``, ``Optional`` and ``Union``. * ``pcapkit/protocols/schema/internet/ipv6_route.py:136`` used ``Protocol`` and ``:271`` used ``Optional``; added, ``Protocol`` as ``ProtocolBase as Protocol``. Twenty-one sibling schema modules already spell it that way, in the same ``payload:`` stub; this makes twenty-two. mypy 2.3.1 over ``pcapkit``: 3 ``name-defined`` errors before, 0 after; 115 total errors before, 112 after, so nothing else moved. ``MANIFEST.in:14-17`` asserted that ``include README.md`` was "the only thing that puts it in an sdist" and that an sdist without it "cannot be installed at all". Both halves are false, and the file had contradicted itself since #631 wrote the correct mechanism seven lines below without correcting this. Deleting the lines and rebuilding gives a byte-identical sdist listing -- empty diff -- that installs with exit 0: ``setuptools/command/sdist.py:59-60`` ships the README unconditionally and ``setuptools/dist.py:460``'s default ``license_files`` glob ships ``LICENSE``. Of the original three ``include`` lines only ``CHANGELOG.md`` is load-bearing. The comment now says that, and the same correction is applied to the #619 entry in ``docs/source/changelog/1.5.0.rst``, which carried the identical claim. Three changelog bullets gained the citation they were missing: ``(#619)`` for the README entry, ``(#570)`` for the ``code=`` keyword and ``(#577)`` for the ``StreamEOFError`` gaps. Two of the five remain uncited because no number could be recovered for them. ``CHANGELOG.md`` regenerated with ``util/changelog_md.py``; ``--check`` exits 0. New ``tests/project/test_annotation_names.py`` resolves every string annotation in the package -- following a nested forward reference such as ``'list["Nested"]'``, while treating ``Literal`` members and ``Annotated`` metadata as the values they are -- against the names its own module binds. It reports the same three findings as mypy on the unfixed tree and none after. 127 -> 132 passed over ``tests/project`` and ``tests/utilities/test_logging.py``, both exit 0, subtests unchanged at 487.
…a false packaging claim (#642) Three names appeared in string annotations that their module never imported, and they were mypy's complete set of ``name-defined`` findings for the package: * ``pcapkit/utilities/logging.py:350`` used ``Any``; added to the ``TYPE_CHECKING`` block beside ``IO``, ``Optional`` and ``Union``. * ``pcapkit/protocols/schema/internet/ipv6_route.py:136`` used ``Protocol`` and ``:271`` used ``Optional``; added, ``Protocol`` as ``ProtocolBase as Protocol``. Twenty-one sibling schema modules already spell it that way, in the same ``payload:`` stub; this makes twenty-two. mypy 2.3.1 over ``pcapkit``: 3 ``name-defined`` errors before, 0 after; 115 total errors before, 112 after, so nothing else moved. ``MANIFEST.in:14-17`` asserted that ``include README.md`` was "the only thing that puts it in an sdist" and that an sdist without it "cannot be installed at all". Both halves are false, and the file had contradicted itself since #631 wrote the correct mechanism seven lines below without correcting this. Deleting the lines and rebuilding gives a byte-identical sdist listing -- empty diff -- that installs with exit 0: ``setuptools/command/sdist.py:59-60`` ships the README unconditionally and ``setuptools/dist.py:460``'s default ``license_files`` glob ships ``LICENSE``. Of the original three ``include`` lines only ``CHANGELOG.md`` is load-bearing. The comment now says that. New ``tests/project/test_annotation_names.py`` resolves every string annotation in the package -- following a nested forward reference such as ``'list["Nested"]'``, while treating ``Literal`` members and ``Annotated`` metadata as the values they are -- against the names its own module binds. It reports the same three findings as mypy on the unfixed tree and none after. That module named ``ast.TypeAlias`` and ``ast.TypeVar`` directly, and both are PEP 695 nodes added in Python 3.12, so *every* test in it raised ``AttributeError`` on the 3.10 and 3.11 matrix jobs -- ``bound_names`` walks every node of every file, so the attribute is reached whatever a test does. Both are now resolved once at module scope through ``getattr(ast, ..., ())``, leaving the ``isinstance`` branches otherwise untouched: ``isinstance(x, ())`` is always False, so the branches stay live on 3.12+ and are simply unreachable below it. Chosen over a ``sys.version_info`` comparison because it writes no version number down at all -- a comparison states 3.12 next to the attribute it guards, and the two can then drift -- and over a per-node ``getattr`` because a module-level constant lifts the lookup out of a loop that runs on every node of every file. ``ast.TypeVar`` is the branch that earns its keep: it carries its name as a bare ``str`` and emits no ``ast.Name`` node, so forcing ``_TYPE_VAR`` to ``()`` on 3.14.7 turns ``T`` and ``U`` into false findings. ``ast.TypeAlias`` is defensive by comparison -- its name *is* an ``ast.Name`` in ``Store`` context, which the preceding branch already catches -- and is left as it stands rather than removed. A new ``test_a_pep695_type_parameter_is_in_scope`` pins both the guards and the behaviour, skipped below 3.12 because its fixture source cannot parse there. Measured on real interpreters rather than simulated. 3.10.21 and 3.11.15: 5 failed, exit 1 -> 5 passed, 1 skipped, exit 0. 3.14.7: all 6 pass, exit 0. 133 passed over ``tests/project`` and ``tests/utilities/test_logging.py``, exit 0, subtests unchanged at 487. No changelog entry on this branch. Per the rule that no code branch touches ``CHANGELOG.md`` or anything under ``docs/source/changelog/``, this change's entry -- and the wording correction the ``MANIFEST.in`` claim implies for the #619 entry, plus the missing ``(#570)`` and ``(#577)`` citations -- go to the shared changelog pull request #657 instead.
The changelog changes #666 was carrying on its own branch, moved here so that #666 touches only `MANIFEST.in`, `pcapkit/protocols/schema/internet/ipv6_route.py`, `pcapkit/utilities/logging.py` and `tests/project/test_annotation_names.py`. #666 was the last open branch still editing `CHANGELOG.md` itself; it no longer does. Four pieces, not one, because #666 had amended existing entries as well as needing a new one. A new **Fixed** bullet for #642: three names used in string annotations that their own module never imported -- `Any` in `pcapkit/utilities/logging.py`, and `Protocol` and `Optional` in `pcapkit/protocols/schema/internet/ipv6_route.py`. The bullet names the `typing.cast` case specifically, because that is the one no running test can catch: `cast` never evaluates its first argument. It states plainly that nothing resolves at runtime that did not before, since `TYPE_CHECKING` is `False` when the interpreter runs, so that the entry is not read as a runtime fix. mypy 2.3.1's before/after is quoted as the measurement -- three `name-defined` errors to none, 115 total to 112 -- and the new `tests/project/test_annotation_names.py` is described as what pins the invariant without a type checker installed. Three missing citations recovered: `(#570)` on the L2TPv3 worked-example line, `(#577)` on the `register_extractor_engine` keyword line, and `(#619)` on the README rename entry. And the #619 entry's packaging claim corrected in place. It asserted that `include README.md` in `MANIFEST.in` was "the only thing that puts the README in a source distribution" and that an sdist without it "cannot be installed". Both halves are false: setuptools' own `sdist` command ships the README before `MANIFEST.in` is read at all, so dropping the line leaves the listing byte-identical at 861 entries, and `setup.py` reads the file from wherever it is executing, which for a `pip` install of an sdist is the unpacked sdist. #666 corrects the same claim in the `MANIFEST.in` comment, so the two stay in step. No `:pep:` role, though the new bullet discusses PEP 695: `util/changelog_md.py` converts only double-backtick literals and the `:rfc:` role, and raises `ResidualMarkupError` on anything else, exactly as the #661 entry hit with `:obj:`. Plain prose instead. 50 lines added to the two files, 11 reflowed. `CHANGELOG.md` regenerated with `util/changelog_md.py`, not edited; `--check` exits 0 and `tests/project/` is green at 96 passed, 469 subtests, exit 0 -- the same counts the previous commit on this branch reported, so nothing else moved. Committed from a detached HEAD and pushed to the branch ref, because `docs/changelog-1.5.0` is checked out in another agent's worktree at a stale f846523 and could not be taken here. Written against b2ec64b and rebased onto d47ada0, the branch having taken #641's entry and the #652/#650 boundary correction in the meantime. Both files conflicted, both at the append point rather than in substance -- #641's bullet and this one land in the same place at the end of **Fixed** -- so the resolution keeps both, #641's first. `CHANGELOG.md` was not hand-resolved: it is generated, so it was regenerated from the resolved entry file and `--check` re-run, which is the only resolution that cannot drift. Refs #642
…a false packaging claim (#642) (#666) Three names appeared in string annotations that their module never imported, and they were mypy's complete set of ``name-defined`` findings for the package: * ``pcapkit/utilities/logging.py:350`` used ``Any``; added to the ``TYPE_CHECKING`` block beside ``IO``, ``Optional`` and ``Union``. * ``pcapkit/protocols/schema/internet/ipv6_route.py:136`` used ``Protocol`` and ``:271`` used ``Optional``; added, ``Protocol`` as ``ProtocolBase as Protocol``. Twenty-one sibling schema modules already spell it that way, in the same ``payload:`` stub; this makes twenty-two. mypy 2.3.1 over ``pcapkit``: 3 ``name-defined`` errors before, 0 after; 115 total errors before, 112 after, so nothing else moved. ``MANIFEST.in:14-17`` asserted that ``include README.md`` was "the only thing that puts it in an sdist" and that an sdist without it "cannot be installed at all". Both halves are false, and the file had contradicted itself since #631 wrote the correct mechanism seven lines below without correcting this. Deleting the lines and rebuilding gives a byte-identical sdist listing -- empty diff -- that installs with exit 0: ``setuptools/command/sdist.py:59-60`` ships the README unconditionally and ``setuptools/dist.py:460``'s default ``license_files`` glob ships ``LICENSE``. Of the original three ``include`` lines only ``CHANGELOG.md`` is load-bearing. The comment now says that. New ``tests/project/test_annotation_names.py`` resolves every string annotation in the package -- following a nested forward reference such as ``'list["Nested"]'``, while treating ``Literal`` members and ``Annotated`` metadata as the values they are -- against the names its own module binds. It reports the same three findings as mypy on the unfixed tree and none after. That module named ``ast.TypeAlias`` and ``ast.TypeVar`` directly, and both are PEP 695 nodes added in Python 3.12, so *every* test in it raised ``AttributeError`` on the 3.10 and 3.11 matrix jobs -- ``bound_names`` walks every node of every file, so the attribute is reached whatever a test does. Both are now resolved once at module scope through ``getattr(ast, ..., ())``, leaving the ``isinstance`` branches otherwise untouched: ``isinstance(x, ())`` is always False, so the branches stay live on 3.12+ and are simply unreachable below it. Chosen over a ``sys.version_info`` comparison because it writes no version number down at all -- a comparison states 3.12 next to the attribute it guards, and the two can then drift -- and over a per-node ``getattr`` because a module-level constant lifts the lookup out of a loop that runs on every node of every file. ``ast.TypeVar`` is the branch that earns its keep: it carries its name as a bare ``str`` and emits no ``ast.Name`` node, so forcing ``_TYPE_VAR`` to ``()`` on 3.14.7 turns ``T`` and ``U`` into false findings. ``ast.TypeAlias`` is defensive by comparison -- its name *is* an ``ast.Name`` in ``Store`` context, which the preceding branch already catches -- and is left as it stands rather than removed. A new ``test_a_pep695_type_parameter_is_in_scope`` pins both the guards and the behaviour, skipped below 3.12 because its fixture source cannot parse there. Measured on real interpreters rather than simulated. 3.10.21 and 3.11.15: 5 failed, exit 1 -> 5 passed, 1 skipped, exit 0. 3.14.7: all 6 pass, exit 0. 133 passed over ``tests/project`` and ``tests/utilities/test_logging.py``, exit 0, subtests unchanged at 487. No changelog entry on this branch. Per the rule that no code branch touches ``CHANGELOG.md`` or anything under ``docs/source/changelog/``, this change's entry -- and the wording correction the ``MANIFEST.in`` claim implies for the #619 entry, plus the missing ``(#570)`` and ``(#577)`` citations -- go to the shared changelog pull request #657 instead.
Requested by the project owner, in their words: "for README specifically, we might want to remove some of the technical details from it - and maybe change back to Markdown format."
Both halves are done, and the references to the renamed file were updated with it — a change that renames a file owns the references to it.
What the README became
424 lines / 17,951 bytes → 103 lines / 4,548 bytes.
What stays is what a reader arriving from PyPI or a search result actually needs: what the library is, why it exists rather than Scapy/DPKT/PyShark, how to install it, a worked example, and where the real documentation is.
The worked example is new — the old README had no usage example at all, which is an odd gap for a landing page. Every value in it was measured against this branch using the committed
examples/captures/in.pcap, not written from plausibility. (The first draft guessedlen(flows.trace)was0; it is3. A README example is the first thing a reader tries and the only thing they can check without reading source, so a wrong number there is worse than no example.)Nothing was deleted that existed only in the README
Every block removed was checked against
docs/source/first.Already there, in a fuller form — now linked instead of restated:
docs/source/index.rst:60-103(alsopcapkit/__init__.py's docstring)docs/source/index.rst:105-144docs/source/index.rst:146-172docs/source/index.rst:174-184docs/source/index.rst:186-217docs/source/index.rst:291-312docs/source/index.rst:314-409, plus the gap tables indocs/source/pcapkit/foundation/engines/index.rst:72-150Existed nowhere else — moved, not dropped:
docs/source/testing.rst, a new page registered in theindex.rsttoctree. There was no testing page in the docs at all;pep.rst:586-599covered the untracked-fixtures fact andmake samples, butmake test-all, the tshark-is-only-for-PyShark note, theexamples/legacy_smoke/fixture path and theexamples/generators/options.pyround-trip mechanism had no copy anywhere else.make test-allin particular appeared only in theMakefileand this README.make setuplocal development block (the~/Library/Cachespermission issue, the Homebrewlibxml2/libxsltissue, and thePIPENV_VENV_IN_PROJECT=1 …invocation) joined the Installation section ofdocs/source/index.rst. It was not in the docs, and not inCONTRIBUTING.mdeither.The convention this deliberately crosses
This repo's standing rule is that documentation is
.rst, never.md, with the generated rootCHANGELOG.mdas the one exception. The owner is overriding that for the README specifically, so please do not "fix" this back.The rationale, for the record: the README is the one documentation file whose renderers are GitHub and PyPI rather than Sphinx. That is exactly why it has been a recurring hazard —
1.5.0b1half-shipped becausetwine checkfound a Sphinx-only:mod:role inREADME.rst, and the wholeexamples/benchmark/report.pytoolchain carries defensive machinery to keep Sphinx roles out of the emitted tables. A Markdown README removes the class of failure where RST-that-Sphinx-accepts is RST-that-PyPI-rejects.No other
.rstfile was converted.The references to the renamed file
examples/benchmark/DockerfilecopiedREADME.rstby literal name, with no glob and no.dockerignorein the repository, so the layer failed outright and tookmake bench,make bench-quickandrun.shwith it. NowREADME.md. Verified both ways with aFROM scratchbuild against the same contextrun.shuses (REPO_ROOT), which is instant and needs no image pull:The benchmark harness prose named the root README as where its generated tables land. That was stale twice over — wrong extension and wrong destination, since Test Results and Test Environment are two of the sections that moved to
docs/source/index.rst. Rather than correct the extension and leave them pointing at a file that no longer holds those tables, the destination was fixed properly across all of it: theMakefilecomment,report.py(9 sites),test_harness.py(7),run.sh(2) andexamples/benchmark/README.rst(5).One of those was not a stale path but an inverted reason.
report.pyand the suite's README both justified emitting docutils-safe RST on the grounds that GitHub renders the README with docutils, where a:mod:role is a visible error block. The destination is now a Sphinx-rendered page, where a Sphinx role would in fact survive. The generator's behaviour is unchanged and its tests still assert docutils-cleanliness — but the prose now says what is true: staying docutils-clean is a conservative choice that keeps a table pasteable into any reStructuredText a plain docutils reader will see, rather than a hard requirement. Relaxing the constraint is a design call for that tree's owner and was not taken here.examples/benchmark/benchmark.py:25still saysREADME.rst, and is correct. It was reported to me as stale; it is not. It refers to the benchmark suite's ownREADME.rstin the same directory, whose "Departures from the legacy methodology" section is at line 247. Left alone.Also left alone:
CONTRIBUTING.md:9, handled separately by dropping the extension, andtests/project/test_changelog_md.py:432, a string fixture describing the historical1.5.0b1failure.Verification
twine check --stricton a real build, re-run after the rebase onto545b174bf:Also confirmed:
README.mdpresent at the sdist root, noREADME.rst—include README.mdinMANIFEST.inis what does it.global-include *.rstno longer matches the README, so that line went from belt-and-braces to load-bearing, and the comment above it now says so.Description-Content-Type: text/markdownwith the 4,548-character body.tests/project/test_setup.py(4),tests/project/test_changelog_md.py(47 + 37 subtests),examples/benchmark/test_harness.py(116). The setup tests executesetup.pytop-to-bottom, so they would catch a staleREADME.rstreference; they are filename-agnostic and assert only that the description containsPyPCAPKit.python util/changelog_md.py --checkexits 0. The rebase conflicted on both changelog files, as expected with siblings landing; the.rstwas resolved keeping all four of545b174bf's bullets with mine last, andCHANGELOG.mdwas regenerated rather than hand-merged.index.rst+testing.rst: build succeeded,testing.htmlrenders, and no "document isn't included in any toctree" warning, so the toctree registration is good.#installation,#module-structure,#engine-comparison) were confirmed in the generated HTML, and 6 external links carried over unchanged.Two things found and deliberately not changed
No licence section was added to the README. The old one had none, and the licence question is open, so this keeps the status quo rather than asserting something that may be about to change.
A possible hang in the public API, unrelated to this change and being filed separately.
no_eof=Truedoes not terminate. Reproduced deterministically in both forms, with controls that pass:extract(cap, nofile=True, no_eof=True)faulthandlerstack inpcapkit/protocols/protocol.py__init__extract(cap, nofile=True, auto=False, store=False, no_eof=True)then iteratelogging/__init__.pymakeRecordno_eof(control)frames=6no_eof, iterating (control)seen=6ExtractionWarning: EOF reachedis emitted in all four cases, including the hanging ones, so EOF is detected — whatno_eofsuppresses is theEOFErrorthat stops the loop, and nothing else stops it. No library code was touched here.