Skip to content

Commit

Permalink
Fix handling of code blocks which are legal in python scripts but wou…
Browse files Browse the repository at this point in the history
…ld require a newline in REPL mode (e.g. a for loop followed by another statement without a separating empty line).
  • Loading branch information
Kasper Peeters committed Dec 22, 2024
1 parent 9e7cf52 commit a6bf3d3
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 16 deletions.
2 changes: 1 addition & 1 deletion client_server/ComputeThread.cc
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ void ComputeThread::on_message(const std::string& msg)
}
else {
std::cerr << "cadabra-client: received cell we did not expect: "
<< msg_type << std::endl;
<< msg_type << ": " << content << std::endl;
}
}
}
Expand Down
1 change: 1 addition & 0 deletions core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ endif()
add_executable(cadabra2-cli
cadabra2-cli.cc
CdbPython.cc
Exceptions.cc
InstallPrefix.cc
pythoncdb/py_helpers.cc
${CADABRA_LIBS_DIR}/whereami/whereami.c
Expand Down
35 changes: 29 additions & 6 deletions core/CdbPython.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "CdbPython.hh"
#include <pybind11/pybind11.h>
#include <pybind11/embed.h>
#include "Exceptions.hh"

#ifndef CDBPYTHON_NO_NOTEBOOK
#include "DataCell.hh"
Expand Down Expand Up @@ -81,24 +82,40 @@ std::string cadabra::cdb2python_string(const std::string& blk, bool display)

while(true) {
// std::cerr << "CHECK:---\n" << tmpblk << "\n---" << std::endl;
int ic = is_python_code_complete(tmpblk);
if(ic==1) {
std::string error;
int ic = is_python_code_complete(tmpblk, error);
if(ic==1) { // complete
newblks.push_back(res.first + tmpblk + "\n");
tmpblk = "";
break;
}
if(ic==0) {
if(ic==0) { // incomplete
tmpblk += "\n";
break;
}
if(ic==-1) {
if(ic==-1) { // indentation error
if(newblks.size()==0)
break;
// Grow block by adding previously ok block,
// then try compiling again.
tmpblk = newblks.back() + tmpblk;
newblks.pop_back();
}
if(ic==-2) {
// This is either a genuine syntax error, or one line
// added too many (after a previous 'incomplete' result).
// Remove the line from the block, then re-run that line
// separately.
if(tmpblk != "") {
if(size_t pos = tmpblk.rfind('\n'); pos != std::string::npos) {
newblks.push_back(tmpblk.substr(0, pos)+"\n");
tmpblk = tmpblk.substr(pos+1);
// re-run
}
else throw ParseException(error);
}
else throw ParseException(error);
}
}
}

Expand All @@ -116,8 +133,9 @@ std::string cadabra::cdb2python_string(const std::string& blk, bool display)
// 1: complete
// 0: incomplete
// -1: indentation error, need backtracking
// -2: syntax error

int cadabra::is_python_code_complete(const std::string& code)
int cadabra::is_python_code_complete(const std::string& code, std::string& error)
{
// The following code prints None, <code object> and <code object>.
// Make sure that the string you feed here does *not* include the
Expand Down Expand Up @@ -150,13 +168,18 @@ int cadabra::is_python_code_complete(const std::string& code)
else return 1;
}
catch (pybind11::error_already_set& e) {
// std::cerr << "EXCEPTION: " << e.what() << std::endl;
// std::cerr << "EXCEPTION: " << e.what() << std::endl;
error=e.what();
if (std::string(e.what()).find("unexpected EOF") != std::string::npos) {
return -1;
}
if (std::string(e.what()).find("Indentation") != std::string::npos) {
return -1;
}
if (std::string(e.what()).find("SyntaxError") != std::string::npos) {
return -2;
}

throw;
}
}
Expand Down
3 changes: 2 additions & 1 deletion core/CdbPython.hh
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ namespace cadabra {
/// 1: complete
/// 0: incomplete
/// -1: indentation error, need backtracking
/// -2: overcomplete

int is_python_code_complete(const std::string&);
int is_python_code_complete(const std::string&, std::string& error);

/// \ingroup files
/// Object to store pre-parsing intermediate results. Necessary
Expand Down
3 changes: 3 additions & 0 deletions core/cadabra2_defaults.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,9 @@ def display(obj, cell_id=0, delay_send=False):
'display' function call so that the expression is displayed immediately.
"""

if cell_id==None:
cell_id = 0

if type(obj)==list and len(obj)>0 and (isinstance(obj[0], matplotlib.figure.Figure) or isinstance(obj[0], matplotlib.figure.Artist)):
# matplotlib has the annoying habit of returning plots as lists of figures.
# print("list of figures", file=sys.stderr)
Expand Down
Loading

0 comments on commit a6bf3d3

Please sign in to comment.