Type hint for a file or file-like object?

60,960

Solution 1

Use either the typing.TextIO or typing.BinaryIO types, for files opened in text mode or binary mode respectively.

From the docs:

class typing.IO

Wrapper namespace for I/O stream types.

This defines the generic type IO[AnyStr] and aliases TextIO and BinaryIO for respectively IO[str] and IO[bytes]. These representing the types of I/O streams such as returned by open().

Solution 2

The short answer:

  • You need to be explicit. That is from typing import TextIO not just from typing import *.
  • Use IO to mean a file without specifying what kind
  • Use TextIO or BinaryIO if you know the type
  • You cannot currently specify it be opened for write or its encoding.

As an example:

from typing import BinaryIO

def binf(inf: BinaryIO):
    pass

with open('x') as f:
    binf(f)

gives an inspection error (in PyCharm) of Expected type 'BinaryIO', got 'TextIO' instead

Share:
60,960

Related videos on Youtube

Mark Amery
Author by

Mark Amery

Email address: [email protected]. No spam, please. I work for Curative Inc: https://curative.com/ I license you to use any of my Stack Overflow contributions in any way you like. If you find something wrong in one of my posts, feel free to edit it. I'm a frequent visitor and can always roll back if I think a change you've made is wrong or stupid, so you may as well be bold - it's better, here, to ask for forgiveness than permission.

Updated on July 08, 2022

Comments

  • Mark Amery
    Mark Amery almost 2 years

    Is there any correct type hint to use for a file or file-like object in Python? For example, how would I type-hint the return value of this function?

    def foo() -> ???:
        return open('bar')
    
  • Yongwei Wu
    Yongwei Wu about 7 years
    Generically, maybe typing.IO as the type description?
  • Admin
    Admin about 7 years
    None of these seem to work for me: def f() -> IO: return open('test') gives "Expected type 'IO', got 'TextIOWrapper[str]' instead" in PyCharm.
  • Wayne Werner
    Wayne Werner about 7 years
    @Marein what about IO[str]?
  • Admin
    Admin about 7 years
    The same I'm afraid. I'm also noticing that iterating over the lines in a file gives "Expected 'collections.iterable'".
  • Wayne Werner
    Wayne Werner about 7 years
    @Marein I suggest that you post a new question with a minimal reproducible example because your code works fine for me, even using PyCharm.
  • Jean-François Corbett
    Jean-François Corbett over 6 years
    Reproduced @Marein's issue in PyCharm community 2017.2: i.imgur.com/Ai4sVQl.jpg
  • CMCDragonkai
    CMCDragonkai about 4 years
    Why does BufferedReader not come under the IO type? Mypy keeps saying that it got BufferedReader, but expects Optional[IO[Any]].
  • Tshirtman
    Tshirtman about 3 years
    The documentation is a bit confusing, it indicates a deprecation, but i’m not entirely sure what is covered by it, the optimist interpretation that it’s only about the typing.io namespace, but i’m not keen on being too optimistic when programming.
  • mxmlnkn
    mxmlnkn about 3 years
    @Tshirtman I think you can be a optimistic about this. I found this issue regarding the deprecation and it seems to be clearer about typing.io being the namespace to be deprecated because typing.io.BinaryIO and others also exist and were mostly used directly from the typing namespace, e.g., typing.BinaryIO.
  • Tshirtman
    Tshirtman almost 3 years
    @mxmlnkn indeed, that bug certainly disambiguates it, thanks :)