diff --git a/include/aidge/backend/OperatorImpl.hpp b/include/aidge/backend/OperatorImpl.hpp
index 4af7da64ebca3c02eb9aabca1f2dad88fd8b9829..649898dd130d5811f65f65af87bc117d3502647c 100644
--- a/include/aidge/backend/OperatorImpl.hpp
+++ b/include/aidge/backend/OperatorImpl.hpp
@@ -28,7 +28,7 @@ class Operator;
 
 /**
  * @brief ImplSpec stores the requirements or the specifications of an implementation.
- * 
+ *
  */
 struct ImplSpec {
     struct IOSpec {
@@ -73,10 +73,15 @@ inline bool operator<(const ImplSpec& lhs, const ImplSpec& rhs) {
         || (lhs.inputs == rhs.inputs && lhs.outputs == rhs.outputs && lhs.attrs < rhs.attrs);
 }
 
+
+inline bool operator==(const ImplSpec& lhs, const ImplSpec& rhs) {
+    return !(lhs < rhs) && !(rhs < lhs);
+}
+
 /**
  * @brief Impl stores the details of a specific implementation.
  * It is associated to a ImplSpec in a registry.
- * 
+ *
  */
 template <class FwdFunc, class BwdFunc>
 struct Impl {
@@ -108,7 +113,7 @@ public:
     /**
      * @brief Get the operator required implementation specification, according
      * to the current operator configuration.
-     * 
+     *
      */
     ImplSpec getRequiredSpec() const;
 
@@ -116,15 +121,15 @@ public:
      * @brief Get the best implementation that matches \p requiredSpecs.
      * If no implementation matches \p requiredSpecs, \p requiredSpecs is
      * returned.
-     * 
+     *
      */
     ImplSpec getBestMatch(const ImplSpec& requiredSpecs) const;
 
     /**
-     * @brief Get an adapted meta operator corresponding to the required 
+     * @brief Get an adapted meta operator corresponding to the required
      * specifications \p requiredSpecs from the implementation specifications
      * \p spec.
-     * 
+     *
      * @param spec Implementation specification
      * @param requiredSpecs Required specifications
      * @return std::shared_ptr<Node> Adapted meta op or nullptr
@@ -132,12 +137,12 @@ public:
     std::shared_ptr<Node> getAdaptation(const ImplSpec& spec, const ImplSpec& requiredSpecs) const;
 
     /**
-     * @brief Get the best adapted meta operator corresponding to the required 
+     * @brief Get the best adapted meta operator corresponding to the required
      * specifications \p requiredSpecs.
      * The best adaptation is the one with the lowest overhead cost.
-     * Currently, it is the one requiring the least number of additionnal 
+     * Currently, it is the one requiring the least number of additionnal
      * operators to match the available implementations.
-     * 
+     *
      * @param requiredSpecs Required specifications
      * @return std::shared_ptr<Node> Adapted meta op or nullptr
      */
@@ -147,7 +152,7 @@ public:
 
 protected:
     virtual std::shared_ptr<ProdConso> getProdConso() const;
-    virtual std::set<ImplSpec> getAvailableImplSpecs() const;
+    virtual std::vector<ImplSpec> getAvailableImplSpecs() const;
     bool checkIOSpec(const ImplSpec::IOSpec& required, const ImplSpec::IOSpec& spec) const;
 
     const Operator &mOp;
diff --git a/python_binding/backend/pybind_OperatorImpl.cpp b/python_binding/backend/pybind_OperatorImpl.cpp
index 04172c3ff68641a9fe0d14f9a326cd17e7002912..0c5aac0044fd7f00f03ad45694ac0252dea5c15c 100644
--- a/python_binding/backend/pybind_OperatorImpl.cpp
+++ b/python_binding/backend/pybind_OperatorImpl.cpp
@@ -55,9 +55,9 @@ public:
         );
     }
 
-    std::set<ImplSpec> getAvailableImplSpecs() const noexcept override {
+    std::vector<ImplSpec> getAvailableImplSpecs() const noexcept override {
         PYBIND11_OVERRIDE_NAME(
-            std::set<ImplSpec>,
+            std::vector<ImplSpec>,
             OperatorImpl,
             "get_available_impl_specs",
             getAvailableImplSpecs
@@ -81,6 +81,10 @@ void init_OperatorImpl(py::module& m){
     .def(py::init<const DynamicAttributes&>(), py::arg("attr") = DynamicAttributes())
     .def(py::init<const ImplSpec::IOSpec&, const DynamicAttributes&>(), py::arg("io"), py::arg("attr") = DynamicAttributes())
     .def(py::init<const ImplSpec::IOSpec&, const ImplSpec::IOSpec&, const DynamicAttributes&>(), py::arg("i"), py::arg("o"), py::arg("attr") = DynamicAttributes())
+    .def("__eq__", static_cast<bool(*)(const ImplSpec&, const ImplSpec&)>(&operator==))
+    .def("__repr__", [](ImplSpec self){
+        return fmt::format("{}\n", self);
+    })
     ;
 
     py::class_<OperatorImpl, std::shared_ptr<OperatorImpl>, pyOperatorImpl>(m, "OperatorImpl", py::dynamic_attr())
@@ -98,4 +102,4 @@ void init_OperatorImpl(py::module& m){
     .def("get_available_impl_specs", &OperatorImpl_Publicist::getAvailableImplSpecs)
     ;
 }
-}
+} // namespace Aidge