From 628eee29f7d154edecc6c8029cff3f14e2a0421c Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Sat, 10 Aug 2019 22:08:18 +0200 Subject: [PATCH] Use Literal in a few more places (#3176) --- stdlib/2and3/xml/etree/ElementTree.pyi | 6 ++++- stdlib/3/_winapi.pyi | 13 ++++++++--- stdlib/3/ast.pyi | 8 ++++--- stdlib/3/gettext.pyi | 9 +++++--- stdlib/3/subprocess.pyi | 6 ++++- third_party/2and3/werkzeug/wrappers.pyi | 29 ++++++++++++++++++++----- 6 files changed, 54 insertions(+), 17 deletions(-) diff --git a/stdlib/2and3/xml/etree/ElementTree.pyi b/stdlib/2and3/xml/etree/ElementTree.pyi index 6b765f6f4..0318bd8c2 100644 --- a/stdlib/2and3/xml/etree/ElementTree.pyi +++ b/stdlib/2and3/xml/etree/ElementTree.pyi @@ -1,10 +1,14 @@ # Stubs for xml.etree.ElementTree from typing import Any, Callable, Dict, Generator, IO, ItemsView, Iterable, Iterator, KeysView, List, MutableSequence, Optional, overload, Sequence, Text, Tuple, TypeVar, Union -from typing_extensions import Literal import io import sys +if sys.version_info < (3,) or sys.version_info >= (3, 8): + from typing import Literal +else: + from typing_extensions import Literal + VERSION: str class ParseError(SyntaxError): diff --git a/stdlib/3/_winapi.pyi b/stdlib/3/_winapi.pyi index af6c9231b..18a1ee937 100644 --- a/stdlib/3/_winapi.pyi +++ b/stdlib/3/_winapi.pyi @@ -1,5 +1,11 @@ +import sys from typing import Any, Union, Tuple, Optional, overload, Dict, NoReturn, Sequence +if sys.version_info >= (3, 8): + from typing import Literal +else: + from typing_extensions import Literal + CREATE_NEW_CONSOLE: int CREATE_NEW_PROCESS_GROUP: int DUPLICATE_CLOSE_SOURCE: int @@ -46,11 +52,12 @@ WAIT_TIMEOUT: int def CloseHandle(handle: int) -> None: ... -# TODO: once literal types are supported, overload with Literal[True/False] @overload -def ConnectNamedPipe(handle: int, overlapped: Union[int, bool]) -> Any: ... +def ConnectNamedPipe(handle: int, overlapped: Literal[True]) -> Overlapped: ... @overload -def ConnectNamedPipe(handle: int) -> None: ... +def ConnectNamedPipe(handle: int, overlapped: Literal[False] = ...) -> None: ... +@overload +def ConnectNamedPipe(handle: int, overlapped: bool) -> Any: ... def CreateFile(file_name: str, desired_access: int, share_mode: int, security_attributes: int, creation_disposition: int, flags_and_attributes: int, template_file: int) -> int: ... def CreateJunction(src_path: str, dest_path: str) -> None: ... diff --git a/stdlib/3/ast.pyi b/stdlib/3/ast.pyi index e4c355dc2..8e89b2486 100644 --- a/stdlib/3/ast.pyi +++ b/stdlib/3/ast.pyi @@ -1,12 +1,9 @@ -# Python 3.5 ast - import sys # Rename typing to _typing, as not to conflict with typing imported # from _ast below when loaded in an unorthodox way by the Dropbox # internal Bazel integration. import typing as _typing from typing import overload, Any, Iterator, Optional, Union, TypeVar -from typing_extensions import Literal # The same unorthodox Bazel integration causes issues with sys, which # is imported in both modules. unfortunately we can't just rename sys, @@ -14,6 +11,11 @@ from typing_extensions import Literal # sys. from _ast import * # type: ignore +if sys.version_info >= (3, 8): + from typing import Literal +else: + from typing_extensions import Literal + class NodeVisitor(): def visit(self, node: AST) -> Any: ... def generic_visit(self, node: AST) -> Any: ... diff --git a/stdlib/3/gettext.pyi b/stdlib/3/gettext.pyi index 7697404fb..4b5398a46 100644 --- a/stdlib/3/gettext.pyi +++ b/stdlib/3/gettext.pyi @@ -1,7 +1,10 @@ -# Stubs for gettext (Python 3.4) - +import sys from typing import overload, Any, Container, IO, Iterable, Optional, Type, TypeVar -from typing_extensions import Literal + +if sys.version_info >= (3, 8): + from typing import Literal +else: + from typing_extensions import Literal class NullTranslations: def __init__(self, fp: IO[str] = ...) -> None: ... diff --git a/stdlib/3/subprocess.pyi b/stdlib/3/subprocess.pyi index 57bff805e..0e5df2c50 100644 --- a/stdlib/3/subprocess.pyi +++ b/stdlib/3/subprocess.pyi @@ -7,9 +7,13 @@ from typing import ( Generic, TypeVar, AnyStr, overload, ) -from typing_extensions import Literal from types import TracebackType +if sys.version_info >= (3, 8): + from typing import Literal +else: + from typing_extensions import Literal + # We prefer to annotate inputs to methods (eg subprocess.check_call) with these # union types. # For outputs we use laborious literal based overloads to try to determine diff --git a/third_party/2and3/werkzeug/wrappers.pyi b/third_party/2and3/werkzeug/wrappers.pyi index 74cb6ffa8..4ea56495a 100644 --- a/third_party/2and3/werkzeug/wrappers.pyi +++ b/third_party/2and3/werkzeug/wrappers.pyi @@ -1,8 +1,8 @@ +import sys from datetime import datetime from typing import ( - Any, Callable, Iterable, Iterator, Mapping, MutableMapping, Optional, Sequence, Text, Tuple, Type, TypeVar, Union, + Any, Callable, Iterable, Iterator, Mapping, MutableMapping, Optional, Sequence, Text, Tuple, Type, TypeVar, Union, overload ) - from wsgiref.types import WSGIEnvironment, InputStream from .datastructures import ( @@ -12,6 +12,11 @@ from .datastructures import ( ) from .useragents import UserAgent +if sys.version_info >= (3, 8): + from typing import Literal +else: + from typing_extensions import Literal + class BaseRequest: charset: str encoding_errors: str @@ -44,8 +49,16 @@ class BaseRequest: args: ImmutableMultiDict @property def data(self) -> bytes: ... - # TODO: once Literal types are supported, overload with as_text - def get_data(self, cache: bool = ..., as_text: bool = ..., parse_form_data: bool = ...) -> Any: ... # returns bytes if as_text is False (the default), else Text + @overload + def get_data(self, cache: bool = ..., as_text: Literal[False] = ..., parse_form_data: bool = ...) -> bytes: ... + @overload + def get_data(self, cache: bool, as_text: Literal[True], parse_form_data: bool = ...) -> Text: ... + @overload + def get_data(self, *, as_text: Literal[True], parse_form_data: bool = ...) -> Text: ... + @overload + def get_data(self, cache: bool, as_text: bool, parse_form_data: bool = ...) -> Any: ... + @overload + def get_data(self, *, as_text: bool, parse_form_data: bool = ...) -> Any: ... form: ImmutableMultiDict values: CombinedMultiDict files: MultiDict @@ -107,8 +120,12 @@ class BaseResponse: def force_type(cls: Type[_SelfT], response: object, environ: Optional[WSGIEnvironment] = ...) -> _SelfT: ... @classmethod def from_app(cls: Type[_SelfT], app: Any, environ: WSGIEnvironment, buffered: bool = ...) -> _SelfT: ... - # TODO: once Literal types are supported, overload with as_text - def get_data(self, as_text: bool = ...) -> Any: ... # returns bytes if as_text is False (the default), else Text + @overload + def get_data(self, as_text: Literal[False] = ...) -> bytes: ... + @overload + def get_data(self, as_text: Literal[True]) -> Text: ... + @overload + def get_data(self, as_text: bool) -> Any: ... def set_data(self, value: Union[bytes, Text]) -> None: ... data: Any def calculate_content_length(self) -> Optional[int]: ...