Also allow TypeAliasType in isinstance and issubclass

The old way to annotate aliases, TypeAlias (TypeT: TypeAlias = int | str) is currently supported in isinstance and issubclass checks.

Since 3.12 we have new, better type aliases, TypeAliasType, which are created by putting type before the name of the alias.

x = StringNode(...)

TextNodeT = StringNode | IdentifierNode

if issubclass(type, TextNodeT):
    ...
else:
    ...

This works at type checking and runtime currently, but this does not:

x = StringNode(...)

type TextNodeT = StringNode | IdentifierNode

if issubclass(type, TextNodeT):
    ...
else:
    ...

Is there a reason we don’t support both? Does it have to do how 3.14 introduced later evaluation of type expressions and if so, can we work it out?

Here is the issue where support for TypeAlias type was added for isinstance and issubclass:

Yeah, it’s this. We don’t support isinstance or issubclass on string-literal forward references either:

ForwardRefType = "int | str"
isinstance(0, ForwardRefType) # TypeError: isinstance() arg 2 must be a type, a tuple of types, or a union
issubclass(int, ForwardRefType) # TypeError: issubclass() arg 2 must be a class, a tuple of classes, or a union

We could probably use TypeAliasType.__value__. I’d imagine this would have the following effects:

  • A small runtime cost on non-alias, exception-raising isinstance and issubclass calls (since we’d have to check for TypeAliasType if the initial check fails).
  • The potential to make isinstance and issubclass expensive if the second argument is indeed a TypeAliasType.

Neither’s immediately fatal, I’d imagine, but they’re worth considering.

Only sometimes.

from typing import TypeAlias

Foo: TypeAlias = int | str
isinstance(1, Foo) # Works

Bar: TypeAlias = int | list[str]
isinstance(["a"], Bar) # TypeError: isinstance() argument 2 cannot be a parameterized generic

I don’t think TypeAliasType should support this as long as it can go from “working” to “not working” because someone added another member to the union.