From 0acf922fd4ce8c6bb6addf3b8c84be44215f65c8 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Wed, 19 Jul 2023 08:51:57 +0900 Subject: [PATCH 1/4] Implement intersection on TypeVars --- mypy/meet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/meet.py b/mypy/meet.py index 29c4d3663503..9aaf875b8d28 100644 --- a/mypy/meet.py +++ b/mypy/meet.py @@ -683,7 +683,7 @@ def visit_type_var(self, t: TypeVarType) -> ProperType: if isinstance(self.s, TypeVarType) and self.s.id == t.id: return self.s else: - return self.default(self.s) + return t.copy_modified(upper_bound=meet_types(t.upper_bound, self.s)) def visit_param_spec(self, t: ParamSpecType) -> ProperType: if self.s == t: From a2fcd0f98efaf16dfd66669459c92cddca35a4b4 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Wed, 19 Jul 2023 09:26:51 +0900 Subject: [PATCH 2/4] Only affect instances --- mypy/meet.py | 13 +++++-------- mypy/test/testtypes.py | 4 +++- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/mypy/meet.py b/mypy/meet.py index 9aaf875b8d28..f9fa732dfa72 100644 --- a/mypy/meet.py +++ b/mypy/meet.py @@ -682,8 +682,11 @@ def visit_erased_type(self, t: ErasedType) -> ProperType: def visit_type_var(self, t: TypeVarType) -> ProperType: if isinstance(self.s, TypeVarType) and self.s.id == t.id: return self.s - else: + # this may be alright on things other than just instances + elif isinstance(self.s, Instance): return t.copy_modified(upper_bound=meet_types(t.upper_bound, self.s)) + else: + return self.default(self.s) def visit_param_spec(self, t: ParamSpecType) -> ProperType: if self.s == t: @@ -753,13 +756,7 @@ def visit_instance(self, t: Instance) -> ProperType: if is_subtype(self.s.fallback, t): return self.s return self.default(self.s) - elif isinstance(self.s, TypeType): - return meet_types(t, self.s) - elif isinstance(self.s, TupleType): - return meet_types(t, self.s) - elif isinstance(self.s, LiteralType): - return meet_types(t, self.s) - elif isinstance(self.s, TypedDictType): + elif isinstance(self.s, (TypeType, TupleType, LiteralType, TypedDictType, TypeVarType)): return meet_types(t, self.s) return self.default(self.s) diff --git a/mypy/test/testtypes.py b/mypy/test/testtypes.py index b1f21b3be79b..89afabe674d3 100644 --- a/mypy/test/testtypes.py +++ b/mypy/test/testtypes.py @@ -1135,7 +1135,9 @@ def test_simple_generics(self) -> None: self.assert_meet(self.fx.ga, self.fx.nonet, self.fx.nonet) self.assert_meet(self.fx.ga, self.fx.anyt, self.fx.ga) - for t in [self.fx.a, self.fx.t, self.tuple(), self.callable(self.fx.a, self.fx.b)]: + self.assert_meet(self.fx.t, self.fx.ga, self.fx.t) + + for t in [self.fx.a, self.tuple(), self.callable(self.fx.a, self.fx.b)]: self.assert_meet(t, self.fx.ga, self.fx.nonet) def test_generics_with_multiple_args(self) -> None: From 1aab932595a48b999c2923d4b7387252a546e470 Mon Sep 17 00:00:00 2001 From: A5rocks Date: Wed, 19 Jul 2023 09:32:53 +0900 Subject: [PATCH 3/4] Also work on unions, I suppose --- mypy/meet.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mypy/meet.py b/mypy/meet.py index f9fa732dfa72..eec4f396f665 100644 --- a/mypy/meet.py +++ b/mypy/meet.py @@ -685,6 +685,8 @@ def visit_type_var(self, t: TypeVarType) -> ProperType: # this may be alright on things other than just instances elif isinstance(self.s, Instance): return t.copy_modified(upper_bound=meet_types(t.upper_bound, self.s)) + elif isinstance(self.s, UnionType): + return meet_types(t, self.s) else: return self.default(self.s) From e4917e13868e2b36aa0b12cf5b6f5b563ddf89ec Mon Sep 17 00:00:00 2001 From: A5rocks Date: Wed, 19 Jul 2023 10:00:07 +0900 Subject: [PATCH 4/4] Handle tuples and Nones too, I suppose --- mypy/meet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/meet.py b/mypy/meet.py index eec4f396f665..6f22925727b8 100644 --- a/mypy/meet.py +++ b/mypy/meet.py @@ -683,7 +683,7 @@ def visit_type_var(self, t: TypeVarType) -> ProperType: if isinstance(self.s, TypeVarType) and self.s.id == t.id: return self.s # this may be alright on things other than just instances - elif isinstance(self.s, Instance): + elif isinstance(self.s, (Instance, NoneType, TupleType)): return t.copy_modified(upper_bound=meet_types(t.upper_bound, self.s)) elif isinstance(self.s, UnionType): return meet_types(t, self.s)