esheldon / esutil

A variety of python utilities focusing on numerical, scientific, and astrophysical computing

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

init_numpy() should explicitly return NULL

SogoMineo opened this issue · comments

There are a few definitions of "static int *init_numpy(void)" in the source tree that call numpy's import_array(). Their definitions should be

static int *init_numpy(void) {
    import_array();
    return NULL;
}

import_array() is a macro that returns if and only if it fails. With the current definition of init_numpy(), the control flow comes out of import_array() if succeess, and returns from init_numpy() without a return statement.

The optimizer of g++ (but not gcc) in gcc-8 assumes that the control flow never reaches a point where the control flow would have to return without a return value. This means that gcc-8 optimizes init_numpy() such that import_array() will always fail, because the control flow would return without a return statement if import_array() were to succeed.

In fact, if I compile the current esutil with gcc-8, esutil.htm.HTM() fails with this error:

RuntimeError: FATAL: module compiled as little endian, but detected different endianness at runtime
ImportError: numpy.core.multiarray failed to import

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/path/to/site-packages/esutil/htm/htmc.py", line 152, in __init__
    this = _htmc.new_HTMC(depth)
SystemError: <built-in function new_HTMC> returned a result with an error set

Thanks for the report. Do you have a suggestion how to modify the C++ code to deal with this?

I made a pull request.
This patch works, but strictly speaking, the document says import_array() should be called "in the initialization section of a module." That the macro import_array() has a return statement only in a failure case also implies it should be used in a special context (that is, in a initialization function of a module).

agreed, calling this in the constructor seems to work but is not correct. Better would be to have this done by swig, but I could not get that to work correctly when I wrote this

Have you tried this code in both py3 and py2?

I have made sure that esutil.test() passes in python-2.7 and python-3.6 with my patch.

OK, sorry for the delay. Can you pleas submit the pull request against the htmlnull branch?

I canceled my old request and made a new pull request against htmnull branch.

this was addressed via the PR, thanks