Skip to content

Conversation

@A5rocks
Copy link
Collaborator

@A5rocks A5rocks commented Jan 12, 2026

Fixes #20571. @JelleZijlstra I somehow didn't realize this was something until I saw microsoft/pyright#11225, so I didn't put this as a test case last time...

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@A5rocks
Copy link
Collaborator Author

A5rocks commented Jan 13, 2026

I just realized in the pyright issue there, @erictraut thinks this should error (i.e. current behavior) rather than be accepted. (I just skimmed and realized that my last PR didn't address this case)

I think generally we should be forgiving and that this is justifiable by the PEP, but I would be OK if we want to discuss this more instead. The weak justification being just this:

By the rules defined above, spelling a concrete instance of a class generic with respect to only a single ParamSpec would require unsightly double brackets. For aesthetic purposes we allow these to be omitted.

And there being no reason that shouldn't apply for an empty Parameters.

Copy link
Collaborator

@hauntsaninja hauntsaninja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing that is clearly a bug in pyright is the inconsistency between the class case and the type alias case.

I think the behaviour of this PR makes sense. This is the test case I used when I reviewed it (maybe worth adding?):

# flags: --strict
from typing import Callable

class Cls[**P]:
    def __call__(self, *a: P.args, **k: P.kwargs) -> None: ...
type TA[**P] = Callable[P, None]

def f(cls: Cls[()], vt: TA[()], vt2: TA[(int,)]) -> None:
    reveal_type(cls)
    reveal_type(vt)
    reveal_type(vt2)

    cls()
    cls(1)

    vt()
    vt(1)
    
    vt2()
    vt2(1)

@github-actions
Copy link
Contributor

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

@hauntsaninja hauntsaninja merged commit 1f0ab28 into python:master Jan 13, 2026
23 checks passed
@A5rocks A5rocks deleted the empty-tuple-paramspec branch January 13, 2026 06:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ParamSpec should accept empty tuple

2 participants