From 2d679951d17dfbb6dcb9625b905ea12041eef696 Mon Sep 17 00:00:00 2001 From: hauntsaninja <> Date: Thu, 6 Aug 2020 21:15:30 -0700 Subject: [PATCH 1/2] pathlib.Path.open: bring on the overloads --- stdlib/3/pathlib.pyi | 45 +++++++++++++++++++++++++++++++++++--- third_party/2/pathlib2.pyi | 45 +++++++++++++++++++++++++++++++++++--- 2 files changed, 84 insertions(+), 6 deletions(-) diff --git a/stdlib/3/pathlib.pyi b/stdlib/3/pathlib.pyi index 279e8d57e215..6a500b3d43e0 100644 --- a/stdlib/3/pathlib.pyi +++ b/stdlib/3/pathlib.pyi @@ -1,8 +1,10 @@ import os import sys -from _typeshed import OpenBinaryMode, OpenTextMode +from _typeshed import OpenBinaryMode, OpenBinaryModeReading, OpenBinaryModeUpdating, OpenBinaryModeWriting, OpenTextMode +from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWrapper from types import TracebackType from typing import IO, Any, BinaryIO, Generator, List, Optional, Sequence, TextIO, Tuple, Type, TypeVar, Union, overload +from typing_extensions import Literal _P = TypeVar("_P", bound=PurePath) @@ -83,6 +85,8 @@ class Path(PurePath): def mkdir(self, mode: int = ..., parents: bool = ...) -> None: ... else: def mkdir(self, mode: int = ..., parents: bool = ..., exist_ok: bool = ...) -> None: ... + # Adapted from builtins.open + # Text mode: always returns a TextIOWrapper @overload def open( self, @@ -91,11 +95,46 @@ class Path(PurePath): encoding: Optional[str] = ..., errors: Optional[str] = ..., newline: Optional[str] = ..., - ) -> TextIO: ... + ) -> TextIOWrapper: ... + # Unbuffered binary mode: returns a FileIO @overload def open( - self, mode: OpenBinaryMode, buffering: int = ..., encoding: None = ..., errors: None = ..., newline: None = ... + self, mode: OpenBinaryMode, buffering: Literal[0], encoding: None = ..., errors: None = ..., newline: None = ..., + ) -> FileIO: ... + # Buffering is on: return BufferedRandom, BufferedReader, or BufferedWriter + @overload + def open( + self, + mode: OpenBinaryModeUpdating, + buffering: Literal[-1, 1] = ..., + encoding: None = ..., + errors: None = ..., + newline: None = ..., + ) -> BufferedRandom: ... + @overload + def open( + self, + mode: OpenBinaryModeWriting, + buffering: Literal[-1, 1] = ..., + encoding: None = ..., + errors: None = ..., + newline: None = ..., + ) -> BufferedWriter: ... + @overload + def open( + self, + mode: OpenBinaryModeReading, + buffering: Literal[-1, 1] = ..., + encoding: None = ..., + errors: None = ..., + newline: None = ..., + ) -> BufferedReader: ... + # Buffering cannot be determined: fall back to BinaryIO + @overload + def open( + self, mode: OpenBinaryMode, buffering: int, encoding: None = ..., errors: None = ..., newline: None = ..., ) -> BinaryIO: ... + # Fallback if mode is not specified @overload def open( self, diff --git a/third_party/2/pathlib2.pyi b/third_party/2/pathlib2.pyi index 279e8d57e215..6a500b3d43e0 100644 --- a/third_party/2/pathlib2.pyi +++ b/third_party/2/pathlib2.pyi @@ -1,8 +1,10 @@ import os import sys -from _typeshed import OpenBinaryMode, OpenTextMode +from _typeshed import OpenBinaryMode, OpenBinaryModeReading, OpenBinaryModeUpdating, OpenBinaryModeWriting, OpenTextMode +from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWrapper from types import TracebackType from typing import IO, Any, BinaryIO, Generator, List, Optional, Sequence, TextIO, Tuple, Type, TypeVar, Union, overload +from typing_extensions import Literal _P = TypeVar("_P", bound=PurePath) @@ -83,6 +85,8 @@ class Path(PurePath): def mkdir(self, mode: int = ..., parents: bool = ...) -> None: ... else: def mkdir(self, mode: int = ..., parents: bool = ..., exist_ok: bool = ...) -> None: ... + # Adapted from builtins.open + # Text mode: always returns a TextIOWrapper @overload def open( self, @@ -91,11 +95,46 @@ class Path(PurePath): encoding: Optional[str] = ..., errors: Optional[str] = ..., newline: Optional[str] = ..., - ) -> TextIO: ... + ) -> TextIOWrapper: ... + # Unbuffered binary mode: returns a FileIO @overload def open( - self, mode: OpenBinaryMode, buffering: int = ..., encoding: None = ..., errors: None = ..., newline: None = ... + self, mode: OpenBinaryMode, buffering: Literal[0], encoding: None = ..., errors: None = ..., newline: None = ..., + ) -> FileIO: ... + # Buffering is on: return BufferedRandom, BufferedReader, or BufferedWriter + @overload + def open( + self, + mode: OpenBinaryModeUpdating, + buffering: Literal[-1, 1] = ..., + encoding: None = ..., + errors: None = ..., + newline: None = ..., + ) -> BufferedRandom: ... + @overload + def open( + self, + mode: OpenBinaryModeWriting, + buffering: Literal[-1, 1] = ..., + encoding: None = ..., + errors: None = ..., + newline: None = ..., + ) -> BufferedWriter: ... + @overload + def open( + self, + mode: OpenBinaryModeReading, + buffering: Literal[-1, 1] = ..., + encoding: None = ..., + errors: None = ..., + newline: None = ..., + ) -> BufferedReader: ... + # Buffering cannot be determined: fall back to BinaryIO + @overload + def open( + self, mode: OpenBinaryMode, buffering: int, encoding: None = ..., errors: None = ..., newline: None = ..., ) -> BinaryIO: ... + # Fallback if mode is not specified @overload def open( self, From cdee2de32b1dbbf6b9f3f25ee47fdebd4811142c Mon Sep 17 00:00:00 2001 From: hauntsaninja <> Date: Fri, 7 Aug 2020 13:04:54 -0700 Subject: [PATCH 2/2] adapt from _io.open for py2 --- stdlib/3/pathlib.pyi | 131 ++++++++++++++++++++----------------- third_party/2/pathlib2.pyi | 131 ++++++++++++++++++++----------------- 2 files changed, 142 insertions(+), 120 deletions(-) diff --git a/stdlib/3/pathlib.pyi b/stdlib/3/pathlib.pyi index 6a500b3d43e0..ff7e2e4d81af 100644 --- a/stdlib/3/pathlib.pyi +++ b/stdlib/3/pathlib.pyi @@ -3,7 +3,7 @@ import sys from _typeshed import OpenBinaryMode, OpenBinaryModeReading, OpenBinaryModeUpdating, OpenBinaryModeWriting, OpenTextMode from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWrapper from types import TracebackType -from typing import IO, Any, BinaryIO, Generator, List, Optional, Sequence, TextIO, Tuple, Type, TypeVar, Union, overload +from typing import IO, Any, BinaryIO, Generator, List, Optional, Sequence, Text, TextIO, Tuple, Type, TypeVar, Union, overload from typing_extensions import Literal _P = TypeVar("_P", bound=PurePath) @@ -85,65 +85,76 @@ class Path(PurePath): def mkdir(self, mode: int = ..., parents: bool = ...) -> None: ... else: def mkdir(self, mode: int = ..., parents: bool = ..., exist_ok: bool = ...) -> None: ... - # Adapted from builtins.open - # Text mode: always returns a TextIOWrapper - @overload - def open( - self, - mode: OpenTextMode = ..., - buffering: int = ..., - encoding: Optional[str] = ..., - errors: Optional[str] = ..., - newline: Optional[str] = ..., - ) -> TextIOWrapper: ... - # Unbuffered binary mode: returns a FileIO - @overload - def open( - self, mode: OpenBinaryMode, buffering: Literal[0], encoding: None = ..., errors: None = ..., newline: None = ..., - ) -> FileIO: ... - # Buffering is on: return BufferedRandom, BufferedReader, or BufferedWriter - @overload - def open( - self, - mode: OpenBinaryModeUpdating, - buffering: Literal[-1, 1] = ..., - encoding: None = ..., - errors: None = ..., - newline: None = ..., - ) -> BufferedRandom: ... - @overload - def open( - self, - mode: OpenBinaryModeWriting, - buffering: Literal[-1, 1] = ..., - encoding: None = ..., - errors: None = ..., - newline: None = ..., - ) -> BufferedWriter: ... - @overload - def open( - self, - mode: OpenBinaryModeReading, - buffering: Literal[-1, 1] = ..., - encoding: None = ..., - errors: None = ..., - newline: None = ..., - ) -> BufferedReader: ... - # Buffering cannot be determined: fall back to BinaryIO - @overload - def open( - self, mode: OpenBinaryMode, buffering: int, encoding: None = ..., errors: None = ..., newline: None = ..., - ) -> BinaryIO: ... - # Fallback if mode is not specified - @overload - def open( - self, - mode: str, - buffering: int = ..., - encoding: Optional[str] = ..., - errors: Optional[str] = ..., - newline: Optional[str] = ..., - ) -> IO[Any]: ... + if sys.version_info >= (3,): + # Adapted from builtins.open + # Text mode: always returns a TextIOWrapper + @overload + def open( + self, + mode: OpenTextMode = ..., + buffering: int = ..., + encoding: Optional[str] = ..., + errors: Optional[str] = ..., + newline: Optional[str] = ..., + ) -> TextIOWrapper: ... + # Unbuffered binary mode: returns a FileIO + @overload + def open( + self, mode: OpenBinaryMode, buffering: Literal[0], encoding: None = ..., errors: None = ..., newline: None = ..., + ) -> FileIO: ... + # Buffering is on: return BufferedRandom, BufferedReader, or BufferedWriter + @overload + def open( + self, + mode: OpenBinaryModeUpdating, + buffering: Literal[-1, 1] = ..., + encoding: None = ..., + errors: None = ..., + newline: None = ..., + ) -> BufferedRandom: ... + @overload + def open( + self, + mode: OpenBinaryModeWriting, + buffering: Literal[-1, 1] = ..., + encoding: None = ..., + errors: None = ..., + newline: None = ..., + ) -> BufferedWriter: ... + @overload + def open( + self, + mode: OpenBinaryModeReading, + buffering: Literal[-1, 1] = ..., + encoding: None = ..., + errors: None = ..., + newline: None = ..., + ) -> BufferedReader: ... + # Buffering cannot be determined: fall back to BinaryIO + @overload + def open( + self, mode: OpenBinaryMode, buffering: int, encoding: None = ..., errors: None = ..., newline: None = ..., + ) -> BinaryIO: ... + # Fallback if mode is not specified + @overload + def open( + self, + mode: str, + buffering: int = ..., + encoding: Optional[str] = ..., + errors: Optional[str] = ..., + newline: Optional[str] = ..., + ) -> IO[Any]: ... + else: + # Adapted from _io.open + def open( + self, + mode: Text = ..., + buffering: int = ..., + encoding: Optional[Text] = ..., + errors: Optional[Text] = ..., + newline: Optional[Text] = ..., + ) -> IO[Any]: ... def owner(self) -> str: ... if sys.version_info >= (3, 9): def readlink(self: _P) -> _P: ... diff --git a/third_party/2/pathlib2.pyi b/third_party/2/pathlib2.pyi index 6a500b3d43e0..ff7e2e4d81af 100644 --- a/third_party/2/pathlib2.pyi +++ b/third_party/2/pathlib2.pyi @@ -3,7 +3,7 @@ import sys from _typeshed import OpenBinaryMode, OpenBinaryModeReading, OpenBinaryModeUpdating, OpenBinaryModeWriting, OpenTextMode from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWrapper from types import TracebackType -from typing import IO, Any, BinaryIO, Generator, List, Optional, Sequence, TextIO, Tuple, Type, TypeVar, Union, overload +from typing import IO, Any, BinaryIO, Generator, List, Optional, Sequence, Text, TextIO, Tuple, Type, TypeVar, Union, overload from typing_extensions import Literal _P = TypeVar("_P", bound=PurePath) @@ -85,65 +85,76 @@ class Path(PurePath): def mkdir(self, mode: int = ..., parents: bool = ...) -> None: ... else: def mkdir(self, mode: int = ..., parents: bool = ..., exist_ok: bool = ...) -> None: ... - # Adapted from builtins.open - # Text mode: always returns a TextIOWrapper - @overload - def open( - self, - mode: OpenTextMode = ..., - buffering: int = ..., - encoding: Optional[str] = ..., - errors: Optional[str] = ..., - newline: Optional[str] = ..., - ) -> TextIOWrapper: ... - # Unbuffered binary mode: returns a FileIO - @overload - def open( - self, mode: OpenBinaryMode, buffering: Literal[0], encoding: None = ..., errors: None = ..., newline: None = ..., - ) -> FileIO: ... - # Buffering is on: return BufferedRandom, BufferedReader, or BufferedWriter - @overload - def open( - self, - mode: OpenBinaryModeUpdating, - buffering: Literal[-1, 1] = ..., - encoding: None = ..., - errors: None = ..., - newline: None = ..., - ) -> BufferedRandom: ... - @overload - def open( - self, - mode: OpenBinaryModeWriting, - buffering: Literal[-1, 1] = ..., - encoding: None = ..., - errors: None = ..., - newline: None = ..., - ) -> BufferedWriter: ... - @overload - def open( - self, - mode: OpenBinaryModeReading, - buffering: Literal[-1, 1] = ..., - encoding: None = ..., - errors: None = ..., - newline: None = ..., - ) -> BufferedReader: ... - # Buffering cannot be determined: fall back to BinaryIO - @overload - def open( - self, mode: OpenBinaryMode, buffering: int, encoding: None = ..., errors: None = ..., newline: None = ..., - ) -> BinaryIO: ... - # Fallback if mode is not specified - @overload - def open( - self, - mode: str, - buffering: int = ..., - encoding: Optional[str] = ..., - errors: Optional[str] = ..., - newline: Optional[str] = ..., - ) -> IO[Any]: ... + if sys.version_info >= (3,): + # Adapted from builtins.open + # Text mode: always returns a TextIOWrapper + @overload + def open( + self, + mode: OpenTextMode = ..., + buffering: int = ..., + encoding: Optional[str] = ..., + errors: Optional[str] = ..., + newline: Optional[str] = ..., + ) -> TextIOWrapper: ... + # Unbuffered binary mode: returns a FileIO + @overload + def open( + self, mode: OpenBinaryMode, buffering: Literal[0], encoding: None = ..., errors: None = ..., newline: None = ..., + ) -> FileIO: ... + # Buffering is on: return BufferedRandom, BufferedReader, or BufferedWriter + @overload + def open( + self, + mode: OpenBinaryModeUpdating, + buffering: Literal[-1, 1] = ..., + encoding: None = ..., + errors: None = ..., + newline: None = ..., + ) -> BufferedRandom: ... + @overload + def open( + self, + mode: OpenBinaryModeWriting, + buffering: Literal[-1, 1] = ..., + encoding: None = ..., + errors: None = ..., + newline: None = ..., + ) -> BufferedWriter: ... + @overload + def open( + self, + mode: OpenBinaryModeReading, + buffering: Literal[-1, 1] = ..., + encoding: None = ..., + errors: None = ..., + newline: None = ..., + ) -> BufferedReader: ... + # Buffering cannot be determined: fall back to BinaryIO + @overload + def open( + self, mode: OpenBinaryMode, buffering: int, encoding: None = ..., errors: None = ..., newline: None = ..., + ) -> BinaryIO: ... + # Fallback if mode is not specified + @overload + def open( + self, + mode: str, + buffering: int = ..., + encoding: Optional[str] = ..., + errors: Optional[str] = ..., + newline: Optional[str] = ..., + ) -> IO[Any]: ... + else: + # Adapted from _io.open + def open( + self, + mode: Text = ..., + buffering: int = ..., + encoding: Optional[Text] = ..., + errors: Optional[Text] = ..., + newline: Optional[Text] = ..., + ) -> IO[Any]: ... def owner(self) -> str: ... if sys.version_info >= (3, 9): def readlink(self: _P) -> _P: ...