Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Unexpected error behaviour: Parameterized generics cannot be used with class or instance checks #12155

Closed
JohanSchott opened this issue Feb 9, 2022 · 6 comments · Fixed by #17371
Labels
bug mypy got something wrong topic-pep-604 PEP 604 (union | operator)

Comments

@JohanSchott
Copy link

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?

@JelleZijlstra
Copy link
Member

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.

@AlexWaygood AlexWaygood added the bug mypy got something wrong label Mar 28, 2022
@lindycoder
Copy link

lindycoder commented Aug 1, 2023

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)

@tibbe
Copy link

tibbe commented Aug 31, 2023

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."

@brandon-neth
Copy link

I'm also wondering about the status on this.

@hunterC90
Copy link

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.

@JelleZijlstra JelleZijlstra added the topic-pep-604 PEP 604 (union | operator) label Feb 22, 2024
@msetina
Copy link

msetina commented Apr 24, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-pep-604 PEP 604 (union | operator)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants