python / python/typing

How to alias `Annotated` to a subscriptable type

Offen
#779 3 Kommentare 2 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

topic: feature
Vorherrschende Sprache
Python
Sterne
1.8k
Forks
302
Ø Merge
23 Std.
Gemergte PRs (30 T.)
8

Beschreibung

Hi, I want to create a type alias that simply wraps a tuple into Annotated.

PEP 593

I want to be able to write

SpecialReturn[int, bool, str]

And get

Annotated[Tuple[int, bool, str], 'special return!']

Among other things, I've tried:

class SpecialReturn():
    def __class_getitem__(self, params: Tuple[Any, ...]) -> Tuple[Any, ...]:
        return typing.cast(
            Tuple[Any, ...],
            _typing.Annotated[
                typing.Tuple.__getitem__(params),
                'multiple_return',
            ]
        )

Which mypy is happy with the declaration, but not using it:

import typing

from typing import Annotated, Any, Tuple


class SpecialReturn():
    def __class_getitem__(self, params: Tuple[Any, ...]) -> Tuple[Any, ...]:
        return typing.cast(
            Tuple[Any, ...],
            Annotated[
                typing.Tuple.__getitem__(params),
                'multiple_return',
            ]
        )


def test() -> SpecialReturn[int, int]:
    return 1, 2
test8.py:17: error: "SpecialReturn" expects no type arguments, but 2 given
test8.py:18: error: Incompatible return value type (got "Tuple[int, int]", expected "SpecialReturn")

Which happens because I guess mypy does not evaluate the type annotation, it just treats SpecialReturn as a separate type. I am not sure what is the reasoning behind this, but I assume there it makes sense in some way(?).

So, is there any alternative? How do achieve this? I essentially want to alias Tuple and be able to find out at runtime if the type is a normal tuple or my special one.

My first jab at this, and what I think makes most sense to a Python developer is the following

from typing import Tuple


class SpecialReturn(Tuple):
    pass


def test() -> SpecialReturn[int, int]:
    return 1, 2

But mypy can't handle it either:

test.py:4: error: Missing type parameters for generic type "Tuple"
test.py:8: error: "SpecialReturn" expects no type arguments, but 2 given
test.py:9: error: Incompatible return value type (got "Tuple[int, int]", expected "SpecialReturn")

I was thinking maybe something like this was possible with Annotated, but it seems not.

Beitragsleitfaden

Für dieses Repository ist kein Beitragsleitfaden indexiert

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 von PEP 593 und den Beispielen in diesem Issue und überprüfe anschließend, wie das typing project Annotated, generische Aliase und class_getitem darstellt. Das Issue nennt keine Datei, keinen Test und keinen Implementierungseinstiegspunkt; für den Abschluss müsste geklärt werden, ob dieses Verhalten unterstützt werden sollte und wie es spezifiziert werden sollte.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
devtools
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Muss geklärt werden
Anfängerfreundlichkeit
20/100

Neue Issues direkt in Ihr Postfach

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