type[Union[A, B, ...]] produces false bad-specialization error when passed to constrained TypeVar parameter
Author: mfish33Created Jul 10, 2026Updated Sep 22, 2026
Labelstypecheckingneeds-triage
Describe the Bug
Passing a value of type type[A | B | C] to a parameter typed type[T] where T is a constrained TypeVar produces a spurious bad-specialization error, even when every member of the union individually satisfies a constraint.
Reproducer
from typing import TypeVar, Union
TPrimitive = TypeVar("TPrimitive", str, bool, float, int, bytes, None)
ScalarValue = Union[str, bool, float, int, bytes, None]
PRIMITIVE_TYPES: dict[str, type[ScalarValue]] = {
"S8": int,
"double": float,
"char": str,
}
def assertPrimitive(expectedType: type[TPrimitive]) -> TPrimitive: ...
expectedType = PRIMITIVE_TYPES["S8"]
assertPrimitive(expectedType)Actual: bool | bytes | float | int | str | None is not assignable to any of constraints str, bool, float, int, bytes, None of type variable TPrimitive [bad-specialization]
Expected: No error. Each member of the union independently satisfies a constraint of TPrimitive.
Note: mypy, pyright, and ty all fail with this same false positive issue
Sandbox Link
(Only applicable for extension issues) IDE Information
No response
Source: facebook/pyrefly