Changeset: 9a8852ef2aa2 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=9a8852ef2aa2
Modified Files:
monetdb5/extras/pyapi/Tests/All
monetdb5/extras/pyapi/Tests/pyapi01.malC
monetdb5/extras/pyapi/Tests/pyapi02.malC
monetdb5/extras/pyapi/Tests/pyapi03.malC
monetdb5/extras/pyapi/pyapi.c
Branch: pyapi
Log Message:
Fixed boolean types.
diffs (truncated from 413 to 300 lines):
diff --git a/monetdb5/extras/pyapi/Tests/All b/monetdb5/extras/pyapi/Tests/All
--- a/monetdb5/extras/pyapi/Tests/All
+++ b/monetdb5/extras/pyapi/Tests/All
@@ -1,4 +1,1 @@
-HAVE_LIBPY?pyapi00
-HAVE_LIBPY?pyapi01
-HAVE_LIBPY?pyapi02
-HAVE_LIBPY?pyapi03
+HAVE_LIBPY?pyapi_types_string
diff --git a/monetdb5/extras/pyapi/Tests/pyapi01.malC
b/monetdb5/extras/pyapi/Tests/pyapi01.malC
--- a/monetdb5/extras/pyapi/Tests/pyapi01.malC
+++ b/monetdb5/extras/pyapi/Tests/pyapi01.malC
@@ -1,16 +1,17 @@
+#testing basic string and boolean types
#booleans
-bool:= bat.new(:oid,:str);
-bat.append(bool,"T":str);
-bat.append(bool,"T":str);
-bat.append(bool,"T":str);
-bat.append(bool,"T":str);
-bat.append(bool,"T":str);
-bat.append(bool,"T":str);
-bat.append(bool,"T":str);
-bat.append(bool,nil:str);
-rbool:bat[:oid,:str] := pyapi.eval(nil:ptr,"return([[True]])",bool);
+bool:= bat.new(:oid,:bte);
+bat.append(bool,1:bte);
+bat.append(bool,1:bte);
+bat.append(bool,1:bte);
+bat.append(bool,1:bte);
+bat.append(bool,1:bte);
+bat.append(bool,1:bte);
+bat.append(bool,1:bte);
+bat.append(bool,nil:bte);
+rbool:bat[:oid,:bte] := pyapi.eval(nil:ptr,"return(all(arg1))",bool);
io.print(rbool);
#strings testing
diff --git a/monetdb5/extras/pyapi/Tests/pyapi02.malC
b/monetdb5/extras/pyapi/Tests/pyapi02.malC
--- a/monetdb5/extras/pyapi/Tests/pyapi02.malC
+++ b/monetdb5/extras/pyapi/Tests/pyapi02.malC
@@ -36,8 +36,8 @@ bat.append(bint,846930886:int);
bat.append(bint,1681692777:int);
bat.append(bint,1714636915:int);
bat.append(bint,nil:int);
-#rint:bat[:oid,:dbl] :=
pyapi.eval(nil:ptr,"return([numpy.add(arg1.filled(0),1)])",bint);
-#io.print(rint);
+rint:bat[:oid,:dbl] :=
pyapi.eval(nil:ptr,"return([numpy.add(arg1.filled(0),1)])",bint);
+io.print(rint);
bwrd:= bat.new(:oid,:wrd);
bat.append(bwrd,1804289383:wrd);
@@ -45,16 +45,16 @@ bat.append(bwrd,846930886:wrd);
bat.append(bwrd,1681692777:wrd);
bat.append(bwrd,1714636915:wrd);
bat.append(bwrd,nil:wrd);
-#rwrd:bat[:oid,:dbl] :=
pyapi.eval(nil:ptr,"return([numpy.add(arg1.filled(0),1)])",bwrd);
-#io.print(rwrd);
+rwrd:bat[:oid,:dbl] :=
pyapi.eval(nil:ptr,"return([numpy.add(arg1.filled(0),1)])",bwrd);
+io.print(rwrd);
blng:= bat.new(:oid,:lng);
bat.append(blng,1804289383L);
bat.append(blng,846930886L);
bat.append(blng,1681692777L);
bat.append(blng,1714636915L);
-#rlng:bat[:oid,:dbl] :=
pyapi.eval(nil:ptr,"return([numpy.add(arg1.filled(0),1)])",blng);
-#io.print(rlng);
+rlng:bat[:oid,:dbl] :=
pyapi.eval(nil:ptr,"return([numpy.add(arg1.filled(0),1)])",blng);
+io.print(rlng);
# not sure what to with hge, numpy only supports 128 bits when sizeof(long)=16
# bhge:= bat.new(:oid,:hge);
@@ -82,8 +82,8 @@ bat.append(bdbl,84.6930886:dbl);
bat.append(bdbl,168169.2777:dbl);
bat.append(bdbl,17146369.15:dbl);
bat.append(bdbl,nil:dbl);
-#rdbl:bat[:oid,:dbl] :=
pyapi.eval(nil:ptr,"return([numpy.add(arg1.filled(0),1)])",bdbl);
-#io.print(rdbl);
+rdbl:bat[:oid,:dbl] :=
pyapi.eval(nil:ptr,"return([numpy.add(arg1.filled(0),1)])",bdbl);
+io.print(rdbl);
# strings
@@ -92,23 +92,21 @@ bat.append(bstr,"asdf":str);
bat.append(bstr,"sd asd asd asd asd a":str);
bat.append(bstr,nil:str);
bat.append(bstr,"test":str);
-#rstr:bat[:oid,:str] := pyapi.eval(nil:ptr,"print(arg1);\nreturn(arg1)",bstr);
-#io.print(rstr);
+rstr:bat[:oid,:str] := pyapi.eval(nil:ptr,"print(arg1);\nreturn(arg1)",bstr);
+io.print(rstr);
-#STRANGE BUG HERE WITH .filled()
-#TODO: Investigate
#booleans
-bool:= bat.new(:oid,:str);
-bat.append(bool,"T":str);
-bat.append(bool,"T":str);
-bat.append(bool,"T":str);
-bat.append(bool,"T":str);
-bat.append(bool,"T":str);
-bat.append(bool,"T":str);
-bat.append(bool,"T":str);
-bat.append(bool,"T":str);
-rbool:bat[:oid,:str] := pyapi.eval(nil:ptr,"print arg1\nreturn(arg1)",bool);
+bool:= bat.new(:oid,:bte);
+bat.append(bool,1:bte);
+bat.append(bool,1:bte);
+bat.append(bool,1:bte);
+bat.append(bool,1:bte);
+bat.append(bool,1:bte);
+bat.append(bool,1:bte);
+bat.append(bool,1:bte);
+bat.append(bool,nil:bte);
+rbool:bat[:oid,:bte] := pyapi.eval(nil:ptr,"print arg1\nreturn(arg1)",bool);
io.print(rbool);
diff --git a/monetdb5/extras/pyapi/Tests/pyapi03.malC
b/monetdb5/extras/pyapi/Tests/pyapi03.malC
--- a/monetdb5/extras/pyapi/Tests/pyapi03.malC
+++ b/monetdb5/extras/pyapi/Tests/pyapi03.malC
@@ -1,10 +1,9 @@
-# input types testing
+# different functions testing
# inty types
-#single-value array gives segmentation fault
-rstr:bat[:oid,:dbl] := pyapi.eval(nil:ptr,"return [55]");
+rstr:bat[:oid,:str] := pyapi.eval(nil:ptr,"return 42");
io.print(rstr);
bstr:= bat.new(:oid,:int);
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
@@ -28,7 +28,7 @@
const char* pyapi_enableflag = "embedded_py";
char *NPYConstToString(int);
-bool IsPyArrayObject(PyObject *);
+bool IsPyArrayObject(PyObject *, int);
int PyAPIEnabled(void) {
return (GDKgetenv_istrue(pyapi_enableflag)
@@ -71,6 +71,7 @@ static int pyapiInitialized = FALSE;
}
\
} \
}
+
#define NP_MAKE_BAT(bat, mtpe, nptpe) { \
BATseqbase(bat, 0); bat->T->nil = 0; bat->T->nonil = 1; \
bat->tkey = 0; bat->tsorted = 0; bat->trevsorted = 0; \
@@ -246,55 +247,6 @@ str PyAPIeval(MalBlkPtr mb, MalStkPtr st
maxsize = length;
}
- if (maxsize == 1 || maxsize == strlen(str_nil))
- {
- //BOOLEANS
- bool isbool = true;
- BATloop(b, p, q)
- {
- const char *t = (const char *)
BUNtail(li, p);
- if (t[0] != 'T' && t[0] !='F' &&
strcmp(t, str_nil) != 0)
- {
- isbool = false;
- break;
- }
- }
- if (isbool)
- {
- //create a NPY_BOOL array object
- vararray = PyArray_New(
- &PyArray_Type,
- 1,
- (npy_intp[1]) {count},
- NPY_BOOL,
- NULL,
- NULL,
- 0,
- NPY_ARRAY_CARRAY ||
NPY_ARRAY_WRITEABLE,
- NULL);
-
- //fill the NPY_BOOL array object using
the PyArray_SETITEM function
- j = 0;
- BATloop(b, p, q)
- {
- const char *t = (const char *)
BUNtail(li, p);
- PyObject *value;
- if (t[0] == 'T')
- {
- Py_INCREF(Py_True);
- value = Py_True;
- }
- else
- {
- Py_INCREF(Py_False);
- value = Py_False;
- }
-
PyArray_SETITEM((PyArrayObject*)vararray,
PyArray_GETPTR1((PyArrayObject*)vararray, j), value);
- j++;
- }
- break;
- }
- }
//create a NPY_STRING array object
vararray = PyArray_New(
&PyArray_Type,
@@ -319,8 +271,6 @@ str PyAPIeval(MalBlkPtr mb, MalStkPtr st
case TYPE_hge:
vararray = BAT_TO_NP(b, hge, NPY_LONGDOUBLE);
break;
-
- // TODO: implement other types (boolean)
default:
msg = createException(MAL, "pyapi.eval", "unknown
argument type ");
goto wrapup;
@@ -472,31 +422,51 @@ str PyAPIeval(MalBlkPtr mb, MalStkPtr st
goto wrapup; // shudder
}
- if (!pResult || !PyList_Check(pResult) || PyList_Size(pResult)
!= pci->retc)
+ if (pResult)
{
- //the object is not a PyList, but maybe it is a single
PyArrayObject, so we will check if it is
- if (IsPyArrayObject(pResult))
+ PyObject * pColO;
+
+ if (!PyList_Check(pResult))
{
- //a single array is returned rather than a list
of arrays
- //convert the single array to a list of size 1
-
- //TODO: Accept a single object (not just a
single array) and cast it to an array
- //TODO: Accept a single array with a single
object in it (this currently gives a Segmentation Fault)
+ if (pci->retc == 1)
+ {
+ //the object is not a PyList, turn it
into a PyList!
+ PyObject *list = PyList_New(1);
+ PyList_SetItem(list, 0, pResult);
+ pResult = list;
+ }
+ else
+ {
+ //the result object is not a PyList,
yet we expect more than one answer. We can only convert the result into a list
with a single element, so the output is necessarily wrong.
+ msg = createException(MAL,
"pyapi.eval", "Invalid result object. Need list of size %d containing numpy
arrays", pci->retc);
+ goto wrapup;
+ }
+ }
+ //now check the first entry of the pResult
+ pColO = PyList_GetItem(pResult, 0);
+ if (!IsPyArrayObject(pColO, 1))
+ {
+ //the first entry isn't a PyArrayObject! Then
lets make it a double PyList!
PyObject *list = PyList_New(1);
PyList_SetItem(list, 0, pResult);
pResult = list;
}
- else
+
+ if (PyList_Size(pResult) != pci->retc)
{
- //it is neither a PyList nor a PyArrayObject,
so throw an error
+ //wrong return size, we expect pci->retc arrays
msg = createException(MAL, "pyapi.eval",
"Invalid result object. Need list of size %d containing numpy arrays",
pci->retc);
goto wrapup;
}
}
+ else
+ {
+ msg = createException(MAL, "pyapi.eval", "Invalid
result object. No result object could be generated.");
+ goto wrapup;
+ }
// delete the function again
PyRun_SimpleString("del pyfun");
}
-
// collect the return values
for (i = 0; i < pci->retc; i++) {
PyArrayObject *pCol = NULL;
@@ -504,7 +474,6 @@ str PyAPIeval(MalBlkPtr mb, MalStkPtr st
PyObject *pMask = NULL;
PyObject * pColO = PyList_GetItem(pResult, i);
int bat_type = ATOMstorage(getColumnType(getArgType(mb,pci,i)));
- bool isbool;
// TODO null handling
switch (bat_type) {
@@ -534,77 +503,37 @@ str PyAPIeval(MalBlkPtr mb, MalStkPtr st
break;
case TYPE_str:
- pCol = (PyArrayObject*) PyArray_FromAny(pColO, \
- NULL, 1, 1, NPY_ARRAY_CARRAY | \
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list