Repository: python/mypy
Issue category: Bug Report

Issue:
[1.12 regression] New error on type[memoryView] | type[str]
**Bug Report**

new to 1.12.0
incorrect error message on union of two type one being memoryview

Complete file checked:

"""
a_type: type[memoryview] | type[str] = memoryview
"""

mypy 1.11.2 no error

mypy 1.12.0
Incompatible default for argument "a_type" (default has type "type[memoryview[Any]]", argument has type "type[memoryview[int]] | type[str]")

**Your Environment**
github action ubuntu various , python various

- Mypy command-line flags:
-no flags
- Mypy configuration options from `mypy.ini` (and other config files):
- None
- Python version used: via github actions
3.8, 3.9, 3.10, 3.11, 3.12 and 3.13 

while
"""
a_type: type[memoryview] = memoryview
""""
Works ok!




Hints:

Patch:
diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py
index b06aaa8f89f5..08d7345452fb 100644
--- a/mypy/checkexpr.py
+++ b/mypy/checkexpr.py
@@ -399,8 +399,8 @@ def analyze_ref_expr(self, e: RefExpr, lvalue: bool = False) -> Type:
                 # TODO: always do this in type_object_type by passing the original context
                 result.ret_type.line = e.line
                 result.ret_type.column = e.column
-            if isinstance(get_proper_type(self.type_context[-1]), TypeType):
-                # This is the type in a Type[] expression, so substitute type
+            if is_type_type_context(self.type_context[-1]):
+                # This is the type in a type[] expression, so substitute type
                 # variables with Any.
                 result = erasetype.erase_typevars(result)
         elif isinstance(node, MypyFile):
@@ -6617,3 +6617,12 @@ def get_partial_instance_type(t: Type | None) -> PartialType | None:
     if t is None or not isinstance(t, PartialType) or t.type is None:
         return None
     return t
+
+
+def is_type_type_context(context: Type | None) -> bool:
+    context = get_proper_type(context)
+    if isinstance(context, TypeType):
+        return True
+    if isinstance(context, UnionType):
+        return any(is_type_type_context(item) for item in context.items)
+    return False


Test patch:
diff --git a/test-data/unit/check-typevar-defaults.test b/test-data/unit/check-typevar-defaults.test
index 9ca67376da26..22e2594eb38b 100644
--- a/test-data/unit/check-typevar-defaults.test
+++ b/test-data/unit/check-typevar-defaults.test
@@ -717,3 +717,15 @@ def func_d3(
     reveal_type(c)  # N: Revealed type is "__main__.B[__main__.A[builtins.dict[builtins.int, builtins.float]]]"
     reveal_type(d)  # N: Revealed type is "__main__.B[builtins.int]"
 [builtins fixtures/dict.pyi]
+
+[case testTypeVarDefaultsAndTypeObjectTypeInUnion]
+from __future__ import annotations
+from typing import Generic
+from typing_extensions import TypeVar
+
+_I = TypeVar("_I", default=int)
+
+class C(Generic[_I]): pass
+
+t: type[C] | int = C
+[builtins fixtures/tuple.pyi]