Skip to content

Commit

Permalink
Improvements to functools.partial of types (#17898)
Browse files Browse the repository at this point in the history
Fixes #17556 , fixes
#17659
  • Loading branch information
hauntsaninja authored Oct 9, 2024
1 parent b0db694 commit 621c7aa
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 4 deletions.
8 changes: 4 additions & 4 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -686,10 +686,10 @@ def extract_callable_type(self, inner_type: Type | None, ctx: Context) -> Callab
if isinstance(inner_type, TypeVarLikeType):
inner_type = get_proper_type(inner_type.upper_bound)
if isinstance(inner_type, TypeType):
if isinstance(inner_type.item, Instance):
inner_type = expand_type_by_instance(
type_object_type(inner_type.item.type, self.named_type), inner_type.item
)
inner_type = get_proper_type(
self.expr_checker.analyze_type_type_callee(inner_type.item, ctx)
)

if isinstance(inner_type, CallableType):
outer_type = inner_type
elif isinstance(inner_type, Instance):
Expand Down
36 changes: 36 additions & 0 deletions test-data/unit/check-functools.test
Original file line number Diff line number Diff line change
Expand Up @@ -557,3 +557,39 @@ def bar(f: S) -> S:
g = functools.partial(f, "foo")
return f
[builtins fixtures/primitives.pyi]


[case testFunctoolsPartialAbstractType]
# flags: --python-version 3.9
from abc import ABC, abstractmethod
from functools import partial

class A(ABC):
def __init__(self) -> None: ...
@abstractmethod
def method(self) -> None: ...

def f1(cls: type[A]) -> None:
cls()
partial_cls = partial(cls)
partial_cls()

def f2() -> None:
A() # E: Cannot instantiate abstract class "A" with abstract attribute "method"
partial_cls = partial(A) # E: Cannot instantiate abstract class "A" with abstract attribute "method"
partial_cls() # E: Cannot instantiate abstract class "A" with abstract attribute "method"
[builtins fixtures/tuple.pyi]


[case testFunctoolsPartialSelfType]
from functools import partial
from typing_extensions import Self

class A:
def __init__(self, ts: float, msg: str) -> None: ...

@classmethod
def from_msg(cls, msg: str) -> Self:
factory = partial(cls, ts=0)
return factory(msg=msg)
[builtins fixtures/tuple.pyi]
2 changes: 2 additions & 0 deletions test-data/unit/lib-stub/typing_extensions.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ Required: _SpecialForm
NotRequired: _SpecialForm
ReadOnly: _SpecialForm

Self: _SpecialForm

@final
class TypeAliasType:
def __init__(
Expand Down

0 comments on commit 621c7aa

Please sign in to comment.