From 872e86a76589cd70835f946fb44a12403a56ab68 Mon Sep 17 00:00:00 2001 From: mypybot <> Date: Sun, 15 Sep 2024 00:06:08 +0000 Subject: [PATCH 1/4] Sync typeshed Source commit: https://github.com/python/typeshed/commit/9e506eb5e8fc2823db8c60ad561b1145ff114947 --- mypy/typeshed/stdlib/VERSIONS | 2 +- mypy/typeshed/stdlib/_ctypes.pyi | 6 +- mypy/typeshed/stdlib/_curses.pyi | 2 +- mypy/typeshed/stdlib/_locale.pyi | 149 ++++++++++-------- mypy/typeshed/stdlib/_winapi.pyi | 28 ++++ mypy/typeshed/stdlib/builtins.pyi | 98 +++++++++++- mypy/typeshed/stdlib/codecs.pyi | 2 +- mypy/typeshed/stdlib/copy.pyi | 9 +- mypy/typeshed/stdlib/distutils/dist.pyi | 25 ++- mypy/typeshed/stdlib/doctest.pyi | 26 ++- .../stdlib/email/_header_value_parser.pyi | 4 + mypy/typeshed/stdlib/email/_policybase.pyi | 39 +++-- mypy/typeshed/stdlib/email/errors.pyi | 3 + mypy/typeshed/stdlib/email/utils.pyi | 16 +- mypy/typeshed/stdlib/io.pyi | 3 +- mypy/typeshed/stdlib/subprocess.pyi | 5 + mypy/typeshed/stdlib/tempfile.pyi | 6 +- 17 files changed, 315 insertions(+), 108 deletions(-) diff --git a/mypy/typeshed/stdlib/VERSIONS b/mypy/typeshed/stdlib/VERSIONS index 641f951ce3c0..66bf2bec7cb0 100644 --- a/mypy/typeshed/stdlib/VERSIONS +++ b/mypy/typeshed/stdlib/VERSIONS @@ -41,7 +41,7 @@ _json: 3.0- _locale: 3.0- _lsprof: 3.0- _markupbase: 3.0- -_msi: 3.0- +_msi: 3.0-3.12 _operator: 3.4- _osx_support: 3.0- _posixsubprocess: 3.2- diff --git a/mypy/typeshed/stdlib/_ctypes.pyi b/mypy/typeshed/stdlib/_ctypes.pyi index 0fe7521d7749..5313195a0ba8 100644 --- a/mypy/typeshed/stdlib/_ctypes.pyi +++ b/mypy/typeshed/stdlib/_ctypes.pyi @@ -168,7 +168,11 @@ class Array(_CData, Generic[_CT]): def _type_(self) -> type[_CT]: ... @_type_.setter def _type_(self, value: type[_CT]) -> None: ... - raw: bytes # Note: only available if _CT == c_char + # Note: only available if _CT == c_char + @property + def raw(self) -> bytes: ... + @raw.setter + def raw(self, value: ReadableBuffer) -> None: ... value: Any # Note: bytes if _CT == c_char, str if _CT == c_wchar, unavailable otherwise # TODO These methods cannot be annotated correctly at the moment. # All of these "Any"s stand for the array's element type, but it's not possible to use _CT diff --git a/mypy/typeshed/stdlib/_curses.pyi b/mypy/typeshed/stdlib/_curses.pyi index 505637574af1..b68c8925a041 100644 --- a/mypy/typeshed/stdlib/_curses.pyi +++ b/mypy/typeshed/stdlib/_curses.pyi @@ -493,7 +493,7 @@ class _CursesWindow: def instr(self, y: int, x: int, n: int = ...) -> bytes: ... def is_linetouched(self, line: int, /) -> bool: ... def is_wintouched(self) -> bool: ... - def keypad(self, yes: bool) -> None: ... + def keypad(self, yes: bool, /) -> None: ... def leaveok(self, yes: bool) -> None: ... def move(self, new_y: int, new_x: int) -> None: ... def mvderwin(self, y: int, x: int) -> None: ... diff --git a/mypy/typeshed/stdlib/_locale.pyi b/mypy/typeshed/stdlib/_locale.pyi index 0825e12034f4..ccce7a0d9d70 100644 --- a/mypy/typeshed/stdlib/_locale.pyi +++ b/mypy/typeshed/stdlib/_locale.pyi @@ -1,17 +1,38 @@ import sys from _typeshed import StrPath -from collections.abc import Mapping +from typing import Final, Literal, TypedDict, type_check_only -LC_CTYPE: int -LC_COLLATE: int -LC_TIME: int -LC_MONETARY: int -LC_NUMERIC: int -LC_ALL: int -CHAR_MAX: int +@type_check_only +class _LocaleConv(TypedDict): + decimal_point: str + grouping: list[int] + thousands_sep: str + int_curr_symbol: str + currency_symbol: str + p_cs_precedes: Literal[0, 1, 127] + n_cs_precedes: Literal[0, 1, 127] + p_sep_by_space: Literal[0, 1, 127] + n_sep_by_space: Literal[0, 1, 127] + mon_decimal_point: str + frac_digits: int + int_frac_digits: int + mon_thousands_sep: str + mon_grouping: list[int] + positive_sign: str + negative_sign: str + p_sign_posn: Literal[0, 1, 2, 3, 4, 127] + n_sign_posn: Literal[0, 1, 2, 3, 4, 127] + +LC_CTYPE: Final[int] +LC_COLLATE: Final[int] +LC_TIME: Final[int] +LC_MONETARY: Final[int] +LC_NUMERIC: Final[int] +LC_ALL: Final[int] +CHAR_MAX: Final = 127 def setlocale(category: int, locale: str | None = None, /) -> str: ... -def localeconv() -> Mapping[str, int | str | list[int]]: ... +def localeconv() -> _LocaleConv: ... if sys.version_info >= (3, 11): def getencoding() -> str: ... @@ -25,67 +46,67 @@ def strxfrm(string: str, /) -> str: ... if sys.platform != "win32": LC_MESSAGES: int - ABDAY_1: int - ABDAY_2: int - ABDAY_3: int - ABDAY_4: int - ABDAY_5: int - ABDAY_6: int - ABDAY_7: int + ABDAY_1: Final[int] + ABDAY_2: Final[int] + ABDAY_3: Final[int] + ABDAY_4: Final[int] + ABDAY_5: Final[int] + ABDAY_6: Final[int] + ABDAY_7: Final[int] - ABMON_1: int - ABMON_2: int - ABMON_3: int - ABMON_4: int - ABMON_5: int - ABMON_6: int - ABMON_7: int - ABMON_8: int - ABMON_9: int - ABMON_10: int - ABMON_11: int - ABMON_12: int + ABMON_1: Final[int] + ABMON_2: Final[int] + ABMON_3: Final[int] + ABMON_4: Final[int] + ABMON_5: Final[int] + ABMON_6: Final[int] + ABMON_7: Final[int] + ABMON_8: Final[int] + ABMON_9: Final[int] + ABMON_10: Final[int] + ABMON_11: Final[int] + ABMON_12: Final[int] - DAY_1: int - DAY_2: int - DAY_3: int - DAY_4: int - DAY_5: int - DAY_6: int - DAY_7: int + DAY_1: Final[int] + DAY_2: Final[int] + DAY_3: Final[int] + DAY_4: Final[int] + DAY_5: Final[int] + DAY_6: Final[int] + DAY_7: Final[int] - ERA: int - ERA_D_T_FMT: int - ERA_D_FMT: int - ERA_T_FMT: int + ERA: Final[int] + ERA_D_T_FMT: Final[int] + ERA_D_FMT: Final[int] + ERA_T_FMT: Final[int] - MON_1: int - MON_2: int - MON_3: int - MON_4: int - MON_5: int - MON_6: int - MON_7: int - MON_8: int - MON_9: int - MON_10: int - MON_11: int - MON_12: int + MON_1: Final[int] + MON_2: Final[int] + MON_3: Final[int] + MON_4: Final[int] + MON_5: Final[int] + MON_6: Final[int] + MON_7: Final[int] + MON_8: Final[int] + MON_9: Final[int] + MON_10: Final[int] + MON_11: Final[int] + MON_12: Final[int] - CODESET: int - D_T_FMT: int - D_FMT: int - T_FMT: int - T_FMT_AMPM: int - AM_STR: int - PM_STR: int + CODESET: Final[int] + D_T_FMT: Final[int] + D_FMT: Final[int] + T_FMT: Final[int] + T_FMT_AMPM: Final[int] + AM_STR: Final[int] + PM_STR: Final[int] - RADIXCHAR: int - THOUSEP: int - YESEXPR: int - NOEXPR: int - CRNCYSTR: int - ALT_DIGITS: int + RADIXCHAR: Final[int] + THOUSEP: Final[int] + YESEXPR: Final[int] + NOEXPR: Final[int] + CRNCYSTR: Final[int] + ALT_DIGITS: Final[int] def nl_langinfo(key: int, /) -> str: ... diff --git a/mypy/typeshed/stdlib/_winapi.pyi b/mypy/typeshed/stdlib/_winapi.pyi index 62ea124045cc..0f71a0687748 100644 --- a/mypy/typeshed/stdlib/_winapi.pyi +++ b/mypy/typeshed/stdlib/_winapi.pyi @@ -99,6 +99,20 @@ if sys.platform == "win32": SEC_RESERVE: Final = 0x4000000 SEC_WRITECOMBINE: Final = 0x40000000 + if sys.version_info >= (3, 13): + STARTF_FORCEOFFFEEDBACK: Final = 0x80 + STARTF_FORCEONFEEDBACK: Final = 0x40 + STARTF_PREVENTPINNING: Final = 0x2000 + STARTF_RUNFULLSCREEN: Final = 0x20 + STARTF_TITLEISAPPID: Final = 0x1000 + STARTF_TITLEISLINKNAME: Final = 0x800 + STARTF_UNTRUSTEDSOURCE: Final = 0x8000 + STARTF_USECOUNTCHARS: Final = 0x8 + STARTF_USEFILLATTRIBUTE: Final = 0x10 + STARTF_USEHOTKEY: Final = 0x200 + STARTF_USEPOSITION: Final = 0x4 + STARTF_USESIZE: Final = 0x2 + STARTF_USESHOWWINDOW: Final = 0x1 STARTF_USESTDHANDLES: Final = 0x100 @@ -250,6 +264,20 @@ if sys.platform == "win32": def cancel(self) -> None: ... def getbuffer(self) -> bytes | None: ... + if sys.version_info >= (3, 13): + def BatchedWaitForMultipleObjects( + handle_seq: Sequence[int], wait_all: bool, milliseconds: int = 0xFFFFFFFF + ) -> list[int]: ... + def CreateEventW(security_attributes: int, manual_reset: bool, initial_state: bool, name: str | None) -> int: ... + def CreateMutexW(security_attributes: int, initial_owner: bool, name: str) -> int: ... + def GetLongPathName(path: str) -> str: ... + def GetShortPathName(path: str) -> str: ... + def OpenEventW(desired_access: int, inherit_handle: bool, name: str) -> int: ... + def OpenMutexW(desired_access: int, inherit_handle: bool, name: str) -> int: ... + def ReleaseMutex(mutex: int) -> None: ... + def ResetEvent(event: int) -> None: ... + def SetEvent(event: int) -> None: ... + if sys.version_info >= (3, 12): def CopyFile2(existing_file_name: str, new_file_name: str, flags: int, progress_routine: int | None = None) -> int: ... def NeedCurrentDirectoryForExePath(exe_name: str, /) -> bool: ... diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi index a6065cc6777f..f70e3d6db1b1 100644 --- a/mypy/typeshed/stdlib/builtins.pyi +++ b/mypy/typeshed/stdlib/builtins.pyi @@ -1,3 +1,4 @@ +# ruff: noqa: PYI036 # This is the module declaring BaseException import _ast import _typeshed import sys @@ -62,6 +63,7 @@ from typing import ( # noqa: Y022 from typing_extensions import ( # noqa: Y023 Concatenate, Literal, + LiteralString, ParamSpec, Self, TypeAlias, @@ -436,16 +438,31 @@ class str(Sequence[str]): def __new__(cls, object: object = ...) -> Self: ... @overload def __new__(cls, object: ReadableBuffer, encoding: str = ..., errors: str = ...) -> Self: ... + @overload + def capitalize(self: LiteralString) -> LiteralString: ... + @overload def capitalize(self) -> str: ... # type: ignore[misc] + @overload + def casefold(self: LiteralString) -> LiteralString: ... + @overload def casefold(self) -> str: ... # type: ignore[misc] + @overload + def center(self: LiteralString, width: SupportsIndex, fillchar: LiteralString = " ", /) -> LiteralString: ... + @overload def center(self, width: SupportsIndex, fillchar: str = " ", /) -> str: ... # type: ignore[misc] def count(self, sub: str, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /) -> int: ... def encode(self, encoding: str = "utf-8", errors: str = "strict") -> bytes: ... def endswith( self, suffix: str | tuple[str, ...], start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., / ) -> bool: ... + @overload + def expandtabs(self: LiteralString, tabsize: SupportsIndex = 8) -> LiteralString: ... + @overload def expandtabs(self, tabsize: SupportsIndex = 8) -> str: ... # type: ignore[misc] def find(self, sub: str, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /) -> int: ... + @overload + def format(self: LiteralString, *args: LiteralString, **kwargs: LiteralString) -> LiteralString: ... + @overload def format(self, *args: object, **kwargs: object) -> str: ... def format_map(self, mapping: _FormatMapMapping, /) -> str: ... def index(self, sub: str, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /) -> int: ... @@ -461,35 +478,99 @@ class str(Sequence[str]): def isspace(self) -> bool: ... def istitle(self) -> bool: ... def isupper(self) -> bool: ... + @overload + def join(self: LiteralString, iterable: Iterable[LiteralString], /) -> LiteralString: ... + @overload def join(self, iterable: Iterable[str], /) -> str: ... # type: ignore[misc] + @overload + def ljust(self: LiteralString, width: SupportsIndex, fillchar: LiteralString = " ", /) -> LiteralString: ... + @overload def ljust(self, width: SupportsIndex, fillchar: str = " ", /) -> str: ... # type: ignore[misc] + @overload + def lower(self: LiteralString) -> LiteralString: ... + @overload def lower(self) -> str: ... # type: ignore[misc] + @overload + def lstrip(self: LiteralString, chars: LiteralString | None = None, /) -> LiteralString: ... + @overload def lstrip(self, chars: str | None = None, /) -> str: ... # type: ignore[misc] + @overload + def partition(self: LiteralString, sep: LiteralString, /) -> tuple[LiteralString, LiteralString, LiteralString]: ... + @overload def partition(self, sep: str, /) -> tuple[str, str, str]: ... # type: ignore[misc] if sys.version_info >= (3, 13): + @overload + def replace( + self: LiteralString, old: LiteralString, new: LiteralString, /, count: SupportsIndex = -1 + ) -> LiteralString: ... + @overload def replace(self, old: str, new: str, /, count: SupportsIndex = -1) -> str: ... # type: ignore[misc] else: + @overload + def replace( + self: LiteralString, old: LiteralString, new: LiteralString, count: SupportsIndex = -1, / + ) -> LiteralString: ... + @overload def replace(self, old: str, new: str, count: SupportsIndex = -1, /) -> str: ... # type: ignore[misc] if sys.version_info >= (3, 9): + @overload + def removeprefix(self: LiteralString, prefix: LiteralString, /) -> LiteralString: ... + @overload def removeprefix(self, prefix: str, /) -> str: ... # type: ignore[misc] + @overload + def removesuffix(self: LiteralString, suffix: LiteralString, /) -> LiteralString: ... + @overload def removesuffix(self, suffix: str, /) -> str: ... # type: ignore[misc] def rfind(self, sub: str, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /) -> int: ... def rindex(self, sub: str, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /) -> int: ... + @overload + def rjust(self: LiteralString, width: SupportsIndex, fillchar: LiteralString = " ", /) -> LiteralString: ... + @overload def rjust(self, width: SupportsIndex, fillchar: str = " ", /) -> str: ... # type: ignore[misc] + @overload + def rpartition(self: LiteralString, sep: LiteralString, /) -> tuple[LiteralString, LiteralString, LiteralString]: ... + @overload def rpartition(self, sep: str, /) -> tuple[str, str, str]: ... # type: ignore[misc] + @overload + def rsplit(self: LiteralString, sep: LiteralString | None = None, maxsplit: SupportsIndex = -1) -> list[LiteralString]: ... + @overload def rsplit(self, sep: str | None = None, maxsplit: SupportsIndex = -1) -> list[str]: ... # type: ignore[misc] + @overload + def rstrip(self: LiteralString, chars: LiteralString | None = None, /) -> LiteralString: ... + @overload def rstrip(self, chars: str | None = None, /) -> str: ... # type: ignore[misc] + @overload + def split(self: LiteralString, sep: LiteralString | None = None, maxsplit: SupportsIndex = -1) -> list[LiteralString]: ... + @overload def split(self, sep: str | None = None, maxsplit: SupportsIndex = -1) -> list[str]: ... # type: ignore[misc] + @overload + def splitlines(self: LiteralString, keepends: bool = False) -> list[LiteralString]: ... + @overload def splitlines(self, keepends: bool = False) -> list[str]: ... # type: ignore[misc] def startswith( self, prefix: str | tuple[str, ...], start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., / ) -> bool: ... + @overload + def strip(self: LiteralString, chars: LiteralString | None = None, /) -> LiteralString: ... + @overload def strip(self, chars: str | None = None, /) -> str: ... # type: ignore[misc] + @overload + def swapcase(self: LiteralString) -> LiteralString: ... + @overload def swapcase(self) -> str: ... # type: ignore[misc] + @overload + def title(self: LiteralString) -> LiteralString: ... + @overload def title(self) -> str: ... # type: ignore[misc] def translate(self, table: _TranslateTable, /) -> str: ... + @overload + def upper(self: LiteralString) -> LiteralString: ... + @overload def upper(self) -> str: ... # type: ignore[misc] + @overload + def zfill(self: LiteralString, width: SupportsIndex, /) -> LiteralString: ... + @overload def zfill(self, width: SupportsIndex, /) -> str: ... # type: ignore[misc] @staticmethod @overload @@ -500,6 +581,9 @@ class str(Sequence[str]): @staticmethod @overload def maketrans(x: str, y: str, z: str, /) -> dict[int, int | None]: ... + @overload + def __add__(self: LiteralString, value: LiteralString, /) -> LiteralString: ... + @overload def __add__(self, value: str, /) -> str: ... # type: ignore[misc] # Incompatible with Sequence.__contains__ def __contains__(self, key: str, /) -> bool: ... # type: ignore[override] @@ -508,13 +592,25 @@ class str(Sequence[str]): def __getitem__(self, key: SupportsIndex | slice, /) -> str: ... def __gt__(self, value: str, /) -> bool: ... def __hash__(self) -> int: ... + @overload + def __iter__(self: LiteralString) -> Iterator[LiteralString]: ... + @overload def __iter__(self) -> Iterator[str]: ... # type: ignore[misc] def __le__(self, value: str, /) -> bool: ... def __len__(self) -> int: ... def __lt__(self, value: str, /) -> bool: ... + @overload + def __mod__(self: LiteralString, value: LiteralString | tuple[LiteralString, ...], /) -> LiteralString: ... + @overload def __mod__(self, value: Any, /) -> str: ... + @overload + def __mul__(self: LiteralString, value: SupportsIndex, /) -> LiteralString: ... + @overload def __mul__(self, value: SupportsIndex, /) -> str: ... # type: ignore[misc] def __ne__(self, value: object, /) -> bool: ... + @overload + def __rmul__(self: LiteralString, value: SupportsIndex, /) -> LiteralString: ... + @overload def __rmul__(self, value: SupportsIndex, /) -> str: ... # type: ignore[misc] def __getnewargs__(self) -> tuple[str]: ... @@ -1653,7 +1749,7 @@ _SupportsSumNoDefaultT = TypeVar("_SupportsSumNoDefaultT", bound=_SupportsSumWit # without creating many false-positive errors (see #7578). # Instead, we special-case the most common examples of this: bool and literal integers. @overload -def sum(iterable: Iterable[bool], /, start: int = 0) -> int: ... +def sum(iterable: Iterable[bool | _LiteralInteger], /, start: int = 0) -> int: ... @overload def sum(iterable: Iterable[_SupportsSumNoDefaultT], /) -> _SupportsSumNoDefaultT | Literal[0]: ... @overload diff --git a/mypy/typeshed/stdlib/codecs.pyi b/mypy/typeshed/stdlib/codecs.pyi index 9bc098dbc6d7..a41df9752d33 100644 --- a/mypy/typeshed/stdlib/codecs.pyi +++ b/mypy/typeshed/stdlib/codecs.pyi @@ -80,7 +80,7 @@ class _Encoder(Protocol): def __call__(self, input: str, errors: str = ..., /) -> tuple[bytes, int]: ... # signature of Codec().encode class _Decoder(Protocol): - def __call__(self, input: bytes, errors: str = ..., /) -> tuple[str, int]: ... # signature of Codec().decode + def __call__(self, input: ReadableBuffer, errors: str = ..., /) -> tuple[str, int]: ... # signature of Codec().decode class _StreamReader(Protocol): def __call__(self, stream: _ReadableStream, errors: str = ..., /) -> StreamReader: ... diff --git a/mypy/typeshed/stdlib/copy.pyi b/mypy/typeshed/stdlib/copy.pyi index 020ce6c31b58..2cceec6a2250 100644 --- a/mypy/typeshed/stdlib/copy.pyi +++ b/mypy/typeshed/stdlib/copy.pyi @@ -1,16 +1,15 @@ import sys from typing import Any, Protocol, TypeVar -from typing_extensions import ParamSpec, Self +from typing_extensions import Self __all__ = ["Error", "copy", "deepcopy"] _T = TypeVar("_T") -_SR = TypeVar("_SR", bound=_SupportsReplace[Any]) -_P = ParamSpec("_P") +_SR = TypeVar("_SR", bound=_SupportsReplace) -class _SupportsReplace(Protocol[_P]): +class _SupportsReplace(Protocol): # In reality doesn't support args, but there's no other great way to express this. - def __replace__(self, *args: _P.args, **kwargs: _P.kwargs) -> Self: ... + def __replace__(self, *args: Any, **kwargs: Any) -> Self: ... # None in CPython but non-None in Jython PyStringMap: Any diff --git a/mypy/typeshed/stdlib/distutils/dist.pyi b/mypy/typeshed/stdlib/distutils/dist.pyi index 7013167dddbf..75fc7dbb388d 100644 --- a/mypy/typeshed/stdlib/distutils/dist.pyi +++ b/mypy/typeshed/stdlib/distutils/dist.pyi @@ -270,7 +270,7 @@ class Distribution: def has_data_files(self) -> bool: ... def is_pure(self) -> bool: ... - # Getter methods generated in __init__ + # Default getter methods generated in __init__ from self.metadata._METHOD_BASENAMES def get_name(self) -> str: ... def get_version(self) -> str: ... def get_fullname(self) -> str: ... @@ -292,3 +292,26 @@ class Distribution: def get_requires(self) -> list[str]: ... def get_provides(self) -> list[str]: ... def get_obsoletes(self) -> list[str]: ... + + # Default attributes generated in __init__ from self.display_option_names + help_commands: bool | Literal[0] + name: str | Literal[0] + version: str | Literal[0] + fullname: str | Literal[0] + author: str | Literal[0] + author_email: str | Literal[0] + maintainer: str | Literal[0] + maintainer_email: str | Literal[0] + contact: str | Literal[0] + contact_email: str | Literal[0] + url: str | Literal[0] + license: str | Literal[0] + licence: str | Literal[0] + description: str | Literal[0] + long_description: str | Literal[0] + platforms: str | list[str] | Literal[0] + classifiers: str | list[str] | Literal[0] + keywords: str | list[str] | Literal[0] + provides: list[str] | Literal[0] + requires: list[str] | Literal[0] + obsoletes: list[str] | Literal[0] diff --git a/mypy/typeshed/stdlib/doctest.pyi b/mypy/typeshed/stdlib/doctest.pyi index 7e334ef0c504..4380083027a6 100644 --- a/mypy/typeshed/stdlib/doctest.pyi +++ b/mypy/typeshed/stdlib/doctest.pyi @@ -1,9 +1,10 @@ +import sys import types import unittest from _typeshed import ExcInfo from collections.abc import Callable -from typing import Any, NamedTuple -from typing_extensions import TypeAlias +from typing import Any, ClassVar, NamedTuple +from typing_extensions import Self, TypeAlias __all__ = [ "register_optionflag", @@ -41,9 +42,22 @@ __all__ = [ "debug", ] -class TestResults(NamedTuple): - failed: int - attempted: int +# MyPy errors on conditionals within named tuples. + +if sys.version_info >= (3, 13): + class TestResults(NamedTuple): + def __new__(cls, failed: int, attempted: int, *, skipped: int = 0) -> Self: ... # type: ignore[misc] + skipped: int + failed: int + attempted: int + _fields: ClassVar = ("failed", "attempted") # type: ignore[misc] + __match_args__ = ("failed", "attempted") # type: ignore[misc] + __doc__: None # type: ignore[misc] + +else: + class TestResults(NamedTuple): + failed: int + attempted: int OPTIONFLAGS_BY_NAME: dict[str, int] @@ -134,6 +148,8 @@ class DocTestRunner: original_optionflags: int tries: int failures: int + if sys.version_info >= (3, 13): + skips: int test: DocTest def __init__(self, checker: OutputChecker | None = None, verbose: bool | None = None, optionflags: int = 0) -> None: ... def report_start(self, out: _Out, test: DocTest, example: Example) -> None: ... diff --git a/mypy/typeshed/stdlib/email/_header_value_parser.pyi b/mypy/typeshed/stdlib/email/_header_value_parser.pyi index 806fc84cf784..ff405a8b61d2 100644 --- a/mypy/typeshed/stdlib/email/_header_value_parser.pyi +++ b/mypy/typeshed/stdlib/email/_header_value_parser.pyi @@ -16,6 +16,10 @@ TOKEN_ENDS: Final[set[str]] ASPECIALS: Final[set[str]] ATTRIBUTE_ENDS: Final[set[str]] EXTENDED_ATTRIBUTE_ENDS: Final[set[str]] +# Added in Python 3.8.20, 3.9.20, 3.10.15, 3.11.10, 3.12.5 +NLSET: Final[set[str]] +# Added in Python 3.8.20, 3.9.20, 3.10.15, 3.11.10, 3.12.5 +SPECIALSNL: Final[set[str]] def quote_string(value: Any) -> str: ... diff --git a/mypy/typeshed/stdlib/email/_policybase.pyi b/mypy/typeshed/stdlib/email/_policybase.pyi index a3dd61a282ce..9e1f653c9d78 100644 --- a/mypy/typeshed/stdlib/email/_policybase.pyi +++ b/mypy/typeshed/stdlib/email/_policybase.pyi @@ -3,20 +3,9 @@ from collections.abc import Callable from email.errors import MessageDefect from email.header import Header from email.message import Message -from typing import Any from typing_extensions import Self class _PolicyBase: - def __add__(self, other: Any) -> Self: ... - def clone(self, **kw: Any) -> Self: ... - -class Policy(_PolicyBase, metaclass=ABCMeta): - max_line_length: int | None - linesep: str - cte_type: str - raise_on_defect: bool - mangle_from_: bool - message_factory: Callable[[Policy], Message] | None def __init__( self, *, @@ -24,9 +13,35 @@ class Policy(_PolicyBase, metaclass=ABCMeta): linesep: str = "\n", cte_type: str = "8bit", raise_on_defect: bool = False, - mangle_from_: bool = False, + mangle_from_: bool = ..., # default depends on sub-class message_factory: Callable[[Policy], Message] | None = None, + # Added in Python 3.8.20, 3.9.20, 3.10.15, 3.11.10, 3.12.5 + verify_generated_headers: bool = True, ) -> None: ... + def clone( + self, + *, + max_line_length: int | None = ..., + linesep: str = ..., + cte_type: str = ..., + raise_on_defect: bool = ..., + mangle_from_: bool = ..., + message_factory: Callable[[Policy], Message] | None = ..., + # Added in Python 3.8.20, 3.9.20, 3.10.15, 3.11.10, 3.12.5 + verify_generated_headers: bool = ..., + ) -> Self: ... + def __add__(self, other: Policy) -> Self: ... + +class Policy(_PolicyBase, metaclass=ABCMeta): + max_line_length: int | None + linesep: str + cte_type: str + raise_on_defect: bool + mangle_from_: bool + message_factory: Callable[[Policy], Message] | None + # Added in Python 3.8.20, 3.9.20, 3.10.15, 3.11.10, 3.12.5 + verify_generated_headers: bool + def handle_defect(self, obj: Message, defect: MessageDefect) -> None: ... def register_defect(self, obj: Message, defect: MessageDefect) -> None: ... def header_max_count(self, name: str) -> int | None: ... diff --git a/mypy/typeshed/stdlib/email/errors.pyi b/mypy/typeshed/stdlib/email/errors.pyi index c54f1560c9ae..f105576c5ee4 100644 --- a/mypy/typeshed/stdlib/email/errors.pyi +++ b/mypy/typeshed/stdlib/email/errors.pyi @@ -7,6 +7,9 @@ class BoundaryError(MessageParseError): ... class MultipartConversionError(MessageError, TypeError): ... class CharsetError(MessageError): ... +# Added in Python 3.8.20, 3.9.20, 3.10.15, 3.11.10, 3.12.5 +class HeaderWriteError(MessageError): ... + class MessageDefect(ValueError): def __init__(self, line: str | None = None) -> None: ... diff --git a/mypy/typeshed/stdlib/email/utils.pyi b/mypy/typeshed/stdlib/email/utils.pyi index 9dab22c18f6c..dc3eecb5ef7f 100644 --- a/mypy/typeshed/stdlib/email/utils.pyi +++ b/mypy/typeshed/stdlib/email/utils.pyi @@ -30,20 +30,12 @@ _PDTZ: TypeAlias = tuple[int, int, int, int, int, int, int, int, int, int | None def quote(str: str) -> str: ... def unquote(str: str) -> str: ... -if sys.version_info >= (3, 13): - def parseaddr(addr: str | list[str], *, strict: bool = True) -> tuple[str, str]: ... - -else: - def parseaddr(addr: str) -> tuple[str, str]: ... - +# `strict` parameter added in Python 3.8.20, 3.9.20, 3.10.15, 3.11.10, 3.12.5 +def parseaddr(addr: str | list[str], *, strict: bool = True) -> tuple[str, str]: ... def formataddr(pair: tuple[str | None, str], charset: str | Charset = "utf-8") -> str: ... -if sys.version_info >= (3, 13): - def getaddresses(fieldvalues: Iterable[str], *, strict: bool = True) -> list[tuple[str, str]]: ... - -else: - def getaddresses(fieldvalues: Iterable[str]) -> list[tuple[str, str]]: ... - +# `strict` parameter added in Python 3.8.20, 3.9.20, 3.10.15, 3.11.10, 3.12.5 +def getaddresses(fieldvalues: Iterable[str], *, strict: bool = True) -> list[tuple[str, str]]: ... @overload def parsedate(data: None) -> None: ... @overload diff --git a/mypy/typeshed/stdlib/io.pyi b/mypy/typeshed/stdlib/io.pyi index 2d64d261951d..7607608696dd 100644 --- a/mypy/typeshed/stdlib/io.pyi +++ b/mypy/typeshed/stdlib/io.pyi @@ -84,7 +84,6 @@ class RawIOBase(IOBase): def read(self, size: int = -1, /) -> bytes | None: ... class BufferedIOBase(IOBase): - raw: RawIOBase # This is not part of the BufferedIOBase API and may not exist on some implementations. def detach(self) -> RawIOBase: ... def readinto(self, buffer: WriteableBuffer, /) -> int: ... def write(self, buffer: ReadableBuffer, /) -> int: ... @@ -119,11 +118,13 @@ class BytesIO(BufferedIOBase, BinaryIO): # type: ignore[misc] # incompatible d def read1(self, size: int | None = -1, /) -> bytes: ... class BufferedReader(BufferedIOBase, BinaryIO): # type: ignore[misc] # incompatible definitions of methods in the base classes + raw: RawIOBase def __enter__(self) -> Self: ... def __init__(self, raw: RawIOBase, buffer_size: int = ...) -> None: ... def peek(self, size: int = 0, /) -> bytes: ... class BufferedWriter(BufferedIOBase, BinaryIO): # type: ignore[misc] # incompatible definitions of writelines in the base classes + raw: RawIOBase def __enter__(self) -> Self: ... def __init__(self, raw: RawIOBase, buffer_size: int = ...) -> None: ... def write(self, buffer: ReadableBuffer, /) -> int: ... diff --git a/mypy/typeshed/stdlib/subprocess.pyi b/mypy/typeshed/stdlib/subprocess.pyi index 2a5859807b51..703a5012012c 100644 --- a/mypy/typeshed/stdlib/subprocess.pyi +++ b/mypy/typeshed/stdlib/subprocess.pyi @@ -2582,6 +2582,11 @@ else: def list2cmdline(seq: Iterable[StrOrBytesPath]) -> str: ... # undocumented if sys.platform == "win32": + if sys.version_info >= (3, 13): + from _winapi import STARTF_FORCEOFFFEEDBACK, STARTF_FORCEONFEEDBACK + + __all__ += ["STARTF_FORCEOFFFEEDBACK", "STARTF_FORCEONFEEDBACK"] + class STARTUPINFO: def __init__( self, diff --git a/mypy/typeshed/stdlib/tempfile.pyi b/mypy/typeshed/stdlib/tempfile.pyi index 62422b84eb37..0c19d56fc7a6 100644 --- a/mypy/typeshed/stdlib/tempfile.pyi +++ b/mypy/typeshed/stdlib/tempfile.pyi @@ -253,11 +253,11 @@ class _TemporaryFileWrapper(IO[AnyStr]): def truncate(self, size: int | None = ...) -> int: ... def writable(self) -> bool: ... @overload - def write(self: _TemporaryFileWrapper[str], s: str) -> int: ... + def write(self: _TemporaryFileWrapper[str], s: str, /) -> int: ... @overload - def write(self: _TemporaryFileWrapper[bytes], s: ReadableBuffer) -> int: ... + def write(self: _TemporaryFileWrapper[bytes], s: ReadableBuffer, /) -> int: ... @overload - def write(self, s: AnyStr) -> int: ... + def write(self, s: AnyStr, /) -> int: ... @overload def writelines(self: _TemporaryFileWrapper[str], lines: Iterable[str]) -> None: ... @overload From 3bece3357b3c6c68c201bb8be1e628ff2c36052c Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Mon, 26 Sep 2022 12:55:07 -0700 Subject: [PATCH 2/4] Remove use of LiteralString in builtins (#13743) --- mypy/typeshed/stdlib/builtins.pyi | 95 ------------------------------- 1 file changed, 95 deletions(-) diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi index f70e3d6db1b1..f847985b9868 100644 --- a/mypy/typeshed/stdlib/builtins.pyi +++ b/mypy/typeshed/stdlib/builtins.pyi @@ -63,7 +63,6 @@ from typing import ( # noqa: Y022 from typing_extensions import ( # noqa: Y023 Concatenate, Literal, - LiteralString, ParamSpec, Self, TypeAlias, @@ -438,31 +437,16 @@ class str(Sequence[str]): def __new__(cls, object: object = ...) -> Self: ... @overload def __new__(cls, object: ReadableBuffer, encoding: str = ..., errors: str = ...) -> Self: ... - @overload - def capitalize(self: LiteralString) -> LiteralString: ... - @overload def capitalize(self) -> str: ... # type: ignore[misc] - @overload - def casefold(self: LiteralString) -> LiteralString: ... - @overload def casefold(self) -> str: ... # type: ignore[misc] - @overload - def center(self: LiteralString, width: SupportsIndex, fillchar: LiteralString = " ", /) -> LiteralString: ... - @overload def center(self, width: SupportsIndex, fillchar: str = " ", /) -> str: ... # type: ignore[misc] def count(self, sub: str, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /) -> int: ... def encode(self, encoding: str = "utf-8", errors: str = "strict") -> bytes: ... def endswith( self, suffix: str | tuple[str, ...], start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., / ) -> bool: ... - @overload - def expandtabs(self: LiteralString, tabsize: SupportsIndex = 8) -> LiteralString: ... - @overload def expandtabs(self, tabsize: SupportsIndex = 8) -> str: ... # type: ignore[misc] def find(self, sub: str, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /) -> int: ... - @overload - def format(self: LiteralString, *args: LiteralString, **kwargs: LiteralString) -> LiteralString: ... - @overload def format(self, *args: object, **kwargs: object) -> str: ... def format_map(self, mapping: _FormatMapMapping, /) -> str: ... def index(self, sub: str, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /) -> int: ... @@ -478,99 +462,35 @@ class str(Sequence[str]): def isspace(self) -> bool: ... def istitle(self) -> bool: ... def isupper(self) -> bool: ... - @overload - def join(self: LiteralString, iterable: Iterable[LiteralString], /) -> LiteralString: ... - @overload def join(self, iterable: Iterable[str], /) -> str: ... # type: ignore[misc] - @overload - def ljust(self: LiteralString, width: SupportsIndex, fillchar: LiteralString = " ", /) -> LiteralString: ... - @overload def ljust(self, width: SupportsIndex, fillchar: str = " ", /) -> str: ... # type: ignore[misc] - @overload - def lower(self: LiteralString) -> LiteralString: ... - @overload def lower(self) -> str: ... # type: ignore[misc] - @overload - def lstrip(self: LiteralString, chars: LiteralString | None = None, /) -> LiteralString: ... - @overload def lstrip(self, chars: str | None = None, /) -> str: ... # type: ignore[misc] - @overload - def partition(self: LiteralString, sep: LiteralString, /) -> tuple[LiteralString, LiteralString, LiteralString]: ... - @overload def partition(self, sep: str, /) -> tuple[str, str, str]: ... # type: ignore[misc] if sys.version_info >= (3, 13): - @overload - def replace( - self: LiteralString, old: LiteralString, new: LiteralString, /, count: SupportsIndex = -1 - ) -> LiteralString: ... - @overload def replace(self, old: str, new: str, /, count: SupportsIndex = -1) -> str: ... # type: ignore[misc] else: - @overload - def replace( - self: LiteralString, old: LiteralString, new: LiteralString, count: SupportsIndex = -1, / - ) -> LiteralString: ... - @overload def replace(self, old: str, new: str, count: SupportsIndex = -1, /) -> str: ... # type: ignore[misc] if sys.version_info >= (3, 9): - @overload - def removeprefix(self: LiteralString, prefix: LiteralString, /) -> LiteralString: ... - @overload def removeprefix(self, prefix: str, /) -> str: ... # type: ignore[misc] - @overload - def removesuffix(self: LiteralString, suffix: LiteralString, /) -> LiteralString: ... - @overload def removesuffix(self, suffix: str, /) -> str: ... # type: ignore[misc] def rfind(self, sub: str, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /) -> int: ... def rindex(self, sub: str, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /) -> int: ... - @overload - def rjust(self: LiteralString, width: SupportsIndex, fillchar: LiteralString = " ", /) -> LiteralString: ... - @overload def rjust(self, width: SupportsIndex, fillchar: str = " ", /) -> str: ... # type: ignore[misc] - @overload - def rpartition(self: LiteralString, sep: LiteralString, /) -> tuple[LiteralString, LiteralString, LiteralString]: ... - @overload def rpartition(self, sep: str, /) -> tuple[str, str, str]: ... # type: ignore[misc] - @overload - def rsplit(self: LiteralString, sep: LiteralString | None = None, maxsplit: SupportsIndex = -1) -> list[LiteralString]: ... - @overload def rsplit(self, sep: str | None = None, maxsplit: SupportsIndex = -1) -> list[str]: ... # type: ignore[misc] - @overload - def rstrip(self: LiteralString, chars: LiteralString | None = None, /) -> LiteralString: ... - @overload def rstrip(self, chars: str | None = None, /) -> str: ... # type: ignore[misc] - @overload - def split(self: LiteralString, sep: LiteralString | None = None, maxsplit: SupportsIndex = -1) -> list[LiteralString]: ... - @overload def split(self, sep: str | None = None, maxsplit: SupportsIndex = -1) -> list[str]: ... # type: ignore[misc] - @overload - def splitlines(self: LiteralString, keepends: bool = False) -> list[LiteralString]: ... - @overload def splitlines(self, keepends: bool = False) -> list[str]: ... # type: ignore[misc] def startswith( self, prefix: str | tuple[str, ...], start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., / ) -> bool: ... - @overload - def strip(self: LiteralString, chars: LiteralString | None = None, /) -> LiteralString: ... - @overload def strip(self, chars: str | None = None, /) -> str: ... # type: ignore[misc] - @overload - def swapcase(self: LiteralString) -> LiteralString: ... - @overload def swapcase(self) -> str: ... # type: ignore[misc] - @overload - def title(self: LiteralString) -> LiteralString: ... - @overload def title(self) -> str: ... # type: ignore[misc] def translate(self, table: _TranslateTable, /) -> str: ... - @overload - def upper(self: LiteralString) -> LiteralString: ... - @overload def upper(self) -> str: ... # type: ignore[misc] - @overload - def zfill(self: LiteralString, width: SupportsIndex, /) -> LiteralString: ... - @overload def zfill(self, width: SupportsIndex, /) -> str: ... # type: ignore[misc] @staticmethod @overload @@ -581,9 +501,6 @@ class str(Sequence[str]): @staticmethod @overload def maketrans(x: str, y: str, z: str, /) -> dict[int, int | None]: ... - @overload - def __add__(self: LiteralString, value: LiteralString, /) -> LiteralString: ... - @overload def __add__(self, value: str, /) -> str: ... # type: ignore[misc] # Incompatible with Sequence.__contains__ def __contains__(self, key: str, /) -> bool: ... # type: ignore[override] @@ -592,25 +509,13 @@ class str(Sequence[str]): def __getitem__(self, key: SupportsIndex | slice, /) -> str: ... def __gt__(self, value: str, /) -> bool: ... def __hash__(self) -> int: ... - @overload - def __iter__(self: LiteralString) -> Iterator[LiteralString]: ... - @overload def __iter__(self) -> Iterator[str]: ... # type: ignore[misc] def __le__(self, value: str, /) -> bool: ... def __len__(self) -> int: ... def __lt__(self, value: str, /) -> bool: ... - @overload - def __mod__(self: LiteralString, value: LiteralString | tuple[LiteralString, ...], /) -> LiteralString: ... - @overload def __mod__(self, value: Any, /) -> str: ... - @overload - def __mul__(self: LiteralString, value: SupportsIndex, /) -> LiteralString: ... - @overload def __mul__(self, value: SupportsIndex, /) -> str: ... # type: ignore[misc] def __ne__(self, value: object, /) -> bool: ... - @overload - def __rmul__(self: LiteralString, value: SupportsIndex, /) -> LiteralString: ... - @overload def __rmul__(self, value: SupportsIndex, /) -> str: ... # type: ignore[misc] def __getnewargs__(self) -> tuple[str]: ... From 90c9c834f4bb878223cf2cf1e3d44132c05f276f Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Sat, 29 Oct 2022 12:47:21 -0700 Subject: [PATCH 3/4] Revert sum literal integer change (#13961) This is allegedly causing large performance problems, see 13821 typeshed/8231 had zero hits on mypy_primer, so it's not the worst thing to undo. Patching this in typeshed also feels weird, since there's a more general soundness issue. If a typevar has a bound or constraint, we might not want to solve it to a Literal. If we can confirm the performance regression or fix the unsoundness within mypy, I might pursue upstreaming this in typeshed. (Reminder: add this to the sync_typeshed script once merged) --- mypy/typeshed/stdlib/builtins.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi index f847985b9868..0999fb1d6c36 100644 --- a/mypy/typeshed/stdlib/builtins.pyi +++ b/mypy/typeshed/stdlib/builtins.pyi @@ -1654,7 +1654,7 @@ _SupportsSumNoDefaultT = TypeVar("_SupportsSumNoDefaultT", bound=_SupportsSumWit # without creating many false-positive errors (see #7578). # Instead, we special-case the most common examples of this: bool and literal integers. @overload -def sum(iterable: Iterable[bool | _LiteralInteger], /, start: int = 0) -> int: ... +def sum(iterable: Iterable[bool], /, start: int = 0) -> int: ... @overload def sum(iterable: Iterable[_SupportsSumNoDefaultT], /) -> _SupportsSumNoDefaultT | Literal[0]: ... @overload From e475679f6632cc54fda3e3e976c39b4b2135315f Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Mon, 1 May 2023 20:34:55 +0100 Subject: [PATCH 4/4] Revert typeshed ctypes change Since the plugin provides superior type checking: https://github.com/python/mypy/pull/13987#issuecomment-1310863427 A manual cherry-pick of e437cdf. --- mypy/typeshed/stdlib/_ctypes.pyi | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/mypy/typeshed/stdlib/_ctypes.pyi b/mypy/typeshed/stdlib/_ctypes.pyi index 5313195a0ba8..0fe7521d7749 100644 --- a/mypy/typeshed/stdlib/_ctypes.pyi +++ b/mypy/typeshed/stdlib/_ctypes.pyi @@ -168,11 +168,7 @@ class Array(_CData, Generic[_CT]): def _type_(self) -> type[_CT]: ... @_type_.setter def _type_(self, value: type[_CT]) -> None: ... - # Note: only available if _CT == c_char - @property - def raw(self) -> bytes: ... - @raw.setter - def raw(self, value: ReadableBuffer) -> None: ... + raw: bytes # Note: only available if _CT == c_char value: Any # Note: bytes if _CT == c_char, str if _CT == c_wchar, unavailable otherwise # TODO These methods cannot be annotated correctly at the moment. # All of these "Any"s stand for the array's element type, but it's not possible to use _CT