22
33from semver import Version
44
5- _re_partial_version = re .compile (r"^([0-9]+)(?:\.([0-9]+)(?:\.([0-9]+))?)?$" )
5+ _re_digits_g = "[0-9]+"
6+
7+
8+ def _re_group (inner = "" , numeric = True , delimiter = "." ):
9+ capture = _re_digits_g if numeric else ".*"
10+ return f"(?:{ delimiter } ({ capture } ){ inner } )?"
11+
12+
13+ _re_prerelease = _re_group (numeric = False )
14+ _re_optional = _re_group (_re_group (_re_prerelease ))
15+ _re_partial_version = re .compile (rf"^({ _re_digits_g } ){ _re_optional } $" )
616
717
818def _parse_partial_version (x ):
919 m = _re_partial_version .match (x )
1020 if m is None :
1121 return None , None
12- major , minor , patch = m .groups ()
13- v = Version (major , minor or 0 , patch or 0 )
14- n = 1 if minor is None else 2 if patch is None else 3
22+ major , minor , patch , prerelease = m .groups ()
23+ v = Version (major , minor or 0 , patch or 0 , prerelease )
24+ n = 1 if minor is None else 2 if patch is None else 3 if prerelease is None else 4
1525 return (v , n )
1626
1727
@@ -87,20 +97,26 @@ def caret(cls, v, n):
8797 v .major ,
8898 v .minor if n >= 2 else 0 ,
8999 v .patch if n >= 3 else 0 ,
100+ v .prerelease if n >= 4 else None ,
90101 )
91102 hi = (
92103 v .bump_major ()
93104 if v .major != 0 or n < 2
94105 else v .bump_minor ()
95106 if v .minor != 0 or n < 3
96107 else v .bump_patch ()
108+ if v .patch != 0 or n < 4
109+ else v .bump_prerelease ()
97110 )
98111 return Range (lo , hi )
99112
100113 @classmethod
101114 def equality (cls , v ):
102115 lo = v
103- hi = v .bump_patch ()
116+ if lo .prerelease is not None :
117+ hi = v .bump_prerelease ()
118+ else :
119+ hi = v .bump_patch ()
104120 return Range (lo , hi )
105121
106122 @classmethod
@@ -120,7 +136,7 @@ def parse(cls, x):
120136 elif x .startswith ("=" ):
121137 # equality specifier
122138 v , n = _parse_partial_version (x [1 :])
123- if v is not None and n = = 3 :
139+ if v is not None and n > = 3 :
124140 return cls .equality (v )
125141 elif " - " in x :
126142 # range specifier
@@ -140,26 +156,40 @@ def __str__(self):
140156 lo = self .lo
141157 hi = self .hi
142158 if self == Range .equality (lo ):
143- return f"={ lo .major } .{ lo .minor } .{ lo .patch } "
159+ prerelease = f"-{ lo .prerelease } " if lo .prerelease else ""
160+ return f"={ lo .major } .{ lo .minor } .{ lo .patch } { prerelease } "
144161 if self == Range .caret (lo , 1 ):
145162 return f"^{ lo .major } "
146163 if self == Range .caret (lo , 2 ):
147164 return f"^{ lo .major } .{ lo .minor } "
148165 if self == Range .caret (lo , 3 ):
149166 return f"^{ lo .major } .{ lo .minor } .{ lo .patch } "
167+ if self == Range .caret (lo , 4 ):
168+ return f"^{ lo .major } .{ lo .minor } .{ lo .patch } -{ lo .prerelease } "
150169 if self == Range .tilde (lo , 1 ):
151170 return f"~{ lo .major } "
152171 if self == Range .tilde (lo , 2 ):
153172 return f"~{ lo .major } .{ lo .minor } "
154173 if self == Range .tilde (lo , 3 ):
155174 return f"~{ lo .major } .{ lo .minor } .{ lo .patch } "
156- lostr = f"{ lo .major } .{ lo .minor } .{ lo .patch } "
175+ if self == Range .tilde (lo , 4 ):
176+ return f"~{ lo .major } .{ lo .minor } .{ lo .patch } -{ lo .prerelease } "
177+ if lo .prerelease is None :
178+ lostr = f"{ lo .major } .{ lo .minor } .{ lo .patch } "
179+ else :
180+ lostr = f"{ lo .major } .{ lo .minor } .{ lo .patch } -{ lo .prerelease } "
181+ hi_str = ""
157182 if hi .major > 0 and hi .minor == 0 and hi .patch == 0 :
158183 return f"{ lostr } - { hi .major - 1 } "
184+ hi_str += f"{ hi .major } "
159185 if hi .minor > 0 and hi .patch == 0 :
160- return f"{ lostr } - { hi .major } .{ hi .minor - 1 } "
161- if hi .patch > 0 :
162- return f"{ lostr } - { hi .major } .{ hi .minor } .{ hi .patch - 1 } "
186+ return f"{ lostr } - { hi_str } .{ hi .minor - 1 } "
187+ hi_str += f".{ hi .minor } "
188+ if hi .patch > 0 and hi .prerelease is None :
189+ return f"{ lostr } - { hi_str } .{ hi .patch - 1 } "
190+ hi_str += f".{ hi .patch } "
191+ if hi .prerelease is not None :
192+ return f"{ lostr } - { hi_str } -{ self ._decrease_string (hi .prerelease )} "
163193 raise ValueError ("invalid range" )
164194
165195 def __repr__ (self ):
@@ -180,3 +210,11 @@ def __eq__(self, other):
180210
181211 def is_empty (self ):
182212 return not (self .lo < self .hi )
213+
214+ def _decrease_string (self , string ):
215+ match = Version ._LAST_NUMBER .search (string )
216+ if match :
217+ prev_ = str (int (match .group (1 )) - 1 )
218+ start , end = match .span (1 )
219+ string = string [: max (end - len (prev_ ), start )] + prev_ + string [end :]
220+ return string
0 commit comments