Open KotlinIsland opened 5 months ago
The type
class in the builtins.pyi
stub file is defined as:
class type:
...
def __init__(self, name: str, bases: tuple[type, ...], dict: dict[str, Any], /, **kwds: Any) -> None: ...
...
def __call__(self, *args: Any, **kwds: Any) -> Any: ...
Based on this definition, mypy is working correctly. Not surprisingly, its behavior matches the other major type checkers here.
If you think that typeshed definition is incorrect or could be improved, you could file a bug report or PR in the typeshed project.
if these type checkers were just following the stubs, then I would expect A("a")
to behave identically to A.__call__("a")
and not show an error. The truth is that currently type checkers are special casing type.__call__
, but only the operator form, and not the attribute form.
The truth is that currently type checkers are special casing type.call, but only the operator form, and not the attribute form.
Yes, that's conformant with the recently accepted typing spec chapter on constructor call validation. Mypy is doing the right thing here according to the typing spec, and so are the other type checkers.
If you would like to suggest a change to the typing spec, the typing forum would be a good place to have that discussion.
Type checkers should mirror this runtime behavior when analyzing a constructor call.
Type checkers are not mirroring this runtime behavior correctly in this case.
That spec should be updated to be more explicit about how to mirror the runtime behavior (to match this case), the type-checkers should be updated to match the runtime behaviour, and typeshed could be updated to have the correct type.
The typing spec says:
So mypy is checking that usages of the call syntax (
()
) are conforming to the constructor type, but the functionally identical call attribute__call__
. This is against the spec, which specifies that type checkers should mirror the behavior that__call__
will invoke__new__
and__init__