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

isinstance doesn't work on type aliases that use a union #11673

Closed
DetachHead opened this issue Dec 7, 2021 · 10 comments · Fixed by #17371
Closed

isinstance doesn't work on type aliases that use a union #11673

DetachHead opened this issue Dec 7, 2021 · 10 comments · Fixed by #17371
Labels
bug mypy got something wrong topic-pep-604 PEP 604 (union | operator) topic-runtime-semantics mypy doesn't model runtime semantics correctly topic-type-alias TypeAlias and other type alias issues

Comments

@DetachHead
Copy link
Contributor

DetachHead commented Dec 7, 2021

Foo = int | str

foo: object

isinstance(foo, Foo) # error
isinstance(foo, int | str) # no error

https://mypy-play.net/?mypy=master&python=3.10&gist=da37bef9ace54d59c18631a0a9f5bef2

@DetachHead DetachHead added the bug mypy got something wrong label Dec 7, 2021
@sobolevn
Copy link
Member

sobolevn commented Dec 7, 2021

I've also added explicit TypeAlias to this example, it also raises an error:

from typing import TypeAlias

A = int | str
B: TypeAlias = int | str

foo: object

isinstance(foo, A)  # error
isinstance(foo, B)  # error 
isinstance(foo, int | str)  # no error, but should be?

Output:

out/ex.py:8: error: Parameterized generics cannot be used with class or instance checks
out/ex.py:8: error: Argument 2 to "isinstance" has incompatible type "object"; expected "Union[type, UnionType, Tuple[Union[type, UnionType, Tuple[Any, ...]], ...]]"
out/ex.py:9: error: Parameterized generics cannot be used with class or instance checks
out/ex.py:9: error: Argument 2 to "isinstance" has incompatible type "object"; expected "Union[type, UnionType, Tuple[Union[type, UnionType, Tuple[Any, ...]], ...]]"

@sobolevn
Copy link
Member

sobolevn commented Dec 7, 2021

In runtime isinstance(1, int | str) works just fine:

>>> isinstance(1, int | str)
True
>>> isinstance(b'', int | str)
False

So, I guess the problem is that isinstance(foo, A) raises. In my opinion B should not be used as a value, when having explicit TypeAlias declaration.

@esoma
Copy link
Contributor

esoma commented Dec 8, 2021

Half of this is fixed in #11650

error: Parameterized generics cannot be used with class or instance checks will still occur if that is merged. It's something I looked into early on, but didn't want to complicate that PR further.

@sobolevn
Copy link
Member

sobolevn commented Dec 8, 2021

@esoma awesome! Thank you! 👍

@dgutson
Copy link

dgutson commented May 4, 2023

Half of this is fixed in #11650

error: Parameterized generics cannot be used with class or instance checks will still occur if that is merged. It's something I looked into early on, but didn't want to complicate that PR further.

@esoma so what's next? This is indeed still happening.
CC @qequ

@esoma
Copy link
Contributor

esoma commented May 4, 2023

@dgutson That PR didn't receive much attention and I don't use mypy anymore so I haven't pursued it any further.

@Gunni
Copy link

Gunni commented Nov 13, 2023

This is still broken.

error: Parameterized generics cannot be used with class or instance checks [misc]

error: Argument 2 to "isinstance" has incompatible type ""; expected "_ClassInfo" [arg-type]

import ipaddress as i
from typing import TypeAlias, TypeVar

IPAddress: TypeAlias = i.IPv4Address | i.IPv6Address
IPInterface: TypeAlias = i.IPv4Interface | i.IPv6Interface

_T = TypeVar('_T', bound=IPInterface | IPAddress)

def get_sort_key(ip: _T) -> tuple[int, IPAddress]:
	# https://github.com/python/mypy/issues/11673
	ipaddr = ip.ip if isinstance(ip, IPInterface) else ip
	return i.get_mixed_type_key(ipaddr)


def sort_ips(addresses: set[_T]) -> list[_T]:
	return sorted(addresses, key=get_sort_key)

@DetachHead
Copy link
Contributor Author

@esoma out of curiosity, which type checker did you switch to?

@sobolevn
Copy link
Member

The main problem is that we don't pass uses_pep604_syntax information anywhere in the code.
So, it is impossible to separate Union[str, int] from int | str later in the code, where this error happens.

@esoma
Copy link
Contributor

esoma commented Nov 13, 2023

@DetachHead
I probably should have said I generally don't use the python typing system anymore -- don't want to derail this issue with details. When I do I still use mypy.

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) topic-runtime-semantics mypy doesn't model runtime semantics correctly topic-type-alias TypeAlias and other type alias issues
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants