3. 存储库布局
3. 存储库布局
CPython 存储库围绕解释器的主要子系统进行组织:对象实现、运行时机制、编译器管道、解析器、内置模块、标准库、测试、文档和平台构建文件。
好的第一步是将源代码树视为职责地图。```text cpython/ Include/ Objects/ Python/ Parser/ Modules/ Lib/ Programs/ Tools/ Doc/ Grammar/ PC/ PCbuild/ Mac/
## 3.1 顶层结构
|目录 |主要角色|
| ----------- | --------------------------------------------------- |
|`Include/`|公共、内部和私有 C 头文件 |
|`Objects/`|核心对象类型的实现 |
|`Python/`|运行时、编译器、解释器循环、初始化 |
|`Parser/`|分词器和解析器支持代码 |
|`Grammar/`|语法输入文件 |
|`Modules/`|用 C 编写的内置和扩展模块 |
|`Lib/`| Python标准库|
|`Lib/test/`| CPython 回归测试套件 |
|`Programs/`|可执行入口点|
|`Tools/`|开发人员和构建工具|
|`Doc/`|文档来源|
|`PC/`| Windows 特定的源文件和配置文件 |
|`PCbuild/`| Windows 构建系统 |
|`Mac/`| macOS 特定支持 |
内部阅读最重要的目录是:```text
Include/
Objects/
Python/
Parser/
Modules/
Lib/test/
```这些目录涵盖对象模型、执行引擎、编译器、解析器、内置类型、C API 和测试。
## 3.2`Include/`:C 头文件`Include/`包含 CPython 本身使用的头文件、扩展模块和嵌入器。
简化的布局:```text
Include/
Python.h
object.h
unicodeobject.h
listobject.h
dictobject.h
cpython/
internal/
```最重要的文件是:```c
#include <Python.h>
Python.h是扩展模块的总括公共标头。它包含许多其他公共标头并公开大多数扩展作者使用的 C API。
标题类别
| 标题区 | 观众 | 稳定性 |
|---|---|---|
Include/*.h |
公共 C API 用户 | 比较稳定 |
Include/cpython/ |
CPython 特定 API | 不太便携 |
Include/internal/ |
仅限 CPython 内部 | 可以自由改变 |
这种区别很重要。 CPython 内部的代码可以包含内部标头。第三方扩展通常不应该。
例如:```c #include "Python.h"
但:```c
#include "internal/pycore_runtime.h"
```用于 CPython 核心代码。它公开了不属于稳定公共 API 的内部运行时结构。
## 3.3`Objects/`:内置对象实现`Objects/`包含许多核心 Python 对象类型的 C 实现。
示例:
|文件|实施|
| ------------------- | --------------------------------- |
|`object.c`|基础对象操作 |
|`typeobject.c`|类型对象、类、MRO、槽 |
|`longobject.c`| Python 整数 |
|`floatobject.c`| Python 浮动 |
|`unicodeobject.c`| Python 字符串 |
|`bytesobject.c` | `bytes` |
| `bytearrayobject.c` | `bytearray` |
| `listobject.c` | `list` |
| `tupleobject.c` | `tuple` |
| `dictobject.c` | `dict` |
| `setobject.c` | `set`和`frozenset` |
| `funcobject.c`|函数对象 |
|`methodobject.c`|内置方法对象 |
|`moduleobject.c`|模块对象 |
|`genobject.c`|生成器和协程 |
|`frameobject.c`|框架对象支持 |
|`codeobject.c`|代码对象 |
|`cellobject.c`|封闭细胞|
|`descrobject.c`|描述符|
该目录是研究 Python 值如何表示和操作的最佳位置。
例如,列表行为主要存在于:```text
Objects/listobject.c
```字典行为主要体现在:```text
Objects/dictobject.c
```字符串行为主要存在于:```text
Objects/unicodeobject.c
```当Python运行时:```python
items = []
items.append(1)
```底层的列表分配、调整大小、方法查找和追加操作最终涉及到以下代码:`Objects/listobject.c`并键入机械`Objects/typeobject.c`。
## 3.4`Python/`:运行时、编译器和解释器核心`Python/`包含 CPython 的大部分核心机制。
重要文件包括:
|文件 |角色 |
| ------------------ | -------------------------------------------------- |
|`ceval.c`|字节码评估循环 |
|`bytecodes.c`|现代 CPython 中的字节码指令定义 |
|`compile.c`| AST 到代码对象编译器 |
|`symtable.c`|符号表分析|
|`ast.c`| AST 支持 |
|`pythonrun.c`|高级执行入口点 |
|`pylifecycle.c`|运行时初始化和终止|
|`import.c`|进口支持|
|`errors.c`|异常状态和错误API |
|`traceback.c`|追溯支持 |
|`sysmodule.c`|实施`sys` |
| `bltinmodule.c`|内置函数和内置模块 |
|`marshal.c`|代码对象的内部序列化格式|
|`thread.c`|线程抽象层|
|`context.c`|上下文变量支持 |
|`bootstrap_hash.c`|哈希秘密初始化 |
文件名不仅仅是标签。它们反映了深层运行时子系统。
### 解释器执行
字节码解释器以评估循环为中心。从历史上看,这与`ceval.c`。在较新的 CPython 版本中,操作码定义和生成的解释器片段可能会拆分到其他文件中。
概念角色:```text
frame enters evaluation
↓
bytecode instruction fetched
↓
instruction dispatch
↓
object operation
↓
stack and frame state updated
```### 编译器管道
编译器代码将 AST 节点降低为代码对象。
简化的路径:```text
source text
↓
tokens
↓
parse tree
↓
AST
↓
symbol table
↓
compiler
↓
code object
```关键文件通常是:```text
Parser/
Python/ast.c
Python/symtable.c
Python/compile.c
Objects/codeobject.c
```## 3.5`Parser/`:分词器和解析器支持`Parser/`包含分词器、解析器生成器支持、解析器实现文件以及生成的解析器相关代码。
重要领域包括:
|面积 |角色 |
| ---------------------- | ------------------------------------------------ |
|分词器 |将源文本转换为标记 |
|解析器|从标记构建语法结构 |
| PEG机械|支持Python的PEG解析器 |
|生成的解析器文件 |由语法定义产生 |
解析器的工作是确定源文本是否是有效的 Python 语法,并构建稍后成为 AST 的结构。
例子:```python
x = 1 + 2
```解析器需要识别:```text
assignment statement
target name x
expression 1 + 2
integer literal 1
integer literal 2
binary addition operator
```解析先于语义分析。解析器知道语法。符号表稍后决定名称是本地变量、全局变量、自由变量还是单元变量。
## 3.6`Grammar/`: 语法定义`Grammar/`包含用于生成解析器相关代码的语法输入文件。
该语法以 CPython 解析器工具使用的形式定义了 Python 语法。
对于内部工作来说,语法变化影响很大。语法更改可能会影响:```text
parser generation
AST generation
compiler behavior
error messages
tests
documentation
tools that parse Python
```语法级别的更改通常需要重新生成和有针对性的测试。
通常的工作流程是:```text
edit grammar input
regenerate parser files
rebuild CPython
run parser, AST, compiler, and syntax tests
```## 3.7`Modules/`:内置和扩展模块`Modules/`包含许多 CPython 附带的 C 模块。
示例:
|文件或目录 |模块|
| ------------------- | ------------------------ |
|`_io/`| I/O 实现 |
|`_decimal/`|十进制加速器 |
|`_sqlite/`| SQLite 模块 |
|`_ssl.c`| SSL 支持 |
|`_hashopenssl.c`|使用 OpenSSL 进行哈希处理 |
|`_ctypes/` | `ctypes` |
| `arraymodule.c` | `array` |
| `mathmodule.c` | `math` |
| `itertoolsmodule.c` | `itertools` |
| `functoolsmodule.c` | `_functools` |
| `posixmodule.c` | `os`平台运营|
|`timemodule.c` | `time`|
一些标准库模块是用 Python 编写的,并使用来自`Modules/`。
例如,公共 Python 模块可能位于`Lib/`,而私人绩效关键帮手住在`Modules/`。
这种模式为 CPython 提供了一个干净的公共 API,同时保留了热路径的快速 C 实现。
## 3.8`Lib/`:标准库`Lib/`包含Python标准库。
示例:
|路径|角色 |
| -------------------- | -------------------------------- |
|`Lib/os.py`|操作系统接口层|
|`Lib/pathlib/`|面向对象的路径|
|`Lib/importlib/`|导入系统实施 |
|`Lib/asyncio/`|异步 I/O 框架 |
|`Lib/collections/`|收集实用程序 |
|`Lib/dataclasses.py`|数据类支持 |
|`Lib/typing.py`|打字支持 |
|`Lib/unittest/`|单元测试框架|
|`Lib/json/`| JSON 实现 |
|`Lib/concurrent/`| Futures 和进程/线程池 |
通过首先阅读 Python 级别的标准库,许多 CPython 内部结构会更容易理解。
例如,`importlib`包含 Python 代码中的大部分导入系统。 CPython 特别引导它,但大部分内容仍然像 Python 一样可读。
## 3.9`Lib/test/`:回归测试`Lib/test/`包含 CPython 的测试套件。
该目录对于内部工作至关重要。
示例:
|测试文件|焦点 |
| ------------------- | -------------------- |
|`test_dict.py`|字典行为 |
|`test_list.py`|列出行为|
|`test_gc.py`|垃圾收集器 |
|`test_sys.py` | `sys`模块|
|`test_dis.py`|字节码反汇编 |
|`test_compile.py`|编译器行为 |
|`test_ast.py`| AST 行为 |
|`test_importlib/`|导入系统|
|`test_capi/`| C API 行为 |
|`test_threading.py`|线程行为 |
研究子系统时,请将实现文件与其测试配对。
|实施 |测试 |
| ---------------------- | ------------------------ | |
|`Objects/dictobject.c` | `Lib/test/test_dict.py` |
| `Objects/listobject.c` | `Lib/test/test_list.py` |
| `Python/compile.c` | `Lib/test/test_compile.py` |
| `Python/symtable.c` | `Lib/test/test_symtable.py` |
| `Python/sysmodule.c` | `Lib/test/test_sys.py` |
| `Modules/mathmodule.c` | `Lib/test/test_math.py`|
这种习惯阻碍了孤立地阅读代码。 CPython 行为是由代码、测试、文档以及兼容性期望定义的。
## 3.10`Programs/`:可执行入口点`Programs/`包含 CPython 可执行程序的源文件。
典型的文件包括:```text
Programs/python.c
Programs/_testembed.c
Programs/python.c是正常的命令行解释器入口点。
简化的启动路径如下所示:```text main() ↓ initialize runtime ↓ configure interpreter ↓ run command, script, module, stdin, or REPL ↓ finalize runtime
## 3.11`Tools/`:开发者工具`Tools/`包含 CPython 开发的帮助程序。
Examples include tools for:```text
generated file maintenance
bytecode and opcode metadata
C API inspection
test support
build support
freeze tooling
scripts used by maintainers
```确切的内容会随着时间的推移而变化。重要的规则是,CPython 中的许多生成的文件都有源输入和重新生成工具。`Tools/`通常是这些工具所在的地方。
更改语法、Argument Clinic 块、操作码定义或生成的元数据时,请在编辑生成的输出之前检查相关工具工作流程。
## 3.12`Doc/`:文档来源`Doc/`包含 CPython 的文档源。
该文档涵盖:```text
language reference
library reference
C API reference
extending and embedding
how-to guides
tutorial
installing and using Python
```对于内部工作,文档很重要,因为行为的改变通常需要文档更新。
CPython 更改可能需要在多个位置进行编辑:```text
implementation code
tests
documentation
news entry
C API docs
library docs
```文档源使用 reStructuredText 而不是 Markdown。
## 3.13 平台目录
CPython 支持许多平台。有些目录主要用于特定于平台的配置和构建。
|目录 |平台角色|
| ------------------------------------------------------ | ------------------------------------------ |
|`PC/`| Windows 特定源/配置 |
|`PCbuild/`| Visual Studio 构建文件 |
|`Mac/`| macOS 支持 |
|平台文件位于`Python/`和`Modules/`|特定于操作系统的实现 |
平台支持通过条件编译出现在整个树中。
示例模式:```c
#ifdef MS_WINDOWS
/* Windows-specific code */
#else
/* POSIX-like code */
#endif
```内部读取通常需要将可移植运行时逻辑与特定于平台的分支区分开来。
## 3.14 生成的代码和源输入
CPython 包含手写文件和生成文件。
常见的生成区域包括:```text
parser output from grammar
AST-related generated files
opcode metadata and bytecode tables
Argument Clinic output
frozen importlib modules
configuration files
```生成的文件通常在顶部附近有一条注释,解释它是如何生成的。
在编辑可疑的机械块之前,请查找以下标记:```text
generated by
do not edit
clinic start generated code
autogenerated
```对生成区域的手动编辑通常会在再生过程中丢失。
## 3.15 存储库的读取路径
一个好的第一阅读路径是:```text
Programs/python.c
↓
Python/pylifecycle.c
↓
Python/pythonrun.c
↓
Python/compile.c
↓
Python/ceval.c
↓
Objects/object.c
↓
Objects/typeobject.c
↓
Objects/dictobject.c
↓
Objects/listobject.c
```该路径遵循从进程启动到运行时行为的执行。
对象内部的第二个阅读路径:```text
Include/object.h
↓
Include/cpython/object.h
↓
Objects/object.c
↓
Objects/typeobject.c
↓
Objects/longobject.c
↓
Objects/unicodeobject.c
↓
Objects/listobject.c
↓
Objects/dictobject.c
```源代码到字节码的第三条路径:```text
Grammar/
↓
Parser/
↓
Python/ast.c
↓
Python/symtable.c
↓
Python/compile.c
↓
Objects/codeobject.c
↓
Python/ceval.c
```## 3.16 如何查找 Python 功能的代码
从Python功能开始,然后将其映射到子系统。
|特色 |第一个要检查的文件 |
| ------------- | ------------------------------------------------------ |
|`list.append` | `Objects/listobject.c` |
| `dict[key]` | `Objects/dictobject.c` |
| `x.y` | `Objects/object.c`, `Objects/typeobject.c` |
| `class C:` | `Objects/typeobject.c`, `Python/compile.c` |
| `try/except` | `Python/compile.c`, `Python/ceval.c` |
| `import x` | `Lib/importlib/`, `Python/import.c` |
| `async def` | `Python/compile.c`, `Objects/genobject.c` |
| `with` | `Python/compile.c`, `Python/ceval.c` |
| `len(x)` | `Python/bltinmodule.c`, 类型槽 |
|`print(x)` | `Python/bltinmodule.c`, 文件 I/O 模块 |
使用测试来确认行为:```bash
./python -m test test_dict
./python -m test test_descr
./python -m test test_importlib
```## 3.17 存储库布局作为架构
目录结构反映了 CPython 的架构。```text
Include/ exposes C interfaces
Objects/ defines runtime values
Python/ executes and manages programs
Parser/ understands syntax
Modules/ provides C-backed modules
Lib/ provides Python-level standard library
Lib/test/ protects behavior
Programs/ starts the executable
Tools/ maintains generated and developer workflows
Doc/ explains public behavior
```这种布局并不完美。较旧的代码、平台限制、向后兼容性和生成的文件会产生异常。尽管如此,结构还是足够连贯的,可以指导源代码的阅读。
## 3.18 章节总结
CPython 存储库是一个工作系统,而不是孤立文件的集合。`Objects/`定义 Python 值是什么。`Python/`定义程序如何编译和执行。`Parser/`和`Grammar/`定义语法处理。`Modules/`和`Lib/`提供标准库。`Include/`公开 C 接口。`Lib/test/`定义了回归安全网的大部分内容。
高效的读者会在实现、测试和文档之间移动。一旦每个源文件在运行时架构中都有一个明确的位置,CPython 内部就会变得更容易。