From 28d3adc12cbac269f5938e49bac9e609f443951c Mon Sep 17 00:00:00 2001 From: 40% Date: Mon, 26 Jan 2026 09:06:34 +0800 Subject: [PATCH 01/16] Optimize Expr negation with Cython dict iteration Refactors the __neg__ method in the Expr class to use Cython's PyDict_Next and PyDict_SetItem for more efficient negation of terms, replacing the previous Python dict comprehension. --- src/pyscipopt/expr.pxi | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/pyscipopt/expr.pxi b/src/pyscipopt/expr.pxi index 07d6ab031..26975a8b0 100644 --- a/src/pyscipopt/expr.pxi +++ b/src/pyscipopt/expr.pxi @@ -46,7 +46,7 @@ import math from typing import TYPE_CHECKING from pyscipopt.scip cimport Variable, Solution -from cpython.dict cimport PyDict_Next +from cpython.dict cimport PyDict_Next, PyDict_SetItem from cpython.ref cimport PyObject import numpy as np @@ -309,7 +309,14 @@ cdef class Expr: raise TypeError(f"Unsupported base type {type(other)} for exponentiation.") def __neg__(self): - return Expr({v:-c for v,c in self.terms.items()}) + cdef dict res = {} + cdef Py_ssize_t pos = 0 + cdef PyObject* key_ptr + cdef PyObject* val_ptr + + while PyDict_Next(self.terms, &pos, &key_ptr, &val_ptr): + PyDict_SetItem(res, key_ptr, -(val_ptr)) + return Expr(res) def __sub__(self, other): return self + (-other) From 1be74c8a35d8763ac2db4c7d811cf0a83703ad9e Mon Sep 17 00:00:00 2001 From: 40% Date: Mon, 26 Jan 2026 09:18:16 +0800 Subject: [PATCH 02/16] Add copy method and negation to GenExpr and ProdExpr Introduces a copy method to GenExpr for duplicating expression objects, with support for deep or shallow copying. Also implements the __neg__ method for ProdExpr to allow negation of product expressions by negating their constant term. --- src/pyscipopt/expr.pxi | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/pyscipopt/expr.pxi b/src/pyscipopt/expr.pxi index 26975a8b0..6d6e2a527 100644 --- a/src/pyscipopt/expr.pxi +++ b/src/pyscipopt/expr.pxi @@ -45,9 +45,10 @@ import math from typing import TYPE_CHECKING -from pyscipopt.scip cimport Variable, Solution +from cpython.object cimport Py_TYPE from cpython.dict cimport PyDict_Next, PyDict_SetItem from cpython.ref cimport PyObject +from pyscipopt.scip cimport Variable, Solution import numpy as np @@ -654,6 +655,19 @@ cdef class GenExpr: '''returns operator of GenExpr''' return self._op + cdef GenExpr copy(self, bool copy = True): + cdef object cls = Py_TYPE(self) + cdef GenExpr res = cls.__new__(cls) + res._op = self._op + res.children = self.children.copy() if copy else self.children + if cls is SumExpr: + (res).constant = (self).constant + (res).coefs = (self).coefs.copy() if copy else (self).coefs + if cls is ProdExpr: + (res).constant = (self).constant + elif cls is PowExpr: + (res).expo = (self).expo + return res # Sum Expressions cdef class SumExpr(GenExpr): @@ -689,6 +703,11 @@ cdef class ProdExpr(GenExpr): self.children = [] self._op = Operator.prod + def __neg__(self): + cdef ProdExpr res = self.copy() + res.constant = -res.constant + return res + def __repr__(self): return self._op + "(" + str(self.constant) + "," + ",".join(map(lambda child : child.__repr__(), self.children)) + ")" From e4351fa3f36d47664ade92aa081c5df2b652ca58 Mon Sep 17 00:00:00 2001 From: 40% Date: Mon, 26 Jan 2026 09:19:55 +0800 Subject: [PATCH 03/16] Add return type annotations to __neg__ methods Added explicit return type annotations to the __neg__ methods in Expr and ProdExpr classes, and updated the corresponding type hints in scip.pyi. This improves type checking and code clarity. --- src/pyscipopt/expr.pxi | 4 ++-- src/pyscipopt/scip.pyi | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pyscipopt/expr.pxi b/src/pyscipopt/expr.pxi index 6d6e2a527..caf098715 100644 --- a/src/pyscipopt/expr.pxi +++ b/src/pyscipopt/expr.pxi @@ -309,7 +309,7 @@ cdef class Expr: else: raise TypeError(f"Unsupported base type {type(other)} for exponentiation.") - def __neg__(self): + def __neg__(self) -> Expr: cdef dict res = {} cdef Py_ssize_t pos = 0 cdef PyObject* key_ptr @@ -703,7 +703,7 @@ cdef class ProdExpr(GenExpr): self.children = [] self._op = Operator.prod - def __neg__(self): + def __neg__(self) -> ProdExpr: cdef ProdExpr res = self.copy() res.constant = -res.constant return res diff --git a/src/pyscipopt/scip.pyi b/src/pyscipopt/scip.pyi index 61c4ba773..b8f07917f 100644 --- a/src/pyscipopt/scip.pyi +++ b/src/pyscipopt/scip.pyi @@ -343,7 +343,7 @@ class Expr: def __lt__(self, other: object) -> bool: ... def __mul__(self, other: Incomplete) -> Incomplete: ... def __ne__(self, other: object) -> bool: ... - def __neg__(self) -> Incomplete: ... + def __neg__(self) -> Expr: ... def __pow__(self, other: Incomplete, modulo: Incomplete = ...) -> Incomplete: ... def __radd__(self, other: Incomplete) -> Incomplete: ... def __rmul__(self, other: Incomplete) -> Incomplete: ... @@ -386,7 +386,7 @@ class GenExpr: def __lt__(self, other: object) -> bool: ... def __mul__(self, other: Incomplete) -> Incomplete: ... def __ne__(self, other: object) -> bool: ... - def __neg__(self) -> Incomplete: ... + def __neg__(self) -> GenExpr: ... def __pow__(self, other: Incomplete, modulo: Incomplete = ...) -> Incomplete: ... def __radd__(self, other: Incomplete) -> Incomplete: ... def __rmul__(self, other: Incomplete) -> Incomplete: ... From fb9fcc824a67f5bc3901c421767c7a2707e5f8c6 Mon Sep 17 00:00:00 2001 From: 40% Date: Mon, 26 Jan 2026 13:07:23 +0800 Subject: [PATCH 04/16] Optimize SumExpr coefficients with cpython.array Refactors SumExpr to use cpython.array for storing coefficients instead of Python lists, improving performance and memory efficiency. Adds a __neg__ method for SumExpr to efficiently negate coefficients and the constant term. Updates the copy method to properly clone arrays when copying SumExpr instances. --- src/pyscipopt/expr.pxi | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/pyscipopt/expr.pxi b/src/pyscipopt/expr.pxi index caf098715..0db0905e5 100644 --- a/src/pyscipopt/expr.pxi +++ b/src/pyscipopt/expr.pxi @@ -45,8 +45,9 @@ import math from typing import TYPE_CHECKING -from cpython.object cimport Py_TYPE +from cpython.array cimport array, clone from cpython.dict cimport PyDict_Next, PyDict_SetItem +from cpython.object cimport Py_TYPE from cpython.ref cimport PyObject from pyscipopt.scip cimport Variable, Solution @@ -57,6 +58,9 @@ if TYPE_CHECKING: double = float +cdef array DOUBLE_TEMPLATE = array("d") + + def _is_number(e): try: f = float(e) @@ -656,13 +660,15 @@ cdef class GenExpr: return self._op cdef GenExpr copy(self, bool copy = True): - cdef object cls = Py_TYPE(self) + cdef object cls = Py_TYPE(self) cdef GenExpr res = cls.__new__(cls) res._op = self._op res.children = self.children.copy() if copy else self.children if cls is SumExpr: - (res).constant = (self).constant - (res).coefs = (self).coefs.copy() if copy else (self).coefs + self = self + res = res + res.constant = self.constant + res.coefs = clone(self.coefs, len(self.coefs), False) if copy else self.coefs if cls is ProdExpr: (res).constant = (self).constant elif cls is PowExpr: @@ -677,9 +683,24 @@ cdef class SumExpr(GenExpr): def __init__(self): self.constant = 0.0 - self.coefs = [] + self.coefs = array("d") self.children = [] self._op = Operator.add + + def __neg__(self) -> SumExpr: + cdef int i = 0, n = len(self.coefs) + cdef array coefs = clone(DOUBLE_TEMPLATE, n, False) + cdef double[:] dest_view = coefs + cdef double[:] src_view = self.coefs + + for i in range(n): + dest_view[i] = -src_view[i] + + cdef SumExpr res = self.copy() + res.constant = -res.constant + res.coefs = coefs + return res + def __repr__(self): return self._op + "(" + str(self.constant) + "," + ",".join(map(lambda child : child.__repr__(), self.children)) + ")" From f55c2225e20ad8f0a407eb0f73dc8c0a1b8f2e53 Mon Sep 17 00:00:00 2001 From: 40% Date: Mon, 26 Jan 2026 13:08:10 +0800 Subject: [PATCH 05/16] Add tests for negation of expression objects Introduces the test_neg function to verify correct behavior when negating ProdExpr and SumExpr objects in the expression API. Ensures that negated expressions have the expected types, string representations, and coefficients. --- tests/test_expr.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/tests/test_expr.py b/tests/test_expr.py index c9135d2fa..b5e5a2d41 100644 --- a/tests/test_expr.py +++ b/tests/test_expr.py @@ -2,8 +2,8 @@ import pytest -from pyscipopt import Model, sqrt, log, exp, sin, cos -from pyscipopt.scip import Expr, GenExpr, ExprCons, Term +from pyscipopt import Model, cos, exp, log, sin, sqrt +from pyscipopt.scip import Expr, ExprCons, GenExpr, ProdExpr, SumExpr, Term @pytest.fixture(scope="module") @@ -218,3 +218,22 @@ def test_getVal_with_GenExpr(): with pytest.raises(ZeroDivisionError): m.getVal(1 / z) + + +def test_neg(): + m = Model() + x = m.addVar(name="x") + base = sqrt(x) + + expr = base * -1 + neg_expr = -expr + assert isinstance(expr, ProdExpr) + assert isinstance(neg_expr, ProdExpr) + assert str(neg_expr) == "prod(1.0,sqrt(sum(0.0,prod(1.0,x))))" + + expr = base + x - 1 + neg_expr = -expr + assert isinstance(expr, SumExpr) + assert isinstance(neg_expr, SumExpr) + assert str(neg_expr) == "sum(1.0,sqrt(sum(0.0,prod(1.0,x))),prod(1.0,x))" + assert list(neg_expr.coefs) == [-1, -1] From 5896012b1fc069bb2f721d770048a79684c53392 Mon Sep 17 00:00:00 2001 From: 40% Date: Thu, 29 Jan 2026 13:19:40 +0800 Subject: [PATCH 06/16] Update changelog with negation speed improvements Added an entry noting the speedup of `Expr.__neg__`, `ProdExpr.__neg__`, and `Constant.__neg__` using the C-level API. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0bfca7d74..f2967e69f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ - Speed up MatrixExpr.add.reduce via quicksum - Speed up np.ndarray(..., dtype=np.float64) @ MatrixExpr - MatrixExpr and MatrixExprCons use `__array_ufunc__` protocol to control all numpy.ufunc inputs and outputs +- Speed up `Expr.__neg__` and `ProdExpr.__neg__` and `Constant.__neg__` via C-level API ### Removed ## 6.0.0 - 2025.xx.yy From 6387cfa091449c50e327890073254e9ea8e1d78b Mon Sep 17 00:00:00 2001 From: 40% Date: Thu, 29 Jan 2026 13:22:03 +0800 Subject: [PATCH 07/16] Remove @disjoint_base decorator from UnaryExpr The @disjoint_base decorator was removed from the UnaryExpr class in the type stub, possibly to correct or update the class hierarchy or decorator usage. --- src/pyscipopt/scip.pyi | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pyscipopt/scip.pyi b/src/pyscipopt/scip.pyi index 7d889b31f..1d7396efa 100644 --- a/src/pyscipopt/scip.pyi +++ b/src/pyscipopt/scip.pyi @@ -2162,7 +2162,6 @@ class Term: def __lt__(self, other: object) -> bool: ... def __ne__(self, other: object) -> bool: ... -@disjoint_base class UnaryExpr(GenExpr): def __init__(self, *args: Incomplete, **kwargs: Incomplete) -> None: ... From fecba063bec09cd3acecc2df926c048bf20d818e Mon Sep 17 00:00:00 2001 From: 40% Date: Thu, 29 Jan 2026 15:03:35 +0800 Subject: [PATCH 08/16] Optimize coefs access in SumExpr evaluation Changed the type of 'coefs' from list to memoryview (double[:]) in SumExpr._evaluate for more efficient access during evaluation. --- src/pyscipopt/expr.pxi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pyscipopt/expr.pxi b/src/pyscipopt/expr.pxi index 0db0905e5..809628443 100644 --- a/src/pyscipopt/expr.pxi +++ b/src/pyscipopt/expr.pxi @@ -708,7 +708,7 @@ cdef class SumExpr(GenExpr): cdef double res = self.constant cdef int i = 0, n = len(self.children) cdef list children = self.children - cdef list coefs = self.coefs + cdef double[:] coefs = self.coefs for i in range(n): res += coefs[i] * (children[i])._evaluate(sol) return res From 02e32b551d20f30121561944b4941b23976ff5f9 Mon Sep 17 00:00:00 2001 From: 40% Date: Thu, 29 Jan 2026 15:08:01 +0800 Subject: [PATCH 09/16] Fix negation logic in SumExpr class Refactors the negation method in SumExpr to correctly create a new instance, negate the constant, copy children, and set the operator. This ensures proper behavior when negating sum expressions. --- src/pyscipopt/expr.pxi | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pyscipopt/expr.pxi b/src/pyscipopt/expr.pxi index 809628443..5e013c6e2 100644 --- a/src/pyscipopt/expr.pxi +++ b/src/pyscipopt/expr.pxi @@ -696,9 +696,11 @@ cdef class SumExpr(GenExpr): for i in range(n): dest_view[i] = -src_view[i] - cdef SumExpr res = self.copy() - res.constant = -res.constant + cdef SumExpr res = SumExpr.__new__(SumExpr) + res.constant = -self.constant res.coefs = coefs + res.children = self.children.copy() + res._op = Operator.add return res def __repr__(self): From bd280f6bca6d3a1aa2745483ae2326db632fb466 Mon Sep 17 00:00:00 2001 From: 40% Date: Thu, 29 Jan 2026 17:15:01 +0800 Subject: [PATCH 10/16] Add negation support to Constant expressions Implemented the __neg__ method for the Constant class, allowing unary negation of constant expressions. --- src/pyscipopt/expr.pxi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pyscipopt/expr.pxi b/src/pyscipopt/expr.pxi index 5e013c6e2..18aed3d8d 100644 --- a/src/pyscipopt/expr.pxi +++ b/src/pyscipopt/expr.pxi @@ -795,11 +795,16 @@ cdef class UnaryExpr(GenExpr): # class for constant expressions cdef class Constant(GenExpr): + cdef public number + def __init__(self,number): self.number = number self._op = Operator.const + def __neg__(self): + return Constant(-self.number) + def __repr__(self): return str(self.number) From 2e97cc7ae0750dc6d021d9ade0010213519d0f49 Mon Sep 17 00:00:00 2001 From: 40% Date: Thu, 29 Jan 2026 17:18:08 +0800 Subject: [PATCH 11/16] Add test for negation of Constant expression Imported Constant from pyscipopt.scip and added an assertion to test the string representation of the negated Constant expression in test_neg. --- tests/test_expr.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_expr.py b/tests/test_expr.py index b5e5a2d41..eaefeac96 100644 --- a/tests/test_expr.py +++ b/tests/test_expr.py @@ -3,7 +3,7 @@ import pytest from pyscipopt import Model, cos, exp, log, sin, sqrt -from pyscipopt.scip import Expr, ExprCons, GenExpr, ProdExpr, SumExpr, Term +from pyscipopt.scip import Constant, Expr, ExprCons, GenExpr, ProdExpr, SumExpr, Term @pytest.fixture(scope="module") @@ -237,3 +237,5 @@ def test_neg(): assert isinstance(neg_expr, SumExpr) assert str(neg_expr) == "sum(1.0,sqrt(sum(0.0,prod(1.0,x))),prod(1.0,x))" assert list(neg_expr.coefs) == [-1, -1] + + assert str(-Constant(3.0)) == "-3.0" From 67ce45d1d15cb92eae3b5c567c5ee95a2536c21d Mon Sep 17 00:00:00 2001 From: 40% Date: Thu, 29 Jan 2026 18:14:53 +0800 Subject: [PATCH 12/16] Expand test_neg to cover negation of power expressions Added assertions to test_neg to verify correct negation and string representation of expressions involving powers. This enhances test coverage for expression negation logic. --- tests/test_expr.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/test_expr.py b/tests/test_expr.py index eaefeac96..13a167e13 100644 --- a/tests/test_expr.py +++ b/tests/test_expr.py @@ -223,8 +223,17 @@ def test_getVal_with_GenExpr(): def test_neg(): m = Model() x = m.addVar(name="x") - base = sqrt(x) + expr = (x + 1) ** 3 + neg_expr = -expr + assert isinstance(expr, Expr) + assert isinstance(neg_expr, Expr) + assert ( + str(neg_expr) + == "Expr({Term(x, x, x): -1.0, Term(x, x): -3.0, Term(x): -3.0, Term(): -1.0})" + ) + + base = sqrt(x) expr = base * -1 neg_expr = -expr assert isinstance(expr, ProdExpr) From 40945adbc8b61458c1e4bb839ef4deb64469297e Mon Sep 17 00:00:00 2001 From: 40% Date: Thu, 29 Jan 2026 18:15:48 +0800 Subject: [PATCH 13/16] Update CHANGELOG for negation speedup details Clarified that `SumExpr.__neg__` is also sped up via the C-level API, in addition to other negation methods. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6289d3065..2929b2054 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,7 @@ - Speed up MatrixExpr.add.reduce via quicksum - Speed up np.ndarray(..., dtype=np.float64) @ MatrixExpr - MatrixExpr and MatrixExprCons use `__array_ufunc__` protocol to control all numpy.ufunc inputs and outputs -- Speed up `Expr.__neg__` and `ProdExpr.__neg__` and `Constant.__neg__` via C-level API +- Speed up `Expr.__neg__`, `SumExpr.__neg__`, `ProdExpr.__neg__` and `Constant.__neg__` via C-level API - Set `__array_priority__` for MatrixExpr and MatrixExprCons - changed addConsNode() and addConsLocal() to mirror addCons() and accept ExprCons instead of Constraint ### Removed From ef034c4a93a4bbda7bb6d3f59a9f52bda92a65e8 Mon Sep 17 00:00:00 2001 From: 40% Date: Fri, 30 Jan 2026 11:28:39 +0800 Subject: [PATCH 14/16] Refactor SumExpr to use Python lists for coefficients Replaces usage of cpython.array for storing coefficients in SumExpr with standard Python lists. Simplifies code by removing array-specific imports and clone operations, improving maintainability and compatibility. --- src/pyscipopt/expr.pxi | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/pyscipopt/expr.pxi b/src/pyscipopt/expr.pxi index 18aed3d8d..248e7b71c 100644 --- a/src/pyscipopt/expr.pxi +++ b/src/pyscipopt/expr.pxi @@ -45,7 +45,6 @@ import math from typing import TYPE_CHECKING -from cpython.array cimport array, clone from cpython.dict cimport PyDict_Next, PyDict_SetItem from cpython.object cimport Py_TYPE from cpython.ref cimport PyObject @@ -58,9 +57,6 @@ if TYPE_CHECKING: double = float -cdef array DOUBLE_TEMPLATE = array("d") - - def _is_number(e): try: f = float(e) @@ -668,7 +664,7 @@ cdef class GenExpr: self = self res = res res.constant = self.constant - res.coefs = clone(self.coefs, len(self.coefs), False) if copy else self.coefs + res.coefs = self.coefs.copy() if copy else self.coefs if cls is ProdExpr: (res).constant = (self).constant elif cls is PowExpr: @@ -683,13 +679,13 @@ cdef class SumExpr(GenExpr): def __init__(self): self.constant = 0.0 - self.coefs = array("d") + self.coefs = [] self.children = [] self._op = Operator.add def __neg__(self) -> SumExpr: cdef int i = 0, n = len(self.coefs) - cdef array coefs = clone(DOUBLE_TEMPLATE, n, False) + cdef list coefs = [0.0] * n cdef double[:] dest_view = coefs cdef double[:] src_view = self.coefs From 86678e2a7f17cca2639c64e391966f8a50d8b9c3 Mon Sep 17 00:00:00 2001 From: 40% Date: Fri, 30 Jan 2026 11:31:05 +0800 Subject: [PATCH 15/16] Remove `GenExpr.copy` Removed the unused GenExpr.copy() method and refactored the __neg__ methods for SumExpr and ProdExpr to avoid using the copy method. This simplifies the code and clarifies object construction during negation. --- src/pyscipopt/expr.pxi | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/pyscipopt/expr.pxi b/src/pyscipopt/expr.pxi index 248e7b71c..79fb392ba 100644 --- a/src/pyscipopt/expr.pxi +++ b/src/pyscipopt/expr.pxi @@ -655,21 +655,6 @@ cdef class GenExpr: '''returns operator of GenExpr''' return self._op - cdef GenExpr copy(self, bool copy = True): - cdef object cls = Py_TYPE(self) - cdef GenExpr res = cls.__new__(cls) - res._op = self._op - res.children = self.children.copy() if copy else self.children - if cls is SumExpr: - self = self - res = res - res.constant = self.constant - res.coefs = self.coefs.copy() if copy else self.coefs - if cls is ProdExpr: - (res).constant = (self).constant - elif cls is PowExpr: - (res).expo = (self).expo - return res # Sum Expressions cdef class SumExpr(GenExpr): @@ -693,9 +678,9 @@ cdef class SumExpr(GenExpr): dest_view[i] = -src_view[i] cdef SumExpr res = SumExpr.__new__(SumExpr) - res.constant = -self.constant res.coefs = coefs res.children = self.children.copy() + res.constant = -self.constant res._op = Operator.add return res @@ -723,8 +708,10 @@ cdef class ProdExpr(GenExpr): self._op = Operator.prod def __neg__(self) -> ProdExpr: - cdef ProdExpr res = self.copy() + cdef ProdExpr res = ProdExpr.__new__(ProdExpr) res.constant = -res.constant + self.children = self.children.copy() + res._op = Operator.prod return res def __repr__(self): From 394c682458ef00ab73da65ee190b779225c01119 Mon Sep 17 00:00:00 2001 From: 40% Date: Fri, 30 Jan 2026 13:13:28 +0800 Subject: [PATCH 16/16] Add @disjoint_base decorator to UnaryExpr class Applied the @disjoint_base decorator to the UnaryExpr class in scip.pyi to clarify its role in the type hierarchy. --- src/pyscipopt/scip.pyi | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pyscipopt/scip.pyi b/src/pyscipopt/scip.pyi index 9fd7015de..620caa162 100644 --- a/src/pyscipopt/scip.pyi +++ b/src/pyscipopt/scip.pyi @@ -2198,6 +2198,7 @@ class Term: def __lt__(self, other: object) -> bool: ... def __ne__(self, other: object) -> bool: ... +@disjoint_base class UnaryExpr(GenExpr): def __init__(self, *args: Incomplete, **kwargs: Incomplete) -> None: ...