Describe the bug
When passing file-like object opened in a binary mode to a function that accepts BinaryIO object, pyright throws an error:
Argument of type "IO[Any]" cannot be assigned to parameter "file" in function "foo" of type "BinaryIO"
"IO[Any]" is incompatible with "BinaryIO" (reportGeneralTypeIssues)
To Reproduce
Steps to reproduce the behavior.
Consider this piece of code:
from typing import BinaryIO
def foo(file: BinaryIO) -> bytes:
return file.read()
with open("test.txt", "rb") as f:
foo(f)
Both in VS Code extension and CLI there is an error mentioned above.
Expected behavior
The type should be recognised correctly as BinaryIO.
Additional context
json
{
"pyright.typeCheckingMode": "strict",
"pyright.useLibraryCodeForTypes": true
}
Pyright is following the type information provided in the stdlib typeshed stub. The type information for the "open" method is:
def open(file: Union[str, bytes, int, _PathLike[Any]], mode: str = ..., buffering: int = ..., encoding: Optional[str] = ..., errors: Optional[str] = ..., newline: Optional[str] = ..., closefd: bool = ..., opener: Optional[Callable[[str, int], int]] = ...) -> IO[Any]: ...
As you can see, the return type is IO[Any].
Python 3.8 introduced support for "Literal", so it would be possible to update the typeshed stub file to include @overload versions of the open method that return different types based on the literal value passed to the mode parameter. That change would need to be made in the (typeshed repo)[https://github.com/python/typeshed]. You're welcome to submit a change or file a bug in that project. If you get that fixed, let me know, and I'll pull an updated version of the typeshed stubs into Pyright.
In the meantime, you can work around the issue by adding an assert to your code:
assert isinstance(f, BinaryIO)
@erictraut Thanks for the quick and detailed response!
I'll look into the typeshed repo
@erictraut more precise return types were introduced to the typeshed repo here: https://github.com/python/typeshed/commit/846d922df238d307a99347f74d91ccb362f876ad
Great! I'll pull the latest typeshed stubs and include them in the next release of Pyright.
The latest typeshed stubs are included in Pyright 1.1.43, which I just published.