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
@@ -265,39 +267,35 @@ def bump(
265
267
if self .local and is_local_version :
266
268
local_version = self .scheme (self .local ).bump (increment )
267
269
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
270
+
271
+ base = self ._get_increment_base (increment , exact_increment )
272
+ dev_version = self .generate_devrelease (devrelease )
273
+
274
+ release = list (self .release )
275
+ if len (release ) < 3 :
276
+ release += [0 ] * (3 - len (release ))
277
+ current_base = "." .join (str (part ) for part in release )
278
+
279
+ pre_version = (
280
+ self if base == current_base else cast (BaseVersion , self .scheme (base ))
281
+ ).generate_prerelease (prerelease , offset = prerelease_offset )
282
+
283
+ # TODO: post version
284
+ return self .scheme (
285
+ f"{ base } { pre_version } { dev_version } { self .generate_build_metadata (build_metadata )} "
286
+ ) # type: ignore
287
+
288
+ def _get_increment_base (
289
+ self , increment : Increment | None , exact_increment : bool
290
+ ) -> str :
291
+ if (
292
+ not self .is_prerelease
293
+ or exact_increment
294
+ or (increment == MINOR and self .micro != 0 )
295
+ or (increment == MAJOR and (self .minor != 0 or self .micro != 0 ))
296
+ ):
297
+ return self .increment_base (increment )
298
+ return f"{ self .major } .{ self .minor } .{ self .micro } "
301
299
302
300
303
301
class Pep440 (BaseVersion ):
@@ -316,7 +314,7 @@ class SemVer(BaseVersion):
316
314
"""
317
315
318
316
def __str__ (self ) -> str :
319
- parts = []
317
+ parts : list [ str ] = []
320
318
321
319
# Epoch
322
320
if self .epoch != 0 :
@@ -364,7 +362,7 @@ def prerelease(self) -> str | None:
364
362
return None
365
363
366
364
def __str__ (self ) -> str :
367
- parts = []
365
+ parts : list [ str ] = []
368
366
369
367
# Epoch
370
368
if self .epoch != 0 :
@@ -373,9 +371,19 @@ def __str__(self) -> str:
373
371
# Release segment
374
372
parts .append ("." .join (str (x ) for x in self .release ))
375
373
374
+ if prerelease := self ._get_prerelease ():
375
+ parts .append (f"-{ prerelease } " )
376
+
377
+ # Local version segment
378
+ if self .local :
379
+ parts .append (f"+{ self .local } " )
380
+
381
+ return "" .join (parts )
382
+
383
+ def _get_prerelease (self ) -> str :
376
384
# Pre-release identifiers
377
385
# See: https://semver.org/spec/v2.0.0.html#spec-item-9
378
- prerelease_parts = []
386
+ prerelease_parts : list [ str ] = []
379
387
if self .prerelease :
380
388
prerelease_parts .append (f"{ self .prerelease } " )
381
389
@@ -387,15 +395,7 @@ def __str__(self) -> str:
387
395
if self .dev is not None :
388
396
prerelease_parts .append (f"dev.{ self .dev } " )
389
397
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 )
398
+ return "." .join (prerelease_parts )
399
399
400
400
401
401
DEFAULT_SCHEME : VersionScheme = Pep440
0 commit comments