¿Cómo se debe anotar un NamedTemporaryFile?

Oct 19 2020

Intenté typing.IOcomo se sugiere en la sugerencia de tipo para un archivo o un objeto similar a un archivo. , pero no funciona:

from __future__ import annotations
from tempfile import NamedTemporaryFile
from typing import IO

def example(tmp: IO) -> str:
    print(tmp.file)
    return tmp.name


print(example(NamedTemporaryFile()))

para esto mypy me dice:

test.py:6: error: "IO[Any]" has no attribute "file"; maybe "fileno"?

y Python funciona bien. Entonces el código está bien.

Respuestas

4 Carcigenicate Oct 19 2020 at 21:15

No creo que esto se pueda insinuar fácilmente.

Si comprueba la definición de NamedTemporaryFile, verá que es una función que termina en:

return _TemporaryFileWrapper(file, name, delete)

Y _TemporaryFileWrapperse define como:

class _TemporaryFileWrapper:

Lo que significa que no hay una superclase que pueda indicarse y _TemporaryFileWrapperes "módulo privado". Tampoco parece que tenga miembros que lo hagan parte de un existente Protocol(excepto por Iterabley ContextManager; pero no estás usando esos métodos aquí).

Creo que deberás usar _TemporaryFileWrappere ignorar las advertencias:

from tempfile import _TemporaryFileWrapper  # Weak error

def example(tmp: _TemporaryFileWrapper) -> str:
    print(tmp.file)
    return tmp.name

Si realmente desea una solución limpia, puede implementar la suya propia Protocol que incluya los atributos que necesita y que también herede de Iterabley ContextManager. Luego, puede escribir una pista usando su archivo personalizado Protocol.