Skip to content

type[A] cannot be instantiated via partial if A is abstract #17556

Closed
@iutlu

Description

@iutlu

For a variable cls annotated as cls: type[A] where A is an ABC, the semantics from #2853 suggest that mypy resolves the type of the variable to concrete subclasses of A. The semantics do not seem to apply if the referenced concrete subclass is not instantiated directly via cls(), but rather via a partial as in partial(cls, *args, **kwargs)().

Mypy complains with cannot instantiate abstract class errors if a class variable referencing a presumed-concrete subclass of an ABC is invoked via partial:

To Reproduce

from abc import ABC, abstractmethod
from functools import partial
from typing import final


class A(ABC):
    @final
    def __init__(self, *, x: object, y: object) -> None:
        self.x = x
        self.y = y

    @abstractmethod
    def m(self) -> None:
        pass


class C(A):
    def m(self) -> None:
        """Implementation."""


def fun(cls: type[A]) -> None:
    cls(x=3, y=5)  # allowed
    partial_cls = partial(cls, x=3, y=5)  # cannot instantiate abstract class A
    partial_cls()  # cannot instantiate abstract class A

Expected Behavior

I'd have expected this to work, since if cls in the above example refers to a concrete subclass per #2853, it should be legal to use partial on it.

Instead, we get

Cannot instantiate abstract class "A" with abstract attribute "m"Mypy[abstract](https://mypy.readthedocs.io/en/latest/_refs.html#code-abstract)

Your Environment

  • Mypy version used: 1.11
  • Mypy configuration options from mypy.ini (and other config files):
[tool.mypy]
disallow_any_generics = true
disallow_subclassing_any = true
disallow_incomplete_defs = true
disallow_untyped_decorators = true
warn_redundant_casts = true
warn_unused_ignores = true
warn_return_any = true
warn_unreachable = true
implicit_reexport = false
strict_equality = true
show_column_numbers = true
enable_incomplete_feature = ["NewGenericSyntax"]
plugins = [
  'pydantic.mypy',
  'pydantic.v1.mypy'
]
  • Python version used: 3.12

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions