ยปCore Development>Code coverage>Python/importdl.c

Python code coverage for Python/importdl.c

#countcontent
1n/a
2n/a/* Support for dynamic loading of extension modules */
3n/a
4n/a#include "Python.h"
5n/a
6n/a/* ./configure sets HAVE_DYNAMIC_LOADING if dynamic loading of modules is
7n/a supported on this platform. configure will then compile and link in one
8n/a of the dynload_*.c files, as appropriate. We will call a function in
9n/a those modules to get a function pointer to the module's init function.
10n/a*/
11n/a#ifdef HAVE_DYNAMIC_LOADING
12n/a
13n/a#include "importdl.h"
14n/a
15n/a#ifdef MS_WINDOWS
16n/aextern dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix,
17n/a const char *shortname,
18n/a PyObject *pathname,
19n/a FILE *fp);
20n/a#else
21n/aextern dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix,
22n/a const char *shortname,
23n/a const char *pathname, FILE *fp);
24n/a#endif
25n/a
26n/astatic const char * const ascii_only_prefix = "PyInit";
27n/astatic const char * const nonascii_prefix = "PyInitU";
28n/a
29n/a/* Get the variable part of a module's export symbol name.
30n/a * Returns a bytes instance. For non-ASCII-named modules, the name is
31n/a * encoded as per PEP 489.
32n/a * The hook_prefix pointer is set to either ascii_only_prefix or
33n/a * nonascii_prefix, as appropriate.
34n/a */
35n/astatic PyObject *
36n/aget_encoded_name(PyObject *name, const char **hook_prefix) {
37n/a PyObject *tmp;
38n/a PyObject *encoded = NULL;
39n/a PyObject *modname = NULL;
40n/a Py_ssize_t name_len, lastdot;
41n/a _Py_IDENTIFIER(replace);
42n/a
43n/a /* Get the short name (substring after last dot) */
44n/a name_len = PyUnicode_GetLength(name);
45n/a lastdot = PyUnicode_FindChar(name, '.', 0, name_len, -1);
46n/a if (lastdot < -1) {
47n/a return NULL;
48n/a } else if (lastdot >= 0) {
49n/a tmp = PyUnicode_Substring(name, lastdot + 1, name_len);
50n/a if (tmp == NULL)
51n/a return NULL;
52n/a name = tmp;
53n/a /* "name" now holds a new reference to the substring */
54n/a } else {
55n/a Py_INCREF(name);
56n/a }
57n/a
58n/a /* Encode to ASCII or Punycode, as needed */
59n/a encoded = PyUnicode_AsEncodedString(name, "ascii", NULL);
60n/a if (encoded != NULL) {
61n/a *hook_prefix = ascii_only_prefix;
62n/a } else {
63n/a if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) {
64n/a PyErr_Clear();
65n/a encoded = PyUnicode_AsEncodedString(name, "punycode", NULL);
66n/a if (encoded == NULL) {
67n/a goto error;
68n/a }
69n/a *hook_prefix = nonascii_prefix;
70n/a } else {
71n/a goto error;
72n/a }
73n/a }
74n/a
75n/a /* Replace '-' by '_' */
76n/a modname = _PyObject_CallMethodId(encoded, &PyId_replace, "cc", '-', '_');
77n/a if (modname == NULL)
78n/a goto error;
79n/a
80n/a Py_DECREF(name);
81n/a Py_DECREF(encoded);
82n/a return modname;
83n/aerror:
84n/a Py_DECREF(name);
85n/a Py_XDECREF(encoded);
86n/a return NULL;
87n/a}
88n/a
89n/aPyObject *
90n/a_PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp)
91n/a{
92n/a#ifndef MS_WINDOWS
93n/a PyObject *pathbytes = NULL;
94n/a#endif
95n/a PyObject *name_unicode = NULL, *name = NULL, *path = NULL, *m = NULL;
96n/a const char *name_buf, *hook_prefix;
97n/a const char *oldcontext;
98n/a dl_funcptr exportfunc;
99n/a PyModuleDef *def;
100n/a PyObject *(*p0)(void);
101n/a
102n/a name_unicode = PyObject_GetAttrString(spec, "name");
103n/a if (name_unicode == NULL) {
104n/a return NULL;
105n/a }
106n/a
107n/a name = get_encoded_name(name_unicode, &hook_prefix);
108n/a if (name == NULL) {
109n/a goto error;
110n/a }
111n/a name_buf = PyBytes_AS_STRING(name);
112n/a
113n/a path = PyObject_GetAttrString(spec, "origin");
114n/a if (path == NULL)
115n/a goto error;
116n/a
117n/a#ifdef MS_WINDOWS
118n/a exportfunc = _PyImport_FindSharedFuncptrWindows(hook_prefix, name_buf,
119n/a path, fp);
120n/a#else
121n/a pathbytes = PyUnicode_EncodeFSDefault(path);
122n/a if (pathbytes == NULL)
123n/a goto error;
124n/a exportfunc = _PyImport_FindSharedFuncptr(hook_prefix, name_buf,
125n/a PyBytes_AS_STRING(pathbytes),
126n/a fp);
127n/a Py_DECREF(pathbytes);
128n/a#endif
129n/a
130n/a if (exportfunc == NULL) {
131n/a if (!PyErr_Occurred()) {
132n/a PyObject *msg;
133n/a msg = PyUnicode_FromFormat(
134n/a "dynamic module does not define "
135n/a "module export function (%s_%s)",
136n/a hook_prefix, name_buf);
137n/a if (msg == NULL)
138n/a goto error;
139n/a PyErr_SetImportError(msg, name_unicode, path);
140n/a Py_DECREF(msg);
141n/a }
142n/a goto error;
143n/a }
144n/a
145n/a p0 = (PyObject *(*)(void))exportfunc;
146n/a
147n/a /* Package context is needed for single-phase init */
148n/a oldcontext = _Py_PackageContext;
149n/a _Py_PackageContext = PyUnicode_AsUTF8(name_unicode);
150n/a if (_Py_PackageContext == NULL) {
151n/a _Py_PackageContext = oldcontext;
152n/a goto error;
153n/a }
154n/a m = p0();
155n/a _Py_PackageContext = oldcontext;
156n/a
157n/a if (m == NULL) {
158n/a if (!PyErr_Occurred()) {
159n/a PyErr_Format(
160n/a PyExc_SystemError,
161n/a "initialization of %s failed without raising an exception",
162n/a name_buf);
163n/a }
164n/a goto error;
165n/a } else if (PyErr_Occurred()) {
166n/a PyErr_Clear();
167n/a PyErr_Format(
168n/a PyExc_SystemError,
169n/a "initialization of %s raised unreported exception",
170n/a name_buf);
171n/a m = NULL;
172n/a goto error;
173n/a }
174n/a if (Py_TYPE(m) == NULL) {
175n/a /* This can happen when a PyModuleDef is returned without calling
176n/a * PyModuleDef_Init on it
177n/a */
178n/a PyErr_Format(PyExc_SystemError,
179n/a "init function of %s returned uninitialized object",
180n/a name_buf);
181n/a m = NULL; /* prevent segfault in DECREF */
182n/a goto error;
183n/a }
184n/a if (PyObject_TypeCheck(m, &PyModuleDef_Type)) {
185n/a Py_DECREF(name_unicode);
186n/a Py_DECREF(name);
187n/a Py_DECREF(path);
188n/a return PyModule_FromDefAndSpec((PyModuleDef*)m, spec);
189n/a }
190n/a
191n/a /* Fall back to single-phase init mechanism */
192n/a
193n/a if (hook_prefix == nonascii_prefix) {
194n/a /* don't allow legacy init for non-ASCII module names */
195n/a PyErr_Format(
196n/a PyExc_SystemError,
197n/a "initialization of * did not return PyModuleDef",
198n/a name_buf);
199n/a goto error;
200n/a }
201n/a
202n/a /* Remember pointer to module init function. */
203n/a def = PyModule_GetDef(m);
204n/a if (def == NULL) {
205n/a PyErr_Format(PyExc_SystemError,
206n/a "initialization of %s did not return an extension "
207n/a "module", name_buf);
208n/a goto error;
209n/a }
210n/a def->m_base.m_init = p0;
211n/a
212n/a /* Remember the filename as the __file__ attribute */
213n/a if (PyModule_AddObject(m, "__file__", path) < 0)
214n/a PyErr_Clear(); /* Not important enough to report */
215n/a else
216n/a Py_INCREF(path);
217n/a
218n/a if (_PyImport_FixupExtensionObject(m, name_unicode, path) < 0)
219n/a goto error;
220n/a
221n/a Py_DECREF(name_unicode);
222n/a Py_DECREF(name);
223n/a Py_DECREF(path);
224n/a
225n/a return m;
226n/a
227n/aerror:
228n/a Py_DECREF(name_unicode);
229n/a Py_XDECREF(name);
230n/a Py_XDECREF(path);
231n/a Py_XDECREF(m);
232n/a return NULL;
233n/a}
234n/a
235n/a#endif /* HAVE_DYNAMIC_LOADING */