Skip to content

Commit fe6d745

Browse files
committed
feat: make ResourceReference hashable
Closes #1666 This allows `ResourceReference` to be used as a key in dicts, as well as added to sets by making it hashable. Also adds a `to_reference` method, while leaving the the `as_reference` static method in place untouched.
1 parent 59eaebb commit fe6d745

File tree

5 files changed

+34
-10
lines changed

5 files changed

+34
-10
lines changed

tableauserverclient/models/group_item.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Callable, Optional, TYPE_CHECKING
1+
from typing import Callable, Optional, Self, TYPE_CHECKING
22

33
from defusedxml.ElementTree import fromstring
44

@@ -157,3 +157,8 @@ def from_response(cls, resp, ns) -> list["GroupItem"]:
157157
@staticmethod
158158
def as_reference(id_: str) -> ResourceReference:
159159
return ResourceReference(id_, GroupItem.tag_name)
160+
161+
def to_reference(self: Self) -> ResourceReference:
162+
if self.id is None:
163+
raise ValueError("UserItem must have id to be converted to reference")
164+
return ResourceReference(self.id, self.tag_name)

tableauserverclient/models/groupset_item.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Optional
1+
from typing import Optional, Self
22
import xml.etree.ElementTree as ET
33

44
from defusedxml.ElementTree import fromstring
@@ -51,3 +51,8 @@ def get_group(group_xml: ET.Element) -> GroupItem:
5151
@staticmethod
5252
def as_reference(id_: str) -> ResourceReference:
5353
return ResourceReference(id_, GroupSetItem.tag_name)
54+
55+
def to_reference(self: Self) -> ResourceReference:
56+
if self.id is None:
57+
raise ValueError("UserItem must have id to be converted to reference")
58+
return ResourceReference(self.id, self.tag_name)
Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
from typing import Self
2+
3+
14
class ResourceReference:
2-
def __init__(self, id_, tag_name):
5+
def __init__(self, id_: str | None, tag_name: str) -> None:
36
self.id = id_
47
self.tag_name = tag_name
58

6-
def __str__(self):
9+
def __str__(self) -> str:
710
return f"<ResourceReference id={self._id} tag={self._tag_name}>"
811

912
__repr__ = __str__
@@ -13,18 +16,21 @@ def __eq__(self, other: object) -> bool:
1316
return False
1417
return (self.id == other.id) and (self.tag_name == other.tag_name)
1518

19+
def __hash__(self: Self) -> int:
20+
return hash((self.id, self.tag_name))
21+
1622
@property
17-
def id(self):
23+
def id(self) -> str | None:
1824
return self._id
1925

2026
@id.setter
21-
def id(self, value):
27+
def id(self, value: str | None) -> None:
2228
self._id = value
2329

2430
@property
25-
def tag_name(self):
31+
def tag_name(self) -> str:
2632
return self._tag_name
2733

2834
@tag_name.setter
29-
def tag_name(self, value):
35+
def tag_name(self, value: str) -> None:
3036
self._tag_name = value

tableauserverclient/models/user_item.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import xml.etree.ElementTree as ET
33
from datetime import datetime
44
from enum import IntEnum
5-
from typing import Optional, TYPE_CHECKING
5+
from typing import Optional, TYPE_CHECKING, Self
66

77
from defusedxml.ElementTree import fromstring
88

@@ -376,6 +376,11 @@ def _parse_xml(cls, element_name, resp, ns):
376376
def as_reference(id_) -> ResourceReference:
377377
return ResourceReference(id_, UserItem.tag_name)
378378

379+
def to_reference(self: Self) -> ResourceReference:
380+
if self.id is None:
381+
raise ValueError("UserItem must have id to be converted to reference")
382+
return ResourceReference(self.id, self.tag_name)
383+
379384
@staticmethod
380385
def _parse_element(user_xml, ns):
381386
id = user_xml.get("id", None)

tableauserverclient/server/request_factory.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,10 @@ def add_req(self, rules: Iterable[PermissionsRule]) -> bytes:
512512
for rule in rules:
513513
grantee_capabilities_element = ET.SubElement(permissions_element, "granteeCapabilities")
514514
grantee_element = ET.SubElement(grantee_capabilities_element, rule.grantee.tag_name)
515-
grantee_element.attrib["id"] = rule.grantee.id
515+
if rule.grantee.id is not None:
516+
grantee_element.attrib["id"] = rule.grantee.id
517+
else:
518+
raise ValueError("Grantee must have an ID")
516519

517520
capabilities_element = ET.SubElement(grantee_capabilities_element, "capabilities")
518521
self._add_all_capabilities(capabilities_element, rule.capabilities)

0 commit comments

Comments
 (0)