Pythonize Class and libpythonize

libPythonize and the Pythonize class simplify embedding, loading and communicating with the Python interpreter. Pythonize is a class with methods for handling the interpreter and is included in libpythonize. Also in libpythonize is a C wrapper for the C++ Pythonize class. There is also a standalone C library libpythonizec, written completely in C. All 3 versions (C++, C and C wrapper) use the same methods/functions and the same args - the only major difference is in initialization and finalization.

The method descriptions here apply to both C and C++ versions unless noted.

Although libpythonize is used with (and installed with) PyKDE, it has no dependencies itself on PyKDE/KDE, PyTQt/TQt or sip. It does require qmake from TrollTech (part of TQt) to build.

Initialization and Finalization

In C++, the interpreter is loaded and initialized using the Pythonize () constructor, which takes no arguments. In C, the initialize() function call accomplishes the same thing. The interpreter is finalized in C++ using the destructor ~Pythonize (). In C, the finalize() function accomplishes the same thing.

Threading and Locking

Pythonize obtains the Python global interpreter lock when it initializes Python. It is currently the programmer's responsibility to release the lock when C++ accesses to the interpreter are complete. If the lock is not released, access will be denied to Python code relying on the interpreter (for example bindings like PyTQt or PyKDE).

If a second instance of Pythonize is created (within the same parent process), that instance will acquire the lock automatically. In order to allow a second (and third or more) instance of Pythonize to be created and obtain the lock, it's necessary to have a related thread state (PyThreadState). This thread state is created by a call to PyThreadState_Get when the first instance of Pythonize is created. The thread state is stored in a global variable (declared in the cpp file) that is used by all subsequent instances of Pythonize. This means that applications using libpythonize are mormally single-threaded, at least in relation to the libpythonize interpreter instance. This is important for utilization with sip-based bindings like PyKDE and PyTQt.

The global thread state is accessible via the getThreadState/setThreadState methods.

Methods/Functions

Methods are either called directly in C or as class members in C++. In C, int variables/values are used instead of bool.

 
C++:
	Pythonize *pyize = Pythonize ();
	...
	bool result = pyize->appendToSysPath ("/usr/local/foo");

C:
	initialize ();
	...
	int result = appendToSysPath ("/usr/local/foo");

Pythonize () [C++] or initialize () [C]

Constructor/initializer - loads and initializaes the interpreter and acquires the global interpreter lock. Sets the value of pythonInit to true on success or false if construction/initialization fails Initializes the global thread state (first instance) or restores the global thread state (second and later instances). It is the programmer's resposibility to release the global interpreter lock to enable other code to access the interpreter. The lock and thread state are automatically acquired when any Pythonize instance is created..


bool getPythonInit ()

Returns the result of initializing/constructing the interpreter object. If the return value is true, the interpreter should be usable. If it returns false, an error occurred and the interpreter will not be useful. Most methods/functions check the value of pythonInit and won't run if it's false


~Pythonize () [C++] or finalize () [C]

Destructor/finalizer - shuts down the interpreter and destroys the class Sets pythonInit to false.


bool appendToSysPath (const char* newPath);

Appends newPath to sys.path


PyObject *importModule (char *moduleName);

Imports a module into the interpreter. Same as "import " in Python. moduleName must exist somewhere on sys.path. Returns a reference to the module imported. Returns NULL on failure.


PyObject *getNewObjectRef (PyObject *module, char *object)

Returns a reference to an object in an already loaded module (use importModule to load the module or get a reference to it) Returns NULL on failure.


PyObject *getSysModule ()

Returns a reference to the Python sys module. Returns NULL on failure.


PyObject *getMainModule ()

Returns a reference to the Python main module. Returns NULL on failure.


[internal] void *setMainModule ()

Sets internal value of main module


void decref (PyObject *object)

Uses Py_XDECREF to decrement the reference count of an object


bool runScript (char *scriptPath);

Runs an arbitrary script in the interpreter and returns Python's result.


bool runString (char *str);

Runs an arbitrary string in the interpreter (indentation required for mulit-line strings) and returns Python's result.


PyObject *runFunction (PyObject *object, PyObject *args);

If object is callable, runs object with args and returns the results of the function call as a PyObject. Returns NULL on failure.


void releaseLock ()

Releases the global interpreter lock using PyEval_SaveThread. Saves the global thread state.


void acquireLock ()

Acquires the global interpreter lock using PyEval_RestoreThread. Restores the global thread state.


PyThreadState *getThreadState ()

Retrieves the current value of the global thread state. Does not affect the global interpreter lock.


PyThreadState *setThreadState (PyThreadState *tstate)

Sets the global thread state to tstate and returns the previous global thread state. Does not affect the global interpreter lock.


Using libpythonize in an application

Include the pythonize.h header file (requires Python.h) and link to libpythonize.so - that's pretty much it. There are unit tests in both C and C++ in the pythonize/tests/ subdirectory. An example of libpythonize usage is in pykpanelapplet.cpp in the PyKDE distribution (pykpanelapplet/ directory).

Obtaining and building libpythonize

At present only the C++/C wrapper versions are available, and they're distributed with PyKDE.

The build process for libpythonize uses TrollTech's qmake (available as part of TQt), but is simple enough to be included in most make files. See the pythonize.pro file for more information - most of the additional libs required are required by libpython, and may vary by platform.

You can contact me at this address: Jim Bublitz <jbublitz@nwinternet.com>

Prev Home
Applet Installer