I l@ve RuBoard Previous Section Next Section

20.2 C Embedding API Overview

The first thing you should know about Python's embedded-call API is that it is less structured than the extension interfaces. Embedding Python in C may require a bit more creativity on your part than extending; you must pick tools from a general collection of calls to implement the Python integration, rather than coding to a boilerplate structure. The upside of this loose structure is that programs can combine embedding calls and strategies to build up arbitrary integration architectures.

The lack of a more rigid model for embedding is largely the result of a less clear-cut goal. When extending Python, there is a distinct separation for Python and C responsibilities and a clear structure for the integration. C modules and types are required to fit the Python module/type model by conforming to standard extension structures. This makes the integration seamless for Python clients: C extensions look like Python objects and handle most of the work.

But when Python is embedded, the structure isn't as obvious; because C is the enclosing level, there is no clear way to know what model the embedded Python code should fit. C may want to run objects fetched from modules, strings fetched from files or parsed out of documents, and so on. Instead of deciding what C can and cannot do, Python provides a collection of general embedding interface tools, which you use and structure according to your embedding goals.

Most of these tools correspond to tools available to Python programs. Table 20-1 lists some of the more common API calls used for embedding, and their Python equivalents. In general, if you can figure out how to accomplish your embedding goals in pure Python code, you can probably find C API tools that achieve the same results.

Table 20-1. Common API Functions

C API Call

Python Equivalent

PyImport_ImportModule

import module, __import__

PyImport_ReloadModule

reload(module)

PyImport_GetModuleDict

sys.modules

PyModule_GetDict

module.__dict__

PyDict_GetItemString

dict[key]

PyDict_SetItemString

dict[key]=val

PyDict_New

dict = {}

PyObject_GetAttrString

getattr(obj, attr)

PyObject_SetAttrString

setattr(obj, attr, val)

PyEval_CallObject

apply(funcobj, argstuple)

PyRun_String

eval(exprstr), exec stmtstr

PyRun_File

execfile(filename)

Because embedding relies on API call selection, though, becoming familiar with the Python C API is fundamental to the embedding task. This chapter presents a handful of representative embedding examples and discusses common API calls, but does not provide a comprehensive list of all tools in the API. Once you've mastered the examples here, you'll probably need to consult Python's integration manuals for more details on available calls in this domain. The most recent Python release comes with two standard manuals for C/C++ integration programmers: Extending and Embedding, an integration tutorial; and Python/C API, the Python runtime library reference.

You can find these manuals on the book's CD (view CD-ROM content online at http://examples.oreilly.com/python2), or fetch their most recent releases at http://www.python.org. Beyond this chapter, these manuals are likely to be your best resource for up-to-date and complete Python API tool information.

20.2.1 What Is Embedded Code?

Before we jump into details, let's get a handle on some of the core ideas in the embedding domain. When this book speaks of "embedded" Python code, it simply means any Python program structure that can be executed from C. Generally speaking, embedded Python code can take a variety of forms:

Code strings

C programs can represent Python programs as character strings, and run them as either expressions or statements (like eval and exec).

Callable objects

C programs can load or reference Python callable objects such as functions, methods, and classes, and call them with argument lists (like apply).

Code files

C programs can execute entire Python program files by importing modules and running script files though the API or general system calls (e.g., popen).

The Python binary library is usually what is physically embedded in the C program; the actual Python code run from C can come from a wide variety of sources:

  • Code strings might be loaded from files, fetched from persistent databases and shelves, parsed out of HTML or XML files, read over sockets, built or hardcoded in a C program, passed to C extension functions from Python registration code, and so on.

  • Callable objects might be fetched from Python modules, returned from other Python API calls, passed to C extension functions from Python registration code, and so on.

  • Code files simply exist as files, modules, and executable scripts.

Registration is a technique commonly used in callback scenarios that we will explore in more detail later in this chapter. But especially for strings of code, there are as many possible sources as there are for C character strings. For example, C programs can construct arbitrary Python code dynamically by building and running strings.

Finally, once you have some Python code to run, you need a way to communicate with it: the Python code may need to use inputs passed in from the C layer, and may want to generate outputs to communicate results back to C. In fact, embedding generally becomes interesting only when the embedded code has access to the enclosing C layer. Usually, the form of the embedded code suggests its communication mediums:

  • Code strings that are Python expressions return an expression result as their output. Both inputs and outputs can take the form of global variables in the namespace in which a code string is run -- C may set variables to serve as input, run Python code, and fetch variables as the code's result. Inputs and outputs can also be passed with exported C extension calls -- Python code may use C modules or types to get or set variables in the enclosing C layer. Communications schemes are often combined; for instance, C may preassign global names to objects that export state and interface calls to the embedded Python code.[1]

    [1] If you want an example, flip back to the discussion of Active Scripting in Chapter 15. This system fetches Python code embedded in an HTML web page file, assigns global variables in a namespace to objects that give access to the web browser's environment, and runs the Python code in the namespace where the objects were assigned. I recently worked on a project where we did something similar, but Python code was embedded in XML documents, and objects preassigned to globals in the code's namespace represented widgets in a GUI.

  • Callable objects may accept inputs as function arguments and produce results as function return values. Passed-in mutable arguments (e.g., lists, dictionaries, class instances) can be used as both input and output for the embedded code -- changes made in Python are retained in objects held by C. Objects can also make use of the global variable and C extension interface techniques described for strings to communicate with C.

  • Code files can communicate with most of the same techniques as code strings; when run as separate programs, files can also employ IPC techniques.

Naturally, all embedded code forms can also communicate with C using general system-level tools: files, sockets, pipes, and so on. These techniques are generally less direct and slower, though.

    I l@ve RuBoard Previous Section Next Section