Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
PyArray_API is *not* a unique symbol. (Trac #1928) #2521
numpy makes the API to its array type available through the symbol PyArray_API. But it also allows users to make it available through some other symbol by defining PY_ARRAY_UNIQUE_SYMBOL to be whatever other symbol is desired. (Why anyone would want to use a different symbol name never became clear to me, but some do.)
__multiarray_api.h has some C preprocessor magic that defines the symbol one way if PY_ARRAY_UNIQUE_SYMBOL is defined, and another way if PY_ARRAY_UNIQUE_SYMBOL is not defined. It all works well, except...
...In the numpy header fortranobject.h, PY_ARRAY_UNIQUE_SYMBOL is defined as PyArray_API. This makes it look as if a different symbol is being used, but the "different" symbol being used is the same as the "real" symbol for the API. This results in anyone including fortranobject.h (scipy does) having a definition of PyArray_API that does not play well at all with the "real" global definition of PyArray_API.
I was sometimes getting a crash when invoking "import scipy.signal" I tracked it down to:
It was this statement that was causing trouble. My debugger was telling me that the value being returned from PyCObject_AsVoidPtr was the same as the address of PyArray_API. In other words, after the above statement, &PyArray_API == PyArray_API is true. I'm pretty sure that's not good. It resulted in the first attempt to access the contents of PyArray_API (a call to PyArray_GetNDArrayCVersion() a few lines later) crashing.
The crash only happens if I do the "import scipy.signal" after I import my own C-python module that uses numpy arrays. I suppose it could be a bug in my code, but I can't see how. My source file just has a "#include <numarray/libnumarray.h>", without define any optional symbols (no PY_ARRAY_UNIQUE_SYMBOL, no NO_IMPORT or NO_IMPORT_ARRAY). It does not anywhere (directly) reference PyArray_API. The only thing the init routine does with numpy is call _import_array. Of course, my module has routines that do stuff with numpy arrays, but I don't call any of those between importing my module and importing scipy.signal to get the crash. If I am doing something wrong, then consider this to be a bug report on the docs, which have not made it clear what I am doing wrong. (I've looked. A bit.)
I tried to fix the problem by removing the #define of PY_ARRAY_UNIQUE_SYMBOL in fortranobject.h. That did indeed prevent the crash when I import my module followed by scipy.signal. However, if I import scipy.signal without first importing my module, the attempt to import scipy.signal raises in ImportError with complaint of undefined symbol PyArray_API.
I then tried to fix it by changing the define of PY_ARRAY_UNIQUE_SYMBOL in fortranobject.h to something (anything) other than PyArray_API. That worked. I am now able to import scipy.signal whether or not I first import my module. Is that the "right" fix? You decide.
trac user phil@... wrote on 2011-08-11
I looked into the problem a little more. It was indeed something my module was doing that was causing the problem, but it had nothing to do with my module using numpy arrays. It was because the python wrapper around my C-python module was sharing symbols across modules. The problem is easily reproduced thusly:
What I said about changing the definition of PY_ARRAY_UNIQUE_SYMBOL in fortranobject.h still fixes it, and I still think it might be a good idea to check in the change. But that's just my unexpert opinion...
For a project I'm working on I'm currently needing to build a statically compiled Python binary with several extension modules built in (NumPy, SciPy, etc).
I'm experiencing this crash as well when importing a SciPy module:
The cause appears to be the same. If