1
1
import abc
2
2
import copy
3
- from typing import Iterable , Optional , Protocol , Set , Union , TYPE_CHECKING , runtime_checkable
3
+ from typing import Generic , Iterable , Optional , Protocol , Set , TypeVar , Union , TYPE_CHECKING , runtime_checkable
4
4
import urllib .parse
5
5
6
6
from tableauserverclient .server .endpoint .endpoint import Endpoint , api
@@ -61,28 +61,22 @@ def update_tags(self, baseurl, resource_item):
61
61
resource_item ._initial_tags = copy .copy (resource_item .tags )
62
62
logger .info ("Updated tags to {0}" .format (resource_item .tags ))
63
63
64
-
65
- class HasID (Protocol ):
66
- @property
67
- def id (self ) -> Optional [str ]:
68
- pass
69
-
64
+ class Response (Protocol ):
65
+ content : bytes
70
66
71
67
@runtime_checkable
72
68
class Taggable (Protocol ):
73
- _initial_tags : Set [str ]
74
69
tags : Set [str ]
70
+ _initial_tags : Set [str ]
75
71
76
72
@property
77
73
def id (self ) -> Optional [str ]:
78
74
pass
79
75
80
-
81
- class Response (Protocol ):
82
- content : bytes
76
+ T = TypeVar ("T" )
83
77
84
78
85
- class TaggingMixin (abc .ABC ):
79
+ class TaggingMixin (abc .ABC , Generic [ T ] ):
86
80
parent_srv : "Server"
87
81
88
82
@property
@@ -98,7 +92,7 @@ def put_request(self, url, request) -> Response:
98
92
def delete_request (self , url ) -> None :
99
93
pass
100
94
101
- def add_tags (self , item : Union [HasID , Taggable , str ], tags : Union [Iterable [str ], str ]) -> Set [str ]:
95
+ def add_tags (self , item : Union [T , str ], tags : Union [Iterable [str ], str ]) -> Set [str ]:
102
96
item_id = getattr (item , "id" , item )
103
97
104
98
if not isinstance (item_id , str ):
@@ -114,7 +108,7 @@ def add_tags(self, item: Union[HasID, Taggable, str], tags: Union[Iterable[str],
114
108
server_response = self .put_request (url , add_req )
115
109
return TagItem .from_response (server_response .content , self .parent_srv .namespace )
116
110
117
- def delete_tags (self , item : Union [HasID , Taggable , str ], tags : Union [Iterable [str ], str ]) -> None :
111
+ def delete_tags (self , item : Union [T , str ], tags : Union [Iterable [str ], str ]) -> None :
118
112
item_id = getattr (item , "id" , item )
119
113
120
114
if not isinstance (item_id , str ):
@@ -130,17 +124,23 @@ def delete_tags(self, item: Union[HasID, Taggable, str], tags: Union[Iterable[st
130
124
url = f"{ self .baseurl } /{ item_id } /tags/{ encoded_tag_name } "
131
125
self .delete_request (url )
132
126
133
- def update_tags (self , item : Taggable ) -> None :
134
- if item .tags == item ._initial_tags :
127
+ def update_tags (self , item : T ) -> None :
128
+ if (initial_tags := getattr (item , "_initial_tags" , None )) is None :
129
+ raise ValueError (f"{ item } does not have initial tags." )
130
+ if (tags := getattr (item , "tags" , None )) is None :
131
+ raise ValueError (f"{ item } does not have tags." )
132
+ if tags == initial_tags :
135
133
return
136
134
137
- add_set = item . tags - item . _initial_tags
138
- remove_set = item . _initial_tags - item . tags
135
+ add_set = tags - initial_tags
136
+ remove_set = initial_tags - tags
139
137
self .delete_tags (item , remove_set )
140
138
if add_set :
141
- item .tags = self .add_tags (item , add_set )
142
- item ._initial_tags = copy .copy (item .tags )
143
- logger .info (f"Updated tags to { item .tags } " )
139
+ tags = self .add_tags (item , add_set )
140
+ setattr (item , "tags" , tags )
141
+
142
+ setattr (item , "_initial_tags" , copy .copy (tags ))
143
+ logger .info (f"Updated tags to { tags } " )
144
144
145
145
146
146
content = Iterable [Union ["ColumnItem" , "DatabaseItem" , "DatasourceItem" , "FlowItem" , "TableItem" , "WorkbookItem" ]]
0 commit comments