How to call import_array() properly?
In my Python code I have import cvisual cvisual.init_numpy() and in my C++ code I have void init_numpy() { import_array(); } import_array() in numpy/core/include/numpy/_multiarray_api.h is a macro: #if PY_VERSION_HEX >= 0x03000000 #define NUMPY_IMPORT_ARRAY_RETVAL NULL #else #define NUMPY_IMPORT_ARRAY_RETVAL #endif #define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return NUMPY_IMPORT_ARRAY_RETVAL; } } Note that for Python 3 there is a change so that the macro returns NULL, whereas for Python 2 it returned nothing. On Windows and Mac, this works fine for Python 2, and it works fine for a with Python 3, but with either Microsoft Visual Studio 2008 or 2010 this fails for Python 3 with the message "'void' function returning a value", presumably due to the return NULL for Python 3, something that doesn't bother the Mac. So my dumb question is, how should I call import_array() from my routine init_numpy() to get around this problem? I have found a workaround, consisting of defining init_numpy to be of type int on Windows with Python 3, but this seems like an odd kludge, since it isn't needed on the Mac, and I think it's also not needed on Linux. Bruce Sherwood
I made a mistake: the Mac behaves the same way when I repeat the experiment. I guess I simply have to define init_numpy() to be of type int for Python 3 on both machines. Nevertheless, if you see a more elegant coding, I'd be interested. Thanks. Bruce Sherwood On Sun, Dec 26, 2010 at 3:26 PM, Bruce Sherwood <Bruce_Sherwood@ncsu.edu> wrote:
In my Python code I have
import cvisual cvisual.init_numpy()
and in my C++ code I have
void init_numpy() { import_array(); }
import_array() in numpy/core/include/numpy/_multiarray_api.h is a macro:
#if PY_VERSION_HEX >= 0x03000000 #define NUMPY_IMPORT_ARRAY_RETVAL NULL #else #define NUMPY_IMPORT_ARRAY_RETVAL #endif
#define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return NUMPY_IMPORT_ARRAY_RETVAL; } }
Note that for Python 3 there is a change so that the macro returns NULL, whereas for Python 2 it returned nothing.
On Windows and Mac, this works fine for Python 2, and it works fine for a with Python 3, but with either Microsoft Visual Studio 2008 or 2010 this fails for Python 3 with the message "'void' function returning a value", presumably due to the return NULL for Python 3, something that doesn't bother the Mac.
So my dumb question is, how should I call import_array() from my routine init_numpy() to get around this problem? I have found a workaround, consisting of defining init_numpy to be of type int on Windows with Python 3, but this seems like an odd kludge, since it isn't needed on the Mac, and I think it's also not needed on Linux.
Bruce Sherwood
On Sun, Dec 26, 2010 at 17:26, Bruce Sherwood <Bruce_Sherwood@ncsu.edu> wrote:
In my Python code I have
import cvisual cvisual.init_numpy()
and in my C++ code I have
void init_numpy() { import_array(); }
The import_array() call goes into the initialization function for your module, e.g. initcvisual(). Do not put it into a separate function for the user of your module to call. -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco
Thanks for the good suggestion. I now see that it was purely historical that import_array was driven (indirectly through init_numpy) from the pure Python component of the module rather than in the import of the C++ component, and I've changed that. However, I'm still curious as to whether there's a more intelligent or elegant way to drive import_array than the following code: #if PY_MAJOR_VERSION >= 3 int init_numpy() { import_array(); } #else void init_numpy() { import_array(); } #endif Bruce Sherwood On Mon, Dec 27, 2010 at 8:20 AM, Robert Kern <robert.kern@gmail.com> wrote:
On Sun, Dec 26, 2010 at 17:26, Bruce Sherwood <Bruce_Sherwood@ncsu.edu> wrote:
In my Python code I have
import cvisual cvisual.init_numpy()
and in my C++ code I have
void init_numpy() { import_array(); }
The import_array() call goes into the initialization function for your module, e.g. initcvisual(). Do not put it into a separate function for the user of your module to call.
-- Robert Kern
"I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
On Mon, Dec 27, 2010 at 13:09, Bruce Sherwood <Bruce_Sherwood@ncsu.edu> wrote:
Thanks for the good suggestion. I now see that it was purely historical that import_array was driven (indirectly through init_numpy) from the pure Python component of the module rather than in the import of the C++ component, and I've changed that. However, I'm still curious as to whether there's a more intelligent or elegant way to drive import_array than the following code:
#if PY_MAJOR_VERSION >= 3 int init_numpy() { import_array(); } #else void init_numpy() { import_array(); } #endif
Just put "import_array();" into initcvisual(). You should not put it in any other function. -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco
The module I'm working with, which uses Boost, doesn't have a function "initcvisual". Rather there's a section headed with BOOST_PYTHON_MODULE( cvisual). Placing the import_array macro directly in this section causes an unwanted return. I guess it doesn't matter, since what I've done works okay. And I realized that I could collapse init_numpy a bit: #if PY_MAJOR_VERSION >= 3 int #else void #endif init_numpy() { import_array(); } Bruce Sherwood On Mon, Dec 27, 2010 at 12:15 PM, Robert Kern <robert.kern@gmail.com> wrote:
On Mon, Dec 27, 2010 at 13:09, Bruce Sherwood <Bruce_Sherwood@ncsu.edu> wrote:
Thanks for the good suggestion. I now see that it was purely historical that import_array was driven (indirectly through init_numpy) from the pure Python component of the module rather than in the import of the C++ component, and I've changed that. However, I'm still curious as to whether there's a more intelligent or elegant way to drive import_array than the following code:
#if PY_MAJOR_VERSION >= 3 int init_numpy() { import_array(); } #else void init_numpy() { import_array(); } #endif
Just put "import_array();" into initcvisual(). You should not put it in any other function.
-- Robert Kern
"I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
participants (2)
-
Bruce Sherwood -
Robert Kern