Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add type hints and type loop variables #946

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
2 changes: 2 additions & 0 deletions src/pyscipopt/benders.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ cdef SCIP_RETCODE PyBendersPostsolve (SCIP* scip, SCIP_BENDERS* benders, SCIP_SO
SCIP_BENDERSENFOTYPE type, int* mergecands, int npriomergecands, int nmergecands, SCIP_Bool checkint,
SCIP_Bool infeasible, SCIP_Bool* merged) noexcept with gil:
cdef SCIP_BENDERSDATA* bendersdata
cdef int i

bendersdata = SCIPbendersGetData(benders)
PyBenders = <Benders>bendersdata
if sol == NULL:
Expand Down
6 changes: 3 additions & 3 deletions src/pyscipopt/branchrule.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@
'''informs branching rule that the branch and bound process data is being freed'''
pass

def branchexeclp(self, allowaddcons):
def branchexeclp(self, SCIP_Bool allowaddcons):

Check warning on line 26 in src/pyscipopt/branchrule.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/branchrule.pxi#L26

Added line #L26 was not covered by tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these methods not defined with cdef? I would say in the python world we should use bool and in the c world SCIP_Bool. So where are we here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I said in the bigger comment, these functions should be accessible from the Python side, so we need to use def.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I guess to avoid confusion we should also use bool instead of SCIP_Bool and convert when entering the C world again.

Copy link
Collaborator

@Opt-Mucca Opt-Mucca Jan 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SCIP_Bool does not make sense here. The user should never have access to such a type and the type hint should simply be bool (like Dominik suggested).
Cython will handle the conversion or use a local declaration of SCIP_Bool inside of the function.

'''executes branching rule for fractional LP solution'''
raise NotImplementedError("branchexeclp() is a fundamental callback and should be implemented in the derived "
"class")

def branchexecext(self, allowaddcons):
def branchexecext(self, SCIP_Bool allowaddcons):

Check warning on line 31 in src/pyscipopt/branchrule.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/branchrule.pxi#L31

Added line #L31 was not covered by tests
'''executes branching rule for external branching candidates '''
raise NotImplementedError("branchexecext() is a fundamental callback and should be implemented in the derived class")

def branchexecps(self, allowaddcons):
def branchexecps(self, SCIP_Bool allowaddcons):

Check warning on line 35 in src/pyscipopt/branchrule.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/branchrule.pxi#L35

Added line #L35 was not covered by tests
'''executes branching rule for not completely fixed pseudo solution '''
# this method needs to be implemented by the user
raise NotImplementedError("branchexecps() is a fundamental callback and should be implemented in the derived class")
Expand Down
56 changes: 36 additions & 20 deletions src/pyscipopt/conshdlr.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
'''informs constraint handler that the branch and bound process is being started '''
pass

def consexitsol(self, constraints, restart):
def consexitsol(self, constraints, SCIP_Bool restart):

Check warning on line 32 in src/pyscipopt/conshdlr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/conshdlr.pxi#L32

Added line #L32 was not covered by tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about constraints?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure if they were allowed to be just one or not and was too lazy to check

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is the list of constraints, I would not allow it to be a single constraint, can we declare it an iterable?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can declare something as an iterable in Python type hints. We might need to then import the collections library

'''informs constraint handler that the branch and bound process data is being freed '''
pass

Expand All @@ -45,74 +45,74 @@
'''calls LP initialization method of constraint handler to separate all initial active constraints '''
return {}

def conssepalp(self, constraints, nusefulconss):
def conssepalp(self, constraints, int nusefulconss):

Check warning on line 48 in src/pyscipopt/conshdlr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/conshdlr.pxi#L48

Added line #L48 was not covered by tests
'''calls separator method of constraint handler to separate LP solution '''
return {}

def conssepasol(self, constraints, nusefulconss, solution):
def conssepasol(self, constraints, int nusefulconss, Solution solution):

Check warning on line 52 in src/pyscipopt/conshdlr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/conshdlr.pxi#L52

Added line #L52 was not covered by tests
'''calls separator method of constraint handler to separate given primal solution '''
return {}

def consenfolp(self, constraints, nusefulconss, solinfeasible):
def consenfolp(self, constraints, int nusefulconss, SCIP_Bool solinfeasible):

Check warning on line 56 in src/pyscipopt/conshdlr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/conshdlr.pxi#L56

Added line #L56 was not covered by tests
'''calls enforcing method of constraint handler for LP solution for all constraints added'''
print("python error in consenfolp: this method needs to be implemented")
return {}

def consenforelax(self, solution, constraints, nusefulconss, solinfeasible):
def consenforelax(self, Solution solution, constraints, int nusefulconss, solinfeasible):

Check warning on line 61 in src/pyscipopt/conshdlr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/conshdlr.pxi#L61

Added line #L61 was not covered by tests
'''calls enforcing method of constraint handler for a relaxation solution for all constraints added'''
print("python error in consenforelax: this method needs to be implemented")
return {}

def consenfops(self, constraints, nusefulconss, solinfeasible, objinfeasible):
def consenfops(self, constraints, int nusefulconss, SCIP_Bool solinfeasible, SCIP_Bool objinfeasible):

Check warning on line 66 in src/pyscipopt/conshdlr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/conshdlr.pxi#L66

Added line #L66 was not covered by tests
'''calls enforcing method of constraint handler for pseudo solution for all constraints added'''
print("python error in consenfops: this method needs to be implemented")
return {}

def conscheck(self, constraints, solution, checkintegrality, checklprows, printreason, completely):
def conscheck(self, constraints, Solution solution, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool printreason, SCIP_Bool completely):

Check warning on line 71 in src/pyscipopt/conshdlr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/conshdlr.pxi#L71

Added line #L71 was not covered by tests
'''calls feasibility check method of constraint handler '''
print("python error in conscheck: this method needs to be implemented")
return {}

def consprop(self, constraints, nusefulconss, nmarkedconss, proptiming):
def consprop(self, constraints, int nusefulconss, int nmarkedconss, SCIP_PROPTIMING proptiming):

Check warning on line 76 in src/pyscipopt/conshdlr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/conshdlr.pxi#L76

Added line #L76 was not covered by tests
'''calls propagation method of constraint handler '''
return {}

def conspresol(self, constraints, nrounds, presoltiming,
nnewfixedvars, nnewaggrvars, nnewchgvartypes, nnewchgbds, nnewholes,
nnewdelconss, nnewaddconss, nnewupgdconss, nnewchgcoefs, nnewchgsides, result_dict):
def conspresol(self, constraints, int nrounds, SCIP_PRESOLTIMING presoltiming,

Check warning on line 80 in src/pyscipopt/conshdlr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/conshdlr.pxi#L80

Added line #L80 was not covered by tests
int nnewfixedvars, int nnewaggrvars, int nnewchgvartypes, int nnewchgbds, int nnewholes,
int nnewdelconss, int nnewaddconss, int nnewupgdconss, int nnewchgcoefs, int nnewchgsides, result_dict):
'''calls presolving method of constraint handler '''
return result_dict

def consresprop(self):
'''sets propagation conflict resolving method of constraint handler '''
return {}

def conslock(self, constraint, locktype, nlockspos, nlocksneg):
def conslock(self, constraint: Union[Constraint, ExprCons], int locktype, int nlockspos, int nlocksneg):

Check warning on line 90 in src/pyscipopt/conshdlr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/conshdlr.pxi#L90

Added line #L90 was not covered by tests
'''variable rounding lock method of constraint handler'''
print("python error in conslock: this method needs to be implemented")
return {}

def consactive(self, constraint):
def consactive(self, constraint: Union[Constraint, ExprCons]):

Check warning on line 95 in src/pyscipopt/conshdlr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/conshdlr.pxi#L95

Added line #L95 was not covered by tests
'''sets activation notification method of constraint handler '''
pass

def consdeactive(self, constraint):
def consdeactive(self, constraint: Union[Constraint, ExprCons]):

Check warning on line 99 in src/pyscipopt/conshdlr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/conshdlr.pxi#L99

Added line #L99 was not covered by tests
'''sets deactivation notification method of constraint handler '''
pass

def consenable(self, constraint):
def consenable(self, constraint: Union[Constraint, ExprCons]):

Check warning on line 103 in src/pyscipopt/conshdlr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/conshdlr.pxi#L103

Added line #L103 was not covered by tests
'''sets enabling notification method of constraint handler '''
pass

def consdisable(self, constraint):
def consdisable(self, constraint: Union[Constraint, ExprCons]):

Check warning on line 107 in src/pyscipopt/conshdlr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/conshdlr.pxi#L107

Added line #L107 was not covered by tests
'''sets disabling notification method of constraint handler '''
pass

def consdelvars(self, constraints):
def consdelvars(self, constraint: Union[Constraint, ExprCons]):

Check warning on line 111 in src/pyscipopt/conshdlr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/conshdlr.pxi#L111

Added line #L111 was not covered by tests
'''calls variable deletion method of constraint handler'''
pass

def consprint(self, constraint):
def consprint(self, constraint: Union[Constraint, ExprCons]):

Check warning on line 115 in src/pyscipopt/conshdlr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/conshdlr.pxi#L115

Added line #L115 was not covered by tests
'''sets constraint display method of constraint handler '''
pass

Expand All @@ -124,11 +124,11 @@
'''sets constraint parsing method of constraint handler '''
pass

def consgetvars(self, constraint):
def consgetvars(self, constraint: Union[Constraint, ExprCons]):

Check warning on line 127 in src/pyscipopt/conshdlr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/conshdlr.pxi#L127

Added line #L127 was not covered by tests
'''sets constraint variable getter method of constraint handler'''
pass

def consgetnvars(self, constraint):
def consgetnvars(self, constraint: Union[Constraint, ExprCons]):

Check warning on line 131 in src/pyscipopt/conshdlr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/conshdlr.pxi#L131

Added line #L131 was not covered by tests
'''sets constraint variable number getter method of constraint handler '''
return {}

Expand Down Expand Up @@ -169,6 +169,7 @@

cdef SCIP_RETCODE PyConsInit (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef int i
cdef constraints = []
Joao-Dionisio marked this conversation as resolved.
Show resolved Hide resolved
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
Expand All @@ -178,6 +179,7 @@
cdef SCIP_RETCODE PyConsExit (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
PyConshdlr.consexit(constraints)
Expand All @@ -186,6 +188,7 @@
cdef SCIP_RETCODE PyConsInitpre (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
PyConshdlr.consinitpre(constraints)
Expand All @@ -194,6 +197,7 @@
cdef SCIP_RETCODE PyConsExitpre (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
PyConshdlr.consexitpre(constraints)
Expand All @@ -202,6 +206,7 @@
cdef SCIP_RETCODE PyConsInitsol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
PyConshdlr.consinitsol(constraints)
Expand All @@ -210,6 +215,7 @@
cdef SCIP_RETCODE PyConsExitsol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, SCIP_Bool restart) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
PyConshdlr.consexitsol(constraints, restart)
Expand Down Expand Up @@ -246,6 +252,7 @@
cdef SCIP_RETCODE PyConsInitlp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, SCIP_Bool* infeasible) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
result_dict = PyConshdlr.consinitlp(constraints)
Expand All @@ -255,6 +262,7 @@
cdef SCIP_RETCODE PyConsSepalp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, int nusefulconss, SCIP_RESULT* result) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
result_dict = PyConshdlr.conssepalp(constraints, nusefulconss)
Expand All @@ -265,6 +273,7 @@
SCIP_SOL* sol, SCIP_RESULT* result) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
solution = Solution.create(scip, sol)
Expand All @@ -276,6 +285,7 @@
SCIP_Bool solinfeasible, SCIP_RESULT* result) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
result_dict = PyConshdlr.consenfolp(constraints, nusefulconss, solinfeasible)
Expand All @@ -285,6 +295,7 @@
cdef SCIP_RETCODE PyConsEnforelax (SCIP* scip, SCIP_SOL* sol, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, int nusefulconss, SCIP_Bool solinfeasible, SCIP_RESULT* result) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
solution = Solution.create(scip, sol)
Expand All @@ -296,6 +307,7 @@
SCIP_Bool solinfeasible, SCIP_Bool objinfeasible, SCIP_RESULT* result) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
result_dict = PyConshdlr.consenfops(constraints, nusefulconss, solinfeasible, objinfeasible)
Expand All @@ -306,6 +318,7 @@
SCIP_Bool checklprows, SCIP_Bool printreason, SCIP_Bool completely, SCIP_RESULT* result) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
solution = Solution.create(scip, sol)
Expand All @@ -317,6 +330,7 @@
SCIP_PROPTIMING proptiming, SCIP_RESULT* result) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
result_dict = PyConshdlr.consprop(constraints, nusefulconss, nmarkedconss, proptiming)
Expand All @@ -330,6 +344,7 @@
int* ndelconss, int* naddconss, int* nupgdconss, int* nchgcoefs, int* nchgsides, SCIP_RESULT* result) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
# dictionary for input/output parameters
Expand Down Expand Up @@ -403,6 +418,7 @@
cdef SCIP_RETCODE PyConsDelvars (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
PyConshdlr.consdelvars(constraints)
Expand Down
5 changes: 3 additions & 2 deletions src/pyscipopt/cutsel.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
'''executed before the branch-and-bound process is freed'''
pass

def cutselselect(self, cuts, forcedcuts, root, maxnselectedcuts):
def cutselselect(self, list[SCIP_ROW] cuts, int forcedcuts, SCIP_Bool root, int maxnselectedcuts):

Check warning on line 26 in src/pyscipopt/cutsel.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/cutsel.pxi#L26

Added line #L26 was not covered by tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess if we have def then the int means the Python int whereas SCIP_Bool is the C unsigned int, or am I wrong?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not entirely sure how this works, because in things like addCons I type all the options as SCIP_Bools, but then assign them Python booleans. I guess Cython makes some kind of automatic conversion?

Copy link
Contributor

@DominikKamp DominikKamp Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I am not aware of the Cython rules, but I find these type declarations confusing because

  1. list[SCIP_ROW] seems to be a Python-container of a C-type
  2. int is the C-int
  3. SCIP_Bool is the C-uint

and since this should be a Python-callback, I would prefer if it is consistently supplied with Python-objects.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also not sure about Cython, but I think there must be a definitive difference between this callback and a normal Python function. That's because using this sort of syntax (e.g. int forcedcuts) leads to an invalid syntax error.

Type hints in Python would use the following syntax (and not be enforced, making them somewhat useless):

def cutselselect(self, cuts: list[SCIP_ROW] , forcedcuts: int, root: bool, maxnselectedcuts: int):

Further, in these callbacks, bool is not recognized as a type identifier.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we're mixing type hints and variable type declarations here.
Regardless: list[SCIP_ROW] would be incorrect because the callback receives list[Row], where one in theory could then access row._scip_row, which has type SCIP_ROW.

'''first method called in each iteration in the main solving loop. '''
# this method needs to be implemented by the user
return {}
Expand Down Expand Up @@ -76,7 +76,8 @@
cdef SCIP_ROW* scip_row
cutseldata = SCIPcutselGetData(cutsel)
PyCutsel = <Cutsel>cutseldata

cdef int i

Joao-Dionisio marked this conversation as resolved.
Show resolved Hide resolved
# translate cuts to python
pycuts = [Row.create(cuts[i]) for i in range(ncuts)]
pyforcedcuts = [Row.create(forcedcuts[i]) for i in range(nforcedcuts)]
Expand Down
19 changes: 10 additions & 9 deletions src/pyscipopt/expr.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
return False


def _expr_richcmp(self, other, op):
def _expr_richcmp(self, other, int op):

Check warning on line 57 in src/pyscipopt/expr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/expr.pxi#L57

Added line #L57 was not covered by tests
if op == 1: # <=
if isinstance(other, Expr) or isinstance(other, GenExpr):
return (self - other) <= 0.0
Expand Down Expand Up @@ -90,7 +90,7 @@
self.ptrtuple = tuple(v.ptr() for v in self.vartuple)
self.hashval = sum(self.ptrtuple)

def __getitem__(self, idx):
def __getitem__(self, int idx):

Check warning on line 93 in src/pyscipopt/expr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/expr.pxi#L93

Added line #L93 was not covered by tests
return self.vartuple[idx]

def __hash__(self):
Expand All @@ -115,6 +115,7 @@
# helper function
def buildGenExprObj(expr):
"""helper function to generate an object of type GenExpr"""
cdef SCIP_Real coef
if _is_number(expr):
return Constant(expr)
elif isinstance(expr, Expr):
Expand Down Expand Up @@ -143,7 +144,7 @@
#See also the @ref ExprDetails "description" in the expr.pxi.
cdef class Expr:

def __init__(self, terms=None):
def __init__(self, terms: Union[None, dict[Variable,SCIP_Real]] = None):
'''terms is a dict of variables to coefficients.

CONST is used as key for the constant term.'''
Expand Down Expand Up @@ -620,23 +621,23 @@
def __repr__(self):
return str(self.number)

def exp(expr):
def exp(expr: Union[Expr, GenExpr]):

Check warning on line 624 in src/pyscipopt/expr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/expr.pxi#L624

Added line #L624 was not covered by tests
"""returns expression with exp-function"""
return UnaryExpr(Operator.exp, buildGenExprObj(expr))
def log(expr):
def log(expr: Union[Expr, GenExpr]):

Check warning on line 627 in src/pyscipopt/expr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/expr.pxi#L627

Added line #L627 was not covered by tests
"""returns expression with log-function"""
return UnaryExpr(Operator.log, buildGenExprObj(expr))
def sqrt(expr):
def sqrt(expr: Union[Expr, GenExpr]):

Check warning on line 630 in src/pyscipopt/expr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/expr.pxi#L630

Added line #L630 was not covered by tests
"""returns expression with sqrt-function"""
return UnaryExpr(Operator.sqrt, buildGenExprObj(expr))
def sin(expr):
def sin(expr: Union[Expr, GenExpr]):

Check warning on line 633 in src/pyscipopt/expr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/expr.pxi#L633

Added line #L633 was not covered by tests
"""returns expression with sin-function"""
return UnaryExpr(Operator.sin, buildGenExprObj(expr))
def cos(expr):
def cos(expr: Union[Expr, GenExpr]):

Check warning on line 636 in src/pyscipopt/expr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/expr.pxi#L636

Added line #L636 was not covered by tests
"""returns expression with cos-function"""
return UnaryExpr(Operator.cos, buildGenExprObj(expr))

def expr_to_nodes(expr):
def expr_to_nodes(expr: Union[Expr, GenExpr]):

Check warning on line 640 in src/pyscipopt/expr.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/expr.pxi#L640

Added line #L640 was not covered by tests
'''transforms tree to an array of nodes. each node is an operator and the position of the
children of that operator (i.e. the other nodes) in the array'''
assert isinstance(expr, GenExpr)
Expand Down
2 changes: 1 addition & 1 deletion src/pyscipopt/heuristic.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
'''informs primal heuristic that the branch and bound process data is being freed'''
pass

def heurexec(self, heurtiming, nodeinfeasible):
def heurexec(self, SCIP_HEURTIMING heurtiming, SCIP_Bool nodeinfeasible):

Check warning on line 27 in src/pyscipopt/heuristic.pxi

View check run for this annotation

Codecov / codecov/patch

src/pyscipopt/heuristic.pxi#L27

Added line #L27 was not covered by tests
'''should the heuristic the executed at the given depth, frequency, timing,...'''
print("python error in heurexec: this method needs to be implemented")
return {}
Expand Down
Loading