@@ -67,20 +67,28 @@ Python::Interpreter::Interpreter(){
6767 auto module_name=it->path ().stem ().string ();
6868 if (module_name!=" __pycache__" ){
6969 auto module =import (module_name);
70- if (!module )
71- std::cerr << std::string (Error ()) << std::endl;
70+ if (!module ){
71+ auto err=std::string (Error ());
72+ auto msg=" Error loading plugin " +module_name+" :\n " ;
73+ Terminal::get ().print (msg,true );
74+ Terminal::get ().print (err+" \n " );
75+ }
7276 }
7377 }
7478}
7579
76- pybind11::module Python::Interpreter:: get_loaded_module (const std::string &module_name){
80+ pybind11::module Python::get_loaded_module (const std::string &module_name){
7781 return pybind11::module (PyImport_AddModule (module_name.c_str ()), true );
7882}
7983
80- pybind11::module Python::Interpreter:: import (const std::string &module_name){
84+ pybind11::module Python::import (const std::string &module_name){
8185 return pybind11::module (PyImport_ImportModule (module_name.c_str ()), false );
8286}
8387
88+ pybind11::module Python::reload (pybind11::module &module ){
89+ return pybind11::module (PyImport_ReloadModule (module .ptr ()),false );
90+ }
91+
8492void Python::Interpreter::add_path (const boost::filesystem::path &path){
8593 if (path.empty ())
8694 return ;
@@ -103,26 +111,54 @@ Python::Interpreter::~Interpreter(){
103111 std::cerr << std::string (err) << std::endl;
104112}
105113
114+ pybind11::object Python::error_occured (){
115+ return pybind11::object (PyErr_Occurred (),true );
116+ }
117+
118+ bool Python::thrown_exception_matches (Error::Type type){
119+ pybind11::object compare;
120+ switch (type){
121+ case Error::Type::Syntax : compare=pybind11::object (PyExc_SyntaxError,false );
122+ case Error::Type::Attribute : compare=pybind11::object (PyExc_AttributeError,false );
123+ case Error::Type::Import : compare=pybind11::object (PyExc_ImportError,false );
124+ }
125+ return PyErr_GivenExceptionMatches (Python::error_occured ().ptr (), compare.ptr ());
126+ }
127+
106128Python::Error::Error (){
107- pybind11::object error (PyErr_Occurred (), false );
108- if (error){
109- PyObject *exception,*value,*traceback;
110- PyErr_Fetch (&exception,&value,&traceback);
111- PyErr_NormalizeException (&exception,&value,&traceback);
129+ if (error_occured ()){
112130 try {
113- exp=std::string (pybind11::object (exception,false ).str ());
114- val=std::string (pybind11::object (value,false ).str ());
115- trace=std::string (pybind11::object (traceback,false ).str ());
116- } catch (const std::runtime_error &e){
117- exp=e.what ();
131+ PyErr_Fetch (&exp.ptr (),&val.ptr (),&trace.ptr ());
132+ PyErr_NormalizeException (&exp.ptr (),&val.ptr (),&trace.ptr ());
133+ }catch (const std::exception &e) {
134+ Terminal::get ().print (e.what ());
118135 }
119136 }
120137}
121138
122139Python::Error::operator std::string (){
123- return exp + " \n " + val + " \n " + trace;
140+ return std::string (exp.str ())+" \n " +std::string (val.str ())+" \n " ;
141+ }
142+
143+ Python::SyntaxError::SyntaxError ():Error(){
144+ if (val){
145+ _Py_IDENTIFIER (msg);
146+ _Py_IDENTIFIER (lineno);
147+ _Py_IDENTIFIER (offset);
148+ _Py_IDENTIFIER (text);
149+ exp=std::string (pybind11::str (_PyObject_GetAttrId (val.ptr (),&PyId_msg),false ));
150+ text=std::string (pybind11::str (_PyObject_GetAttrId (val.ptr (),&PyId_text),false ));
151+ pybind11::object py_line_number (_PyObject_GetAttrId (val.ptr (),&PyId_lineno),false );
152+ pybind11::object py_line_offset (_PyObject_GetAttrId (val.ptr (),&PyId_offset),false );
153+ line_number=pybind11::cast<int >(py_line_number);
154+ line_offset=pybind11::cast<int >(py_line_offset);
155+ }
156+ }
157+
158+ Python::SyntaxError::operator std::string (){
159+ return exp+" (" +std::to_string (line_number)+" :" +std::to_string (line_offset)+" ):\n " +text;
124160}
125161
126162Python::Error::operator bool (){
127- return ! exp. empty () ;
163+ return exp;
128164}
0 commit comments