lib
pythoninterpreter.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "pythoninterpreter.h"
00021 #include "pythonscript.h"
00022 #include "pythonmodule.h"
00023 #include "pythonsecurity.h"
00024
00025 #include "../api/variant.h"
00026
00027 #include <kglobal.h>
00028 #include <kdebug.h>
00029 #include <kstandarddirs.h>
00030
00031 #if defined(Q_WS_WIN)
00032 #define PYPATHDELIMITER ";"
00033 #else
00034 #define PYPATHDELIMITER ":"
00035 #endif
00036
00037 extern "C"
00038 {
00048 void* krossinterpreter(Kross::Api::InterpreterInfo* info)
00049 {
00050 try {
00051 return new Kross::Python::PythonInterpreter(info);
00052 }
00053 catch(Kross::Api::Exception::Ptr e) {
00054 kdWarning() << "krossinterpreter(Kross::Api::InterpreterInfo* info): Unhandled exception." << endl;
00055 }
00056 return 0;
00057 }
00058 }
00059
00060 using namespace Kross::Python;
00061
00062 namespace Kross { namespace Python {
00063
00065 class PythonInterpreterPrivate
00066 {
00067 public:
00068
00070 PythonModule* mainmodule;
00071
00073 PythonSecurity* security;
00074 };
00075
00076 }}
00077
00078 PythonInterpreter::PythonInterpreter(Kross::Api::InterpreterInfo* info)
00079 : Kross::Api::Interpreter(info)
00080 , d(new PythonInterpreterPrivate())
00081 {
00082
00083 initialize();
00084
00085
00086 Py_SetProgramName(const_cast<char*>("Kross"));
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 QString path;
00098
00099
00100
00101 Py::Module sysmod( PyImport_ImportModule("sys"), true );
00102 Py::Dict sysmoddict = sysmod.getDict();
00103 Py::Object syspath = sysmoddict.getItem("path");
00104 if(syspath.isList()) {
00105 Py::List syspathlist = syspath;
00106 for(Py::List::iterator it = syspathlist.begin(); it != syspathlist.end(); ++it)
00107 if( (*it).isString() )
00108 path.append( QString(Py::String(*it).as_string().c_str()) + PYPATHDELIMITER );
00109 }
00110 else
00111 path = Py_GetPath();
00112
00113
00114
00115 QStringList krossdirs = KGlobal::dirs()->findDirs("data", "kross/python");
00116 for(QStringList::Iterator krossit = krossdirs.begin(); krossit != krossdirs.end(); ++krossit)
00117 path.append(*krossit + PYPATHDELIMITER);
00118
00119 QStringList appdirs = KGlobal::dirs()->findDirs("appdata", "kross/python");
00120 for(QStringList::Iterator appit = appdirs.begin(); appit != appdirs.end(); ++appit)
00121 path.append(*appit + PYPATHDELIMITER);
00122
00123
00124 PySys_SetPath( (char*) path.latin1() );
00125
00126 kdDebug() << "Python ProgramName: " << Py_GetProgramName() << endl;
00127 kdDebug() << "Python ProgramFullPath: " << Py_GetProgramFullPath() << endl;
00128 kdDebug() << "Python Version: " << Py_GetVersion() << endl;
00129 kdDebug() << "Python Platform: " << Py_GetPlatform() << endl;
00130 kdDebug() << "Python Prefix: " << Py_GetPrefix() << endl;
00131 kdDebug() << "Python ExecPrefix: " << Py_GetExecPrefix() << endl;
00132 kdDebug() << "Python Path: " << Py_GetPath() << endl;
00133 kdDebug() << "Python System Path: " << path << endl;
00134
00135
00136 d->mainmodule = new PythonModule(this);
00137
00138
00139 Py::Dict moduledict = d->mainmodule->getDict();
00140
00141
00142
00143 QString s =
00144 "import sys\n"
00145
00146
00147
00148 "sys.argv = ['']\n"
00149
00150
00151
00152 "import cStringIO\n"
00153 "sys.stdin = cStringIO.StringIO()\n"
00154
00155
00156
00157 "class Redirect:\n"
00158 " def __init__(self, target):\n"
00159 " self.target = target\n"
00160 " def write(self, s):\n"
00161 " self.target.call(s)\n"
00162
00163
00164
00165
00166
00167 "import __builtin__\n"
00168 "import __main__\n"
00169 "class Importer:\n"
00170 " def __init__(self):\n"
00171 " self.realImporter = __builtin__.__import__\n"
00172 " __builtin__.__import__ = self._import\n"
00173 " def _import(self, name, globals=None, locals=None, fromlist=[]):\n"
00174 " mod = __main__._import(name, globals, locals, fromlist)\n"
00175 " if mod != None: return mod\n"
00176 " return self.realImporter(name, globals, locals, fromlist)\n"
00177 "Importer()\n"
00178 ;
00179
00180 PyObject* pyrun = PyRun_String(s.latin1(), Py_file_input, moduledict.ptr(), moduledict.ptr());
00181 if(! pyrun) {
00182 Py::Object errobj = Py::value(Py::Exception());
00183 throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("Failed to prepare the __main__ module: %1").arg(errobj.as_string().c_str())) );
00184 }
00185 Py_XDECREF(pyrun);
00186
00187
00188 d->security = new PythonSecurity(this);
00189 }
00190
00191 PythonInterpreter::~PythonInterpreter()
00192 {
00193
00194 delete d->security; d->security = 0;
00195
00196 delete d->mainmodule; d->mainmodule = 0;
00197
00198 finalize();
00199
00200 delete d;
00201 }
00202
00203 void PythonInterpreter::initialize()
00204 {
00205
00206 Py_Initialize();
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 }
00224
00225 void PythonInterpreter::finalize()
00226 {
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 Py_Finalize();
00240 }
00241
00242 Kross::Api::Script* PythonInterpreter::createScript(Kross::Api::ScriptContainer* scriptcontainer)
00243 {
00244 return new PythonScript(this, scriptcontainer);
00245 }
00246
00247 PythonModule* PythonInterpreter::mainModule()
00248 {
00249 return d->mainmodule;
00250 }
00251
00252 PythonSecurity* PythonInterpreter::securityModule()
00253 {
00254 return d->security;
00255 }
00256
|