CPython v3.12.1 源码学习Windows篇(一)

        

(本文路径均从项目根目录下出发)

入口文件是Programs/python.c:

Windows会走wmain,主要是处理宽字符问题:

最后都会进pymain_main这个函数:

pymain_init(args)内部:

初始化工作,包括执行_PyRuntime_Initialize()、PyPreConfig_InitPythonConfig(&preconfig)、_Py_PreInitializeFromPyArgv(&preconfig, args)、PyConfig_InitPythonConfig(&config)、PyConfig_SetArgv(&config, args->argc, args->wchar_argv),函数里PyConfig类型的config变量很重要,它读取命令行参数、环境变量和配置文件,继续往下走,Py_InitializeFromConfig(&config),status作为一个PyState用来判断错误。这里有无异常都会进行config的clear内存释放,虽然这里config是栈变量,但其内部包含了指向堆的指针,需保证动态分配的内存也被正确释放,否则config被自动释放后,堆上的内存可能没引用但也没释放(内存泄漏

以下是关于PyState判断用到的宏函数(不止这三个):

Py_RunMain():

Py_RunMain主要就是内部调用了pymain_run_python(&exitcode):

pymain_run_python(&exitcode):

拿到了PyInterpreterState(通过当前线程拿到的)和config,断言是因为下面才开始设置Python中的sys.path,此前如果不为空说明有问题。

下面要开始设置sys.path了,也就python找包的搜索路径:

它先判断run_filename是否是一个包含__main__.py的目录,如果是,待会它会优先设置它到sys.path[0],但只是优先,在此之前还要做一个事情。      

  

往下走可以看到,这里在设置sys.path之前先去导入readline和rlcompetor,防止后续因为命名冲突的问题不能导入这两个模块,当然这里也不一定会导入,pymain_import_readline内部会判断是否是交互式启动而选择性导入这两个模块。

然后就是设置sys.path[0]的部分,可以看到

刚刚如果你的fun_filename满足要求,这里会被优先设置为sys.path[0]。而且这里生成的目录名(如果是else if分支会被去掉文件名,只保留完整路径,相对路径也会被转换为绝对路径)是PyObject了(猜测应该是PyUnicode_Type),不会再存为C的宽字符wchar或字符char。

下面就是检查了一次path0,然后将其赋值给了interp->runtime->sys_path_0和interp->sysdict这个字典的"path"键的项,它就是Python层面的sys.path,然后插入到0号位置。

sys.path[0]设置好之后,再下来

关注一下_PyInterpreterState_SetRunningMain函数即可,它会将拿到当前的执行线程,并将当前解释器的threads_main指向这个线程,注意线程在此之前已经指向了这个解释器,所以在函数内部他还会判断下,这个是不是一一对应关系,如果不是会报错

下一篇文章,我们就将进入

看一看我们的脚本是如何被解释和运行的。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值