Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Class Generic ParamSpec cannot be used in Callable #12011

Closed
isra17 opened this issue Jan 18, 2022 · 5 comments
Closed

Class Generic ParamSpec cannot be used in Callable #12011

isra17 opened this issue Jan 18, 2022 · 5 comments
Labels
affects-typeshed Anything that blocks a typeshed change bug mypy got something wrong topic-paramspec PEP 612, ParamSpec, Concatenate

Comments

@isra17
Copy link

isra17 commented Jan 18, 2022

Bug Report

Mypy doesn't seem to support a Generic class with a ParamSpec argument to use this ParamSpec in an inherited generic class.

eg:

import typing as t

TCallable = t.TypeVar("TCallable", bound=t.Callable[..., t.Any])
P = t.ParamSpec("P")

class X(t.Generic[TCallable]):
  pass  
  
class Y(t.Generic[P], X[t.Callable[P, t.Any]]): # error: The first argument to Callable must be a list of types or "..."
  pass

To Reproduce

https://mypy-play.net/?mypy=master&python=3.10&gist=9edf71a609a6a1fe5764db342beaa710

This code seems to work on Pyright

Expected Behavior

The code above should pass.

Actual Behavior

The code above have an error: error: The first argument to Callable must be a list of types or "...". This error seems to be from some codepath unaware of ParamSpec.

Your Environment

  • Mypy version used: 0.931 and master
  • Python version used: 3.10
@isra17 isra17 added the bug mypy got something wrong label Jan 18, 2022
@isra17
Copy link
Author

isra17 commented Jan 18, 2022

A colleague made a good even more minimal use-case which seems to be the actual root cause:

import typing as t

P = t.ParamSpec("P")
R = t.TypeVar("R")

class Callable(t.Generic[P, R]):
  pass

class Y( 
    t.Generic[P],
    Callable[P, t.Any], # error: ParamSpec "P" is unbound
): 
  pass

Quickly debugging Mypy shows the Callable error comes from:

return None

@JelleZijlstra JelleZijlstra added the topic-paramspec PEP 612, ParamSpec, Concatenate label Mar 19, 2022
@AlexWaygood
Copy link
Member

AlexWaygood commented Apr 28, 2022

Reproduced on mypy 0.950 (and on mypy master as of 27/04/2022):

from typing import Generic, ParamSpec

P = ParamSpec("P")
class Foo(Generic[P]): ...
class Bar(Foo[P]): ...  # error: ParamSpec "P" is unbound

@AlexWaygood
Copy link
Member

AlexWaygood commented Apr 29, 2022

@A5rocks / @cdce8p, do either of you have any idea where the error in mypy is here?

The specific line immediately responsible for emitting the error is here, but I'm struggling to get much further than that:

self.fail('ParamSpec "{}" is unbound'.format(t.name), t)

@A5rocks
Copy link
Collaborator

A5rocks commented Feb 12, 2023

This seems fixed as of mypy 1.0

@hauntsaninja
Copy link
Collaborator

Thanks :-)

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
affects-typeshed Anything that blocks a typeshed change bug mypy got something wrong topic-paramspec PEP 612, ParamSpec, Concatenate
Projects
None yet
Development

No branches or pull requests

5 participants