2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-21 05:02:17 +00:00

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]
This commit is contained in:
Ralf W. Grosse-Kunstleve
2009-08-18 00:24:54 +00:00
parent d47e3b2a15
commit 8d2ca93e98
2 changed files with 41 additions and 32 deletions

View File

@@ -17,14 +17,15 @@ namespace python
object BOOST_PYTHON_DECL eval(str string, object global, object local)
{
// Set suitable default values for global and local dicts.
if (!global)
object none;
if (global.ptr() == none.ptr())
{
if (PyObject *g = PyEval_GetGlobals())
global = object(detail::borrowed_reference(g));
else
global = dict();
}
if (!local) local = global;
if (local.ptr() == none.ptr()) local = global;
// should be 'char const *' but older python versions don't use 'const' yet.
char *s = python::extract<char *>(string);
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)
object BOOST_PYTHON_DECL exec(str string, object global, object local)
{
// Set suitable default values for global and local dicts.
if (!global)
object none;
if (global.ptr() == none.ptr())
{
if (PyObject *g = PyEval_GetGlobals())
global = object(detail::borrowed_reference(g));
else
global = dict();
}
if (!local) local = global;
if (local.ptr() == none.ptr()) local = global;
// should be 'char const *' but older python versions don't use 'const' yet.
char *s = python::extract<char *>(string);
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)
object BOOST_PYTHON_DECL exec_statement(str string, object global, object local)
{
// Set suitable default values for global and local dicts.
if (!global)
object none;
if (global.ptr() == none.ptr())
{
if (PyObject *g = PyEval_GetGlobals())
global = object(detail::borrowed_reference(g));
else
global = dict();
}
if (!local) local = global;
if (local.ptr() == none.ptr()) local = global;
// should be 'char const *' but older python versions don't use 'const' yet.
char *s = python::extract<char *>(string);
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)
object BOOST_PYTHON_DECL exec_file(str filename, object global, object local)
{
// Set suitable default values for global and local dicts.
if (!global)
object none;
if (global.ptr() == none.ptr())
{
if (PyObject *g = PyEval_GetGlobals())
global = object(detail::borrowed_reference(g));
else
global = dict();
}
if (!local) local = global;
if (local.ptr() == none.ptr()) local = global;
// should be 'char const *' but older python versions don't use 'const' yet.
char *f = python::extract<char *>(filename);
// Let python open the file to avoid potential binary incompatibilities.

View File

@@ -108,6 +108,25 @@ void exec_test_error()
python::object result = python::exec("print unknown \n", global, global);
}
void check_pyerr(bool pyerr_expected=false)
{
if (PyErr_Occurred())
{
if (!pyerr_expected) {
BOOST_ERROR("Python Error detected");
PyErr_Print();
}
else {
PyErr_Clear();
}
}
else
{
BOOST_ERROR("A C++ exception was thrown for which "
"there was no exception handler registered.");
}
}
int main(int argc, char **argv)
{
BOOST_TEST(argc == 2);
@@ -115,37 +134,23 @@ int main(int argc, char **argv)
// Initialize the interpreter
Py_Initialize();
if (python::handle_exception(eval_test) ||
python::handle_exception(exec_test) ||
python::handle_exception(boost::bind(exec_file_test, script)))
{
if (PyErr_Occurred())
{
BOOST_ERROR("Python Error detected");
PyErr_Print();
}
else
{
BOOST_ERROR("A C++ exception was thrown for which "
"there was no exception handler registered.");
}
if (python::handle_exception(eval_test)) {
check_pyerr();
}
else if(python::handle_exception(exec_test)) {
check_pyerr();
}
else if (python::handle_exception(boost::bind(exec_file_test, script))) {
check_pyerr();
}
if (python::handle_exception(exec_test_error))
{
if (PyErr_Occurred())
{
PyErr_Print();
}
else
{
BOOST_ERROR("A C++ exception was thrown for which "
"there was no exception handler registered.");
}
check_pyerr(/*pyerr_expected*/ true);
}
else
{
BOOST_ERROR("Python exception expected, but not seen.");
BOOST_ERROR("Python exception expected, but not seen.");
}
// Boost.Python doesn't support Py_Finalize yet.