41
41
42
42
Increment : TypeAlias = Literal ["MAJOR" , "MINOR" , "PATCH" ]
43
43
Prerelease : TypeAlias = Literal ["alpha" , "beta" , "rc" ]
44
- DEFAULT_VERSION_PARSER = r"v?(?P<version>([0-9]+)\.([0-9]+)(?:\.([0-9]+))?(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z.]+)?(\w+)?)"
44
+ _DEFAULT_VERSION_PARSER = re .compile (
45
+ r"v?(?P<version>([0-9]+)\.([0-9]+)(?:\.([0-9]+))?(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z.]+)?(\w+)?)"
46
+ )
45
47
46
48
47
49
@runtime_checkable
@@ -156,7 +158,7 @@ class BaseVersion(_BaseVersion):
156
158
A base class implementing the `VersionProtocol` for PEP440-like versions.
157
159
"""
158
160
159
- parser : ClassVar [re .Pattern ] = re . compile ( DEFAULT_VERSION_PARSER )
161
+ parser : ClassVar [re .Pattern ] = _DEFAULT_VERSION_PARSER
160
162
"""Regex capturing this version scheme into a `version` group"""
161
163
162
164
@property
@@ -186,20 +188,16 @@ def generate_prerelease(
186
188
if not prerelease :
187
189
return ""
188
190
191
+ new_prerelease_number = offset
189
192
# prevent down-bumping the pre-release phase, e.g. from 'b1' to 'a2'
190
193
# https://packaging.python.org/en/latest/specifications/version-specifiers/#pre-releases
191
194
# https://semver.org/#spec-item-11
192
195
if self .is_prerelease and self .pre :
193
196
prerelease = max (prerelease , self .pre [0 ])
197
+ if prerelease .startswith (self .pre [0 ]):
198
+ new_prerelease_number = self .pre [1 ] + 1
194
199
195
- # version.pre is needed for mypy check
196
- if self .is_prerelease and self .pre and prerelease .startswith (self .pre [0 ]):
197
- prev_prerelease : int = self .pre [1 ]
198
- new_prerelease_number = prev_prerelease + 1
199
- else :
200
- new_prerelease_number = offset
201
- pre_version = f"{ prerelease } { new_prerelease_number } "
202
- return pre_version
200
+ return f"{ prerelease } { new_prerelease_number } "
203
201
204
202
def generate_devrelease (self , devrelease : int | None ) -> str :
205
203
"""Generate devrelease
@@ -265,39 +263,35 @@ def bump(
265
263
if self .local and is_local_version :
266
264
local_version = self .scheme (self .local ).bump (increment )
267
265
return self .scheme (f"{ self .public } +{ local_version } " ) # type: ignore
268
- else :
269
- if not self .is_prerelease :
270
- base = self .increment_base (increment )
271
- elif exact_increment :
272
- base = self .increment_base (increment )
273
- else :
274
- base = f"{ self .major } .{ self .minor } .{ self .micro } "
275
- if increment == PATCH :
276
- pass
277
- elif increment == MINOR :
278
- if self .micro != 0 :
279
- base = self .increment_base (increment )
280
- elif increment == MAJOR :
281
- if self .minor != 0 or self .micro != 0 :
282
- base = self .increment_base (increment )
283
- dev_version = self .generate_devrelease (devrelease )
284
-
285
- release = list (self .release )
286
- if len (release ) < 3 :
287
- release += [0 ] * (3 - len (release ))
288
- current_base = "." .join (str (part ) for part in release )
289
- if base == current_base :
290
- pre_version = self .generate_prerelease (
291
- prerelease , offset = prerelease_offset
292
- )
293
- else :
294
- base_version = cast (BaseVersion , self .scheme (base ))
295
- pre_version = base_version .generate_prerelease (
296
- prerelease , offset = prerelease_offset
297
- )
298
- build_metadata = self .generate_build_metadata (build_metadata )
299
- # TODO: post version
300
- return self .scheme (f"{ base } { pre_version } { dev_version } { build_metadata } " ) # type: ignore
266
+
267
+ base = self ._get_increment_base (increment , exact_increment )
268
+ dev_version = self .generate_devrelease (devrelease )
269
+
270
+ release = list (self .release )
271
+ if len (release ) < 3 :
272
+ release += [0 ] * (3 - len (release ))
273
+ current_base = "." .join (str (part ) for part in release )
274
+
275
+ pre_version = (
276
+ self if base == current_base else cast (BaseVersion , self .scheme (base ))
277
+ ).generate_prerelease (prerelease , offset = prerelease_offset )
278
+
279
+ # TODO: post version
280
+ return self .scheme (
281
+ f"{ base } { pre_version } { dev_version } { self .generate_build_metadata (build_metadata )} "
282
+ ) # type: ignore
283
+
284
+ def _get_increment_base (
285
+ self , increment : Increment | None , exact_increment : bool
286
+ ) -> str :
287
+ if (
288
+ not self .is_prerelease
289
+ or exact_increment
290
+ or (increment == MINOR and self .micro != 0 )
291
+ or (increment == MAJOR and (self .minor != 0 or self .micro != 0 ))
292
+ ):
293
+ return self .increment_base (increment )
294
+ return f"{ self .major } .{ self .minor } .{ self .micro } "
301
295
302
296
303
297
class Pep440 (BaseVersion ):
@@ -316,7 +310,7 @@ class SemVer(BaseVersion):
316
310
"""
317
311
318
312
def __str__ (self ) -> str :
319
- parts = []
313
+ parts : list [ str ] = []
320
314
321
315
# Epoch
322
316
if self .epoch != 0 :
@@ -364,7 +358,7 @@ def prerelease(self) -> str | None:
364
358
return None
365
359
366
360
def __str__ (self ) -> str :
367
- parts = []
361
+ parts : list [ str ] = []
368
362
369
363
# Epoch
370
364
if self .epoch != 0 :
@@ -373,9 +367,19 @@ def __str__(self) -> str:
373
367
# Release segment
374
368
parts .append ("." .join (str (x ) for x in self .release ))
375
369
370
+ if prerelease := self ._get_prerelease ():
371
+ parts .append (f"-{ prerelease } " )
372
+
373
+ # Local version segment
374
+ if self .local :
375
+ parts .append (f"+{ self .local } " )
376
+
377
+ return "" .join (parts )
378
+
379
+ def _get_prerelease (self ) -> str :
376
380
# Pre-release identifiers
377
381
# See: https://semver.org/spec/v2.0.0.html#spec-item-9
378
- prerelease_parts = []
382
+ prerelease_parts : list [ str ] = []
379
383
if self .prerelease :
380
384
prerelease_parts .append (f"{ self .prerelease } " )
381
385
@@ -387,15 +391,7 @@ def __str__(self) -> str:
387
391
if self .dev is not None :
388
392
prerelease_parts .append (f"dev.{ self .dev } " )
389
393
390
- if prerelease_parts :
391
- parts .append ("-" )
392
- parts .append ("." .join (prerelease_parts ))
393
-
394
- # Local version segment
395
- if self .local :
396
- parts .append (f"+{ self .local } " )
397
-
398
- return "" .join (parts )
394
+ return "." .join (prerelease_parts )
399
395
400
396
401
397
DEFAULT_SCHEME : VersionScheme = Pep440
0 commit comments