Skip to content

Commit d0cac1b

Browse files
committed
Subclassed version of Version that supports -platform
1 parent 4c6d100 commit d0cac1b

File tree

1 file changed

+124
-1
lines changed

1 file changed

+124
-1
lines changed

libtmux/_compat.py

+124-1
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,13 @@ def str_from_console(s):
2828

2929

3030
try:
31+
import collections
32+
import functools
3133
import re
3234
from typing import Iterator, List, Tuple
3335

34-
from packaging.version import Version, _BaseVersion
36+
from packaging import version as V
37+
from packaging.version import VERSION_PATTERN, Version, _BaseVersion
3538

3639
###
3740
### Legacy support for LooseVersion / LegacyVersion, e.g. 2.4-openbsd
@@ -127,6 +130,126 @@ def base_version(self) -> str:
127130
def epoch(self) -> int:
128131
return -1
129132

133+
@functools.total_ordering
134+
class _VersionCmpMixin:
135+
# Credit: @layday
136+
# Link: https://github.com/pypa/packaging/issues/465#issuecomment-1013715662
137+
def __eq__(self, other: object) -> bool:
138+
if isinstance(other, str):
139+
other = self.__class__(other)
140+
return super().__eq__(other)
141+
142+
def __lt__(self, other: object) -> bool:
143+
if isinstance(other, str):
144+
other = self.__class__(other)
145+
return super().__lt__(other)
146+
147+
_Version = collections.namedtuple(
148+
"_Version", ["epoch", "release", "dev", "pre", "post", "local", "platform"]
149+
)
150+
151+
def _cmpkey(
152+
epoch, # type: int
153+
release, # type: Tuple[int, ...]
154+
pre, # type: Optional[Tuple[str, int]]
155+
post, # type: Optional[Tuple[str, int]]
156+
dev, # type: Optional[Tuple[str, int]]
157+
local, # type: Optional[Tuple[SubLocalType]]
158+
platform, # type: Optional[Tuple[SubLocalType]]
159+
):
160+
return V._cmpkey(epoch, release, pre, post, dev, local) + (
161+
tuple(
162+
(i, "") if isinstance(i, int) else (V.NegativeInfinity, i)
163+
for i in platform
164+
)
165+
)
166+
167+
class LegacyVersion(Version):
168+
_regex = re.compile
169+
_regex = re.compile(
170+
r"^\s*"
171+
+ VERSION_PATTERN
172+
+ r"(?:(?P<platform>(?:[-_\.][a-z0-9]+)*))? # platform version"
173+
+ r"\s*$",
174+
re.VERBOSE | re.IGNORECASE,
175+
)
176+
177+
def __init__(self, version):
178+
# type: (str) -> None
179+
180+
# Validate the version and parse it into pieces
181+
match = self._regex.search(version)
182+
if not match:
183+
raise V.InvalidVersion("Invalid version: '{0}'".format(version))
184+
185+
# Store the parsed out pieces of the version
186+
self._version = _Version(
187+
epoch=int(match.group("epoch")) if match.group("epoch") else 0,
188+
release=tuple(int(i) for i in match.group("release").split(".")),
189+
pre=V._parse_letter_version(match.group("pre_l"), match.group("pre_n")),
190+
post=V._parse_letter_version(
191+
match.group("post_l"),
192+
match.group("post_n1") or match.group("post_n2"),
193+
),
194+
dev=V._parse_letter_version(match.group("dev_l"), match.group("dev_n")),
195+
local=V._parse_local_version(match.group("local")),
196+
platform=str(match.group("platform"))
197+
if match.group("platform")
198+
else "",
199+
)
200+
201+
# Generate a key which will be used for sorting
202+
self._key = _cmpkey(
203+
self._version.epoch,
204+
self._version.release,
205+
self._version.pre,
206+
self._version.post,
207+
self._version.dev,
208+
self._version.local,
209+
self._version.platform,
210+
)
211+
212+
@property
213+
def platform(self):
214+
# type: () -> Optional[str]
215+
if self._version.platform:
216+
return ".".join(str(x) for x in self._version.platform)
217+
else:
218+
return None
219+
220+
def __str__(self):
221+
# type: () -> str
222+
parts = []
223+
224+
# Epoch
225+
if self.epoch != 0:
226+
parts.append("{0}!".format(self.epoch))
227+
228+
# Release segment
229+
parts.append(".".join(str(x) for x in self.release))
230+
231+
# Pre-release
232+
if self.pre is not None:
233+
parts.append("".join(str(x) for x in self.pre))
234+
235+
# Post-release
236+
if self.post is not None:
237+
parts.append(".post{0}".format(self.post))
238+
239+
# Development release
240+
if self.dev is not None:
241+
parts.append(".dev{0}".format(self.dev))
242+
243+
# Local version segment
244+
if self.local is not None:
245+
parts.append("+{0}".format(self.local))
246+
247+
# Platform version segment
248+
if self.platform is not None:
249+
parts.append("_{0}".format(self.platform))
250+
251+
return "".join(parts)
252+
130253
LooseVersion = LegacyVersion
131254
except ImportError:
132255
from distutils.version import LooseVersion, Version

0 commit comments

Comments
 (0)