Skip to content

mypy: TransportProtocol.undefined types as int, so four base-template defaults disagree with their annotations #770

Description

@JarryShaw

Describe the bug

Four [assignment] errors in pcapkit/const/reg/apptype/apptype.py's base-template code, every one
about TransportProtocol.undefined used as a default where a TransportProtocol is annotated. They
were masked by a file-wide # mypy: disable-error-code=assignment pragma until #769 removed it.

Reproduction

$ mypy --follow-imports=silent --ignore-missing-imports --show-column-numbers --show-error-codes \
       pcapkit/const/reg/apptype/apptype.py          # with the pragma
Success: no issues found in 1 source file

$ # same command, pragma removed
:2258:42: error: Incompatible types in assignment (expression has type "int", variable has type "TransportProtocol")  [assignment]
:2282:46: error: Incompatible default for parameter "proto" (default has type "int", parameter has type "TransportProtocol")  [assignment]
:2371:48: error: Incompatible default for parameter "proto" (default has type "int", parameter has type "TransportProtocol | str")  [assignment]
:2429:52: error: Incompatible default for parameter "proto" (default has type "int", parameter has type "TransportProtocol | str")  [assignment]
Found 4 errors in 1 file (checked 1 source file)

Whole-package: 112 errors in 38 files → 116 in 39.

Expected behavior

TransportProtocol.undefined should type as TransportProtocol, so the four defaults agree with
their annotations and no suppression is needed.

Additional context

Root cause isolated: undefined = 0 is a bare int literal, so mypy infers its attribute type as
int, while tcp/udp/sctp/dccp are auto()-valued and infer as Any — which is why only
undefined trips it. mypy has no aenum plugin, so the class is treated as a plain class rather
than an enum. Pre-existing and independent of #769: stripping only the pragma on unmodified
main reproduces all four, and none of the ~12,391 per-member lines contributes one.

The four sites are __new__, _dispatch, get and get_all; the fix belongs in the BASE
template in pcapkit/vendor/reg/apptype/apptype.py, not in the generated file. Whether it is
achievable without an aenum stub is not established.

Not urgent — mypy is advisory in CI (continue-on-error: true in lint.yml).

One follow-up this creates. lint.yml's header pins mypy at 112 errors / 38 files measured at
932cb48d1 (#753, #761). That pin stays honest because it names its commit, but once #769 merges
the current figure is 116/39. Either re-pin it or note the delta here, whichever the maintainer
prefers — flagging it so the two PRs do not quietly leave each other stale.

Activity

  1. added
    bugIssues reporting a defect (set by the bug report template; a default, not an assessment)
    blockedDeferred pending another issue or decision; see the last comment for what unblocks it
    on Sep 25, 2026
  2. JarryShaw commented on Sep 25, 2026

    @JarryShaw
    OwnerAuthor

    Blocked on #769, which is open and owns pcapkit/vendor/reg/apptype/apptype.py — the BASE template where the fix for these four errors belongs. #769 is also what unmasks them, by removing the file-wide # mypy: disable-error-code=assignment pragma, so this issue cannot be actioned before it lands.

    Unblocks when #769 merges. Note the follow-up recorded in the body: lint.yml's mypy pin moves 112/38 -> 116/39 at that point.

  3. JarryShaw commented on Sep 25, 2026

    @JarryShaw
    OwnerAuthor

    Correction to the site list above — one of the four is misattributed, and it is my error.

    apptype.py:2258 is not _dispatch. It is the class-level attribute

    __transport__: 'TransportProtocol' = TransportProtocol.undefined

    so it is an attribute assignment rather than a default argument, which is also why its message reads "Incompatible types in assignment" while the other three read "Incompatible default for parameter". _dispatch has no proto default and contributes nothing here. The correct four sites are __transport__ (:2258), __new__ (:2282), get (:2371) and get_all (:2429).

    One further measurement worth recording: the pragma removal is wider than #744 requires. The per-member annotation lives only in the crawler's TRANSPORT template — the base module has had no members since #754 — so keeping the pragma in the base module while removing it from TRANSPORT returns mypy to exactly Found 112 errors in 38 files (checked 506 source files). That is a live minimal alternative to fixing the inference, measured clean. It does not change the ruling already given (option 1, leave them visible), but it belongs on the record here.

  4. removed
    blockedDeferred pending another issue or decision; see the last comment for what unblocks it
    on Sep 25, 2026
  5. JarryShaw commented on Sep 25, 2026

    @JarryShaw
    OwnerAuthor

    Unblocked — #769 merged as 83b58ebda, so pcapkit/vendor/reg/apptype/apptype.py (the BASE template, where the fix belongs) is free.

    The four errors are now live on main: whole-package mypy is 116 in 39 files, up from 112/38, because #769 removed the file-wide # mypy: disable-error-code=assignment. Two measured notes carried over from the review. The site list in the body is corrected in the comment above — :2258 is the class attribute __transport__: 'TransportProtocol' = TransportProtocol.undefined, not _dispatch. And there is a minimal alternative that measures clean: keeping the pragma in the base module alone, while leaving it off the four per-transport modules, restores Found 112 errors in 38 files (checked 506 source files) exactly — because the per-member annotation only ever lived in the TRANSPORT template. The maintainer ruled (option 1) to leave the errors visible rather than re-suppress, so that alternative is recorded, not recommended.

    Also still open here: lint.yml pins mypy at 112/38 measured at 932cb48d1. That pin stays literally true because it names its commit, but the live figure is now 116/39.

  6. added
    wipWork in flight - a covering PR is open or an agent is actively on it
    on Sep 25, 2026
  7. removed
    wipWork in flight - a covering PR is open or an agent is actively on it
    on Sep 25, 2026
  8. added this to the 1.5 milestone on Oct 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIssues reporting a defect (set by the bug report template; a default, not an assessment)

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions