Paramspec Mapped Types
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 1.8k
- Forks
- 302
- Merge moyen
- 23 h
- PR mergées (30 j)
- 8
Description
Apologies if this has already been asked/solved - I can't figure out exactly what this is called so it's very difficult to search for.
I'm writing a simple strongly typed dependency system, based on function closures. I have a decorator function that has this typing:
# This is a stand-in for a full class implementation that has a __call__ method matching
# Callable[P, Awaitable[R]] - I'm just omitting it for brevity
type CallableObject[**P, R] = Callable[P, Awaitable[R]]
def dependency[**P, R](*args: P.args, **kwargs: P.kwargs) -> Callable[
[Callable[P, Awaitable[R]] | Callable[P, R]], CallableObject
]:
...
This works to a degree, but, I want to transform the arguments in P to also accept functions that return the arguments type or an Awaitable of that type. For example:
def one() -> int:
return 1
def two() -> int:
return 2
@dependency()
def three(one: int, two: int) -> int:
return one + two
# I want the decorated three to have this signature
def decorated_three(one: int | Callable[..., Awaitable[int] | int], two: int | Callable[..., Awaitable[int] | int]) -> int:
...
Essentially, I want to apply a mapping to every arg and kwarg in P that transforms it into P | Callable[..., Awaitable[P] | P]. Is this possible with the current grammar?
As a reference, I wrote an example that does what I'm attempting to do in typescript, where you can unpack what they call "type tuples" using the keyof syntax to mutate their values:
function dependency<P extends unknown[], R>(wrap: (...args: P) => R): (...args: {[V in keyof P]: P[V] | ((...args: any) => P[V] | Promise<P[V]>)}) => R {
return wrap as any
}
function one(): number { return 1 }
function two(): number { return 2 }
function three(one: number, two: number): number { return one + two }
// Has type: const decorated_three: (one: number | ((...args: any) => number | Promise<number>), two: number | ((...args: any) => number | Promise<number>)) => number;
const decorated_three = dependency(three)
(Playground where you can see / verify the typing works as expected)
Apologies for dragging in another type system/language - I'm just looking for the python equivalent (if it exists).
Appreciate the help in advance. If this is a duplicate, please close it and mark it with the correct issue - I just couldn't find it 😅
Guide de contribution
Aucun guide de contribution indexé pour ce dépôt
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par les exemples de ParamSpec et la signature décorée demandée dans l’issue, puis examinez la grammaire actuelle de Python typing pour les parameter packs et les types callable. Comparez la transformation souhaitée pour chaque paramètre avec l’exemple TypeScript lié de mapped-tuple ; le travail est considéré comme terminé lorsqu’il a été établi si la grammaire permet de l’exprimer et que l’équivalent pris en charge ou la limitation a été documenté.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- python
- Domaine
- developer-experience
- Type d'issue
- Fonctionnalité
- Difficulté
- 5/5
- Temps estimé
- Plus d'une semaine
- Activité
- Active
- Clarté
- Plutôt claire
- Accessibilité débutants
- 38/100