Skip to content

TypeVar/ParamSpec/TypeVarTuple/NewType: mark special-form 'name' as positional-only #15804

Description

@adamtheturtle

TypeVar, ParamSpec, TypeVarTuple, and NewType declare name as positional-or-keyword, but every type checker (mypy, pyright, ty, pyre) requires it positionally. This is not a per-checker quirk: the typing spec itself (PEP 484 for TypeVar, PEP 612 for ParamSpec, PEP 646 for TypeVarTuple, and the typing spec's NewType section) mandates the first argument be a string literal so the checker can bind it statically, so any conformant checker must reject name=.... mypy core, no plugins:

from typing import ParamSpec
P = ParamSpec(name="P")  # error: ParamSpec() expects a string literal as first argument  [misc]

So the keyword form the stub advertises produces a type error wherever it is used: a checker has to tie the variable name to the assigned target statically, so it only accepts a positional string literal and rejects name=... (the error above). Proposal: mark name positional-only (name: str, /) on these constructors so the stub reflects the real contract.

Checkers special-case these and ignore the signature, so this is a no-op for them. The motivation is third-party tools that read typeshed as ground truth (e.g. keyword-argument linters flagging ParamSpec("P") and suggesting the type-checker-breaking ParamSpec(name="P")). Happy to PR. Fine if intentionally out of scope.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions