Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should a NamedTemporaryFile be annotated?

I tried typing.IO as suggested in Type hint for a file or file-like object?, but it doesn't work:

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()))

for this, mypy tells me:

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

and Python runs fine. So the code is ok.

like image 709
Martin Thoma Avatar asked Oct 19 '20 14:10

Martin Thoma


People also ask

What is namedtemporaryfile used for in Python?

In Python, when you need to create a temporary file with a filename associated to it on disk, NamedTemporaryFile function in the tempfile module is the goto function. Here are some use cases that I think one might use it for.

What is the default delete setting for namedtemporaryfile?

By default delete is set to True when calling NamedTemporaryFile (), and thus setting it to False gives more control on when the file gets removed from disk.

How to create a temporary file with a filename in Python?

In Python, when you need to create a temporary file with a filename associated to it on disk, NamedTemporaryFile function in the tempfile module is the goto function.

What is an a descriptive annotation?

A descriptive annotation summarizes the approach and arguments of a source in an objective way, without attempting to assess their validity. In this way, it resembles an abstract, but it differs in that you’re describing the source’s approach explicitly rather than just summarizing the ideas it expresses.


Video Answer


1 Answers

I don't think this can be easily type hinted.

If you check the definition of NamedTemporaryFile, you'll see that it's a function that ends in:

return _TemporaryFileWrapper(file, name, delete)

And _TemporaryFileWrapper is defined as:

class _TemporaryFileWrapper:

Which means there isn't a super-class that can be indicated, and _TemporaryFileWrapper is "module-private". It also doesn't look like it has any members that make it a part of an existing Protocol * (except for Iterable and ContextManager; but you aren't using those methods here).

I think you'll need to use _TemporaryFileWrapper and ignore the warnings:

from tempfile import _TemporaryFileWrapper  # Weak error

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

If you really want a clean solution, you could implement your own Protocol that includes the attributes you need, and have it also inherit from Iterable and ContextManager. Then you can type-hint using your custom Protocol.


* It was later pointed out that it does fulfil IO, but the OP requires attributes that aren't in IO, so that can't be used.

like image 114
Carcigenicate Avatar answered Oct 21 '22 03:10

Carcigenicate