diff --git a/src/python_interpreter.cc b/src/python_interpreter.cc index c552f76e..052d9f5e 100644 --- a/src/python_interpreter.cc +++ b/src/python_interpreter.cc @@ -62,16 +62,23 @@ Python::Interpreter::Interpreter(){ Py_Initialize(); argv=Py_DecodeLocale("",&size); PySys_SetArgv(0,&argv); + auto sys=get_loaded_module("sys"); + auto exc_func=[](pybind11::object type,pybind11::object value,pybind11::object traceback){ + if(!given_exception_matches(type,PyExc_ImportError)) + Terminal::get().print(Error(type,value,traceback),true); + else + Terminal::get().print(SyntaxError(type,value,traceback),true); + }; + sys.attr("excepthook")=pybind11::cpp_function(exc_func); boost::filesystem::directory_iterator end_it; for(boost::filesystem::directory_iterator it(plugin_path);it!=end_it;it++){ auto module_name=it->path().stem().string(); if(module_name!="__pycache__"){ auto module=import(module_name); if(!module){ + auto msg="Error loading plugin `"+module_name+"`:\n"; auto err=std::string(Error()); - auto msg="Error loading plugin "+module_name+":\n"; - Terminal::get().print(msg,true); - Terminal::get().print(err+"\n"); + Terminal::get().print(msg+err+"\n"); } } } @@ -89,6 +96,15 @@ pybind11::module Python::reload(pybind11::module &module){ return pybind11::module(PyImport_ReloadModule(module.ptr()),false); } +Python::SyntaxError::SyntaxError(pybind11::object type,pybind11::object value,pybind11::object traceback) +: Error(type,value,traceback){} + +Python::Error::Error(pybind11::object type,pybind11::object value,pybind11::object traceback){ + exp=type; + val=value; + trace=traceback; +} + void Python::Interpreter::add_path(const boost::filesystem::path &path){ if(path.empty()) return; @@ -115,14 +131,12 @@ pybind11::object Python::error_occured(){ return pybind11::object(PyErr_Occurred(),true); } -bool Python::thrown_exception_matches(Error::Type type){ - pybind11::object compare; - switch(type){ - case Error::Type::Syntax : compare=pybind11::object(PyExc_SyntaxError,false); - case Error::Type::Attribute : compare=pybind11::object(PyExc_AttributeError,false); - case Error::Type::Import : compare=pybind11::object(PyExc_ImportError,false); - } - return PyErr_GivenExceptionMatches(Python::error_occured().ptr(), compare.ptr()); +bool Python::thrown_exception_matches(pybind11::handle exception_type){ + return PyErr_ExceptionMatches(exception_type.ptr()); +} + +bool Python::given_exception_matches(const pybind11::object &exception, pybind11::handle exception_type){ + return PyErr_GivenExceptionMatches(exception.ptr(),exception_type.ptr()); } Python::Error::Error(){ @@ -131,7 +145,7 @@ Python::Error::Error(){ PyErr_Fetch(&exp.ptr(),&val.ptr(),&trace.ptr()); PyErr_NormalizeException(&exp.ptr(),&val.ptr(),&trace.ptr()); }catch(const std::exception &e) { - Terminal::get().print(e.what()); + Terminal::get().print(e.what(),true); } } } @@ -160,5 +174,5 @@ Python::SyntaxError::operator std::string(){ } Python::Error::operator bool(){ - return exp; + return exp || trace || val; } diff --git a/src/python_interpreter.h b/src/python_interpreter.h index a25d0d28..0853793b 100644 --- a/src/python_interpreter.h +++ b/src/python_interpreter.h @@ -29,21 +29,23 @@ class Python { class Error { public: Error(); + Error(pybind11::object type,pybind11::object value,pybind11::object traceback); operator std::string(); operator bool(); pybind11::object exp, val, trace; - enum Type {Syntax,Attribute,Import}; }; - class SyntaxError : Error{ + class SyntaxError : public Error{ public: SyntaxError(); + SyntaxError(pybind11::object type,pybind11::object value,pybind11::object traceback); operator std::string(); std::string exp, text; int line_number, line_offset; }; - bool static thrown_exception_matches(Error::Type exception_type); + bool static thrown_exception_matches(pybind11::handle exception_type); + bool static given_exception_matches(const pybind11::object &exception,pybind11::handle exception_type); private: pybind11::object static error_occured(); diff --git a/src/window.cc b/src/window.cc index 15c9ce82..55fd4ddd 100644 --- a/src/window.cc +++ b/src/window.cc @@ -253,21 +253,22 @@ void Window::set_menu_actions() { } } while(file_path.has_parent_path()){ - if(file_path == Config::get().python.plugin_directory){ + auto parent=file_path.parent_path(); + if(parent==Config::get().python.plugin_directory){ auto stem=file_path.stem().string(); auto module=Python::get_loaded_module(stem); module=module ? Python::reload(module) : Python::import(stem); if(module) Terminal::get().print("Plugin `"+stem+"` was reloaded\n"); else { - if(Python::thrown_exception_matches(Python::Error::Type::Syntax)) + if(Python::thrown_exception_matches(PyExc_SyntaxError)) Terminal::get().print(Python::SyntaxError()); else Terminal::get().print(Python::Error()); } break; } - file_path=file_path.parent_path(); + file_path=parent; } } }