99import typing as t
1010
1111
12- class WorkItem :
13- """A data class containing all relevant data of a Polarion WorkItem."""
14-
12+ class BaseItem :
1513 id : str | None = None
16- title : str | None = None
17- description_type : str | None = None
18- description : str | None = None
1914 type : str | None = None
2015 status : str | None = None
21- additional_attributes : dict [str , t .Any ] = {}
22- linked_work_items : list [WorkItemLink ] = []
23- attachments : list [WorkItemAttachment ] = []
2416 _checksum : str | None = None
2517
2618 def __init__ (
2719 self ,
2820 id : str | None = None ,
29- title : str | None = None ,
30- description_type : str | None = None ,
31- description : str | None = None ,
3221 type : str | None = None ,
3322 status : str | None = None ,
34- additional_attributes : dict [str , t .Any ] | None = None ,
35- linked_work_items : list [WorkItemLink ] | None = None ,
36- attachments : list [WorkItemAttachment ] | None = None ,
37- ** kwargs ,
3823 ):
3924 self .id = id
40- self .title = title
41- self .description_type = description_type
42- self .description = description
4325 self .type = type
4426 self .status = status
45- self .additional_attributes = (additional_attributes or {}) | kwargs
46- self ._checksum = self .additional_attributes .pop ("checksum" , None )
47- self .linked_work_items = linked_work_items or []
48- self .attachments = attachments or []
49-
50- def __getattribute__ (self , item : str ) -> t .Any :
51- """Return all non WorkItem attributes from additional_properties."""
52- if item .startswith ("__" ) or item in dir (WorkItem ):
53- return super ().__getattribute__ (item )
54- return self .additional_attributes .get (item )
55-
56- def __setattr__ (self , key : str , value : t .Any ):
57- """Set all non WorkItem attributes in additional_properties."""
58- if key in dir (WorkItem ):
59- super ().__setattr__ (key , value )
60- else :
61- self .additional_attributes [key ] = value
27+ self ._checksum = None
6228
6329 def __eq__ (self , other : object ) -> bool :
64- """Compare only WorkItem attributes."""
65- if not isinstance (other , WorkItem ):
30+ """Compare only BaseItem attributes."""
31+ if not isinstance (other , BaseItem ):
6632 return NotImplemented
6733 if self .get_current_checksum () is None :
6834 self .calculate_checksum ()
@@ -71,48 +37,24 @@ def __eq__(self, other: object) -> bool:
7137
7238 return self .get_current_checksum () == other .get_current_checksum ()
7339
74- def to_dict (self ) -> dict [str , t .Any ]:
75- """Return the content of the WorkItem as dictionary."""
76- sorted_links = sorted (
77- self .linked_work_items ,
78- key = lambda x : f"{ x .role } /{ x .secondary_work_item_project } /{ x .secondary_work_item_id } " , # pylint: disable=line-too-long
79- )
80-
81- sorted_attachments = sorted (
82- self .attachments , key = lambda x : x .file_name or ""
83- )
84-
40+ def to_dict (self ) -> dict [str , Any ]:
41+ """Return the content of the BaseItem as dictionary."""
8542 return {
8643 "id" : self .id ,
87- "title" : self .title ,
88- "description_type" : self .description_type ,
89- "description" : self .description ,
9044 "type" : self .type ,
9145 "status" : self .status ,
92- "additional_attributes" : dict (
93- sorted (self .additional_attributes .items ())
94- ),
9546 "checksum" : self ._checksum ,
96- "linked_work_items" : [
97- dataclasses .asdict (lwi ) for lwi in sorted_links
98- ],
99- "attachments" : [
100- dataclasses .asdict (at ) for at in sorted_attachments
101- ],
10247 }
10348
10449 def calculate_checksum (self ) -> str :
105- """Calculate and return a checksum for this WorkItem .
50+ """Calculate and return a checksum for this BaseItem .
10651
10752 In addition, the checksum will be written to self._checksum.
10853 """
10954 data = self .to_dict ()
11055 del data ["checksum" ]
11156 del data ["id" ]
11257
113- for at in data ["attachments" ]:
114- del at ["id" ]
115-
11658 data = dict (sorted (data .items ()))
11759
11860 converted = json .dumps (data ).encode ("utf8" )
@@ -124,6 +66,51 @@ def get_current_checksum(self) -> str | None:
12466 return self ._checksum
12567
12668
69+ class WorkItem (BaseItem ):
70+ """A data class containing all relevant data of a Polarion WorkItem."""
71+
72+ title : str | None = None
73+ description_type : str | None = None
74+ description : str | None = None
75+ additional_attributes : dict [str , Any ] = {}
76+ linked_work_items : list [WorkItemLink ] = []
77+ attachments : list [WorkItemAttachment ] = []
78+
79+ def __init__ (
80+ self ,
81+ id : str | None = None ,
82+ title : str | None = None ,
83+ description_type : str | None = None ,
84+ description : str | None = None ,
85+ type : str | None = None ,
86+ status : str | None = None ,
87+ additional_attributes : dict [str , Any ] | None = None ,
88+ linked_work_items : list [WorkItemLink ] | None = None ,
89+ attachments : list [WorkItemAttachment ] | None = None ,
90+ ** kwargs ,
91+ ):
92+ super ().__init__ (id , type , status )
93+ self .title = title
94+ self .description_type = description_type
95+ self .description = description
96+ self .additional_attributes = (additional_attributes or {}) | kwargs
97+ self .linked_work_items = linked_work_items or []
98+ self .attachments = attachments or []
99+
100+ def __getattribute__ (self , item : str ) -> Any :
101+ """Return all non WorkItem attributes from additional_properties."""
102+ if item .startswith ("__" ) or item in dir (WorkItem ):
103+ return super ().__getattribute__ (item )
104+ return self .additional_attributes .get (item )
105+
106+ def __setattr__ (self , key : str , value : Any ):
107+ """Set all non WorkItem attributes in additional_properties."""
108+ if key in dir (WorkItem ):
109+ super ().__setattr__ (key , value )
110+ else :
111+ self .additional_attributes [key ] = value
112+
113+
127114@dataclasses .dataclass
128115class WorkItemLink :
129116 """A link between multiple Polarion WorkItems.
@@ -153,16 +140,10 @@ class WorkItemAttachment:
153140 file_name : str | None = None
154141
155142
156- class Document :
157- """A data class containing all relevant data of a Polarion WorkItem."""
158-
159- id : str | None = None
143+ class Document (BaseItem ):
160144 module_folder : str | None = None
161145 module_name : str | None = None
162- type : str | None = None
163- status : str | None = None
164146 home_page_content : dict | None = None
165- _checksum : str | None = None
166147
167148 def __init__ (
168149 self ,
@@ -173,52 +154,7 @@ def __init__(
173154 status : str | None = None ,
174155 home_page_content : dict | None = None ,
175156 ):
176- self . id = id
157+ super (). __init__ ( id , type , status )
177158 self .module_folder = module_folder
178159 self .module_name = module_name
179- self .type = type
180- self .status = status
181160 self .home_page_content = home_page_content
182- self ._checksum = None
183-
184- def __eq__ (self , other : object ) -> bool :
185- """Compare only Document attributes."""
186- if not isinstance (other , Document ):
187- return NotImplemented
188- if self .get_current_checksum () is None :
189- self .calculate_checksum ()
190- if other .get_current_checksum () is None :
191- other .calculate_checksum ()
192-
193- return self .get_current_checksum () == other .get_current_checksum ()
194-
195- def to_dict (self ) -> dict [str , t .Any ]:
196- """Return the content of the Document as dictionary."""
197- return {
198- "id" : self .id ,
199- "module_folder" : self .module_folder ,
200- "module_name" : self .module_name ,
201- "type" : self .type ,
202- "status" : self .status ,
203- "home_page_content" : self .home_page_content ,
204- "checksum" : self ._checksum ,
205- }
206-
207- def calculate_checksum (self ) -> str :
208- """Calculate and return a checksum for this Document.
209-
210- In addition, the checksum will be written to self._checksum.
211- """
212- data = self .to_dict ()
213- del data ["checksum" ]
214- del data ["id" ]
215-
216- data = dict (sorted (data .items ()))
217-
218- converted = json .dumps (data ).encode ("utf8" )
219- self ._checksum = hashlib .sha256 (converted ).hexdigest ()
220- return self ._checksum
221-
222- def get_current_checksum (self ) -> str | None :
223- """Return the checksum currently set without calculation."""
224- return self ._checksum
0 commit comments