Python NewType ('X', Y): mypy visualizza l'errore: ottenuto Y, previsto X

Oct 03 2020

Voglio usare un controllo del tipo che mi aiuti a scrivere un buon codice e penso che mypy faccia quello che voglio. Ma non capisco come scrivere il codice seguente.

import typing as tau

Offset = tau.NewType('Offset', tau.Tuple[int, int])


def f(x: int, y: int) -> Offset:
    return x, y


important_for_me = Offset != tau.Tuple[int, int]
assert important_for_me

Per un framework che sto scrivendo è importante non solo assegnare un identificatore a un tipo, ma voglio comunque che il typechecker sappia come aiutarmi (quindi non solo assegnare TypeVar e perdere informazioni).

typing.NewType funziona perfettamente, ma mypy mi dà un errore alla riga 7:

Tipo di valore restituito incompatibile (ottenuto "Tuple [int, int]", previsto "Offset")

C'è un modo per scriverlo esattamente come ho fatto io, ma in un modo che il tipografo lo capisca?

Risposte

5 MarioIshac Oct 03 2020 at 22:10

Devi creare esplicitamente un Offsetdalla tua x, ytupla:

def f(x: int, y: int) -> Offset:
    return Offset((x, y))

Questo perché, dalla funzione di supporto NewType : "i controlli di tipo richiedono cast espliciti da intdove UserIdè previsto", o nel tuo caso: da Tuple[int, int]a Offset.

Può essere solo per il tuo esempio, ma se fdavvero non esegue alcuna convalida xe yprima di restituire un Offset, un NewTypequi non è necessario. In tal caso, suggerirei di dichiarare Offsetcome:

Offset = tau.Tuple[int, int]

che è un alias di tipo .