Skip to content

Commit 9f269a3

Browse files
committed
Vendorize LegacyVersion behavior for patterns like "2.4-openbsd"
We still need those to work - not to break pypi conformance, but since we use this for tmux versions.
1 parent 1a6efb2 commit 9f269a3

File tree

1 file changed

+93
-1
lines changed

1 file changed

+93
-1
lines changed

libtmux/_compat.py

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,98 @@ def str_from_console(s):
2828

2929

3030
try:
31-
from packaging.version import LegacyVersion as LooseVersion, Version
31+
import re
32+
33+
from packaging.version import Version, _BaseVersion
34+
35+
###
36+
### Legacy support for LooseVersion / LegacyVersion, e.g. 2.4-openbsd
37+
### https://github.com/pypa/packaging/blob/21.3/packaging/version.py#L106-L115
38+
### License: BSD, Accessed: Jan 14th, 2022
39+
###
40+
41+
_legacy_version_component_re = re.compile(r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE)
42+
_legacy_version_replacement_map = {
43+
"pre": "c",
44+
"preview": "c",
45+
"-": "final-",
46+
"rc": "c",
47+
"dev": "@",
48+
}
49+
50+
def _parse_version_parts(s):
51+
# type: (str) -> Iterator[str]
52+
for part in _legacy_version_component_re.split(s):
53+
part = _legacy_version_replacement_map.get(part, part)
54+
55+
if not part or part == ".":
56+
continue
57+
58+
if part[:1] in "0123456789":
59+
# pad for numeric comparison
60+
yield part.zfill(8)
61+
else:
62+
yield "*" + part
63+
64+
# ensure that alpha/beta/candidate are before final
65+
yield "*final"
66+
67+
def _legacy_cmpkey(version):
68+
# type: (str) -> LegacyCmpKey
69+
70+
# We hardcode an epoch of -1 here. A PEP 440 version can only have a epoch
71+
# greater than or equal to 0. This will effectively put the LegacyVersion,
72+
# which uses the defacto standard originally implemented by setuptools,
73+
# as before all PEP 440 versions.
74+
epoch = -1
75+
76+
# This scheme is taken from pkg_resources.parse_version setuptools prior to
77+
# it's adoption of the packaging library.
78+
parts = [] # type: List[str]
79+
for part in _parse_version_parts(version.lower()):
80+
if part.startswith("*"):
81+
# remove "-" before a prerelease tag
82+
if part < "*final":
83+
while parts and parts[-1] == "*final-":
84+
parts.pop()
85+
86+
# remove trailing zeros from each series of numeric parts
87+
while parts and parts[-1] == "00000000":
88+
parts.pop()
89+
90+
parts.append(part)
91+
92+
return epoch, tuple(parts)
93+
94+
class LegacyVersion(_BaseVersion):
95+
def __init__(self, version):
96+
# type: (str) -> None
97+
self._version = str(version)
98+
self._key = _legacy_cmpkey(self._version)
99+
100+
def __str__(self):
101+
# type: () -> str
102+
return self._version
103+
104+
def __repr__(self):
105+
# type: () -> str
106+
return "<LegacyVersion({0})>".format(repr(str(self)))
107+
108+
@property
109+
def public(self):
110+
# type: () -> str
111+
return self._version
112+
113+
@property
114+
def base_version(self):
115+
# type: () -> str
116+
return self._version
117+
118+
@property
119+
def epoch(self):
120+
# type: () -> int
121+
return -1
122+
123+
LooseVersion = LegacyVersion
32124
except ImportError:
33125
from distutils.version import LooseVersion, Version

0 commit comments

Comments
 (0)