Changeset: a81f559785ba for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=a81f559785ba
Modified Files:
        monetdb5/extras/pyapi/Benchmarks/pyapi_test.sh
        monetdb5/extras/pyapi/formatinput.c
        monetdb5/extras/pyapi/formatinput.h
        monetdb5/extras/pyapi/pyapi.c
Branch: pyapi
Log Message:

Added better error reporting for problems while formatting Python code.


diffs (190 lines):

diff --git a/monetdb5/extras/pyapi/Benchmarks/pyapi_test.sh 
b/monetdb5/extras/pyapi/Benchmarks/pyapi_test.sh
--- a/monetdb5/extras/pyapi/Benchmarks/pyapi_test.sh
+++ b/monetdb5/extras/pyapi/Benchmarks/pyapi_test.sh
@@ -1,7 +1,7 @@
 
 
 # The base directory of testing, a new folder is created in this base 
directory [$PYAPI_TEST_DIR], and everything is done in that new folder
-export PYAPI_BASE_DIR=$HOME
+export PYAPI_BASE_DIR=/export/scratch1/raasveld
 # The terminal to start mserver with, examples are 'gnome-terminal', 'xterm', 
'konsole'
 export TERMINAL=x-terminal-emulator
 # A command that tests if the mserver is still running (used to find out when 
the shutting down of mserver is completed)
diff --git a/monetdb5/extras/pyapi/formatinput.c 
b/monetdb5/extras/pyapi/formatinput.c
--- a/monetdb5/extras/pyapi/formatinput.c
+++ b/monetdb5/extras/pyapi/formatinput.c
@@ -8,10 +8,11 @@
 #include "mal_linker.h"
 #include "gdk_utils.h"
 #include "gdk.h"
+#include "mal_exception.h"
 
 
 //! Parse a PyCodeObject from a string, the string is expected to be in the 
format {@<encoded_function>};, where <encoded_function> is all the PyCodeObject 
properties in order
-PyObject *PyCodeObject_ParseString(char *string);
+PyObject *PyCodeObject_ParseString(char *string, char **msg);
 
 char* GetArg(char *string, char *storage, int index);
 char* GetArg(char *string, char *storage, int index)
@@ -62,8 +63,8 @@ size_t ModifyCode(char *string, char *st
     return j;
 }
 
-PyObject *GetConstantObject(char *string, char *storage);
-PyObject *GetConstantObject(char *string, char *storage)
+PyObject *GetConstantObject(char *string, char *storage, char **msg);
+PyObject *GetConstantObject(char *string, char *storage, char **msg)
 {
     int numbers = 0, i = 0, j = 0, k = 0;
     int length = strlen(string);
@@ -81,6 +82,7 @@ PyObject *GetConstantObject(char *string
     }
     if (brackets != 0) {
         //invalid number of brackets
+        *msg = createException(MAL, "pyapi.eval", "Invalid number of brackets 
in encoded Python code object string.");
         return NULL;
     }
 
@@ -110,9 +112,9 @@ PyObject *GetConstantObject(char *string
                     object = PyUnicode_FromString(storage);
                 } else if (strcmp(type_str, "code") == 0) {
                     //recursive call, we've got a function within this 
function, so we have to parse another code object
-                    object = PyCodeObject_ParseString(storage);
+                    object = PyCodeObject_ParseString(storage, msg);
                 } else {
-                    printf("ERROR: Unrecognized type %s!", type_str);
+                    *msg = createException(MAL, "pyapi.eval", "Unrecognized 
constant type %s in encoded Python code object string.", type_str);
                     return NULL;
                 }
                 PyTuple_SetItem(result, j, object);
@@ -170,13 +172,17 @@ PyObject* GetStringTuple(char *string, c
     return result;
 }
 
-PyObject *PyCodeObject_ParseString(char *string)
+PyObject *PyCodeObject_ParseString(char *string, char **msg)
 {
     int argcount, nlocals, stacksize, flags, firstlineno;
     PyObject *code, *name, *filename, *lnotab;
     PyObject *consts, *names, *varnames, *freevars, *cellvars;
     char *temp_string = GDKmalloc(strlen(string));
     char *temp_string2 = GDKmalloc(strlen(string));
+    if (temp_string == NULL || temp_string2 == NULL) {
+        *msg = createException(MAL, "pyapi.eval", MAL_MALLOC_FAIL);
+        return NULL;
+    }
     size_t size;
 
     //argcount is a single int
@@ -191,7 +197,7 @@ PyObject *PyCodeObject_ParseString(char 
     size = ModifyCode(GetArg(string, temp_string, 4), temp_string2);
     code = PyString_FromStringAndSize(temp_string2, size);
     //now parse the constants, constants are a list of python objects in the 
form of (type:value) (ex: (int:20)(int:33)(str:hello))
-    consts = GetConstantObject(GetArg(string, temp_string, 5), temp_string2);
+    consts = GetConstantObject(GetArg(string, temp_string, 5), temp_string2, 
msg);
     //now parse the names, this is a list of strings delimited by commas (ex: 
name,name2,)
     names = GetStringTuple(GetArg(string, temp_string, 6), temp_string2);
     //now parse the varnames, same as above
@@ -214,7 +220,7 @@ PyObject *PyCodeObject_ParseString(char 
     return (PyObject*)PyCode_New(argcount, nlocals, stacksize, flags, code, 
consts, names, varnames, freevars, cellvars, filename, name, firstlineno, 
lnotab);
 }
 
-char* FormatCode(char* code, char **args, size_t argcount, size_t tabwidth, 
PyObject **code_object)
+char* FormatCode(char* code, char **args, size_t argcount, size_t tabwidth, 
PyObject **code_object, char **msg)
 {
     // Format the python code by fixing the indentation levels
     // We do two passes, first we get the length of the resulting formatted 
code and then we actually create the resulting code
@@ -247,15 +253,16 @@ char* FormatCode(char* code, char **args
 
     char base_start[] = "def pyfun(";
     char base_end[] = "):\n";
-
+    *msg = NULL;
     if (code[1] == '@') {
-        *code_object = PyCodeObject_ParseString(code);
+        *code_object = PyCodeObject_ParseString(code, msg);
         return NULL;
     }
 
     indentation_levels = (size_t*)GDKzalloc(max_indentation * sizeof(size_t));
     statements_per_level = (size_t*)GDKzalloc(max_indentation * 
sizeof(size_t));
     if (indentation_levels == NULL || statements_per_level == NULL) {
+        *msg = createException(MAL, "pyapi.eval", MAL_MALLOC_FAIL);
         goto finally;
     }
 
@@ -343,9 +350,15 @@ char* FormatCode(char* code, char **args
                     // This probably will never happen unless in really 
extreme code (or if max_indentation is set very low)
                     size_t *new_indentation = GDKzalloc(2 * max_indentation * 
sizeof(size_t));
                     size_t *new_statements_per_level;
-                    if (new_indentation == NULL) goto finally;
+                    if (new_indentation == NULL) { 
+                        *msg = createException(MAL, "pyapi.eval", 
MAL_MALLOC_FAIL);
+                        goto finally;
+                    }
                     new_statements_per_level = GDKzalloc(2 * max_indentation * 
sizeof(size_t));
-                    if (new_statements_per_level == NULL) goto finally;
+                    if (new_statements_per_level == NULL) {
+                        *msg = createException(MAL, "pyapi.eval", 
MAL_MALLOC_FAIL);
+                        goto finally;
+                    }
 
                     for(i = 0; i < max_indentation; i++) {
                         new_indentation[i] = indentation_levels[i];
@@ -402,7 +415,10 @@ char* FormatCode(char* code, char **args
 
     // Allocate space for the function
     newcode = GDKzalloc(size);
-    if (newcode == NULL) goto finally;
+    if (newcode == NULL) { 
+        *msg = createException(MAL, "pyapi.eval", MAL_MALLOC_FAIL);
+        goto finally;
+    }
     initial_spaces = 0;
     seen_statement = false;
 
@@ -467,7 +483,7 @@ char* FormatCode(char* code, char **args
                     // This should never happen, because it means the initial 
spaces was not present in the array
                     // When we just did exactly the same loop over the array, 
we should have encountered this statement
                     // This means that something happened to either the 
indentation_levels array or something happened to the code
-                    printf("WHAT HAPPENED\n");
+                    *msg = createException(MAL, "pyapi.eval", "If you see this 
error something went wrong in the code. Sorry.");
                     goto finally;
                 }
                 for(j = 0; j < (level + 1) * spaces_per_level; j++) {
@@ -490,7 +506,7 @@ char* FormatCode(char* code, char **args
     newcode[code_location] = '\0';
     if (code_location >= size) {
         // Something went wrong with our size computation, this also should 
never happen
-        printf("WHAT HAPPENED\n");
+        *msg = createException(MAL, "pyapi.eval", "If you see this error 
something went wrong in the code (size computation). Sorry.");
         goto finally;
     }
 finally:
diff --git a/monetdb5/extras/pyapi/formatinput.h 
b/monetdb5/extras/pyapi/formatinput.h
--- a/monetdb5/extras/pyapi/formatinput.h
+++ b/monetdb5/extras/pyapi/formatinput.h
@@ -21,6 +21,6 @@
 #undef _POSIX_C_SOURCE
 #include <Python.h>
  
-char* FormatCode(char* code, char **args, size_t argcount, size_t tabwidth, 
PyObject **code_object);
+char* FormatCode(char* code, char **args, size_t argcount, size_t tabwidth, 
PyObject **code_object, char **return_message);
 
 #endif /* _PY_FORMAT_INPUT_LIB_ */
diff --git a/monetdb5/extras/pyapi/pyapi.c b/monetdb5/extras/pyapi/pyapi.c
--- a/monetdb5/extras/pyapi/pyapi.c
+++ b/monetdb5/extras/pyapi/pyapi.c
@@ -696,9 +696,10 @@ str PyAPIeval(MalBlkPtr mb, MalStkPtr st
 
     /*[PARSE_CODE]*/
     VERBOSE_MESSAGE("Formatting python code.\n"); 
-    pycall = FormatCode(exprStr, args, pci->argc, 4, &code_object);
+    pycall = FormatCode(exprStr, args, pci->argc, 4, &code_object, &msg);
     if (pycall == NULL && code_object == NULL) {
-        throw(MAL, "pyapi.eval", MAL_MALLOC_FAIL);
+        if (msg == NULL) { msg = createException(MAL, "pyapi.eval", "Error 
while parsing Python code."); }
+        goto wrapup;
     }
     
     /*[CONVERT_BAT]*/
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to