Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Check file type annotations against open mode #2337
I have a function argument whose type I want to limit to a file object that's open for binary reading — i.e. I want only an instance of
from typing import IO def parser(file_obj: IO[bytes]) -> None: pass
As I would expect, mypy runs without complaint on this code:
But it doesn't output an error for this:
In that case, I would want an error along the lines of
I was trying to type check if the file was open in binary mode too, and noticed a few things (and a workaround right at the end of all this)...
mypy -2 doesn't seem to know that io.BufferedReader is there.
If I run mypy in python3 mode, it passes.
Also if I change it to use _io, it works under mypy -2, but not in python3 mode.
With mypy in 3 mode I get:
In python python2.7 and 3.6, the types for io.open are like so.
Hacking about some more I make this mess below which does let me check that every file obj passed into the object is a BufferedReader. Of course, I need to manually cast every instance... not at all nice.
Finally I decide to have a separate open function wrapper for every mode. This way I can use a cast inside it, and the type checker works. Any file not using my custom wrappers also fails - which is great because I know where I have to track things down to check them.
I think this technique would work anywhere you have a factory pattern where the return types are dependent on logic inside the function, or the parameters. As long as number of combinations are not too big that is! (open_rb, open_r, open_w, open_wb)