From 6a5466578f49a42b8d972a57ef5e1bfc6aabecdb Mon Sep 17 00:00:00 2001 From: David Arnold Date: Mon, 21 Oct 2024 03:16:35 +0200 Subject: [PATCH] chore(typing): type _dict (#28205) --- frappe/types/frappedict.py | 62 ++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/frappe/types/frappedict.py b/frappe/types/frappedict.py index 5a1127ee5b..fa245db0c7 100644 --- a/frappe/types/frappedict.py +++ b/frappe/types/frappedict.py @@ -1,20 +1,62 @@ -class _dict(dict): +from collections.abc import Iterable, Mapping +from typing import ( + TYPE_CHECKING, + TypeVar, + overload, +) + +from typing_extensions import Self, override + +_KT = TypeVar("_KT") +_VT = TypeVar("_VT") + + +class _dict(dict[_KT, _VT]): """dict like object that exposes keys as attributes""" __slots__ = () - __getattr__ = dict.get - __setattr__ = dict.__setitem__ - __delattr__ = dict.__delitem__ - __setstate__ = dict.update - def __getstate__(self): + def __getattr__(self, k: str) -> _VT | None: + return super().get(k) # type: ignore[arg-type] + + @override + def __setattr__(self, k: str, v: _VT) -> None: + return super().__setitem__(k, v) # type: ignore[index] + + @override + def __delattr__(self, k: str): + return super().__delitem__(k) # type: ignore[arg-type] + + def __setstate__(self, m: Mapping[_KT, _VT]) -> None: + return super().update(m) + + @override + def __getstate__(self) -> Self: return self - def update(self, *args, **kwargs): + @overload # type: ignore[override] + def update(self, m: Mapping[_KT, _VT], /, **kwargs: _VT) -> Self: + ... + + @overload + def update(self, m: Iterable[tuple[_KT, _VT]], /, **kwargs: _VT) -> Self: + ... + + @overload + def update(self, /, **kwargs: _VT) -> Self: + ... + + @override + def update( + self, m: Mapping[_KT, _VT] | Iterable[tuple[_KT, _VT]] | None = None, /, **kwargs: _VT + ) -> Self: """update and return self -- the missing dict feature in python""" - - super().update(*args, **kwargs) + if m: + super().update(m, **kwargs) + else: + super().update(**kwargs) return self - def copy(self): + @override + def copy(self) -> "_dict[_KT, _VT]": return _dict(self)