From 8decb45cb3ee05ea5187fec3d6912d6bbd1d39dc Mon Sep 17 00:00:00 2001 From: Hal <13111745+loonghao@users.noreply.github.com> Date: Sun, 14 Apr 2024 03:10:42 +0800 Subject: [PATCH] Fix error caused by weakly referenced package not specifying version range (#1712) Signed-off-by: loonghao --- .../2.0/package.py | 4 ++++ .../2.0/package.py | 6 +++++ src/rez/package_order.py | 22 ++++++++++++------- src/rez/tests/test_completion.py | 3 ++- src/rez/tests/test_packages.py | 4 +++- src/rez/tests/test_solver.py | 17 ++++++++++++++ 6 files changed, 46 insertions(+), 10 deletions(-) create mode 100644 src/rez/data/tests/solver/packages/test_weakly_reference_requires/2.0/package.py create mode 100644 src/rez/data/tests/solver/packages/test_weakly_reference_variant/2.0/package.py diff --git a/src/rez/data/tests/solver/packages/test_weakly_reference_requires/2.0/package.py b/src/rez/data/tests/solver/packages/test_weakly_reference_requires/2.0/package.py new file mode 100644 index 000000000..39740bc9b --- /dev/null +++ b/src/rez/data/tests/solver/packages/test_weakly_reference_requires/2.0/package.py @@ -0,0 +1,4 @@ +name = "test_weakly_reference_requires" +version = "2.0" + +requires = ["~test_variant_split_mid1", "~test_variant_split_mid2"] diff --git a/src/rez/data/tests/solver/packages/test_weakly_reference_variant/2.0/package.py b/src/rez/data/tests/solver/packages/test_weakly_reference_variant/2.0/package.py new file mode 100644 index 000000000..92f704037 --- /dev/null +++ b/src/rez/data/tests/solver/packages/test_weakly_reference_variant/2.0/package.py @@ -0,0 +1,6 @@ +name = "test_weakly_reference_variant" +version = "2.0" + +requires = ["~pyfoo"] + +variants = [["test_variant_split_mid1", "~test_variant_split_mid2-1..3"]] diff --git a/src/rez/package_order.py b/src/rez/package_order.py index a71dbac02..e60662d77 100644 --- a/src/rez/package_order.py +++ b/src/rez/package_order.py @@ -116,8 +116,9 @@ def sort_key(self, package_name, version_like): Args: package_name: (str) The family name of the package we are sorting - version_like: (Version|_LowerBound|_UpperBound|_Bound|VersionRange) - the version-like object you wish to generate a key for + version_like: (Version|_LowerBound|_UpperBound|_Bound|VersionRange|None) + The version-like object to be used as a basis for generating a sort key. + Note that 'None' is also a supported value, which maintains the default sorting order. Returns: Sortable object @@ -126,21 +127,26 @@ def sort_key(self, package_name, version_like): """ if isinstance(version_like, VersionRange): return tuple(self.sort_key(package_name, bound) for bound in version_like.bounds) - elif isinstance(version_like, _Bound): + if isinstance(version_like, _Bound): return (self.sort_key(package_name, version_like.lower), self.sort_key(package_name, version_like.upper)) - elif isinstance(version_like, _LowerBound): + if isinstance(version_like, _LowerBound): inclusion_key = -2 if version_like.inclusive else -1 return self.sort_key(package_name, version_like.version), inclusion_key - elif isinstance(version_like, _UpperBound): + if isinstance(version_like, _UpperBound): inclusion_key = 2 if version_like.inclusive else 1 return self.sort_key(package_name, version_like.version), inclusion_key - elif isinstance(version_like, Version): + if isinstance(version_like, Version): # finally, the bit that we actually use the sort_key_implementation for. return FallbackComparable( self.sort_key_implementation(package_name, version_like), version_like) - else: - raise TypeError(version_like) + if version_like is None: + # As no version range is provided for this package, + # Python's sort preserves the order of equal elements. + # Thus, to maintain the original order, + # we return the same object for all None values. + return 0 + raise TypeError(version_like) def sort_key_implementation(self, package_name, version): """Returns a sort key usable for sorting these packages within the diff --git a/src/rez/tests/test_completion.py b/src/rez/tests/test_completion.py index ef8c390c6..f87629903 100644 --- a/src/rez/tests/test_completion.py +++ b/src/rez/tests/test_completion.py @@ -52,7 +52,8 @@ def _eq(prefix, expected_completions): _eq("", ["bahish", "nada", "nopy", "pybah", "pydad", "pyfoo", "pymum", "pyodd", "pyson", "pysplit", "python", "pyvariants", "test_variant_split_start", "test_variant_split_mid1", - "test_variant_split_mid2", "test_variant_split_end", "missing_variant_requires"]) + "test_variant_split_mid2", "test_variant_split_end", "missing_variant_requires", + "test_weakly_reference_requires", "test_weakly_reference_variant"]) _eq("py", ["pybah", "pydad", "pyfoo", "pymum", "pyodd", "pyson", "pysplit", "python", "pyvariants"]) _eq("pys", ["pyson", "pysplit"]) diff --git a/src/rez/tests/test_packages.py b/src/rez/tests/test_packages.py index 55f5254c6..5e42b0eaf 100644 --- a/src/rez/tests/test_packages.py +++ b/src/rez/tests/test_packages.py @@ -58,7 +58,9 @@ 'timestamped-1.0.5', 'timestamped-1.0.6', 'timestamped-1.1.0', 'timestamped-1.1.1', 'timestamped-1.2.0', 'timestamped-2.0.0', 'timestamped-2.1.0', 'timestamped-2.1.5', 'multi-1.0', 'multi-1.1', 'multi-1.2', 'multi-2.0', - 'missing_variant_requires-1' + 'missing_variant_requires-1', + 'test_weakly_reference_requires-2.0', + 'test_weakly_reference_variant-2.0', ]) diff --git a/src/rez/tests/test_solver.py b/src/rez/tests/test_solver.py index 4c9d44266..11c3c4ce9 100644 --- a/src/rez/tests/test_solver.py +++ b/src/rez/tests/test_solver.py @@ -256,6 +256,23 @@ def test_12_missing_variant_requires(self): config.override("error_on_missing_variant_requires", False) self._solve(["missing_variant_requires"], ["nada[]", "missing_variant_requires-1[1]"]) + def test_13_resolve_weakly_reference_requires(self): + """Test resolving a package with a weakly referenced requirement.""" + self._solve(["test_weakly_reference_requires", "test_variant_split_mid2-2"], + ['test_weakly_reference_requires-2.0[]', + 'test_variant_split_end-3.0[0]', + 'test_variant_split_mid2-2.0[1]']) + + def test_14_resolve_weakly_reference_variant(self): + """Test resolving a package with a weakly referenced variant.""" + self._solve(["test_weakly_reference_variant-2.0", "test_variant_split_mid2-2", "pyfoo"], + ['test_variant_split_end-1.0[1]', + 'test_variant_split_mid1-1.0[1]', + 'test_weakly_reference_variant-2.0[0]', + 'test_variant_split_mid2-2.0[0]', + 'python-2.6.8[]', + 'pyfoo-3.1.0[]']) + if __name__ == '__main__': unittest.main()