Skip to content

Support type[SomeProtocol] #903

@tpgillam

Description

@tpgillam

Question

With ty 0.0.1-alpha16, consider the following:

from __future__ import annotations

import dataclasses
import typing

if typing.TYPE_CHECKING:
    import _typeshed


def moo1(cls: _typeshed.DataclassInstance) -> None:
    print(cls)


def moo2(cls: type[_typeshed.DataclassInstance]) -> None:
    print(cls)


def moo3[T: _typeshed.DataclassInstance](cls: type[T]) -> None:
    print(cls)


@dataclasses.dataclass
class A:
    a: int


moo1(A(1))  # ty happy
moo2(A)     # ty unhappy
moo3(A)     # ty happy

Then uvx ty check will give the following output:

error[invalid-argument-type]: Argument to function `moo2` is incorrect
  --> moo2.py:28:6
   |
27 | moo1(A(1))
28 | moo2(A)
   |      ^ Expected `type[DataclassInstance]`, found `<class 'A'>`
29 | moo3(A)
   |
info: Function defined here
  --> moo2.py:14:5
   |
14 | def moo2(cls: type[_typeshed.DataclassInstance]) -> None:
   |     ^^^^ -------------------------------------- Parameter declared here
15 |     print(cls)
   |
info: rule `invalid-argument-type` is enabled by default

Found 1 diagnostic

Is this expected / correct behaviour? pyright will accept all the calls.

Since DataclassInstance is a protocol it seems plausible that type[DataclassInstance] might be poorly defined (I don't know the ins-and-outs of the typing spec) ... but if that were the case then I'm mildly surprised that ty doesn't complain about:

from collections.abc import Sequence

def moo4(a: type[Sequence]) -> None:
    print(a)

moo4(list)

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions