Skip to content

Commit

Permalink
refactor internal handling of expanded attributes
Browse files Browse the repository at this point in the history
Signed-off-by: flashdagger <flashdagger@googlemail.com>
  • Loading branch information
flashdagger committed Mar 14, 2024
1 parent 9fc9bb1 commit 1adb6ae
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 31 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ contextmanager-decorators = ["contextlib.contextmanager"]
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E1101 when accessed. Python regular
# expressions are accepted.
# generated-members =
generated-members = ["__annotations__"]

# Tells whether missing members accessed in mixin class should be ignored. A
# class is considered mixin if its name matches the mixin-class-rgx option.
Expand Down
2 changes: 2 additions & 0 deletions tests/test_types_tickets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
reveal_type(ticket.owner) # N: Revealed type is "zammadoo.users.User"
reveal_type(ticket.created_by) # N: Revealed type is "zammadoo.users.User"
reveal_type(ticket.updated_by) # N: Revealed type is "zammadoo.users.User"
reveal_type(
ticket.create_article_sender) # N: Revealed type is "builtins.str"
reveal_type(ticket.articles) # N: Revealed type is "builtins.list[zammadoo.articles.Article]"
article = ticket.articles[0]
Expand Down
9 changes: 4 additions & 5 deletions zammadoo/groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,18 @@ class TypedInfo(TypedDict, total=False):

_info: TypedInfo
shared_drafts: bool #:
user_ids: List[int] #:

@property
def parent_group(self: _T_co) -> Optional[_T_co]:
"""available since Zammad version 6.2"""
self._initialize()
self._assert_attribute()
pid = self._info.get("parent_id")
return self.parent(pid) if pid is not None else None
return None if pid is None else self.parent(pid)

@property
def users(self) -> List["User"]:
self._initialize()
uids = self._info["user_ids"]
return list(map(self.parent.client.users, uids))
return list(map(self.parent.client.users, self.user_ids))


class Groups(IterableT[Group], CreatableT[Group]):
Expand Down
10 changes: 7 additions & 3 deletions zammadoo/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# -*- coding: UTF-8 -*-

from datetime import datetime
from typing import TYPE_CHECKING, Any, Optional
from typing import TYPE_CHECKING, Any, FrozenSet, Optional

from .resources import ResourcesT, _T_co
from .utils import FrozenInfo
Expand All @@ -13,6 +13,8 @@


class Resource(FrozenInfo):
EXPANDED_ATTRIBUTES: FrozenSet[str] = frozenset()

id: int #:
url: str #: the API endpoint URL

Expand All @@ -34,9 +36,11 @@ def __repr__(self):
def __eq__(self, other: Any) -> bool:
return isinstance(other, Resource) and other.url == self.url

def _initialize(self, expanded_attribute: Optional[str] = None) -> None:
def _assert_attribute(self, name: Optional[str] = None) -> None:
info = self._info
expand = expanded_attribute and expanded_attribute not in info
expand = (
name is not None and name in self.EXPANDED_ATTRIBUTES and name not in info
)
refresh = info and expand

if refresh:
Expand Down
8 changes: 3 additions & 5 deletions zammadoo/roles.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,17 @@ class Role(NamedResource):
class TypedInfo(TypedDict, total=False):
permissions: List[str]

EXPANDED_ATTRIBUTES = frozenset(TypedInfo.__annotations__.keys())

_info: TypedInfo
default_at_signup: bool #:
permissions: List[str] #:

@property
def groups(self) -> List["Group"]:
groups = self.parent.client.groups
return list(map(groups, self["group_ids"]))

@property
def permissions(self) -> List[str]:
self._initialize(expanded_attribute="permissions")
return self._info["permissions"]

def delete(self):
"""
Since roles cannot be deletet via REST API, this method is not implemented
Expand Down
18 changes: 6 additions & 12 deletions zammadoo/tickets.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,24 +96,19 @@ class TypedInfo(TypedDict, total=False):
create_article_sender: str
create_article_type: str

EXPANDED_ATTRIBUTES = frozenset(TypedInfo.__annotations__.keys())

_info: TypedInfo

article_count: Optional[int] #:
article_ids: List[int] #:
create_article_sender: str #:
create_article_type: str #:
note: Optional[str] #:
number: str #:
time_unit: Optional[str] #:
title: str #:

@property
def create_article_sender(self) -> str:
self._initialize(expanded_attribute="create_article_sender")
return self._info["create_article_sender"]

@property
def create_article_type(self) -> str:
self._initialize(expanded_attribute="create_article_type")
return self._info["create_article_type"]

@property
def customer(self) -> "User":
uid = self["customer_id"]
Expand Down Expand Up @@ -153,9 +148,8 @@ def articles(self) -> List["Article"]:
"""
all articles related to the ticket as sent by ``/ticket_articles/by_ticket/{ticket id}``
"""
self._initialize(expanded_attribute="article_ids")
articles = self.parent.client.ticket_articles
return [articles(aid) for aid in sorted(self._info["article_ids"])]
return [articles(aid) for aid in sorted(self.article_ids)]

@property
def time_accountings(self) -> List[TimeAccounting]:
Expand Down
4 changes: 3 additions & 1 deletion zammadoo/time_accountings.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class TimeAccounting(MutableResource):
class TypedInfo(TypedDict, total=False):
type: Optional[str]

EXPANDED_ATTRIBUTES = frozenset(TypedInfo.__annotations__.keys())

_info: TypedInfo

id: int #:
Expand Down Expand Up @@ -50,7 +52,7 @@ def ticket_article(self) -> Optional["Article"]:
def type(self) -> Optional[str]:
if self.type_id is None:
return None
self._initialize(expanded_attribute="type")
self._assert_attribute("type")
return self._info["type"]

def update(self: _T_co, **kwargs) -> _T_co:
Expand Down
8 changes: 4 additions & 4 deletions zammadoo/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def __init__(
self._frozen = True

def __getattr__(self, name: str) -> object:
self._initialize()
self._assert_attribute(name)
info = self._info

key = name[:-1] if name in {"from_"} else name
Expand All @@ -92,7 +92,7 @@ def __getattr__(self, name: str) -> object:

return value

def _initialize(self) -> None:
def _assert_attribute(self, name: Optional[str] = None) -> None:
pass

def __setattr__(self, name: str, value: Any) -> None:
Expand All @@ -107,7 +107,7 @@ def __delattr__(self, name: str) -> None:
raise AttributeError(f"object {self.__class__.__name__!r} is read-only")

def __getitem__(self, name: str) -> Any:
self._initialize()
self._assert_attribute(name)
return self._info[name]

def __dir__(self):
Expand All @@ -121,5 +121,5 @@ def view(self) -> "MappingProxyType[str, JsonType]":
:rtype: :class:`MappingProxyType[str, Any]`
"""
self._initialize()
self._assert_attribute()
return MappingProxyType(self._info)

0 comments on commit 1adb6ae

Please sign in to comment.