Skip to content

Commit 8d2ca93

Browse files
author
Ralf W. Grosse-Kunstleve
committed
libs/python/src/exec.cpp: bug fixes
Remark: operator!() for boost::python::object invokes PyObject_IsTrue() and is therefore not equivalent to "is None". In this particular case !global or !local returns true for an empty dict. (Changes to libs/python/test/exec.cpp just helped in debugging.) [SVN r55639]
1 parent d47e3b2 commit 8d2ca93

File tree

2 files changed

+41
-32
lines changed

2 files changed

+41
-32
lines changed

src/exec.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,15 @@ namespace python
1717
object BOOST_PYTHON_DECL eval(str string, object global, object local)
1818
{
1919
// Set suitable default values for global and local dicts.
20-
if (!global)
20+
object none;
21+
if (global.ptr() == none.ptr())
2122
{
2223
if (PyObject *g = PyEval_GetGlobals())
2324
global = object(detail::borrowed_reference(g));
2425
else
2526
global = dict();
2627
}
27-
if (!local) local = global;
28+
if (local.ptr() == none.ptr()) local = global;
2829
// should be 'char const *' but older python versions don't use 'const' yet.
2930
char *s = python::extract<char *>(string);
3031
PyObject* result = PyRun_String(s, Py_eval_input, global.ptr(), local.ptr());
@@ -35,14 +36,15 @@ object BOOST_PYTHON_DECL eval(str string, object global, object local)
3536
object BOOST_PYTHON_DECL exec(str string, object global, object local)
3637
{
3738
// Set suitable default values for global and local dicts.
38-
if (!global)
39+
object none;
40+
if (global.ptr() == none.ptr())
3941
{
4042
if (PyObject *g = PyEval_GetGlobals())
4143
global = object(detail::borrowed_reference(g));
4244
else
4345
global = dict();
4446
}
45-
if (!local) local = global;
47+
if (local.ptr() == none.ptr()) local = global;
4648
// should be 'char const *' but older python versions don't use 'const' yet.
4749
char *s = python::extract<char *>(string);
4850
PyObject* result = PyRun_String(s, Py_file_input, global.ptr(), local.ptr());
@@ -53,14 +55,15 @@ object BOOST_PYTHON_DECL exec(str string, object global, object local)
5355
object BOOST_PYTHON_DECL exec_statement(str string, object global, object local)
5456
{
5557
// Set suitable default values for global and local dicts.
56-
if (!global)
58+
object none;
59+
if (global.ptr() == none.ptr())
5760
{
5861
if (PyObject *g = PyEval_GetGlobals())
5962
global = object(detail::borrowed_reference(g));
6063
else
6164
global = dict();
6265
}
63-
if (!local) local = global;
66+
if (local.ptr() == none.ptr()) local = global;
6467
// should be 'char const *' but older python versions don't use 'const' yet.
6568
char *s = python::extract<char *>(string);
6669
PyObject* result = PyRun_String(s, Py_single_input, global.ptr(), local.ptr());
@@ -74,14 +77,15 @@ object BOOST_PYTHON_DECL exec_statement(str string, object global, object local)
7477
object BOOST_PYTHON_DECL exec_file(str filename, object global, object local)
7578
{
7679
// Set suitable default values for global and local dicts.
77-
if (!global)
80+
object none;
81+
if (global.ptr() == none.ptr())
7882
{
7983
if (PyObject *g = PyEval_GetGlobals())
8084
global = object(detail::borrowed_reference(g));
8185
else
8286
global = dict();
8387
}
84-
if (!local) local = global;
88+
if (local.ptr() == none.ptr()) local = global;
8589
// should be 'char const *' but older python versions don't use 'const' yet.
8690
char *f = python::extract<char *>(filename);
8791
// Let python open the file to avoid potential binary incompatibilities.

test/exec.cpp

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -108,44 +108,49 @@ void exec_test_error()
108108
python::object result = python::exec("print unknown \n", global, global);
109109
}
110110

111+
void check_pyerr(bool pyerr_expected=false)
112+
{
113+
if (PyErr_Occurred())
114+
{
115+
if (!pyerr_expected) {
116+
BOOST_ERROR("Python Error detected");
117+
PyErr_Print();
118+
}
119+
else {
120+
PyErr_Clear();
121+
}
122+
}
123+
else
124+
{
125+
BOOST_ERROR("A C++ exception was thrown for which "
126+
"there was no exception handler registered.");
127+
}
128+
}
129+
111130
int main(int argc, char **argv)
112131
{
113132
BOOST_TEST(argc == 2);
114133
std::string script = argv[1];
115134
// Initialize the interpreter
116135
Py_Initialize();
117136

118-
if (python::handle_exception(eval_test) ||
119-
python::handle_exception(exec_test) ||
120-
python::handle_exception(boost::bind(exec_file_test, script)))
121-
{
122-
if (PyErr_Occurred())
123-
{
124-
BOOST_ERROR("Python Error detected");
125-
PyErr_Print();
126-
}
127-
else
128-
{
129-
BOOST_ERROR("A C++ exception was thrown for which "
130-
"there was no exception handler registered.");
131-
}
137+
if (python::handle_exception(eval_test)) {
138+
check_pyerr();
139+
}
140+
else if(python::handle_exception(exec_test)) {
141+
check_pyerr();
142+
}
143+
else if (python::handle_exception(boost::bind(exec_file_test, script))) {
144+
check_pyerr();
132145
}
133146

134147
if (python::handle_exception(exec_test_error))
135148
{
136-
if (PyErr_Occurred())
137-
{
138-
PyErr_Print();
139-
}
140-
else
141-
{
142-
BOOST_ERROR("A C++ exception was thrown for which "
143-
"there was no exception handler registered.");
144-
}
149+
check_pyerr(/*pyerr_expected*/ true);
145150
}
146151
else
147152
{
148-
BOOST_ERROR("Python exception expected, but not seen.");
153+
BOOST_ERROR("Python exception expected, but not seen.");
149154
}
150155

151156
// Boost.Python doesn't support Py_Finalize yet.

0 commit comments

Comments
 (0)