55#include < pygobject.h>
66#include " menu.h"
77#include " directories.h"
8+ #include " terminal.h"
89
910static wchar_t * DecodeLocale (const char * arg, size_t *size)
1011{
@@ -20,32 +21,25 @@ static wchar_t* DecodeLocale(const char* arg, size_t *size)
2021inline pybind11::module pyobject_from_gobj (gpointer ptr){
2122 auto obj=G_OBJECT (ptr);
2223 if (obj)
23- return pybind11::module (pygobject_new (obj), false );
24- return pybind11::module (Py_None, false );
24+ return pybind11::reinterpret_steal<pybind11:: module > (pygobject_new (obj));
25+ return pybind11::reinterpret_steal<pybind11:: module > (Py_None);
2526}
2627
2728Python::Interpreter::Interpreter (){
28- #ifdef _WIN32
29- auto root_path=Config::get ().terminal .msys2_mingw_path ;
30- append_path (root_path/" include/python3.5m" );
31- append_path (root_path/" lib/python3.5" );
32- long long unsigned size = 0L ;
33- #else
34- long unsigned size = 0L ;
35- #endif
29+
3630 auto init_juci_api=[](){
37- pybind11::module (pygobject_init (-1 ,-1 ,-1 ), false );
31+ auto module = pybind11::reinterpret_steal<pybind11:: module > (pygobject_init (-1 ,-1 ,-1 ));
3832 pybind11::module api (" jucpp" ," Python bindings for juCi++" );
3933 api
40- .def (" get_juci_home" ,[](){return Config::get ().juci_home_path () .string ();})
34+ .def (" get_juci_home" ,[](){return Config::get ().home_juci_path .string ();})
4135 .def (" get_plugin_folder" ,[](){return Config::get ().python .plugin_directory ;});
4236 api
4337 .def_submodule (" editor" )
4438 .def (" get_current_gtk_source_view" ,[](){
4539 auto view=Notebook::get ().get_current_view ();
4640 if (view)
4741 return pyobject_from_gobj (view->gobj ());
48- return pybind11::module (Py_None, false );
42+ return pybind11::reinterpret_steal<pybind11:: module > (Py_None);
4943 })
5044 .def (" get_file_path" ,[](){
5145 auto view=Notebook::get ().get_current_view ();
@@ -55,13 +49,12 @@ Python::Interpreter::Interpreter(){
5549 });
5650 api
5751 .def (" get_gio_plugin_menu" ,[](){
58- auto &plugin_menu=Menu::get ().plugin_menu ;
59- if (!plugin_menu){
60- plugin_menu=Gio::Menu::create ();
61- plugin_menu->append (" <empty>" );
62- Menu::get ().window_menu ->append_submenu (" _Plugins" ,plugin_menu);
52+ if (!Menu::get ().plugin_menu ){
53+ Menu::get ().plugin_menu =Gio::Menu::create ();
54+ Menu::get ().plugin_menu ->append (" <empty>" );
55+ Menu::get ().window_menu ->append_submenu (" _Plugins" ,Menu::get ().plugin_menu );
6356 }
64- return pyobject_from_gobj (plugin_menu->gobj ());
57+ return pyobject_from_gobj (Menu::get (). plugin_menu ->gobj ());
6558 })
6659 .def (" get_gio_window_menu" ,[](){return pyobject_from_gobj (Menu::get ().window_menu ->gobj ());})
6760 .def (" get_gio_juci_menu" ,[](){return pyobject_from_gobj (Menu::get ().juci_menu ->gobj ());})
@@ -76,129 +69,87 @@ Python::Interpreter::Interpreter(){
7669 return api.ptr ();
7770 };
7871 PyImport_AppendInittab (" jucipp" , init_juci_api);
72+
7973 Config::get ().load ();
80- auto plugin_path=Config::get ().python .plugin_directory ;
81- add_path (Config::get ().python .site_packages );
82- add_path (plugin_path);
74+ configure_path ();
8375 Py_Initialize ();
76+ #ifdef _WIN32
77+ long long unsigned size = 0L ;
78+ #else
79+ long unsigned size = 0L ;
80+ #endif
8481 argv=DecodeLocale (" " ,&size);
8582 PySys_SetArgv (0 ,&argv);
86- auto sys=get_loaded_module (" sys" );
87- auto exc_func=[](pybind11::object type,pybind11::object value,pybind11::object traceback){
88- if (!given_exception_matches (type,PyExc_SyntaxError))
89- Terminal::get ().print (Error (type,value,traceback),true );
90- else
91- Terminal::get ().print (SyntaxError (type,value,traceback),true );
92- };
93- sys.attr (" excepthook" )=pybind11::cpp_function (exc_func);
9483 boost::filesystem::directory_iterator end_it;
95- for (boost::filesystem::directory_iterator it (plugin_path );it!=end_it;it++){
84+ for (boost::filesystem::directory_iterator it (Config::get (). python . plugin_directory );it!=end_it;it++){
9685 auto module_name=it->path ().stem ().string ();
9786 if (module_name.empty ())
98- break ;
87+ continue ;
9988 auto is_directory=boost::filesystem::is_directory (it->path ());
10089 auto has_py_extension=it->path ().extension ()==" .py" ;
10190 auto is_pycache=module_name==" __pycache__" ;
10291 if ((is_directory && !is_pycache)||has_py_extension){
103- auto module =import (module_name);
104- if (!module ){
105- auto msg=" Error loading plugin `" +module_name+" `:\n " ;
106- auto err=std::string (Error ());
107- Terminal::get ().print (msg+err+" \n " );
92+ try {
93+ pybind11::module::import (module_name.c_str ());
94+ } catch (pybind11::error_already_set &error) {
95+ Terminal::get ().print (" Error loading plugin `" +module_name+" `:\n " +error.what ()+" \n " );
10896 }
10997 }
11098 }
99+ auto sys=find_module (" sys" );
100+ if (sys){
101+ auto exc_func=[](pybind11::object type,pybind11::object value,pybind11::object traceback){
102+ std::cerr << " ERROR FUNCTION" ;
103+ };
104+ sys.attr (" excepthook" )=pybind11::cpp_function (exc_func);
105+ } else {
106+ std::cerr << " Failed to set exception hook\n " ;
107+ }
111108}
112109
113- pybind11::module Python::get_loaded_module (const std::string &module_name){
114- return pybind11::module (PyImport_AddModule (module_name.c_str ()), true );
115- }
116-
117- pybind11::module Python::import (const std::string &module_name){
118- return pybind11::module (PyImport_ImportModule (module_name.c_str ()), false );
119- }
120-
121- pybind11::module Python::reload (pybind11::module &module ){
122- return pybind11::module (PyImport_ReloadModule (module .ptr ()),false );
110+ pybind11::module Python::Interpreter::find_module (const std::string &module_name){
111+ return pybind11::reinterpret_borrow<pybind11::module >(PyImport_AddModule (module_name.c_str ()));
123112}
124113
125- Python::SyntaxError::SyntaxError (pybind11::object type,pybind11::object value,pybind11::object traceback)
126- : Error(type,value,traceback){}
127-
128- Python::Error::Error (pybind11::object type,pybind11::object value,pybind11::object traceback){
129- exp=type;
130- val=value;
131- trace=traceback;
114+ pybind11::module Python::Interpreter::reload (pybind11::module &module ){
115+ auto reload=pybind11::reinterpret_steal<pybind11::module >(PyImport_ReloadModule (module .ptr ()));
116+ if (!reload)
117+ throw pybind11::error_already_set ();
118+ return reload;
132119}
133120
134- void Python::Interpreter::add_path (const boost::filesystem::path &path){
135- if (path.empty ())
136- return ;
137- std::wstring sys_path (Py_GetPath ());
138- if (!sys_path.empty ())
139- #ifdef _WIN32
140- sys_path += ' ;' ;
141- #else
142- sys_path += ' :' ;
143- #endif
144- sys_path += path.generic_wstring ();
121+ void Python::Interpreter::configure_path (){
122+ const std::vector<boost::filesystem::path> python_path = {
123+ " /usr/lib/python3.6" ,
124+ " /usr/lib/python3.6/lib-dynload" ,
125+ " /usr/lib/python3.6/site-packages" ,
126+ Config::get ().python .site_packages ,
127+ Config::get ().python .plugin_directory
128+ };
129+ std::wstring sys_path;
130+ for (auto &path:python_path){
131+ if (path.empty ())
132+ continue ;
133+ if (!sys_path.empty ()){
134+ #ifdef _WIN32
135+ sys_path += ' ;' ;
136+ #else
137+ sys_path += ' :' ;
138+ #endif
139+ }
140+ sys_path += path.generic_wstring ();
141+ }
145142 Py_SetPath (sys_path.c_str ());
146143}
147144
148145Python::Interpreter::~Interpreter (){
149- auto err=Error ();
150146 if (Py_IsInitialized ())
151147 Py_Finalize ();
152- if (err )
153- std::cerr << std::string (err ) << std::endl;
148+ if (error () )
149+ std::cerr << pybind11::error_already_set (). what ( ) << std::endl;
154150}
155151
156- pybind11::object Python::error_occured (){
157- return pybind11::object (PyErr_Occurred (), true );
152+ pybind11::object Python::Interpreter::error (){
153+ return pybind11::reinterpret_borrow<pybind11:: object> (PyErr_Occurred ());
158154}
159155
160- bool Python::thrown_exception_matches (pybind11::handle exception_type){
161- return PyErr_ExceptionMatches (exception_type.ptr ());
162- }
163-
164- bool Python::given_exception_matches (const pybind11::object &exception, pybind11::handle exception_type){
165- return PyErr_GivenExceptionMatches (exception.ptr (),exception_type.ptr ());
166- }
167-
168- Python::Error::Error (){
169- if (error_occured ()){
170- try {
171- PyErr_Fetch (&exp.ptr (),&val.ptr (),&trace.ptr ());
172- PyErr_NormalizeException (&exp.ptr (),&val.ptr (),&trace.ptr ());
173- }catch (const std::exception &e) {
174- Terminal::get ().print (e.what (),true );
175- }
176- }
177- }
178-
179- Python::Error::operator std::string (){
180- return std::string (exp.str ())+" \n " +std::string (val.str ())+" \n " ;
181- }
182-
183- Python::SyntaxError::SyntaxError ():Error(){
184- if (val){
185- _Py_IDENTIFIER (msg);
186- _Py_IDENTIFIER (lineno);
187- _Py_IDENTIFIER (offset);
188- _Py_IDENTIFIER (text);
189- exp=std::string (pybind11::str (_PyObject_GetAttrId (val.ptr (),&PyId_msg),false ));
190- text=std::string (pybind11::str (_PyObject_GetAttrId (val.ptr (),&PyId_text),false ));
191- pybind11::object py_line_number (_PyObject_GetAttrId (val.ptr (),&PyId_lineno),false );
192- pybind11::object py_line_offset (_PyObject_GetAttrId (val.ptr (),&PyId_offset),false );
193- line_number=pybind11::cast<int >(py_line_number);
194- line_offset=pybind11::cast<int >(py_line_offset);
195- }
196- }
197-
198- Python::SyntaxError::operator std::string (){
199- return exp+" (" +std::to_string (line_number)+" :" +std::to_string (line_offset)+" ):\n " +text;
200- }
201-
202- Python::Error::operator bool (){
203- return exp || trace || val;
204- }
0 commit comments