Commit 31e83563 authored by Nikita Sirgienko's avatar Nikita Sirgienko
Browse files

[Python2] Fix bug with server, which don't work with multiexpression code (for...

[Python2] Fix bug with server, which don't work with multiexpression code (for example "a=3\nb=4"). Also add regression tests for this problem.
parent e74a5ff2
......@@ -65,6 +65,7 @@ void PythonServer::runPythonCommand(const QString& command) const
"sys.stderr = errorPythonBackend\n";
PyRun_SimpleString(prepareCommand);
#if PY_MAJOR_VERSION == 3
PyObject* compile = Py_CompileString(command.toStdString().c_str(), filePath.toStdString().c_str(), Py_single_input);
// There are two reasons for the error:
// 1) This code is not single expression, so we can't compile this with flag Py_single_input
......@@ -81,10 +82,39 @@ void PythonServer::runPythonCommand(const QString& command) const
return;
}
}
#if PY_MAJOR_VERSION == 3
PyEval_EvalCode(compile, py_dict, py_dict);
#elif PY_MAJOR_VERSION == 2
PyEval_EvalCode((PyCodeObject*)compile, py_dict, py_dict);
// Python 2.X don't check, that input string contains only one expression.
// So for checking this, we compile string as file and as single expression and compare bytecode
// FIXME?
PyObject* codeFile = Py_CompileString(command.toStdString().c_str(), filePath.toStdString().c_str(), Py_file_input);
if (PyErr_Occurred())
{
PyErr_PrintEx(0);
return;
}
PyObject* codeSingle = Py_CompileString(command.toStdString().c_str(), filePath.toStdString().c_str(), Py_single_input);
if (PyErr_Occurred())
{
// We have error with Py_single_input, but haven't error with Py_file_input
// So, the code can't be compiled as singel input -> use file input right away
PyErr_Clear();
PyEval_EvalCode((PyCodeObject*)codeFile, py_dict, py_dict);
}
else
{
PyObject* bytecode1 = ((PyCodeObject*)codeSingle)->co_code;
PyObject* bytecode2 = ((PyCodeObject*)codeFile)->co_code;
if (PyObject_Length(bytecode1) >= PyObject_Length(bytecode2))
{
PyEval_EvalCode((PyCodeObject*)codeSingle, py_dict, py_dict);
}
else
{
PyEval_EvalCode((PyCodeObject*)codeFile, py_dict, py_dict);
}
}
#else
#warning Unknown Python version
#endif
......
......@@ -55,5 +55,33 @@ void TestPython2::testCodeWithComments()
}
}
void TestPython2::testSimpleCode()
{
Cantor::Expression* e=evalExp( QLatin1String("2+2"));
QVERIFY( e!=nullptr );
QVERIFY( e->result()!=nullptr );
QString result=e->result()->toHtml();
QCOMPARE( cleanOutput(result ), QLatin1String("4") );
}
void TestPython2::testMultilineCode()
{
Cantor::Expression* e=evalExp(QLatin1String(
"a = 2+2\n"
"b = 3+3\n"
"print a,b"
));
QVERIFY( e!=nullptr );
QVERIFY( e->result()!=nullptr );
QString result=e->result()->toHtml();
QCOMPARE( cleanOutput(result ), QLatin1String("4 6") );
}
QTEST_MAIN(TestPython2)
......@@ -30,6 +30,8 @@ class TestPython2 : public BackendTest
private Q_SLOTS:
void testImportNumpy();
void testCodeWithComments();
void testSimpleCode();
void testMultilineCode();
private:
QString backendName() override;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment