大师兄的Python源码学习笔记(三十): 运行环境初始化(二)
大师兄的Python源码学习笔记(三十二): 运行环境初始化(四)
2. 创建sys module
2.1 sys module的备份
- 在__builtin__ module之后,Python会用同样的流程设置sys module,并像设置interp->builtins一样设置interp->sysdict。
Python\pylifecycle.c
static _PyInitError
new_interpreter(PyThreadState **tstate_p)
{
PyInterpreterState *interp;
PyThreadState *tstate, *save_tstate;
PyObject *bimod, *sysmod;
_PyInitError err;
... ...
sysmod = _PyImport_FindBuiltin("sys", modules);
if (sysmod != NULL) {
interp->sysdict = PyModule_GetDict(sysmod);
if (interp->sysdict == NULL)
goto handle_error;
Py_INCREF(interp->sysdict);
PyDict_SetItemString(interp->sysdict, "modules", modules);
... ...
}
- 通过_PyImport_FindBuiltin创建sys module,并通过_PyImport_FindExtensionObjectEx将其备份:
Python\import.c
PyObject *
_PyImport_FindBuiltin(const char *name, PyObject *modules)
{
PyObject *res, *nameobj;
nameobj = PyUnicode_InternFromString(name);
if (nameobj == NULL)
return NULL;
res = _PyImport_FindExtensionObjectEx(nameobj, nameobj, modules);
Py_DECREF(nameobj);
return res;
}
Python\import.c
static PyObject *extensions = NULL;
... ...
PyObject *
_PyImport_FindExtensionObjectEx(PyObject *name, PyObject *filename,
PyObject *modules)
{
PyObject *mod, *mdict, *key;
PyModuleDef* def;
if (extensions == NULL)
return NULL;
key = PyTuple_Pack(2, filename, name);
if (key == NULL)
return NULL;
def = (PyModuleDef *)PyDict_GetItem(extensions, key);
Py_DECREF(key);
if (def == NULL)
return NULL;
if (def->m_size == -1) {
/* Module does not support repeated initialization */
if (def->m_base.m_copy == NULL)
return NULL;
mod = _PyImport_AddModuleObject(name, modules);
if (mod == NULL)
return NULL;
mdict = PyModule_GetDict(mod);
if (mdict == NULL)
return NULL;
if (PyDict_Update(mdict, def->m_base.m_copy))
return NULL;
}
else {
if (def->m_base.m_init == NULL)
return NULL;
mod = def->m_base.m_init();
if (mod == NULL)
return NULL;
if (PyObject_SetItem(modules, name, mod) == -1) {
Py_DECREF(mod);
return NULL;
}
Py_DECREF(mod);
}
if (_PyState_AddModule(mod, def) < 0) {
PyMapping_DelItem(modules, name);
Py_DECREF(mod);
return NULL;
}
if (Py_VerboseFlag)
PySys_FormatStderr("import %U # previously loaded (%R)\n",
name, filename);
return mod;
}
- 从上一段代码可以看出,Python内部维护了一个全局变量extensions,它是一个PyDictObject对象,用于维护所有已经被Python加载的module中的PyDictObject的一个备份。
- 当Python系统的module集合中的某个标准扩展module被删除后不久又被重新加载时,Python不需要再次初始化这些module,而是从extensions中备份的PyDictObject对象来创建一个新的module即可。
- 这也说明了为什么Python中的标准扩展module是不会在运行时动态改变的。
- 在完成了__builtin__和sys两个module对象的设置之后,PyInterpreterState对象和PyThreadState对象在内存中如上图所示。
- 注意,与之前的源码相同,在上图中__builtins__和sys指向的是PyDictObject对象,而不是PyModuleObject对象。
2.2 设置module的搜索路径
- Python在创建了sys module之后,会在其中设置一个搜索module时的默认搜索路径集合。
Python\sysmodule.c
void
PySys_SetPath(const wchar_t *path)
{
PyObject *v;
if ((v = makepathobject(path, DELIM)) == NULL)
Py_FatalError("can't create sys.path");
if (_PySys_SetObjectId(&PyId_path, v) != 0)
Py_FatalError("can't assign sys.path");
Py_DECREF(v);
}
Python\sysmodule.c
static PyObject *
makepathobject(const wchar_t *path, wchar_t delim)
{
int i, n;
const wchar_t *p;
PyObject *v, *w;
n = 1;
p = path;
while ((p = wcschr(p, delim)) != NULL) {
n++;
p++;
}
v = PyList_New(n);
if (v == NULL)
return NULL;
for (i = 0; ; i++) {
p = wcschr(path, delim);
if (p == NULL)
p = path + wcslen(path); /* End of string */
w = PyUnicode_FromWideChar(path, (Py_ssize_t)(p - path));
if (w == NULL) {
Py_DECREF(v);
return NULL;
}
PyList_SET_ITEM(v, i, w);
if (*p == '\0')
break;
path = p+1;
}
return v;
}
Python\sysmodule.c
int
_PySys_SetObjectId(_Py_Identifier *key, PyObject *v)
{
PyThreadState *tstate = PyThreadState_GET();
PyObject *sd = tstate->interp->sysdict;
if (v == NULL) {
if (_PyDict_GetItemId(sd, key) == NULL)
return 0;
else
return _PyDict_DelItemId(sd, key);
}
else
return _PyDict_SetItemId(sd, key, v);
}
- 在makepathobject中,Python会创建一个PyListObject对象,这个list中包含了一组PyStringObject对象,每一个PyStringObject对象的内容就是一个module的搜索路径。
- 最终,这个PyListObject对象会在_PySys_SetObjectId中被插入到interp->sysdict,也就是sys module维护的PyDictObject对象中。
- Python随后还会进行一些琐碎的动作,其中包括初始化import环境,初始化内建异常。
Python\pylifecycle.c
_PyInitError
_Py_InitializeCore_impl(PyInterpreterState **interp_p,
const _PyCoreConfig *core_config)
{
PyInterpreterState *interp;
_PyInitError err;
... ...
err = _PyImport_Init(interp);
... ...
}
Python\pylifecycle.c
static _PyInitError
new_interpreter(PyThreadState **tstate_p)
{
PyInterpreterState *interp;
PyThreadState *tstate, *save_tstate;
PyObject *bimod, *sysmod;
_PyInitError err;
... ...
bimod = _PyImport_FindBuiltin("builtins", modules);
if (bimod != NULL) {
interp->builtins = PyModule_GetDict(bimod);
if (interp->builtins == NULL)
goto handle_error;
Py_INCREF(interp->builtins);
}
else if (PyErr_Occurred()) {
goto handle_error;
}
/* initialize builtin exceptions */
_PyExc_Init(bimod);
... ...
}
网友评论