Skip to content

Commit

Permalink
Improve open overloads when mode is a literal union
Browse files Browse the repository at this point in the history
As pointed out by @gvanrossum in python/typing#1096

Improves type inference in cases when we know that mode is
OpenBinaryMode, but don't know anything more specific:
```
def my_open(name: str, write: bool):
    mode: Literal['rb', 'wb'] = 'wb' if write else 'rb'
    with open(name, mode) as f:
        reveal_type(f)  # previously typing.IO[Any], now typing.BinaryIO
```

You may be tempted into thinking this is some limitation of type
checkers. mypy does in fact have logic for detecting if we match
multiple overloads and union-ing up the return types of matched
overloads. The problem is the last overload interferes with this logic.
That is, if you remove the fallback overload (prior to this PR), you'd get
"Union[io.BufferedReader, io.BufferedWriter]" in the above example.
  • Loading branch information
hauntsaninja committed Mar 2, 2022
1 parent a5ec3c6 commit 43223af
Show file tree
Hide file tree
Showing 5 changed files with 5 additions and 5 deletions.
2 changes: 1 addition & 1 deletion stdlib/builtins.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -1308,7 +1308,7 @@ def open(
def open(
file: _OpenFile,
mode: OpenBinaryMode,
buffering: int,
buffering: int = ...,
encoding: None = ...,
errors: None = ...,
newline: None = ...,
Expand Down
2 changes: 1 addition & 1 deletion stdlib/importlib/abc.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ if sys.version_info >= (3, 9):
@overload
@abstractmethod
def open(
self, mode: OpenBinaryMode, buffering: int, encoding: None = ..., errors: None = ..., newline: None = ...
self, mode: OpenBinaryMode, buffering: int = ..., encoding: None = ..., errors: None = ..., newline: None = ...
) -> BinaryIO: ...
# Fallback if mode is not specified
@overload
Expand Down
2 changes: 1 addition & 1 deletion stdlib/os/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ def fdopen(
def fdopen(
fd: int,
mode: OpenBinaryMode,
buffering: int,
buffering: int = ...,
encoding: None = ...,
errors: None = ...,
newline: None = ...,
Expand Down
2 changes: 1 addition & 1 deletion stdlib/pathlib.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ class Path(PurePath):
# Buffering cannot be determined: fall back to BinaryIO
@overload
def open(
self, mode: OpenBinaryMode, buffering: int, encoding: None = ..., errors: None = ..., newline: None = ...
self, mode: OpenBinaryMode, buffering: int = ..., encoding: None = ..., errors: None = ..., newline: None = ...
) -> BinaryIO: ...
# Fallback if mode is not specified
@overload
Expand Down
2 changes: 1 addition & 1 deletion stubs/aiofiles/aiofiles/threadpool/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def open(
def open(
file: _OpenFile,
mode: OpenBinaryMode,
buffering: int,
buffering: int = ...,
encoding: None = ...,
errors: None = ...,
newline: None = ...,
Expand Down

0 comments on commit 43223af

Please sign in to comment.