Kross::Python::PythonScript Class Reference

#include <pythonscript.h>

Inheritance diagram for Kross::Python::PythonScript:

Inheritance graph
[legend]
Collaboration diagram for Kross::Python::PythonScript:

Collaboration graph
[legend]
List of all members.

Detailed Description

Handle python scripts. This class implements Kross::Api::Script for python.

Definition at line 36 of file pythonscript.h.

Public Member Functions

 PythonScript (Kross::Api::Interpreter *interpreter, Kross::Api::ScriptContainer *scriptcontainer)
virtual ~PythonScript ()
virtual const QStringListgetFunctionNames ()
virtual Kross::Api::Object::Ptr execute ()
virtual Kross::Api::Object::Ptr callFunction (const QString &name, Kross::Api::List::Ptr args)
virtual const QStringListgetClassNames ()
virtual Kross::Api::Object::Ptr classInstance (const QString &name)
bool hadException ()
Exception::Ptr getException ()
void setException (Exception::Ptr e)
void clearException ()

Protected Attributes

Interpreter *const m_interpreter
 The Interpreter used to create this Script instance.
ScriptContainer *const m_scriptcontainer
 The ScriptContainer associated with this Script.


Constructor & Destructor Documentation

PythonScript::PythonScript Kross::Api::Interpreter interpreter,
Kross::Api::ScriptContainer scriptcontainer
[explicit]
 

Constructor.

Parameters:
interpreter The Kross::Python::PythonInterpreter used to create this PythonScript instance.
scriptcontainer The with this PythonScript associated Kross::Api::ScriptContainer instance that spends us e.g. the python scripting code.

Definition at line 65 of file pythonscript.cpp.

References Kross::Python::PythonScriptPrivate::m_code, and Kross::Python::PythonScriptPrivate::m_module.

00066     : Kross::Api::Script(interpreter, scriptcontainer)
00067     , d(new PythonScriptPrivate())
00068 {
00069 #ifdef KROSS_PYTHON_SCRIPT_CTOR_DEBUG
00070     kdDebug() << "PythonScript::PythonScript() Constructor." << endl;
00071 #endif
00072     d->m_module = 0;
00073     d->m_code = 0;
00074 }

PythonScript::~PythonScript  )  [virtual]
 

Destructor.

Definition at line 76 of file pythonscript.cpp.

00077 {
00078 #ifdef KROSS_PYTHON_SCRIPT_DTOR_DEBUG
00079     kdDebug() << "PythonScript::~PythonScript() Destructor." << endl;
00080 #endif
00081     finalize();
00082     delete d;
00083 }


Member Function Documentation

Kross::Api::Object::Ptr PythonScript::callFunction const QString name,
Kross::Api::List::Ptr  args
[virtual]
 

Call a function.

Implements Kross::Api::Script.

Definition at line 348 of file pythonscript.cpp.

References Kross::Api::Script::hadException(), QString::latin1(), Kross::Python::PythonScriptPrivate::m_functions, Kross::Python::PythonScriptPrivate::m_module, QString::number(), and Kross::Api::Script::setException().

00349 {
00350 #ifdef KROSS_PYTHON_SCRIPT_CALLFUNC_DEBUG
00351     kdDebug() << QString("PythonScript::callFunction(%1, %2)")
00352                  .arg(name)
00353                  .arg(args ? QString::number(args->count()) : QString("NULL"))
00354                  << endl;
00355 #endif
00356 
00357     if(hadException()) return 0; // abort if we had an unresolved exception.
00358 
00359     if(! d->m_module) {
00360         setException( new Kross::Api::Exception(QString("Script not initialized.")) );
00361         return 0;
00362     }
00363 
00364     try {
00365         Py::Dict moduledict = d->m_module->getDict();
00366 
00367         // Try to determinate the function we like to execute.
00368         PyObject* func = PyDict_GetItemString(moduledict.ptr(), name.latin1());
00369 
00370         if( (! d->m_functions.contains(name)) || (! func) )
00371             throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("No such function '%1'.").arg(name)) );
00372 
00373         Py::Callable funcobject(func, true); // the funcobject takes care of freeing our func pyobject.
00374 
00375         // Check if the object is really a function and therefore callable.
00376         if(! funcobject.isCallable())
00377             throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("Function is not callable.")) );
00378 
00379         // Call the function.
00380         Py::Object result = funcobject.apply(PythonExtension::toPyTuple(args));
00381         return PythonExtension::toObject(result);
00382     }
00383     catch(Py::Exception& e) {
00384         QString err = Py::value(e).as_string().c_str();
00385         e.clear(); // exception is handled. clear it now.
00386         setException( new Kross::Api::Exception(QString("Python Exception: %1").arg(err)) );
00387     }
00388     catch(Kross::Api::Exception::Ptr e) {
00389         setException(e);
00390     }
00391 
00392     return 0; // return nothing if exception got thrown.
00393 }

Kross::Api::Object::Ptr PythonScript::classInstance const QString name  )  [virtual]
 

Create and return a new class instance.

Implements Kross::Api::Script.

Definition at line 402 of file pythonscript.cpp.

References Kross::Api::Script::hadException(), QString::latin1(), Kross::Python::PythonScriptPrivate::m_classes, Kross::Python::PythonScriptPrivate::m_module, and Kross::Api::Script::setException().

00403 {
00404     if(hadException()) return 0; // abort if we had an unresolved exception.
00405 
00406     if(! d->m_module) {
00407         setException( new Kross::Api::Exception(QString("Script not initialized.")) );
00408         return 0;
00409     }
00410 
00411     try {
00412         Py::Dict moduledict = d->m_module->getDict();
00413 
00414         // Try to determinate the class.
00415         PyObject* pyclass = PyDict_GetItemString(moduledict.ptr(), name.latin1());
00416         if( (! d->m_classes.contains(name)) || (! pyclass) )
00417             throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("No such class '%1'.").arg(name)) );
00418 
00419         PyObject *pyobj = PyInstance_New(pyclass, 0, 0);//aclarg, 0);
00420         if(! pyobj)
00421             throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("Failed to create instance of class '%1'.").arg(name)) );
00422 
00423         Py::Object classobject(pyobj, true);
00424 
00425 #ifdef KROSS_PYTHON_SCRIPT_CLASSINSTANCE_DEBUG
00426         kdDebug() << QString("PythonScript::classInstance() inst='%1'").arg(classobject.as_string().c_str()) << endl;
00427 #endif
00428         return PythonExtension::toObject(classobject);
00429     }
00430     catch(Py::Exception& e) {
00431         QString err = Py::value(e).as_string().c_str();
00432         e.clear(); // exception is handled. clear it now.
00433         setException( Kross::Api::Exception::Ptr( new Kross::Api::Exception(err) ) );
00434     }
00435     catch(Kross::Api::Exception::Ptr e) {
00436         setException(e);
00437     }
00438 
00439     return 0; // return nothing if exception got thrown.
00440 }

void Script::clearException  )  [inherited]
 

Clear previous exceptions. If called hadException() will return false again.

Definition at line 55 of file script.cpp.

00056 {
00057     m_exception = 0;
00058 }

Kross::Api::Object::Ptr PythonScript::execute  )  [virtual]
 

Execute the script.

Implements Kross::Api::Script.

Definition at line 252 of file pythonscript.cpp.

References Kross::Python::PythonScriptPrivate::m_classes, Kross::Python::PythonScriptPrivate::m_code, Kross::Python::PythonScriptPrivate::m_functions, Kross::Api::Script::m_interpreter, and Kross::Python::PythonScriptPrivate::m_module.

00253 {
00254 #ifdef KROSS_PYTHON_SCRIPT_EXEC_DEBUG
00255     kdDebug() << QString("PythonScript::execute()") << endl;
00256 #endif
00257 
00258     try {
00259         if(! d->m_module)
00260             initialize();
00261 
00262         // the main module dictonary.
00263         Py::Dict mainmoduledict = ((PythonInterpreter*)m_interpreter)->mainModule()->getDict();
00264         // the local context dictonary.
00265         Py::Dict moduledict( d->m_module->getDict().ptr() );
00266 
00267         // Initialize context before execution.
00268         QString s =
00269             "import sys\n"
00270             //"if self.has(\"stdout\"):\n"
00271             //"  sys.stdout = Redirect( self.get(\"stdout\") )\n"
00272             //"if self.has(\"stderr\"):\n"
00273             //"  sys.stderr = Redirect( self.get(\"stderr\") )\n"
00274             ;
00275 
00276         PyObject* pyrun = PyRun_String(s.latin1(), Py_file_input, mainmoduledict.ptr(), moduledict.ptr());
00277         if(! pyrun)
00278             throw Py::Exception(); // throw exception
00279         Py_XDECREF(pyrun); // free the reference.
00280 
00281         // Acquire interpreter lock*/
00282         PyGILState_STATE gilstate = PyGILState_Ensure();
00283 
00284         // Evaluate the already compiled code.
00285         PyObject* pyresult = PyEval_EvalCode(
00286             (PyCodeObject*)d->m_code->ptr(),
00287             mainmoduledict.ptr(),
00288             moduledict.ptr()
00289         );
00290 
00291         // Free interpreter lock
00292         PyGILState_Release(gilstate);
00293 
00294         if(! pyresult) {
00295             kdWarning() << "Kross::Python::PythonScript::execute(): Failed to PyEval_EvalCode" << endl;
00296             throw Py::Exception();
00297         }
00298         Py::Object result(pyresult, true);
00299 
00300 #ifdef KROSS_PYTHON_SCRIPT_EXEC_DEBUG
00301         kdDebug()<<"PythonScript::execute() result="<<result.as_string().c_str()<<endl;
00302 #endif
00303 
00304         for(Py::Dict::iterator it = moduledict.begin(); it != moduledict.end(); ++it) {
00305             Py::Dict::value_type vt(*it);
00306             if(PyClass_Check( vt.second.ptr() )) {
00307 #ifdef KROSS_PYTHON_SCRIPT_EXEC_DEBUG
00308                 kdDebug() << QString("PythonScript::execute() class '%1' added.").arg(vt.first.as_string().c_str()) << endl;
00309 #endif
00310                 d->m_classes.append( vt.first.as_string().c_str() );
00311             }
00312             else if(vt.second.isCallable()) {
00313 #ifdef KROSS_PYTHON_SCRIPT_EXEC_DEBUG
00314                 kdDebug() << QString("PythonScript::execute() function '%1' added.").arg(vt.first.as_string().c_str()) << endl;
00315 #endif
00316                 d->m_functions.append( vt.first.as_string().c_str() );
00317             }
00318         }
00319 
00320         Kross::Api::Object::Ptr r = PythonExtension::toObject(result);
00321         return r;
00322     }
00323     catch(Py::Exception& e) {
00324         try {
00325             Py::Object errobj = Py::value(e);
00326             if(errobj.ptr() == Py_None) // at least string-exceptions have there errormessage in the type-object
00327                 errobj = Py::type(e);
00328             QString err = errobj.as_string().c_str();
00329 
00330             Kross::Api::Exception::Ptr exception = toException( QString("Failed to execute python code: %1").arg(err) );
00331             e.clear(); // exception is handled. clear it now.
00332             setException( exception );
00333         }
00334         catch(Py::Exception& e) {
00335             QString err = Py::value(e).as_string().c_str();
00336             Kross::Api::Exception::Ptr exception = toException( QString("Failed to execute python code: %1").arg(err) );
00337             e.clear(); // exception is handled. clear it now.
00338             setException( exception );
00339         }
00340     }
00341     catch(Kross::Api::Exception::Ptr e) {
00342         setException(e);
00343     }
00344 
00345     return 0; // return nothing if exception got thrown.
00346 }

const QStringList & PythonScript::getClassNames  )  [virtual]
 

Return a list of class types this script supports.

Implements Kross::Api::Script.

Definition at line 395 of file pythonscript.cpp.

References Kross::Python::PythonScriptPrivate::m_classes, and Kross::Python::PythonScriptPrivate::m_module.

00396 {
00397     if(! d->m_module)
00398         initialize(); //TODO catch exception
00399     return d->m_classes;
00400 }

Exception::Ptr Script::getException  )  [inherited]
 

Returns:
the Exception the script throwed.

Definition at line 45 of file script.cpp.

Referenced by Kross::Api::ScriptContainer::classInstance(), and Kross::Api::ScriptContainer::execute().

00046 {
00047     return m_exception;
00048 }

const QStringList & PythonScript::getFunctionNames  )  [virtual]
 

Return a list of callable functionnames this script spends.

Implements Kross::Api::Script.

Definition at line 237 of file pythonscript.cpp.

References Kross::Python::PythonScriptPrivate::m_functions, and Kross::Python::PythonScriptPrivate::m_module.

00238 {
00239     if(! d->m_module)
00240         initialize(); //TODO catch exception
00241     return d->m_functions;
00242     /*
00243     QStringList list;
00244     Py::List l = d->m_module->getDict().keys();
00245     int length = l.length();
00246     for(Py::List::size_type i = 0; i < length; ++i)
00247         list.append( l[i].str().as_string().c_str() );
00248     return list;
00249     */
00250 }

bool Script::hadException  )  [inherited]
 

Returns:
true if the script throwed an exception else false.

Definition at line 40 of file script.cpp.

Referenced by callFunction(), Kross::Api::ScriptContainer::classInstance(), classInstance(), and Kross::Api::ScriptContainer::execute().

00041 {
00042     return m_exception != 0;
00043 }

void Script::setException Exception::Ptr  e  )  [inherited]
 

Set a new exception this script throwed.

Parameters:
e The Exception .

Definition at line 50 of file script.cpp.

Referenced by callFunction(), classInstance(), and Kross::Ruby::RubyScript::execute().

00051 {
00052     m_exception = e;
00053 }


The documentation for this class was generated from the following files:
Generated on Thu Feb 9 18:01:39 2006 for Kross by  doxygen 1.4.6