Move Match and Pattern to re.pyi; move ContextManager protocols to contextlib.pyi (#8447)

This commit is contained in:
Alex Waygood
2022-07-31 14:27:47 +01:00
committed by GitHub
parent 36a5bb08ad
commit ea7bbbdad7
3 changed files with 145 additions and 140 deletions

View File

@@ -1,8 +1,9 @@
import sys
from _typeshed import Self, StrOrBytesPath
from abc import abstractmethod
from collections.abc import AsyncGenerator, AsyncIterator, Awaitable, Callable, Generator, Iterator
from types import TracebackType
from typing import IO, Any, AsyncContextManager, ContextManager, Generic, Protocol, TypeVar, overload # noqa: Y022,Y027
from typing import IO, Any, Generic, Protocol, TypeVar, overload, runtime_checkable
from typing_extensions import ParamSpec, TypeAlias
__all__ = [
@@ -35,8 +36,21 @@ _P = ParamSpec("_P")
_ExitFunc: TypeAlias = Callable[[type[BaseException] | None, BaseException | None, TracebackType | None], bool | None]
_CM_EF = TypeVar("_CM_EF", bound=AbstractContextManager[Any] | _ExitFunc)
AbstractContextManager = ContextManager
AbstractAsyncContextManager = AsyncContextManager
@runtime_checkable
class AbstractContextManager(Protocol[_T_co]):
def __enter__(self) -> _T_co: ...
@abstractmethod
def __exit__(
self, __exc_type: type[BaseException] | None, __exc_value: BaseException | None, __traceback: TracebackType | None
) -> bool | None: ...
@runtime_checkable
class AbstractAsyncContextManager(Protocol[_T_co]):
async def __aenter__(self) -> _T_co: ...
@abstractmethod
async def __aexit__(
self, __exc_type: type[BaseException] | None, __exc_value: BaseException | None, __traceback: TracebackType | None
) -> bool | None: ...
class ContextDecorator:
def __call__(self, func: _F) -> _F: ...

View File

@@ -2,10 +2,13 @@ import enum
import sre_compile
import sys
from _typeshed import ReadableBuffer
from collections.abc import Callable, Iterator
from collections.abc import Callable, Iterator, Mapping
from sre_constants import error as error
from typing import Any, AnyStr, Match as Match, Pattern as Pattern, overload
from typing_extensions import TypeAlias
from typing import Any, AnyStr, Generic, TypeVar, overload
from typing_extensions import Literal, TypeAlias, final
if sys.version_info >= (3, 9):
from types import GenericAlias
__all__ = [
"match",
@@ -42,6 +45,121 @@ __all__ = [
if sys.version_info >= (3, 11):
__all__ += ["NOFLAG", "RegexFlag"]
_T = TypeVar("_T")
@final
class Match(Generic[AnyStr]):
@property
def pos(self) -> int: ...
@property
def endpos(self) -> int: ...
@property
def lastindex(self) -> int | None: ...
@property
def lastgroup(self) -> str | None: ...
@property
def string(self) -> AnyStr: ...
# The regular expression object whose match() or search() method produced
# this match instance.
@property
def re(self) -> Pattern[AnyStr]: ...
@overload
def expand(self: Match[str], template: str) -> str: ...
@overload
def expand(self: Match[bytes], template: ReadableBuffer) -> bytes: ...
# group() returns "AnyStr" or "AnyStr | None", depending on the pattern.
@overload
def group(self, __group: Literal[0] = ...) -> AnyStr: ...
@overload
def group(self, __group: str | int) -> AnyStr | Any: ...
@overload
def group(self, __group1: str | int, __group2: str | int, *groups: str | int) -> tuple[AnyStr | Any, ...]: ...
# Each item of groups()'s return tuple is either "AnyStr" or
# "AnyStr | None", depending on the pattern.
@overload
def groups(self) -> tuple[AnyStr | Any, ...]: ...
@overload
def groups(self, default: _T) -> tuple[AnyStr | _T, ...]: ...
# Each value in groupdict()'s return dict is either "AnyStr" or
# "AnyStr | None", depending on the pattern.
@overload
def groupdict(self) -> dict[str, AnyStr | Any]: ...
@overload
def groupdict(self, default: _T) -> dict[str, AnyStr | _T]: ...
def start(self, __group: int | str = ...) -> int: ...
def end(self, __group: int | str = ...) -> int: ...
def span(self, __group: int | str = ...) -> tuple[int, int]: ...
@property
def regs(self) -> tuple[tuple[int, int], ...]: ... # undocumented
# __getitem__() returns "AnyStr" or "AnyStr | None", depending on the pattern.
@overload
def __getitem__(self, __key: Literal[0]) -> AnyStr: ...
@overload
def __getitem__(self, __key: int | str) -> AnyStr | Any: ...
def __copy__(self) -> Match[AnyStr]: ...
def __deepcopy__(self, __memo: Any) -> Match[AnyStr]: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any) -> GenericAlias: ...
@final
class Pattern(Generic[AnyStr]):
@property
def flags(self) -> int: ...
@property
def groupindex(self) -> Mapping[str, int]: ...
@property
def groups(self) -> int: ...
@property
def pattern(self) -> AnyStr: ...
@overload
def search(self: Pattern[str], string: str, pos: int = ..., endpos: int = ...) -> Match[str] | None: ...
@overload
def search(self: Pattern[bytes], string: ReadableBuffer, pos: int = ..., endpos: int = ...) -> Match[bytes] | None: ...
@overload
def match(self: Pattern[str], string: str, pos: int = ..., endpos: int = ...) -> Match[str] | None: ...
@overload
def match(self: Pattern[bytes], string: ReadableBuffer, pos: int = ..., endpos: int = ...) -> Match[bytes] | None: ...
@overload
def fullmatch(self: Pattern[str], string: str, pos: int = ..., endpos: int = ...) -> Match[str] | None: ...
@overload
def fullmatch(self: Pattern[bytes], string: ReadableBuffer, pos: int = ..., endpos: int = ...) -> Match[bytes] | None: ...
@overload
def split(self: Pattern[str], string: str, maxsplit: int = ...) -> list[str | Any]: ...
@overload
def split(self: Pattern[bytes], string: ReadableBuffer, maxsplit: int = ...) -> list[bytes | Any]: ...
# return type depends on the number of groups in the pattern
@overload
def findall(self: Pattern[str], string: str, pos: int = ..., endpos: int = ...) -> list[Any]: ...
@overload
def findall(self: Pattern[bytes], string: ReadableBuffer, pos: int = ..., endpos: int = ...) -> list[Any]: ...
@overload
def finditer(self: Pattern[str], string: str, pos: int = ..., endpos: int = ...) -> Iterator[Match[str]]: ...
@overload
def finditer(self: Pattern[bytes], string: ReadableBuffer, pos: int = ..., endpos: int = ...) -> Iterator[Match[bytes]]: ...
@overload
def sub(self: Pattern[str], repl: str | Callable[[Match[str]], str], string: str, count: int = ...) -> str: ...
@overload
def sub(
self: Pattern[bytes],
repl: ReadableBuffer | Callable[[Match[bytes]], ReadableBuffer],
string: ReadableBuffer,
count: int = ...,
) -> bytes: ...
@overload
def subn(self: Pattern[str], repl: str | Callable[[Match[str]], str], string: str, count: int = ...) -> tuple[str, int]: ...
@overload
def subn(
self: Pattern[bytes],
repl: ReadableBuffer | Callable[[Match[bytes]], ReadableBuffer],
string: ReadableBuffer,
count: int = ...,
) -> tuple[bytes, int]: ...
def __copy__(self) -> Pattern[AnyStr]: ...
def __deepcopy__(self, __memo: Any) -> Pattern[AnyStr]: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any) -> GenericAlias: ...
# ----- re variables and constants -----
class RegexFlag(enum.IntFlag):

View File

@@ -1,7 +1,9 @@
import collections # Needed by aliases like DefaultDict, see mypy issue 2986
import sys
from _typeshed import IdentityFunction, Incomplete, ReadableBuffer, Self as TypeshedSelf, SupportsKeysAndGetItem
from _typeshed import IdentityFunction, Incomplete, Self as TypeshedSelf, SupportsKeysAndGetItem
from abc import ABCMeta, abstractmethod
from contextlib import AbstractAsyncContextManager, AbstractContextManager
from re import Match as Match, Pattern as Pattern
from types import (
BuiltinFunctionType,
CodeType,
@@ -14,10 +16,7 @@ from types import (
TracebackType,
WrapperDescriptorType,
)
from typing_extensions import Literal as _Literal, ParamSpec as _ParamSpec, final as _final
if sys.version_info >= (3, 9):
from types import GenericAlias
from typing_extensions import ParamSpec as _ParamSpec, final as _final
__all__ = [
"AbstractSet",
@@ -120,6 +119,9 @@ if sys.version_info >= (3, 11):
"reveal_type",
]
ContextManager = AbstractContextManager
AsyncContextManager = AbstractAsyncContextManager
# This itself is only available during type checking
def type_check_only(func_or_cls: _F) -> _F: ...
@@ -568,22 +570,6 @@ class ValuesView(MappingView, Iterable[_VT_co], Generic[_VT_co]):
if sys.version_info >= (3, 8):
def __reversed__(self) -> Iterator[_VT_co]: ...
@runtime_checkable
class ContextManager(Protocol[_T_co]):
def __enter__(self) -> _T_co: ...
@abstractmethod
def __exit__(
self, __exc_type: Type[BaseException] | None, __exc_value: BaseException | None, __traceback: TracebackType | None
) -> bool | None: ...
@runtime_checkable
class AsyncContextManager(Protocol[_T_co]):
async def __aenter__(self) -> _T_co: ...
@abstractmethod
async def __aexit__(
self, __exc_type: Type[BaseException] | None, __exc_value: BaseException | None, __traceback: TracebackType | None
) -> bool | None: ...
class Mapping(Collection[_KT], Generic[_KT, _VT_co]):
# TODO: We wish the key type could also be covariant, but that doesn't work,
# see discussion in https://github.com/python/typing/pull/273.
@@ -718,119 +704,6 @@ class TextIO(IO[str]):
class ByteString(Sequence[int], metaclass=ABCMeta): ...
@_final
class Match(Generic[AnyStr]):
@property
def pos(self) -> int: ...
@property
def endpos(self) -> int: ...
@property
def lastindex(self) -> int | None: ...
@property
def lastgroup(self) -> str | None: ...
@property
def string(self) -> AnyStr: ...
# The regular expression object whose match() or search() method produced
# this match instance.
@property
def re(self) -> Pattern[AnyStr]: ...
@overload
def expand(self: Match[str], template: str) -> str: ...
@overload
def expand(self: Match[bytes], template: ReadableBuffer) -> bytes: ...
# group() returns "AnyStr" or "AnyStr | None", depending on the pattern.
@overload
def group(self, __group: _Literal[0] = ...) -> AnyStr: ...
@overload
def group(self, __group: str | int) -> AnyStr | Any: ...
@overload
def group(self, __group1: str | int, __group2: str | int, *groups: str | int) -> tuple[AnyStr | Any, ...]: ...
# Each item of groups()'s return tuple is either "AnyStr" or
# "AnyStr | None", depending on the pattern.
@overload
def groups(self) -> tuple[AnyStr | Any, ...]: ...
@overload
def groups(self, default: _T) -> tuple[AnyStr | _T, ...]: ...
# Each value in groupdict()'s return dict is either "AnyStr" or
# "AnyStr | None", depending on the pattern.
@overload
def groupdict(self) -> dict[str, AnyStr | Any]: ...
@overload
def groupdict(self, default: _T) -> dict[str, AnyStr | _T]: ...
def start(self, __group: int | str = ...) -> int: ...
def end(self, __group: int | str = ...) -> int: ...
def span(self, __group: int | str = ...) -> tuple[int, int]: ...
@property
def regs(self) -> tuple[tuple[int, int], ...]: ... # undocumented
# __getitem__() returns "AnyStr" or "AnyStr | None", depending on the pattern.
@overload
def __getitem__(self, __key: _Literal[0]) -> AnyStr: ...
@overload
def __getitem__(self, __key: int | str) -> AnyStr | Any: ...
def __copy__(self) -> Match[AnyStr]: ...
def __deepcopy__(self, __memo: Any) -> Match[AnyStr]: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any) -> GenericAlias: ...
@_final
class Pattern(Generic[AnyStr]):
@property
def flags(self) -> int: ...
@property
def groupindex(self) -> Mapping[str, int]: ...
@property
def groups(self) -> int: ...
@property
def pattern(self) -> AnyStr: ...
@overload
def search(self: Pattern[str], string: str, pos: int = ..., endpos: int = ...) -> Match[str] | None: ...
@overload
def search(self: Pattern[bytes], string: ReadableBuffer, pos: int = ..., endpos: int = ...) -> Match[bytes] | None: ...
@overload
def match(self: Pattern[str], string: str, pos: int = ..., endpos: int = ...) -> Match[str] | None: ...
@overload
def match(self: Pattern[bytes], string: ReadableBuffer, pos: int = ..., endpos: int = ...) -> Match[bytes] | None: ...
@overload
def fullmatch(self: Pattern[str], string: str, pos: int = ..., endpos: int = ...) -> Match[str] | None: ...
@overload
def fullmatch(self: Pattern[bytes], string: ReadableBuffer, pos: int = ..., endpos: int = ...) -> Match[bytes] | None: ...
@overload
def split(self: Pattern[str], string: str, maxsplit: int = ...) -> list[str | Any]: ...
@overload
def split(self: Pattern[bytes], string: ReadableBuffer, maxsplit: int = ...) -> list[bytes | Any]: ...
# return type depends on the number of groups in the pattern
@overload
def findall(self: Pattern[str], string: str, pos: int = ..., endpos: int = ...) -> list[Any]: ...
@overload
def findall(self: Pattern[bytes], string: ReadableBuffer, pos: int = ..., endpos: int = ...) -> list[Any]: ...
@overload
def finditer(self: Pattern[str], string: str, pos: int = ..., endpos: int = ...) -> Iterator[Match[str]]: ...
@overload
def finditer(self: Pattern[bytes], string: ReadableBuffer, pos: int = ..., endpos: int = ...) -> Iterator[Match[bytes]]: ...
@overload
def sub(self: Pattern[str], repl: str | Callable[[Match[str]], str], string: str, count: int = ...) -> str: ...
@overload
def sub(
self: Pattern[bytes],
repl: ReadableBuffer | Callable[[Match[bytes]], ReadableBuffer],
string: ReadableBuffer,
count: int = ...,
) -> bytes: ...
@overload
def subn(self: Pattern[str], repl: str | Callable[[Match[str]], str], string: str, count: int = ...) -> tuple[str, int]: ...
@overload
def subn(
self: Pattern[bytes],
repl: ReadableBuffer | Callable[[Match[bytes]], ReadableBuffer],
string: ReadableBuffer,
count: int = ...,
) -> tuple[bytes, int]: ...
def __copy__(self) -> Pattern[AnyStr]: ...
def __deepcopy__(self, __memo: Any) -> Pattern[AnyStr]: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any) -> GenericAlias: ...
# Functions
_get_type_hints_obj_allowed_types = ( # noqa: Y026 # TODO: Use TypeAlias once mypy bugs are fixed