From ecb5148c607a97250eae74eab7396b930fc5f57a Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 21 Jul 2023 09:23:57 +0300 Subject: [PATCH 1/3] Raise errors on unbound TypeVars with values --- mypy/checker.py | 5 +++++ test-data/unit/check-typevar-unbound.test | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index f2873c7d58e40..ff219b06f7bf8 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -1069,6 +1069,7 @@ def check_func_def( """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,10 @@ def check_func_def( 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 d3e54c75e373a..ed6beaa100db0 100644 --- a/test-data/unit/check-typevar-unbound.test +++ b/test-data/unit/check-typevar-unbound.test @@ -15,8 +15,7 @@ def g() -> U: # E: A function returning TypeVar should receive at least one argu 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] From 4d8d59f50f53d94da27defe6abd76591d66921f8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 21 Jul 2023 06:25:04 +0000 Subject: [PATCH 2/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mypy/checker.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mypy/checker.py b/mypy/checker.py index ff219b06f7bf8..724a1dd1f7d73 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -1127,7 +1127,9 @@ def check_func_def( 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: + 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) From c7204f385baa04440c575aa4442f3a9f7ef75699 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 21 Jul 2023 09:54:54 +0300 Subject: [PATCH 3/3] Fix CI --- test-data/unit/deps-generics.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-data/unit/deps-generics.test b/test-data/unit/deps-generics.test index c78f3fad90c0d..6baa57266d2f5 100644 --- a/test-data/unit/deps-generics.test +++ b/test-data/unit/deps-generics.test @@ -159,7 +159,7 @@ class D: pass 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, m.A, m.f