Annotate sync/async code via Generic | generic TypeVar / Type aliases in Generic
Nessuno ha ancora preso questa issue.
- Lingua principale
- Python
- Stelle
- 1.8k
- Fork
- 302
- Merge medio
- 23h
- PR unite (30g)
- 8
Descrizione
Consider this case:
import asyncio
from typing import Any, Coroutine, Generic, TypeVar
from httpx import AsyncClient, Client, Response
ClientT = TypeVar("ClientT", bound=Client | AsyncClient)
class API(Generic[ClientT]):
client: ClientT
def __init__(self, client: ClientT) -> None:
self.client = client
def get_items(self) -> Response | Coroutine[Any, Any, Response]:
return self.client.request('get', 'https://example.com/api/v1/get_items')
response = API[Client](Client()).get_items()
response.json() # Item "Coroutine[Any, Any, Response]" of "Union[Response, Coroutine[Any, Any, Response]]" has no attribute "json" [union-attr]
response_coroutine = API[AsyncClient](AsyncClient()).get_items()
asyncio.run(response_coroutine) # Argument 1 to "run" has incompatible type "Union[Response, Coroutine[Any, Any, Response]]"; expected "Awaitable[Response]" [arg-type]mypy(error)
How can I express bound between ClientT and return type of API().get_items()?
How it could look like if Generic would support type aliases or TypeVar supported another type variables:
import asyncio
from typing import Annotated, Any, Awaitable, Coroutine, Generic, TypeVar
from typing_extensions import reveal_type
from httpx import AsyncClient, Client, Response
ClientT = TypeVar("ClientT", bound=Client | AsyncClient)
T = TypeVar("T")
# Using Annotated just as generic type that returns its argument as is
Sync = Annotated[T, ...]
MightBeAwaitable = TypeVar("MightBeAwaitable", bound=Awaitable | Sync)
# or MightBeAwaitable = Awaitable | Sync
class API(Generic[ClientT, MightBeAwaitable):
client: ClientT
def __init__(self, client: ClientT) -> None:
self.client = client
def get_items(self) -> MightBeAwaitable[Response]: # TypeError: 'TypeVar' object is not subscriptable
return self.client.request('get', 'https://example.com/api/v1/get_items')
response = API[Client, Sync](Client()).get_items()
reveal_type(response) # Revealed type is "Response"
response_coroutine = API[AsyncClient, Awaitable](AsyncClient()).get_items()
reveal_type(response_coroutine) # Revealed type is "typing.Awaitable[Any]"
Sorry if it's the wrong place/type for this issue.
Guida per i contributori
Nessuna guida per i contributori indicizzata per questo repository
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia dagli esempi Python di questo issue e dai costrutti di tipizzazione che utilizzano: Generic, TypeVar, alias di tipo, Annotated, Awaitable e Coroutine. Determina la relazione prevista tra il tipo del client e il tipo restituito da get_items(), quindi documenta un design di tipizzazione supportato e i tipi rivelati attesi.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- python
- Ambito
- developer-experience
- Tipo di issue
- Funzionalità
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Stato di attività
- Ferma
- Chiarezza
- Da chiarire
- Idoneità per principianti
- 20/100