views:

44

answers:

2

I'm working on making my first Python C extension, which defines a few functions and custom types. The strange thing is that the custom types are working, but not the regular functions. The top-level MyModule.c file looks like this:

static PyMethodDef MyModule_methods[] = {
    {"doStuff", MyModule_doStuff, METH_VARARGS, ""},
    {NULL, NULL, 0, NULL} /* Sentinel */
};

static struct PyModuleDef MyModule_module = {
    PyModuleDef_HEAD_INIT,
    "mymodule",
    "Documentation",
    -1,
    MyModule_methods
};

PyMODINIT_FUNC PyInit_audioDevice(void) {
    PyObject *object = PyModule_Create(&MyModule_module);
    if(object == NULL) {
        return NULL;
    }

    if(PyType_Ready(&MyCustomType_type) < 0) {
        return NULL;
    }

    Py_INCREF(&MyCustomType_type);
    PyModule_AddObject(object, "MyCustomType", (PyObject*)&MyCustomType_type);

    return object;
}

I'm building the extension with this setup.py file:

from distutils.core import setup, Extension
setup(name = "mymodule",
      version = "1.0",
      ext_modules = [Extension("mymodule", ["MyModule.c", "MyCustomType.c", "DoStuff.c"])])

The "DoStuff" file defines its function as such:

static PyObject*
AudioOutputOSX_doStuff(PyObject *self, PyObject *args) {
  printf("Hello from doStuff\n");
  return Py_None;
}

The funny thing is that the MyCustomType type works fine, as I can instantiate it with:

from mymodule.MyCustomType import MyCustomType
foo = MyCustomType()

And I see my printf() statements from the custom type's new and init methods printed out. However, this code fails:

import mymodule
mymodule.doStuff()

I get the following error: Traceback (most recent call last): File "MyModuleTest.py", line 9, in mymodule.doStuff(buffer) AttributeError: 'module' object has no attribute 'doStuff'

What is going on here? Do I have some error in my module's method declarations somehow?

A: 

What do you see if you do import mymodule followed by print(dir(mymodule)) ?

Is your module really large enough to be split over 3 files? Splitting does add a whole lot of complexity with the linking ... name-mangling, perhaps?

AudioOutputOSX_doStuff versus MyModule_doStuff ... a real problem, or just a question-editing problem?

What platform, what compiler?

John Machin
+2  A: 

The fact that this code works:

from mymodule.MyCustomType import MyCustomType

is absolutely astonishing and tells us that mymodule is actually a package, and MyCustomType a module within that package (which contains a type or class by the same name).

Therefore, to call the function, you'll obviously have to do:

from mymodule import MyCustomType as therealmodule
therealmodule.doStuff()

or the like -- assuming the info you give us, particularly that first line of code which I've quoted from code you say works, is indeed exact.

Alex Martelli