diff --git a/common/pybindings.cc b/common/pybindings.cc index 13e0976c..02c39fa3 100644 --- a/common/pybindings.cc +++ b/common/pybindings.cc @@ -127,11 +127,9 @@ BOOST_PYTHON_MODULE(MODULE_NAME) class_, boost::noncopyable>("Context", no_init).def("checksum", &Context::checksum); } -void arch_appendinittab() { PyImport_AppendInittab(TOSTRING(MODULE_NAME), PYINIT_MODULE_NAME); } - static wchar_t *program; -void init_python(const char *executable) +void init_python(const char *executable,bool first) { #ifdef MAIN_EXECUTABLE program = Py_DecodeLocale(executable, NULL); @@ -140,11 +138,15 @@ void init_python(const char *executable) exit(1); } try { - PyImport_AppendInittab(TOSTRING(MODULE_NAME), PYINIT_MODULE_NAME); - emb::append_inittab(); + if (first) + { + PyImport_AppendInittab(TOSTRING(MODULE_NAME), PYINIT_MODULE_NAME); + emb::append_inittab(); + } Py_SetProgramName(program); Py_Initialize(); - PyImport_ImportModule(TOSTRING(MODULE_NAME)); + if (first) + PyImport_ImportModule(TOSTRING(MODULE_NAME)); } catch (boost::python::error_already_set const &) { // Parse and output the exception std::string perror_str = parse_python_exception(); diff --git a/common/pybindings.h b/common/pybindings.h index 1f5ca004..4180c2e9 100644 --- a/common/pybindings.h +++ b/common/pybindings.h @@ -100,14 +100,12 @@ template void python_export_global(const char *name, Tn &x) } }; -void init_python(const char *executable); +void init_python(const char *executable, bool first); void deinit_python(); void execute_python_file(const char *python_file); -void arch_appendinittab(); - NEXTPNR_NAMESPACE_END #endif /* end of include guard: COMMON_PYBINDINGS_HH */ diff --git a/dummy/main.cc b/dummy/main.cc index de578ca3..d025d8d4 100644 --- a/dummy/main.cc +++ b/dummy/main.cc @@ -92,11 +92,6 @@ int main(int argc, char *argv[]) Context ctx(ArchArgs{}); -#ifndef NO_PYTHON - init_python(argv[0]); - python_export_global("ctx", ctx); -#endif - if (vm.count("verbose")) { ctx.verbose = true; } @@ -111,9 +106,14 @@ int main(int argc, char *argv[]) #ifndef NO_PYTHON if (vm.count("run")) { + init_python(argv[0], true); + python_export_global("ctx", ctx); + std::vector files = vm["run"].as>(); for (auto filename : files) execute_python_file(filename.c_str()); + + deinit_python(); } #endif @@ -125,9 +125,6 @@ int main(int argc, char *argv[]) rc = a.exec(); } -#endif -#ifndef NO_PYTHON - deinit_python(); #endif return rc; } catch (log_execution_error_exception) { diff --git a/gui/basewindow.cc b/gui/basewindow.cc index 69f4f622..2e8d7c85 100644 --- a/gui/basewindow.cc +++ b/gui/basewindow.cc @@ -74,7 +74,9 @@ BaseMainWindow::BaseMainWindow(QWidget *parent) : QMainWindow(parent), ctx(nullp tabWidget = new QTabWidget(); #ifndef NO_PYTHON - tabWidget->addTab(new PythonTab(), "Python"); + PythonTab *pythontab = new PythonTab(); + tabWidget->addTab(pythontab, "Python"); + connect(this, SIGNAL(contextChanged(Context*)), pythontab, SLOT(newContext(Context*))); #endif info = new InfoTab(); tabWidget->addTab(info, "Info"); diff --git a/gui/pythontab.cc b/gui/pythontab.cc index 397920d9..816039ba 100644 --- a/gui/pythontab.cc +++ b/gui/pythontab.cc @@ -25,10 +25,8 @@ NEXTPNR_NAMESPACE_BEGIN -PythonTab::PythonTab(QWidget *parent) : QWidget(parent) +PythonTab::PythonTab(QWidget *parent) : QWidget(parent),initialized(false) { - PyImport_ImportModule("emb"); - // Add text area for Python output and input line plainTextEdit = new QPlainTextEdit(); plainTextEdit->setReadOnly(true); @@ -57,7 +55,25 @@ PythonTab::PythonTab(QWidget *parent) : QWidget(parent) setLayout(mainLayout); connect(lineEdit, SIGNAL(textLineInserted(QString)), this, SLOT(editLineReturnPressed(QString))); +} +PythonTab::~PythonTab() +{ + if (initialized) + deinit_python(); +} + +void PythonTab::newContext(Context *ctx) +{ + if (initialized) + deinit_python(); + + plainTextEdit->clear(); + + init_python("nextpnr", !initialized); + python_export_global("ctx", ctx); + + PyImport_ImportModule("emb"); write = [this](std::string s) { plainTextEdit->moveCursor(QTextCursor::End); plainTextEdit->insertPlainText(s.c_str()); @@ -65,6 +81,8 @@ PythonTab::PythonTab(QWidget *parent) : QWidget(parent) }; emb::set_stdout(write); + initialized = true; + char buff[1024]; sprintf(buff, "Python %s on %s\n", Py_GetVersion(), Py_GetPlatform()); print(buff); @@ -121,9 +139,12 @@ int PythonTab::executePython(std::string &command) void PythonTab::editLineReturnPressed(QString text) { - std::string input = text.toStdString(); - print(std::string(">>> " + input + "\n")); - executePython(input); + if (initialized) + { + std::string input = text.toStdString(); + print(std::string(">>> " + input + "\n")); + executePython(input); + } } void PythonTab::showContextMenu(const QPoint &pt) { contextMenu->exec(mapToGlobal(pt)); } diff --git a/gui/pythontab.h b/gui/pythontab.h index 40de0ebe..871d2450 100644 --- a/gui/pythontab.h +++ b/gui/pythontab.h @@ -37,6 +37,7 @@ class PythonTab : public QWidget public: explicit PythonTab(QWidget *parent = 0); + ~PythonTab(); private: void print(std::string line); @@ -45,12 +46,14 @@ class PythonTab : public QWidget void editLineReturnPressed(QString text); void showContextMenu(const QPoint &pt); void clearBuffer(); - + public Q_SLOTS: + void newContext(Context *ctx); private: QPlainTextEdit *plainTextEdit; LineEditor *lineEdit; QMenu *contextMenu; emb::stdout_write_type write; + bool initialized; }; NEXTPNR_NAMESPACE_END diff --git a/ice40/main.cc b/ice40/main.cc index ecaba87f..f1736fab 100644 --- a/ice40/main.cc +++ b/ice40/main.cc @@ -269,11 +269,6 @@ int main(int argc, char *argv[]) Context ctx(chipArgs); -#ifndef NO_PYTHON - init_python(argv[0]); - python_export_global("ctx", ctx); -#endif - if (vm.count("verbose")) { ctx.verbose = true; } @@ -390,9 +385,14 @@ int main(int argc, char *argv[]) #ifndef NO_PYTHON if (vm.count("run")) { + init_python(argv[0], true); + python_export_global("ctx", ctx); + std::vector files = vm["run"].as>(); for (auto filename : files) execute_python_file(filename.c_str()); + + deinit_python(); } #endif @@ -405,10 +405,6 @@ int main(int argc, char *argv[]) rc = a.exec(); } #endif - -#ifndef NO_PYTHON - deinit_python(); -#endif return rc; } catch (log_execution_error_exception) { #if defined(_MSC_VER)