python / python/typing

Suggestion: Allow free type variables in type variable bounds that permeate beyond

Ouverte
#1,311 1 commentaire 7 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

topic: feature
Langage dominant
Python
Étoiles
1.8k
Forks
302
Merge moyen
23 h
PR mergées (30 j)
8

Description

Suppose we have the following code:

T_co = TypeVar("T_co", covariant=True)

class CanProduce(Protocol[T_co]):
    def produce(self) -> T_co:
        ...

T_in = TypeVar("T_in")
U = TypeVar("U")

@dataclass
class Container(Generic[T_in]):
    value: T_in

    def produce_from_value(self: Container[CanProduce[U]]) -> U:
        return self.value.produce()

This code has an undesirable property: Since T_in is invariant, produce_from_value can only be called on instances of Container whose type parameter is exactly CanProduce[U], for some U:

class IntProducer(CanProduce[int]):
    def produce(self) -> int:
        return 42

c: Container[IntProducer] = Container(IntProducer())
c.produce_from_value()  # this produces a type error

It would be ideal if we could communicate that in this method (which need not be an instance method, it could be a discrete function also), the type parameter behaves as though it were covariant, where any subtype of CanProduce[U] is valid.

In fact, there exists a mechanism for doing this in other situations. Consider if we have the following non-generic protocol:

class SupportsIndex(Protocol):
    def __index__(self) -> int:
        ...

We can then make a method index_from_value that works with all subtypes of SupportsIndex:

SI = TypeVar("SI", bound=SupportsIndex)

@dataclass
class Container(Generic[T_in]):
    value: T_in
    
    def index_from_value(self: Container[SI]):
        return self.value.__index__

Now, the following is valid:

c: Container[int] = Container(27)
c.index_from_value()

Unfortunately, this method cannot be used with generic protocols, because the following is invalid:

U = TypeVar("U")
CPU = TypeVar("CPU", bound=CanProduce[U])  # this produces a type error

I suggest altering the restriction to allow this trick to work.

Guide de contribution

Aucun guide de contribution indexé pour ce dépôt

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par les exemples génériques de protocol, Container et TypeVar dans l’issue, puis comparez-les avec le cas non générique SupportsIndex. L’issue ne sera prête à être traitée qu’une fois que la modification de contrainte proposée et son comportement pour les sous-types seront spécifiés assez clairement pour pouvoir être évalués.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
python
Domaine
devtools
Type d'issue
Fonctionnalité
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
25/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.