python / python/mypy

Abstract settable properties are not fully supported

Open
#13,649 2 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

Python docs say that properties can have individual abstract parts: https://docs.python.org/3/library/abc.html#abc.abstractproperty

So, let's see what mypy thinks about it.

abstract getter

import abc

class Base(abc.ABC):
    @property
    @abc.abstractmethod
    def x(self) -> int: ...

class Child(Base):
    ...

c = Child()  # error: Cannot instantiate abstract class "Child" with abstract attribute "x"

It is supported ✅

abstract setter

import abc

class Base(abc.ABC):
    @property
    def x(self) -> int: ...

    @x.setter
    @abc.abstractmethod
    def x(self, arg: int) -> None: ...

class Child(Base):
    ...

c = Child()
c.x = 2
reveal_type(c)  # Revealed type is "ex.Child"
# Runtime:
# TypeError: Can't instantiate abstract class Child with abstract method x

Not supported 🚫

Should instead say: # error: Cannot instantiate abstract class "Child" with abstract attribute "x"
Or even better with abstract property setter "x"

abstract getter and setter

import abc

class Base(abc.ABC):
    @property
    @abc.abstractmethod
    def x(self) -> int: ...

    @x.setter
    @abc.abstractmethod
    def x(self, arg: int) -> None: ...

class Child(Base):
    ...

c = Child()  # E: Cannot instantiate abstract class "Child" with abstract attribute "x"

However, this does not fully cover this case:

import abc

class Base(abc.ABC):
    @property
    @abc.abstractmethod
    def x(self) -> int: ...

    @x.setter
    @abc.abstractmethod
    def x(self, arg: int) -> None: ...

class Child(Base):
    @property  # E: Read-only property cannot override read-write property
    def x(self) -> int: ...

Child()  # ok

We can add additional note about x.setter being abstract. Or we can keep this as is.

Related:

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the abstract-setter and abstract getter/setter examples from the issue and compare mypy's diagnostics with Python's runtime behavior. Trace the handling of abstract properties and setters, then add coverage so the abstract setter case reports the expected abstract attribute or property-setter diagnostic without regressing the existing getter behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.