[C++-sig] (David Abrahams)numpy.ndarray did not match PyArrayObject *

Philip Austin paustin at eos.ubc.ca
Tue Sep 26 19:50:39 CEST 2006


Qinfeng(Javen) Shi  writes:
 > 
 > Sorry, I don't get you.
 > The Python type of the ndarray is PyArray_Type. InC, every ndarray is a
 > pointer to a PyArrayObject structure.
 > So what is the extract_array_object and what is PyArrayObject_Type?
 > I tried

[snip]

 > They all failed.
 > 
 > Could you please tell me exactly?

He wasn't sure of the exact type name, so he put in a place holder.

The actual type name is PyArray_Type, defined in 

http://svn.scipy.org/svn/numpy/trunk/numpy/core/src/arrayobject.c

As you note, this struct is compiled and passed to extension modules
using the PyArray_API array in __multiarray_api.c, which is
generated together with __multiarray_api.h by the script
http://svn.scipy.org/svn/numpy/trunk/numpy/core/code_generators/generate_array_api.py

so instead of getting PyArray_Type directly, as in the noddy
example in boost_1_33_1/libs/python/test/m1.cpp, it's provided by 
the line:

#define PyArray_Type (*(PyTypeObject *)PyArray_API[2])
which you get when you include __multiarray_api.h

I think this indirection is causing problems for 
lvalue_from_pytype<extract_array_object, &PyArray_Type>();
since I can't get this to work either.

Specifically, I edited

/home/phil/install/boost_1_33_1/libs/python/test/m1.cpp  
(diff is appended below)

to add 

  struct extract_array_object
  {
      static PyArrayObject& execute(PyArrayObject& x)
      {
          return x;
      }
  };

and at line 223:

    lvalue_from_pytype<extract_array_object, &PyArray_Type>();


but g++ 3.4.4 is unhappy with the second argument:

pam1.cpp: In function `void init_module_m1()':
pam1.cpp:223: error: missing `>' to terminate the template argument list
pam1.cpp:223: error: template argument 2 is invalid
pam1.cpp:223: error: expected primary-expression before ')' token

I'm out of time to work on this, but what I was going to try next was
to switch to Numeric-24.2 (because it's a little simpler 
to install and understand), and  reproduce the problem.

In Numeric the pertinent files are

Numeric-24.2/Src/_numpymodule.c  which has:

    PyArray_API[PyArray_Type_NUM] = (void *)&PyArray_Type;

and Include/arrayobject.h which has the PyArray_Type define

#define PyArray_Type *(PyTypeObject *)PyArray_API[PyArray_Type_NUM]

To convince myself that it's a C++ problem I was going to try to
create an array using

PyObject_NEW(PyArrayObject, &PyArray_Type) as in Src/arrayobject.c

and then put out a a working example with a failing lvalue converter
and an appeal to people who know more about C++ than I do 
-- regards, Phil

~/install/boost_1_33_1/libs/python/test phil at gull% diff -crN m1.cpp new_m1.cpp
*** m1.cpp	2004-08-20 04:09:19.000000000 -0700
--- new_m1.cpp	2006-09-26 09:50:42.000000000 -0700
***************
*** 16,21 ****
--- 16,23 ----
  #include <string.h>
  #include "simple_type.hpp"
  #include "complicated.hpp"
+ //#include <numpy/noprefix.h>
+ #include <numpy/arrayobject.h>
  
  // Declare some straightforward extension types
  extern "C" void
***************
*** 48,53 ****
--- 50,57 ----
      0,          /*tp_hash */
  };
  
+ 
+ 
  // Create a Noddy containing 42
  PyObject* new_noddy()
  {
***************
*** 200,212 ****
  
  Unregistered* make_unregistered2(int) { return new Unregistered; }
  
! BOOST_PYTHON_MODULE(m1)
  {
      using namespace boost::python;
      using boost::shared_ptr;
      
      simple_to_python();
  
      lvalue_from_pytype<int_from_noddy,&NoddyType>();
  
      lvalue_from_pytype<
--- 204,227 ----
  
  Unregistered* make_unregistered2(int) { return new Unregistered; }
  
!   struct extract_array_object
!   {
!       static PyArrayObject& execute(PyArrayObject& x)
!       {
!           return x;
!       }
!   };
! 
! 
! BOOST_PYTHON_MODULE(pam1)
  {
      using namespace boost::python;
      using boost::shared_ptr;
      
      simple_to_python();
  
+     lvalue_from_pytype<extract_array_object, &PyArray_Type>();
+ 
      lvalue_from_pytype<int_from_noddy,&NoddyType>();
  
      lvalue_from_pytype<
~/install/boost_1_33_1/libs/python/test phil at gull% 




More information about the Cplusplus-sig mailing list