From 8c5831c9997e7eae954c4abb13b9079522e7e0f8 Mon Sep 17 00:00:00 2001 From: costynus Date: Mon, 8 Jun 2026 00:12:09 +0300 Subject: [PATCH] improve boltons dictuils stubs --- stubs/boltons/boltons/dictutils.pyi | 53 ++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/stubs/boltons/boltons/dictutils.pyi b/stubs/boltons/boltons/dictutils.pyi index aa438b46076a..e48debf89423 100644 --- a/stubs/boltons/boltons/dictutils.pyi +++ b/stubs/boltons/boltons/dictutils.pyi @@ -1,6 +1,6 @@ from _typeshed import SupportsKeysAndGetItem -from collections.abc import Generator, ItemsView, Iterable, KeysView, ValuesView -from typing import NoReturn, TypeAlias, TypeVar, overload +from collections.abc import Collection, Generator, ItemsView, Iterable, Iterator, KeysView, ValuesView +from typing import Generic, NoReturn, TypeAlias, TypeVar, overload from typing_extensions import Self _KT = TypeVar("_KT") @@ -12,17 +12,26 @@ class OrderedMultiDict(dict[_KT, _VT]): def addlist(self, k: _KT, v: Iterable[_VT]) -> None: ... def clear(self) -> None: ... def copy(self) -> Self: ... - def counts(self) -> Self: ... + def counts(self) -> OrderedMultiDict[_KT, int]: ... + + @overload # type: ignore[override] + @classmethod + def fromkeys(cls, keys: Iterable[_KT], default: None = None) -> OrderedMultiDict[_KT, None]: ... + @overload @classmethod - def fromkeys(cls, keys: _KT, default: _VT | None = None) -> Self: ... # type: ignore[override] + def fromkeys(cls, keys: Iterable[_KT], default: _T) -> OrderedMultiDict[_KT, _T]: ... @overload # type: ignore[override] def get(self, k: _KT, default: None = None) -> _VT | None: ... @overload def get(self, k: _KT, default: _VT) -> _VT: ... - def getlist(self, k: _KT, default: list[_VT] = ...) -> list[_VT]: ... - def inverted(self) -> Self: ... + @overload + def getlist(self, k: _KT) -> list[_VT]: ... + @overload + def getlist(self, k: _KT, default: _T) -> list[_VT] | _T: ... + + def inverted(self) -> OrderedMultiDict[_VT, _KT]: ... def items(self, multi: bool = False) -> list[tuple[_KT, _VT]]: ... # type: ignore[override] def iteritems(self, multi: bool = False) -> Generator[tuple[_KT, _VT]]: ... def iterkeys(self, multi: bool = False) -> Generator[_KT]: ... @@ -61,31 +70,41 @@ class OneToOne(dict[_KT, _VT]): def copy(self) -> Self: ... def pop(self, key: _KT, default: _VT | _T = ...) -> _VT | _T: ... def popitem(self) -> tuple[_KT, _VT]: ... - def setdefault(self, key: _KT, default: _VT | None = None) -> _VT: ... + + @overload + def setdefault(self, key: _KT, default: None = None) -> _VT | None: ... + @overload + def setdefault(self, key: _KT, default: _VT) -> _VT: ... + @classmethod def unique(cls, *a, **kw) -> Self: ... def update(self, dict_or_iterable, **kw) -> None: ... # type: ignore[override] -class ManyToMany(dict[_KT, frozenset[_VT]]): +class ManyToMany(Collection[_KT], Generic[_KT, _VT]): data: dict[_KT, set[_VT]] - inv: dict[_VT, set[_KT]] - # def __contains__(self, key: _KT): ... + inv: ManyToMany[_VT, _KT] + def __contains__(self, key: object) -> bool: ... def __delitem__(self, key: _KT) -> None: ... def __eq__(self, other): ... - def __getitem__(self, key: _KT): ... + def __getitem__(self, key: _KT) -> frozenset[_VT]: ... def __init__( - self, items: ManyToMany[_KT, _VT] | SupportsKeysAndGetItem[_KT, _VT] | tuple[_KT, _VT] | None = None + self, items: ManyToMany[_KT, _VT] | SupportsKeysAndGetItem[_KT, _VT] | Iterable[tuple[_KT, _VT]] | None = None ) -> None: ... - def __iter__(self): ... - def __len__(self): ... + def __iter__(self) -> Iterator[_KT]: ... + def __len__(self) -> int: ... def __setitem__(self, key: _KT, vals: Iterable[_VT]) -> None: ... def add(self, key: _KT, val: _VT) -> None: ... - def get(self, key: _KT, default: frozenset[_VT] = ...) -> frozenset[_VT]: ... # type: ignore[override] + + @overload + def get(self, key: _KT) -> frozenset[_VT]: ... + @overload + def get(self, key: _KT, default: _T) -> frozenset[_VT] | _T: ... + def iteritems(self) -> Generator[tuple[_KT, _VT]]: ... - def keys(self): ... + def keys(self) -> KeysView[_KT]: ... def remove(self, key: _KT, val: _VT) -> None: ... def replace(self, key: _KT, newkey: _KT) -> None: ... - def update(self, iterable: ManyToMany[_KT, _VT] | SupportsKeysAndGetItem[_KT, _VT] | tuple[_KT, _VT]) -> None: ... # type: ignore[override] + def update(self, iterable: ManyToMany[_KT, _VT] | SupportsKeysAndGetItem[_KT, _VT] | Iterable[tuple[_KT, _VT]]) -> None: ... def subdict(d: dict[_KT, _VT], keep: Iterable[_KT] | None = None, drop: Iterable[_KT] | None = None) -> dict[_KT, _VT]: ...