Skip to content

Invalid union types in isinstance() calls are not detected when nested in tuples #1600

@AlexWaygood

Description

@AlexWaygood

Summary

We currently emit a diagnostic when an invalid types.UnionType instance is used as the second argument to isinstance() or issubclass(). But we do not currently detect this if the types.UnionType instance is nested inside a tuple.

It's probably not high-priority to fix this because I'm not sure why you'd write code like this, but it's a known edge case that we don't handle currently, so it seemed worth opening an issue about.

from typing import Literal

def f(x):
    if isinstance(x, str | Literal[42]):  # diagnostic (good! this fails at runtime)
        reveal_type(x)

    if isinstance(x, (int, str | Literal[42])):  # no diagnostic
        reveal_type(x)  # revealed: Unknown

    if isinstance(x, (int, (str, (bytes, memoryview | Literal[42])))):  # no diagnostic
        reveal_type(x)  # revealed: Unknown

At runtime:

Python 3.13.1 (main, Jan  3 2025, 12:04:03) [Clang 15.0.0 (clang-1500.3.9.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from typing import Literal
>>> if isinstance(42, (bytes, str | int)):
...     print('got you')
...     
got you
>>> if isinstance(42, (bytes, str | Literal[42])):
...     print('got you')
...     
Traceback (most recent call last):
  File "<python-input-3>", line 1, in <module>
    if isinstance(42, (bytes, str | Literal[42])):
       ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/alexw/.pyenv/versions/3.13.1/lib/python3.13/typing.py", line 1786, in __instancecheck__
    return self.__subclasscheck__(type(obj))
           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
  File "/Users/alexw/.pyenv/versions/3.13.1/lib/python3.13/typing.py", line 1790, in __subclasscheck__
    if issubclass(cls, arg):
       ~~~~~~~~~~^^^^^^^^^^
  File "/Users/alexw/.pyenv/versions/3.13.1/lib/python3.13/typing.py", line 1378, in __subclasscheck__
    raise TypeError("Subscripted generics cannot be used with"
                    " class and instance checks")
TypeError: Subscripted generics cannot be used with class and instance checks

Version

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    runtime semanticsAccurate modeling of how Python's semantics work at runtime

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions