Index: src/backends/python2/python2backend.cpp =================================================================== --- src/backends/python2/python2backend.cpp +++ src/backends/python2/python2backend.cpp @@ -34,7 +34,7 @@ // to make sure that python modules such as numpy see them // (see bug #330032) QLibrary pythonLib(QLatin1String("python2.7")); - pythonLib.setLoadHints(QLibrary::ExportExternalSymbolsHint); + pythonLib.setLoadHints(QLibrary::ResolveAllSymbolsHint); pythonLib.load(); } Index: src/backends/python3/CMakeLists.txt =================================================================== --- src/backends/python3/CMakeLists.txt +++ src/backends/python3/CMakeLists.txt @@ -5,17 +5,18 @@ kconfig_add_kcfg_files(Python3Backend_SRCS settings.kcfgc) +include_directories(${PYTHONLIBS3_INCLUDE_DIRS}) + add_backend(python3backend ${Python3Backend_SRCS}) target_link_libraries(cantor_python3backend + ${PYTHONLIBS3_LIBRARIES} cantor_pythonbackend - Qt5::DBus) + ) install(FILES cantor_python3.knsrc DESTINATION ${KDE_INSTALL_CONFDIR}) install(FILES python3backend.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR}) -add_subdirectory(python3server) - if(BUILD_TESTING) add_subdirectory(tests) endif() Index: src/backends/python3/python3backend.h =================================================================== --- src/backends/python3/python3backend.h +++ src/backends/python3/python3backend.h @@ -25,6 +25,7 @@ class Python3Backend : public PythonBackend { + Q_OBJECT public: explicit Python3Backend(QObject* parent = nullptr, const QList args = QList()); Index: src/backends/python3/python3backend.cpp =================================================================== --- src/backends/python3/python3backend.cpp +++ src/backends/python3/python3backend.cpp @@ -29,6 +29,9 @@ : PythonBackend(parent, args) { setObjectName(QLatin1String("python3backend")); + QLibrary pythonLib(QLatin1String("python3.6m")); + pythonLib.setLoadHints(QLibrary::ResolveAllSymbolsHint); + pythonLib.load(); } Cantor::Session* Python3Backend::createSession() Index: src/backends/python3/python3server/CMakeLists.txt =================================================================== --- src/backends/python3/python3server/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -include_directories(${PYTHONLIBS3_INCLUDE_DIRS}) - -set(Python3Server_SRCS - python3server.cpp - main.cpp -) - -add_executable(cantor_python3server ${Python3Server_SRCS}) - -set_target_properties(cantor_python3server PROPERTIES INSTALL_RPATH_USE_LINK_PATH false) -target_link_libraries(cantor_python3server - ${PYTHONLIBS3_LIBRARIES} - Qt5::Widgets - Qt5::DBus) - -install(TARGETS cantor_python3server ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) Index: src/backends/python3/python3server/main.cpp =================================================================== --- src/backends/python3/python3server/main.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - --- - Copyright (C) 2015 Minh Ngo - */ - -#include -#include -#include -#include -#include - -#include "python3server.h" - -int main(int argc, char *argv[]) -{ - QCoreApplication app(argc, argv); - - if (!QDBusConnection::sessionBus().isConnected()) - { - qDebug() << "Can't connect to the D-Bus session bus.\n" - "To start it, run: eval `dbus-launch --auto-syntax`"; - return 1; - } - - const QString& serviceName = QString::fromLatin1("org.kde.Cantor.Python3-%1").arg(app.applicationPid()); - - if (!QDBusConnection::sessionBus().registerService(serviceName)) - { - qDebug() << QDBusConnection::sessionBus().lastError().message(); - return 2; - } - - Python3Server server; - QDBusConnection::sessionBus().registerObject(QString::fromLatin1("/"), &server, QDBusConnection::ExportAllSlots); - - QTextStream(stdout) << "ready" << endl; - - return app.exec(); -} Index: src/backends/python3/python3server/python3server.h =================================================================== --- src/backends/python3/python3server/python3server.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - --- - Copyright (C) 2015 Minh Ngo - */ - -#ifndef _PYTHON3SERVER_H -#define _PYTHON3SERVER_H -#include -#include - -struct _object; -typedef _object PyObject; - -class Python3Server : public QObject -{ - Q_OBJECT - public: - Python3Server(QObject* parent = nullptr); - - public Q_SLOTS: - Q_SCRIPTABLE void login(); - Q_SCRIPTABLE void runPythonCommand(const QString& command) const; - Q_SCRIPTABLE QString getOutput() const; - Q_SCRIPTABLE QString getError() const; - - private: - PyObject* m_pModule; -}; - -#endif Index: src/backends/python3/python3server/python3server.cpp =================================================================== --- src/backends/python3/python3server/python3server.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - --- - Copyright (C) 2015 Minh Ngo - */ - -#include "python3server.h" - -#include - -Python3Server::Python3Server(QObject* parent) - : QObject(parent) -{ -} - -namespace -{ - QString pyObjectToQString(PyObject* obj) - { - return QString::fromUtf8(PyUnicode_AsUTF8(obj)); - } -} - -void Python3Server::login() -{ - Py_Initialize(); - m_pModule = PyImport_AddModule("__main__"); -} - -void Python3Server::runPythonCommand(const QString& command) const -{ - PyRun_SimpleString(command.toStdString().c_str()); -} - -QString Python3Server::getError() const -{ - PyObject *errorPython = PyObject_GetAttrString(m_pModule, "errorPythonBackend"); - PyObject *error = PyObject_GetAttrString(errorPython, "value"); - - return pyObjectToQString(error); -} - -QString Python3Server::getOutput() const -{ - PyObject *outputPython = PyObject_GetAttrString(m_pModule, "outputPythonBackend"); - PyObject *output = PyObject_GetAttrString(outputPython, "value"); - - return pyObjectToQString(output); -} - - - -#include "python3server.moc" Index: src/backends/python3/python3session.h =================================================================== --- src/backends/python3/python3session.h +++ src/backends/python3/python3session.h @@ -23,34 +23,28 @@ #include "../python/pythonsession.h" -class QDBusInterface; -class KProcess; +struct _object; +typedef _object PyObject; + class Python3Session : public PythonSession { - Q_OBJECT public: Python3Session(Cantor::Backend* backend); - void login(); - void logout(); - void interrupt(); + void login() Q_DECL_OVERRIDE; - bool integratePlots() const; - QStringList autorunScripts() const; + bool integratePlots() const Q_DECL_OVERRIDE; + QStringList autorunScripts() const Q_DECL_OVERRIDE; private: - void runPythonCommand(const QString& command) const; - void readExpressionOutput(const QString& commandProcessing); + void runPythonCommand(const QString& command) const Q_DECL_OVERRIDE; + QString getOutput() const Q_DECL_OVERRIDE; + QString getError() const Q_DECL_OVERRIDE; - QString getOutput() const; - QString getError() const; + QString pyObjectToQString(PyObject* obj) const; private: - QDBusInterface* m_pIface; - KProcess* m_pProcess; - - Q_SIGNALS: - void updateHighlighter(); + PyObject *m_pModule; }; #endif Index: src/backends/python3/python3session.cpp =================================================================== --- src/backends/python3/python3session.cpp +++ src/backends/python3/python3session.cpp @@ -20,113 +20,49 @@ #include "python3session.h" #include "settings.h" -#include "../python/pythonexpression.h" -#include -#include -#include -#include - -#include +#include Python3Session::Python3Session(Cantor::Backend* backend) : PythonSession(backend) - , m_pIface(nullptr) - , m_pProcess(nullptr) -{ -} - -void Python3Session::login() -{ - if (m_pProcess) - m_pProcess->deleteLater(); - - m_pProcess = new KProcess(this); - m_pProcess->setOutputChannelMode(KProcess::SeparateChannels); - - (*m_pProcess) << QStandardPaths::findExecutable(QLatin1String("cantor_python3server")); - - m_pProcess->start(); - - m_pProcess->waitForStarted(); - m_pProcess->waitForReadyRead(); - QTextStream stream(m_pProcess->readAllStandardOutput()); - - const QString& readyStatus = QString::fromLatin1("ready"); - while (m_pProcess->state() == QProcess::Running) - { - const QString& rl = stream.readLine(); - if (rl == readyStatus) - break; - } - - if (!QDBusConnection::sessionBus().isConnected()) - { - qWarning() << "Can't connect to the D-Bus session bus.\n" - "To start it, run: eval `dbus-launch --auto-syntax`"; - return; - } - - const QString& serviceName = QString::fromLatin1("org.kde.Cantor.Python3-%1").arg(m_pProcess->pid()); - - m_pIface = new QDBusInterface(serviceName, - QString::fromLatin1("/"), QString(), QDBusConnection::sessionBus()); - if (!m_pIface->isValid()) - { - qWarning() << QDBusConnection::sessionBus().lastError().message(); - return; - } - - m_pIface->call(QString::fromLatin1("login")); - - PythonSession::login(); -} - -void Python3Session::logout() -{ - m_pProcess->terminate(); - PythonSession::logout(); -} - -void Python3Session::interrupt() + , m_pModule(nullptr) { - if (m_pProcess->pid()) - m_pProcess->kill(); - - PythonSession::interrupt(); } void Python3Session::runPythonCommand(const QString& command) const { - m_pIface->call(QString::fromLatin1("runPythonCommand"), command); + PyRun_SimpleString(command.toStdString().c_str()); } -void Python3Session::readExpressionOutput(const QString& commandProcessing) +void Python3Session::login() { - runClassOutputPython(); - runPythonCommand(commandProcessing); - m_output = getOutput(); - m_error = getError(); + Py_Initialize(); + m_pModule = PyImport_AddModule("__main__"); - updateOutput(); + PythonSession::login(); } QString Python3Session::getOutput() const { - const QDBusReply& reply = m_pIface->call(QString::fromLatin1("getOutput")); - if (reply.isValid()) - return reply.value(); + PyObject *outputPython = PyObject_GetAttrString(m_pModule, "outputPythonBackend"); + PyObject *output = PyObject_GetAttrString(outputPython, "value"); + PyObject *encoded = PyUnicode_AsEncodedString(output, "UTF-8", "strict"); - return reply.error().message(); + return pyObjectToQString(encoded); } QString Python3Session::getError() const { - const QDBusReply& reply = m_pIface->call(QString::fromLatin1("getError")); - if (reply.isValid()) - return reply.value(); + PyObject *errorPython = PyObject_GetAttrString(m_pModule, "errorPythonBackend"); + PyObject *error = PyObject_GetAttrString(errorPython, "value"); + PyObject *encoded = PyUnicode_AsEncodedString(error, "UTF-8", "strict"); - return reply.error().message(); + return pyObjectToQString(encoded); +} + +QString Python3Session::pyObjectToQString(PyObject* obj) const +{ + return QLatin1String(PyBytes_AsString(obj)); } bool Python3Session::integratePlots() const