Changeset: 73fa640cdf6a for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/73fa640cdf6a Modified Files: sql/backends/monet5/UDF/pyapi3/connection3.c sql/backends/monet5/UDF/pyapi3/conversion3.c sql/backends/monet5/UDF/pyapi3/convert_loops.h sql/backends/monet5/UDF/pyapi3/pyapi3.c Branch: default Log Message:
fixing leaks in the python sieve diffs (truncated from 401 to 300 lines): diff --git a/sql/backends/monet5/UDF/pyapi3/connection3.c b/sql/backends/monet5/UDF/pyapi3/connection3.c --- a/sql/backends/monet5/UDF/pyapi3/connection3.c +++ b/sql/backends/monet5/UDF/pyapi3/connection3.c @@ -15,7 +15,8 @@ #include "type_conversion.h" #include "gdk_interprocess.h" -static PyObject *_connection_execute(Py_ConnectionObject *self, PyObject *args) +static PyObject * +_connection_execute(Py_ConnectionObject *self, PyObject *args) { char *query = NULL; if (PyUnicode_CheckExact(args)) { @@ -67,8 +68,7 @@ static PyObject *_connection_execute(Py_ input.scalar = false; input.sql_subtype = &col.type; - numpy_array = - PyMaskedArray_FromBAT(&input, 0, input.count, &res, true); + numpy_array = PyMaskedArray_FromBAT(&input, 0, input.count, &res, true); if (!numpy_array) { _connection_cleanup_result(output); BBPunfix(b->batCacheid); @@ -76,9 +76,9 @@ static PyObject *_connection_execute(Py_ (res ? getExceptionMessage(res) : "<no error>")); return NULL; } - PyDict_SetItem(result, - PyUnicode_FromString(output->cols[i].name), - numpy_array); + PyObject *nme = PyUnicode_FromString(output->cols[i].name); + PyDict_SetItem(result, nme, numpy_array); + Py_DECREF(nme); Py_DECREF(numpy_array); BBPunfix(input.bat->batCacheid); } diff --git a/sql/backends/monet5/UDF/pyapi3/conversion3.c b/sql/backends/monet5/UDF/pyapi3/conversion3.c --- a/sql/backends/monet5/UDF/pyapi3/conversion3.c +++ b/sql/backends/monet5/UDF/pyapi3/conversion3.c @@ -114,14 +114,13 @@ wrapup: return vararray; } -PyObject *PyMaskedArray_FromBAT(PyInput *inp, size_t t_start, size_t t_end, - char **return_message, bool copy) +PyObject * +PyMaskedArray_FromBAT(PyInput *inp, size_t t_start, size_t t_end, char **return_message, bool copy) { BAT *b; char *msg; - PyObject *vararray; + PyObject *vararray = PyArrayObject_FromBAT(inp, t_start, t_end, return_message, copy); - vararray = PyArrayObject_FromBAT(inp, t_start, t_end, return_message, copy); if (vararray == NULL) { return NULL; } @@ -137,12 +136,15 @@ PyObject *PyMaskedArray_FromBAT(PyInput bool bnonil = b->tnonil; MT_lock_unset(&b->theaplock); if (!bnonil) { - PyObject *mask; - PyObject *mafunc = PyObject_GetAttrString( - PyImport_Import(PyUnicode_FromString("numpy.ma")), "masked_array"); + PyObject *nme = PyUnicode_FromString("numpy.ma"); + PyObject *mod = PyImport_Import(nme); + PyObject *mafunc = PyObject_GetAttrString( mod, "masked_array"); PyObject *nullmask = PyNullMask_FromBAT(b, t_start, t_end); + Py_DECREF(nme); if (!nullmask) { + Py_DECREF(mafunc); + Py_DECREF(mod); msg = createException(MAL, "pyapi3.eval", "Failed to create mask for some reason"); goto wrapup; } else if (nullmask == Py_None) { @@ -154,16 +156,18 @@ PyObject *PyMaskedArray_FromBAT(PyInput // Now we will actually construct the mask by calling the masked // array constructor - mask = PyObject_CallObject(mafunc, maargs); + PyObject *mask = PyObject_CallObject(mafunc, maargs); + Py_DECREF(maargs); if (!mask) { + Py_DECREF(mafunc); + Py_DECREF(mod); msg = createException(MAL, "pyapi3.eval", SQLSTATE(PY000) "Failed to create mask"); goto wrapup; } - Py_DECREF(maargs); - vararray = mask; } Py_DECREF(mafunc); + Py_DECREF(mod); } return vararray; wrapup: @@ -171,8 +175,8 @@ wrapup: return NULL; } -PyObject *PyArrayObject_FromBAT(PyInput *inp, size_t t_start, size_t t_end, - char **return_message, bool copy) +PyObject * +PyArrayObject_FromBAT(PyInput *inp, size_t t_start, size_t t_end, char **return_message, bool copy) { // This variable will hold the converted Python object PyObject *vararray = NULL; @@ -527,8 +531,7 @@ PyObject *PyNullMask_FromBAT(BAT *b, siz // False size_t count = t_end - t_start; npy_intp elements[1] = {count}; - PyArrayObject *nullmask = - (PyArrayObject *)PyArray_EMPTY(1, elements, NPY_BOOL, 0); + PyArrayObject *nullmask = (PyArrayObject *)PyArray_EMPTY(1, elements, NPY_BOOL, 0); const void *nil = ATOMnilptr(b->ttype); size_t j; bool found_nil = false; @@ -580,12 +583,11 @@ PyObject *PyNullMask_FromBAT(BAT *b, siz return (PyObject *)nullmask; } -PyObject *PyDict_CheckForConversion(PyObject *pResult, int expected_columns, - char **retcol_names, char **return_message) +PyObject * +PyDict_CheckForConversion(PyObject *pResult, int expected_columns, char **retcol_names, char **return_message) { char *msg = MAL_SUCCEED; - PyObject *result = PyList_New(expected_columns), - *keys = PyDict_Keys(pResult); + PyObject *result = PyList_New(expected_columns); int i; for (i = 0; i < expected_columns; i++) { @@ -614,28 +616,27 @@ PyObject *PyDict_CheckForConversion(PyOb Py_INCREF(item); Py_DECREF(object); } else { + if (object) + Py_DECREF(object); msg = createException(MAL, "pyapi3.eval", SQLSTATE(PY000) "Why is this not a list?"); goto wrapup; } } - Py_DECREF(keys); Py_DECREF(pResult); - // Py_INCREF(result); return result; wrapup: *return_message = msg; Py_DECREF(result); - Py_DECREF(keys); Py_DECREF(pResult); return NULL; } -PyObject *PyObject_CheckForConversion(PyObject *pResult, int expected_columns, - int *actual_columns, - char **return_message) +PyObject * +PyObject_CheckForConversion(PyObject *pResult, int expected_columns, int *actual_columns, char **return_message) { char *msg; int columns = 0; + if (pResult) { PyObject *pColO = NULL; if (PyType_IsPandasDataFrame(pResult)) { @@ -643,15 +644,17 @@ PyObject *PyObject_CheckForConversion(Py // we can convert the pandas data frame to a numpy array by simply // accessing the "values" field (as pandas dataframes are numpy // arrays internally) - pResult = PyObject_GetAttrString(pResult, "values"); - if (pResult == NULL) { + PyObject *nResult = PyObject_GetAttrString(pResult, "values"); + Py_DECREF(pResult); + if (nResult == NULL) { msg = createException(MAL, "pyapi3.eval", SQLSTATE(PY000) "Invalid Pandas data frame."); goto wrapup; } // we transpose the values field so it's aligned correctly for our // purposes - pResult = PyObject_GetAttrString(pResult, "T"); + pResult = PyObject_GetAttrString(nResult, "T"); + Py_DECREF(nResult); if (pResult == NULL) { msg = createException(MAL, "pyapi3.eval", SQLSTATE(PY000) "Invalid Pandas data frame."); @@ -688,14 +691,15 @@ PyObject *PyObject_CheckForConversion(Py } else { // if it is not a scalar, we check if it is a single array bool IsSingleArray = true; - PyObject *data = pResult; + PyObject *data = pResult, *ndata = NULL; if (PyType_IsNumpyMaskedArray(data)) { - data = PyObject_GetAttrString(pResult, "data"); - if (data == NULL) { + ndata = PyObject_GetAttrString(pResult, "data"); + if (ndata == NULL) { msg = createException(MAL, "pyapi3.eval", SQLSTATE(PY000) "Invalid masked array."); goto wrapup; } + data = ndata; } if (PyType_IsNumpyArray(data)) { if (PyArray_NDIM((PyArrayObject *)data) != 1) { @@ -703,10 +707,9 @@ PyObject *PyObject_CheckForConversion(Py } else if (PyArray_SIZE((PyArrayObject *)data) == 0) { IsSingleArray = true; } else { - pColO = PyArray_GETITEM( - (PyArrayObject *)data, - PyArray_GETPTR1((PyArrayObject *)data, 0)); + pColO = PyArray_GETITEM( (PyArrayObject *)data, PyArray_GETPTR1((PyArrayObject *)data, 0)); IsSingleArray = PyType_IsPyScalar(pColO); + Py_DECREF(pColO); } } else if (PyList_Check(data)) { if (PyList_Size(data) == 0) { @@ -768,6 +771,8 @@ PyObject *PyObject_CheckForConversion(Py goto wrapup; } } + if (ndata) + Py_DECREF(ndata); } } else { msg = createException( @@ -786,13 +791,13 @@ wrapup: return NULL; } -str PyObject_GetReturnValues(PyObject *obj, PyReturn *ret) +str +PyObject_GetReturnValues(PyObject *obj, PyReturn *ret) { PyObject *pMask = NULL; str msg = MAL_SUCCEED; // If it isn't we need to convert pColO to the expected Numpy Array type - ret->numpy_array = PyArray_FromAny( - obj, NULL, 1, 1, NPY_ARRAY_CARRAY | NPY_ARRAY_FORCECAST, NULL); + ret->numpy_array = PyArray_FromAny( obj, NULL, 1, 1, NPY_ARRAY_CARRAY | NPY_ARRAY_FORCECAST, NULL); if (ret->numpy_array == NULL) { msg = createException( MAL, "pyapi3.eval", @@ -800,9 +805,7 @@ str PyObject_GetReturnValues(PyObject *o goto wrapup; } - ret->result_type = - PyArray_DESCR((PyArrayObject *)ret->numpy_array) - ->type_num; // We read the result type from the resulting array + ret->result_type = PyArray_DESCR((PyArrayObject *)ret->numpy_array)->type_num; // We read the result type from the resulting array ret->memory_size = PyArray_DESCR((PyArrayObject *)ret->numpy_array)->elsize; ret->count = PyArray_DIMS((PyArrayObject *)ret->numpy_array)[0]; ret->array_data = PyArray_DATA((PyArrayObject *)ret->numpy_array); @@ -812,14 +815,12 @@ str PyObject_GetReturnValues(PyObject *o if (PyObject_HasAttrString(obj, "mask")) { pMask = PyObject_GetAttrString(obj, "mask"); if (pMask != NULL) { - ret->numpy_mask = - PyArray_FromAny(pMask, PyArray_DescrFromType(NPY_BOOL), 1, 1, - NPY_ARRAY_CARRAY, NULL); - if (ret->numpy_mask == NULL || - PyArray_DIMS((PyArrayObject *)ret->numpy_mask)[0] != - (int)ret->count) { + ret->numpy_mask = PyArray_FromAny(pMask, PyArray_DescrFromType(NPY_BOOL), 1, 1, NPY_ARRAY_CARRAY, NULL); + Py_DECREF(pMask); + if (ret->numpy_mask == NULL || PyArray_DIMS((PyArrayObject *)ret->numpy_mask)[0] != (int)ret->count) { PyErr_Clear(); - pMask = NULL; + if (ret->numpy_mask) + Py_DECREF(ret->numpy_mask); ret->numpy_mask = NULL; } } @@ -830,8 +831,8 @@ wrapup: return msg; } -bool PyObject_PreprocessObject(PyObject *pResult, PyReturn *pyreturn_values, - int column_count, char **return_message) +bool +PyObject_PreprocessObject(PyObject *pResult, PyReturn *pyreturn_values, int column_count, char **return_message) { int i; char *msg; @@ -857,15 +858,15 @@ bool PyObject_PreprocessObject(PyObject // If it is a PyList, we simply get the i'th Numpy array from the // PyList pColO = PyList_GetItem(pResult, i); + Py_INCREF(pColO); } else { // If it isn't, the result object is either a Nump Masked Array or a // Numpy Array PyObject *data = pResult; if (PyType_IsNumpyMaskedArray(data)) { _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org