[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