[C++-sig] Re: Injecting python code to a class
Raoul Gough
RaoulGough at yahoo.co.uk
Mon Mar 29 22:58:41 CEST 2004
Nicodemus <nicodemus at esss.com.br> writes:
> Hi Raoul,
>
> Raoul Gough wrote:
>
>>Actually, that was the idea I had originally, but I wasn't sure where
>>to get the necessary function arguments from. PyRun_String needs the
>>global and local dictionaries to operate with - is there any easy way
>>to get these? It would be running within a def_visitor::visit
>>function...
>>
>
> IIRC, you have to pass NULL as the dictionaries in PyRunString.
That was the first thing I tried, but I get the following error:
Traceback (most recent call last):
File "runexample.py", line 1, in ?
from example import vector_int
SystemError: PyEval_EvalCodeEx: NULL globals
After some further research, it seems that I should be passing
__builtins__.__dict__ as the global dictionary to PyRun_String, and
the locals builtin can indeed be NULL. This might depend on what your
string actually does, in my case it's just a lambda expression.
Anyway, finding this global __dict__ object is relatively easy, as
mentioned here:
http://mail.python.org/pipermail/python-list/1999-April/000125.html
The code I've ended up with is shown below, slightly simplified. I'm
still not sure that this is the "right" way to do it, but it seems to
work.
// Get the global dictionary
boost::python::object global_dict ()
{
using namespace boost::python;
handle<> builtin_handle (PyImport_ImportModule("__builtin__"));
return object (borrowed (PyModule_GetDict (builtin_handle.get())));
}
// Return the result of evaluating a python expression
boost::python::object python_eval (char const *str)
{
using namespace boost::python;
return object (handle<> (PyRun_String (
const_cast<char *>(str), Py_eval_input, global_dict().ptr(), 0)));
}
// Add a __repr__ method for a container
template<class PythonClass> void add_repr (PythonClass &pyClass)
{
boost::python::objects::add_to_namespace (
pyClass, "__repr__", python_eval ("lambda v: repr([x for x in v])"));
}
--
Raoul Gough.
export LESS='-X'
More information about the Cplusplus-sig
mailing list