Skip to content

Commit

Permalink
Merge pull request #929 from scipopt/243-fix-write-methods-dont-work-…
Browse files Browse the repository at this point in the history
…after-redirectoutput

Correct output redirection
  • Loading branch information
Opt-Mucca authored Dec 3, 2024
2 parents cfbd832 + a4a5f70 commit d05b049
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- Added stage checks to presolve, freereoptsolve, freetransform
- Added primal_dual_evolution recipe and a plot recipe
### Fixed
- Only redirect stdout and stderr in redirectOutput() so that file output still works afterwards
### Changed
- GitHub actions using Mac now use precompiled SCIP from latest release
### Removed
Expand Down
18 changes: 15 additions & 3 deletions src/pyscipopt/scip.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ cimport cython
from cpython cimport Py_INCREF, Py_DECREF
from cpython.pycapsule cimport PyCapsule_New, PyCapsule_IsValid, PyCapsule_GetPointer
from libc.stdlib cimport malloc, free
from libc.stdio cimport fdopen, fclose
from libc.stdio cimport stdout, stderr, fdopen, fputs, fflush, fclose
from posix.stdio cimport fileno

from collections.abc import Iterable
Expand Down Expand Up @@ -1851,10 +1851,22 @@ cdef class Constraint:


cdef void relayMessage(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *msg) noexcept:
sys.stdout.write(msg.decode('UTF-8'))
if file is stdout:
sys.stdout.write(msg.decode('UTF-8'))
elif file is stderr:
sys.stderr.write(msg.decode('UTF-8'))
else:
if msg is not NULL:
fputs(msg, file)
fflush(file)

cdef void relayErrorMessage(void *messagehdlr, FILE *file, const char *msg) noexcept:
sys.stderr.write(msg.decode('UTF-8'))
if file is NULL:
sys.stderr.write(msg.decode('UTF-8'))
else:
if msg is not NULL:
fputs(msg, file)
fflush(file)

# - remove create(), includeDefaultPlugins(), createProbBasic() methods
# - replace free() by "destructor"
Expand Down
35 changes: 34 additions & 1 deletion tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import itertools

from pyscipopt import Model, SCIP_STAGE, SCIP_PARAMSETTING, quicksum
from helpers.utils import random_mip_1

def test_model():
# create solver instance
Expand Down Expand Up @@ -477,4 +478,36 @@ def test_getObjVal():
assert m.getVal(x) == 0

assert m.getObjVal() == 16
assert m.getVal(x) == 0
assert m.getVal(x) == 0

# tests writeProblem() after redirectOutput()
def test_redirection():

# create problem instances
original = random_mip_1(False, False, False, -1, True)
redirect = Model()

# redirect console output
original.redirectOutput()

# write problem instance
original.writeProblem("redirection.lp")

# solve original instance
original.optimize()

# read problem instance
redirect.readProblem("redirection.lp")

# remove problem file
os.remove("redirection.lp")

# compare problem dimensions
assert redirect.getNVars(False) == original.getNVars(False)
assert redirect.getNConss(False) == original.getNConss(False)

# solve redirect instance
redirect.optimize()

# compare objective values
assert original.isEQ(redirect.getObjVal(), original.getObjVal())

0 comments on commit d05b049

Please sign in to comment.