PyObject* PythonSecurity::compile_restricted(const QString& source, const QString& filename, const QString& mode) { krossdebug("PythonSecurity::compile_restricted"); if(! m_pymodule) initRestrictedPython(); // throws exception if failed try { Py::Dict mainmoduledict = ((PythonInterpreter*)m_interpreter)->mainModule()->getDict(); PyObject* func = PyDict_GetItemString(m_pymodule->getDict().ptr(), "compile_restricted"); if(! func) throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("No such function '%1'.").arg("compile_restricted")) ); Py::Callable funcobject(func, true); // the funcobject takes care of freeing our func pyobject. if(! funcobject.isCallable()) throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("Function '%1' is not callable.").arg("compile_restricted")) ); Py::Tuple args(3); args[0] = Py::String(source.utf8()); args[1] = Py::String(filename.utf8()); args[2] = Py::String(mode.utf8()); Py::Object result = funcobject.apply(args); PyObject* pycode = PyEval_EvalCode( (PyCodeObject*)result.ptr(), mainmoduledict.ptr(), mainmoduledict.ptr() ); if(! pycode) throw Py::Exception(); /* Py::List ml = mainmoduledict; for(Py::List::size_type mi = 0; mi < ml.length(); ++mi) { krossdebug( QString("dir() = %1").arg( ml[mi].str().as_string().c_str() ) ); //krossdebug( QString("dir().dir() = %1").arg( Py::Object(ml[mi]).dir().as_string().c_str() ) ); } */ Py::Object code(pycode); krossdebug( QString("%1 callable=%2").arg(code.as_string().c_str()).arg(PyCallable_Check(code.ptr())) ); Py::List l = code.dir(); for(Py::List::size_type i = 0; i < l.length(); ++i) { krossdebug( QString("dir() = %1").arg( l[i].str().as_string().c_str() ) ); //krossdebug( QString("dir().dir() = %1").arg( Py::Object(l[i]).dir().as_string().c_str() ) ); } return pycode; } catch(Py::Exception& e) { QString err = Py::value(e).as_string().c_str(); e.clear(); throw Kross::Api::Exception::Ptr( new Kross::Api::Exception(QString("Function '%1' failed with python exception: %2").arg("compile_restricted").arg(err) ) ); } }
Py::List toListOfStrings( Py::Object obj ) { Py::List list; if( obj.isList() ) list = obj; else list.append( obj ); // check all members of the list are strings for( Py::List::size_type i=0; i<list.length(); i++ ) { Py::String path_str( list[i] ); } return list; }
void PythonInterpreter::extractException(QStringList& errorlist, int& lineno) { lineno = -1; PyObject *type, *value, *traceback; PyErr_Fetch(&type, &value, &traceback); Py_FlushLine(); PyErr_NormalizeException(&type, &value, &traceback); if(traceback) { Py::List tblist; try { Py::Module tbmodule( PyImport_Import(Py::String("traceback").ptr()), true ); Py::Dict tbdict = tbmodule.getDict(); Py::Callable tbfunc(tbdict.getItem("format_tb")); Py::Tuple args(1); args.setItem(0, Py::Object(traceback)); tblist = tbfunc.apply(args); uint length = tblist.length(); for(Py::List::size_type i = 0; i < length; ++i) errorlist.append( Py::Object(tblist[i]).as_string().c_str() ); } catch(Py::Exception& e) { QString err = Py::value(e).as_string().c_str(); e.clear(); // exception is handled. clear it now. #ifdef KROSS_PYTHON_EXCEPTION_DEBUG krosswarning( QString("Kross::PythonScript::toException() Failed to fetch a traceback: %1").arg(err) ); #endif } PyObject *next; while (traceback && traceback != Py_None) { PyFrameObject *frame = (PyFrameObject*)PyObject_GetAttrString(traceback, const_cast< char* >("tb_frame")); { PyObject *getobj = PyObject_GetAttrString(traceback, const_cast< char* >("tb_lineno") ); lineno = PyInt_AsLong(getobj); Py_DECREF(getobj); } if(Py_OptimizeFlag) { PyObject *getobj = PyObject_GetAttrString(traceback, const_cast< char* >("tb_lasti") ); int lasti = PyInt_AsLong(getobj); Py_DECREF(getobj); lineno = PyCode_Addr2Line(frame->f_code, lasti); } //const char* filename = PyString_AsString(frame->f_code->co_filename); //const char* name = PyString_AsString(frame->f_code->co_name); //errorlist.append( QString("%1#%2: \"%3\"").arg(filename).arg(lineno).arg(name) ); //Py_DECREF(frame); // don't free cause we don't own it. next = PyObject_GetAttrString(traceback, const_cast< char* >("tb_next") ); Py_DECREF(traceback); traceback = next; } } if(lineno < 0 && value && PyObject_HasAttrString(value, const_cast< char* >("lineno"))) { PyObject *getobj = PyObject_GetAttrString(value, const_cast< char* >("lineno") ); if(getobj) { lineno = PyInt_AsLong(getobj); Py_DECREF(getobj); } } #ifdef KROSS_PYTHON_EXCEPTION_DEBUG //krossdebug( QString("PythonInterpreter::extractException: %1").arg( Py::Object(value).as_string().c_str() ) ); krossdebug( QString("PythonInterpreter::extractException:\n%1").arg( errorlist.join("\n") ) ); #endif PyErr_Restore(type, value, traceback); }