diff --git a/CHANGELOG.md b/CHANGELOG.md index c19ccfa4f..aabcecf95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased ### Added +- Added more type annotations and deprecation markers to the stubs. ### Fixed ### Changed ### Removed diff --git a/pyproject.toml b/pyproject.toml index 8c6c8d9fb..a9a1bedd8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,6 +28,10 @@ Homepage = "https://github.com/SCIP-Interfaces/PySCIPOpt" norecursedirs = ["check"] testpaths = ["tests"] +[tool.mypy] +warn_unused_ignores = true +enable_error_code = ["deprecated"] + [tool.setuptools] include-package-data = false diff --git a/src/pyscipopt/recipes/infeasibilities.py b/src/pyscipopt/recipes/infeasibilities.py index 2d50de7ab..d6d63684b 100644 --- a/src/pyscipopt/recipes/infeasibilities.py +++ b/src/pyscipopt/recipes/infeasibilities.py @@ -35,10 +35,10 @@ def get_infeasible_constraints(orig_model: Model, verbose: bool = False): model.optimize() n_infeasibilities_detected = 0 - for c in binary: - if model.isInfinity(model.getVal(binary[c])) or model.isGT(model.getVal(binary[c]), 0): + for name in binary: + if model.isInfinity(model.getVal(binary[name])) or model.isGT(model.getVal(binary[name]), 0): n_infeasibilities_detected += 1 - print("Constraint %s is causing an infeasibility." % c) + print("Constraint %s is causing an infeasibility." % name) if verbose: if n_infeasibilities_detected > 0: @@ -47,4 +47,4 @@ def get_infeasible_constraints(orig_model: Model, verbose: bool = False): else: print("Model is feasible.") - return n_infeasibilities_detected, aux \ No newline at end of file + return n_infeasibilities_detected, aux diff --git a/src/pyscipopt/scip.pyi b/src/pyscipopt/scip.pyi index 316b13e9f..a29999dc1 100644 --- a/src/pyscipopt/scip.pyi +++ b/src/pyscipopt/scip.pyi @@ -1,16 +1,17 @@ import os from collections.abc import Iterable, Mapping, Sequence -from typing import Any, AnyStr, ClassVar, Literal, SupportsFloat, overload +from typing import Any, ClassVar, Literal, SupportsFloat, overload import numpy as np -from _typeshed import Incomplete -from typing_extensions import CapsuleType, Self, disjoint_base +from _typeshed import Incomplete, StrOrBytesPath +from numpy.typing import NDArray +from typing_extensions import CapsuleType, Self, deprecated, disjoint_base CONST: Term EventNames: dict MAJOR: int MINOR: int -Operator: Op +Operator: Op # type: ignore[deprecated] PATCH: int PY_SCIP_CALL: Incomplete StageNames: dict @@ -22,14 +23,14 @@ _core_sum: Incomplete buildGenExprObj: Incomplete expr_to_array: Incomplete expr_to_nodes: Incomplete -is_memory_freed: Incomplete -print_memory_in_use: Incomplete quickprod: Incomplete quicksum: Incomplete -readStatistics: Incomplete -str_conversion: Incomplete value_to_array: Incomplete +def is_memory_freed() -> bool: ... +def print_memory_in_use() -> None: ... +def readStatistics(filename: StrOrBytesPath) -> Statistics: ... +def str_conversion(x: str) -> bytes: ... @overload def exp(x: float | Expr | GenExpr) -> ExpExpr: ... @overload @@ -107,9 +108,9 @@ class BoundChange: def __init__(self) -> None: ... def getBoundchgtype(self) -> Incomplete: ... def getBoundtype(self) -> Incomplete: ... - def getNewBound(self) -> Incomplete: ... - def getVar(self) -> Incomplete: ... - def isRedundant(self) -> Incomplete: ... + def getNewBound(self) -> float: ... + def getVar(self) -> Variable: ... + def isRedundant(self) -> bool: ... @disjoint_base class Branchrule: @@ -126,17 +127,17 @@ class Branchrule: @disjoint_base class Column: - data: Incomplete + data: Any def __init__(self) -> None: ... - def getAge(self) -> Incomplete: ... - def getBasisStatus(self) -> Incomplete: ... - def getLPPos(self) -> Incomplete: ... - def getLb(self) -> Incomplete: ... - def getObjCoeff(self) -> Incomplete: ... - def getPrimsol(self) -> Incomplete: ... - def getUb(self) -> Incomplete: ... - def getVar(self) -> Incomplete: ... - def isIntegral(self) -> Incomplete: ... + def getAge(self) -> int: ... + def getBasisStatus(self) -> Literal["lower", "basic", "upper", "zero"]: ... + def getLPPos(self) -> int: ... + def getLb(self) -> float: ... + def getObjCoeff(self) -> float: ... + def getPrimsol(self) -> float: ... + def getUb(self) -> float: ... + def getVar(self) -> Variable: ... + def isIntegral(self) -> bool: ... def __eq__(self, other: object, /) -> bool: ... def __ge__(self, other: object, /) -> bool: ... def __gt__(self, other: object, /) -> bool: ... @@ -147,7 +148,7 @@ class Column: @disjoint_base class ColumnExact: - data: Incomplete + data: Any def __init__(self) -> None: ... @disjoint_base @@ -250,8 +251,8 @@ class Conshdlr: @disjoint_base class Constant(GenExpr): - number: Incomplete - def __init__(self, *args: Incomplete, **kwargs: Incomplete) -> None: ... + number: SupportsFloat + def __init__(self, number: SupportsFloat) -> None: ... def __neg__(self, /) -> Constant: ... def __pow__( # type: ignore[override] self, other: float | Constant, mod: Incomplete = ..., / @@ -259,28 +260,28 @@ class Constant(GenExpr): @disjoint_base class Constraint: - data: Incomplete - name: Incomplete + data: Any + name: str def __init__(self) -> None: ... - def getConshdlrName(self) -> Incomplete: ... - def isActive(self) -> Incomplete: ... - def isChecked(self) -> Incomplete: ... - def isCumulative(self) -> Incomplete: ... - def isDynamic(self) -> Incomplete: ... - def isEnforced(self) -> Incomplete: ... - def isInitial(self) -> Incomplete: ... - def isKnapsack(self) -> Incomplete: ... - def isLinear(self) -> Incomplete: ... - def isLinearType(self) -> Incomplete: ... - def isLocal(self) -> Incomplete: ... - def isModifiable(self) -> Incomplete: ... - def isNonlinear(self) -> Incomplete: ... - def isOriginal(self) -> Incomplete: ... - def isPropagated(self) -> Incomplete: ... - def isRemovable(self) -> Incomplete: ... - def isSeparated(self) -> Incomplete: ... - def isStickingAtNode(self) -> Incomplete: ... - def ptr(self) -> Incomplete: ... + def getConshdlrName(self) -> str: ... + def isActive(self) -> bool: ... + def isChecked(self) -> bool: ... + def isCumulative(self) -> bool: ... + def isDynamic(self) -> bool: ... + def isEnforced(self) -> bool: ... + def isInitial(self) -> bool: ... + def isKnapsack(self) -> bool: ... + def isLinear(self) -> bool: ... + def isLinearType(self) -> bool: ... + def isLocal(self) -> bool: ... + def isModifiable(self) -> bool: ... + def isNonlinear(self) -> bool: ... + def isOriginal(self) -> bool: ... + def isPropagated(self) -> bool: ... + def isRemovable(self) -> bool: ... + def isSeparated(self) -> bool: ... + def isStickingAtNode(self) -> bool: ... + def ptr(self) -> int: ... def __eq__(self, other: object, /) -> bool: ... def __ge__(self, other: object, /) -> bool: ... def __gt__(self, other: object, /) -> bool: ... @@ -309,21 +310,21 @@ class Cutsel: @disjoint_base class DomainChanges: def __init__(self) -> None: ... - def getBoundchgs(self) -> Incomplete: ... + def getBoundchgs(self) -> list[BoundChange]: ... @disjoint_base class Event: - data: Incomplete + data: Any name: Incomplete def __init__(self) -> None: ... - def _getEventNames(self) -> Incomplete: ... - def getName(self) -> Incomplete: ... - def getNewBound(self) -> Incomplete: ... - def getNode(self) -> Incomplete: ... - def getOldBound(self) -> Incomplete: ... - def getRow(self) -> Incomplete: ... + def _getEventNames(self) -> None: ... + def getName(self) -> str: ... + def getNewBound(self) -> float: ... + def getNode(self) -> Node | None: ... + def getOldBound(self) -> float: ... + def getRow(self) -> Row: ... def getType(self) -> Incomplete: ... - def getVar(self) -> Incomplete: ... + def getVar(self) -> Variable: ... def __eq__(self, other: object, /) -> bool: ... def __ge__(self, other: object, /) -> bool: ... def __gt__(self, other: object, /) -> bool: ... @@ -379,9 +380,9 @@ class ExprLike: @disjoint_base class Expr(ExprLike): terms: Incomplete - def __init__(self, terms: Incomplete = ...) -> None: ... - def degree(self) -> Incomplete: ... - def normalize(self) -> Incomplete: ... + def __init__(self, terms: Incomplete = None) -> None: ... + def degree(self) -> int: ... + def normalize(self) -> None: ... def __neg__(self, /) -> Expr: ... @overload def __add__(self, other: float | Expr, /) -> Expr: ... @@ -428,24 +429,25 @@ class Expr(ExprLike): @disjoint_base class ExprCons: - _lhs: Incomplete - _rhs: Incomplete - expr: Incomplete + _lhs: float | None + _rhs: float | None + expr: Expr | GenExpr def __init__( - self, expr: Incomplete, lhs: Incomplete = ..., rhs: Incomplete = ... + self, expr: Expr | GenExpr, lhs: float | None = None, rhs: float | None = None ) -> None: ... - def normalize(self) -> Incomplete: ... + def normalize(self) -> None: ... def __bool__(self) -> bool: ... def __ge__(self, other: float, /) -> ExprCons: ... def __le__(self, other: float, /) -> ExprCons: ... @disjoint_base class GenExpr(ExprLike): - _op: Incomplete + _op: str | None children: Incomplete def __init__(self) -> None: ... - def degree(self) -> Incomplete: ... - def getOp(self) -> Incomplete: ... + def degree(self) -> float: ... + @deprecated("Deprecated since 6.3.0; use type(expr) instead.") + def getOp(self) -> str | None: ... def __neg__(self, /) -> ProdExpr | Constant: ... @overload def __add__(self, other: float | ExprLike, /) -> SumExpr: ... @@ -487,14 +489,14 @@ class Heur: @disjoint_base class IIS: def __init__(self) -> None: ... - def getNNodes(self) -> Incomplete: ... - def getSubscip(self) -> Incomplete: ... - def getTime(self) -> Incomplete: ... - def greedyMakeIrreducible(self) -> Incomplete: ... - def isSubscipInfeasible(self) -> Incomplete: ... - def isSubscipIrreducible(self) -> Incomplete: ... - def setSubscipInfeasible(self, infeasible: Incomplete) -> Incomplete: ... - def setSubscipIrreducible(self, irreducible: Incomplete) -> Incomplete: ... + def getNNodes(self) -> int: ... + def getSubscip(self) -> Model: ... + def getTime(self) -> float: ... + def greedyMakeIrreducible(self) -> None: ... + def isSubscipInfeasible(self) -> bool: ... + def isSubscipIrreducible(self) -> bool: ... + def setSubscipInfeasible(self, infeasible: bool) -> None: ... + def setSubscipIrreducible(self, irreducible: bool) -> None: ... @disjoint_base class IISfinder: @@ -506,72 +508,74 @@ class IISfinder: @disjoint_base class LP: - name: Incomplete - def __init__(self, name: Incomplete = ..., sense: Incomplete = ...) -> None: ... + name: str + def __init__( + self, name: str = "LP", sense: Literal["minimize", "maximize"] = "minimize" + ) -> None: ... def addCol( self, - entries: Incomplete, - obj: Incomplete = ..., - lb: Incomplete = ..., - ub: Incomplete = ..., - ) -> Incomplete: ... + entries: Sequence[tuple[int, float]], + obj: float = 0.0, + lb: float = 0.0, + ub: float | None = None, + ) -> None: ... def addCols( self, - entrieslist: Incomplete, - objs: Incomplete = ..., - lbs: Incomplete = ..., - ubs: Incomplete = ..., - ) -> Incomplete: ... + entrieslist: Sequence[Sequence[tuple[int, float]]], + objs: Sequence[float] | None = None, + lbs: Sequence[float] | None = None, + ubs: Sequence[float] | None = None, + ) -> None: ... def addRow( - self, entries: Incomplete, lhs: Incomplete = ..., rhs: Incomplete = ... - ) -> Incomplete: ... + self, + entries: Sequence[tuple[int, float]], + lhs: float = 0.0, + rhs: float | None = None, + ) -> None: ... def addRows( - self, entrieslist: Incomplete, lhss: Incomplete = ..., rhss: Incomplete = ... - ) -> Incomplete: ... - def chgBound( - self, col: Incomplete, lb: Incomplete, ub: Incomplete - ) -> Incomplete: ... - def chgCoef( - self, row: Incomplete, col: Incomplete, newval: Incomplete - ) -> Incomplete: ... - def chgObj(self, col: Incomplete, obj: Incomplete) -> Incomplete: ... - def chgSide( - self, row: Incomplete, lhs: Incomplete, rhs: Incomplete - ) -> Incomplete: ... - def clear(self) -> Incomplete: ... - def delCols(self, firstcol: Incomplete, lastcol: Incomplete) -> Incomplete: ... - def delRows(self, firstrow: Incomplete, lastrow: Incomplete) -> Incomplete: ... - def getActivity(self) -> Incomplete: ... - def getBase(self) -> Incomplete: ... - def getBasisInds(self) -> Incomplete: ... + self, + entrieslist: Sequence[Sequence[tuple[int, float]]], + lhss: Sequence[float] | None = None, + rhss: Sequence[float] | None = None, + ) -> None: ... + def chgBound(self, col: int, lb: float, ub: float) -> None: ... + def chgCoef(self, row: int, col: int, newval: float) -> None: ... + def chgObj(self, col: int, obj: float) -> None: ... + def chgSide(self, row: int, lhs: float, rhs: float) -> None: ... + def clear(self) -> None: ... + def delCols(self, firstcol: int, lastcol: int) -> None: ... + def delRows(self, firstrow: int, lastrow: int) -> None: ... + def getActivity(self) -> list[float]: ... + def getBase(self) -> tuple[list[Incomplete], list[Incomplete]]: ... + def getBasisInds(self) -> list[int]: ... def getBounds( - self, firstcol: Incomplete = ..., lastcol: Incomplete = ... - ) -> Incomplete: ... - def getDual(self) -> Incomplete: ... - def getDualRay(self) -> Incomplete: ... - def getIntParam(self, param: Incomplete) -> Incomplete: ... - def getNIterations(self) -> Incomplete: ... - def getObjVal(self) -> Incomplete: ... - def getPrimal(self) -> Incomplete: ... - def getPrimalRay(self) -> Incomplete: ... - def getRealParam(self, param: Incomplete) -> Incomplete: ... - def getRedcost(self) -> Incomplete: ... + self, firstcol: int = 0, lastcol: int | None = None + ) -> tuple[list[float], list[float]] | None: ... + def getDual(self) -> list[float]: ... + def getDualRay(self) -> list[float] | None: ... + def getIntParam(self, param: Incomplete) -> int: ... + def getNIterations(self) -> int: ... + def getObjVal(self) -> float: ... + def getPrimal(self) -> list[float]: ... + def getPrimalRay(self) -> list[float] | None: ... + def getRealParam(self, param: Incomplete) -> float: ... + def getRedcost(self) -> list[float]: ... def getSides( - self, firstrow: Incomplete = ..., lastrow: Incomplete = ... - ) -> Incomplete: ... - def infinity(self) -> Incomplete: ... - def isDualFeasible(self) -> Incomplete: ... - def isInfinity(self, val: Incomplete) -> Incomplete: ... - def isOptimal(self) -> Incomplete: ... - def isPrimalFeasible(self) -> Incomplete: ... - def ncols(self) -> Incomplete: ... - def nrows(self) -> Incomplete: ... - def readLP(self, filename: Incomplete) -> Incomplete: ... - def setBase(self, cstat: Incomplete, rstat: Incomplete) -> Incomplete: ... - def setIntParam(self, param: Incomplete, value: Incomplete) -> Incomplete: ... - def setRealParam(self, param: Incomplete, value: Incomplete) -> Incomplete: ... - def solve(self, dual: Incomplete = ...) -> Incomplete: ... - def writeLP(self, filename: Incomplete) -> Incomplete: ... + self, firstrow: int = 0, lastrow: int | None = None + ) -> tuple[list[float], list[float]] | None: ... + def infinity(self) -> float: ... + def isDualFeasible(self) -> bool: ... + def isInfinity(self, val: float) -> bool: ... + def isOptimal(self) -> bool: ... + def isPrimalFeasible(self) -> bool: ... + def ncols(self) -> int: ... + def nrows(self) -> int: ... + def readLP(self, filename: bytes | bytearray) -> None: ... + def setBase(self, cstat: Incomplete, rstat: Incomplete) -> None: ... + def setIntParam(self, param: Incomplete, value: int) -> None: ... + def setRealParam(self, param: Incomplete, value: float) -> None: ... + def solve(self, dual: bool = True) -> float: ... + def writeLP(self, filename: bytes | bytearray) -> None: ... class MatrixConstraint(np.ndarray): def getConshdlrName(self) -> Incomplete: ... @@ -590,7 +594,7 @@ class MatrixConstraint(np.ndarray): def isStickingAtNode(self) -> Incomplete: ... class MatrixExpr(np.ndarray): - def _evaluate(self, sol: Solution) -> Incomplete: ... + def _evaluate(self, sol: Solution) -> NDArray[np.object_]: ... def __array_ufunc__( self, ufunc: np.ufunc, @@ -645,26 +649,28 @@ class MatrixExprCons(np.ndarray): class MatrixGenExpr(MatrixExpr): ... class MatrixVariable(MatrixExpr): - def getAvgSol(self) -> Incomplete: ... - def getCol(self) -> Incomplete: ... - def getIndex(self) -> Incomplete: ... - def getLPSol(self) -> Incomplete: ... - def getLbGlobal(self) -> Incomplete: ... - def getLbLocal(self) -> Incomplete: ... - def getLbOriginal(self) -> Incomplete: ... - def getObj(self) -> Incomplete: ... - def getUbGlobal(self) -> Incomplete: ... - def getUbLocal(self) -> Incomplete: ... - def getUbOriginal(self) -> Incomplete: ... - def isInLP(self) -> Incomplete: ... - def varMayRound(self, direction: Incomplete = ...) -> Incomplete: ... - def vtype(self) -> Incomplete: ... + def getAvgSol(self) -> NDArray[np.float64]: ... + def getCol(self) -> NDArray[np.object_]: ... + def getIndex(self) -> NDArray[np.int_]: ... + def getLPSol(self) -> NDArray[np.float64]: ... + def getLbGlobal(self) -> NDArray[np.float64]: ... + def getLbLocal(self) -> NDArray[np.float64]: ... + def getLbOriginal(self) -> NDArray[np.float64]: ... + def getObj(self) -> NDArray[np.float64]: ... + def getUbGlobal(self) -> NDArray[np.float64]: ... + def getUbLocal(self) -> NDArray[np.float64]: ... + def getUbOriginal(self) -> NDArray[np.float64]: ... + def isInLP(self) -> NDArray[np.bool_]: ... + def varMayRound( + self, direction: Literal["up", "down"] = "down" + ) -> NDArray[np.bool_]: ... + def vtype(self) -> NDArray[np.object_]: ... def __pos__(self, /) -> MatrixExpr: ... # type: ignore[override] @disjoint_base class Model: - _freescip: Incomplete - data: Incomplete + _freescip: bool + data: Any def __init__( self, problemName: str = "model", @@ -676,11 +682,19 @@ class Model: createscip: bool = True, threadsafe: bool = False, ) -> None: ... - def _createConsGenNonlinear(self, cons: Incomplete) -> Incomplete: ... - def _createConsLinear(self, lincons: Incomplete) -> Incomplete: ... - def _createConsNonlinear(self, cons: Incomplete) -> Incomplete: ... - def _createConsQuadratic(self, quadcons: Incomplete) -> Incomplete: ... - def _getStageNames(self) -> Incomplete: ... + def _createConsGenNonlinear( + self, cons: ExprCons, **kwargs: Incomplete + ) -> Constraint: ... + def _createConsLinear( + self, lincons: ExprCons, **kwargs: Incomplete + ) -> Constraint: ... + def _createConsNonlinear( + self, cons: ExprCons, **kwargs: Incomplete + ) -> Constraint: ... + def _createConsQuadratic( + self, quadcons: ExprCons, **kwargs: Incomplete + ) -> Constraint: ... + def _getStageNames(self) -> None: ... def activateBenders(self, benders: Benders, nsubproblems: int) -> None: ... def addBendersSubproblem(self, benders: Benders, subproblem: Model) -> None: ... def addCoefKnapsack( @@ -690,7 +704,7 @@ class Model: def addCoefLogicor(self, logicor_cons: Constraint, var: Variable) -> None: ... def addCons( self, - cons: Incomplete, + cons: ExprCons, name: str = "", initial: bool = True, separate: bool = True, @@ -757,7 +771,7 @@ class Model: ) -> Constraint: ... def addConsDisjunction( self, - conss: Iterable[Incomplete], + conss: Iterable[ExprCons], name: str = "", initial: bool = True, relaxcons: Constraint | None = None, @@ -772,7 +786,7 @@ class Model: ) -> Constraint: ... def addConsIndicator( self, - cons: Incomplete, + cons: ExprCons, binvar: Variable | None = None, activeone: bool = True, name: str = "", @@ -805,7 +819,7 @@ class Model: ) -> Constraint: ... def addConsLocal( self, - cons: Incomplete, + cons: ExprCons, validnode: Node | None = None, name: str = "", initial: bool = True, @@ -836,7 +850,7 @@ class Model: def addConsNode( self, node: Node, - cons: Incomplete, + cons: ExprCons, validnode: Node | None = None, name: str = "", initial: bool = True, @@ -913,7 +927,7 @@ class Model: ) -> Constraint: ... def addConss( self, - conss: Iterable[Incomplete], + conss: Iterable[ExprCons] | MatrixExprCons, name: str | Iterable[str] = "", initial: bool | Iterable[bool] = True, separate: bool | Iterable[bool] = True, @@ -928,11 +942,11 @@ class Model: ) -> list[Constraint]: ... def addCut(self, cut: Row, forcecut: bool = False) -> bool: ... def addExprNonlinear( - self, cons: Constraint, expr: Incomplete, coef: float + self, cons: Constraint, expr: Expr | GenExpr, coef: float ) -> None: ... def addMatrixCons( self, - cons: Incomplete, + cons: ExprCons | MatrixExprCons, name: str | np.ndarray = "", initial: bool | np.ndarray = True, separate: bool | np.ndarray = True, @@ -947,7 +961,7 @@ class Model: ) -> Constraint | MatrixConstraint: ... def addMatrixConsDisjunction( self, - conss: Incomplete, + conss: Iterable[ExprCons | MatrixExprCons], name: str | np.ndarray = "", initial: bool | np.ndarray = True, relaxcons: None = None, @@ -956,10 +970,10 @@ class Model: local: bool | np.ndarray = False, modifiable: bool | np.ndarray = False, dynamic: bool | np.ndarray = False, - ) -> Incomplete: ... + ) -> Constraint | MatrixConstraint: ... def addMatrixConsIndicator( self, - cons: Incomplete, + cons: ExprCons | MatrixExprCons, binvar: Variable | MatrixVariable | None = None, activeone: bool | np.ndarray = True, name: str | np.ndarray = "", @@ -1109,7 +1123,7 @@ class Model: ) -> Constraint: ... def createConsFromExpr( self, - cons: Incomplete, + cons: ExprCons, name: str = "", initial: bool = True, separate: bool = True, @@ -1177,6 +1191,9 @@ class Model: def flushRowExtensions(self, row: Row) -> None: ... def frac(self, value: float) -> float: ... def free(self) -> None: ... + @deprecated( + "Deprecated since 5.7.0; Benders subproblems are freed automatically when the master Model is deallocated." + ) def freeBendersSubproblems(self) -> None: ... def freeProb(self) -> None: ... def freeReoptSolve(self) -> None: ... @@ -1234,6 +1251,7 @@ class Model: def getDepth(self) -> int: ... def getDeterministicTime(self) -> float: ... def getFirstPrimalBound(self) -> float: ... + @deprecated("Use Model.getDualsolLinear(cons) instead.") def getDualMultiplier(self, cons: Constraint) -> float: ... def getDualSolVal( self, cons: Constraint, boundconstraint: bool = False @@ -1306,7 +1324,7 @@ class Model: def getNSols(self) -> int: ... def getNSolsFound(self) -> int: ... def getNStrongbranchLPIterations(self) -> int: ... - def getPrimalDualIntegral(self) -> Incomplete: ... + def getPrimalDualIntegral(self) -> float: ... def getNTotalNodes(self) -> int: ... def getNVars(self, transformed: bool = True) -> int: ... def getNVarsAnd(self, and_cons: Constraint) -> int: ... @@ -1584,7 +1602,7 @@ class Model: def isNLPConstructed(self) -> bool: ... def isNegative(self, val: float) -> bool: ... def isObjChangedProbing(self) -> bool: ... - def isObjIntegral(self) -> Incomplete: ... + def isObjIntegral(self) -> bool: ... def isPositive(self, val: float) -> bool: ... def isReoptEnabled(self) -> bool: ... def isZero(self, value: float) -> bool: ... @@ -1606,9 +1624,7 @@ class Model: def printSol( self, solution: Solution | None = None, write_zeros: bool = False ) -> None: ... - def printStatistics( - self, filename: str | os.PathLike[str] | None = None - ) -> None: ... + def printStatistics(self, filename: StrOrBytesPath | None = None) -> None: ... def printStatisticsJson(self) -> None: ... def printVersion(self) -> None: ... def propagateProbing(self, maxproprounds: int) -> tuple[bool, int]: ... @@ -1687,10 +1703,10 @@ class Model: def solveProbingLP(self, itlim: int = -1) -> tuple[bool, bool]: ... def solveProbingLPWithPricing( self, - pretendroot: Incomplete = ..., - displayinfo: Incomplete = ..., - maxpricerounds: Incomplete = ..., - ) -> Incomplete: ... + pretendroot: bool = False, + displayinfo: bool = False, + maxpricerounds: int = -1, + ) -> tuple[bool, bool]: ... def sortAndCons(self, and_cons: Constraint) -> None: ... def startDive(self) -> None: ... def startProbing(self) -> None: ... @@ -1731,12 +1747,12 @@ class Model: def version(self) -> float: ... def writeBestSol( self, - filename: str | bytes | os.PathLike[AnyStr] = "origprob.sol", + filename: StrOrBytesPath = "origprob.sol", write_zeros: bool = False, ) -> None: ... def writeBestTransSol( self, - filename: str | bytes | os.PathLike[AnyStr] = "transprob.sol", + filename: StrOrBytesPath = "transprob.sol", write_zeros: bool = False, ) -> None: ... def writeLP(self, filename: str | os.PathLike[str] = "LP.lp") -> None: ... @@ -1757,7 +1773,7 @@ class Model: ) -> None: ... def writeProblem( self, - filename: str | os.PathLike[str] = "model.cip", + filename: str | os.PathLike[str] | None = "model.cip", trans: bool = False, genericnames: bool = False, verbose: bool = True, @@ -1765,19 +1781,17 @@ class Model: def writeSol( self, solution: Solution, - filename: str | bytes | os.PathLike[AnyStr] = "origprob.sol", + filename: StrOrBytesPath = "origprob.sol", write_zeros: bool = False, ) -> None: ... - def writeStatistics( - self, filename: str | bytes | os.PathLike[AnyStr] = "origprob.stats" - ) -> None: ... + def writeStatistics(self, filename: StrOrBytesPath = "origprob.stats") -> None: ... def writeStatisticsJson( - self, filename: str | os.PathLike[str] = "origprob.stats.json" + self, filename: StrOrBytesPath = "origprob.stats.json" ) -> None: ... def writeTransSol( self, solution: Solution, - filename: str | bytes | os.PathLike[AnyStr] = "transprob.sol", + filename: StrOrBytesPath = "transprob.sol", write_zeros: bool = False, ) -> None: ... def __eq__(self, other: object, /) -> bool: ... @@ -1790,14 +1804,14 @@ class Model: @disjoint_base class NLRow: - data: Incomplete - name: Incomplete + data: Any + name: str def __init__(self) -> None: ... - def getConstant(self) -> Incomplete: ... - def getDualsol(self) -> Incomplete: ... - def getLhs(self) -> Incomplete: ... - def getLinearTerms(self) -> Incomplete: ... - def getRhs(self) -> Incomplete: ... + def getConstant(self) -> float: ... + def getDualsol(self) -> float: ... + def getLhs(self) -> float: ... + def getLinearTerms(self) -> list[tuple[Variable, float]]: ... + def getRhs(self) -> float: ... def __eq__(self, other: object, /) -> bool: ... def __ge__(self, other: object, /) -> bool: ... def __gt__(self, other: object, /) -> bool: ... @@ -1808,22 +1822,24 @@ class NLRow: @disjoint_base class Node: - data: Incomplete + data: Any def __init__(self) -> None: ... - def getAddedConss(self) -> Incomplete: ... - def getDepth(self) -> Incomplete: ... - def getDomchg(self) -> Incomplete: ... - def getEstimate(self) -> Incomplete: ... - def getLowerbound(self) -> Incomplete: ... - def getNAddedConss(self) -> Incomplete: ... - def getNDomchg(self) -> Incomplete: ... - def getNParentBranchings(self) -> Incomplete: ... - def getNumber(self) -> Incomplete: ... - def getParent(self) -> Incomplete: ... - def getParentBranchings(self) -> Incomplete: ... + def getAddedConss(self) -> list[Constraint]: ... + def getDepth(self) -> int: ... + def getDomchg(self) -> DomainChanges | None: ... + def getEstimate(self) -> float: ... + def getLowerbound(self) -> float: ... + def getNAddedConss(self) -> int: ... + def getNDomchg(self) -> tuple[int, int, int]: ... + def getNParentBranchings(self) -> int: ... + def getNumber(self) -> int: ... + def getParent(self) -> Node | None: ... + def getParentBranchings( + self, + ) -> tuple[list[Variable], list[float], list[Incomplete]] | None: ... def getType(self) -> Incomplete: ... - def isActive(self) -> Incomplete: ... - def isPropagatedAgain(self) -> Incomplete: ... + def isActive(self) -> bool: ... + def isPropagatedAgain(self) -> bool: ... def __eq__(self, other: object, /) -> bool: ... def __ge__(self, other: object, /) -> bool: ... def __gt__(self, other: object, /) -> bool: ... @@ -1844,6 +1860,7 @@ class Nodesel: def nodeinitsol(self) -> Incomplete: ... def nodeselect(self) -> Incomplete: ... +@deprecated("Use type(expr) to check the expression type instead.") class Op: add: ClassVar[str] = ... const: ClassVar[str] = ... @@ -2127,8 +2144,8 @@ class PY_SCIP_STATUS: @disjoint_base class PowExpr(GenExpr): - expo: Incomplete - def __init__(self, *args: Incomplete, **kwargs: Incomplete) -> None: ... + expo: SupportsFloat + def __init__(self) -> None: ... def __neg__(self, /) -> ProdExpr: ... @disjoint_base @@ -2158,8 +2175,8 @@ class Pricer: @disjoint_base class ProdExpr(GenExpr): - constant: Incomplete - def __init__(self, *args: Incomplete, **kwargs: Incomplete) -> None: ... + constant: SupportsFloat + def __init__(self) -> None: ... def __neg__(self, /) -> ProdExpr: ... @disjoint_base @@ -2226,29 +2243,29 @@ class Relax: @disjoint_base class Row: - data: Incomplete - name: Incomplete + data: Any + name: str def __init__(self) -> None: ... - def getAge(self) -> Incomplete: ... - def getBasisStatus(self) -> Incomplete: ... - def getCols(self) -> Incomplete: ... - def getConsOriginConshdlrtype(self) -> Incomplete: ... - def getConstant(self) -> Incomplete: ... - def getDualfarkas(self) -> Incomplete: ... - def getDualsol(self) -> Incomplete: ... - def getLPPos(self) -> Incomplete: ... - def getLhs(self) -> Incomplete: ... - def getNLPNonz(self) -> Incomplete: ... - def getNNonz(self) -> Incomplete: ... - def getNorm(self) -> Incomplete: ... + def getAge(self) -> int: ... + def getBasisStatus(self) -> Literal["lower", "basic", "upper"]: ... + def getCols(self) -> list[Column]: ... + def getConsOriginConshdlrtype(self) -> str: ... + def getConstant(self) -> float: ... + def getDualfarkas(self) -> float: ... + def getDualsol(self) -> float: ... + def getLPPos(self) -> int: ... + def getLhs(self) -> float: ... + def getNLPNonz(self) -> int: ... + def getNNonz(self) -> int: ... + def getNorm(self) -> float: ... def getOrigintype(self) -> Incomplete: ... - def getRhs(self) -> Incomplete: ... - def getVals(self) -> Incomplete: ... - def isInGlobalCutpool(self) -> Incomplete: ... - def isIntegral(self) -> Incomplete: ... - def isLocal(self) -> Incomplete: ... - def isModifiable(self) -> Incomplete: ... - def isRemovable(self) -> Incomplete: ... + def getRhs(self) -> float: ... + def getVals(self) -> list[float]: ... + def isInGlobalCutpool(self) -> bool: ... + def isIntegral(self) -> bool: ... + def isLocal(self) -> bool: ... + def isModifiable(self) -> bool: ... + def isRemovable(self) -> bool: ... def __eq__(self, other: object, /) -> bool: ... def __ge__(self, other: object, /) -> bool: ... def __gt__(self, other: object, /) -> bool: ... @@ -2259,7 +2276,7 @@ class Row: @disjoint_base class RowExact: - data: Incomplete + data: Any def __init__(self) -> None: ... @disjoint_base @@ -2277,14 +2294,17 @@ class Sepa: @disjoint_base class Solution: - data: Incomplete - def __init__(self, raise_error: Incomplete = ...) -> None: ... - def _checkStage(self, method: Incomplete) -> Incomplete: ... + data: Any + def __init__(self, raise_error: bool = True) -> None: ... + def _checkStage(self, method: str) -> None: ... def getOrigin(self) -> Incomplete: ... - def retransform(self) -> Incomplete: ... - def translate(self, target: Incomplete) -> Incomplete: ... - def __getitem__(self, index: Incomplete, /) -> Incomplete: ... - def __setitem__(self, key: Incomplete, value: Incomplete, /) -> None: ... + def retransform(self) -> None: ... + def translate(self, target: Model) -> Solution: ... + @overload + def __getitem__(self, index: Expr | GenExpr, /) -> float: ... + @overload + def __getitem__(self, index: MatrixExpr, /) -> np.ndarray: ... + def __setitem__(self, key: Variable, value: float, /) -> None: ... class Statistics: status: str @@ -2354,14 +2374,14 @@ class Statistics: @disjoint_base class SumExpr(GenExpr): - constant: Incomplete - def __init__(self, *args: Incomplete, **kwargs: Incomplete) -> None: ... + constant: SupportsFloat + def __init__(self) -> None: ... def __neg__(self, /) -> ProdExpr: ... @disjoint_base class Term: - vartuple: Incomplete - def __init__(self, *vartuple: Incomplete) -> None: ... + vartuple: tuple[Variable, ...] + def __init__(self, *vartuple: Variable) -> None: ... def __mul__(self, other: Term, /) -> Term: ... def __eq__(self, other: object, /) -> bool: ... def __ge__(self, other: object, /) -> bool: ... @@ -2374,7 +2394,7 @@ class Term: def __ne__(self, other: object, /) -> bool: ... class UnaryExpr(GenExpr): - def __init__(self, *args: Incomplete, **kwargs: Incomplete) -> None: ... + def __init__(self, op: str, expr: GenExpr) -> None: ... def __neg__(self, /) -> ProdExpr: ... class AbsExpr(UnaryExpr): ... @@ -2387,46 +2407,50 @@ class CosExpr(UnaryExpr): ... @disjoint_base class VarExpr(GenExpr): var: Incomplete - def __init__(self, *args: Incomplete, **kwargs: Incomplete) -> None: ... + def __init__(self, var: Expr) -> None: ... def __neg__(self, /) -> ProdExpr: ... @disjoint_base class Variable(Expr): - data: Incomplete - name: Incomplete + data: Any + name: str def __init__(self) -> None: ... - def getAvgSol(self) -> Incomplete: ... - def getCol(self) -> Incomplete: ... + def getAvgSol(self) -> float: ... + def getCol(self) -> Column: ... def getImplType(self) -> Incomplete: ... - def getIndex(self) -> Incomplete: ... - def getLPSol(self) -> Incomplete: ... - def getLbGlobal(self) -> Incomplete: ... - def getLbLocal(self) -> Incomplete: ... - def getLbOriginal(self) -> Incomplete: ... - def getNBranchings(self, branchdir: Incomplete) -> Incomplete: ... - def getNBranchingsCurrentRun(self, branchdir: Incomplete) -> Incomplete: ... - def getNLocksDown(self) -> Incomplete: ... - def getNLocksDownType(self, locktype: Incomplete) -> Incomplete: ... - def getNLocksUp(self) -> Incomplete: ... - def getNLocksUpType(self, locktype: Incomplete) -> Incomplete: ... - def getObj(self) -> Incomplete: ... - def getStatus(self) -> Incomplete: ... - def getUbGlobal(self) -> Incomplete: ... - def getUbLocal(self) -> Incomplete: ... - def getUbOriginal(self) -> Incomplete: ... - def isActive(self) -> Incomplete: ... - def isBinary(self) -> Incomplete: ... - def isDeletable(self) -> Incomplete: ... - def isImpliedIntegral(self) -> Incomplete: ... - def isInLP(self) -> Incomplete: ... - def isIntegral(self) -> Incomplete: ... - def isNonImpliedIntegral(self) -> Incomplete: ... - def isOriginal(self) -> Incomplete: ... - def isRelaxationOnly(self) -> Incomplete: ... - def markRelaxationOnly(self) -> Incomplete: ... - def ptr(self) -> Incomplete: ... - def varMayRound(self, direction: Incomplete = ...) -> Incomplete: ... - def vtype(self) -> Incomplete: ... + def getIndex(self) -> int: ... + def getLPSol(self) -> float: ... + def getLbGlobal(self) -> float: ... + def getLbLocal(self) -> float: ... + def getLbOriginal(self) -> float: ... + def getNBranchings(self, branchdir: Incomplete) -> int: ... + def getNBranchingsCurrentRun(self, branchdir: Incomplete) -> int: ... + def getNLocksDown(self) -> int: ... + def getNLocksDownType(self, locktype: Incomplete) -> int: ... + def getNLocksUp(self) -> int: ... + def getNLocksUpType(self, locktype: Incomplete) -> int: ... + def getObj(self) -> float: ... + def getStatus( + self, + ) -> Literal[ + "ORIGINAL", "LOOSE", "COLUMN", "FIXED", "AGGREGATED", "MULTAGGR", "NEGATED" + ]: ... + def getUbGlobal(self) -> float: ... + def getUbLocal(self) -> float: ... + def getUbOriginal(self) -> float: ... + def isActive(self) -> bool: ... + def isBinary(self) -> bool: ... + def isDeletable(self) -> bool: ... + def isImpliedIntegral(self) -> bool: ... + def isInLP(self) -> bool: ... + def isIntegral(self) -> bool: ... + def isNonImpliedIntegral(self) -> bool: ... + def isOriginal(self) -> bool: ... + def isRelaxationOnly(self) -> bool: ... + def markRelaxationOnly(self) -> None: ... + def ptr(self) -> int: ... + def varMayRound(self, direction: Literal["up", "down"] = "down") -> bool: ... + def vtype(self) -> Literal["BINARY", "INTEGER", "CONTINUOUS", "IMPLINT"]: ... @disjoint_base class _VarArray: diff --git a/stubs/allowlist b/stubs/allowlist index dc849f74c..33d6a8c28 100644 --- a/stubs/allowlist +++ b/stubs/allowlist @@ -7,3 +7,7 @@ pyscipopt.scip.ExprLike.__rmul__ pyscipopt.scip.ExprLike.__rsub__ pyscipopt.scip.ExprLike.__rtruediv__ pyscipopt.scip.ExprLike.__sub__ +# Cython exposes generic signatures; these constructors reject arguments at runtime. +pyscipopt.scip.PowExpr.__init__ +pyscipopt.scip.ProdExpr.__init__ +pyscipopt.scip.SumExpr.__init__