Reputation: 40380
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?
Upvotes: 0
Views: 769
Reputation: 881555
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.
Upvotes: 2
Reputation: 82924
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?
Upvotes: 0