From ce309a974da449b02cf3df0203c7b0d30438a7ce Mon Sep 17 00:00:00 2001 From: elazar Date: Sun, 4 Jun 2017 18:32:08 +0300 Subject: [PATCH 1/2] fall to metaclass in overload --- mypy/checkexpr.py | 4 ++++ test-data/unit/check-classes.test | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 6e0bb9ff8168..838d7b4ab722 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -2651,8 +2651,12 @@ def overload_arg_similarity(actual: Type, formal: Type) -> int: else: return 0 elif isinstance(actual, TypeType): + item = actual.item if formal.type.fullname() in {"builtins.object", "builtins.type"}: return 2 + elif isinstance(item, Instance): + # FIX: this does not handle e.g. Union of instances + return overload_arg_similarity(item.type.metaclass_type, formal) else: return 0 else: diff --git a/test-data/unit/check-classes.test b/test-data/unit/check-classes.test index f2b83290cb60..7eafa2b9c233 100644 --- a/test-data/unit/check-classes.test +++ b/test-data/unit/check-classes.test @@ -3290,6 +3290,24 @@ x3: M = cv [builtins fixtures/classmethod.pyi] +[case testMetaclassOverloadResolution] +from typing import Type, overload + +class EM(type): pass +class E(metaclass=EM): pass + +@overload +def f(x: EM) -> int: return 0 +@overload +def f(x: str) -> str: return '' +def f(x: object) -> object: return '' + +e1: EM +reveal_type(f(e1)) # E: Revealed type is 'builtins.int' + +e2: Type[E] +reveal_type(f(e2)) # E: Revealed type is 'builtins.int' + -- Synthetic types crashes -- ----------------------- From 0946d1f2d18104912852c7e89e20c559d4d09139 Mon Sep 17 00:00:00 2001 From: elazar Date: Sun, 25 Jun 2017 19:24:05 +0300 Subject: [PATCH 2/2] add test cases to the test --- test-data/unit/check-classes.test | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/test-data/unit/check-classes.test b/test-data/unit/check-classes.test index 7eafa2b9c233..78337dde5279 100644 --- a/test-data/unit/check-classes.test +++ b/test-data/unit/check-classes.test @@ -3292,21 +3292,35 @@ x3: M = cv [case testMetaclassOverloadResolution] from typing import Type, overload +class A: pass class EM(type): pass class E(metaclass=EM): pass +class EM1(type): pass +class E1(metaclass=EM1): pass + +@overload +def f(x: EM) -> int: ... @overload -def f(x: EM) -> int: return 0 +def f(x: EM1) -> A: ... @overload -def f(x: str) -> str: return '' +def f(x: str) -> str: ... def f(x: object) -> object: return '' -e1: EM -reveal_type(f(e1)) # E: Revealed type is 'builtins.int' +e: EM +reveal_type(f(e)) # E: Revealed type is 'builtins.int' + +et: Type[E] +reveal_type(f(et)) # E: Revealed type is 'builtins.int' + +e1: EM1 +reveal_type(f(e1)) # E: Revealed type is '__main__.A' + +e1t: Type[E1] +reveal_type(f(e1t)) # E: Revealed type is '__main__.A' -e2: Type[E] -reveal_type(f(e2)) # E: Revealed type is 'builtins.int' +reveal_type(f('')) # E: Revealed type is 'builtins.str' -- Synthetic types crashes -- -----------------------