Raise errors on unbound TypeVars with values (#15732)
Completes a `TODO` item :)
Refs https://github.com/python/mypy/issues/15724
---------
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
diff --git a/mypy/checker.py b/mypy/checker.py
index f2873c7..724a1dd 100644
--- a/mypy/checker.py
+++ b/mypy/checker.py
@@ -1069,6 +1069,7 @@
"""Type check a function definition."""
# Expand type variables with value restrictions to ordinary types.
expanded = self.expand_typevars(defn, typ)
+ original_typ = typ
for item, typ in expanded:
old_binder = self.binder
self.binder = ConditionalTypeBinder()
@@ -1126,6 +1127,12 @@
message_registry.RETURN_TYPE_CANNOT_BE_CONTRAVARIANT, typ.ret_type
)
self.check_unbound_return_typevar(typ)
+ elif (
+ isinstance(original_typ.ret_type, TypeVarType) and original_typ.ret_type.values
+ ):
+ # Since type vars with values are expanded, the return type is changed
+ # to a raw value. This is a hack to get it back.
+ self.check_unbound_return_typevar(original_typ)
# Check that Generator functions have the appropriate return type.
if defn.is_generator:
diff --git a/test-data/unit/check-typevar-unbound.test b/test-data/unit/check-typevar-unbound.test
index d3e54c7..ed6beaa 100644
--- a/test-data/unit/check-typevar-unbound.test
+++ b/test-data/unit/check-typevar-unbound.test
@@ -15,8 +15,7 @@
V = TypeVar('V', int, str)
-# TODO: this should also give an error
-def h() -> V:
+def h() -> V: # E: A function returning TypeVar should receive at least one argument containing the same TypeVar
...
[case testInnerFunctionTypeVar]
diff --git a/test-data/unit/deps-generics.test b/test-data/unit/deps-generics.test
index c78f3fa..6baa572 100644
--- a/test-data/unit/deps-generics.test
+++ b/test-data/unit/deps-generics.test
@@ -159,7 +159,7 @@
T = TypeVar('T', A, B)
S = TypeVar('S', C, D)
-def f(x: T) -> S:
+def f(x: T, y: S) -> S:
pass
[out]
<m.A> -> <m.T>, <m.f>, m, m.A, m.f