Skip to content

open() returns IO[str] instead of io.TextIOWrapper #1229

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jcrmatos opened this issue May 1, 2017 · 5 comments
Closed

open() returns IO[str] instead of io.TextIOWrapper #1229

jcrmatos opened this issue May 1, 2017 · 5 comments
Labels
stubs: false positive Type checkers report false errors

Comments

@jcrmatos
Copy link

jcrmatos commented May 1, 2017

Hello,

My env is Win7P+SP1 x64, Py 3.5.2 32b, Mypy 0.501.

I opened this issue (#3286) in mypy, but GVR told me to open it here because it was a "(complex) typeshed issue".

The var used in the with context is of type <class '_io.TextIOWrapper'>.

with open(pathname, encoding='utf-8') as f_in:
    print(type(f_in))

<class '_io.TextIOWrapper'>

But when I try to set it's type, mypy returns the following error

from io import TextIOWrapper
with open(pathname, encoding='utf-8') as f_in:  # type: TextIOWrapper
    print(type(f_in))

data_processing.py:917: error: Incompatible types in assignment (expression has type IO[Any], variable has type "TextIOWrapper")

If I try to use module typing's own TextIO type it returns

from typing import TextIO
with open(pathname, encoding='utf-8') as f_in:  # type: TextIO
    print(type(f_in))

data_processing.py:917: error: Incompatible types in assignment (expression has type IO[Any], variable has type "TextIO")

It only works if I do

from typing import IO
with open(pathname, encoding='utf-8') as f_in:  # type: IO[Any]
    print(type(f_in))

Best regards,

JM

@lincolnq
Copy link
Contributor

lincolnq commented May 30, 2017

The solution to your problem is probably to use IO[str], which is compatible with the IO[Any] returned by open() and has (most of) the right methods. It doesn't have the TextIO specific ones (like .encoding, .line_buffering, etc.), so if you want those you should use cast(TextIO, open(...)).

However, I agree that this is an interesting problem and worth thinking about. It means TextIO and BinaryIO are annoyingly impractical to use in real code (a cast is necessary whenever open() is called). The documentation doesn't give many examples or suggest that IO[str] is what most people should use.

@gvanrossum
Copy link
Member

Yeah, this is not one of the smoothest APIs. Note that in master, open(fn, 'rb') will now return IO[bytes] while open(fn, 'r') will return IO[str]. (However, if the mode argument is a variable, it returns IO[Any]; and in PY2 they all return BinaryIO regardless of the mode.)

I think this is still wrong though. open() with a recognized mode argument should return BinaryIO or TextIO. That way you can write

f: TextIO = open(fn, 'rb')

Some classes used by the implementation in the io module are subclasses of TextIO or BinaryIO, but you're better off not referencing them.

(Another note: it's not great to use runtime inspection to come up with type names to put into annotations -- things at runtime are a bit different from how things are dine on the static typing side of things.)

@srittau
Copy link
Collaborator

srittau commented Sep 11, 2018

I think any further improvements in typeshed for this are dependent on implementing dependent types, see python/mypy#3062.

@srittau srittau changed the title Mypy assumes and only accepts type IO[Any] when it is _io.TextIOWrapper (GVR told me to open this here) open() returns IO[str] instead of io.TextIOWrapper Oct 28, 2018
@srittau srittau added stubs: false positive Type checkers report false errors size-large labels Oct 28, 2018
@srittau
Copy link
Collaborator

srittau commented Oct 28, 2018

This is part of the IO classes restructuring.

@hauntsaninja
Copy link
Collaborator

This was fixed in #4146 and others!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stubs: false positive Type checkers report false errors
Projects
None yet
Development

No branches or pull requests

5 participants