git: d17420708924 - main - science/py-dwave-optimization: update 0.7.2 → 0.7.3

From: Yuri Victorovich <yuri_at_FreeBSD.org>
Date: Tue, 08 Sep 2026 00:42:04 UTC
The branch main has been updated by yuri:

URL: https://cgit.FreeBSD.org/ports/commit/?id=d17420708924316220ded85099d59ca5f6ec8acf

commit d17420708924316220ded85099d59ca5f6ec8acf
Author:     Yuri Victorovich <yuri@FreeBSD.org>
AuthorDate: 2026-09-07 17:42:12 +0000
Commit:     Yuri Victorovich <yuri@FreeBSD.org>
CommitDate: 2026-09-08 00:38:55 +0000

    science/py-dwave-optimization: update 0.7.2 → 0.7.3
---
 science/py-dwave-optimization/Makefile             | 19 +++++---
 science/py-dwave-optimization/distinfo             |  6 +--
 .../files/patch-dwave_optimization__model.pyx      | 56 ----------------------
 ...n_include_dwave-optimization_nodes_binaryop.hpp | 34 -------------
 ...ization_include_dwave-optimization_nodes_lp.hpp | 39 +++++++--------
 5 files changed, 35 insertions(+), 119 deletions(-)

diff --git a/science/py-dwave-optimization/Makefile b/science/py-dwave-optimization/Makefile
index 813a2a6d4546..726b128a01be 100644
--- a/science/py-dwave-optimization/Makefile
+++ b/science/py-dwave-optimization/Makefile
@@ -1,5 +1,5 @@
 PORTNAME=	dwave-optimization
-DISTVERSION=	0.7.2
+DISTVERSION=	0.7.3
 CATEGORIES=	science python # quantum-computing
 MASTER_SITES=	PYPI
 PKGNAMEPREFIX=	${PYTHON_PKGNAMEPREFIX}
@@ -12,11 +12,16 @@ WWW=		https://github.com/dwavesystems/dwave-optimization
 LICENSE=	APACHE20
 LICENSE_FILE=	${WRKSRC}/LICENSE
 
-BUILD_DEPENDS=	${PYTHON_PKGNAMEPREFIX}meson-python>0:devel/meson-python@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}numpy>=1.21.3:math/py-numpy@${PY_FLAVOR}
-RUN_DEPENDS=	${PYTHON_PKGNAMEPREFIX}numpy>=1.21.3:math/py-numpy@${PY_FLAVOR}
-TEST_DEPENDS=	${PYTHON_PKGNAMEPREFIX}dimod>=0.12.21:science/py-dimod@${PY_FLAVOR} \
-		${PYTHON_PKGNAMEPREFIX}scikit-learn>=1.6.0:science/py-scikit-learn@${PY_FLAVOR}
+BUILD_DEPENDS=	${PYTHON_PKGNAMEPREFIX}cython>=3.2.0:lang/cython@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}meson-python>=0.18.0:devel/meson-python@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}numpy>=2:math/py-numpy@${PY_FLAVOR} \
+		meson>=1.10.2:devel/meson \
+		ninja>=1.13.0:devel/ninja
+RUN_DEPENDS=	${PYTHON_PKGNAMEPREFIX}numpy>=2:math/py-numpy@${PY_FLAVOR}
+TEST_DEPENDS=	${PYTHON_PKGNAMEPREFIX}dimod>=0.12.16:science/py-dimod@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}networkx>=3.2:math/py-networkx@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}scikit-learn>=1.6.0:science/py-scikit-learn@${PY_FLAVOR} \
+		${PYTHON_PKGNAMEPREFIX}scipy>=1.13.0:science/py-scipy@${PY_FLAVOR}
 
 USES=		python
 USE_PYTHON=	autoplist cython pep517 pytest
@@ -35,7 +40,7 @@ pre-test:
 	@cd ${STAGEDIR}${PYTHON_SITELIBDIR}/dwave/optimization && \
 		${FIND} . -name '*.so' -exec ${CP} {} ${WRKSRC}/dwave/optimization/{} \;
 
-# tests as of 0.7.2: 869 passed, 1 broken in 3.23s
+# tests as of 0.7.3: 874 passed, 5 deselected, 538 subtests passed in 3.39s
 
 # all C++ patches are workaround for https://github.com/dwavesystems/dwave-optimization/issues/595
 
diff --git a/science/py-dwave-optimization/distinfo b/science/py-dwave-optimization/distinfo
index a2e87c68b9ae..ec6b27725fb9 100644
--- a/science/py-dwave-optimization/distinfo
+++ b/science/py-dwave-optimization/distinfo
@@ -1,3 +1,3 @@
-TIMESTAMP = 1785188115
-SHA256 (dwave_optimization-0.7.2.tar.gz) = c8bd908c4714a0036a8710ad27840b5226c3b3cdd9f85f5176149b7db3a4ace3
-SIZE (dwave_optimization-0.7.2.tar.gz) = 535092
+TIMESTAMP = 1788794378
+SHA256 (dwave_optimization-0.7.3.tar.gz) = 2a610790c1a329bdc85e0db0c8d6e625f660969cd1f66cfd43a37d5b6f25fa7e
+SIZE (dwave_optimization-0.7.3.tar.gz) = 549273
diff --git a/science/py-dwave-optimization/files/patch-dwave_optimization__model.pyx b/science/py-dwave-optimization/files/patch-dwave_optimization__model.pyx
deleted file mode 100644
index 352cb53479e2..000000000000
--- a/science/py-dwave-optimization/files/patch-dwave_optimization__model.pyx
+++ /dev/null
@@ -1,56 +0,0 @@
--- Use the mangled C++ type name as the runtime type registry key instead of
--- std::type_index.  On FreeBSD/Clang libc++ compares type_info object addresses
--- by default, and the same class template instantiations are emitted into both
--- libdwave-optimization.so and each Cython extension module.  The resulting
--- distinct type_info objects for the same type cause registry lookups to fail,
--- producing "given pointer cannot be cast to a known node type".  Comparing
--- mangled type name strings works across DSO boundaries.
-
---- dwave/optimization/_model.pyx.orig	2026-07-23 12:58:12 UTC
-+++ dwave/optimization/_model.pyx
-@@ -32,7 +32,7 @@
- from libcpp cimport bool
- from libcpp.memory cimport make_shared
- from libcpp.span cimport span
--from libcpp.typeindex cimport type_index
-+from libcpp.string cimport string
- from libcpp.unordered_map cimport unordered_map
- from libcpp.utility cimport move
- from libcpp.vector cimport vector
-@@ -65,17 +65,22 @@
- """A tuple of 2-tuples listing all serialization versions supported."""
-
-
--# Store a mapping from the type_index of each C++ Node type to the relevant
--# Cython class. We don't refcount the PyObject*s pointing to each class because
--# the lifespace of this map is identical to that of the type objects.
--cdef unordered_map[type_index, PyObject*] _cpp_type_to_python
-+# Store a mapping from the mangled C++ type name of each Node type to the
-+# relevant Cython class. We use the type name string rather than std::type_index
-+# because libc++'s default type_info comparison compares object addresses, and
-+# the same C++ class template instantiations are emitted into both
-+# libdwave-optimization.so and the individual Cython extension modules, giving
-+# distinct type_info objects for the same type across DSOs on FreeBSD/Clang.
-+# We don't refcount the PyObject*s pointing to each class because the lifespan of
-+# this map is identical to that of the type objects.
-+cdef unordered_map[string, PyObject*] _cpp_type_to_python
-
- # Register a mapping between the given Cython class and C++ class.
- cdef void _register(object cls, const type_info& typeinfo):
-     """Register a Python/Cython symbol to allow it to be created from a pointer
-     via `symbol_from_ptr`.
-     """
--    _cpp_type_to_python[type_index(typeinfo)] = <PyObject*>(cls)
-+    _cpp_type_to_python[string(typeinfo.name())] = <PyObject*>(cls)
-
-
- cdef object symbol_from_ptr(_Graph model, cppNode* node_ptr):
-@@ -86,7 +91,7 @@
-         raise ValueError("cannot construct a Symbol from the given pointer")
-
-     try:
--        cls = <object>_cpp_type_to_python.at(type_index(typeid(deref(node_ptr))))
-+        cls = <object>_cpp_type_to_python.at(string(typeid(deref(node_ptr)).name()))
-     except IndexError:
-         # IndexError would be returned by .at()
-         raise RuntimeError("given pointer cannot be cast to a known node type") from None
diff --git a/science/py-dwave-optimization/files/patch-dwave_optimization_include_dwave-optimization_nodes_binaryop.hpp b/science/py-dwave-optimization/files/patch-dwave_optimization_include_dwave-optimization_nodes_binaryop.hpp
deleted file mode 100644
index 6f107c0cecb0..000000000000
--- a/science/py-dwave-optimization/files/patch-dwave_optimization_include_dwave-optimization_nodes_binaryop.hpp
+++ /dev/null
@@ -1,34 +0,0 @@
--- Declare explicit template instantiations for BinaryOpNode specializations so
--- they are defined only in libdwave-optimization.so (dwave/optimization/src/nodes/binaryop.cpp).
--- Without this, each Cython extension module that creates a binary-op node
--- instantiates its own copy of the class template, producing a distinct type_info
--- object for the same type.  libc++'s default type_info comparison then treats
--- those copies as different types and cross-DSO dynamic_cast fails on
--- FreeBSD/Clang.
-
---- dwave/optimization/include/dwave-optimization/nodes/binaryop.hpp.orig	2026-07-23 12:58:12 UTC
-+++ dwave/optimization/include/dwave-optimization/nodes/binaryop.hpp
-@@ -106,4 +106,23 @@
- using SubtractNode = BinaryOpNode<std::minus<double>>;
- using XorNode = BinaryOpNode<functional::logical_xor<double>>;
-
-+// Explicit instantiations live in dwave/optimization/src/nodes/binaryop.cpp so
-+// that libdwave-optimization.so owns the canonical type_info objects. Tell
-+// other translation units (especially the Cython extension modules) not to
-+// emit their own copies, which would break cross-DSO dynamic_cast on
-+// FreeBSD/Clang.
-+extern template class BinaryOpNode<std::plus<double>>;
-+extern template class BinaryOpNode<std::logical_and<double>>;
-+extern template class BinaryOpNode<std::divides<double>>;
-+extern template class BinaryOpNode<std::equal_to<double>>;
-+extern template class BinaryOpNode<std::less_equal<double>>;
-+extern template class BinaryOpNode<functional::max<double>>;
-+extern template class BinaryOpNode<functional::min<double>>;
-+extern template class BinaryOpNode<functional::modulus<double>>;
-+extern template class BinaryOpNode<std::multiplies<double>>;
-+extern template class BinaryOpNode<std::logical_or<double>>;
-+extern template class BinaryOpNode<functional::safe_divides<double>>;
-+extern template class BinaryOpNode<std::minus<double>>;
-+extern template class BinaryOpNode<functional::logical_xor<double>>;
-+
- }  // namespace dwave::optimization
diff --git a/science/py-dwave-optimization/files/patch-dwave_optimization_include_dwave-optimization_nodes_lp.hpp b/science/py-dwave-optimization/files/patch-dwave_optimization_include_dwave-optimization_nodes_lp.hpp
index 55123382dbfd..9aca0bf0b9fb 100644
--- a/science/py-dwave-optimization/files/patch-dwave_optimization_include_dwave-optimization_nodes_lp.hpp
+++ b/science/py-dwave-optimization/files/patch-dwave_optimization_include_dwave-optimization_nodes_lp.hpp
@@ -1,53 +1,54 @@
--- Make the LP node destructors out-of-line so their type_info objects are
--- emitted as strong (GLOBAL) symbols in libdwave-optimization.so.  Without
--- this, the Cython lp.so module emits its own copies of the polymorphic base
--- LinearProgramNodeBase type_info, which breaks cross-DSO dynamic_cast from
--- LinearProgramNode to LinearProgramNodeBase on FreeBSD/Clang.
+-- Add missing out-of-line destructor declarations for the LP node classes so
+-- their type_info objects are emitted as strong (GLOBAL) symbols in
+-- libdwave-optimization.so.  Without this, the Cython lp.so module emits its
+-- own copies of the polymorphic base LinearProgramNodeBase type_info, which
+-- breaks cross-DSO dynamic_cast from LinearProgramNode to LinearProgramNodeBase
+-- on FreeBSD/Clang.
 
---- dwave/optimization/include/dwave-optimization/nodes/lp.hpp.orig	2026-07-23 12:58:12 UTC
+--- dwave/optimization/include/dwave-optimization/nodes/lp.hpp.orig	2026-09-07 15:29:23 UTC
 +++ dwave/optimization/include/dwave-optimization/nodes/lp.hpp
-@@ -27,6 +27,8 @@
+@@ -27,6 +27,8 @@ class LinearProgramFeasibleNode : public ScalarOutputM
  /// A logical node that propagates whether or not its predecessor LinearProgram is feasible.
  class LinearProgramFeasibleNode : public ScalarOutputMixin<EqualityMixin<ArrayNode>, true> {
   public:
 +    virtual ~LinearProgramFeasibleNode();
 +
      explicit LinearProgramFeasibleNode(LinearProgramNodeBase* lp_ptr);
-
+ 
      /// @copydoc Node::initialize_state()
-@@ -53,6 +55,8 @@
-
+@@ -53,6 +55,8 @@ class LinearProgramNodeBase : public Node {
+ 
  class LinearProgramNodeBase : public Node {
   public:
 +    virtual ~LinearProgramNodeBase();
 +
      /// The default lower bound for variables
      static const double default_lower_bound();
-
-@@ -102,6 +106,8 @@
+ 
+@@ -102,6 +106,8 @@ class LinearProgramNode : public EqualityMixin<LinearP
  ///         callback=None, options=None, x0=None, integrality=None)
  class LinearProgramNode : public EqualityMixin<LinearProgramNodeBase, LinearProgramNode> {
   public:
 +    virtual ~LinearProgramNode();
 +
-     /// Construct a LinearProgramNode
-     ///
-     /// Note: parameter names are chosen to match scipy.optimize.lingprog()
-@@ -194,6 +200,8 @@
+     using linprog_type = std::function<std::vector<double>(
+         std::span<const double> c,
+         std::span<const double> b_lb,
+@@ -208,6 +214,8 @@ class LinearProgramObjectiveValueNode : public ScalarO
  /// LinearProgramNode. Note that the output is undefined if the solution is not feasible.
  class LinearProgramObjectiveValueNode : public ScalarOutputMixin<EqualityMixin<ArrayNode>, true> {
   public:
 +    virtual ~LinearProgramObjectiveValueNode();
 +
      explicit LinearProgramObjectiveValueNode(LinearProgramNodeBase* lp_ptr);
-
+ 
      /// @copydoc Node::initialize_state()
-@@ -222,6 +230,8 @@
+@@ -236,6 +244,8 @@ class LinearProgramSolutionNode : public ArrayOutputMi
  /// solution may not be feasible or optimial.
  class LinearProgramSolutionNode : public ArrayOutputMixin<EqualityMixin<ArrayNode>> {
   public:
 +    virtual ~LinearProgramSolutionNode();
 +
      explicit LinearProgramSolutionNode(LinearProgramNodeBase* lp_ptr);
-
+ 
      /// @copydoc Array::buff()