At the moment Roland's plugin is going to be hard to install if 
don't have PyKDE-3.8rc2 installed already. If you dont' have 
PyKDE-3.8rc2 installed, it's available at: 

        http://www.sourceforge.net/projects/pykde

You can copy the attached cpp and h files (but NOT the .pro 
file!) into PyKDE-3.8rc2/pythonize, overwriting what's there.
Then cd to that directory, run make, su, make install (you 
shouldn't have to rebuild PyKDE *IF* you've already built it).

Without PyKDE-3.8rc2, you'll need to futz around with the .pro 
file attached. @BL_INCLUDE_PATH@ is the path to Python.h 
(something like /usr/include/python) and @BL_LIBPYTHON@ is the 
path to libpython.a (something like /usr/lib/python/config). 
Just replace the @xxx@ symbols with the correct paths. You'll 
also need to adjust the target directory in the .pro file. Run 
qmake on the .pro file to create a make file, and make. If the 
target directory only has root write perms, you'll need to su to 
run make.

After that, you'll probably need to touch up the paths in 
Roland's .pro file, run qmake on it, and then make, etc. His 
paths that start with '$$' are into the qt directory hierarchy - 
plugins/ and interfaces/ I believe. You may need to fix some of 
his other paths/libs for your system.

The pythonize stuff that's in 3.8rc2 will probably work, but only 
for a single widget. The attached files fix that. libpythonize 
has no dependencies on PyKDE or PyQt or sip, but hasn't been 
packaged up for anything but PyKDE yet because nothing else used 
it. All libpythonize does is embeds the Python interpreter in a 
.so file and provides a simple wrapper for some Python C/API 
stuff.

It isn't as hard as it probably looks. I started writing out a 
step by step procedure, and there are a lot of steps and 'ifs' 
depending on how your system is set up. Also, I don't know if 
any of this will work on Windows - don't have a machine to test 
it on. Seems like it should.

Obviously, this needs an install procedure someday.

Jim
/* copyright 2003 Jim Bublitz <[EMAIL PROTECTED]>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
*/

#include <stdarg.h>
#include <string.h>

#include <Python.h>

PyThreadState *ts;
#include <pythonize.h>

#define debug 1


ObjectRef::ObjectRef (ObjectRef *oi, PyObject *o)
{
    prevObject = oi;
    object     = o;
}


Pythonize::Pythonize ()
{
    pythonInit = true;
    mainModule = NULL;
    sysModule  = NULL;
    objects    = NULL;

    if (debug) printf ("\n\nPythonize constructor -- pid = %i\n", getpid ());

    if (!Py_IsInitialized ())
    {
        // First instance
        PyEval_InitThreads ();
        Py_Initialize ();
        if (!Py_IsInitialized ())
        {
            pythonInit = false;
            return;
        }

        // Always instantiate a new interpreter (for the thread state)
        ts = Py_NewInterpreter ();
        if (debug) printf ("Python interpreter initialized\n\n");

        sysModule  = PyImport_ImportModule ("sys");

        if (!sysModule)
            pythonInit = false;
            return;
    }
    else
    {
        // Other instances - just get the thread state and lock
        acquireLock ();
    }

        // this doesn't work here ???
//    mainModule = PyImport_ImportModule ("__main__");

}

bool Pythonize::runScript (char *scriptPath)
{
    FILE *f;
    int res;

    if (scriptPath == NULL || strlen (scriptPath) == 0) return false;

    f = fopen (scriptPath, "r");
    if (f == NULL) return false;

    res = PyRun_SimpleFile (f, scriptPath);
    fclose (f);

    return res == 0;
}

PyObject * Pythonize::runFunction (PyObject *object, PyObject *args)
{

    if (!PyCallable_Check (object))
        return NULL;

    PyObject *res = PyObject_CallObject (object, args ? args : PyTuple_New (0));
    if (res)
        Py_INCREF (res);

    return res;
}

bool Pythonize::runString (char *str)
{

    if (str == NULL || strlen (str) == 0) return false;

    int res = PyRun_SimpleString (str);

    return res == 0;
}

bool Pythonize::appendToSysPath (const char* newPath)
{
    if (newPath == NULL || strlen (newPath) == 0) return false;

    char *fmtString = "import sys\nif not '%s' in sys.path:\n\tsys.path.append ('%s')\n"; //print sys.path\n";
    int length      = strlen (fmtString) + 2*strlen (newPath) + 1;
    char *line      = new char [length];
    if (!line) return false;
    snprintf (line, length, fmtString, newPath, newPath);

    int res = PyRun_SimpleString (line);
    delete line;

    return res == 0;
}

PyObject *Pythonize::importModule (char *moduleName)
{
    if (moduleName == NULL || strlen (moduleName) == 0) return NULL;

    PyObject *module = PyImport_ImportModule (moduleName);

    objects = new ObjectRef (objects, module);

    return module;
}


Pythonize::~Pythonize ()
{

    if (debug) printf ("Pythonize destructor\n");
    acquireLock ();

    ObjectRef *top;

    while (objects)
    {
        top = objects;
        objects = objects->prevObject;
        delete top;
    }

    if (debug) printf (" --- Objects destroyed\n");

//    Py_XDECREF (sysModule);
    Py_XDECREF (mainModule);

    if (debug) printf (" --- Our mainModule object released\n");

//    Py_Finalize ();
    releaseLock ();
    if (debug) printf (" --- Py_Finalized\n");
}

void Pythonize::releaseLock ()
{
    ts = PyEval_SaveThread ();
}

void Pythonize::acquireLock ()
{
    PyEval_RestoreThread (ts);
}


PyThreadState *Pythonize::getThreadState ()
{
    return ts;
}

PyThreadState *Pythonize::setThreadState (PyThreadState *tstate)
{
    PyThreadState * oldts = ts;
    ts = tstate;
    return oldts;
}


extern "C"
{
Pythonize *_pythonize;

Pythonize *initialize ()
{
    if (_pythonize) return _pythonize;

    _pythonize = new Pythonize ();
    if (!_pythonize || !_pythonize->getPythonInit ())
    {
        if (_pythonize) delete _pythonize;
        return NULL;
    }

    return _pythonize;
}

void finalize ()
{
    if (_pythonize) delete _pythonize;
}

            // adds a path to sys.path
bool appendToSysPath (const char* newPath)
{
    return _pythonize ? _pythonize->appendToSysPath (newPath) : false;
}

                // imports a module into the interpreter
                // or gets a PyObject for an already loaded module
PyObject *importModule (char *moduleName)
{
    return _pythonize ? _pythonize->importModule (moduleName) : NULL;
}

                // returns an object from a loaded module
                // you must decref the object returned when done with it (new reference returned)
PyObject *getNewObjectRef (PyObject *module, char *object)
{
    printf ("getting object ref\n");
    return _pythonize ? _pythonize->getNewObjectRef (module, object) : NULL;
}

PyObject *getSysModule ()
{
    return _pythonize ? _pythonize->getSysModule() : NULL;
}

PyObject *getMainModule ()
{
    return _pythonize ? _pythonize->getMainModule () : NULL;
}

                // ??? for some reason, this won't work in the Pythonize ctor ???
void *setMainModule ()
{
    if (_pythonize) _pythonize->setMainModule ();
}

bool getPythonInit ()
{
    return _pythonize ? _pythonize->getPythonInit () : false;
}

                // decrements the ref count of an object
void decref (PyObject *object)
{
     Py_XDECREF (object);
}

                // runs a script on the current sys.path
bool runScript (char *scriptPath)
{
    return _pythonize ? _pythonize->runScript (scriptPath) : false;
}

                // executes a string of Python in the interpreter
bool runString (char *str)
{
    return _pythonize ? _pythonize->runString (str) : false;
}

                // runs a callable Python object
PyObject *runFunction (PyObject *object, PyObject *args)
{
    return _pythonize ? _pythonize->runFunction (object, args) : NULL;
}

void releaseLock ()
{
    if (_pythonize)
        _pythonize->releaseLock ();
}

void acquireLock ()
{
    if (_pythonize)
        _pythonize->acquireLock ();
}
PyThreadState *getThreadState ()
{
    if (_pythonize)
        return _pythonize->getThreadState ();
    else
        return NULL;
}

PyThreadState *setThreadState (PyThreadState *tstate)
{
    if (_pythonize)
        return _pythonize->setThreadState (tstate);
    else
        return NULL;
}
}










/* copyright 2003 Jim Bublitz <[EMAIL PROTECTED]>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of
   the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
*/

#ifndef __pythonize_h__
#define __pythonize_h__


// Pythonize is a general purpose library that wraps the Python
// interpreter with an interface to a set of common operations
// used when embedding the interpreter.

#include <Python.h>


struct ObjectRef
{
                        ObjectRef (ObjectRef *oi, PyObject *o);
                        ~ObjectRef () { Py_XDECREF (object); }

        PyObject        *object;        // pointer to an object we created
        ObjectRef       *prevObject;    // pointer to next object on the stack
};


class Pythonize
{
public:
                        Pythonize ();
                        ~Pythonize ();

                        // adds a path to sys.path
        bool            appendToSysPath (const char* newPath);

                        // imports a module into the interpreter
                        // or gets a PyObject for an already loaded module
        PyObject        *importModule (char *moduleName);

                        // returns an object from a loaded module
                        // you must decref the object returned when done with it (new reference returned)
        PyObject        *getNewObjectRef (PyObject *module, char *object) { return PyObject_GetAttrString (module, object); }

        PyObject        *getSysModule () { return sysModule; }
        PyObject        *getMainModule () { return mainModule; }

                        // ??? for some reason, this won't work in the Pythonize ctor ???
        void            setMainModule () { mainModule = PyImport_ImportModule ("__main__"); }
        bool            getPythonInit () { return pythonInit; }

                        // decrements the ref count of an object
        void            decref (PyObject *object) { Py_XDECREF (object); }

                        // runs a script on the current sys.path
        bool            runScript (char *scriptPath);

                        // executes a string of Python in the interpreter
        bool            runString (char *str);

                        // runs a callable Python object
        PyObject        *runFunction (PyObject *object, PyObject *args);

                        // handle the thread state and global interpreter lock
        void            releaseLock ();
        void            acquireLock ();
        PyThreadState   *getThreadState ();
        PyThreadState   *setThreadState (PyThreadState *tstate);

private:
        bool            pythonInit;     // status of Py_Initialize
        PyObject        *sysModule;     // a pointer to the sys module which is always loaded first
        PyObject        *mainModule;    // a pointer to __main__
        ObjectRef       *objects;       // a stack of PyObjects (used in destructor)

};

extern "C"
{
    Pythonize       *initialize ();
    void            finalize ();

                    // adds a path to sys.path
    bool            appendToSysPath (const char* newPath);

                    // imports a module into the interpreter
                    // or gets a PyObject for an already loaded module
    PyObject        *importModule (char *moduleName);

                    // returns an object from a loaded module
                    // you must decref the object returned when done with it (new reference returned)
    PyObject        *getNewObjectRef (PyObject *module, char *object);

    PyObject        *getSysModule ();
    PyObject        *getMainModule ();

                    // ??? for some reason, this won't work in the Pythonize ctor ???
    void            *setMainModule ();
    bool            getPythonInit ();

                    // decrements the ref count of an object
    void            decref (PyObject *object);

                    // runs a script on the current sys.path
    bool            runScript (char *scriptPath);

                    // executes a string of Python in the interpreter
    bool            runString (char *str);

                    // runs a callable Python object
    PyObject        *runFunction (PyObject *object, PyObject *args);

    void            releaseLock ();
    void            acquireLock ();

    PyThreadState  *getThreadState ();
    PyThreadState  *setThreadState (PyThreadState *tstate);

}

#endif
#
#     Copyright 2003 Jim Bublitz <[EMAIL PROTECTED]>

TEMPLATE = lib
TARGET = pythonize
DESTDIR = ../libs
CONFIG = dll warn_off
INCLUDEPATH += @BL_INCLUDEPATH@ .
DEFINES =
QMAKE_LFLAGS_SHLIB += -Xlinker -export-dynamic -Wl,-E
unix:LIBS +=  -L @BL_LIBPYTHON@ -lutil -lpthread -ldl
SOURCES = pythonize.cpp
HEADERS = \
        pythonize.h

Reply via email to