python / python/mypy

Abstract settable properties are not fully supported

Aperta
#13,649 2 commenti 2 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

bug
Lingua principale
Python
Stelle
20.6k
Fork
3.3k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

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:

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia riproducendo gli esempi di setter astratto e getter/setter astratti dell’issue e confronta le diagnosi di mypy con il comportamento di Python a runtime. Traccia la gestione delle proprietà e dei setter astratti, quindi aggiungi la copertura necessaria affinché il caso del setter astratto riporti la diagnostica prevista per un attributo astratto o un setter di proprietà, senza introdurre regressioni nel comportamento esistente del getter.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
devtools
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
38/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.