11import abc
22import 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
44import urllib .parse
55
66from tableauserverclient .server .endpoint .endpoint import Endpoint , api
@@ -62,27 +62,24 @@ def update_tags(self, baseurl, resource_item):
6262 logger .info ("Updated tags to {0}" .format (resource_item .tags ))
6363
6464
65- class HasID (Protocol ):
66- @property
67- def id (self ) -> Optional [str ]:
68- pass
65+ class Response (Protocol ):
66+ content : bytes
6967
7068
7169@runtime_checkable
7270class Taggable (Protocol ):
73- _initial_tags : Set [str ]
7471 tags : Set [str ]
72+ _initial_tags : Set [str ]
7573
7674 @property
7775 def id (self ) -> Optional [str ]:
7876 pass
7977
8078
81- class Response (Protocol ):
82- content : bytes
79+ T = TypeVar ("T" )
8380
8481
85- class TaggingMixin (abc .ABC ):
82+ class TaggingMixin (abc .ABC , Generic [ T ] ):
8683 parent_srv : "Server"
8784
8885 @property
@@ -98,7 +95,7 @@ def put_request(self, url, request) -> Response:
9895 def delete_request (self , url ) -> None :
9996 pass
10097
101- def add_tags (self , item : Union [HasID , Taggable , str ], tags : Union [Iterable [str ], str ]) -> Set [str ]:
98+ def add_tags (self , item : Union [T , str ], tags : Union [Iterable [str ], str ]) -> Set [str ]:
10299 item_id = getattr (item , "id" , item )
103100
104101 if not isinstance (item_id , str ):
@@ -114,7 +111,7 @@ def add_tags(self, item: Union[HasID, Taggable, str], tags: Union[Iterable[str],
114111 server_response = self .put_request (url , add_req )
115112 return TagItem .from_response (server_response .content , self .parent_srv .namespace )
116113
117- def delete_tags (self , item : Union [HasID , Taggable , str ], tags : Union [Iterable [str ], str ]) -> None :
114+ def delete_tags (self , item : Union [T , str ], tags : Union [Iterable [str ], str ]) -> None :
118115 item_id = getattr (item , "id" , item )
119116
120117 if not isinstance (item_id , str ):
@@ -130,17 +127,23 @@ def delete_tags(self, item: Union[HasID, Taggable, str], tags: Union[Iterable[st
130127 url = f"{ self .baseurl } /{ item_id } /tags/{ encoded_tag_name } "
131128 self .delete_request (url )
132129
133- def update_tags (self , item : Taggable ) -> None :
134- if item .tags == item ._initial_tags :
130+ def update_tags (self , item : T ) -> None :
131+ if (initial_tags := getattr (item , "_initial_tags" , None )) is None :
132+ raise ValueError (f"{ item } does not have initial tags." )
133+ if (tags := getattr (item , "tags" , None )) is None :
134+ raise ValueError (f"{ item } does not have tags." )
135+ if tags == initial_tags :
135136 return
136137
137- add_set = item . tags - item . _initial_tags
138- remove_set = item . _initial_tags - item . tags
138+ add_set = tags - initial_tags
139+ remove_set = initial_tags - tags
139140 self .delete_tags (item , remove_set )
140141 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 } " )
142+ tags = self .add_tags (item , add_set )
143+ setattr (item , "tags" , tags )
144+
145+ setattr (item , "_initial_tags" , copy .copy (tags ))
146+ logger .info (f"Updated tags to { tags } " )
144147
145148
146149content = Iterable [Union ["ColumnItem" , "DatabaseItem" , "DatasourceItem" , "FlowItem" , "TableItem" , "WorkbookItem" ]]
0 commit comments