On Thu, 2022-07-07 at 22:37 +0000, lpsm...@uw.edu wrote: > Hello! I am maintaining a C++ codebase with extensive ties to Python > bindings (via SWIG). One of the features of the code is that we > define (in C) a subclass of a NumPy Array. Everything worked until > we started getting this message with numpy 1.23: > > RuntimeError: Object of type <class 'NamedArray'> appears to be C > subclassed NumPy array, void scalar, or allocated in a non-standard > way.NumPy reserves the right to change the size of these structures. > Projects are required to take this into account by either recompiling > against a specific NumPy version or padding the struct and enforcing > a maximum NumPy version. > > My problem is that I don't know how do to either of those things. I > would have assumed that whatever I compiled against, it would always > be compiled against a specific NumPy version, and I also assumed that > 'enforcing a maximum NumPy version' would happen in requirements.txt > for the Python package, but that also seems to not be the case. Any > hints? Thank you!
This should only happen if you compile against NumPy 1.19 and then run your code on NumPy 1.20+. (The warning is quite a lot older than 1.23 so I am surprised about you mentioning 1.23 specifically.) Of course you also have to compile with the oldest NumPy version you wish to support, so that would be a normal thing. If you don't find the pattern for extending the `PyArrayObject` struct maybe you can share a bit of the code (we can do that off-list if necessary). In principle the warning could be triggered by any bad memory access, but it seems unlikely... The normal reason for this (or what the warning tries to inform you about), is that somewhere in the code you should have the following: typedef struct { PyArrayObject; /* some information you add: */ char *names; } NamedArrayObject; PyTypeObject NamedArray_Type = { .tp_basicsize = sizeof(NamedArrayObject); }; A quick hack would be just to add `void *numpy_reserved[2];` after the `PyArrayObject`, maybe as: typedef struct { void *reserved[2]; } numpy_array_padding; typedef struct { PyArrayObject; numpy_array_padding; /* space for newer NumPy */ char *names; } NamedArrayObject; Then you can add a runtime check at module initialization: sizeof(PyArrayObject) + sizeof(numpy_array+padding) >= PyArray_Type.tp_basicsize To raise an error if a similar incompatibility arises in the future. (I say `void *reserved[2]` because we appended a single `void *` twice.) That padding could be done at run-time as well, but that is a bit trickier and maybe more hassle than worthwhile. Hope this helps fixing it quickly! Cheers, Sebastian > > -Lucian Smith > _______________________________________________ > NumPy-Discussion mailing list -- numpy-discussion@python.org > To unsubscribe send an email to numpy-discussion-le...@python.org > https://mail.python.org/mailman3/lists/numpy-discussion.python.org/ > Member address: sebast...@sipsolutions.net >
signature.asc
Description: This is a digitally signed message part
_______________________________________________ NumPy-Discussion mailing list -- numpy-discussion@python.org To unsubscribe send an email to numpy-discussion-le...@python.org https://mail.python.org/mailman3/lists/numpy-discussion.python.org/ Member address: arch...@mail-archive.com