Skip to content

Commit c692943

Browse files
hauntsaninjaJukkaL
authored andcommitted
Improvements to functools.partial of types (#17898)
Fixes #17556 , fixes #17659
1 parent ba68974 commit c692943

File tree

3 files changed

+42
-4
lines changed

3 files changed

+42
-4
lines changed

mypy/checker.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -686,10 +686,10 @@ def extract_callable_type(self, inner_type: Type | None, ctx: Context) -> Callab
686686
if isinstance(inner_type, TypeVarLikeType):
687687
inner_type = get_proper_type(inner_type.upper_bound)
688688
if isinstance(inner_type, TypeType):
689-
if isinstance(inner_type.item, Instance):
690-
inner_type = expand_type_by_instance(
691-
type_object_type(inner_type.item.type, self.named_type), inner_type.item
692-
)
689+
inner_type = get_proper_type(
690+
self.expr_checker.analyze_type_type_callee(inner_type.item, ctx)
691+
)
692+
693693
if isinstance(inner_type, CallableType):
694694
outer_type = inner_type
695695
elif isinstance(inner_type, Instance):

test-data/unit/check-functools.test

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,3 +557,39 @@ def bar(f: S) -> S:
557557
g = functools.partial(f, "foo")
558558
return f
559559
[builtins fixtures/primitives.pyi]
560+
561+
562+
[case testFunctoolsPartialAbstractType]
563+
# flags: --python-version 3.9
564+
from abc import ABC, abstractmethod
565+
from functools import partial
566+
567+
class A(ABC):
568+
def __init__(self) -> None: ...
569+
@abstractmethod
570+
def method(self) -> None: ...
571+
572+
def f1(cls: type[A]) -> None:
573+
cls()
574+
partial_cls = partial(cls)
575+
partial_cls()
576+
577+
def f2() -> None:
578+
A() # E: Cannot instantiate abstract class "A" with abstract attribute "method"
579+
partial_cls = partial(A) # E: Cannot instantiate abstract class "A" with abstract attribute "method"
580+
partial_cls() # E: Cannot instantiate abstract class "A" with abstract attribute "method"
581+
[builtins fixtures/tuple.pyi]
582+
583+
584+
[case testFunctoolsPartialSelfType]
585+
from functools import partial
586+
from typing_extensions import Self
587+
588+
class A:
589+
def __init__(self, ts: float, msg: str) -> None: ...
590+
591+
@classmethod
592+
def from_msg(cls, msg: str) -> Self:
593+
factory = partial(cls, ts=0)
594+
return factory(msg=msg)
595+
[builtins fixtures/tuple.pyi]

test-data/unit/lib-stub/typing_extensions.pyi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ Required: _SpecialForm
4343
NotRequired: _SpecialForm
4444
ReadOnly: _SpecialForm
4545

46+
Self: _SpecialForm
47+
4648
@final
4749
class TypeAliasType:
4850
def __init__(

0 commit comments

Comments
 (0)