Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Assertion error when running tests on Python 3.6 compiled in debug mode #7399

@vstinner

Description

@vstinner

Hi,

I'm trying to run the numpy test suite on the development version of Python 3.6 with Python compiled in debug mode, but I had two issues:

  • Cython doesn't work on Python 3.6 anymore: http://bugs.python.org/issue26519
  • _convert_from_dict() function of numpy/core/src/multiarray/descriptor.c calls directly or indirectly PyObject_GetItem() with an exception set, it's no more allowed in debug mode, since PyObject_GetItem() may clear the current exception.

Following patch (incomplete, see the FIXME) works around assertion errors raised by the test suite:

diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c
index 03a4654..f9fd714 100644
--- a/numpy/core/src/multiarray/descriptor.c
+++ b/numpy/core/src/multiarray/descriptor.c
@@ -977,7 +977,10 @@ _convert_from_dict(PyObject *obj, int align)
      * Use PyMapping_GetItemString to support dictproxy objects as well.
      */
     names = Borrowed_PyMapping_GetItemString(obj, "names");
-    descrs = Borrowed_PyMapping_GetItemString(obj, "formats");
+    if (names)
+        descrs = Borrowed_PyMapping_GetItemString(obj, "formats");
+    else
+        descrs = NULL;
     if (!names || !descrs) {
         Py_DECREF(fields);
         PyErr_Clear();
@@ -985,8 +988,11 @@ _convert_from_dict(PyObject *obj, int align)
     }
     n = PyObject_Length(names);
     offsets = Borrowed_PyMapping_GetItemString(obj, "offsets");
+    if (!offsets) {
+        PyErr_Clear();
+    }
     titles = Borrowed_PyMapping_GetItemString(obj, "titles");
-    if (!offsets || !titles) {
+    if (!titles) {
         PyErr_Clear();
     }

@@ -1080,6 +1086,8 @@ _convert_from_dict(PyObject *obj, int align)
                         "with align=True",
                         (int)offset, (int)newdescr->alignment);
                 ret = NPY_FAIL;
+                /* FIXME: fix ref leaks! ind, tup, ... */
+                goto fail;
             }
             else if (offset + newdescr->elsize > totalsize) {
                 totalsize = offset + newdescr->elsize;

IMHO this function must be rewritten to handle exceptions differently: give up earlier. See also the issue #7360 which is a similar issue, but in a different C function of numpy (ufunc_generic_call).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions