|
4 | 4 |
|
5 | 5 | #include "Python-ast.h"
|
6 | 6 | #undef Yield /* undefine macro conflicting with <winbase.h> */
|
| 7 | +#include "pycore_import.h" // _PyImport_BootstrapImp() |
7 | 8 | #include "pycore_initconfig.h"
|
8 | 9 | #include "pycore_pyerrors.h"
|
9 | 10 | #include "pycore_pyhash.h"
|
@@ -978,84 +979,80 @@ PyImport_GetImporter(PyObject *path)
|
978 | 979 | return importer;
|
979 | 980 | }
|
980 | 981 |
|
981 |
| -/*[clinic input] |
982 |
| -_imp.create_builtin |
983 |
| -
|
984 |
| - spec: object |
985 |
| - / |
986 |
| -
|
987 |
| -Create an extension module. |
988 |
| -[clinic start generated code]*/ |
989 |
| - |
990 |
| -static PyObject * |
991 |
| -_imp_create_builtin(PyObject *module, PyObject *spec) |
992 |
| -/*[clinic end generated code: output=ace7ff22271e6f39 input=37f966f890384e47]*/ |
| 982 | +static PyObject* |
| 983 | +create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec) |
993 | 984 | {
|
994 |
| - PyThreadState *tstate = _PyThreadState_GET(); |
995 |
| - struct _inittab *p; |
996 |
| - PyObject *name; |
997 |
| - const char *namestr; |
998 |
| - PyObject *mod; |
999 |
| - |
1000 |
| - name = PyObject_GetAttrString(spec, "name"); |
1001 |
| - if (name == NULL) { |
1002 |
| - return NULL; |
1003 |
| - } |
1004 |
| - |
1005 |
| - mod = _PyImport_FindExtensionObject(name, name); |
| 985 | + PyObject *mod = _PyImport_FindExtensionObject(name, name); |
1006 | 986 | if (mod || _PyErr_Occurred(tstate)) {
|
1007 |
| - Py_DECREF(name); |
1008 | 987 | Py_XINCREF(mod);
|
1009 | 988 | return mod;
|
1010 | 989 | }
|
1011 | 990 |
|
1012 |
| - namestr = PyUnicode_AsUTF8(name); |
1013 |
| - if (namestr == NULL) { |
1014 |
| - Py_DECREF(name); |
1015 |
| - return NULL; |
1016 |
| - } |
1017 |
| - |
1018 | 991 | PyObject *modules = tstate->interp->modules;
|
1019 |
| - for (p = PyImport_Inittab; p->name != NULL; p++) { |
1020 |
| - PyModuleDef *def; |
| 992 | + for (struct _inittab *p = PyImport_Inittab; p->name != NULL; p++) { |
1021 | 993 | if (_PyUnicode_EqualToASCIIString(name, p->name)) {
|
1022 | 994 | if (p->initfunc == NULL) {
|
1023 | 995 | /* Cannot re-init internal module ("sys" or "builtins") */
|
1024 |
| - mod = PyImport_AddModule(namestr); |
1025 |
| - Py_DECREF(name); |
1026 |
| - return mod; |
| 996 | + return PyImport_AddModuleObject(name); |
1027 | 997 | }
|
| 998 | + |
1028 | 999 | mod = (*p->initfunc)();
|
1029 | 1000 | if (mod == NULL) {
|
1030 |
| - Py_DECREF(name); |
1031 | 1001 | return NULL;
|
1032 | 1002 | }
|
| 1003 | + |
1033 | 1004 | if (PyObject_TypeCheck(mod, &PyModuleDef_Type)) {
|
1034 |
| - Py_DECREF(name); |
1035 | 1005 | return PyModule_FromDefAndSpec((PyModuleDef*)mod, spec);
|
1036 |
| - } else { |
| 1006 | + } |
| 1007 | + else { |
1037 | 1008 | /* Remember pointer to module init function. */
|
1038 |
| - def = PyModule_GetDef(mod); |
| 1009 | + PyModuleDef *def = PyModule_GetDef(mod); |
1039 | 1010 | if (def == NULL) {
|
1040 |
| - Py_DECREF(name); |
1041 | 1011 | return NULL;
|
1042 | 1012 | }
|
| 1013 | + |
1043 | 1014 | def->m_base.m_init = p->initfunc;
|
1044 | 1015 | if (_PyImport_FixupExtensionObject(mod, name, name,
|
1045 | 1016 | modules) < 0) {
|
1046 |
| - Py_DECREF(name); |
1047 | 1017 | return NULL;
|
1048 | 1018 | }
|
1049 |
| - Py_DECREF(name); |
1050 | 1019 | return mod;
|
1051 | 1020 | }
|
1052 | 1021 | }
|
1053 | 1022 | }
|
1054 |
| - Py_DECREF(name); |
| 1023 | + |
| 1024 | + // not found |
1055 | 1025 | Py_RETURN_NONE;
|
1056 | 1026 | }
|
1057 | 1027 |
|
1058 | 1028 |
|
| 1029 | + |
| 1030 | +/*[clinic input] |
| 1031 | +_imp.create_builtin |
| 1032 | +
|
| 1033 | + spec: object |
| 1034 | + / |
| 1035 | +
|
| 1036 | +Create an extension module. |
| 1037 | +[clinic start generated code]*/ |
| 1038 | + |
| 1039 | +static PyObject * |
| 1040 | +_imp_create_builtin(PyObject *module, PyObject *spec) |
| 1041 | +/*[clinic end generated code: output=ace7ff22271e6f39 input=37f966f890384e47]*/ |
| 1042 | +{ |
| 1043 | + PyThreadState *tstate = _PyThreadState_GET(); |
| 1044 | + |
| 1045 | + PyObject *name = PyObject_GetAttrString(spec, "name"); |
| 1046 | + if (name == NULL) { |
| 1047 | + return NULL; |
| 1048 | + } |
| 1049 | + |
| 1050 | + PyObject *mod = create_builtin(tstate, name, spec); |
| 1051 | + Py_DECREF(name); |
| 1052 | + return mod; |
| 1053 | +} |
| 1054 | + |
| 1055 | + |
1059 | 1056 | /* Frozen modules */
|
1060 | 1057 |
|
1061 | 1058 | static const struct _frozen *
|
@@ -2127,46 +2124,88 @@ static PyMethodDef imp_methods[] = {
|
2127 | 2124 | };
|
2128 | 2125 |
|
2129 | 2126 |
|
2130 |
| -static struct PyModuleDef impmodule = { |
| 2127 | +static int |
| 2128 | +imp_module_exec(PyObject *module) |
| 2129 | +{ |
| 2130 | + const wchar_t *mode = _Py_GetConfig()->check_hash_pycs_mode; |
| 2131 | + PyObject *pyc_mode = PyUnicode_FromWideChar(mode, -1); |
| 2132 | + if (pyc_mode == NULL) { |
| 2133 | + return -1; |
| 2134 | + } |
| 2135 | + if (PyModule_AddObjectRef(module, "check_hash_based_pycs", pyc_mode) < 0) { |
| 2136 | + Py_DECREF(pyc_mode); |
| 2137 | + return -1; |
| 2138 | + } |
| 2139 | + Py_DECREF(pyc_mode); |
| 2140 | + |
| 2141 | + return 0; |
| 2142 | +} |
| 2143 | + |
| 2144 | + |
| 2145 | +static PyModuleDef_Slot imp_slots[] = { |
| 2146 | + {Py_mod_exec, imp_module_exec}, |
| 2147 | + {0, NULL} |
| 2148 | +}; |
| 2149 | + |
| 2150 | +static struct PyModuleDef imp_module = { |
2131 | 2151 | PyModuleDef_HEAD_INIT,
|
2132 |
| - "_imp", |
2133 |
| - doc_imp, |
2134 |
| - 0, |
2135 |
| - imp_methods, |
2136 |
| - NULL, |
2137 |
| - NULL, |
2138 |
| - NULL, |
2139 |
| - NULL |
| 2152 | + .m_name = "_imp", |
| 2153 | + .m_doc = doc_imp, |
| 2154 | + .m_size = 0, |
| 2155 | + .m_methods = imp_methods, |
| 2156 | + .m_slots = imp_slots, |
2140 | 2157 | };
|
2141 | 2158 |
|
2142 | 2159 | PyMODINIT_FUNC
|
2143 | 2160 | PyInit__imp(void)
|
2144 | 2161 | {
|
2145 |
| - PyObject *m, *d; |
| 2162 | + return PyModuleDef_Init(&imp_module); |
| 2163 | +} |
2146 | 2164 |
|
2147 |
| - m = PyModule_Create(&impmodule); |
2148 |
| - if (m == NULL) { |
2149 |
| - goto failure; |
| 2165 | + |
| 2166 | +// Import the _imp extension by calling manually _imp.create_builtin() and |
| 2167 | +// _imp.exec_builtin() since importlib is not initialized yet. Initializing |
| 2168 | +// importlib requires the _imp module: this function fix the bootstrap issue. |
| 2169 | +PyObject* |
| 2170 | +_PyImport_BootstrapImp(PyThreadState *tstate) |
| 2171 | +{ |
| 2172 | + PyObject *name = PyUnicode_FromString("_imp"); |
| 2173 | + if (name == NULL) { |
| 2174 | + return NULL; |
2150 | 2175 | }
|
2151 |
| - d = PyModule_GetDict(m); |
2152 |
| - if (d == NULL) { |
2153 |
| - goto failure; |
| 2176 | + |
| 2177 | + // Mock a ModuleSpec object just good enough for PyModule_FromDefAndSpec(): |
| 2178 | + // an object with just a name attribute. |
| 2179 | + // |
| 2180 | + // _imp.__spec__ is overriden by importlib._bootstrap._instal() anyway. |
| 2181 | + PyObject *attrs = Py_BuildValue("{sO}", "name", name); |
| 2182 | + if (attrs == NULL) { |
| 2183 | + goto error; |
| 2184 | + } |
| 2185 | + PyObject *spec = _PyNamespace_New(attrs); |
| 2186 | + Py_DECREF(attrs); |
| 2187 | + if (spec == NULL) { |
| 2188 | + goto error; |
2154 | 2189 | }
|
2155 | 2190 |
|
2156 |
| - const wchar_t *mode = _Py_GetConfig()->check_hash_pycs_mode; |
2157 |
| - PyObject *pyc_mode = PyUnicode_FromWideChar(mode, -1); |
2158 |
| - if (pyc_mode == NULL) { |
2159 |
| - goto failure; |
| 2191 | + // Create the _imp module from its definition. |
| 2192 | + PyObject *mod = create_builtin(tstate, name, spec); |
| 2193 | + Py_CLEAR(name); |
| 2194 | + Py_DECREF(spec); |
| 2195 | + if (mod == NULL) { |
| 2196 | + goto error; |
2160 | 2197 | }
|
2161 |
| - if (PyDict_SetItemString(d, "check_hash_based_pycs", pyc_mode) < 0) { |
2162 |
| - Py_DECREF(pyc_mode); |
2163 |
| - goto failure; |
| 2198 | + assert(mod != Py_None); // not found |
| 2199 | + |
| 2200 | + // Execute the _imp module: call imp_module_exec(). |
| 2201 | + if (exec_builtin_or_dynamic(mod) < 0) { |
| 2202 | + Py_DECREF(mod); |
| 2203 | + goto error; |
2164 | 2204 | }
|
2165 |
| - Py_DECREF(pyc_mode); |
| 2205 | + return mod; |
2166 | 2206 |
|
2167 |
| - return m; |
2168 |
| - failure: |
2169 |
| - Py_XDECREF(m); |
| 2207 | +error: |
| 2208 | + Py_XDECREF(name); |
2170 | 2209 | return NULL;
|
2171 | 2210 | }
|
2172 | 2211 |
|
|
0 commit comments