From 31e6b456d085f6153b13298a981fdb18c11d1dee Mon Sep 17 00:00:00 2001 From: TH3CHARLie Date: Fri, 6 Dec 2019 13:48:46 +0800 Subject: [PATCH 1/4] fix 8050 in solution 2 --- mypy/join.py | 5 +++++ mypy/meet.py | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/mypy/join.py b/mypy/join.py index 5f1d292d65e2..ec1bd8c0a944 100644 --- a/mypy/join.py +++ b/mypy/join.py @@ -187,6 +187,11 @@ def visit_callable_type(self, t: CallableType) -> ProperType: if is_equivalent(t, self.s): return combine_similar_callables(t, self.s) result = join_similar_callables(t, self.s) + # unless some or all items represent abstract objects, + # we set the flag: from_type_type to True + if not ((t.is_type_obj() and t.type_object().is_abstract) or + (self.s.is_type_obj() and self.s.type_object().is_abstract)): + result.from_type_type = True if any(isinstance(tp, (NoneType, UninhabitedType)) for tp in get_proper_types(result.arg_types)): # We don't want to return unusable Callable, attempt fallback instead. diff --git a/mypy/meet.py b/mypy/meet.py index 6e9c68d29529..219c4ed73852 100644 --- a/mypy/meet.py +++ b/mypy/meet.py @@ -533,6 +533,11 @@ def visit_callable_type(self, t: CallableType) -> ProperType: if is_equivalent(t, self.s): return combine_similar_callables(t, self.s) result = meet_similar_callables(t, self.s) + # unless some or all items represent abstract objects, + # we set the flag: from_type_type to True + if not ((t.is_type_obj() and t.type_object().is_abstract) or + (self.s.is_type_obj() and self.s.type_object().is_abstract)): + result.from_type_type = True if isinstance(get_proper_type(result.ret_type), UninhabitedType): # Return a plain None or instead of a weird function. return self.default(self.s) From 9c863ea8cccc7d3acbb6e9db43bb3182e11c2ee1 Mon Sep 17 00:00:00 2001 From: TH3CHARLie Date: Fri, 6 Dec 2019 14:28:08 +0800 Subject: [PATCH 2/4] add test, fix indentation --- mypy/join.py | 2 +- mypy/meet.py | 2 +- test-data/unit/check-abstract.test | 48 ++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/mypy/join.py b/mypy/join.py index ec1bd8c0a944..668718aa6168 100644 --- a/mypy/join.py +++ b/mypy/join.py @@ -190,7 +190,7 @@ def visit_callable_type(self, t: CallableType) -> ProperType: # unless some or all items represent abstract objects, # we set the flag: from_type_type to True if not ((t.is_type_obj() and t.type_object().is_abstract) or - (self.s.is_type_obj() and self.s.type_object().is_abstract)): + (self.s.is_type_obj() and self.s.type_object().is_abstract)): result.from_type_type = True if any(isinstance(tp, (NoneType, UninhabitedType)) for tp in get_proper_types(result.arg_types)): diff --git a/mypy/meet.py b/mypy/meet.py index 219c4ed73852..b5a9c899d1d5 100644 --- a/mypy/meet.py +++ b/mypy/meet.py @@ -536,7 +536,7 @@ def visit_callable_type(self, t: CallableType) -> ProperType: # unless some or all items represent abstract objects, # we set the flag: from_type_type to True if not ((t.is_type_obj() and t.type_object().is_abstract) or - (self.s.is_type_obj() and self.s.type_object().is_abstract)): + (self.s.is_type_obj() and self.s.type_object().is_abstract)): result.from_type_type = True if isinstance(get_proper_type(result.ret_type), UninhabitedType): # Return a plain None or instead of a weird function. diff --git a/test-data/unit/check-abstract.test b/test-data/unit/check-abstract.test index 692943083fa5..1fcbf8bf9f4e 100644 --- a/test-data/unit/check-abstract.test +++ b/test-data/unit/check-abstract.test @@ -951,3 +951,51 @@ default = Config({'cannot': 'modify'}) # OK default[1] = 2 # E: Unsupported target for indexed assignment [builtins fixtures/dict.pyi] [typing fixtures/typing-full.pyi] + +[case testSubclassOfABCFromDictionary] +from abc import abstractmethod, ABCMeta + +class MyAbstractType(metaclass=ABCMeta): + @abstractmethod + def do(self): pass + +class MyConcreteA(MyAbstractType): + def do(self): + print('A') + +class MyConcreteB(MyAbstractType): + def do(self): + print('B') + +class MyAbstractA(MyAbstractType): + @abstractmethod + def do(self): pass + +class MyAbstractB(MyAbstractType): + @abstractmethod + def do(self): pass + +my_concrete_types = { + 'A': MyConcreteA, + 'B': MyConcreteB, +} + +my_abstract_types = { + 'A': MyAbstractA, + 'B': MyAbstractB, +} + +reveal_type(my_concrete_types) # N: Revealed type is 'builtins.dict[builtins.str*, def () -> __main__.MyAbstractType]' +reveal_type(my_abstract_types) # N: Revealed type is 'builtins.dict[builtins.str*, def () -> __main__.MyAbstractType]' + +a = my_concrete_types['A']() +a.do() +b = my_concrete_types['B']() +b.do() + +c = my_abstract_types['A']() # E: Cannot instantiate abstract class 'MyAbstractType' with abstract attribute 'do' +c.do() +d = my_abstract_types['B']() # E: Cannot instantiate abstract class 'MyAbstractType' with abstract attribute 'do' +d.do() + +[builtins fixtures/dict.pyi] From 239fa1c463396147ca329e8597eb8dd4cce2c3a2 Mon Sep 17 00:00:00 2001 From: TH3CHARLie Date: Sat, 7 Dec 2019 08:21:43 +0800 Subject: [PATCH 3/4] change comments --- mypy/join.py | 4 ++-- mypy/meet.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mypy/join.py b/mypy/join.py index 668718aa6168..2595a64473c5 100644 --- a/mypy/join.py +++ b/mypy/join.py @@ -187,8 +187,8 @@ def visit_callable_type(self, t: CallableType) -> ProperType: if is_equivalent(t, self.s): return combine_similar_callables(t, self.s) result = join_similar_callables(t, self.s) - # unless some or all items represent abstract objects, - # we set the flag: from_type_type to True + # We set the from_type_type flag to suppress error when a collection of + # concrete class objects gets inferred as their common abstract superclass. if not ((t.is_type_obj() and t.type_object().is_abstract) or (self.s.is_type_obj() and self.s.type_object().is_abstract)): result.from_type_type = True diff --git a/mypy/meet.py b/mypy/meet.py index b5a9c899d1d5..21baba053c33 100644 --- a/mypy/meet.py +++ b/mypy/meet.py @@ -533,8 +533,8 @@ def visit_callable_type(self, t: CallableType) -> ProperType: if is_equivalent(t, self.s): return combine_similar_callables(t, self.s) result = meet_similar_callables(t, self.s) - # unless some or all items represent abstract objects, - # we set the flag: from_type_type to True + # We set the from_type_type flag to suppress error when a collection of + # concrete class objects gets inferred as their common abstract superclass. if not ((t.is_type_obj() and t.type_object().is_abstract) or (self.s.is_type_obj() and self.s.type_object().is_abstract)): result.from_type_type = True From 24ca2ddc33b5e3d149370806da2b744748cffa2a Mon Sep 17 00:00:00 2001 From: TH3CHARLie Date: Sat, 7 Dec 2019 09:55:14 +0800 Subject: [PATCH 4/4] remove whitespaces --- mypy/join.py | 2 +- mypy/meet.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mypy/join.py b/mypy/join.py index 2595a64473c5..8989a596b70e 100644 --- a/mypy/join.py +++ b/mypy/join.py @@ -187,7 +187,7 @@ def visit_callable_type(self, t: CallableType) -> ProperType: if is_equivalent(t, self.s): return combine_similar_callables(t, self.s) result = join_similar_callables(t, self.s) - # We set the from_type_type flag to suppress error when a collection of + # We set the from_type_type flag to suppress error when a collection of # concrete class objects gets inferred as their common abstract superclass. if not ((t.is_type_obj() and t.type_object().is_abstract) or (self.s.is_type_obj() and self.s.type_object().is_abstract)): diff --git a/mypy/meet.py b/mypy/meet.py index 21baba053c33..608faf8f25fe 100644 --- a/mypy/meet.py +++ b/mypy/meet.py @@ -533,7 +533,7 @@ def visit_callable_type(self, t: CallableType) -> ProperType: if is_equivalent(t, self.s): return combine_similar_callables(t, self.s) result = meet_similar_callables(t, self.s) - # We set the from_type_type flag to suppress error when a collection of + # We set the from_type_type flag to suppress error when a collection of # concrete class objects gets inferred as their common abstract superclass. if not ((t.is_type_obj() and t.type_object().is_abstract) or (self.s.is_type_obj() and self.s.type_object().is_abstract)): pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy