Une instruction «with» prend-elle en charge les indications de type?

16

Pouvez-vous définir l'indice de type pour une variable définie avec la withsyntaxe?

with example() as x:
    print(x)

Je voudrais taper l'indice ci-dessus pour dire que xc'est un str(à titre d'exemple).

Le seul problème que j'ai trouvé est d'utiliser une variable intermédiaire, mais cela semble hacky.

with example() as x:
    y: str = x
    print(y)

Je ne trouve pas d'exemple dans la documentation de frappe .

Reactgular
la source
6
Les vérificateurs de type ne devraient-ils pas pouvoir déduire le type de xcomme type de retour example().__enter__()?
pschill
2
Pourquoi voulez-vous annoter xalors que c'est simplement le type de retour de example.__enter__? Idéalement, vous avez annoté cette méthode / fonction.
a_guest
1
xn'est pas la valeur de retour de example; c'est la valeur de retour de example().__enter__().
chepner
La plupart des méthodes que j'ai trouvées ne définissent pas d'indicateur de type pour la valeur de retour.
Reactgular
1
@Reactgular La solution consiste alors à créer un fichier de raccord pour cette fonction, afin que le vérificateur de type puisse déduire le type. Habituellement, vous annotez aux limites de l'API, pas à l'intérieur. Dans ce cas, il est clair que le type provient example. L'annotation example.__enter__signifie une annotation alors qu'avec votre approche, vous devrez annoter dans tous les endroits où ce gestionnaire de contexte est utilisé, plus en général comment un utilisateur est-il censé savoir quel est le type de retour d'une API s'il n'est pas fourni?
a_guest

Réponses:

11

PEP 526, qui a été implémenté en Python 3.6, vous permet d'annoter des variables. Vous pouvez utiliser, par exemple,

x: str
with example() as x:
    [...]

ou

with example() as x:
    x: str
    [...]
pschill
la source
Cela fonctionne également pour d'autres blocs de code comme for. Excellente réponse, merci.
Reactgular
Si le gestionnaire de contexte n'indique pas ce que la __enter__méthode retournera, la saisie xne sert à rien. mypysera heureux de permettre à une valeur de n'importe quel type d'être liée x.
chepner
@chepner Oui, vous avez raison. PyCharm reconnaît xque strdans les deux cas, mais mypyne le fait pas.
pschill
14

Les annotations de type sont généralement placées aux limites de l'API. Dans ce cas, le type doit être déduit de example.__enter__. Dans le cas où cette fonction ne déclare aucun type, la solution consiste à créer un fichier de raccord correspondant afin d'aider le vérificateur de type à déduire ce type.

Plus précisément, cela signifie créer un .pyifichier avec la même racine que le module à partir duquel a Exampleété importé. Ensuite, le code suivant peut être ajouté:

class Example:
    def __enter__(self) -> str: ...
    def __exit__(self, exc_type, exc_value, exc_traceback) -> None: ...
un invité
la source