Embedding

Alex Martelli aleaxit at yahoo.com
Thu Jun 28 08:34:57 EDT 2001


[posted and mailed, since a few days have passed]

"Mark Rowe" <mark21rowe at yahoo.com> wrote in message
news:3b32f3fe at news.actrix.gen.nz...:

> Thanks for the reply.  I was actually most interested in implementing it
in
> C.  I still cant seem to find the methods to call :)
    ...
> > > has me stuck.  I would like the user to be able to enter some python
> code
> > > containing functions, then at a later point execute one of these
> functions
> > > by name.  I'm not really sure what i need to do for this to work
> >
> > You don't have to do much.  Collect the source code that the user
> > enters (e.g. in a text-entry window in a GUI?), into one big Python
> > string (make sure there's a '\n' at the end:-),

This part you're presumably doing in C, then?  Anyway, if you have
a C string and want to make a Python one, that's what various
Python C API functions such as PyString_FromStringAndSize are for.

But you don't need to do this, since
    PyObject* Py_CompileStringFlags(char* string, char* filename,
        int start, PyCompilerFlags* flags)
already does exactly what you need for the next step, and, as you
see, as its first argument, the string to be compiled, it takes
a char* already (a C-kind of string).  Of course the "filename",
just like for callable-from-Python builtin 'compile', is used just
to build error messages, 'start' is Py_file_input for the 'exec'
kind of compilation, and as for 'flags' you can pass it as 0 (that
is what builtin compile does, unless nested-scopes are an issue).

So, we've taken care of the next step:

> > feed it to builtin
> > function compile() and make sure to catch a SyntaxError that will
> > be raised if the code has syntax errors, and let the user know.   If

except for the "catching errors" part which is done by checking
the returned PyObject* -- if 0 some exception was raised, and you
can find out which one, &c, with the usual PyErr_* family of
functions.  OK so far?  Well then:

> > there are no errors, compile() returns a code-object.  Stash it away,
> > and at any later time you can pass it to statement 'exec' (you may
> > want to pass specific dictionaries to control execution namespaces).
> > Again, be sure to catch and report any exceptions that may arise.

PyObject *
PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)

is the C-API equivalent of eval() and exec.

> > This is all at the Python-level, where it's easiest, but of course there
> > is equivalent functionality accessible from the C API, too -- it's just
> > more work (as usual for C vs Python:-) so, the more you can do in
> > Python, the merrier, no?-)

There's also the little detail that Py_Compile* and PyEval_* are
among the not-well-documented-if-at-all parts of the Python/C API,
but fortunately the sources of Python itself are very clear, so
it should be no big problem with some experimentation to get where
you want to be.

But still, of course, it holds that doing it in Python, as usual,
is *MUCH* less work:-).


Alex






More information about the Python-list mailing list