mirror of
https://github.com/python/cpython.git
synced 2025-10-16 19:57:59 +00:00
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).
This commit is contained in:
parent
ee6fd1c392
commit
2e58ff3ef5
2 changed files with 26 additions and 3 deletions
|
@ -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)
|
||||||
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)
|
||||||
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;
|
||||||
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)
|
||||||
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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue