diff --git a/stdlib/typing.pyi b/stdlib/typing.pyi index cda01e53a..4739bd410 100644 --- a/stdlib/typing.pyi +++ b/stdlib/typing.pyi @@ -173,10 +173,10 @@ Protocol: _SpecialForm = ... Callable: _SpecialForm = ... Type: _SpecialForm = ... NoReturn: _SpecialForm = ... +ClassVar: _SpecialForm = ... Optional: _SpecialForm Tuple: _SpecialForm -ClassVar: _SpecialForm if sys.version_info >= (3, 8): Final: _SpecialForm def final(f: _T) -> _T: ... @@ -781,7 +781,13 @@ class NamedTuple(tuple[Any, ...]): def _replace(self: TypeshedSelf, **kwargs: Any) -> TypeshedSelf: ... # Internal mypy fallback type for all typed dicts (does not exist at runtime) +# N.B. Keep this mostly in sync with typing_extensions._TypedDict/mypy_extensions._TypedDict +@type_check_only class _TypedDict(Mapping[str, object], metaclass=ABCMeta): + __total__: ClassVar[bool] + if sys.version_info >= (3, 9): + __required_keys__: ClassVar[frozenset[str]] + __optional_keys__: ClassVar[frozenset[str]] def copy(self: TypeshedSelf) -> TypeshedSelf: ... # Using NoReturn so that only calls using mypy plugin hook that specialize the signature # can go through. @@ -793,8 +799,9 @@ class _TypedDict(Mapping[str, object], metaclass=ABCMeta): def items(self) -> ItemsView[str, object]: ... def keys(self) -> KeysView[str]: ... def values(self) -> ValuesView[object]: ... - def __or__(self: TypeshedSelf, __value: TypeshedSelf) -> TypeshedSelf: ... - def __ior__(self: TypeshedSelf, __value: TypeshedSelf) -> TypeshedSelf: ... + if sys.version_info >= (3, 9): + def __or__(self: TypeshedSelf, __value: TypeshedSelf) -> TypeshedSelf: ... + def __ior__(self: TypeshedSelf, __value: TypeshedSelf) -> TypeshedSelf: ... @_final class ForwardRef: diff --git a/stdlib/typing_extensions.pyi b/stdlib/typing_extensions.pyi index 0d82ec720..edc0d228e 100644 --- a/stdlib/typing_extensions.pyi +++ b/stdlib/typing_extensions.pyi @@ -1,7 +1,8 @@ +import _typeshed import abc import collections import sys -from _typeshed import IdentityFunction, Self as TypeshedSelf # see #6932 for why the Self alias cannot have a leading underscore +from _typeshed import IdentityFunction from collections.abc import Iterable from typing import ( # noqa: Y022,Y027,Y039 TYPE_CHECKING as TYPE_CHECKING, @@ -31,6 +32,7 @@ from typing import ( # noqa: Y022,Y027,Y039 ValuesView, _Alias, overload as overload, + type_check_only, ) __all__ = [ @@ -120,11 +122,13 @@ Literal: _SpecialForm def IntVar(name: str) -> Any: ... # returns a new TypeVar # Internal mypy fallback type for all typed dicts (does not exist at runtime) +# N.B. Keep this mostly in sync with typing._TypedDict/mypy_extensions._TypedDict +@type_check_only class _TypedDict(Mapping[str, object], metaclass=abc.ABCMeta): - __required_keys__: frozenset[str] - __optional_keys__: frozenset[str] - __total__: bool - def copy(self: TypeshedSelf) -> TypeshedSelf: ... + __required_keys__: ClassVar[frozenset[str]] + __optional_keys__: ClassVar[frozenset[str]] + __total__: ClassVar[bool] + def copy(self: _typeshed.Self) -> _typeshed.Self: ... # Using NoReturn so that only calls using mypy plugin hook that specialize the signature # can go through. def setdefault(self, k: NoReturn, default: object) -> object: ... @@ -135,6 +139,9 @@ class _TypedDict(Mapping[str, object], metaclass=abc.ABCMeta): def keys(self) -> KeysView[str]: ... def values(self) -> ValuesView[object]: ... def __delitem__(self, k: NoReturn) -> None: ... + if sys.version_info >= (3, 9): + def __or__(self: _typeshed.Self, __value: _typeshed.Self) -> _typeshed.Self: ... + def __ior__(self: _typeshed.Self, __value: _typeshed.Self) -> _typeshed.Self: ... # TypedDict is a (non-subscriptable) special form. TypedDict: object @@ -256,10 +263,10 @@ else: @overload def __init__(self, typename: str, fields: None = ..., **kwargs: Any) -> None: ... @classmethod - def _make(cls: type[TypeshedSelf], iterable: Iterable[Any]) -> TypeshedSelf: ... + def _make(cls: type[_typeshed.Self], iterable: Iterable[Any]) -> _typeshed.Self: ... if sys.version_info >= (3, 8): def _asdict(self) -> dict[str, Any]: ... else: def _asdict(self) -> collections.OrderedDict[str, Any]: ... - def _replace(self: TypeshedSelf, **kwargs: Any) -> TypeshedSelf: ... + def _replace(self: _typeshed.Self, **kwargs: Any) -> _typeshed.Self: ... diff --git a/stubs/mypy-extensions/mypy_extensions.pyi b/stubs/mypy-extensions/mypy_extensions.pyi index 85c828e8a..edefcc318 100644 --- a/stubs/mypy-extensions/mypy_extensions.pyi +++ b/stubs/mypy-extensions/mypy_extensions.pyi @@ -1,13 +1,19 @@ import abc +import sys from _typeshed import IdentityFunction, Self from collections.abc import ItemsView, KeysView, Mapping, ValuesView -from typing import Any, Generic, TypeVar, overload +from typing import Any, ClassVar, Generic, TypeVar, overload, type_check_only _T = TypeVar("_T") _U = TypeVar("_U") # Internal mypy fallback type for all typed dicts (does not exist at runtime) +# N.B. Keep this mostly in sync with typing(_extensions)._TypedDict +@type_check_only class _TypedDict(Mapping[str, object], metaclass=abc.ABCMeta): + __total__: ClassVar[bool] + # Unlike typing(_extensions).TypedDict, + # subclasses of mypy_extensions.TypedDict do NOT have the __required_keys__ and __optional_keys__ ClassVars def copy(self: Self) -> Self: ... # Using NoReturn so that only calls using mypy plugin hook that specialize the signature # can go through. @@ -19,6 +25,9 @@ class _TypedDict(Mapping[str, object], metaclass=abc.ABCMeta): def keys(self) -> KeysView[str]: ... def values(self) -> ValuesView[object]: ... def __delitem__(self, k: NoReturn) -> None: ... + if sys.version_info >= (3, 9): + def __or__(self: Self, __other: Self) -> Self: ... + def __ior__(self: Self, __other: Self) -> Self: ... def TypedDict(typename: str, fields: dict[str, type[Any]], total: bool = ...) -> type[dict[str, Any]]: ... @overload