Skip to content

docs: let autodoc resolve the HTTP/2 frame and engine class annotations (#1857) - #1870

Merged
JarryShaw merged 1 commit into
mainfrom
docs/1857-class-guard-annotations
Oct 17, 2026
Merged

JarryShaw merged 1 commit into
mainfrom
docs/1857-class-guard-annotations

Conversation

@JarryShaw

Copy link
Copy Markdown
Owner

Please follow the guide below

What is the purpose of your pull request?

Tick the commit type your subject line carries.

  • fix — corrects a defect
  • feat — adds a feature
  • perf — changes performance, not behaviour
  • refactor — changes neither behaviour nor performance
  • test — tests only
  • docs — documentation only
  • ci — workflows or build tooling
  • release — bumps the version or rolls up a distribution
  • chore — anything else

  • Qualify FrameType's __flags__ as 'FrameType.Flags'. Autodoc evaluates a
    class annotation in the module's globals, where the bare nested Flags is
    unbound, so every frame schema fell back to raw annotation strings.
  • Annotate each third-party engine's _expkg as 'ModuleType', imported in the
    module-level guard, and drop the class-level engine import it named. The docs
    build runs module-level guards only and cannot import pcap or pcapfile; mypy
    already typed calls through _expkg as Any and rejected scapy.all as a type.
  • Drop a dead dpkt local in DPKT.run, which pylint flags once the
    class-level import of the same name is gone.
  • Add a unit test that evaluates class annotations as autodoc does, without
    Sphinx and without importing an engine package.

Closes #1857

Known remainder, deferred to the conf.py batch after #1856: PCAP_CT._handle and PyPCAPFile._extmp still fall back to raw strings in the docs build, because pcap and pcapfile are not installed there.

…ns (#1857)

- Qualify FrameType's `__flags__` as `'FrameType.Flags'`. Autodoc evaluates a
  class annotation in the module's globals, where the bare nested `Flags` is
  unbound, so every frame schema fell back to raw annotation strings.
- Annotate each third-party engine's `_expkg` as `'ModuleType'`, imported in the
  module-level guard, and drop the class-level engine import it named. The docs
  build runs module-level guards only and cannot import pcap or pcapfile; mypy
  already typed calls through `_expkg` as Any and rejected `scapy.all` as a type.
- Drop a dead `dpkt` local in `DPKT.run`, which pylint flags once the
  class-level import of the same name is gone.
- Add a unit test that evaluates class annotations as autodoc does, without
  Sphinx and without importing an engine package.

Closes #1857
@JarryShaw JarryShaw added docs Pull requests that change documentation only (docs: subject prefix) review: running A cross-review is in flight against the current head - no verdict yet labels Oct 16, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

Verdict: GOOD TO GO at 13165eba0. A Sonnet cross-review (author: Opus) confirmed:

  • No runtime change. Importing the engine modules loads no engine package on either tree. Every runtime use binds the package locally, and the removed class-level imports were never visible to methods. The engine tests give identical results on main and here.
  • Dead local. DPKT.run()'s dpkt local was unused.
  • mypy improves slightly. The scapy valid-type and attr-defined errors go away and nothing new appears. Pylint loses a C0415 per engine.
  • Real Sphinx path. Running resolve_type_guarded_imports and then Sphinx's get_type_hints, with pcap/pcapfile mocked, resolves every affected class here, where all of them fail on main.

Non-blocking: test_the_check_imports_no_engine_package depends on test order, because an engine package loaded earlier masks a regression. A sys.meta_path blocker or a subprocess would make it independent.

@JarryShaw JarryShaw added review: good-to-go Cross-review at the current head says ready; CI state is separate and removed review: running A cross-review is in flight against the current head - no verdict yet labels Oct 17, 2026
@JarryShaw

Copy link
Copy Markdown
Owner Author

Would MyPy still be able to properly infer and handle the types with the proposed changes?

@JarryShaw

Copy link
Copy Markdown
Owner Author

Yes, and it measures slightly better. mypy could never type the engine package through _expkg:

  • for scapy.all, mypy rejects a module as a type (Module "scapy.all" is not valid as a type [valid-type]);
  • the other engine packages (dpkt, pyshark, pcap, pcapfile) are untyped;
  • so calls through _expkg were Any before.

With ModuleType, attribute access goes through ModuleType.__getattr__ and is still Any. Inference is the same, minus the error.

Measured with mypy 2.3.1 and the repo's mypy.ini on the touched files: 320 errors in 40 files before, 318 in 39 after. The two removed are scapy's valid-type and attr-defined, and nothing new appears.

Real per-engine typing would need a Protocol describing each package's used surface. That is a separate, larger change, and the untyped packages would not check against it anyway.

@JarryShaw

Copy link
Copy Markdown
Owner Author

I would kinda still like to have per-engine real typings. Can we still do that? For untyped packages, we probably just need to create type stubs for those APIs and data types we used.

@JarryShaw

Copy link
Copy Markdown
Owner Author

Yes. Filed as #1878. Scapy already ships py.typed. For the rest, local .pyi stubs would cover only the APIs and data types we use from dpkt, pyshark, pcap and pcapfile, registered through mypy_path and kept out of the distributions. _expkg would then get a per-engine Protocol describing what each engine reads, because mypy will not take a module as a type. This PR stays the docs fix: it removes the class-level engine imports, which #1878 builds on. #1878 is next in the queue once the current batch frees a slot.

@JarryShaw JarryShaw moved this to In review in PyPCAPKit Oct 17, 2026
@JarryShaw
JarryShaw merged commit 0de96b4 into main Oct 17, 2026
56 checks passed
@github-project-automation github-project-automation Bot moved this from In review to Done in PyPCAPKit Oct 17, 2026
@JarryShaw
JarryShaw deleted the docs/1857-class-guard-annotations branch October 17, 2026 02:07
@JarryShaw JarryShaw removed the review: good-to-go Cross-review at the current head says ready; CI state is separate label Oct 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Pull requests that change documentation only (docs: subject prefix)

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

docs: class-level if TYPE_CHECKING: annotations make autodoc fall back to raw annotation strings

1 participant