'The correct way to annotate a "file type" in Python
In modern versions of Python one can have static type analysis using function annotations, according to PEP 484. This is made easy through the typing module.
Now I'm wondering how I would give a "type hint" towards a "filestream".
def myfunction(file: FILETYPE):
pass
with open(fname) as file:
myfunction(file)
What would I insert as FILETYPE?
Using print(type(file)) returns <class '_io.TextIOWrapper'> which isn't clear at all.
Isn't there a generic "file" type?
Solution 1:[1]
I think you want io.IOBase, "[t]he abstract base class for all I/O classes, acting on streams of bytes."
Note that this includes also in-memory streams like io.StringIO and io.BytesIO. Read the documentation on the module io for details.
Solution 2:[2]
Either this:
from typing import TextIO # or IO or BinaryIO
def myfunction(file: TextIO ):
pass
OR this
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import TextIO # or IO or BinaryIO
def myfunction(file: 'TextIO'):
pass
The second approach would avoid to import the class during execution. Although python would still have to import TYPE_CHECKING during execution, it is a good practice to avoid importing classes for type hinting only: (1) doesn't get executed (just parsed), and (2) it could avoid cyclic imports.
Solution 3:[3]
typeshed has a SupportsRead protocol:
from __future__ import annotations
from typing import TYPE_CHECKING, AnyStr
if TYPE_CHECKING:
from _typeshed import SupportsRead
def takes_readable_str(fo: SupportsRead[str]):
return fo.read()
def takes_readable_bytes(fo: SupportsRead[bytes]):
return fo.read()
def takes_readable_any(fo: SupportsRead[AnyStr]):
return fo.read()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | Alex Waygood |
