Compare commits
1 Commits
develop-20
...
hs/fix/cma
Author | SHA1 | Date | |
---|---|---|---|
![]() |
25c74506a3 |
@@ -2773,6 +2773,22 @@ def prefixes(path):
|
||||
return paths
|
||||
|
||||
|
||||
@system_path_filter
|
||||
def md5sum(file):
|
||||
"""Compute the MD5 sum of a file.
|
||||
|
||||
Args:
|
||||
file (str): file to be checksummed
|
||||
|
||||
Returns:
|
||||
MD5 sum of the file's content
|
||||
"""
|
||||
md5 = hashlib.md5()
|
||||
with open(file, "rb") as f:
|
||||
md5.update(f.read())
|
||||
return md5.digest()
|
||||
|
||||
|
||||
@system_path_filter
|
||||
def remove_directory_contents(dir):
|
||||
"""Remove all contents of a directory."""
|
||||
|
@@ -170,7 +170,7 @@ def get_cmake_prefix_path(pkg: spack.package_base.PackageBase) -> List[str]:
|
||||
edges = traverse.traverse_topo_edges_generator(
|
||||
traverse.with_artificial_edges([pkg.spec]),
|
||||
visitor=traverse.MixedDepthVisitor(
|
||||
direct=dt.BUILD | dt.TEST, transitive=dt.LINK, key=traverse.by_dag_hash
|
||||
direct=dt.BUILD | dt.TEST, transitive=dt.LINK | dt.RUN, key=traverse.by_dag_hash
|
||||
),
|
||||
key=traverse.by_dag_hash,
|
||||
root=False,
|
||||
|
@@ -607,9 +607,6 @@ def test_stringify_version(version_str):
|
||||
v.string = None
|
||||
assert str(v) == version_str
|
||||
|
||||
v.string = None
|
||||
assert v.string == version_str
|
||||
|
||||
|
||||
def test_len():
|
||||
a = Version("1.2.3.4")
|
||||
|
@@ -25,13 +25,11 @@
|
||||
)
|
||||
from .version_types import (
|
||||
ClosedOpenRange,
|
||||
ConcreteVersion,
|
||||
GitVersion,
|
||||
StandardVersion,
|
||||
Version,
|
||||
VersionList,
|
||||
VersionRange,
|
||||
VersionType,
|
||||
_next_version,
|
||||
_prev_version,
|
||||
from_string,
|
||||
@@ -42,23 +40,21 @@
|
||||
any_version: VersionList = VersionList([":"])
|
||||
|
||||
__all__ = [
|
||||
"ClosedOpenRange",
|
||||
"ConcreteVersion",
|
||||
"EmptyRangeError",
|
||||
"GitVersion",
|
||||
"StandardVersion",
|
||||
"Version",
|
||||
"VersionChecksumError",
|
||||
"VersionError",
|
||||
"VersionList",
|
||||
"VersionLookupError",
|
||||
"VersionRange",
|
||||
"VersionType",
|
||||
"_next_version",
|
||||
"_prev_version",
|
||||
"any_version",
|
||||
"from_string",
|
||||
"infinity_versions",
|
||||
"is_git_version",
|
||||
"ver",
|
||||
"from_string",
|
||||
"is_git_version",
|
||||
"infinity_versions",
|
||||
"_prev_version",
|
||||
"_next_version",
|
||||
"VersionList",
|
||||
"ClosedOpenRange",
|
||||
"StandardVersion",
|
||||
"GitVersion",
|
||||
"VersionError",
|
||||
"VersionChecksumError",
|
||||
"VersionLookupError",
|
||||
"EmptyRangeError",
|
||||
"any_version",
|
||||
]
|
||||
|
@@ -3,9 +3,10 @@
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
|
||||
import numbers
|
||||
import re
|
||||
from bisect import bisect_left
|
||||
from typing import Dict, Iterable, Iterator, List, Optional, Tuple, Union
|
||||
from typing import List, Optional, Tuple, Union
|
||||
|
||||
from spack.util.spack_yaml import syaml_dict
|
||||
|
||||
@@ -31,44 +32,26 @@
|
||||
|
||||
|
||||
class VersionStrComponent:
|
||||
"""Internal representation of the string (non-integer) components of Spack versions.
|
||||
|
||||
Versions comprise string and integer components (see ``SEGMENT_REGEX`` above).
|
||||
|
||||
This represents a string component, which is either some component consisting only
|
||||
of alphabetical characters, *or* a special "infinity version" like ``main``,
|
||||
``develop``, ``master``, etc.
|
||||
|
||||
For speed, Spack versions are designed to map to Python tuples, so that we can use
|
||||
Python's fast lexicographic tuple comparison on them. ``VersionStrComponent`` is
|
||||
designed to work as a component in these version tuples, and as such must compare
|
||||
directly with ``int`` or other ``VersionStrComponent`` objects.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ["data"]
|
||||
|
||||
data: Union[int, str]
|
||||
|
||||
def __init__(self, data: Union[int, str]):
|
||||
def __init__(self, data):
|
||||
# int for infinity index, str for literal.
|
||||
self.data = data
|
||||
self.data: Union[int, str] = data
|
||||
|
||||
@staticmethod
|
||||
def from_string(string: str) -> "VersionStrComponent":
|
||||
value: Union[int, str] = string
|
||||
def from_string(string):
|
||||
if len(string) >= iv_min_len:
|
||||
try:
|
||||
value = infinity_versions.index(string)
|
||||
string = infinity_versions.index(string)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
return VersionStrComponent(value)
|
||||
return VersionStrComponent(string)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
def __hash__(self):
|
||||
return hash(self.data)
|
||||
|
||||
def __str__(self) -> str:
|
||||
def __str__(self):
|
||||
return (
|
||||
("infinity" if self.data >= len(infinity_versions) else infinity_versions[self.data])
|
||||
if isinstance(self.data, int)
|
||||
@@ -78,61 +61,38 @@ def __str__(self) -> str:
|
||||
def __repr__(self) -> str:
|
||||
return f'VersionStrComponent("{self}")'
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
def __eq__(self, other):
|
||||
return isinstance(other, VersionStrComponent) and self.data == other.data
|
||||
|
||||
# ignore typing for certain parts of these methods b/c a) they are performance-critical, and
|
||||
# b) mypy isn't smart enough to figure out that if l_inf and r_inf are the same, comparing
|
||||
# self.data and other.data is type safe.
|
||||
def __lt__(self, other: object) -> bool:
|
||||
l_inf = isinstance(self.data, int)
|
||||
def __lt__(self, other):
|
||||
lhs_inf = isinstance(self.data, int)
|
||||
if isinstance(other, int):
|
||||
return not l_inf
|
||||
r_inf = isinstance(other.data, int) # type: ignore
|
||||
return (not l_inf and r_inf) if l_inf ^ r_inf else self.data < other.data # type: ignore
|
||||
return not lhs_inf
|
||||
rhs_inf = isinstance(other.data, int)
|
||||
return (not lhs_inf and rhs_inf) if lhs_inf ^ rhs_inf else self.data < other.data
|
||||
|
||||
def __gt__(self, other: object) -> bool:
|
||||
l_inf = isinstance(self.data, int)
|
||||
if isinstance(other, int):
|
||||
return l_inf
|
||||
r_inf = isinstance(other.data, int) # type: ignore
|
||||
return (l_inf and not r_inf) if l_inf ^ r_inf else self.data > other.data # type: ignore
|
||||
|
||||
def __le__(self, other: object) -> bool:
|
||||
def __le__(self, other):
|
||||
return self < other or self == other
|
||||
|
||||
def __ge__(self, other: object) -> bool:
|
||||
def __gt__(self, other):
|
||||
lhs_inf = isinstance(self.data, int)
|
||||
if isinstance(other, int):
|
||||
return lhs_inf
|
||||
rhs_inf = isinstance(other.data, int)
|
||||
return (lhs_inf and not rhs_inf) if lhs_inf ^ rhs_inf else self.data > other.data
|
||||
|
||||
def __ge__(self, other):
|
||||
return self > other or self == other
|
||||
|
||||
|
||||
# Tuple types that make up the internal representation of StandardVersion.
|
||||
# We use Tuples so that Python can quickly compare versions.
|
||||
|
||||
#: Version components are integers for numeric parts, VersionStrComponents for string parts.
|
||||
VersionComponentTuple = Tuple[Union[int, VersionStrComponent], ...]
|
||||
|
||||
#: A Prerelease identifier is a constant for alpha/beta/rc/final and one optional number.
|
||||
#: Most versions will have this set to ``(FINAL,)``. Prereleases will have some other
|
||||
#: initial constant followed by a number, e.g. ``(RC, 1)``.
|
||||
PrereleaseTuple = Tuple[int, ...]
|
||||
|
||||
#: Actual version tuple, including the split version number itself and the prerelease,
|
||||
#: all represented as tuples.
|
||||
VersionTuple = Tuple[VersionComponentTuple, PrereleaseTuple]
|
||||
|
||||
#: Separators from a parsed version.
|
||||
SeparatorTuple = Tuple[str, ...]
|
||||
|
||||
|
||||
def parse_string_components(string: str) -> Tuple[VersionTuple, SeparatorTuple]:
|
||||
"""Parse a string into a ``VersionTuple`` and ``SeparatorTuple``."""
|
||||
def parse_string_components(string: str) -> Tuple[tuple, tuple]:
|
||||
string = string.strip()
|
||||
|
||||
if string and not VALID_VERSION.match(string):
|
||||
raise ValueError("Bad characters in version string: %s" % string)
|
||||
|
||||
segments = SEGMENT_REGEX.findall(string)
|
||||
separators: Tuple[str] = tuple(m[2] for m in segments)
|
||||
separators = tuple(m[2] for m in segments)
|
||||
prerelease: Tuple[int, ...]
|
||||
|
||||
# <version>(alpha|beta|rc)<number>
|
||||
@@ -149,150 +109,63 @@ def parse_string_components(string: str) -> Tuple[VersionTuple, SeparatorTuple]:
|
||||
else:
|
||||
prerelease = (FINAL,)
|
||||
|
||||
release: VersionComponentTuple = tuple(
|
||||
int(m[0]) if m[0] else VersionStrComponent.from_string(m[1]) for m in segments
|
||||
)
|
||||
release = tuple(int(m[0]) if m[0] else VersionStrComponent.from_string(m[1]) for m in segments)
|
||||
|
||||
return (release, prerelease), separators
|
||||
|
||||
|
||||
class VersionType:
|
||||
"""Base type for all versions in Spack (ranges, lists, regular versions, and git versions).
|
||||
|
||||
Versions in Spack behave like sets, and support some basic set operations. There are
|
||||
four subclasses of ``VersionType``:
|
||||
|
||||
* ``StandardVersion``: a single, concrete version, e.g. 3.4.5 or 5.4b0.
|
||||
* ``GitVersion``: subclass of ``StandardVersion`` for handling git repositories.
|
||||
* ``ClosedOpenRange``: an inclusive version range, closed or open, e.g. ``3.0:5.0``,
|
||||
``3.0:``, or ``:5.0``
|
||||
* ``VersionList``: An ordered list of any of the above types.
|
||||
|
||||
Notably, when Spack parses a version, it's always a range *unless* specified with
|
||||
``@=`` to make it concrete.
|
||||
|
||||
"""
|
||||
|
||||
def intersection(self, other: "VersionType") -> "VersionType":
|
||||
"""Any versions contained in both self and other, or empty VersionList if no overlap."""
|
||||
raise NotImplementedError
|
||||
|
||||
def intersects(self, other: "VersionType") -> bool:
|
||||
"""Whether self and other overlap."""
|
||||
raise NotImplementedError
|
||||
|
||||
def overlaps(self, other: "VersionType") -> bool:
|
||||
"""Whether self and other overlap (same as ``intersects()``)."""
|
||||
return self.intersects(other)
|
||||
|
||||
def satisfies(self, other: "VersionType") -> bool:
|
||||
"""Whether self is entirely contained in other."""
|
||||
raise NotImplementedError
|
||||
|
||||
def union(self, other: "VersionType") -> "VersionType":
|
||||
"""Return a VersionType containing self and other."""
|
||||
raise NotImplementedError
|
||||
|
||||
# We can use SupportsRichComparisonT in Python 3.8 or later, but alas in 3.6 we need
|
||||
# to write all the operators out
|
||||
def __eq__(self, other: object) -> bool:
|
||||
raise NotImplementedError
|
||||
|
||||
def __lt__(self, other: object) -> bool:
|
||||
raise NotImplementedError
|
||||
|
||||
def __gt__(self, other: object) -> bool:
|
||||
raise NotImplementedError
|
||||
|
||||
def __ge__(self, other: object) -> bool:
|
||||
raise NotImplementedError
|
||||
|
||||
def __le__(self, other: object) -> bool:
|
||||
raise NotImplementedError
|
||||
|
||||
def __hash__(self) -> int:
|
||||
raise NotImplementedError
|
||||
class ConcreteVersion:
|
||||
pass
|
||||
|
||||
|
||||
class ConcreteVersion(VersionType):
|
||||
"""Base type for versions that represents a single (non-range or list) version."""
|
||||
|
||||
|
||||
def _stringify_version(versions: VersionTuple, separators: Tuple[str, ...]) -> str:
|
||||
"""Create a string representation from version components."""
|
||||
def _stringify_version(versions: Tuple[tuple, tuple], separators: tuple) -> str:
|
||||
release, prerelease = versions
|
||||
|
||||
components = [f"{rel}{sep}" for rel, sep in zip(release, separators)]
|
||||
string = ""
|
||||
for i in range(len(release)):
|
||||
string += f"{release[i]}{separators[i]}"
|
||||
if prerelease[0] != FINAL:
|
||||
components.append(PRERELEASE_TO_STRING[prerelease[0]])
|
||||
if len(prerelease) > 1:
|
||||
components.append(separators[len(release)])
|
||||
components.append(str(prerelease[1]))
|
||||
|
||||
return "".join(components)
|
||||
string += f"{PRERELEASE_TO_STRING[prerelease[0]]}{separators[len(release)]}"
|
||||
if len(prerelease) > 1:
|
||||
string += str(prerelease[1])
|
||||
return string
|
||||
|
||||
|
||||
class StandardVersion(ConcreteVersion):
|
||||
"""Class to represent versions"""
|
||||
|
||||
__slots__ = ["version", "_string", "separators"]
|
||||
__slots__ = ["version", "string", "separators"]
|
||||
|
||||
_string: str
|
||||
version: VersionTuple
|
||||
separators: Tuple[str, ...]
|
||||
|
||||
def __init__(self, string: str, version: VersionTuple, separators: Tuple[str, ...]):
|
||||
"""Create a StandardVersion from a string and parsed version components.
|
||||
|
||||
Arguments:
|
||||
string: The original version string, or ``""`` if the it is not available.
|
||||
version: A tuple as returned by ``parse_string_components()``. Contains two tuples:
|
||||
one with alpha or numeric components and another with prerelease components.
|
||||
separators: separators parsed from the original version string.
|
||||
|
||||
If constructed with ``string=""``, the string will be lazily constructed from components
|
||||
when ``str()`` is called.
|
||||
"""
|
||||
self._string = string
|
||||
def __init__(self, string: Optional[str], version: Tuple[tuple, tuple], separators: tuple):
|
||||
self.string = string
|
||||
self.version = version
|
||||
self.separators = separators
|
||||
|
||||
@staticmethod
|
||||
def from_string(string: str) -> "StandardVersion":
|
||||
def from_string(string: str):
|
||||
return StandardVersion(string, *parse_string_components(string))
|
||||
|
||||
@staticmethod
|
||||
def typemin() -> "StandardVersion":
|
||||
def typemin():
|
||||
return _STANDARD_VERSION_TYPEMIN
|
||||
|
||||
@staticmethod
|
||||
def typemax() -> "StandardVersion":
|
||||
def typemax():
|
||||
return _STANDARD_VERSION_TYPEMAX
|
||||
|
||||
@property
|
||||
def string(self) -> str:
|
||||
if not self._string:
|
||||
self._string = _stringify_version(self.version, self.separators)
|
||||
return self._string
|
||||
|
||||
@string.setter
|
||||
def string(self, string) -> None:
|
||||
self._string = string
|
||||
|
||||
def __bool__(self) -> bool:
|
||||
def __bool__(self):
|
||||
return True
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, StandardVersion):
|
||||
return self.version == other.version
|
||||
return False
|
||||
|
||||
def __ne__(self, other: object) -> bool:
|
||||
def __ne__(self, other):
|
||||
if isinstance(other, StandardVersion):
|
||||
return self.version != other.version
|
||||
return True
|
||||
|
||||
def __lt__(self, other: object) -> bool:
|
||||
def __lt__(self, other):
|
||||
if isinstance(other, StandardVersion):
|
||||
return self.version < other.version
|
||||
if isinstance(other, ClosedOpenRange):
|
||||
@@ -300,7 +173,7 @@ def __lt__(self, other: object) -> bool:
|
||||
return self <= other.lo
|
||||
return NotImplemented
|
||||
|
||||
def __le__(self, other: object) -> bool:
|
||||
def __le__(self, other):
|
||||
if isinstance(other, StandardVersion):
|
||||
return self.version <= other.version
|
||||
if isinstance(other, ClosedOpenRange):
|
||||
@@ -308,7 +181,7 @@ def __le__(self, other: object) -> bool:
|
||||
return self <= other.lo
|
||||
return NotImplemented
|
||||
|
||||
def __ge__(self, other: object) -> bool:
|
||||
def __ge__(self, other):
|
||||
if isinstance(other, StandardVersion):
|
||||
return self.version >= other.version
|
||||
if isinstance(other, ClosedOpenRange):
|
||||
@@ -316,25 +189,25 @@ def __ge__(self, other: object) -> bool:
|
||||
return self > other.lo
|
||||
return NotImplemented
|
||||
|
||||
def __gt__(self, other: object) -> bool:
|
||||
def __gt__(self, other):
|
||||
if isinstance(other, StandardVersion):
|
||||
return self.version > other.version
|
||||
if isinstance(other, ClosedOpenRange):
|
||||
return self > other.lo
|
||||
return NotImplemented
|
||||
|
||||
def __iter__(self) -> Iterator:
|
||||
def __iter__(self):
|
||||
return iter(self.version[0])
|
||||
|
||||
def __len__(self) -> int:
|
||||
def __len__(self):
|
||||
return len(self.version[0])
|
||||
|
||||
def __getitem__(self, idx: Union[int, slice]):
|
||||
def __getitem__(self, idx):
|
||||
cls = type(self)
|
||||
|
||||
release = self.version[0]
|
||||
|
||||
if isinstance(idx, int):
|
||||
if isinstance(idx, numbers.Integral):
|
||||
return release[idx]
|
||||
|
||||
elif isinstance(idx, slice):
|
||||
@@ -347,38 +220,45 @@ def __getitem__(self, idx: Union[int, slice]):
|
||||
|
||||
if string_arg:
|
||||
string_arg.pop() # We don't need the last separator
|
||||
return cls.from_string("".join(string_arg))
|
||||
string_arg = "".join(string_arg)
|
||||
return cls.from_string(string_arg)
|
||||
else:
|
||||
return StandardVersion.from_string("")
|
||||
|
||||
raise TypeError(f"{cls.__name__} indices must be integers or slices")
|
||||
message = "{cls.__name__} indices must be integers"
|
||||
raise TypeError(message.format(cls=cls))
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.string
|
||||
def __str__(self):
|
||||
return self.string or _stringify_version(self.version, self.separators)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
# Print indirect repr through Version(...)
|
||||
return f'Version("{str(self)}")'
|
||||
|
||||
def __hash__(self) -> int:
|
||||
def __hash__(self):
|
||||
# If this is a final release, do not hash the prerelease part for backward compat.
|
||||
return hash(self.version if self.is_prerelease() else self.version[0])
|
||||
|
||||
def __contains__(rhs, lhs) -> bool:
|
||||
def __contains__(rhs, lhs):
|
||||
# We should probably get rid of `x in y` for versions, since
|
||||
# versions still have a dual interpretation as singleton sets
|
||||
# or elements. x in y should be: is the lhs-element in the
|
||||
# rhs-set. Instead this function also does subset checks.
|
||||
if isinstance(lhs, VersionType):
|
||||
if isinstance(lhs, (StandardVersion, ClosedOpenRange, VersionList)):
|
||||
return lhs.satisfies(rhs)
|
||||
raise TypeError(f"'in' not supported for instances of {type(lhs)}")
|
||||
raise ValueError(lhs)
|
||||
|
||||
def intersects(self, other: VersionType) -> bool:
|
||||
def intersects(self, other: Union["StandardVersion", "GitVersion", "ClosedOpenRange"]) -> bool:
|
||||
if isinstance(other, StandardVersion):
|
||||
return self == other
|
||||
return other.intersects(self)
|
||||
|
||||
def satisfies(self, other: VersionType) -> bool:
|
||||
def overlaps(self, other) -> bool:
|
||||
return self.intersects(other)
|
||||
|
||||
def satisfies(
|
||||
self, other: Union["ClosedOpenRange", "StandardVersion", "GitVersion", "VersionList"]
|
||||
) -> bool:
|
||||
if isinstance(other, GitVersion):
|
||||
return False
|
||||
|
||||
@@ -391,19 +271,19 @@ def satisfies(self, other: VersionType) -> bool:
|
||||
if isinstance(other, VersionList):
|
||||
return other.intersects(self)
|
||||
|
||||
raise NotImplementedError
|
||||
return NotImplemented
|
||||
|
||||
def union(self, other: VersionType) -> VersionType:
|
||||
def union(self, other: Union["ClosedOpenRange", "StandardVersion"]):
|
||||
if isinstance(other, StandardVersion):
|
||||
return self if self == other else VersionList([self, other])
|
||||
return other.union(self)
|
||||
|
||||
def intersection(self, other: VersionType) -> VersionType:
|
||||
def intersection(self, other: Union["ClosedOpenRange", "StandardVersion"]):
|
||||
if isinstance(other, StandardVersion):
|
||||
return self if self == other else VersionList()
|
||||
return other.intersection(self)
|
||||
|
||||
def isdevelop(self) -> bool:
|
||||
def isdevelop(self):
|
||||
"""Triggers on the special case of the `@develop-like` version."""
|
||||
return any(
|
||||
isinstance(p, VersionStrComponent) and isinstance(p.data, int) for p in self.version[0]
|
||||
@@ -424,7 +304,7 @@ def dotted_numeric_string(self) -> str:
|
||||
return ".".join(str(v) for v in numeric)
|
||||
|
||||
@property
|
||||
def dotted(self) -> "StandardVersion":
|
||||
def dotted(self):
|
||||
"""The dotted representation of the version.
|
||||
|
||||
Example:
|
||||
@@ -438,7 +318,7 @@ def dotted(self) -> "StandardVersion":
|
||||
return type(self).from_string(self.string.replace("-", ".").replace("_", "."))
|
||||
|
||||
@property
|
||||
def underscored(self) -> "StandardVersion":
|
||||
def underscored(self):
|
||||
"""The underscored representation of the version.
|
||||
|
||||
Example:
|
||||
@@ -453,7 +333,7 @@ def underscored(self) -> "StandardVersion":
|
||||
return type(self).from_string(self.string.replace(".", "_").replace("-", "_"))
|
||||
|
||||
@property
|
||||
def dashed(self) -> "StandardVersion":
|
||||
def dashed(self):
|
||||
"""The dashed representation of the version.
|
||||
|
||||
Example:
|
||||
@@ -467,7 +347,7 @@ def dashed(self) -> "StandardVersion":
|
||||
return type(self).from_string(self.string.replace(".", "-").replace("_", "-"))
|
||||
|
||||
@property
|
||||
def joined(self) -> "StandardVersion":
|
||||
def joined(self):
|
||||
"""The joined representation of the version.
|
||||
|
||||
Example:
|
||||
@@ -482,7 +362,7 @@ def joined(self) -> "StandardVersion":
|
||||
self.string.replace(".", "").replace("-", "").replace("_", "")
|
||||
)
|
||||
|
||||
def up_to(self, index: int) -> "StandardVersion":
|
||||
def up_to(self, index):
|
||||
"""The version up to the specified component.
|
||||
|
||||
Examples:
|
||||
@@ -602,7 +482,7 @@ def ref_version(self) -> StandardVersion:
|
||||
)
|
||||
return self._ref_version
|
||||
|
||||
def intersects(self, other: VersionType) -> bool:
|
||||
def intersects(self, other):
|
||||
# For concrete things intersects = satisfies = equality
|
||||
if isinstance(other, GitVersion):
|
||||
return self == other
|
||||
@@ -612,14 +492,19 @@ def intersects(self, other: VersionType) -> bool:
|
||||
return self.ref_version.intersects(other)
|
||||
if isinstance(other, VersionList):
|
||||
return any(self.intersects(rhs) for rhs in other)
|
||||
raise TypeError(f"'intersects()' not supported for instances of {type(other)}")
|
||||
raise ValueError(f"Unexpected type {type(other)}")
|
||||
|
||||
def intersection(self, other: VersionType) -> VersionType:
|
||||
def intersection(self, other):
|
||||
if isinstance(other, ConcreteVersion):
|
||||
return self if self == other else VersionList()
|
||||
return other.intersection(self)
|
||||
|
||||
def satisfies(self, other: VersionType) -> bool:
|
||||
def overlaps(self, other) -> bool:
|
||||
return self.intersects(other)
|
||||
|
||||
def satisfies(
|
||||
self, other: Union["GitVersion", StandardVersion, "ClosedOpenRange", "VersionList"]
|
||||
):
|
||||
# Concrete versions mean we have to do an equality check
|
||||
if isinstance(other, GitVersion):
|
||||
return self == other
|
||||
@@ -629,9 +514,9 @@ def satisfies(self, other: VersionType) -> bool:
|
||||
return self.ref_version.satisfies(other)
|
||||
if isinstance(other, VersionList):
|
||||
return any(self.satisfies(rhs) for rhs in other)
|
||||
raise TypeError(f"'satisfies()' not supported for instances of {type(other)}")
|
||||
raise ValueError(f"Unexpected type {type(other)}")
|
||||
|
||||
def __str__(self) -> str:
|
||||
def __str__(self):
|
||||
s = f"git.{self.ref}" if self.has_git_prefix else self.ref
|
||||
# Note: the solver actually depends on str(...) to produce the effective version.
|
||||
# So when a lookup is attached, we require the resolved version to be printed.
|
||||
@@ -649,7 +534,7 @@ def __repr__(self):
|
||||
def __bool__(self):
|
||||
return True
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
def __eq__(self, other):
|
||||
# GitVersion cannot be equal to StandardVersion, otherwise == is not transitive
|
||||
return (
|
||||
isinstance(other, GitVersion)
|
||||
@@ -657,10 +542,10 @@ def __eq__(self, other: object) -> bool:
|
||||
and self.ref_version == other.ref_version
|
||||
)
|
||||
|
||||
def __ne__(self, other: object) -> bool:
|
||||
def __ne__(self, other):
|
||||
return not self == other
|
||||
|
||||
def __lt__(self, other: object) -> bool:
|
||||
def __lt__(self, other):
|
||||
if isinstance(other, GitVersion):
|
||||
return (self.ref_version, self.ref) < (other.ref_version, other.ref)
|
||||
if isinstance(other, StandardVersion):
|
||||
@@ -668,9 +553,9 @@ def __lt__(self, other: object) -> bool:
|
||||
return self.ref_version < other
|
||||
if isinstance(other, ClosedOpenRange):
|
||||
return self.ref_version < other
|
||||
raise TypeError(f"'<' not supported between instances of {type(self)} and {type(other)}")
|
||||
raise ValueError(f"Unexpected type {type(other)}")
|
||||
|
||||
def __le__(self, other: object) -> bool:
|
||||
def __le__(self, other):
|
||||
if isinstance(other, GitVersion):
|
||||
return (self.ref_version, self.ref) <= (other.ref_version, other.ref)
|
||||
if isinstance(other, StandardVersion):
|
||||
@@ -679,9 +564,9 @@ def __le__(self, other: object) -> bool:
|
||||
if isinstance(other, ClosedOpenRange):
|
||||
# Equality is not a thing
|
||||
return self.ref_version < other
|
||||
raise TypeError(f"'<=' not supported between instances of {type(self)} and {type(other)}")
|
||||
raise ValueError(f"Unexpected type {type(other)}")
|
||||
|
||||
def __ge__(self, other: object) -> bool:
|
||||
def __ge__(self, other):
|
||||
if isinstance(other, GitVersion):
|
||||
return (self.ref_version, self.ref) >= (other.ref_version, other.ref)
|
||||
if isinstance(other, StandardVersion):
|
||||
@@ -689,9 +574,9 @@ def __ge__(self, other: object) -> bool:
|
||||
return self.ref_version >= other
|
||||
if isinstance(other, ClosedOpenRange):
|
||||
return self.ref_version > other
|
||||
raise TypeError(f"'>=' not supported between instances of {type(self)} and {type(other)}")
|
||||
raise ValueError(f"Unexpected type {type(other)}")
|
||||
|
||||
def __gt__(self, other: object) -> bool:
|
||||
def __gt__(self, other):
|
||||
if isinstance(other, GitVersion):
|
||||
return (self.ref_version, self.ref) > (other.ref_version, other.ref)
|
||||
if isinstance(other, StandardVersion):
|
||||
@@ -699,14 +584,14 @@ def __gt__(self, other: object) -> bool:
|
||||
return self.ref_version >= other
|
||||
if isinstance(other, ClosedOpenRange):
|
||||
return self.ref_version > other
|
||||
raise TypeError(f"'>' not supported between instances of {type(self)} and {type(other)}")
|
||||
raise ValueError(f"Unexpected type {type(other)}")
|
||||
|
||||
def __hash__(self):
|
||||
# hashing should not cause version lookup
|
||||
return hash(self.ref)
|
||||
|
||||
def __contains__(self, other: object) -> bool:
|
||||
raise NotImplementedError
|
||||
def __contains__(self, other):
|
||||
raise Exception("Not implemented yet")
|
||||
|
||||
@property
|
||||
def ref_lookup(self):
|
||||
@@ -764,7 +649,7 @@ def up_to(self, index) -> StandardVersion:
|
||||
return self.ref_version.up_to(index)
|
||||
|
||||
|
||||
class ClosedOpenRange(VersionType):
|
||||
class ClosedOpenRange:
|
||||
def __init__(self, lo: StandardVersion, hi: StandardVersion):
|
||||
if hi < lo:
|
||||
raise EmptyRangeError(f"{lo}..{hi} is an empty range")
|
||||
@@ -772,14 +657,14 @@ def __init__(self, lo: StandardVersion, hi: StandardVersion):
|
||||
self.hi: StandardVersion = hi
|
||||
|
||||
@classmethod
|
||||
def from_version_range(cls, lo: StandardVersion, hi: StandardVersion) -> "ClosedOpenRange":
|
||||
def from_version_range(cls, lo: StandardVersion, hi: StandardVersion):
|
||||
"""Construct ClosedOpenRange from lo:hi range."""
|
||||
try:
|
||||
return ClosedOpenRange(lo, _next_version(hi))
|
||||
except EmptyRangeError as e:
|
||||
raise EmptyRangeError(f"{lo}:{hi} is an empty range") from e
|
||||
|
||||
def __str__(self) -> str:
|
||||
def __str__(self):
|
||||
# This simplifies 3.1:<3.2 to 3.1:3.1 to 3.1
|
||||
# 3:3 -> 3
|
||||
hi_prev = _prev_version(self.hi)
|
||||
@@ -841,9 +726,9 @@ def __gt__(self, other):
|
||||
def __contains__(rhs, lhs):
|
||||
if isinstance(lhs, (ConcreteVersion, ClosedOpenRange, VersionList)):
|
||||
return lhs.satisfies(rhs)
|
||||
raise TypeError(f"'in' not supported between instances of {type(rhs)} and {type(lhs)}")
|
||||
raise ValueError(f"Unexpected type {type(lhs)}")
|
||||
|
||||
def intersects(self, other: VersionType) -> bool:
|
||||
def intersects(self, other: Union[ConcreteVersion, "ClosedOpenRange", "VersionList"]):
|
||||
if isinstance(other, StandardVersion):
|
||||
return self.lo <= other < self.hi
|
||||
if isinstance(other, GitVersion):
|
||||
@@ -852,18 +737,23 @@ def intersects(self, other: VersionType) -> bool:
|
||||
return (self.lo < other.hi) and (other.lo < self.hi)
|
||||
if isinstance(other, VersionList):
|
||||
return any(self.intersects(rhs) for rhs in other)
|
||||
raise TypeError(f"'intersects' not supported for instances of {type(other)}")
|
||||
raise ValueError(f"Unexpected type {type(other)}")
|
||||
|
||||
def satisfies(self, other: VersionType) -> bool:
|
||||
def satisfies(self, other: Union["ClosedOpenRange", ConcreteVersion, "VersionList"]):
|
||||
if isinstance(other, ConcreteVersion):
|
||||
return False
|
||||
if isinstance(other, ClosedOpenRange):
|
||||
return not (self.lo < other.lo or other.hi < self.hi)
|
||||
if isinstance(other, VersionList):
|
||||
return any(self.satisfies(rhs) for rhs in other)
|
||||
raise TypeError(f"'satisfies()' not supported for instances of {type(other)}")
|
||||
raise ValueError(other)
|
||||
|
||||
def _union_if_not_disjoint(self, other: VersionType) -> Optional["ClosedOpenRange"]:
|
||||
def overlaps(self, other: Union["ClosedOpenRange", ConcreteVersion, "VersionList"]) -> bool:
|
||||
return self.intersects(other)
|
||||
|
||||
def _union_if_not_disjoint(
|
||||
self, other: Union["ClosedOpenRange", ConcreteVersion]
|
||||
) -> Optional["ClosedOpenRange"]:
|
||||
"""Same as union, but returns None when the union is not connected. This function is not
|
||||
implemented for version lists as right-hand side, as that makes little sense."""
|
||||
if isinstance(other, StandardVersion):
|
||||
@@ -880,9 +770,9 @@ def _union_if_not_disjoint(self, other: VersionType) -> Optional["ClosedOpenRang
|
||||
else None
|
||||
)
|
||||
|
||||
raise TypeError(f"'union()' not supported for instances of {type(other)}")
|
||||
raise TypeError(f"Unexpected type {type(other)}")
|
||||
|
||||
def union(self, other: VersionType) -> VersionType:
|
||||
def union(self, other: Union["ClosedOpenRange", ConcreteVersion, "VersionList"]):
|
||||
if isinstance(other, VersionList):
|
||||
v = other.copy()
|
||||
v.add(self)
|
||||
@@ -891,51 +781,35 @@ def union(self, other: VersionType) -> VersionType:
|
||||
result = self._union_if_not_disjoint(other)
|
||||
return result if result is not None else VersionList([self, other])
|
||||
|
||||
def intersection(self, other: VersionType) -> VersionType:
|
||||
def intersection(self, other: Union["ClosedOpenRange", ConcreteVersion]):
|
||||
# range - version -> singleton or nothing.
|
||||
if isinstance(other, ClosedOpenRange):
|
||||
# range - range -> range or nothing.
|
||||
max_lo = max(self.lo, other.lo)
|
||||
min_hi = min(self.hi, other.hi)
|
||||
return ClosedOpenRange(max_lo, min_hi) if max_lo < min_hi else VersionList()
|
||||
|
||||
if isinstance(other, ConcreteVersion):
|
||||
return other if self.intersects(other) else VersionList()
|
||||
|
||||
raise TypeError(f"'intersection()' not supported for instances of {type(other)}")
|
||||
# range - range -> range or nothing.
|
||||
max_lo = max(self.lo, other.lo)
|
||||
min_hi = min(self.hi, other.hi)
|
||||
return ClosedOpenRange(max_lo, min_hi) if max_lo < min_hi else VersionList()
|
||||
|
||||
|
||||
class VersionList(VersionType):
|
||||
class VersionList:
|
||||
"""Sorted, non-redundant list of Version and ClosedOpenRange elements."""
|
||||
|
||||
versions: List[VersionType]
|
||||
|
||||
def __init__(self, vlist: Optional[Union[str, VersionType, Iterable]] = None):
|
||||
def __init__(self, vlist=None):
|
||||
self.versions: List[Union[StandardVersion, GitVersion, ClosedOpenRange]] = []
|
||||
if vlist is None:
|
||||
self.versions = []
|
||||
|
||||
pass
|
||||
elif isinstance(vlist, str):
|
||||
vlist = from_string(vlist)
|
||||
if isinstance(vlist, VersionList):
|
||||
self.versions = vlist.versions
|
||||
else:
|
||||
self.versions = [vlist]
|
||||
|
||||
elif isinstance(vlist, (ConcreteVersion, ClosedOpenRange)):
|
||||
self.versions = [vlist]
|
||||
|
||||
elif isinstance(vlist, VersionList):
|
||||
self.versions = vlist[:]
|
||||
|
||||
elif isinstance(vlist, Iterable):
|
||||
self.versions = []
|
||||
else:
|
||||
for v in vlist:
|
||||
self.add(ver(v))
|
||||
|
||||
else:
|
||||
raise TypeError(f"Cannot construct VersionList from {type(vlist)}")
|
||||
|
||||
def add(self, item: VersionType) -> None:
|
||||
def add(self, item: Union[StandardVersion, GitVersion, ClosedOpenRange, "VersionList"]):
|
||||
if isinstance(item, (StandardVersion, GitVersion)):
|
||||
i = bisect_left(self, item)
|
||||
# Only insert when prev and next are not intersected.
|
||||
@@ -991,7 +865,7 @@ def concrete_range_as_version(self) -> Optional[ConcreteVersion]:
|
||||
return v.lo
|
||||
return None
|
||||
|
||||
def copy(self) -> "VersionList":
|
||||
def copy(self):
|
||||
return VersionList(self)
|
||||
|
||||
def lowest(self) -> Optional[StandardVersion]:
|
||||
@@ -1015,7 +889,7 @@ def preferred(self) -> Optional[StandardVersion]:
|
||||
"""Get the preferred (latest) version in the list."""
|
||||
return self.highest_numeric() or self.highest()
|
||||
|
||||
def satisfies(self, other: VersionType) -> bool:
|
||||
def satisfies(self, other) -> bool:
|
||||
# This exploits the fact that version lists are "reduced" and normalized, so we can
|
||||
# never have a list like [1:3, 2:4] since that would be normalized to [1:4]
|
||||
if isinstance(other, VersionList):
|
||||
@@ -1024,9 +898,9 @@ def satisfies(self, other: VersionType) -> bool:
|
||||
if isinstance(other, (ConcreteVersion, ClosedOpenRange)):
|
||||
return all(lhs.satisfies(other) for lhs in self)
|
||||
|
||||
raise TypeError(f"'satisfies()' not supported for instances of {type(other)}")
|
||||
raise ValueError(f"Unsupported type {type(other)}")
|
||||
|
||||
def intersects(self, other: VersionType) -> bool:
|
||||
def intersects(self, other):
|
||||
if isinstance(other, VersionList):
|
||||
s = o = 0
|
||||
while s < len(self) and o < len(other):
|
||||
@@ -1041,16 +915,19 @@ def intersects(self, other: VersionType) -> bool:
|
||||
if isinstance(other, (ClosedOpenRange, StandardVersion)):
|
||||
return any(v.intersects(other) for v in self)
|
||||
|
||||
raise TypeError(f"'intersects()' not supported for instances of {type(other)}")
|
||||
raise ValueError(f"Unsupported type {type(other)}")
|
||||
|
||||
def to_dict(self) -> Dict:
|
||||
def overlaps(self, other) -> bool:
|
||||
return self.intersects(other)
|
||||
|
||||
def to_dict(self):
|
||||
"""Generate human-readable dict for YAML."""
|
||||
if self.concrete:
|
||||
return syaml_dict([("version", str(self[0]))])
|
||||
return syaml_dict([("versions", [str(v) for v in self])])
|
||||
|
||||
@staticmethod
|
||||
def from_dict(dictionary) -> "VersionList":
|
||||
def from_dict(dictionary):
|
||||
"""Parse dict from to_dict."""
|
||||
if "versions" in dictionary:
|
||||
return VersionList(dictionary["versions"])
|
||||
@@ -1058,29 +935,27 @@ def from_dict(dictionary) -> "VersionList":
|
||||
return VersionList([Version(dictionary["version"])])
|
||||
raise ValueError("Dict must have 'version' or 'versions' in it.")
|
||||
|
||||
def update(self, other: "VersionList") -> None:
|
||||
self.add(other)
|
||||
def update(self, other: "VersionList"):
|
||||
for v in other.versions:
|
||||
self.add(v)
|
||||
|
||||
def union(self, other: VersionType) -> VersionType:
|
||||
def union(self, other: "VersionList"):
|
||||
result = self.copy()
|
||||
result.add(other)
|
||||
result.update(other)
|
||||
return result
|
||||
|
||||
def intersection(self, other: VersionType) -> "VersionList":
|
||||
def intersection(self, other: "VersionList") -> "VersionList":
|
||||
result = VersionList()
|
||||
if isinstance(other, VersionList):
|
||||
for lhs, rhs in ((self, other), (other, self)):
|
||||
for x in lhs:
|
||||
i = bisect_left(rhs.versions, x)
|
||||
if i > 0:
|
||||
result.add(rhs[i - 1].intersection(x))
|
||||
if i < len(rhs):
|
||||
result.add(rhs[i].intersection(x))
|
||||
return result
|
||||
else:
|
||||
return self.intersection(VersionList(other))
|
||||
for lhs, rhs in ((self, other), (other, self)):
|
||||
for x in lhs:
|
||||
i = bisect_left(rhs.versions, x)
|
||||
if i > 0:
|
||||
result.add(rhs[i - 1].intersection(x))
|
||||
if i < len(rhs):
|
||||
result.add(rhs[i].intersection(x))
|
||||
return result
|
||||
|
||||
def intersect(self, other: VersionType) -> bool:
|
||||
def intersect(self, other) -> bool:
|
||||
"""Intersect this spec's list with other.
|
||||
|
||||
Return True if the spec changed as a result; False otherwise
|
||||
@@ -1090,7 +965,6 @@ def intersect(self, other: VersionType) -> bool:
|
||||
self.versions = isection.versions
|
||||
return changed
|
||||
|
||||
# typing this and getitem are a pain in Python 3.6
|
||||
def __contains__(self, other):
|
||||
if isinstance(other, (ClosedOpenRange, StandardVersion)):
|
||||
i = bisect_left(self, other)
|
||||
@@ -1104,52 +978,52 @@ def __contains__(self, other):
|
||||
def __getitem__(self, index):
|
||||
return self.versions[index]
|
||||
|
||||
def __iter__(self) -> Iterator:
|
||||
def __iter__(self):
|
||||
return iter(self.versions)
|
||||
|
||||
def __reversed__(self) -> Iterator:
|
||||
def __reversed__(self):
|
||||
return reversed(self.versions)
|
||||
|
||||
def __len__(self) -> int:
|
||||
def __len__(self):
|
||||
return len(self.versions)
|
||||
|
||||
def __bool__(self) -> bool:
|
||||
def __bool__(self):
|
||||
return bool(self.versions)
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, VersionList):
|
||||
return self.versions == other.versions
|
||||
return False
|
||||
|
||||
def __ne__(self, other) -> bool:
|
||||
def __ne__(self, other):
|
||||
if isinstance(other, VersionList):
|
||||
return self.versions != other.versions
|
||||
return False
|
||||
|
||||
def __lt__(self, other) -> bool:
|
||||
def __lt__(self, other):
|
||||
if isinstance(other, VersionList):
|
||||
return self.versions < other.versions
|
||||
return NotImplemented
|
||||
|
||||
def __le__(self, other) -> bool:
|
||||
def __le__(self, other):
|
||||
if isinstance(other, VersionList):
|
||||
return self.versions <= other.versions
|
||||
return NotImplemented
|
||||
|
||||
def __ge__(self, other) -> bool:
|
||||
def __ge__(self, other):
|
||||
if isinstance(other, VersionList):
|
||||
return self.versions >= other.versions
|
||||
return NotImplemented
|
||||
|
||||
def __gt__(self, other) -> bool:
|
||||
def __gt__(self, other):
|
||||
if isinstance(other, VersionList):
|
||||
return self.versions > other.versions
|
||||
return NotImplemented
|
||||
|
||||
def __hash__(self) -> int:
|
||||
def __hash__(self):
|
||||
return hash(tuple(self.versions))
|
||||
|
||||
def __str__(self) -> str:
|
||||
def __str__(self):
|
||||
if not self.versions:
|
||||
return ""
|
||||
|
||||
@@ -1157,7 +1031,7 @@ def __str__(self) -> str:
|
||||
f"={v}" if isinstance(v, StandardVersion) else str(v) for v in self.versions
|
||||
)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
def __repr__(self):
|
||||
return str(self.versions)
|
||||
|
||||
|
||||
@@ -1232,10 +1106,12 @@ def _next_version(v: StandardVersion) -> StandardVersion:
|
||||
release = release[:-1] + (_next_version_str_component(release[-1]),)
|
||||
else:
|
||||
release = release[:-1] + (release[-1] + 1,)
|
||||
|
||||
# Avoid constructing a string here for performance. Instead, pass "" to
|
||||
# StandardVersion to lazily stringify.
|
||||
return StandardVersion("", (release, prerelease), separators)
|
||||
components = [""] * (2 * len(release))
|
||||
components[::2] = release
|
||||
components[1::2] = separators[: len(release)]
|
||||
if prerelease_type != FINAL:
|
||||
components.extend((PRERELEASE_TO_STRING[prerelease_type], prerelease[1]))
|
||||
return StandardVersion("".join(str(c) for c in components), (release, prerelease), separators)
|
||||
|
||||
|
||||
def _prev_version(v: StandardVersion) -> StandardVersion:
|
||||
@@ -1254,15 +1130,19 @@ def _prev_version(v: StandardVersion) -> StandardVersion:
|
||||
release = release[:-1] + (_prev_version_str_component(release[-1]),)
|
||||
else:
|
||||
release = release[:-1] + (release[-1] - 1,)
|
||||
components = [""] * (2 * len(release))
|
||||
components[::2] = release
|
||||
components[1::2] = separators[: len(release)]
|
||||
if prerelease_type != FINAL:
|
||||
components.extend((PRERELEASE_TO_STRING[prerelease_type], *prerelease[1:]))
|
||||
|
||||
# Avoid constructing a string here for performance. Instead, pass "" to
|
||||
# StandardVersion to lazily stringify.
|
||||
return StandardVersion("", (release, prerelease), separators)
|
||||
# this is only used for comparison functions, so don't bother making a string
|
||||
return StandardVersion(None, (release, prerelease), separators)
|
||||
|
||||
|
||||
def Version(string: Union[str, int]) -> ConcreteVersion:
|
||||
def Version(string: Union[str, int]) -> Union[GitVersion, StandardVersion]:
|
||||
if not isinstance(string, (str, int)):
|
||||
raise TypeError(f"Cannot construct a version from {type(string)}")
|
||||
raise ValueError(f"Cannot construct a version from {type(string)}")
|
||||
string = str(string)
|
||||
if is_git_version(string):
|
||||
return GitVersion(string)
|
||||
@@ -1275,7 +1155,7 @@ def VersionRange(lo: Union[str, StandardVersion], hi: Union[str, StandardVersion
|
||||
return ClosedOpenRange.from_version_range(lo, hi)
|
||||
|
||||
|
||||
def from_string(string: str) -> VersionType:
|
||||
def from_string(string) -> Union[VersionList, ClosedOpenRange, StandardVersion, GitVersion]:
|
||||
"""Converts a string to a version object. This is private. Client code should use ver()."""
|
||||
string = string.replace(" ", "")
|
||||
|
||||
@@ -1304,17 +1184,17 @@ def from_string(string: str) -> VersionType:
|
||||
return VersionRange(v, v)
|
||||
|
||||
|
||||
def ver(obj: Union[VersionType, str, list, tuple, int, float]) -> VersionType:
|
||||
def ver(obj) -> Union[VersionList, ClosedOpenRange, StandardVersion, GitVersion]:
|
||||
"""Parses a Version, VersionRange, or VersionList from a string
|
||||
or list of strings.
|
||||
"""
|
||||
if isinstance(obj, VersionType):
|
||||
return obj
|
||||
if isinstance(obj, (list, tuple)):
|
||||
return VersionList(obj)
|
||||
elif isinstance(obj, str):
|
||||
return from_string(obj)
|
||||
elif isinstance(obj, (list, tuple)):
|
||||
return VersionList(obj)
|
||||
elif isinstance(obj, (int, float)):
|
||||
return from_string(str(obj))
|
||||
elif isinstance(obj, (StandardVersion, GitVersion, ClosedOpenRange, VersionList)):
|
||||
return obj
|
||||
else:
|
||||
raise TypeError("ver() can't convert %s to version!" % type(obj))
|
||||
|
@@ -41,9 +41,6 @@ class Fpm(Package):
|
||||
depends_on("curl", type="build")
|
||||
depends_on("git@1.8.5:", type="build")
|
||||
|
||||
depends_on("c", type="build")
|
||||
depends_on("fortran", type="build")
|
||||
|
||||
def setup_build_environment(self, env):
|
||||
if self.spec.satisfies("@0.4.0"):
|
||||
env.set("FPM_C_COMPILER", self.compiler.cc)
|
||||
|
@@ -406,71 +406,44 @@ class Gcc(AutotoolsPackage, GNUMirrorPackage, CompilerPackage):
|
||||
when="@11.2.0",
|
||||
)
|
||||
|
||||
# aarch64-darwin support from Iain Sandoe's branch
|
||||
# Apple M1 support, created from branch of Darwin maintainer for GCC:
|
||||
# https://github.com/iains/gcc-11-branch
|
||||
patch(
|
||||
"https://github.com/iains/gcc-14-branch/compare/04696df09633baf97cdbbdd6e9929b9d472161d3..gcc-14.2-darwin-r2.patch?full_index=1",
|
||||
sha256="01ea668489f3f0fb2439060f6c333c4c17ef4c19c4c4e6e6aa4b8ea493e97685",
|
||||
when="@14.2.0 target=aarch64:",
|
||||
"https://raw.githubusercontent.com/Homebrew/formula-patches/22dec3fc/gcc/gcc-11.3.0-arm.diff",
|
||||
sha256="e02006b7ec917cc1390645d95735a6a866caed0dfe506d5bef742f7862cab218",
|
||||
when="@11.3.0 target=aarch64:",
|
||||
)
|
||||
# https://github.com/iains/gcc-12-branch
|
||||
patch(
|
||||
"https://raw.githubusercontent.com/Homebrew/formula-patches/76677f2b/gcc/gcc-12.1.0-arm.diff",
|
||||
sha256="a000f1d9cb1dd98c7c4ef00df31435cd5d712d2f9d037ddc044f8bf82a16cf35",
|
||||
when="@12.1.0 target=aarch64:",
|
||||
)
|
||||
patch(
|
||||
"https://github.com/iains/gcc-14-branch/compare/cd0059a1976303638cea95f216de129334fc04d1..gcc-14.1-darwin-r1.patch?full_index=1",
|
||||
sha256="159cc2a1077ad5d9a3cca87880cd977b8202d8fb464a6ec7b53804475d21a682",
|
||||
when="@14.1.0 target=aarch64:",
|
||||
)
|
||||
|
||||
patch(
|
||||
"https://github.com/iains/gcc-13-branch/compare/b71f1de6e9cf7181a288c0f39f9b1ef6580cf5c8..gcc-13.3-darwin-r1.patch?full_index=1",
|
||||
sha256="d957520afc286ac46aa3c4bf9b64618d02ca0bf1466f32321b5d6beec6a396eb",
|
||||
when="@13.3.0 target=aarch64:",
|
||||
)
|
||||
patch(
|
||||
"https://github.com/iains/gcc-13-branch/compare/c891d8dc23e1a46ad9f3e757d09e57b500d40044..gcc-13.2-darwin-r0.patch?full_index=1",
|
||||
sha256="6a49d1074d7dd2e3b76e61613a0f143c668ed648fb8d9d48ed76a6b127815c88",
|
||||
when="@13.2.0 target=aarch64:",
|
||||
)
|
||||
patch(
|
||||
"https://github.com/iains/gcc-13-branch/compare/cc035c5d8672f87dc8c2756d9f8367903aa72d93..gcc-13.1-darwin-r0.patch?full_index=1",
|
||||
sha256="36d2c04d487edb6792b48dedae6936f8b864b6f969bd3fd03763e072d471c022",
|
||||
when="@13.1.0 target=aarch64:",
|
||||
)
|
||||
|
||||
patch(
|
||||
"https://github.com/iains/gcc-12-branch/compare/2bada4bc59bed4be34fab463bdb3c3ebfd2b41bb..gcc-12.4-darwin-r0.patch?full_index=1",
|
||||
sha256="e242adf240a62ed3005da75a9e304bda980b84ce497f124b4bddc819ee821e2a",
|
||||
when="@12.4.0 target=aarch64:",
|
||||
)
|
||||
patch(
|
||||
"https://github.com/iains/gcc-12-branch/compare/8fc1a49c9312b05d925b7d21f1d2145d70818151..gcc-12.3-darwin-r0.patch?full_index=1",
|
||||
sha256="1ebac2010eb9ced33cf46a8d8378193671ed6830f262219aa3428de5bc9fd668",
|
||||
when="@12.3.0 target=aarch64:",
|
||||
)
|
||||
patch(
|
||||
"https://github.com/iains/gcc-12-branch/compare/2ee5e4300186a92ad73f1a1a64cb918dc76c8d67..gcc-12.2-darwin-r0.patch?full_index=1",
|
||||
sha256="16d5203ddb97cd43d6c1e9c34e0f681154aed1d127f2324b2a50006b92960cfd",
|
||||
"https://raw.githubusercontent.com/Homebrew/formula-patches/1d184289/gcc/gcc-12.2.0-arm.diff",
|
||||
sha256="a7843b5c6bf1401e40c20c72af69c8f6fc9754ae980bb4a5f0540220b3dcb62d",
|
||||
when="@12.2.0 target=aarch64:",
|
||||
)
|
||||
patch(
|
||||
"https://github.com/iains/gcc-12-branch/compare/1ea978e3066ac565a1ec28a96a4d61eaf38e2726..gcc-12.1-darwin-r1.patch?full_index=1",
|
||||
sha256="b0a811e33c3451ebd1882eac4e2b4b32ce0b60cfa0b8ccf8c5fda7b24327c820",
|
||||
when="@12.1.0 target=aarch64:",
|
||||
)
|
||||
|
||||
patch(
|
||||
"https://github.com/iains/gcc-11-branch/compare/5cc4c42a0d4de08715c2eef8715ad5b2e92a23b6..gcc-11.5-darwin-r0.patch?full_index=1",
|
||||
sha256="6c92190a9acabd6be13bd42ca675f59f44be050a7121214abeaea99d898db30c",
|
||||
when="@11.5.0 target=aarch64:",
|
||||
"https://raw.githubusercontent.com/Homebrew/formula-patches/5c206c47/gcc/gcc-13.1.0.diff",
|
||||
sha256="cb4e8a89387f748a744da0273025d0dc2e3c76780cc390b18ada704676afea11",
|
||||
when="@13.1.0 target=aarch64:",
|
||||
)
|
||||
patch(
|
||||
"https://github.com/iains/gcc-11-branch/compare/ff4bf326d03e750a8d4905ea49425fe7d15a04b8..gcc-11.4-darwin-r0.patch?full_index=1",
|
||||
sha256="05810e5cdb052c06490f7d987c66a13d47ae7bd2eb285a3a881ad4aa6dd0d13f",
|
||||
when="@11.4.0 target=aarch64:",
|
||||
"https://raw.githubusercontent.com/Homebrew/formula-patches/3c5cbc8e9cf444a1967786af48e430588e1eb481/gcc/gcc-13.2.0.diff",
|
||||
sha256="2df7ef067871a30b2531a2013b3db661ec9e61037341977bfc451e30bf2c1035",
|
||||
when="@13.2.0 target=aarch64:",
|
||||
)
|
||||
patch(
|
||||
"https://github.com/iains/gcc-11-branch/compare/2d280e7eafc086e9df85f50ed1a6526d6a3a204d..gcc-11.3-darwin-r2.patch?full_index=1",
|
||||
sha256="a8097c232dfb21b0e02f3d99e3c3e47443db3982dafbb584938ac1a9a4afd33d",
|
||||
when="@11.3.0 target=aarch64:",
|
||||
"https://raw.githubusercontent.com/Homebrew/formula-patches/82b5c1cd38826ab67ac7fc498a8fe74376a40f4a/gcc/gcc-14.1.0.diff",
|
||||
sha256="1529cff128792fe197ede301a81b02036c8168cb0338df21e4bc7aafe755305a",
|
||||
when="@14.1.0 target=aarch64:",
|
||||
)
|
||||
patch(
|
||||
"https://raw.githubusercontent.com/Homebrew/formula-patches/f30c309442a60cfb926e780eae5d70571f8ab2cb/gcc/gcc-14.2.0-r2.diff",
|
||||
sha256="6c0a4708f35ccf2275e6401197a491e3ad77f9f0f9ef5761860768fa6da14d3d",
|
||||
when="@14.2.0 target=aarch64:",
|
||||
)
|
||||
|
||||
conflicts("+bootstrap", when="@11.3.0,13.1: target=aarch64:")
|
||||
|
||||
# Use -headerpad_max_install_names in the build,
|
||||
|
@@ -46,8 +46,7 @@ class MiopenHip(CMakePackage):
|
||||
conflicts("+asan", when="os=centos7")
|
||||
conflicts("+asan", when="os=centos8")
|
||||
|
||||
depends_on("c", type="build")
|
||||
depends_on("cxx", type="build")
|
||||
depends_on("cxx", type="build") # generated
|
||||
|
||||
depends_on("cmake@3.5:", type="build")
|
||||
depends_on("pkgconfig", type="build")
|
||||
|
@@ -2,7 +2,6 @@
|
||||
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||
#
|
||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||
import os
|
||||
|
||||
from spack.package import *
|
||||
|
||||
@@ -51,35 +50,3 @@ def setup_build_environment(self, env):
|
||||
def cythonize(self):
|
||||
with working_dir(self.build_directory):
|
||||
python(join_path("conf", "cythonize.py"))
|
||||
|
||||
def create_mpi_config_file(self, cfg_fn):
|
||||
"""
|
||||
create mpi.cfg file introduced since version 4.0.0.
|
||||
see https://mpi4py.readthedocs.io/en/stable/mpi4py.html#mpi4py.get_config
|
||||
"""
|
||||
mpi_spec = self.spec["mpi"]
|
||||
include_dirs = mpi_spec.headers.directories
|
||||
library_dirs = mpi_spec.libs.directories
|
||||
with open(cfg_fn, "w") as cfg:
|
||||
cfg.write("[mpi]\n")
|
||||
cfg.write("mpi_dir = {}\n".format(mpi_spec.prefix))
|
||||
cfg.write("mpicc = {}\n".format(mpi_spec.mpicc))
|
||||
cfg.write("mpicxx = {}\n".format(mpi_spec.mpicxx))
|
||||
cfg.write("\n")
|
||||
cfg.write("## define_macros =\n")
|
||||
cfg.write("## undef_macros =\n")
|
||||
cfg.write("include_dirs = {}\n".format(include_dirs))
|
||||
cfg.write("## libraries = mpi\n")
|
||||
cfg.write("library_dirs = {}\n".format(library_dirs))
|
||||
cfg.write("## runtime_library_dirs = %(mpi_dir)s/lib\n")
|
||||
cfg.write("\n")
|
||||
cfg.write("## extra_compile_args =\n")
|
||||
cfg.write("## extra_link_args =\n")
|
||||
cfg.write("## extra_objects =\n")
|
||||
|
||||
@run_after("install", when="@4:")
|
||||
def install_cfg(self):
|
||||
python_dir = join_path(self.prefix, python_platlib, "mpi4py")
|
||||
cfg_fn = join_path(python_dir, "mpi.cfg")
|
||||
if not os.path.isfile(cfg_fn):
|
||||
self.create_mpi_config_file(cfg_fn)
|
||||
|
@@ -12,10 +12,7 @@ class PyNbdime(PythonPackage):
|
||||
homepage = "https://nbdime.readthedocs.io/"
|
||||
pypi = "nbdime/nbdime-3.1.1.tar.gz"
|
||||
|
||||
version("3.2.1", sha256="31409a30f848ffc6b32540697e82d5a0a1b84dcc32716ca74e78bcc4b457c453")
|
||||
with default_args(deprecated=True):
|
||||
# https://nvd.nist.gov/vuln/detail/CVE-2021-41134
|
||||
version("3.1.1", sha256="67767320e971374f701a175aa59abd3a554723039d39fae908e72d16330d648b")
|
||||
version("3.1.1", sha256="67767320e971374f701a175aa59abd3a554723039d39fae908e72d16330d648b")
|
||||
|
||||
depends_on("python@3.6:", type=("build", "run"))
|
||||
depends_on("py-setuptools@40.8.0:", type="build")
|
||||
|
@@ -25,12 +25,6 @@ class PyPip(Package, PythonExtension):
|
||||
|
||||
license("MIT")
|
||||
|
||||
version("24.3.1", sha256="3790624780082365f47549d032f3770eeb2b1e8bd1f7b2e02dace1afa361b4ed")
|
||||
version("24.2", sha256="2cd581cf58ab7fcfca4ce8efa6dcacd0de5bf8d0a3eb9ec927e07405f4d9e2a2")
|
||||
version("24.1.2", sha256="7cd207eed4c60b0f411b444cd1464198fe186671c323b6cd6d433ed80fc9d247")
|
||||
version("24.0", sha256="ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc")
|
||||
version("23.3.2", sha256="5052d7889c1f9d05224cd41741acb7c5d6fa735ab34e339624a614eaaa7e7d76")
|
||||
version("23.2.1", sha256="7ccf472345f20d35bdc9d1841ff5f313260c2c33fe417f48c30ac46cccabf5be")
|
||||
version("23.1.2", sha256="3ef6ac33239e4027d9a5598a381b9d30880a1477e50039db2eac6e8a8f6d1b18")
|
||||
version("23.0", sha256="b5f88adff801f5ef052bcdef3daa31b55eb67b0fccd6d0106c206fa248e0463c")
|
||||
version("22.2.2", sha256="b61a374b5bc40a6e982426aede40c9b5a08ff20e640f5b56977f4f91fed1e39a")
|
||||
@@ -46,7 +40,6 @@ class PyPip(Package, PythonExtension):
|
||||
version("9.0.1", sha256="690b762c0a8460c303c089d5d0be034fb15a5ea2b75bdf565f40421f542fefb0")
|
||||
|
||||
extends("python")
|
||||
depends_on("python@3.8:", when="@24.1:", type=("build", "run"))
|
||||
depends_on("python@3.7:", when="@22:", type=("build", "run"))
|
||||
|
||||
# Uses collections.MutableMapping
|
||||
|
@@ -16,7 +16,6 @@ class PyRuff(PythonPackage):
|
||||
license("MIT")
|
||||
maintainers("adamjstewart")
|
||||
|
||||
version("0.8.1", sha256="3583db9a6450364ed5ca3f3b4225958b24f78178908d5c4bc0f46251ccca898f")
|
||||
version("0.8.0", sha256="a7ccfe6331bf8c8dad715753e157457faf7351c2b69f62f32c165c2dbcbacd44")
|
||||
version("0.6.5", sha256="4d32d87fab433c0cf285c3683dd4dae63be05fd7a1d65b3f5bf7cdd05a6b96fb")
|
||||
version("0.5.7", sha256="8dfc0a458797f5d9fb622dd0efc52d796f23f0a1493a9527f4e49a550ae9a7e5")
|
||||
|
@@ -21,8 +21,7 @@ class PyTorchSparse(PythonPackage):
|
||||
version("0.6.8", sha256="312fb5ae6e4e575fca4bbc0bd092af85e7679d5b8e53459f24492fc2a073c7b6")
|
||||
version("0.6.7", sha256="f69b2ed35baf2a9853234756a2b19e6f7ce88d2c1f029d1c7ca166d91e1adbd0")
|
||||
|
||||
depends_on("c", type="build")
|
||||
depends_on("cxx", type="build")
|
||||
depends_on("cxx", type="build") # generated
|
||||
|
||||
depends_on("py-setuptools", type="build")
|
||||
depends_on("py-scipy", type=("build", "run"))
|
||||
|
@@ -87,15 +87,14 @@ class Vtk(CMakePackage):
|
||||
|
||||
conflicts("%gcc@13", when="@9.2")
|
||||
|
||||
# Based on PyPI wheel availability
|
||||
with when("+python"), default_args(type=("build", "link", "run")):
|
||||
depends_on("python@:3.13")
|
||||
depends_on("python@:3.12", when="@:9.3")
|
||||
depends_on("python@:3.11", when="@:9.2")
|
||||
depends_on("python@:3.10", when="@:9.2.2")
|
||||
depends_on("python@:3.9", when="@:9.1")
|
||||
depends_on("python@:3.8", when="@:9.0.1")
|
||||
depends_on("python@:3.7", when="@:8.2.0")
|
||||
with when("+python"):
|
||||
# Depend on any Python, add bounds below.
|
||||
extends("python@2.7:", type=("build", "run"))
|
||||
depends_on("python@:3.7", when="@:8.2.0", type=("build", "run"))
|
||||
# Python 3.8 support from vtk 9 and patched 8.2
|
||||
depends_on("python@:3.8", when="@:8.2.1a", type=("build", "run"))
|
||||
# Python 3.10 support from vtk 9.2
|
||||
depends_on("python@:3.9", when="@:9.1", type=("build", "run"))
|
||||
|
||||
# We need mpi4py if buidling python wrappers and using MPI
|
||||
depends_on("py-mpi4py", when="+python+mpi", type="run")
|
||||
|
Reference in New Issue
Block a user