mypy
mypy copied to clipboard
Unexpected error behaviour: Parameterized generics cannot be used with class or instance checks
mypy
reports success for
import numpy as np
x = "a"
assert isinstance(x, np.float64)
but fails for
from numpy import float64
x = "a"
assert isinstance(x, float64)
with the error fails.py:3: error: Parameterized generics cannot be used with class or instance checks
I'm using mypy
(0.931) and numpy
(1.22.2).
Why do I get different results?
Interesting. float64 is defined here: https://github.com/numpy/numpy/blob/51abd9693a78907f2ca7dfacee2017ef44fb9f49/numpy/init.pyi#L2973. It's obviously meant as a type alias, but apparently mypy sometimes interprets it as a variable assignment.
I have the same issue with Unions
version:
$ mypy --version
mypy 1.4.1 (compiled: yes)
$ python --version
Python 3.10.9
Config:
[tool.mypy]
namespace_packages=true
explicit_package_bases=true
strict=true
show_error_codes=true
Code
from dataclasses import dataclass
@dataclass
class A:
val_a: str
@dataclass
class B:
val_b: str
ABUnion = A|B
obj = A(val_a="hey")
assert isinstance(obj, ABUnion)
Result:
$ mypy check.py
check.py:16: error: Parameterized generics cannot be used with class or instance checks [misc]
check.py:16: error: Argument 2 to "isinstance" has incompatible type "<typing special form>"; expected "_ClassInfo" [arg-type]
Found 2 errors in 1 file (checked 1 source file)
Code works fine
Thank you!
Edit: One solution is to use get_args on the union
from typing import get_args
assert isinstance(obj, get_args(ABUnion))
This passes both code and check, but does not work as a type guard
Edit 2:
This work as type guard with a TypeGuard
, obj
is correctly scoped to a shorter set of the union
from dataclasses import dataclass
from typing import get_args, TypeGuard
@dataclass
class A:
val_a: str
common: str
@dataclass
class B:
val_b: str
common: str
@dataclass
class C: # no common
val_c: str
ABUnion = A|B # has common
ABCUnion = A|B|C
obj: ABCUnion = A(val_a="hey", common="common")
def is_ab(val: ABCUnion) -> TypeGuard[ABUnion]:
return type(val) in get_args(ABUnion)
if is_ab(obj):
print(obj.common)
Any status update?
Note that isinstance
is defined as working on unions: "If classinfo is a tuple of type objects (or recursively, other such tuples) or a Union Type of multiple types, return True if object is an instance of any of the types."
I'm also wondering about the status on this.
Should this have the label topic-pep-604
? I'm not 100% sure but it seems like it when I look at others open issues that have the label.
Any new development on mitigating this. I am using cryptography and their aliases are not disected properly and even get_args does not help to mark object as suitable. Also a Union of child classes is not properly inspected when variable of object is of parent class but the object is of child class.