Python Language FAQ - Section 5 
Author Message
 Python Language FAQ - Section 5

This FAQ newsgroup posting has been automatically converted from an
HTML snapshot of the original python FAQ; please refer to the original
"Python FAQ Wizard" at < http://www.*-*-*.com/ ;
if source code snippets given in this document do not work - incidentally
some formatting information may have been lost during the conversion.

----------------------------------------------------------------------------

The whole Python FAQ - Section 5

Last changed on Mon Jun 28 19:36:09 1999 EDT

(Entries marked with ** were changed within the last 24 hours; entries
marked with * were changed within the last 7 days.)

----------------------------------------------------------------------------

5. Extending Python

5.1.  Can I create my own functions in C?
5.2.  Can I create my own functions in C++?
5.3.  How can I execute arbitrary Python statements from C?
5.4.  How can I evaluate an arbitrary Python expression from C?
5.5.  How do I extract C values from a Python object?
5.6.  How do I use Py_BuildValue() to create a tuple of arbitrary
      length?
5.7.  How do I call an object's method from C?
5.8.  How do I catch the output from PyErr_Print() (or anything that
      prints to stdout/stderr)?
5.9.  How do I access a module written in Python from C?
5.10. How do I interface to C++ objects from Python?
5.11. mSQLmodule (or other old module) won't build with Python 1.5 (or
      later)
5.12. I added a module using the Setup file and the make fails! Huh?
5.13. I want to compile a Python module on my Red Hat Linux system, but
      some files are missing.
5.14. What does "SystemError: _PyImport_FixupExtension: module
      yourmodule not loaded" mean?

----------------------------------------------------------------------------

5. Extending Python

----------------------------------------------------------------------------

5.1. Can I create my own functions in C?

Yes, you can create built-in modules containing functions, variables,
exceptions and even new types in C. This is explained in the document
"Extending and Embedding the Python Interpreter" (the{*filter*}file
Doc/ext.tex). Also read the chapter on dynamic loading.

There's more information on this in each of the Python books: Programming
Python, Internet Programming with Python, and Das Python-Buch (in German).

----------------------------------------------------------------------------

5.2. Can I create my own functions in C++?

Yes, using the C-compatibility features found in C++. Basically you place
extern "C" { ... } around the Python include files and put extern "C" before
each function that is going to be called by the Python interpreter. Global
or static C++ objects with constructors are probably not a good idea.

----------------------------------------------------------------------------

5.3. How can I execute arbitrary Python statements from C?

The highest-level function to do this is PyRun_SimpleString() which takes a
single string argument which is executed in the context of module __main__
and returns 0 for success and -1 when an exception occurred (including
SyntaxError). If you want more control, use PyRun_String(); see the source
for PyRun_SimpleString() in Python/pythonrun.c.

----------------------------------------------------------------------------

5.4. How can I evaluate an arbitrary Python expression from C?

Call the function PyRun_String() from the previous question with the start
symbol eval_input (Py_eval_input starting with 1.5a1); it parses an
expression, evaluates it and returns its value.

----------------------------------------------------------------------------

5.5. How do I extract C values from a Python object?

That depends on the object's type. If it's a tuple, PyTupleSize(o) returns
its length and PyTuple_GetItem(o, i) returns its i'th item; similar for
lists with PyListSize(o) and PyList_GetItem(o, i). For strings,
PyString_Size(o) returns its length and PyString_AsString(o) a pointer to
its value (note that Python strings may contain null bytes so strlen() is
not safe). To test which type an object is, first make sure it isn't NULL,
and then use PyString_Check(o), PyTuple_Check(o), PyList_Check(o), etc.

There is also a high-level API to Python objects which is provided by the
so-called 'abstract' interface -- read Include/abstract.h for further
details. It allows for example interfacing with any kind of Python sequence
(e.g. lists and tuples) using calls like PySequence_Length(),
PySequence_GetItem(), etc.) as well as many other useful protocols.

----------------------------------------------------------------------------

5.6. How do I use Py_BuildValue() to create a tuple of arbitrary length?

You can't. Use t = PyTuple_New(n) instead, and fill it with objects using
PyTuple_SetItem(t, i, o) -- note that this "eats" a reference count of o.
Similar for lists with PyList_New(n) and PyList_SetItem(l, i, o). Note that
you must set all the tuple items to some value before you pass the tuple to
Python code -- PyTuple_New(n) initializes them to NULL, which isn't a valid
Python value.

----------------------------------------------------------------------------

5.7. How do I call an object's method from C?

Here's a function (untested) that might become part of the next release in
some form. It uses <stdarg.h> to allow passing the argument list on to
vmkvalue():

            object *call_method(object *inst, char *methodname, char *format, ...)
            {
                    object *method;
                    object *args;
                    object *result;
                    va_list va;
                    method = getattr(inst, methodname);
                    if (method == NULL) return NULL;
                    va_start(va, format);
                    args = vmkvalue(format, va);
                    va_end(va);
                    if (args == NULL) {
                            DECREF(method);
                            return NULL;
                    }
                    result = call_object(method, args);
                    DECREF(method);
                    DECREF(args);
                    return result;
            }

This works for any instance that has methods -- whether built-in or
user-defined. You are responsible for eventually DECREF'ing the return
value.

To call, e.g., a file object's "seek" method with arguments 10, 0 (assuming
the file object pointer is "f"):

            res = call_method(f, "seek", "(OO)", 10, 0);
            if (res == NULL) {
                    ... an exception occurred ...
            }
            else {
                    DECREF(res);
            }

Note that since call_object() always wants a tuple for the argument list, to
call a function without arguments, pass "()" for the format, and to call a
function with one argument, surround the argument in parentheses, e.g.
"(i)".

----------------------------------------------------------------------------

5.8. How do I catch the output from PyErr_Print() (or anything that prints
to stdout/stderr)?

(Due to Mark Hammond):

In Python code, define an object that supports the "write()" method.
Redirect sys.stdout and sys.stderr to this object. Call print_error, or just
allow the standard traceback mechanism to work. Then, the output will go
wherever your write() method sends it.

The easiest way to do this is to use the StringIO class in the standard
library.

Sample code and use for catching stdout:

            >>> class StdoutCatcher:
            ...  def __init__(self):
            ...   self.data = ''
            ...  def write(self, stuff):
            ...   self.data = self.data + stuff
            ...
            >>> import sys
            >>> sys.stdout = StdoutCatcher()
            >>> print 'foo'
            >>> print 'hello world!'
            >>> sys.stderr.write(sys.stdout.data)
            foo
            hello world!

----------------------------------------------------------------------------

5.9. How do I access a module written in Python from C?

You can get a pointer to the module object as follows:

            module = PyImport_ImportModule("<modulename>");

If the module hasn't been imported yet (i.e. it is not yet present in
sys.modules), this initializes the module; otherwise it simply returns the
value of sys.modules["<modulename>"]. Note that it doesn't enter the module
into any namespace -- it only ensures it has been initialized and is stored
in sys.modules.

You can then access the module's attributes (i.e. any name defined in the
module) as follows:

            attr = PyObject_GetAttrString(module, "<attrname>");

Calling PyObject_SetAttrString(), to assign to variables in the module, also
works.

----------------------------------------------------------------------------

5.10. How do I interface to C++ objects from Python?

Depending on your requirements, there are many approaches. To do this
manually, begin by reading the "Extending and Embedding" document
(Doc/ext.tex, see also http://www.*-*-*.com/ ). Realize that for the
Python run-time system, there isn't a whole lot of difference between C and
C++ -- so the strategy to build a new Python type around a C structure
(pointer) type will also work for C++ objects.

A useful automated approach (which also works for C) is SWIG:
http://www.*-*-*.com/ ~beazley/SWIG/.

----------------------------------------------------------------------------

5.11. mSQLmodule (or other old module) won't build with Python 1.5 (or
later)

Since python-1.4 "Python.h" will have the file includes needed in an
extension module. Backward compatibility is dropped after version 1.4 and
therefore mSQLmodule.c will not build as "allobjects.h" cannot be found. The
following change in mSQLmodule.c is harmless when building it with 1.4 and
necessary when doing so for later python versions:

Remove lines:

            #include "allobjects.h"
            #include "modsupport.h"

And insert instead:

            #include "Python.h"

You may also need to add

                    #include "rename2.h"

if the module uses "old names".

This may happen with other ancient python modules as well, and the same fix
applies.

----------------------------------------------------------------------------

5.12. I added a module using the Setup file and the make fails! Huh?

Setup must end in a newline, if there is no newline there it gets very sad.
Aside from this possibility, maybe you have other non-Python-specific
linkage problems.

----------------------------------------------------------------------------

5.13. I want to compile a Python module on my Red Hat Linux system, but some
files are missing.

Red Hat's RPM for Python doesn't include the /usr/lib/python1.x/config/
directory, which contains various files required for compiling Python
extensions. Install the python-devel RPM to get the necessary files.

----------------------------------------------------------------------------

5.14. What does "SystemError: _PyImport_FixupExtension: module yourmodule
not loaded" mean?

This means that you have created an extension module named "yourmodule", but
your module init function does not initialize with that name.

Every module init function will have a line similar to:

      module = Py_InitModule("yourmodule", yourmodule_functions);

If the string passed to this function is not the same name as your extenion
module, the SystemError will be raised.

----------------------------------------------------------------------------

--
----------- comp.lang.python.announce (moderated) ----------

Python Language Home Page:   http://www.*-*-*.com/
Python Quick Help Index:     http://www.*-*-*.com/
------------------------------------------------------------



Sun, 23 Dec 2001 03:00:00 GMT  
 
 [ 1 post ] 

 Relevant Pages 

1. Python Language FAQ - Section 5

2. Python Language FAQ - Section 7

3. Python Language FAQ - Section 3

4. Python Language FAQ - Section 1

5. Python Language FAQ - Section 2

6. Python Language FAQ - Section 7

7. Python Language FAQ - Section 8

8. Python Language FAQ - Section 5

9. Python Language FAQ - Section 3

10. Python Language FAQ - Section 2

11. Python Language FAQ - Section 1

 

 
Powered by phpBB® Forum Software