#11741·pyright

TypeForm rejects a union when types are nested and metaclass defines __get__

Author: nickshirobokovCreated Sep 11, 2026Updated Sep 12, 2026
Labelsbug

Describe the bug I defined a metaclass with __get__ returning cls unchanged, nested classes constructed from this metaclass, and a union of the nested classes as a TypeForm. The bug: this TypeForm then rejects appropriate unions.

Code or Screenshots

python
from typing_extensions import TypeForm

class Meta(type):
    def __get__[T: Meta](
        cls: T,
        instance: object | None,
        owner: type | None = None,
    ) -> T:
        return cls

class Owner:
    class A(metaclass=Meta):
        pass

    class B(metaclass=Meta):
        pass

T1: TypeForm[Owner.A | Owner.B] = Owner.A # Accepted
T2: TypeForm[Owner.A | Owner.B] = Owner.B # Accepted
T3: TypeForm[Owner.A | Owner.B] = Owner.A | Owner.B # Rejected:

# Type "UnionType" is not assignable to declared type "TypeForm[A | B]"
# "UnionType" is not assignable to "TypeForm[A | B]"

Module-scoped classes doesn't have this bug.

python
from typing_extensions import TypeForm

class Meta(type):
    def __get__[T: Meta](
        cls: T,
        instance: object | None,
        owner: type | None = None,
    ) -> T:
        return cls

class A(metaclass=Meta):
    pass

class B(metaclass=Meta):
    pass


T1: TypeForm[A | B] = A # Accepted
T2: TypeForm[A | B] = B # Accepted
T3: TypeForm[A | B] = A | B # Accepted

Removing get also makes the bug disappear.

python
from typing_extensions import TypeForm

class Meta(type):
    pass

class Owner:
    class A(metaclass=Meta):
        pass

    class B(metaclass=Meta):
        pass


T1: TypeForm[Owner.A | Owner.B] = Owner.A # Accepted
T2: TypeForm[Owner.A | Owner.B] = Owner.B # Accepted
T3: TypeForm[Owner.A | Owner.B] = Owner.A | Owner.B # Accepted

VS Code extension or command-line

  • Pyright v1.1.414 both CLI and Pylance
  • Python 3.14.7
  • typing_extensions 4.16.0