K
karye2004
Hi!
I'm trying to access python objects from c++. It works once. Second
time it hangs.
Does someone have any clue or some example code or pointer?
Thanks!
/Karim
Here are some python classes:
--------------------------------------------------------------------------------------------------
import portage
class PortageInterface:
def __init__(self):
self.vartree = portage.db[portage.root]["vartree"]
self.porttree = portage.db[portage.root]["porttree"]
def installedPackages(self):
return self.vartree.dbapi.cp_all()
def installedPackagesVersion(self):
t = []
for cpv in self.vartree.dbapi.cpv_all():
mysplit = portage.catpkgsplit(cpv)
mypkg = "/".join(mysplit[:3])
if mysplit[3] != "r0":
mypkg = mypkg + "-" + mysplit[3]
t.append( mypkg )
return t
def portagePackages(self):
return self.porttree.dbapi.cp_all()
def allPortagePackages(self):
t = []
t = self.porttree.dbapi.cp_all()
t += self.vartree.dbapi.cp_all()
return t
def allPackagesVersion(self):
t = []
for x in self.porttree.dbapi.cp_all():
t.extend( self.porttree.dbapi.cp_list(x) )
return t
def getAllPackageData(self, db, keys):
rval = {}
cplist = db.cp_all()
cplist.sort()
for cp in cplist:
for cpv in db.cp_list(cp):
rval[cpv] = db.aux_get(cpv, keys)
return rval
def allPackagesData(self):
testdata = {}
testdata = self.getAllPackageData(self.porttree.dbapi,
["DESCRIPTION", "HOMEPAGE", "LICENSE", "KEYWORDS", "IUSE", "SLOT"])
t = []
for cpv in testdata.keys():
mysplit = portage.catpkgsplit(cpv)
mypkg = "/".join(mysplit[:3])
if mysplit[3] != "r0":
mypkg = mypkg + "-" + mysplit[3]
t.append( mypkg )
for v in testdata[cpv]:
t.append( v )
return t
--------------------------------------------------------------------------------------------------
And the c++ class executed inside a thread:
--------------------------------------------------------------------------------------------------
#include "pythonizer.h"
#ifdef _XOPEN_SOURCE
#undef _XOPEN_SOURCE
#endif
#ifdef _POSIX_C_SOURCE
#undef _POSIX_C_SOURCE
#endif
#include <Python.h>
#include <qstringlist.h>
#include <qfile.h>
#include <kdebug.h>
#define foreach( x ) \
for( QStringList::ConstIterator it = x.begin(), end = x.end(); it !=
end; ++it )
#define LINE_INFO " ( " << k_funcinfo << "Line: " << __LINE__ << " )"
<< endl
#define DEBUG_LINE_INFO kdDebug() << LINE_INFO
Pythonizer:
ythonizer( const char *file, char *pyClass )
: m_file( file ), m_pyClass( pyClass )
{
kdDebug() << "Pythonizer:
ythonizer" << endl;
}
Pythonizer::~Pythonizer()
{
kdDebug() << "Pythonizer::~Pythonizer" << endl;
}
QStringList Pythonizer::getPackages( char *pyModule )
{
DEBUG_LINE_INFO;
// Initialize the Python Interpreter
Py_Initialize();
PyObject *pName, *pModule, *pDict, *pValue, *pClass, *pInstance;
// Build the name object
pName = PyString_FromString( m_file );
DEBUG_LINE_INFO;
if ( PyErr_Occurred() ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QStringList();
}
// Load the module object
pModule = PyImport_Import( pName );
DEBUG_LINE_INFO;
if ( PyErr_Occurred() ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QStringList();
}
// pDict is a borrowed reference
pDict = PyModule_GetDict( pModule );
DEBUG_LINE_INFO;
if ( PyErr_Occurred() ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QStringList();
}
// Build the name of a callable class
pClass = PyDict_GetItemString( pDict, m_pyClass );
DEBUG_LINE_INFO;
if ( PyErr_Occurred() ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QStringList();
}
// Create an instance of the class
if ( PyCallable_Check( pClass ) ) {
pInstance = PyObject_CallObject( pClass, NULL );
DEBUG_LINE_INFO;
if ( PyErr_Occurred() ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QStringList();
}
}
else {
kdDebug() << "Can not create python class instance." << endl;
return QStringList::QStringList();
}
// Call a method of the class with two parameters
pValue = PyObject_CallMethod( pInstance, pyModule, NULL );
if ( PyErr_Occurred() ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QStringList();
}
PyObject *iterator = PyObject_GetIter( pValue );
if ( iterator == NULL ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QStringList();
}
QStringList packageList;
PyObject *item;
while ( item = PyIter_Next( iterator ) ) {
packageList << PyString_AsString( item );
/* release reference when done */
Py_DECREF( item );
}
Py_DECREF( iterator );
// Clean up
Py_DECREF( pValue );
Py_DECREF( pInstance );
Py_DECREF( pClass );
// Py_DECREF( pDict );
Py_DECREF( pModule );
Py_DECREF( pName );
PyErr_Clear();
DEBUG_LINE_INFO;
// Finish the Python Interpreter
Py_Finalize();
return packageList;
}
--------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------
#ifndef PYTHONIZER_H
#define PYTHONIZER_H
#include <qstringlist.h>
class Pythonizer{
public:
Pythonizer( const char *file, char *pyClass );
~Pythonizer();
QStringList getPackages( char *pyModule );
private:
QString m_file;
QString m_pyClass;
};
#endif
--------------------------------------------------------------------------------------------------
I'm trying to access python objects from c++. It works once. Second
time it hangs.
Does someone have any clue or some example code or pointer?
Thanks!
/Karim
Here are some python classes:
--------------------------------------------------------------------------------------------------
import portage
class PortageInterface:
def __init__(self):
self.vartree = portage.db[portage.root]["vartree"]
self.porttree = portage.db[portage.root]["porttree"]
def installedPackages(self):
return self.vartree.dbapi.cp_all()
def installedPackagesVersion(self):
t = []
for cpv in self.vartree.dbapi.cpv_all():
mysplit = portage.catpkgsplit(cpv)
mypkg = "/".join(mysplit[:3])
if mysplit[3] != "r0":
mypkg = mypkg + "-" + mysplit[3]
t.append( mypkg )
return t
def portagePackages(self):
return self.porttree.dbapi.cp_all()
def allPortagePackages(self):
t = []
t = self.porttree.dbapi.cp_all()
t += self.vartree.dbapi.cp_all()
return t
def allPackagesVersion(self):
t = []
for x in self.porttree.dbapi.cp_all():
t.extend( self.porttree.dbapi.cp_list(x) )
return t
def getAllPackageData(self, db, keys):
rval = {}
cplist = db.cp_all()
cplist.sort()
for cp in cplist:
for cpv in db.cp_list(cp):
rval[cpv] = db.aux_get(cpv, keys)
return rval
def allPackagesData(self):
testdata = {}
testdata = self.getAllPackageData(self.porttree.dbapi,
["DESCRIPTION", "HOMEPAGE", "LICENSE", "KEYWORDS", "IUSE", "SLOT"])
t = []
for cpv in testdata.keys():
mysplit = portage.catpkgsplit(cpv)
mypkg = "/".join(mysplit[:3])
if mysplit[3] != "r0":
mypkg = mypkg + "-" + mysplit[3]
t.append( mypkg )
for v in testdata[cpv]:
t.append( v )
return t
--------------------------------------------------------------------------------------------------
And the c++ class executed inside a thread:
--------------------------------------------------------------------------------------------------
#include "pythonizer.h"
#ifdef _XOPEN_SOURCE
#undef _XOPEN_SOURCE
#endif
#ifdef _POSIX_C_SOURCE
#undef _POSIX_C_SOURCE
#endif
#include <Python.h>
#include <qstringlist.h>
#include <qfile.h>
#include <kdebug.h>
#define foreach( x ) \
for( QStringList::ConstIterator it = x.begin(), end = x.end(); it !=
end; ++it )
#define LINE_INFO " ( " << k_funcinfo << "Line: " << __LINE__ << " )"
<< endl
#define DEBUG_LINE_INFO kdDebug() << LINE_INFO
Pythonizer:
: m_file( file ), m_pyClass( pyClass )
{
kdDebug() << "Pythonizer:
}
Pythonizer::~Pythonizer()
{
kdDebug() << "Pythonizer::~Pythonizer" << endl;
}
QStringList Pythonizer::getPackages( char *pyModule )
{
DEBUG_LINE_INFO;
// Initialize the Python Interpreter
Py_Initialize();
PyObject *pName, *pModule, *pDict, *pValue, *pClass, *pInstance;
// Build the name object
pName = PyString_FromString( m_file );
DEBUG_LINE_INFO;
if ( PyErr_Occurred() ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QStringList();
}
// Load the module object
pModule = PyImport_Import( pName );
DEBUG_LINE_INFO;
if ( PyErr_Occurred() ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QStringList();
}
// pDict is a borrowed reference
pDict = PyModule_GetDict( pModule );
DEBUG_LINE_INFO;
if ( PyErr_Occurred() ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QStringList();
}
// Build the name of a callable class
pClass = PyDict_GetItemString( pDict, m_pyClass );
DEBUG_LINE_INFO;
if ( PyErr_Occurred() ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QStringList();
}
// Create an instance of the class
if ( PyCallable_Check( pClass ) ) {
pInstance = PyObject_CallObject( pClass, NULL );
DEBUG_LINE_INFO;
if ( PyErr_Occurred() ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QStringList();
}
}
else {
kdDebug() << "Can not create python class instance." << endl;
return QStringList::QStringList();
}
// Call a method of the class with two parameters
pValue = PyObject_CallMethod( pInstance, pyModule, NULL );
if ( PyErr_Occurred() ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QStringList();
}
PyObject *iterator = PyObject_GetIter( pValue );
if ( iterator == NULL ) {
PyErr_Print();
PyErr_Clear();
return QStringList::QStringList();
}
QStringList packageList;
PyObject *item;
while ( item = PyIter_Next( iterator ) ) {
packageList << PyString_AsString( item );
/* release reference when done */
Py_DECREF( item );
}
Py_DECREF( iterator );
// Clean up
Py_DECREF( pValue );
Py_DECREF( pInstance );
Py_DECREF( pClass );
// Py_DECREF( pDict );
Py_DECREF( pModule );
Py_DECREF( pName );
PyErr_Clear();
DEBUG_LINE_INFO;
// Finish the Python Interpreter
Py_Finalize();
return packageList;
}
--------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------
#ifndef PYTHONIZER_H
#define PYTHONIZER_H
#include <qstringlist.h>
class Pythonizer{
public:
Pythonizer( const char *file, char *pyClass );
~Pythonizer();
QStringList getPackages( char *pyModule );
private:
QString m_file;
QString m_pyClass;
};
#endif
--------------------------------------------------------------------------------------------------