From 28cf27362be65968385564b4989271815a1b5e88 Mon Sep 17 00:00:00 2001 From: Antoine Prouvost Date: Thu, 31 Jul 2025 10:02:55 +0200 Subject: [PATCH] Add missing MatchSpec equality operator (#4033) --- .../include/mamba/specs/build_number_spec.hpp | 11 ++------- libmamba/include/mamba/specs/match_spec.hpp | 24 +++++++------------ libmambapy/src/libmambapy/bindings/specs.cpp | 2 ++ libmambapy/tests/test_specs.py | 2 ++ 4 files changed, 14 insertions(+), 25 deletions(-) diff --git a/libmamba/include/mamba/specs/build_number_spec.hpp b/libmamba/include/mamba/specs/build_number_spec.hpp index a547ac7ff..ea0324245 100644 --- a/libmamba/include/mamba/specs/build_number_spec.hpp +++ b/libmamba/include/mamba/specs/build_number_spec.hpp @@ -124,16 +124,9 @@ namespace mamba::specs */ [[nodiscard]] auto contains(BuildNumber point) const -> bool; - // TODO(C++20): replace by the `= default` implementation of `operator==` - [[nodiscard]] auto operator==(const BuildNumberSpec& other) const -> bool - { - return m_predicate == other.m_predicate; - } + [[nodiscard]] auto operator==(const BuildNumberSpec& other) const -> bool = default; - [[nodiscard]] auto operator!=(const BuildNumberSpec& other) const -> bool - { - return !(*this == other); - } + [[nodiscard]] auto operator!=(const BuildNumberSpec& other) const -> bool = default; private: diff --git a/libmamba/include/mamba/specs/match_spec.hpp b/libmamba/include/mamba/specs/match_spec.hpp index 63d5430b0..943d86b7d 100644 --- a/libmamba/include/mamba/specs/match_spec.hpp +++ b/libmamba/include/mamba/specs/match_spec.hpp @@ -23,7 +23,6 @@ #include "mamba/specs/version_spec.hpp" #include "mamba/util/flat_set.hpp" #include "mamba/util/heap_optional.hpp" -#include "mamba/util/tuple_hash.hpp" namespace mamba::specs { @@ -142,22 +141,15 @@ namespace mamba::specs */ [[nodiscard]] auto contains_except_channel(const PackageInfo& pkg) const -> bool; - // TODO(C++20): replace by the `= default` implementation of `operator==` - [[nodiscard]] auto operator==(const MatchSpec& other) const -> bool - { - return m_channel == other.m_channel // - && m_version == other.m_version // - && m_name == other.m_name // - && m_build_string == other.m_build_string // - && m_name_space == other.m_name_space // - && m_build_number == other.m_build_number // - && m_extra == other.m_extra; - } + /** + * Naive attribute-wise comparison. + * + * @warning Some complex matchspec could compare to false but actually represent the same + * set of packages. This strong equality is hard to detect. + */ + [[nodiscard]] auto operator==(const MatchSpec& other) const -> bool = default; - [[nodiscard]] auto operator!=(const MatchSpec& other) const -> bool - { - return !(*this == other); - } + [[nodiscard]] auto operator!=(const MatchSpec& other) const -> bool = default; auto extra_members_hash() const -> std::size_t; diff --git a/libmambapy/src/libmambapy/bindings/specs.cpp b/libmambapy/src/libmambapy/bindings/specs.cpp index 34f02101b..21aca3dd0 100644 --- a/libmambapy/src/libmambapy/bindings/specs.cpp +++ b/libmambapy/src/libmambapy/bindings/specs.cpp @@ -897,6 +897,8 @@ namespace mambapy .def("is_simple", &MatchSpec::is_simple) .def("is_only_package_name", &MatchSpec::is_only_package_name) .def("conda_build_form", &MatchSpec::conda_build_form) + .def(py::self == py::self) + .def(py::self != py::self) .def("__str__", &MatchSpec::to_string) .def("__copy__", ©) .def("__deepcopy__", &deepcopy, py::arg("memo")); diff --git a/libmambapy/tests/test_specs.py b/libmambapy/tests/test_specs.py index 67490a612..314e0acbf 100644 --- a/libmambapy/tests/test_specs.py +++ b/libmambapy/tests/test_specs.py @@ -932,6 +932,8 @@ def test_MatchSpec(): assert ms.is_file() assert str(ms.name) == "pkg" assert ms.filename == "pkg-2-bld.conda" + assert ms == ms + assert ms != MatchSpec.parse("foo") # Errors with pytest.raises(libmambapy.specs.ParseError):