python / python/mypy

Please add documentation about needing to re-define inherited overload signatures

Offen
#10,699 1 Kommentar 2 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

documentation topic-inheritance topic-overloads topic-usability
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

Documentation

The documentation you have is pretty good, it usually saves me time.

I, unfortunately, spent too much time today trying to find the right keywords in your documentation, and the issues, trying to find the most pythonic solution for inherited overload signatures:

from __future__ import annotations

import abc
from typing import Literal, Mapping, overload


class AdapterBase(abc.ABC):
    @overload
    def get_map_or_value(self, *, as_dict: Literal[True]) -> Mapping[str, str]:
        ...

    @overload
    def get_map_or_value(self, *, as_dict: Literal[False] = ...) -> str:
        ...

    @overload
    def get_map_or_value(self, *, as_dict: bool = ...) -> Mapping[str, str] | str:
        ...

    @abc.abstractmethod
    def get_map_or_value(self, *, as_dict: bool = False) -> Mapping[str, str] | str:
        raise NotImplementedError


class ConcreteAdapter1(AdapterBase):
    # fails strict no-untyped-def checks
    def get_map_or_value(self, *, as_dict):
        if as_dict:
            return {"somekey": "somevalue"}
        return "somevalue"


class ConcreteAdapter2(AdapterBase):
    # Signature of "get_map_or_value" incompatible with supertype "AdapterBase" [override]
    def get_map_or_value(self, *, as_dict: bool = False) -> Mapping[str, str] | str:
        if as_dict:
            return {"someOtherKey": "someOtherValue"}
        return "someOtherValue"


class DoSomethingElse:
    def __init__(self, adapter: AdapterBase) -> None:
        # needs to know about function names, parameters, and return types
        self.adapter = adapter

My intuition in this scenario told me that the overloads could be inherited, and thus I just needed to provide the generic typedef and go on my merry way. That is, clearly, not the case and it took me a while to find #5146, and consequently, https://github.com/python/typing/issues/269.

It would be nice if the documentation could mention that overload variants need to be re-defined in child/concrete classes. It would also clarify that this "edge case", or ones similar to it, is not an edge case, it's by design.

Here are some places where I went looking for answers, and perhaps someone else might too:

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit dem Lesen der verlinkten Abschnitte zu Gültigkeit von Überschreibungen, literalen Typen, Aufrufen überladener Funktionen und abstrakten Basisklassen und sieh dir anschließend die Issues #5146 und typing#269 an, um den Designkontext zu verstehen. Aktualisiere die relevante Dokumentation und erkläre darin, dass abgeleitete oder konkrete Klassen geerbte Überladungsvarianten erneut deklarieren müssen und dass dieses Verhalten beabsichtigt ist; das referenzierte Beispiel sollte klar abgedeckt werden.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
documentation
Issue-Typ
Dokumentation
Schwierigkeit
2/5
Geschätzter Aufwand
1-3 Stunden
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
45/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.