Hello,
I've found an issue with class module names, which do not respect the package
hierarchy.
With foo.py containing:
class Foo:
pass
>>> import foo
>>> foo
<module 'foo' from 'foo.py'>
>>> foo.Foo().__module__
'foo'
Now compiled through Cython:
>>> import foo
>>> foo
<module 'foo' from 'foo.pyd'>
>>> foo.Foo().__module__
'foo'
Same behaviour. Perfect.
Now if I move it into a package:
>>> import pkg.foo
>>> pkg.foo
<module 'pkg.foo' from 'pkg\foo.pyc'>
>>> pkg.foo.Foo().__module__
'pkg.foo'
And through Cython:
>>> import pkg.foo
>>> pkg.foo
<module 'pkg.foo' from 'pkg\foo.pyd'>
>>> pkg.foo.Foo().__module__
'foo' ### ERROR: should have been 'pkg.foo'
To solve it, I patch the generated code to get the module name through the
module:
static PyObject *__Pyx_CreateClass(
PyObject *bases, PyObject *dict, PyObject *name, char *modname) {
PyObject *py_modname;
PyObject *result = 0;
#if PY_MAJOR_VERSION < 3
//SD py_modname = PyString_FromString(modname)
py_modname = PyObject_GetAttrString(__pyx_m, "__name__");
#else
py_modname = PyUnicode_FromString(modname);
#endif
if (!py_modname)
goto bad;
if (PyDict_SetItemString(dict, "__module__", py_modname) < 0)
goto bad;
#if PY_MAJOR_VERSION < 3
result = PyClass_New(bases, dict, name);
#else
result = PyObject_CallFunctionObjArgs((PyObject *)&PyType_Type, name,
bases, dict, NULL);
#endif
bad:
Py_XDECREF(py_modname);
return result;
}
Notes:
- I assume the patch is also compatible with 3.x, but I haven't tested it.
- parameter "modname" is no more needed.
- I could have patched Cython directly, but it's simpler for me to "sed" the
generated code.
Cheers,
Stephane
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev