From bf201c82012e30ec539d9cba514d233e9335bae8 Mon Sep 17 00:00:00 2001 From: hatal175 Date: Thu, 15 Apr 2021 05:14:07 +0300 Subject: [PATCH] Various stubtest fixes (#5215) --- stdlib/netrc.pyi | 4 ++- stdlib/ntpath.pyi | 4 +-- stdlib/operator.pyi | 42 ++++++++++++++++++------ stdlib/optparse.pyi | 7 ++-- stdlib/os/__init__.pyi | 31 +++++++++++++++++ stdlib/pipes.pyi | 2 +- stdlib/pkgutil.pyi | 2 +- tests/stubtest_whitelists/py3_common.txt | 28 +++------------- 8 files changed, 78 insertions(+), 42 deletions(-) diff --git a/stdlib/netrc.pyi b/stdlib/netrc.pyi index 50fe3c0e0..20a0513ea 100644 --- a/stdlib/netrc.pyi +++ b/stdlib/netrc.pyi @@ -1,9 +1,11 @@ +from _typeshed import AnyPath from typing import Dict, List, Optional, Tuple class NetrcParseError(Exception): filename: Optional[str] lineno: Optional[int] msg: str + def __init__(self, msg: str, filename: Optional[AnyPath] = ..., lineno: Optional[int] = ...) -> None: ... # (login, account, password) tuple _NetrcTuple = Tuple[str, Optional[str], Optional[str]] @@ -11,5 +13,5 @@ _NetrcTuple = Tuple[str, Optional[str], Optional[str]] class netrc: hosts: Dict[str, _NetrcTuple] macros: Dict[str, List[str]] - def __init__(self, file: str = ...) -> None: ... + def __init__(self, file: Optional[AnyPath] = ...) -> None: ... def authenticators(self, host: str) -> Optional[_NetrcTuple]: ... diff --git a/stdlib/ntpath.pyi b/stdlib/ntpath.pyi index 9fe5a7df6..33536f751 100644 --- a/stdlib/ntpath.pyi +++ b/stdlib/ntpath.pyi @@ -86,9 +86,9 @@ def isdir(s: AnyPath) -> bool: ... def islink(path: AnyPath) -> bool: ... def ismount(path: AnyPath) -> bool: ... @overload -def join(a: StrPath, *paths: StrPath) -> str: ... +def join(path: StrPath, *paths: StrPath) -> str: ... @overload -def join(a: BytesPath, *paths: BytesPath) -> bytes: ... +def join(path: BytesPath, *paths: BytesPath) -> bytes: ... @overload def relpath(path: BytesPath, start: Optional[BytesPath] = ...) -> bytes: ... @overload diff --git a/stdlib/operator.pyi b/stdlib/operator.pyi index 687de813e..03510fed9 100644 --- a/stdlib/operator.pyi +++ b/stdlib/operator.pyi @@ -1,8 +1,8 @@ import sys from typing import ( Any, - Callable, Container, + Generic, Mapping, MutableMapping, MutableSequence, @@ -14,6 +14,7 @@ from typing import ( ) _T = TypeVar("_T") +_T_co = TypeVar("_T_co", covariant=True) _K = TypeVar("_K") _V = TypeVar("_V") @@ -148,15 +149,36 @@ if sys.version_info < (3,): if sys.version_info >= (3, 4): def length_hint(__obj: Any, __default: int = ...) -> int: ... -@overload -def attrgetter(attr: str) -> Callable[[Any], Any]: ... -@overload -def attrgetter(*attrs: str) -> Callable[[Any], Tuple[Any, ...]]: ... -@overload -def itemgetter(item: Any) -> Callable[[Any], Any]: ... -@overload -def itemgetter(*items: Any) -> Callable[[Any], Tuple[Any, ...]]: ... -def methodcaller(__name: str, *args: Any, **kwargs: Any) -> Callable[..., Any]: ... +class attrgetter(Generic[_T_co]): + @overload + def __new__(cls, attr: str) -> attrgetter[Any]: ... + @overload + def __new__(cls, attr: str, __attr2: str) -> attrgetter[Tuple[Any, Any]]: ... + @overload + def __new__(cls, attr: str, __attr2: str, __attr3: str) -> attrgetter[Tuple[Any, Any, Any]]: ... + @overload + def __new__(cls, attr: str, __attr2: str, __attr3: str, __attr4: str) -> attrgetter[Tuple[Any, Any, Any, Any]]: ... + @overload + def __new__(cls, attr: str, *attrs: str) -> attrgetter[Tuple[Any, ...]]: ... + def __call__(self, obj: Any) -> _T_co: ... + +class itemgetter(Generic[_T_co]): + @overload + def __new__(cls, item: Any) -> itemgetter[Any]: ... + @overload + def __new__(cls, item: Any, __item2: Any) -> itemgetter[Tuple[Any, Any]]: ... + @overload + def __new__(cls, item: Any, __item2: Any, __item3: Any) -> itemgetter[Tuple[Any, Any, Any]]: ... + @overload + def __new__(cls, item: Any, __item2: Any, __item3: Any, __item4: Any) -> itemgetter[Tuple[Any, Any, Any, Any]]: ... + @overload + def __new__(cls, item: Any, *items: Any) -> itemgetter[Tuple[Any, ...]]: ... + def __call__(self, obj: Any) -> _T_co: ... + +class methodcaller: + def __init__(self, __name: str, *args: Any, **kwargs: Any) -> None: ... + def __call__(self, obj: Any) -> Any: ... + def iadd(__a: Any, __b: Any) -> Any: ... def __iadd__(a: Any, b: Any) -> Any: ... def iand(__a: Any, __b: Any) -> Any: ... diff --git a/stdlib/optparse.pyi b/stdlib/optparse.pyi index 78d45d084..2229807bc 100644 --- a/stdlib/optparse.pyi +++ b/stdlib/optparse.pyi @@ -53,7 +53,6 @@ class HelpFormatter: short_first: Any width: int def __init__(self, indent_increment: int, max_help_position: int, width: Optional[int], short_first: int) -> None: ... - def _format__Text(self, _Text: _Text) -> _Text: ... def dedent(self) -> None: ... def expand_default(self, option: Option) -> _Text: ... def format_description(self, description: _Text) -> _Text: ... @@ -165,8 +164,8 @@ class Values: def _update_careful(self, dict: Mapping[_Text, Any]) -> None: ... def _update_loose(self, dict: Mapping[_Text, Any]) -> None: ... def ensure_value(self, attr: _Text, value: Any) -> Any: ... - def read_file(self, filename: _Text, mode: _Text) -> None: ... - def read_module(self, modname: _Text, mode: _Text) -> None: ... + def read_file(self, filename: _Text, mode: _Text = ...) -> None: ... + def read_module(self, modname: _Text, mode: _Text = ...) -> None: ... def __getattr__(self, name: str) -> Any: ... def __setattr__(self, name: str, value: Any) -> None: ... @@ -187,7 +186,7 @@ class OptionParser(OptionContainer): def __init__( self, usage: Optional[_Text] = ..., - option_list: Iterable[Option] = ..., + option_list: Optional[Iterable[Option]] = ..., option_class: Type[Option] = ..., version: Optional[_Text] = ..., conflict_handler: _Text = ..., diff --git a/stdlib/os/__init__.pyi b/stdlib/os/__init__.pyi index 7df622984..f88f9c6a9 100644 --- a/stdlib/os/__init__.pyi +++ b/stdlib/os/__init__.pyi @@ -11,6 +11,7 @@ from _typeshed import ( from builtins import OSError, _PathLike from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWrapper as _TextIOWrapper from posix import listdir as listdir, times_result +from subprocess import Popen from typing import ( IO, Any, @@ -176,7 +177,36 @@ R_OK: int W_OK: int X_OK: int +_EnvironCodeFunc = Callable[[AnyStr], AnyStr] + class _Environ(MutableMapping[AnyStr, AnyStr], Generic[AnyStr]): + encodekey: _EnvironCodeFunc[AnyStr] + decodekey: _EnvironCodeFunc[AnyStr] + encodevalue: _EnvironCodeFunc[AnyStr] + decodevalue: _EnvironCodeFunc[AnyStr] + if sys.version_info >= (3, 9): + def __init__( + self, + data: MutableMapping[AnyStr, AnyStr], + encodekey: _EnvironCodeFunc[AnyStr], + decodekey: _EnvironCodeFunc[AnyStr], + encodevalue: _EnvironCodeFunc[AnyStr], + decodevalue: _EnvironCodeFunc[AnyStr], + ) -> None: ... + else: + putenv: Callable[[AnyStr, AnyStr], None] + unsetenv: Callable[[AnyStr, AnyStr], None] + def __init__( + self, + data: MutableMapping[AnyStr, AnyStr], + encodekey: _EnvironCodeFunc[AnyStr], + decodekey: _EnvironCodeFunc[AnyStr], + encodevalue: _EnvironCodeFunc[AnyStr], + decodevalue: _EnvironCodeFunc[AnyStr], + putenv: Callable[[AnyStr, AnyStr], None], + unsetenv: Callable[[AnyStr, AnyStr], None], + ) -> None: ... + def setdefault(self, key: AnyStr, value: AnyStr) -> AnyStr: ... # type: ignore def copy(self) -> Dict[AnyStr, AnyStr]: ... def __delitem__(self, key: AnyStr) -> None: ... def __getitem__(self, key: AnyStr) -> AnyStr: ... @@ -726,6 +756,7 @@ if sys.platform != "win32": def plock(op: int) -> None: ... # ???op is int? class _wrap_close(_TextIOWrapper): + def __init__(self, stream: _TextIOWrapper, proc: Popen[str]) -> None: ... def close(self) -> Optional[int]: ... # type: ignore def popen(cmd: str, mode: str = ..., buffering: int = ...) -> _wrap_close: ... diff --git a/stdlib/pipes.pyi b/stdlib/pipes.pyi index 2c2fd400a..fb9d7e4e1 100644 --- a/stdlib/pipes.pyi +++ b/stdlib/pipes.pyi @@ -8,7 +8,7 @@ class Template: def append(self, cmd: str, kind: str) -> None: ... def prepend(self, cmd: str, kind: str) -> None: ... def open(self, file: str, rw: str) -> os._wrap_close: ... - def copy(self, file: str, rw: str) -> os._wrap_close: ... + def copy(self, infile: str, outfile: str) -> int: ... # Not documented, but widely used. # Documented as shlex.quote since 3.3. diff --git a/stdlib/pkgutil.pyi b/stdlib/pkgutil.pyi index ae042b73d..1f974619f 100644 --- a/stdlib/pkgutil.pyi +++ b/stdlib/pkgutil.pyi @@ -21,7 +21,7 @@ else: def extend_path(path: Iterable[str], name: str) -> Iterable[str]: ... class ImpImporter: - def __init__(self, dirname: Optional[str] = ...) -> None: ... + def __init__(self, path: Optional[str] = ...) -> None: ... class ImpLoader: def __init__(self, fullname: str, file: IO[str], filename: str, etc: Tuple[str, str, int]) -> None: ... diff --git a/tests/stubtest_whitelists/py3_common.txt b/tests/stubtest_whitelists/py3_common.txt index 47530a47a..98214a4c0 100644 --- a/tests/stubtest_whitelists/py3_common.txt +++ b/tests/stubtest_whitelists/py3_common.txt @@ -24,9 +24,6 @@ _collections_abc.Set.isdisjoint _csv.Dialect.__init__ _dummy_threading _importlib_modulespec -_operator.attrgetter # not a function at runtime -_operator.itemgetter # not a function at runtime -_operator.methodcaller _threading_local.local.__new__ _typeshed.* # Utility types for typeshed, doesn't exist at runtime _weakref.CallableProxyType.__getattr__ @@ -225,26 +222,11 @@ multiprocessing.synchronize.Event.__init__ multiprocessing.synchronize.SemLock.__init__ multiprocessing.synchronize.SemLock.acquire multiprocessing.synchronize.SemLock.release -netrc.NetrcParseError.__init__ -netrc.netrc.__init__ -ntpath.join -numbers.Number.__hash__ -operator.attrgetter # not a function at runtime -operator.itemgetter # not a function at runtime -operator.methodcaller -optparse.HelpFormatter._format__Text -optparse.OptionParser.__init__ -optparse.Values.__getattr__ -optparse.Values.read_file -optparse.Values.read_module -os._Environ.__init__ -os._Environ.setdefault -os._wrap_close.__init__ -pickle.Pickler.persistent_id -pickle.Unpickler.persistent_load -pipes.Template.copy -pkgutil.ImpImporter.__init__ -poplib.POP3_SSL.stls +numbers.Number.__hash__ # typeshed marks this as abstract but code just sets this as None +optparse.Values.__getattr__ # Some attributes are set in __init__ using setattr +pickle.Pickler.persistent_id # C pickler persistent_id is an attribute +pickle.Unpickler.persistent_load # C unpickler persistent_load is an attribute +poplib.POP3_SSL.stls # bad declaration of inherited function. See poplib.pyi pydoc.HTMLDoc.docdata pydoc.HTMLDoc.docproperty pydoc.HTMLDoc.docroutine