Kaydet (Commit) 2e58ff3e authored tarafından Guido van Rossum's avatar Guido van Rossum

Fix importing of shared libraries from inside packages.

This is a bit of a hack: when the shared library is loaded, the module
name is "package.module", but the module calls Py_InitModule*() with just
"module" for the name.  The shared library loader squirrels away the true
name of the module in _Py_PackageContext, and Py_InitModule*() will
substitute this (if the name actually matches).
üst ee6fd1c3
...@@ -233,6 +233,7 @@ _PyImport_LoadDynamicModule(name, pathname, fp) ...@@ -233,6 +233,7 @@ _PyImport_LoadDynamicModule(name, pathname, fp)
#else #else
PyObject *m, *d, *s; PyObject *m, *d, *s;
char funcname[258]; char funcname[258];
char *lastdot, *shortname, *packagecontext;
dl_funcptr p = NULL; dl_funcptr p = NULL;
#ifdef USE_SHLIB #ifdef USE_SHLIB
static struct { static struct {
...@@ -252,7 +253,16 @@ _PyImport_LoadDynamicModule(name, pathname, fp) ...@@ -252,7 +253,16 @@ _PyImport_LoadDynamicModule(name, pathname, fp)
Py_INCREF(m); Py_INCREF(m);
return m; return m;
} }
sprintf(funcname, FUNCNAME_PATTERN, name); lastdot = strrchr(name, '.');
if (lastdot == NULL) {
packagecontext = NULL;
shortname = name;
}
else {
packagecontext = name;
shortname = lastdot+1;
}
sprintf(funcname, FUNCNAME_PATTERN, shortname);
#ifdef USE_SHLIB #ifdef USE_SHLIB
if (fp != NULL) { if (fp != NULL) {
int i; int i;
...@@ -519,11 +529,14 @@ _PyImport_LoadDynamicModule(name, pathname, fp) ...@@ -519,11 +529,14 @@ _PyImport_LoadDynamicModule(name, pathname, fp)
got_it: got_it:
#endif #endif
if (p == NULL) { if (p == NULL) {
PyErr_SetString(PyExc_ImportError, PyErr_Format(PyExc_ImportError,
"dynamic module does not define init function"); "dynamic module does not define init function (%s)",
funcname);
return NULL; return NULL;
} }
_Py_PackageContext = packagecontext;
(*p)(); (*p)();
_Py_PackageContext = NULL;
if (PyErr_Occurred()) if (PyErr_Occurred())
return NULL; return NULL;
if (_PyImport_FixupExtension(name, pathname) == NULL) if (_PyImport_FixupExtension(name, pathname) == NULL)
......
...@@ -39,6 +39,9 @@ typedef extended va_double; ...@@ -39,6 +39,9 @@ typedef extended va_double;
typedef double va_double; typedef double va_double;
#endif #endif
/* Package context -- the full module name for package imports */
char *_Py_PackageContext = NULL;
/* Py_InitModule4() parameters: /* Py_InitModule4() parameters:
- name is the module name - name is the module name
- methods is the list of top-level functions - methods is the list of top-level functions
...@@ -69,6 +72,13 @@ Py_InitModule4(name, methods, doc, passthrough, module_api_version) ...@@ -69,6 +72,13 @@ Py_InitModule4(name, methods, doc, passthrough, module_api_version)
if (module_api_version != PYTHON_API_VERSION) if (module_api_version != PYTHON_API_VERSION)
fprintf(stderr, api_version_warning, fprintf(stderr, api_version_warning,
name, PYTHON_API_VERSION, name, module_api_version); name, PYTHON_API_VERSION, name, module_api_version);
if (_Py_PackageContext != NULL) {
char *p = strrchr(_Py_PackageContext, '.');
if (p != NULL && strcmp(name, p+1) == 0) {
name = _Py_PackageContext;
_Py_PackageContext = NULL;
}
}
if ((m = PyImport_AddModule(name)) == NULL) if ((m = PyImport_AddModule(name)) == NULL)
return NULL; return NULL;
d = PyModule_GetDict(m); d = PyModule_GetDict(m);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment