Skip to content

False negative when inferring paramspec for a class constructor #2587

@Wizzerinus

Description

@Wizzerinus

Summary

The following playground link emits no errors:

from typing import Generic, ParamSpec, Protocol

P = ParamSpec("P")


class ParentClass:
    pass


class MyProto(Protocol, Generic[P]):
    def __call__(self, *args: P.args, **kwargs: P.kwargs) -> ParentClass: ...


class MyType(ParentClass):
    def __init__(self, x: int):
        pass


def create(p: MyProto[P], *args: P.args, **kwargs: P.kwargs):
    pass


create(MyType)

https://play.ty.dev/8273c9c2-da7f-4432-982d-71bba5c60dbe

However, this code is not sound.

To typecheck this method, P must be inferred empty:

def create(p: MyProto[P], *args: P.args, **kwargs: P.kwargs):
    pass


create(MyType)

Hence, the function must accept no parameters except self:

class MyProto(Protocol, Generic[P]):
    def __call__(self, *args: P.args, **kwargs: P.kwargs) -> ParentClass: ...

However, MyType is defined as follows:

class MyType(ParentClass):
    def __init__(self, x: int):
        pass

So it cannot be called with no parameters. (This is not about self being considered a parameter - the result is the same regardless of how many parameters __init__ wants here.)

Version

0.0.13

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions