@@ -199,19 +199,14 @@ def __init__(self, version):
199199 if not self .is_correct (version ):
200200 raise InvalidVersionError (version )
201201
202- # If version is an empty string convert it to 0
203202 version = str (version ).strip ()
204-
205203 self .original = version
206204
205+ # If version is an empty string convert it to 0
207206 if not version :
208207 version = "0"
209208
210209 self .version = version .replace ("-" , ".pre." )
211- self ._segments = ()
212- self ._canonical_segments = ()
213- self ._bump = None
214- self ._release = None
215210
216211 def __str__ (self ):
217212 return self .original
@@ -225,7 +220,7 @@ def equal_strictly(self, other):
225220 return self .version == other .version
226221
227222 def __hash__ (self ):
228- return hash (tuple ( self .canonical_segments ) )
223+ return hash (self .canonical_segments )
229224
230225 def __eq__ (self , other ):
231226 return self .canonical_segments == other .canonical_segments
@@ -242,6 +237,32 @@ def __gt__(self, other):
242237 def __ge__ (self , other ):
243238 return self .__cmp__ (other ) >= 0
244239
240+ @property
241+ def segments (self ):
242+ """
243+ Returns segments for this version where segments are
244+ ints or strings parsed from the original version string.
245+ """
246+ segments = []
247+ find_segments = re .compile (r"[0-9]+|[a-z]+" , re .IGNORECASE ).findall
248+ for seg in find_segments (self .version ):
249+ sub_segments = [int (seg ) if seg .isdigit () else seg ]
250+ segments .extend (sub_segments )
251+ return tuple (segments )
252+
253+ @property
254+ def canonical_segments (self ):
255+ """
256+ Returns "canonical segments" for this version using
257+ the Rubygems way for canonicalization.
258+ """
259+ canonical_segments = []
260+ for segments in self .split_segments ():
261+ # drop the section preceding the least significant zero (if exists)
262+ segs = list (dropwhile (lambda s : s == 0 , reversed (segments )))
263+ canonical_segments .extend (reversed (segs ))
264+ return tuple (canonical_segments )
265+
245266 def bump (self ):
246267 """
247268 Return a new version object where the next to the last revision number
@@ -252,40 +273,33 @@ def bump(self):
252273 >>> assert GemVersion("5.3.1").bump() == GemVersion("5.4"), repr(GemVersion("5.3.1").bump())
253274 >>> assert GemVersion("5.3.1.4-2").bump() == GemVersion("5.3.2"), GemVersion("5.3.1.4-2").bump()
254275 """
255- if not self ._bump :
256- segments = []
257- for seg in self .segments :
258- if isinstance (seg , str ):
259- break
260- else :
261- segments .append (seg )
262-
263- if len (segments ) > 1 :
264- segments .pop ()
276+ segments = []
277+ for seg in self .segments :
278+ if isinstance (seg , str ):
279+ break
280+ else :
281+ segments .append (seg )
265282
266- segments [- 1 ] += 1
267- segments = [str (r ) for r in segments ]
268- self ._bump = GemVersion ("." .join (segments ))
283+ if len (segments ) > 1 :
284+ segments .pop ()
269285
270- return self ._bump
286+ segments [- 1 ] += 1
287+ segments = [str (r ) for r in segments ]
288+ return GemVersion ("." .join (segments ))
271289
272290 def release (self ):
273291 """
274292 Return a new GemVersion which is the release for this version (e.g.,
275293 1.2.0.a -> 1.2.0). Non-prerelease versions return themselves. A release
276294 is composed only of numeric segments.
277295 """
278- if not self ._release :
279- if self .prerelease ():
280- segments = self .segments
281- while any (isinstance (s , str ) for s in segments ):
282- segments .pop ()
283- segments = (str (s ) for s in segments )
284- self ._release = GemVersion ("." .join (segments ))
285- else :
286- self ._release = self
287-
288- return self ._release
296+ if self .prerelease ():
297+ segments = list (self .segments )
298+ while any (isinstance (s , str ) for s in segments ):
299+ segments .pop ()
300+ segments = (str (s ) for s in segments )
301+ return GemVersion ("." .join (segments ))
302+ return self
289303
290304 def prerelease (self ):
291305 """
@@ -294,47 +308,6 @@ def prerelease(self):
294308 """
295309 return any (not str (s ).isdigit () for s in self .segments )
296310
297- @property
298- def segments (self ):
299- """
300- Return a new sequence of segments for this version where segments are
301- ints or strings parsed from the original version string.
302- """
303- if not self ._segments :
304- self ._segments = self .get_segments ()
305- return list (self ._segments )
306-
307- def get_segments (self ):
308- """
309- Return a sequence of segments for this version where segments are ints
310- or strings parsed from the original version string.
311- """
312- find_segments = re .compile (r"[0-9]+|[a-z]+" , re .IGNORECASE ).findall
313- segments = []
314- for seg in find_segments (self .version ):
315- if seg .isdigit ():
316- seg = int (seg )
317- segments .append (seg )
318- return tuple (segments )
319-
320- @property
321- def canonical_segments (self ):
322- if not self ._canonical_segments :
323- self ._canonical_segments = self .get_canonical_segments ()
324- return tuple (self ._canonical_segments )
325-
326- def get_canonical_segments (self ):
327- """
328- Return a new sequence of "canonical segments" for this version using
329- the Rubygems way.
330- """
331- canonical_segments = []
332- for segments in self .split_segments ():
333- segs = list (dropwhile (lambda s : s == 0 , reversed (segments )))
334- segs = reversed (segs )
335- canonical_segments .extend (segs )
336- return tuple (canonical_segments )
337-
338311 def split_segments (self ):
339312 """
340313 Return a two-tuple of segments:
@@ -380,11 +353,11 @@ def __cmp__(self, other, trace=False):
380353 if self .version == other .version :
381354 return 0
382355
383- lhsegments = self .canonical_segments
356+ lhsegments = list ( self .canonical_segments )
384357 if trace :
385358 print (f" lhsegments: canonical_segments: { lhsegments !r} " )
386359
387- rhsegments = other .canonical_segments
360+ rhsegments = list ( other .canonical_segments )
388361 if trace :
389362 print (f" rhsegments: canonical_segments: { rhsegments !r} " )
390363
0 commit comments