python / mypy

Optional static typing for Python
https://www.mypy-lang.org/
Other
18.57k stars 2.85k forks source link

Support typing.Union/typing.Optional in isinstance check (/support old-style unions) #17680

Open bram-tv opened 3 months ago

bram-tv commented 3 months ago

Preamble

Feature

Example code

from typing import Any, Union, Optional

foo: Any = None

if isinstance(foo, int | None):
    reveal_type(foo)

if isinstance(foo, Union[int, None]):
    reveal_type(foo)

if isinstance(foo, Optional[int]):
    reveal_type(foo)

bar = int | None
baz = Optional[int]
if isinstance(foo, bar):
    reveal_type(foo)

if isinstance(foo, baz):
    reveal_type(foo)

Output for the above with mypy v1.11.1:

src/union.py:6: note: Revealed type is "Union[builtins.int, None]"
src/union.py:8: error: Argument 2 to "isinstance" has incompatible type "<typing special form>"; expected "_ClassInfo"  [arg-type]
src/union.py:9: note: Revealed type is "Any"
src/union.py:11: error: Argument 2 to "isinstance" has incompatible type "<typing special form>"; expected "_ClassInfo"  [arg-type]
src/union.py:12: note: Revealed type is "Any"
src/union.py:17: note: Revealed type is "Union[builtins.int, None]"
src/union.py:19: error: Parameterized generics cannot be used with class or instance checks  [misc]
src/union.py:19: error: Argument 2 to "isinstance" has incompatible type "<typing special form>"; expected "_ClassInfo"  [arg-type]
src/union.py:20: note: Revealed type is "Any"
Found 4 errors in 1 file (checked 1 source file)

Running the above with pyright:

.../src/union.py
  .../src/union.py:6:17 - information: Type of "foo" is "int | None"
  .../src/union.py:9:17 - information: Type of "foo" is "int | None"
  .../src/union.py:12:17 - information: Type of "foo" is "int | None"
  .../src/union.py:17:17 - information: Type of "foo" is "int | None"
  .../src/union.py:20:17 - information: Type of "foo" is "int | None"
0 errors, 0 warnings, 5 informations

Summary:

hauntsaninja commented 3 months ago

PR welcome. IIRC isinstance on old-style unions is only supported on 3.10 and newer