[Numpy-discussion] Determine if numpy is installed from anextension

Peter Notebaert peno@telenet...
Wed Feb 3 16:14:06 CST 2010


Just to imform that my approach works:

if (_import_array() < 0) {

   /* Clear the error state since we are handling the error. */
   PyErr_Clear();
   /* ... set up for the sans-numpy case. */
}
else {
   /* ... set up for the with-numpy case. */
}

It is based on Roberts idea to call PyImport_ImportModule("numpy"); and check if that succeededand clean up. In fact, _import_array() is doing this.
The code of _import_array() is in the header file __multiarray_api.h in the numpy folder of the distributed files:

static int
_import_array(void)
{
  int st;
  PyObject *numpy = PyImport_ImportModule("numpy.core.multiarray");
  PyObject *c_api = NULL;
  if (numpy == NULL) return -1;
  c_api = PyObject_GetAttrString(numpy, "_ARRAY_API");
  if (c_api == NULL) {Py_DECREF(numpy); return -1;}
  if (PyCObject_Check(c_api)) {
      PyArray_API = (void **)PyCObject_AsVoidPtr(c_api);
  }
  Py_DECREF(c_api);
  Py_DECREF(numpy);
  if (PyArray_API == NULL) return -1;
  /* Perform runtime check of C API version */
  if (NPY_VERSION != PyArray_GetNDArrayCVersion()) {
    PyErr_Format(PyExc_RuntimeError, "module compiled against "\
        "ABI version %x but this version of numpy is %x", \
        (int) NPY_VERSION, (int) PyArray_GetNDArrayCVersion());
    return -1;
  }
  if (NPY_FEATURE_VERSION > PyArray_GetNDArrayCFeatureVersion()) {
    PyErr_Format(PyExc_RuntimeError, "module compiled against "\
        "API version %x but this version of numpy is %x", \
        (int) NPY_FEATURE_VERSION, (int) PyArray_GetNDArrayCFeatureVersion());
    return -1;
  }

  /*
   * Perform runtime check of endianness and check it matches the one set by
   * the headers (npy_endian.h) as a safeguard
   */
  st = PyArray_GetEndianness();
  if (st == NPY_CPU_UNKNOWN_ENDIAN) {
    PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as unknown endian");
    return -1;
  }
#if NPY_BYTE_ORDER ==NPY_BIG_ENDIAN
  if (st != NPY_CPU_BIG) {
    PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\
        "big endian, but detected different endianness at runtime");
    return -1;
  }
#elif NPY_BYTE_ORDER == NPY_LITTLE_ENDIAN
  if (st != NPY_CPU_LITTLE) {
    PyErr_Format(PyExc_RuntimeError, "FATAL: module compiled as "\
        "little endian, but detected different endianness at runtime");
    return -1;
  }
#endif

  return 0;
}

As you can see, this routine is doing the same at the beginning with additional tests and the return value indicates if ok or not.

So I only had to call PyErr_Clear(); when it failes and the problem is solved.

Thanks for your input.

Peter 


From: Peter Notebaert 
Sent: Wednesday, February 03, 2010 16:57
To: Discussion of Numerical Python 
Subject: Re: [Numpy-discussion] Determine if numpy is installed from anextension


Ah, that is maybe the idea: 


if (_import_array() < 0) {

   /* Clear the error state since we are handling the error. */
   PyErr_Clear();
   /* ... set up for the sans-numpy case. */
}
else {
   /* ... set up for the with-numpy case. */
}


I did not call PyErr_Clear() when _import_array() < 0 and the error is probably still hanging and then given later.


I will try this this evening.


Thank you for the hints.


Peter


On Wed, Feb 3, 2010 at 4:22 PM, Robert Kern <robert.kern@gmail.com> wrote:

  On Wed, Feb 3, 2010 at 03:41, David Cournapeau <cournape@gmail.com> wrote:
  > On Wed, Feb 3, 2010 at 5:38 PM, Peter Notebaert <peno@telenet.be> wrote:
  >> >From an extension? How to import numpy from there and then test if that
  >> succeeded and that without any annoying message if possible...
  >
  > One obvious solution would be to simply call PyImport_Import, something like:
  >
  > #include <Python.h>
  >
  > PyMODINIT_FUNC initfoo(void)
  > {
  >        PyObject *m, *mod;
  >
  >        m = Py_InitModule("foo", NULL);
  >        if (m == NULL) {
  >                return;
  >        }
  >
  >        mod = PyImport_ImportModule("numpy");
  >        if (mod == NULL) {
  >                return;
  >        }
  >        Py_DECREF(mod);


  Or rather, to recover from the failed import as the OP wants to do:


  mod = PyImport_ImportModule("numpy");
  if (mod == NULL) {

     /* Clear the error state since we are handling the error. */
     PyErr_Clear();
     /* ... set up for the sans-numpy case. */
  }
  else {
     Py_DECREF(mod);
     import_array();
     /* ... set up for the with-numpy case. */
  }

  --
  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





--------------------------------------------------------------------------------


_______________________________________________
NumPy-Discussion mailing list
NumPy-Discussion@scipy.org
http://mail.scipy.org/mailman/listinfo/numpy-discussion
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.scipy.org/pipermail/numpy-discussion/attachments/20100203/5661af40/attachment.html 


More information about the NumPy-Discussion mailing list