[Numpy-discussion] Optionally using Numeric in another compiled extension package.

Jack Jansen Jack.Jansen at oratrix.com
Wed Jan 15 14:18:05 CST 2003

On woensdag, jan 15, 2003, at 19:01 Europe/Amsterdam, Chris Barker 

> Paul F Dubois wrote:
>> If you could do:
>> try:
>>     import Numeric
>>     haveNumeric = 1
>> except:
>>     haveNumeric = 0
>> in some initialization routine, then you could use this flag.
>> Alternately you could test on the fly
>> 'Numeric' in [m.__name__ for m in sys.modules]
> Thanks, but I'm talking about doing this at the C++ level in an
> extension package, not at the Python level. This kind of thing is Soo
> much easier in Python, of course!

This can be done, but it is difficult, and you need the cooperation of 
both parties (Numeric and wxPython, in this case). The problem is that 
you need a way to pass C pointers from one extension module to the 
other. One of the pointers you want to pass is the PyTypeObject, so you 
can check that an object passed in from Python is of the correct type. 
Another is the address of some C routine that will get you a C pointer 
to the data. The first one may be visible from Python (so you can get 
at it through normal means) but the second one won't be.

The dirty way to do this (and you should probably avoid this) is to put 
these pointers into Python integers in the supplying module, and put 
them in the module namespace with a funny name 
(__ConvertToCPointerAddress). In wxPython you import Numeric, and if it 
succeeds you look up the funny name, convert the Python integer to a C 
pointer, cross your fingers, and call the address.

A cleaner way to do this is with cobject objects. These are in the 
core, in Objects/cobject.c. Numeric exports a cobject (again named 
__ConvertToCPointerAddress) with the address of the routine as the 
value. But, and this is the nice bit, cobjects can be passed along by 
Python code but can't be fiddled with. And cobject.c even provides a C 
function PyCObject_Import(char *modulename, char *attributename) which 
directly returns you the pointer you're looking for by importing the 
module, looking up the name, checking that it's a cobject and 
extracting the value.

And it even has support for "protocols": Cobjects have an extra field 
called the description, again only settable and readable from C. 
Modules that don't know about each others' existence could still decide 
on a common description that would signify that the pointer in the 
cobject has a specific meaning. We could decide here that if the 
description is the C string "this pointer is a function that you pass 
one Python object and that returns the data just as Numeric would store 
it" would fit that bill, and anyone in the world writing an extension 
module could follow the protocol.
- Jack Jansen        <Jack.Jansen at oratrix.com>        
http://www.cwi.nl/~jack -
- If I can't dance I don't want to be part of your revolution -- Emma 
Goldman -

More information about the Numpy-discussion mailing list