Skip to content

Commit 3d3e482

Browse files
authored
Fix cases of type object handling for overloads (#16168)
Fixes most of #12320. I didn't add tests for every code path because it's niche. I also didn't fix everything, in particular the cases where we proceed to use `ret_type`
1 parent 7a62481 commit 3d3e482

File tree

7 files changed

+21
-13
lines changed

7 files changed

+21
-13
lines changed

mypy/checker.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2986,7 +2986,7 @@ def check_assignment(
29862986
p_rvalue_type = get_proper_type(rvalue_type)
29872987
p_lvalue_type = get_proper_type(lvalue_type)
29882988
if (
2989-
isinstance(p_rvalue_type, CallableType)
2989+
isinstance(p_rvalue_type, FunctionLike)
29902990
and p_rvalue_type.is_type_obj()
29912991
and (
29922992
p_rvalue_type.type_object().is_abstract
@@ -3771,7 +3771,7 @@ def split_around_star(
37713771

37723772
def type_is_iterable(self, type: Type) -> bool:
37733773
type = get_proper_type(type)
3774-
if isinstance(type, CallableType) and type.is_type_obj():
3774+
if isinstance(type, FunctionLike) and type.is_type_obj():
37753775
type = type.fallback
37763776
return is_subtype(
37773777
type, self.named_generic_type("typing.Iterable", [AnyType(TypeOfAny.special_form)])

mypy/checkexpr.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,7 @@ def check_runtime_protocol_test(self, e: CallExpr) -> None:
694694
for expr in mypy.checker.flatten(e.args[1]):
695695
tp = get_proper_type(self.chk.lookup_type(expr))
696696
if (
697-
isinstance(tp, CallableType)
697+
isinstance(tp, FunctionLike)
698698
and tp.is_type_obj()
699699
and tp.type_object().is_protocol
700700
and not tp.type_object().runtime_protocol
@@ -704,7 +704,7 @@ def check_runtime_protocol_test(self, e: CallExpr) -> None:
704704
def check_protocol_issubclass(self, e: CallExpr) -> None:
705705
for expr in mypy.checker.flatten(e.args[1]):
706706
tp = get_proper_type(self.chk.lookup_type(expr))
707-
if isinstance(tp, CallableType) and tp.is_type_obj() and tp.type_object().is_protocol:
707+
if isinstance(tp, FunctionLike) and tp.is_type_obj() and tp.type_object().is_protocol:
708708
attr_members = non_method_protocol_members(tp.type_object())
709709
if attr_members:
710710
self.chk.msg.report_non_method_protocol(tp.type_object(), attr_members, e)
@@ -4190,7 +4190,7 @@ def visit_index_with_type(
41904190
elif isinstance(left_type, TypedDictType):
41914191
return self.visit_typeddict_index_expr(left_type, e.index)
41924192
elif (
4193-
isinstance(left_type, CallableType)
4193+
isinstance(left_type, FunctionLike)
41944194
and left_type.is_type_obj()
41954195
and left_type.type_object().is_enum
41964196
):
@@ -5832,7 +5832,7 @@ def has_abstract_type_part(self, caller_type: ProperType, callee_type: ProperTyp
58325832

58335833
def has_abstract_type(self, caller_type: ProperType, callee_type: ProperType) -> bool:
58345834
return (
5835-
isinstance(caller_type, CallableType)
5835+
isinstance(caller_type, FunctionLike)
58365836
and isinstance(callee_type, TypeType)
58375837
and caller_type.is_type_obj()
58385838
and (caller_type.type_object().is_abstract or caller_type.type_object().is_protocol)

mypy/messages.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ def has_no_attr(
416416
elif member == "__getitem__":
417417
# Indexed get.
418418
# TODO: Fix this consistently in format_type
419-
if isinstance(original_type, CallableType) and original_type.is_type_obj():
419+
if isinstance(original_type, FunctionLike) and original_type.is_type_obj():
420420
self.fail(
421421
"The type {} is not generic and not indexable".format(
422422
format_type(original_type, self.options)

mypy/plugins/proper_plugin.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
from mypy.subtypes import is_proper_subtype
1818
from mypy.types import (
1919
AnyType,
20-
CallableType,
2120
FunctionLike,
2221
Instance,
2322
NoneTyp,
@@ -131,7 +130,7 @@ def is_dangerous_target(typ: ProperType) -> bool:
131130
"""Is this a dangerous target (right argument) for an isinstance() check?"""
132131
if isinstance(typ, TupleType):
133132
return any(is_dangerous_target(get_proper_type(t)) for t in typ.items)
134-
if isinstance(typ, CallableType) and typ.is_type_obj():
133+
if isinstance(typ, FunctionLike) and typ.is_type_obj():
135134
return typ.type_object().has_base("mypy.types.Type")
136135
return False
137136

mypy/typeops.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -989,7 +989,7 @@ def custom_special_method(typ: Type, name: str, check_all: bool = False) -> bool
989989
return any(custom_special_method(t, name) for t in typ.items)
990990
if isinstance(typ, TupleType):
991991
return custom_special_method(tuple_fallback(typ), name, check_all)
992-
if isinstance(typ, CallableType) and typ.is_type_obj():
992+
if isinstance(typ, FunctionLike) and typ.is_type_obj():
993993
# Look up __method__ on the metaclass for class objects.
994994
return custom_special_method(typ.fallback, name, check_all)
995995
if isinstance(typ, AnyType):

test-data/unit/check-abstract.test

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ f(GoodAlias)
241241

242242
[case testInstantiationAbstractsInTypeForVariables]
243243
# flags: --no-strict-optional
244-
from typing import Type
244+
from typing import Type, overload
245245
from abc import abstractmethod
246246

247247
class A:
@@ -269,6 +269,15 @@ if int():
269269
var_old = B # E: Can only assign concrete classes to a variable of type "Type[A]"
270270
if int():
271271
var_old = C # OK
272+
273+
class D(A):
274+
@overload
275+
def __new__(cls, a) -> "D": ...
276+
@overload
277+
def __new__(cls) -> "D": ...
278+
def __new__(cls, a=None) -> "D": ...
279+
if int():
280+
var = D # E: Can only assign concrete classes to a variable of type "Type[A]"
272281
[out]
273282

274283
[case testInstantiationAbstractsInTypeForClassMethods]

test-data/unit/pythoneval.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,9 +1801,9 @@ C = str | int
18011801
D: TypeAlias = str | int
18021802
[out]
18031803
_testTypeAliasNotSupportedWithNewStyleUnion.py:3: error: Invalid type alias: expression is not a valid type
1804-
_testTypeAliasNotSupportedWithNewStyleUnion.py:3: error: Value of type "Type[type]" is not indexable
1804+
_testTypeAliasNotSupportedWithNewStyleUnion.py:3: error: The type "Type[type]" is not generic and not indexable
18051805
_testTypeAliasNotSupportedWithNewStyleUnion.py:4: error: Invalid type alias: expression is not a valid type
1806-
_testTypeAliasNotSupportedWithNewStyleUnion.py:4: error: Value of type "Type[type]" is not indexable
1806+
_testTypeAliasNotSupportedWithNewStyleUnion.py:4: error: The type "Type[type]" is not generic and not indexable
18071807
_testTypeAliasNotSupportedWithNewStyleUnion.py:5: error: Invalid type alias: expression is not a valid type
18081808
_testTypeAliasNotSupportedWithNewStyleUnion.py:5: error: Unsupported left operand type for | ("Type[str]")
18091809
_testTypeAliasNotSupportedWithNewStyleUnion.py:6: error: Invalid type alias: expression is not a valid type

0 commit comments

Comments
 (0)