From e162b2bbb0be597e78cd3353b69296c9e5cd429c Mon Sep 17 00:00:00 2001 From: flashdagger Date: Fri, 5 Apr 2024 21:08:14 +0200 Subject: [PATCH] using __slots__ and info from iterable Signed-off-by: flashdagger --- tests/test_objects.py | 2 +- zammadoo/articles.py | 6 ++---- zammadoo/resource.py | 8 +++++--- zammadoo/resources.py | 13 ++++++++----- zammadoo/utils.py | 20 +++++++++++++++++--- 5 files changed, 33 insertions(+), 16 deletions(-) diff --git a/tests/test_objects.py b/tests/test_objects.py index e9343e8..ef40677 100644 --- a/tests/test_objects.py +++ b/tests/test_objects.py @@ -18,7 +18,7 @@ def test_resource_creation_with_info_needs_proper_id(client): with pytest.raises(AssertionError, match="must contain 'id'"): _ = client.tickets(1, info={"noid": True}) - with pytest.raises(AssertionError, match="be equal with rid"): + with pytest.raises(AssertionError, match="equal to rid"): _ = client.tickets(1, info={"id": 2}) diff --git a/zammadoo/articles.py b/zammadoo/articles.py index 31b3ba5..71a934f 100644 --- a/zammadoo/articles.py +++ b/zammadoo/articles.py @@ -46,7 +46,7 @@ def __repr__(self): @property def size(self) -> int: """attachment size in bytes""" - return int(self._info["size"]) + return int(self["size"]) @staticmethod def info_from_files(*paths: "PathType"): @@ -81,9 +81,7 @@ def info_from_files(*paths: "PathType"): def _response(self) -> requests.Response: response = self._client.response("GET", self.url, stream=True) response.raise_for_status() - - preferences = self._info.get("preferences", {}) - response.encoding = preferences.get("Charset") or response.apparent_encoding + response.encoding = response.apparent_encoding return response diff --git a/zammadoo/resource.py b/zammadoo/resource.py index 8e7ac68..ba3b95d 100644 --- a/zammadoo/resource.py +++ b/zammadoo/resource.py @@ -13,7 +13,7 @@ from typing_extensions import Self from .users import User - from .utils import JsonDict, JsonType + from .utils import JsonDict, JsonMapping, JsonType class TypedResourceDict(JsonDict): @overload @@ -26,6 +26,8 @@ def __getitem__(self, item) -> "JsonType": ... class Resource(FrozenInfo): + __slots__ = ("id", "url", "parent") + EXPANDED_ATTRIBUTES: Tuple[str, ...] = () #: :meta private: id: int #: @@ -36,12 +38,12 @@ def __init__( parent: ResourcesT[Any], rid: int, *, - info: Optional["JsonDict"] = None, + info: Optional["JsonMapping"] = None, ) -> None: self.id = rid self.parent = parent self.url = f"{parent.url}/{rid}" - super().__init__(info) + super().__init__(info or ()) def __repr__(self): return f"<{self.__class__.__qualname__} {self.url!r}>" diff --git a/zammadoo/resources.py b/zammadoo/resources.py index d13b091..a85058e 100644 --- a/zammadoo/resources.py +++ b/zammadoo/resources.py @@ -21,13 +21,15 @@ # noinspection PyUnresolvedReferences from .resource import Resource - from .utils import JsonDict + from .utils import JsonDict, JsonMapping _T_co = TypeVar("_T_co", bound="Resource", covariant=True) class ResourcesT(Generic[_T_co]): + __slots__ = ("_client", "endpoint", "url", "cache") + _RESOURCE_TYPE: Type[_T_co] DEFAULT_CACHE_SIZE = -1 """ @@ -47,12 +49,13 @@ def __init__(self, client: "Client", endpoint: str): max_size=self.DEFAULT_CACHE_SIZE ) #: resource LRU cache - def __call__(self, rid: int, *, info: Optional["JsonDict"] = None) -> _T_co: + def __call__(self, rid: int, *, info: Optional["JsonMapping"] = None) -> _T_co: if info is not None: + mapping = dict(info) assert ( - info.get("id") == rid - ), "parameter info must contain 'id' and be equal with rid" - self.cache[f"{self.url}/{rid}"] = dict(info) + mapping.get("id") == rid + ), "parameter info must contain 'id' equal to rid" + self.cache[f"{self.url}/{rid}"] = mapping return self._RESOURCE_TYPE(self, rid, info=info) diff --git a/zammadoo/utils.py b/zammadoo/utils.py index c04d19e..807811a 100644 --- a/zammadoo/utils.py +++ b/zammadoo/utils.py @@ -5,11 +5,23 @@ from datetime import datetime from itertools import chain from types import MappingProxyType -from typing import Any, Dict, Generic, Iterable, List, Mapping, Optional, TypeVar, Union +from typing import ( + Any, + Dict, + Generic, + Iterable, + List, + Mapping, + Optional, + Tuple, + TypeVar, + Union, +) JsonType = Union[None, bool, int, float, str, List["JsonType"], "JsonDict"] JsonDict = Dict[str, JsonType] StringKeyMapping = Mapping[str, Any] +JsonMapping = Union[JsonDict, Iterable[Tuple[str, JsonType]]] class YieldCounter: @@ -30,11 +42,13 @@ def __call__(self, itr: Iterable[_T]) -> Iterable[_T]: class FrozenInfo: + __slots__ = ("_info", "_frozen") + def __init__( self, - info=None, + info: JsonMapping, ) -> None: - self._info = dict(info) if info is not None else {} + self._info = dict(info) self._frozen = True def __getattr__(self, name: str) -> "JsonType":