Skip to content

Commit d685a5e

Browse files
author
Ralf W. Grosse-Kunstleve
committed
python library: sync with trunk to adopt recent exec.cpp fixes
[SVN r55642]
1 parent e80224b commit d685a5e

File tree

2 files changed

+64
-33
lines changed

2 files changed

+64
-33
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: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -108,46 +108,73 @@ void exec_test_error()
108108
python::object result = python::exec("print unknown \n", global, global);
109109
}
110110

111-
int main(int argc, char **argv)
111+
void exercise_embedding_html()
112112
{
113-
BOOST_TEST(argc == 2);
114-
std::string script = argv[1];
115-
// Initialize the interpreter
116-
Py_Initialize();
113+
using namespace boost::python;
114+
/* code from: libs/python/doc/tutorial/doc/tutorial.qbk
115+
(generates libs/python/doc/tutorial/doc/html/python/embedding.html)
116+
*/
117+
object main_module = import("__main__");
118+
object main_namespace = main_module.attr("__dict__");
119+
120+
object ignored = exec("hello = file('hello.txt', 'w')\n"
121+
"hello.write('Hello world!')\n"
122+
"hello.close()",
123+
main_namespace);
124+
}
117125

118-
if (python::handle_exception(eval_test) ||
119-
python::handle_exception(exec_test) ||
120-
python::handle_exception(boost::bind(exec_file_test, script)))
126+
void check_pyerr(bool pyerr_expected=false)
127+
{
128+
if (PyErr_Occurred())
121129
{
122-
if (PyErr_Occurred())
123-
{
130+
if (!pyerr_expected) {
124131
BOOST_ERROR("Python Error detected");
125132
PyErr_Print();
126133
}
127-
else
128-
{
129-
BOOST_ERROR("A C++ exception was thrown for which "
130-
"there was no exception handler registered.");
134+
else {
135+
PyErr_Clear();
131136
}
132137
}
138+
else
139+
{
140+
BOOST_ERROR("A C++ exception was thrown for which "
141+
"there was no exception handler registered.");
142+
}
143+
}
144+
145+
int main(int argc, char **argv)
146+
{
147+
BOOST_TEST(argc == 2 || argc == 3);
148+
std::string script = argv[1];
149+
// Initialize the interpreter
150+
Py_Initialize();
151+
152+
if (python::handle_exception(eval_test)) {
153+
check_pyerr();
154+
}
155+
else if(python::handle_exception(exec_test)) {
156+
check_pyerr();
157+
}
158+
else if (python::handle_exception(boost::bind(exec_file_test, script))) {
159+
check_pyerr();
160+
}
133161

134162
if (python::handle_exception(exec_test_error))
135163
{
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-
}
164+
check_pyerr(/*pyerr_expected*/ true);
145165
}
146166
else
147167
{
148-
BOOST_ERROR("Python exception expected, but not seen.");
168+
BOOST_ERROR("Python exception expected, but not seen.");
149169
}
150-
170+
171+
if (argc > 2) {
172+
// The main purpose is to test compilation. Since this test generates
173+
// a file and I (rwgk) am uncertain about the side-effects, run it only
174+
// if explicitly requested.
175+
exercise_embedding_html();
176+
}
177+
151178
// Boost.Python doesn't support Py_Finalize yet.
152179
// Py_Finalize();
153180
return boost::report_errors();

0 commit comments

Comments
 (0)