66import sys
77from typing import TYPE_CHECKING , Tuple
88
9+ import rpm
10+
911from specfile .constants import ARCH_NAMES
1012from specfile .exceptions import SpecfileException , UnterminatedMacroException
1113from specfile .formatter import formatted
@@ -28,10 +30,41 @@ def _key(self) -> tuple:
2830 def __hash__ (self ) -> int :
2931 return hash (self ._key ())
3032
33+ def _rpm_evr_tuple (self ) -> Tuple [str , str , str ]:
34+ return str (self .epoch ), self .version or "0" , self .release
35+
36+ def _cmp (self , other : "EVR" ) -> int :
37+ return rpm .labelCompare (self ._rpm_evr_tuple (), other ._rpm_evr_tuple ())
38+
39+ def __lt__ (self , other : object ) -> bool :
40+ if type (other ) is not self .__class__ :
41+ return NotImplemented
42+ return self ._cmp (other ) < 0
43+
44+ def __le__ (self , other : object ) -> bool :
45+ if type (other ) is not self .__class__ :
46+ return NotImplemented
47+ return self ._cmp (other ) <= 0
48+
3149 def __eq__ (self , other : object ) -> bool :
3250 if type (other ) is not self .__class__ :
3351 return NotImplemented
34- return self ._key () == other ._key ()
52+ return self ._cmp (other ) == 0
53+
54+ def __ne__ (self , other : object ) -> bool :
55+ if type (other ) is not self .__class__ :
56+ return NotImplemented
57+ return self ._cmp (other ) != 0
58+
59+ def __ge__ (self , other : object ) -> bool :
60+ if type (other ) is not self .__class__ :
61+ return NotImplemented
62+ return self ._cmp (other ) >= 0
63+
64+ def __gt__ (self , other : object ) -> bool :
65+ if type (other ) is not self .__class__ :
66+ return NotImplemented
67+ return self ._cmp (other ) > 0
3568
3669 @formatted
3770 def __repr__ (self ) -> str :
@@ -65,6 +98,44 @@ def __init__(
6598 def _key (self ) -> tuple :
6699 return self .name , self .epoch , self .version , self .release
67100
101+ def __lt__ (self , other : object ) -> bool :
102+ if type (other ) is not self .__class__ :
103+ return NotImplemented
104+ if self .name != other .name :
105+ return NotImplemented
106+ return self ._cmp (other ) < 0
107+
108+ def __le__ (self , other : object ) -> bool :
109+ if type (other ) is not self .__class__ :
110+ return NotImplemented
111+ if self .name != other .name :
112+ return NotImplemented
113+ return self ._cmp (other ) <= 0
114+
115+ def __eq__ (self , other : object ) -> bool :
116+ if type (other ) is not self .__class__ :
117+ return NotImplemented
118+ return self .name == other .name and self ._cmp (other ) == 0
119+
120+ def __ne__ (self , other : object ) -> bool :
121+ if type (other ) is not self .__class__ :
122+ return NotImplemented
123+ return self .name != other .name or self ._cmp (other ) != 0
124+
125+ def __ge__ (self , other : object ) -> bool :
126+ if type (other ) is not self .__class__ :
127+ return NotImplemented
128+ if self .name != other .name :
129+ return NotImplemented
130+ return self ._cmp (other ) >= 0
131+
132+ def __gt__ (self , other : object ) -> bool :
133+ if type (other ) is not self .__class__ :
134+ return NotImplemented
135+ if self .name != other .name :
136+ return NotImplemented
137+ return self ._cmp (other ) > 0
138+
68139 @formatted
69140 def __repr__ (self ) -> str :
70141 return (
@@ -101,6 +172,50 @@ def __init__(
101172 def _key (self ) -> tuple :
102173 return self .name , self .epoch , self .version , self .release , self .arch
103174
175+ def __lt__ (self , other : object ) -> bool :
176+ if type (other ) is not self .__class__ :
177+ return NotImplemented
178+ if self .name != other .name or self .arch != other .arch :
179+ return NotImplemented
180+ return self ._cmp (other ) < 0
181+
182+ def __le__ (self , other : object ) -> bool :
183+ if type (other ) is not self .__class__ :
184+ return NotImplemented
185+ if self .name != other .name or self .arch != other .arch :
186+ return NotImplemented
187+ return self ._cmp (other ) <= 0
188+
189+ def __eq__ (self , other : object ) -> bool :
190+ if type (other ) is not self .__class__ :
191+ return NotImplemented
192+ return (
193+ self .name == other .name
194+ and self .arch == other .arch
195+ and self ._cmp (other ) == 0
196+ )
197+
198+ def __ne__ (self , other : object ) -> bool :
199+ if type (other ) is not self .__class__ :
200+ return NotImplemented
201+ return (
202+ self .name != other .name or self .arch != other .arch or self ._cmp (other ) != 0
203+ )
204+
205+ def __ge__ (self , other : object ) -> bool :
206+ if type (other ) is not self .__class__ :
207+ return NotImplemented
208+ if self .name != other .name or self .arch != other .arch :
209+ return NotImplemented
210+ return self ._cmp (other ) >= 0
211+
212+ def __gt__ (self , other : object ) -> bool :
213+ if type (other ) is not self .__class__ :
214+ return NotImplemented
215+ if self .name != other .name or self .arch != other .arch :
216+ return NotImplemented
217+ return self ._cmp (other ) > 0
218+
104219 @formatted
105220 def __repr__ (self ) -> str :
106221 return (
0 commit comments