Running the Repository¶
The four pages before this one are about writing library code. The rulings here are about running the repository – what an install carries, what a changelog entry is, and what the issue and pull request labels mean. None of them is derivable from a module, and none fits a code-convention page, so the owner ruled on #918 that they get a page of their own rather than being left in their threads. Each ruling below is paraphrased rather than quoted, also on his instruction there; the issue named beside it is where the original wording is.
The all Extra¶
all means core addons only – the things that let the library itself run at
full functionality – rather than everything a user might conceivably want. The owner
settled that on #910 and named
the three that qualify to date: the CLI addon, the crypto addon, and pycrate.
On the tree, in pyproject.toml:
cli = [ "emoji" ]
crypto = [ "cryptography>=3.4" ]
NGAP = [ "pycrate" ]
all = [ "emoji", "cryptography>=3.4", "pycrate" ]
So all is exactly the union of those three extras, written out as literals rather
than referenced.
Two groups stay out, and the reasons are different rather than two versions of one reason. Keeping them apart is what stops the list drifting the way it already did once:
The third-party capture engines are excluded by kind.
DPKT,Scapy,PyShark,PyPCAPFile,PyPCAPandPCAP_CTare not core addons, so they are on demand – one extra at a time,pip install pypcapkit[Scapy]and so on. This holds however easy they are to install, and it is what the ruling changed: four of them used to be inall.``PyPCAP`` and ``PCAP_CT`` were already excluded for installability, which the ruling leaves untouched.
pypcapis an sdist-only C extension needing a compiler and the libpcap development files;pcap-ctandlibpcapare published only as pre-releases, andallshould not be how somebody acquires a beta they did not ask for.
vendor is the crawler dependency set and is not for end users, so it is out on the
same audience grounds. Narrowing all costs a user nothing at run time:
Extractor.run warns and falls
back to the default engine rather than raising when a requested engine is absent.
Note
The dev extra exists because of this narrowing, and is not a second
catch-all. pylint, mypy and autodoc all resolve imports against what is installed,
so the four engines leaving all would have made them newly unresolvable to the
toolchain. dev is defined by what the toolchain must be able to see, and the
workflows that need full resolution install .[all,dev]. Do not add
pypcap/pcap-ct to it to silence a lint finding; .github/workflows/lint.yml
carries a tracked import-error count that is deliberate rather than accidental.
Changelog Entry Granularity¶
An entry is not one line per commit. Group the changes by topic, and give concise detail of what actually changed in that version bump. Ruled on #918.
Two different things get confused here, so they are named apart:
A pull request’s commits. The shared changelog for the 1.5.0 cycle is a long-lived pull request of its own, carrying roughly one commit per code pull request, deliberately unsquashed so that what is and is not accounted for stays readable in its log. That is a property of the pull request, and it is not what the ruling is about.
A changelog file’s entries.
docs/source/changelog/1.5.0.rstgroups its entries under a section per top-level module, withAdded,ChangedandFixednested inside each, and a single entry routinely cites several changes at once – the completed Mobility Header registry is one bullet, not two. That is a property of the file, and it is the axis the ruling governs.
Both are measurable rather than matters of memory, which is the point of writing the commands down instead of a figure that will be stale by the next merge:
# entries in the file, and the module sections they group under
grep -cE '^\* ' docs/source/changelog/1.5.0.rst
grep -B1 -E '^-{3,}$' docs/source/changelog/1.5.0.rst | grep -vE '^-{3,}$|^--$'
# commits on the shared changelog pull request -- a different number, about a
# different thing
gh pr list -R JarryShaw/PyPCAPKit --state all \
--search 'shared 1.5.0 changelog in:title' \
--json commits -q '.[].commits|length'
The grouping scheme was settled on #918: a section per top-level module, with
Added/Changed/Fixed nested inside each – module granularity, not
per-file and not per-subpackage. The file carries 9 module-level sections holding
155 entries, and no entry carries an inline kind label:
$ grep -cE '^\* \*\*(Added|Changed|Fixed)\*\*' docs/source/changelog/1.5.0.rst
0
Eight of those nine name a module; the ninth, Project infrastructure, is for what
belongs to none. Nor is the map one-to-one with the package list below –
pcapkit.interface has no 1.5.0 entry, so it has no section of its own:
ls -d pcapkit/*/ | sed 's|pcapkit/||;s|/||' # const corekit dumpkit foundation
# interface protocols toolkit
# utilities vendor
Note
One case the rule does not settle by itself: an entry whose change spans modules –
the reassembly and extraction ones touch pcapkit.foundation and
pcapkit.protocols together. Ruled on
#952: file it under the
module the change is about, name the others in the entry’s own text, and do
not duplicate the entry into each section. A reader scanning one module’s
section wants that module’s changes; the same prose appearing twice reads as two
separate changes. Raised originally on #918.
The restructure itself belongs to the shared changelog’s own pull request, which owns the file and merges last; doing it earlier would conflict with every open change that touches an entry.
Issue and Pull Request Labels¶
The owner asked on #918 for
this to be written down alongside breaking, since breaking’s meaning only
makes sense against the scheme it sits in.
Almost every label is applied by hand, by the owner – so a label is generally a
statement someone made rather than a value derived from the change. That matters most
for the review: family below: such a label is not evidence of the state it names,
it is a record that the owner asserted it.
Two paths are automated, and both are worth knowing about because a label they set has had no human judgement behind it:
dependabot puts
dependenciesandpythonon its own pull requests, and only those two:.github/dependabot.ymlconfigures a single ecosystem,pip, so it never opens a workflow bump here.github_actionsexists as a label but is hand-applied like the rest – naming it as dependabot’s would tell a reader the opposite of this section’s point.The issue templates apply an issue-kind label from their front matter, before anyone reads the issue –
.github/ISSUE_TEMPLATE/bug_report.mdcarrieslabels: bugand.github/ISSUE_TEMPLATE/feature_request.mdcarrieslabels: enhancement. Sobugandenhancementon a template-opened issue are defaults rather than assessments.
Nothing else automates a label. .github/release.yml only reads existing
labels to bucket release notes, and the PCAPKIT_CONDA_LABEL in the release
workflows is a conda channel label, unrelated to these.
The ones that carry meaning here fall into five groups, which stack rather than
compete: a pull request normally carries one from the first group and as many of the
rest as apply. The five groups are not the whole label set – the repository also
has GitHub’s own defaults, of which wontfix, invalid, help wanted and
duplicate are all in live use and only good first issue has never been applied.
Those are documented by GitHub rather than here, and are counted rather than listed so
this page does not go stale every time one is added:
$ gh label list -R JarryShaw/PyPCAPKit --limit 100 --json name -q '.[].name' | wc -l
29
One of those defaults carries a local ruling worth knowing: an issue closed as
unnecessary takes invalid (or the nearest applicable) rather than bug, since
the issue was not a defect. #275 is where it was applied –
bug removed and invalid added in the same second – and #707 is the worked example, closed
as invalid because it was filed against main rather than against the pull
request’s diff.
Type – what kind of change it is. Each corresponds to the subject prefix of the commit, so the label and the message agree by construction:
Label |
Applies to |
|---|---|
|
a new capability |
|
a defect repaired |
|
restructuring for its own sake – neither a fix nor a new capability |
|
a performance improvement |
|
documentation only |
|
tests added or corrected |
|
CI or workflow configuration |
|
tooling and repository hygiene, with no library behaviour change |
|
version bumps and distribution rollups |
|
regenerated IANA or vendor constant tables, members keeping their numeric values |
Issue kind, for issues rather than pull requests: design marks a pattern being
decided rather than a defect or a request, and a majority of the rulings on these pages
were filed under it – though not all, several having been settled on a bug or
enhancement thread instead. Alongside bug, enhancement and question.
State – what is happening to it now. An open issue is meant to carry one of these, so that its status is readable without opening it:
wip– in flight: a covering pull request is open, or an agent is on it.blocked– deferred behind other work or a decision, with the last comment saying what unblocks it. The condition is meant to be checkable rather than remembered – a command someone else can run and get an answer from.needs: decision– waiting on the owner, and on nothing else.
Two things the board shows rather than the rule: wip and needs: decision
legitimately co-occur, when the bulk of an issue is being worked and one
sub-question is held for the owner – #918 itself was labelled that way while this
page was being written. And an open issue with no state label at all is a gap rather
than a category, which is worth checking for rather than assuming away:
gh issue list -R JarryShaw/PyPCAPKit --state open --limit 100 \
--json number,labels -q '.[]|"#\(.number) \(.labels|map(.name)|join(","))"'
Review – the cross-review verdict, at the current head. Separate from CI, which
has a status of its own: review: pending means no verdict for this head,
either never reviewed or the head moved since; review: good-to-go and
review: needs-changes are the two verdicts. Because they are keyed on the head
rather than on the pull request, a new push invalidates the label – a verdict that
outlives the commit it was given on is worse than none.
Scope. dependencies and python are dependabot’s, per above.
github_actions is the same kind of label – it scopes a change to the workflows –
but nothing applies it automatically, because dependabot is not configured for that
ecosystem here.
The breaking Label¶
breaking is additive – it goes on alongside the type label, never instead of
it. Its own description in the label set says so, and defines it as breaking
public-facing behaviour or API.
So the question it answers is not “how big is this change” but “can a caller observe the difference without changing their code”. On the tree, the changes carrying it are that kind:
an exception type a caller catches – #805 raising
ProtocolErrorwhere a barestruct.errorused to escape, and #759 raising one where a single-bit lookup used to return a member;a public attribute’s meaning – #618 swapping
Frame.lenandFrame.cap_lenbetween the PCAP and PCAP-NG readers;a signature or a name a caller writes – #806 retyping
AppType.protoand givingregister_apptypevarargs, #778 enforcing@finalat runtime;a path a caller or a script depends on – the change that named the examples directories apart.
Warning
A pull request’s prose and its label can disagree, and the label is not
automatically right. Both directions have happened here. The #759 and
#805 changes carry the label while their changelog bullets never said so, which
a review round on the shared changelog caught and corrected. The
#844 change carries it too,
and its own pull request argues at length that the change is not breaking – a
review round checked that argument and found it right on the facts, so there the
label is the half that overstates. So when the two conflict, settle it on what a
caller can observe, and fix whichever of the two is wrong rather than letting the
pair stand.
Note
The label is not applied uniformly across the repository’s history, and a census
that assumes it is will be wrong. It is dense on pull requests from the
examples-directory change above onward and effectively absent below it: the only
earlier carriers are seven pre-0.15 pull requests, clustered at the very start
of the numbering, with nothing labelled at all between them and that change. Three
of those seven are distribution rollups, each also carrying release; the other
four are early refactor/feat work from before the project stabilised. On
issues it is sparser still, appearing only from #775 up. So breaking’s
absence on an old pull request is weak evidence at best. The current figures, rather
than these:
gh pr list -R JarryShaw/PyPCAPKit --state all --label breaking --limit 200 \
--json number -q '[.[].number]|sort|@json'
gh issue list -R JarryShaw/PyPCAPKit --state all --label breaking --limit 100 \
--json number -q '[.[].number]|sort|@json'