From 556dcbc821188a830f72ff204d49078e5209895d Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Wed, 23 Oct 2024 20:35:32 -0700 Subject: [PATCH 1/4] inheritance for multiprocessing.managers.DictProxy --- stdlib/multiprocessing/managers.pyi | 103 +++++++++++++++++++++------- 1 file changed, 78 insertions(+), 25 deletions(-) diff --git a/stdlib/multiprocessing/managers.pyi b/stdlib/multiprocessing/managers.pyi index c5a1134377a1..4b93aa18ea3c 100644 --- a/stdlib/multiprocessing/managers.pyi +++ b/stdlib/multiprocessing/managers.pyi @@ -2,7 +2,7 @@ import queue import sys import threading from _typeshed import Incomplete, SupportsKeysAndGetItem, SupportsRichComparison, SupportsRichComparisonT -from collections.abc import Callable, Iterable, Iterator, Mapping, MutableMapping, MutableSequence, Sequence +from collections.abc import Callable, Iterable, Iterator, Mapping, MutableSequence, Sequence from types import TracebackType from typing import Any, AnyStr, ClassVar, Generic, SupportsIndex, TypeVar, overload from typing_extensions import Self, TypeAlias @@ -60,32 +60,85 @@ class ValueProxy(BaseProxy, Generic[_T]): if sys.version_info >= (3, 9): def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... -class DictProxy(BaseProxy, MutableMapping[_KT, _VT]): - __builtins__: ClassVar[dict[str, Any]] - def __len__(self) -> int: ... - def __getitem__(self, key: _KT, /) -> _VT: ... - def __setitem__(self, key: _KT, value: _VT, /) -> None: ... - def __delitem__(self, key: _KT, /) -> None: ... - def __iter__(self) -> Iterator[_KT]: ... - def copy(self) -> dict[_KT, _VT]: ... - @overload # type: ignore[override] - def get(self, key: _KT, /) -> _VT | None: ... - @overload - def get(self, key: _KT, default: _VT, /) -> _VT: ... - @overload - def get(self, key: _KT, default: _T, /) -> _VT | _T: ... - @overload - def pop(self, key: _KT, /) -> _VT: ... - @overload - def pop(self, key: _KT, default: _VT, /) -> _VT: ... - @overload - def pop(self, key: _KT, default: _T, /) -> _VT | _T: ... - def keys(self) -> list[_KT]: ... # type: ignore[override] - def items(self) -> list[tuple[_KT, _VT]]: ... # type: ignore[override] - def values(self) -> list[_VT]: ... # type: ignore[override] - if sys.version_info >= (3, 13): +if sys.version_info >= (3, 13): + class _BaseDictProxy(BaseProxy, Generic[_KT, _VT]): + __builtins__: ClassVar[dict[str, Any]] + def __len__(self) -> int: ... + def __contains__(self, x: object, /) -> bool: ... + def __getitem__(self, key: _KT, /) -> _VT: ... + def __setitem__(self, key: _KT, value: _VT, /) -> None: ... + def __delitem__(self, key: _KT, /) -> None: ... + def __iter__(self) -> Iterator[_KT]: ... + def clear(self) -> None: ... + def copy(self) -> dict[_KT, _VT]: ... + @overload # type: ignore[override] + def get(self, key: _KT, /) -> _VT | None: ... + @overload + def get(self, key: _KT, default: _VT, /) -> _VT: ... + @overload + def get(self, key: _KT, default: _T, /) -> _VT | _T: ... + @overload + def pop(self, key: _KT, /) -> _VT: ... + @overload + def pop(self, key: _KT, default: _VT, /) -> _VT: ... + @overload + def pop(self, key: _KT, default: _T, /) -> _VT | _T: ... + def popitem(self) -> tuple[_KT, _VT]: ... + def keys(self) -> list[_KT]: ... # type: ignore[override] + def items(self) -> list[tuple[_KT, _VT]]: ... # type: ignore[override] + def values(self) -> list[_VT]: ... # type: ignore[override] + @overload + def setdefault(self: _BaseDictProxy[_KT, _T | None], key: _KT, default: None = None, /) -> _T | None: ... + @overload + def setdefault(self, key: _KT, default: _VT, /) -> _VT: ... + @overload + def update(self, m: SupportsKeysAndGetItem[_KT, _VT], /, **kwargs: _VT) -> None: ... + @overload + def update(self, m: Iterable[tuple[_KT, _VT]], /, **kwargs: _VT) -> None: ... + @overload + def update(self, **kwargs: _VT) -> None: ... + + class DictProxy(_BaseDictProxy): def __class_getitem__(cls, args: Any, /) -> Any: ... +else: + class DictProxy(BaseProxy, Generic[_KT, _VT]): + __builtins__: ClassVar[dict[str, Any]] + def __len__(self) -> int: ... + def __contains__(self, x: object, /) -> bool: ... + def __getitem__(self, key: _KT, /) -> _VT: ... + def __setitem__(self, key: _KT, value: _VT, /) -> None: ... + def __delitem__(self, key: _KT, /) -> None: ... + def __iter__(self) -> Iterator[_KT]: ... + def clear(self) -> None: ... + def copy(self) -> dict[_KT, _VT]: ... + @overload # type: ignore[override] + def get(self, key: _KT, /) -> _VT | None: ... + @overload + def get(self, key: _KT, default: _VT, /) -> _VT: ... + @overload + def get(self, key: _KT, default: _T, /) -> _VT | _T: ... + @overload + def pop(self, key: _KT, /) -> _VT: ... + @overload + def pop(self, key: _KT, default: _VT, /) -> _VT: ... + @overload + def pop(self, key: _KT, default: _T, /) -> _VT | _T: ... + def popitem(self) -> tuple[_KT, _VT]: ... + def keys(self) -> list[_KT]: ... # type: ignore[override] + def items(self) -> list[tuple[_KT, _VT]]: ... # type: ignore[override] + def values(self) -> list[_VT]: ... # type: ignore[override] + @overload + def setdefault(self: DictProxy[_KT, _T | None], key: _KT, default: None = None, /) -> _T | None: ... + @overload + def setdefault(self, key: _KT, default: _VT, /) -> _VT: ... + @overload + def update(self, m: SupportsKeysAndGetItem[_KT, _VT], /, **kwargs: _VT) -> None: ... + @overload + def update(self, m: Iterable[tuple[_KT, _VT]], /, **kwargs: _VT) -> None: ... + @overload + def update(self, **kwargs: _VT) -> None: ... + class BaseListProxy(BaseProxy, MutableSequence[_T]): __builtins__: ClassVar[dict[str, Any]] def __len__(self) -> int: ... From cac3597dc2b548eeb9b33c449426ea72031e502a Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Wed, 23 Oct 2024 22:14:11 -0700 Subject: [PATCH 2/4] missed the type variables --- stdlib/multiprocessing/managers.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/multiprocessing/managers.pyi b/stdlib/multiprocessing/managers.pyi index 4b93aa18ea3c..cc07deaaa2cf 100644 --- a/stdlib/multiprocessing/managers.pyi +++ b/stdlib/multiprocessing/managers.pyi @@ -98,7 +98,7 @@ if sys.version_info >= (3, 13): @overload def update(self, **kwargs: _VT) -> None: ... - class DictProxy(_BaseDictProxy): + class DictProxy(_BaseDictProxy[_KT, _VT]): def __class_getitem__(cls, args: Any, /) -> Any: ... else: From 4f80827f66f14d0acf7ba8d871ec212cf2aa4260 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Wed, 23 Oct 2024 23:53:23 -0700 Subject: [PATCH 3/4] stubtest fixes --- stdlib/@tests/stubtest_allowlists/common.txt | 6 ------ stdlib/@tests/stubtest_allowlists/py310.txt | 9 +++++++++ stdlib/@tests/stubtest_allowlists/py311.txt | 9 +++++++++ stdlib/@tests/stubtest_allowlists/py312.txt | 9 +++++++++ stdlib/@tests/stubtest_allowlists/py313.txt | 12 ++++++++++++ stdlib/@tests/stubtest_allowlists/py38.txt | 9 +++++++++ stdlib/@tests/stubtest_allowlists/py39.txt | 10 ++++++++++ 7 files changed, 58 insertions(+), 6 deletions(-) diff --git a/stdlib/@tests/stubtest_allowlists/common.txt b/stdlib/@tests/stubtest_allowlists/common.txt index 13024e94aaf3..29ac3fcb79c5 100644 --- a/stdlib/@tests/stubtest_allowlists/common.txt +++ b/stdlib/@tests/stubtest_allowlists/common.txt @@ -435,12 +435,6 @@ multiprocessing.managers.BaseListProxy.__len__ multiprocessing.managers.BaseListProxy.__reversed__ multiprocessing.managers.BaseListProxy.reverse multiprocessing.managers.BaseListProxy.sort -multiprocessing.managers.DictProxy.__iter__ -multiprocessing.managers.DictProxy.__len__ -multiprocessing.managers.DictProxy.copy -multiprocessing.managers.DictProxy.items -multiprocessing.managers.DictProxy.keys -multiprocessing.managers.DictProxy.values multiprocessing.(dummy|managers).Namespace.__[gs]etattr__ # Any field can be set on Namespace # alias for a class defined elsewhere, diff --git a/stdlib/@tests/stubtest_allowlists/py310.txt b/stdlib/@tests/stubtest_allowlists/py310.txt index 8d0631cdd291..e97cca7507b1 100644 --- a/stdlib/@tests/stubtest_allowlists/py310.txt +++ b/stdlib/@tests/stubtest_allowlists/py310.txt @@ -230,6 +230,15 @@ importlib.abc.Traversable.open importlib.metadata.DeprecatedList.reverse importlib.metadata.DeprecatedList.sort +# These multiprocessing proxy methods have *args, **kwargs signatures at runtime, +# But have more precise (accurate) signatures in the stub +multiprocessing.managers.DictProxy.__iter__ +multiprocessing.managers.DictProxy.__len__ +multiprocessing.managers.DictProxy.copy +multiprocessing.managers.DictProxy.items +multiprocessing.managers.DictProxy.keys +multiprocessing.managers.DictProxy.values + # Super-special typing primitives typing\.NamedTuple typing\.Annotated diff --git a/stdlib/@tests/stubtest_allowlists/py311.txt b/stdlib/@tests/stubtest_allowlists/py311.txt index 308855f8f00b..80c7ae31e7be 100644 --- a/stdlib/@tests/stubtest_allowlists/py311.txt +++ b/stdlib/@tests/stubtest_allowlists/py311.txt @@ -184,6 +184,15 @@ importlib.resources.abc.Traversable.open importlib.metadata.DeprecatedList.reverse importlib.metadata.DeprecatedList.sort +# These multiprocessing proxy methods have *args, **kwargs signatures at runtime, +# But have more precise (accurate) signatures in the stub +multiprocessing.managers.DictProxy.__iter__ +multiprocessing.managers.DictProxy.__len__ +multiprocessing.managers.DictProxy.copy +multiprocessing.managers.DictProxy.items +multiprocessing.managers.DictProxy.keys +multiprocessing.managers.DictProxy.values + # Super-special typing primitives typing\._SpecialForm.* typing\.NamedTuple diff --git a/stdlib/@tests/stubtest_allowlists/py312.txt b/stdlib/@tests/stubtest_allowlists/py312.txt index 14500a678fdf..84e75c493050 100644 --- a/stdlib/@tests/stubtest_allowlists/py312.txt +++ b/stdlib/@tests/stubtest_allowlists/py312.txt @@ -174,6 +174,15 @@ importlib.resources.abc.Traversable.open # Deprecation wrapper classes; their methods are just pass-through, so we can ignore them. importlib.metadata.DeprecatedNonAbstract.__new__ +# These multiprocessing proxy methods have *args, **kwargs signatures at runtime, +# But have more precise (accurate) signatures in the stub +multiprocessing.managers.DictProxy.__iter__ +multiprocessing.managers.DictProxy.__len__ +multiprocessing.managers.DictProxy.copy +multiprocessing.managers.DictProxy.items +multiprocessing.managers.DictProxy.keys +multiprocessing.managers.DictProxy.values + # Super-special typing primitives typing\._SpecialForm.* typing\.NamedTuple diff --git a/stdlib/@tests/stubtest_allowlists/py313.txt b/stdlib/@tests/stubtest_allowlists/py313.txt index f1dd2471203e..f96864ece771 100644 --- a/stdlib/@tests/stubtest_allowlists/py313.txt +++ b/stdlib/@tests/stubtest_allowlists/py313.txt @@ -151,6 +151,18 @@ importlib.resources.abc.Traversable.open # Deprecation wrapper classes; their methods are just pass-through, so we can ignore them. importlib.metadata.DeprecatedNonAbstract.__new__ +# These multiprocessing proxy methods have *args, **kwargs signatures at runtime, +# But have more precise (accurate) signatures in the stub +multiprocessing.managers._BaseDictProxy.clear +multiprocessing.managers._BaseDictProxy.copy +multiprocessing.managers._BaseDictProxy.items +multiprocessing.managers._BaseDictProxy.keys +multiprocessing.managers._BaseDictProxy.popitem +multiprocessing.managers._BaseDictProxy.values +multiprocessing.managers._BaseDictProxy.__iter__ +multiprocessing.managers._BaseDictProxy.__len__ + + # Super-special typing primitives typing\._SpecialForm.* typing\.NamedTuple diff --git a/stdlib/@tests/stubtest_allowlists/py38.txt b/stdlib/@tests/stubtest_allowlists/py38.txt index 8a8cebab1364..91cea4d0e6e1 100644 --- a/stdlib/@tests/stubtest_allowlists/py38.txt +++ b/stdlib/@tests/stubtest_allowlists/py38.txt @@ -262,3 +262,12 @@ email._header_value_parser.SPECIALSNL email.errors.HeaderWriteError email.utils.getaddresses email.utils.parseaddr + +# These multiprocessing proxy methods have *args, **kwargs signatures at runtime, +# But have more precise (accurate) signatures in the stub +multiprocessing.managers.DictProxy.__iter__ +multiprocessing.managers.DictProxy.__len__ +multiprocessing.managers.DictProxy.copy +multiprocessing.managers.DictProxy.items +multiprocessing.managers.DictProxy.keys +multiprocessing.managers.DictProxy.values diff --git a/stdlib/@tests/stubtest_allowlists/py39.txt b/stdlib/@tests/stubtest_allowlists/py39.txt index 9c646178b383..8eb1883be07d 100644 --- a/stdlib/@tests/stubtest_allowlists/py39.txt +++ b/stdlib/@tests/stubtest_allowlists/py39.txt @@ -204,6 +204,16 @@ multiprocessing.managers.DictProxy.popitem # Problematic protocol signature at runtime, see source code comments. importlib.abc.Traversable.open +# These multiprocessing proxy methods have *args, **kwargs signatures at runtime, +# But have more precise (accurate) signatures in the stub +multiprocessing.managers.DictProxy.__iter__ +multiprocessing.managers.DictProxy.__len__ +multiprocessing.managers.DictProxy.copy +multiprocessing.managers.DictProxy.items +multiprocessing.managers.DictProxy.keys +multiprocessing.managers.DictProxy.values + + # Super-special typing primitives typing\.NamedTuple typing\.Annotated From 0769e14e2b9dc594753624a1b6a1457aeb255978 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Thu, 24 Oct 2024 00:05:03 -0700 Subject: [PATCH 4/4] fix sort order in the allowlist --- stdlib/@tests/stubtest_allowlists/py313.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/@tests/stubtest_allowlists/py313.txt b/stdlib/@tests/stubtest_allowlists/py313.txt index f96864ece771..c7e0bd5c94fe 100644 --- a/stdlib/@tests/stubtest_allowlists/py313.txt +++ b/stdlib/@tests/stubtest_allowlists/py313.txt @@ -153,14 +153,14 @@ importlib.metadata.DeprecatedNonAbstract.__new__ # These multiprocessing proxy methods have *args, **kwargs signatures at runtime, # But have more precise (accurate) signatures in the stub +multiprocessing.managers._BaseDictProxy.__iter__ +multiprocessing.managers._BaseDictProxy.__len__ multiprocessing.managers._BaseDictProxy.clear multiprocessing.managers._BaseDictProxy.copy multiprocessing.managers._BaseDictProxy.items multiprocessing.managers._BaseDictProxy.keys multiprocessing.managers._BaseDictProxy.popitem multiprocessing.managers._BaseDictProxy.values -multiprocessing.managers._BaseDictProxy.__iter__ -multiprocessing.managers._BaseDictProxy.__len__ # Super-special typing primitives