2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-20 16:52:15 +00:00

exec/eval(): add overloads for char const*

Many times the caller may have a string created in C++,
so there is no need to wrap it in a Python object when
the only thing done with the object is extract<char*>.
This commit is contained in:
John Zwinck
2016-10-21 15:55:06 +08:00
committed by Stefan Seefeld
parent 3844c4fc5f
commit b2f53e1acf
3 changed files with 56 additions and 18 deletions

View File

@@ -1417,6 +1417,8 @@ eval evaluates the given expression and returns the resulting value.
exec executes the given code (typically a set of statements) returning the result,
and exec_file executes the code contained in the given file.
There are also overloads taking `char const*` instead of str as the first argument.
The [^globals] and [^locals] parameters are Python dictionaries
containing the globals and locals of the context in which to run the code.
For most intents and purposes you can use the namespace dictionary of the

View File

@@ -20,6 +20,10 @@ object
BOOST_PYTHON_DECL
eval(str string, object global = object(), object local = object());
object
BOOST_PYTHON_DECL
eval(char const *string, object global = object(), object local = object());
// Execute an individual python statement from str.
// global and local are the global and local scopes respectively,
// used during execution.
@@ -27,6 +31,10 @@ object
BOOST_PYTHON_DECL
exec_statement(str string, object global = object(), object local = object());
object
BOOST_PYTHON_DECL
exec_statement(char const *string, object global = object(), object local = object());
// Execute python source code from str.
// global and local are the global and local scopes respectively,
// used during execution.
@@ -34,6 +42,10 @@ object
BOOST_PYTHON_DECL
exec(str string, object global = object(), object local = object());
object
BOOST_PYTHON_DECL
exec(char const *string, object global = object(), object local = object());
// Execute python source code from file filename.
// global and local are the global and local scopes respectively,
// used during execution.
@@ -41,6 +53,10 @@ object
BOOST_PYTHON_DECL
exec_file(str filename, object global = object(), object local = object());
object
BOOST_PYTHON_DECL
exec_file(char const *filename, object global = object(), object local = object());
}
}

View File

@@ -15,6 +15,11 @@ namespace python
{
object BOOST_PYTHON_DECL eval(str string, object global, object local)
{
return eval(python::extract<char const *>(string));
}
object BOOST_PYTHON_DECL eval(char const *string, object global, object local)
{
// Set suitable default values for global and local dicts.
if (global.is_none())
@@ -26,7 +31,7 @@ object BOOST_PYTHON_DECL eval(str string, object global, object local)
}
if (local.is_none()) local = global;
// should be 'char const *' but older python versions don't use 'const' yet.
char *s = python::extract<char *>(string);
char *s = const_cast<char *>(string);
PyObject* result = PyRun_String(s, Py_eval_input, global.ptr(), local.ptr());
if (!result) throw_error_already_set();
return object(detail::new_reference(result));
@@ -34,23 +39,10 @@ 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.is_none())
{
if (PyObject *g = PyEval_GetGlobals())
global = object(detail::borrowed_reference(g));
else
global = dict();
}
if (local.is_none()) 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());
if (!result) throw_error_already_set();
return object(detail::new_reference(result));
return exec(python::extract<char const *>(string));
}
object BOOST_PYTHON_DECL exec_statement(str string, object global, object local)
object BOOST_PYTHON_DECL exec(char const *string, object global, object local)
{
// Set suitable default values for global and local dicts.
if (global.is_none())
@@ -62,7 +54,30 @@ object BOOST_PYTHON_DECL exec_statement(str string, object global, object local)
}
if (local.is_none()) local = global;
// should be 'char const *' but older python versions don't use 'const' yet.
char *s = python::extract<char *>(string);
char *s = const_cast<char *>(string);
PyObject* result = PyRun_String(s, Py_file_input, global.ptr(), local.ptr());
if (!result) throw_error_already_set();
return object(detail::new_reference(result));
}
object BOOST_PYTHON_DECL exec_statement(str string, object global, object local)
{
return exec_statement(python::extract<char const *>(string), global, local);
}
object BOOST_PYTHON_DECL exec_statement(char const *string, object global, object local)
{
// Set suitable default values for global and local dicts.
if (global.is_none())
{
if (PyObject *g = PyEval_GetGlobals())
global = object(detail::borrowed_reference(g));
else
global = dict();
}
if (local.is_none()) local = global;
// should be 'char const *' but older python versions don't use 'const' yet.
char *s = const_cast<char *>(string);
PyObject* result = PyRun_String(s, Py_single_input, global.ptr(), local.ptr());
if (!result) throw_error_already_set();
return object(detail::new_reference(result));
@@ -72,6 +87,11 @@ object BOOST_PYTHON_DECL exec_statement(str string, object global, object local)
// global and local are the global and local scopes respectively,
// used during execution.
object BOOST_PYTHON_DECL exec_file(str filename, object global, object local)
{
return exec_file(python::extract<char const *>(filename), global, local);
}
object BOOST_PYTHON_DECL exec_file(char const *filename, object global, object local)
{
// Set suitable default values for global and local dicts.
if (global.is_none())
@@ -83,7 +103,7 @@ object BOOST_PYTHON_DECL exec_file(str filename, object global, object local)
}
if (local.is_none()) local = global;
// should be 'char const *' but older python versions don't use 'const' yet.
char *f = python::extract<char *>(filename);
char *f = const_cast<char *>(filename);
// Let python open the file to avoid potential binary incompatibilities.
#if PY_VERSION_HEX >= 0x03040000
FILE *fs = _Py_fopen(f, "r");