Let us walk on the 3-isogeny graph
Loading...
Searching...
No Matches
pip._vendor.distlib.version Namespace Reference

Data Structures

class  LegacyMatcher
 
class  LegacyVersion
 
class  Matcher
 
class  NormalizedMatcher
 
class  NormalizedVersion
 
class  SemanticMatcher
 
class  SemanticVersion
 
class  UnsupportedVersionError
 
class  Version
 
class  VersionScheme
 

Functions

 _pep_440_key (s)
 
 _match_prefix (x, y)
 
 _suggest_semantic_version (s)
 
 _suggest_normalized_version (s)
 
 _legacy_key (s)
 
 is_semver (s)
 
 _semantic_key (s)
 
 get_scheme (name)
 

Variables

 logger = logging.getLogger(__name__)
 
 PEP440_VERSION_RE
 
 _normalized_key = _pep_440_key
 
tuple _REPLACEMENTS
 
tuple _SUFFIX_REPLACEMENTS
 
 _NUMERIC_PREFIX = re.compile(r'(\d+(\.\d+)*)')
 
 _VERSION_PART = re.compile(r'([a-z]+|\d+|[\.-])', re.I)
 
dict _VERSION_REPLACE
 
 _SEMVER_RE
 
dict _SCHEMES
 

Detailed Description

Implementation of a flexible versioning scheme providing support for PEP-440,
setuptools-compatible and semantic versioning.

Function Documentation

◆ _legacy_key()

_legacy_key (   s)
protected

Definition at line 578 of file version.py.

578def _legacy_key(s):
579 def get_parts(s):
580 result = []
581 for p in _VERSION_PART.split(s.lower()):
582 p = _VERSION_REPLACE.get(p, p)
583 if p:
584 if '0' <= p[:1] <= '9':
585 p = p.zfill(8)
586 else:
587 p = '*' + p
589 result.append('*final')
590 return result
591
592 result = []
593 for p in get_parts(s):
594 if p.startswith('*'):
595 if p < '*final':
596 while result and result[-1] == '*final-':
597 result.pop()
598 while result and result[-1] == '00000000':
599 result.pop()
601 return tuple(result)
602
603
for i

References i.

Referenced by LegacyVersion.parse().

Here is the caller graph for this function:

◆ _match_prefix()

_match_prefix (   x,
  y 
)
protected

Definition at line 284 of file version.py.

284def _match_prefix(x, y):
285 x = str(x)
286 y = str(y)
287 if x == y:
288 return True
289 if not x.startswith(y):
290 return False
291 n = len(y)
292 return x[n] == '.'
293
294

References i.

Referenced by NormalizedMatcher._match_compatible(), LegacyMatcher._match_compatible(), NormalizedMatcher._match_eq(), NormalizedMatcher._match_gt(), NormalizedMatcher._match_lt(), and NormalizedMatcher._match_ne().

Here is the caller graph for this function:

◆ _pep_440_key()

_pep_440_key (   s)
protected

Definition at line 184 of file version.py.

184def _pep_440_key(s):
185 s = s.strip()
187 if not m:
188 raise UnsupportedVersionError('Not a valid version: %s' % s)
189 groups = m.groups()
190 nums = tuple(int(v) for v in groups[1].split('.'))
191 while len(nums) > 1 and nums[-1] == 0:
192 nums = nums[:-1]
193
194 if not groups[0]:
195 epoch = 0
196 else:
197 epoch = int(groups[0][:-1])
198 pre = groups[4:6]
199 post = groups[7:9]
200 dev = groups[10:12]
201 local = groups[13]
202 if pre == (None, None):
203 pre = ()
204 else:
205 pre = pre[0], int(pre[1])
206 if post == (None, None):
207 post = ()
208 else:
209 post = post[0], int(post[1])
210 if dev == (None, None):
211 dev = ()
212 else:
213 dev = dev[0], int(dev[1])
214 if local is None:
215 local = ()
216 else:
217 parts = []
218 for part in local.split('.'):
219 # to ensure that numeric compares as > lexicographic, avoid
220 # comparing them directly, but encode a tuple which ensures
221 # correct sorting
222 if part.isdigit():
223 part = (1, int(part))
224 else:
225 part = (0, part)
226 parts.append(part)
227 local = tuple(parts)
228 if not pre:
229 # either before pre-release, or final release and after
230 if not post and dev:
231 # before pre-release
232 pre = ('a', -1) # to sort before a0
233 else:
234 pre = ('z',) # to sort after all pre-releases
235 # now look at the state of post and dev.
236 if not post:
237 post = ('_',) # sort before 'a'
238 if not dev:
239 dev = ('final',)
240
241 #print('%s -> %s' % (s, m.groups()))
242 return epoch, nums, pre, post, dev, local
243
244

References i.

◆ _semantic_key()

_semantic_key (   s)
protected

Definition at line 653 of file version.py.

653def _semantic_key(s):
654 def make_tuple(s, absent):
655 if s is None:
656 result = (absent,)
657 else:
658 parts = s[1:].split('.')
659 # We can't compare ints and strings on Python 3, so fudge it
660 # by zero-filling numeric values so simulate a numeric comparison
661 result = tuple([p.zfill(8) if p.isdigit() else p for p in parts])
662 return result
663
664 m = is_semver(s)
665 if not m:
666 raise UnsupportedVersionError(s)
667 groups = m.groups()
668 major, minor, patch = [int(i) for i in groups[:3]]
669 # choose the '|' and '*' so that versions sort correctly
670 pre, build = make_tuple(groups[3], '|'), make_tuple(groups[5], '*')
671 return (major, minor, patch), pre, build
672
673

References i, and pip._vendor.distlib.version.is_semver().

Referenced by SemanticVersion.parse().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _suggest_normalized_version()

_suggest_normalized_version (   s)
protected
Suggest a normalized version close to the given version string.

If you have a version string that isn't rational (i.e. NormalizedVersion
doesn't like it) then you might be able to get an equivalent (or close)
rational version from this function.

This does a number of simple normalizations to the given string, based
on observation of versions currently in use on PyPI. Given a dump of
those version during PyCon 2009, 4287 of them:
- 2312 (53.93%) match NormalizedVersion without change
  with the automatic suggestion
- 3474 (81.04%) match when using this suggestion method

@param s {str} An irrational version string.
@returns A rational version string, or None, if couldn't determine one.

Definition at line 452 of file version.py.

452def _suggest_normalized_version(s):
453 """Suggest a normalized version close to the given version string.
454
455 If you have a version string that isn't rational (i.e. NormalizedVersion
456 doesn't like it) then you might be able to get an equivalent (or close)
457 rational version from this function.
458
459 This does a number of simple normalizations to the given string, based
460 on observation of versions currently in use on PyPI. Given a dump of
461 those version during PyCon 2009, 4287 of them:
462 - 2312 (53.93%) match NormalizedVersion without change
463 with the automatic suggestion
464 - 3474 (81.04%) match when using this suggestion method
465
466 @param s {str} An irrational version string.
467 @returns A rational version string, or None, if couldn't determine one.
468 """
469 try:
470 _normalized_key(s)
471 return s # already rational
472 except UnsupportedVersionError:
473 pass
474
475 rs = s.lower()
476
477 # part of this could use maketrans
478 for orig, repl in (('-alpha', 'a'), ('-beta', 'b'), ('alpha', 'a'),
479 ('beta', 'b'), ('rc', 'c'), ('-final', ''),
480 ('-pre', 'c'),
481 ('-release', ''), ('.release', ''), ('-stable', ''),
482 ('+', '.'), ('_', '.'), (' ', ''), ('.final', ''),
483 ('final', '')):
484 rs = rs.replace(orig, repl)
485
486 # if something ends with dev or pre, we add a 0
487 rs = re.sub(r"pre$", r"pre0", rs)
488 rs = re.sub(r"dev$", r"dev0", rs)
489
490 # if we have something like "b-2" or "a.2" at the end of the
491 # version, that is probably beta, alpha, etc
492 # let's remove the dash or dot
493 rs = re.sub(r"([abc]|rc)[\-\.](\d+)$", r"\1\2", rs)
494
495 # 1.0-dev-r371 -> 1.0.dev371
496 # 0.1-dev-r79 -> 0.1.dev79
497 rs = re.sub(r"[\-\.](dev)[\-\.]?r?(\d+)$", r".\1\2", rs)
498
499 # Clean: 2.0.a.3, 2.0.b1, 0.9.0~c1
500 rs = re.sub(r"[.~]?([abc])\.?", r"\1", rs)
501
502 # Clean: v0.3, v1.0
503 if rs.startswith('v'):
504 rs = rs[1:]
505
506 # Clean leading '0's on numbers.
507 #TODO: unintended side-effect on, e.g., "2003.05.09"
508 # PyPI stats: 77 (~2%) better
509 rs = re.sub(r"\b0+(\d+)(?!\d)", r"\1", rs)
510
511 # Clean a/b/c with no version. E.g. "1.0a" -> "1.0a0". Setuptools infers
512 # zero.
513 # PyPI stats: 245 (7.56%) better
514 rs = re.sub(r"(\d+[abc])$", r"\g<1>0", rs)
515
516 # the 'dev-rNNN' tag is a dev tag
517 rs = re.sub(r"\.?(dev-r|dev\.r)\.?(\d+)$", r".dev\2", rs)
518
519 # clean the - when used as a pre delimiter
520 rs = re.sub(r"-(a|b|c)(\d+)$", r"\1\2", rs)
521
522 # a terminal "dev" or "devel" can be changed into ".dev0"
523 rs = re.sub(r"[\.\-](dev|devel)$", r".dev0", rs)
524
525 # a terminal "dev" can be changed into ".dev0"
526 rs = re.sub(r"(?![\.\-])dev$", r".dev0", rs)
527
528 # a terminal "final" or "stable" can be removed
529 rs = re.sub(r"(final|stable)$", "", rs)
530
531 # The 'r' and the '-' tags are post release tags
532 # 0.4a1.r10 -> 0.4a1.post10
533 # 0.9.33-17222 -> 0.9.33.post17222
534 # 0.9.33-r17222 -> 0.9.33.post17222
535 rs = re.sub(r"\.?(r|-|-r)\.?(\d+)$", r".post\2", rs)
536
537 # Clean 'r' instead of 'dev' usage:
538 # 0.9.33+r17222 -> 0.9.33.dev17222
539 # 1.0dev123 -> 1.0.dev123
540 # 1.0.git123 -> 1.0.dev123
541 # 1.0.bzr123 -> 1.0.dev123
542 # 0.1a0dev.123 -> 0.1a0.dev123
543 # PyPI stats: ~150 (~4%) better
544 rs = re.sub(r"\.?(dev|git|bzr)\.?(\d+)$", r".dev\2", rs)
545
546 # Clean '.pre' (normalized from '-pre' above) instead of 'c' usage:
547 # 0.2.pre1 -> 0.2c1
548 # 0.2-c1 -> 0.2c1
549 # 1.0preview123 -> 1.0c123
550 # PyPI stats: ~21 (0.62%) better
551 rs = re.sub(r"\.?(pre|preview|-c)(\d+)$", r"c\g<2>", rs)
552
553 # Tcl/Tk uses "px" for their post release markers
554 rs = re.sub(r"p(\d+)$", r".post\1", rs)
555
556 try:
557 _normalized_key(rs)
558 except UnsupportedVersionError:
559 rs = None
560 return rs
561
562#
563# Legacy version processing (distribute-compatible)
564#
565

References pip._vendor.distlib.version._normalized_key, and i.

◆ _suggest_semantic_version()

_suggest_semantic_version (   s)
protected
Try to suggest a semantic form for a version for which
_suggest_normalized_version couldn't come up with anything.

Definition at line 406 of file version.py.

406def _suggest_semantic_version(s):
407 """
408 Try to suggest a semantic form for a version for which
409 _suggest_normalized_version couldn't come up with anything.
410 """
411 result = s.strip().lower()
412 for pat, repl in _REPLACEMENTS:
413 result = pat.sub(repl, result)
414 if not result:
415 result = '0.0.0'
416
417 # Now look for numeric prefix, and separate it out from
418 # the rest.
419 #import pdb; pdb.set_trace()
420 m = _NUMERIC_PREFIX.match(result)
421 if not m:
422 prefix = '0.0.0'
423 suffix = result
424 else:
425 prefix = m.groups()[0].split('.')
426 prefix = [int(i) for i in prefix]
427 while len(prefix) < 3:
429 if len(prefix) == 3:
430 suffix = result[m.end():]
431 else:
432 suffix = '.'.join([str(i) for i in prefix[3:]]) + result[m.end():]
433 prefix = prefix[:3]
434 prefix = '.'.join([str(i) for i in prefix])
435 suffix = suffix.strip()
436 if suffix:
437 #import pdb; pdb.set_trace()
438 # massage the suffix.
439 for pat, repl in _SUFFIX_REPLACEMENTS:
440 suffix = pat.sub(repl, suffix)
441
442 if not suffix:
443 result = prefix
444 else:
445 sep = '-' if 'dev' in suffix else '+'
446 result = prefix + sep + suffix
447 if not is_semver(result):
448 result = None
449 return result
450
451

References i, and pip._vendor.distlib.version.is_semver().

Here is the call graph for this function:

◆ get_scheme()

get_scheme (   name)

Definition at line 736 of file version.py.

736def get_scheme(name):
737 if name not in _SCHEMES:
738 raise ValueError('unknown scheme name: %r' % name)
739 return _SCHEMES[name]

◆ is_semver()

is_semver (   s)

Definition at line 649 of file version.py.

649def is_semver(s):
650 return _SEMVER_RE.match(s)
651
652

References i.

Referenced by pip._vendor.distlib.version._semantic_key(), and pip._vendor.distlib.version._suggest_semantic_version().

Here is the caller graph for this function:

Variable Documentation

◆ _normalized_key

_normalized_key = _pep_440_key
protected

◆ _NUMERIC_PREFIX

_NUMERIC_PREFIX = re.compile(r'(\d+(\.\d+)*)')
protected

Definition at line 403 of file version.py.

◆ _REPLACEMENTS

tuple _REPLACEMENTS
protected
Initial value:
1= (
2 (re.compile('[.+-]$'), ''), # remove trailing puncts
3 (re.compile(r'^[.](\d)'), r'0.\1'), # .N -> 0.N at start
4 (re.compile('^[.-]'), ''), # remove leading puncts
5 (re.compile(r'^\‍((.*)\‍)$'), r'\1'), # remove parentheses
6 (re.compile(r'^v(ersion)?\s*(\d+)'), r'\2'), # remove leading v(ersion)
7 (re.compile(r'^r(ev)?\s*(\d+)'), r'\2'), # remove leading v(ersion)
8 (re.compile('[.]{2,}'), '.'), # multiple runs of '.'
9 (re.compile(r'\b(alfa|apha)\b'), 'alpha'), # misspelt alpha
10 (re.compile(r'\b(pre-alpha|prealpha)\b'),
11 'pre.alpha'), # standardise
12 (re.compile(r'\‍(beta\‍)$'), 'beta'), # remove parentheses
13)

Definition at line 381 of file version.py.

◆ _SCHEMES

dict _SCHEMES
protected
Initial value:
1= {
2 'normalized': VersionScheme(_normalized_key, NormalizedMatcher,
3 _suggest_normalized_version),
4 'legacy': VersionScheme(_legacy_key, LegacyMatcher, lambda self, s: s),
5 'semantic': VersionScheme(_semantic_key, SemanticMatcher,
6 _suggest_semantic_version),
7}

Definition at line 725 of file version.py.

◆ _SEMVER_RE

_SEMVER_RE
protected
Initial value:
1= re.compile(r'^(\d+)\.(\d+)\.(\d+)'
2 r'(-[a-z0-9]+(\.[a-z0-9-]+)*)?'
3 r'(\+[a-z0-9]+(\.[a-z0-9-]+)*)?$', re.I)

Definition at line 644 of file version.py.

◆ _SUFFIX_REPLACEMENTS

tuple _SUFFIX_REPLACEMENTS
protected
Initial value:
1= (
2 (re.compile('^[:~._+-]+'), ''), # remove leading puncts
3 (re.compile('[,*")([\\]]'), ''), # remove unwanted chars
4 (re.compile('[~:+_ -]'), '.'), # replace illegal chars
5 (re.compile('[.]{2,}'), '.'), # multiple runs of '.'
6 (re.compile(r'\.$'), ''), # trailing '.'
7)

Definition at line 395 of file version.py.

◆ _VERSION_PART

_VERSION_PART = re.compile(r'([a-z]+|\d+|[\.-])', re.I)
protected

Definition at line 566 of file version.py.

◆ _VERSION_REPLACE

dict _VERSION_REPLACE
protected
Initial value:
1= {
2 'pre': 'c',
3 'preview': 'c',
4 '-': 'final-',
5 'rc': 'c',
6 'dev': '@',
7 '': None,
8 '.': None,
9}

Definition at line 567 of file version.py.

◆ logger

logger = logging.getLogger(__name__)

Definition at line 22 of file version.py.

◆ PEP440_VERSION_RE

PEP440_VERSION_RE
Initial value:
1= re.compile(r'^v?(\d+!)?(\d+(\.\d+)*)((a|b|c|rc)(\d+))?'
2 r'(\.(post)(\d+))?(\.(dev)(\d+))?'
3 r'(\+([a-zA-Z\d]+(\.[a-zA-Z\d]+)?))?$')

Definition at line 179 of file version.py.