CPython 3.11.0a7 变更全景:异常匹配字节码重构、解释器提速与标准库现代化
本文以 CPython 仓库中记录 3.11.0a7(2022 年 4 月前后发布的第三个 Alpha 里程碑)合并改动的 Misc/NEWS.d/3.11.0a7.rst 为骨架,逐类梳理 Core and Builtins、Library、C API、Build、Windows/macOS 等板块的改动:从
CHECK_EXC_MATCH/CHECK_EG_MATCH等字节码重构,到 asyncio、re、typing、hashlib 等标准库的现代化升级,再到 WebAssembly/Emscripten 平台的信号处理支持。文中所有实现层面的结论均可在当前仓库源码中找到对应物,读者既可把它当作 3.11 早期开发路线的"考古地图",也可据此理解如今 CPython 主线上仍在使用或继续演进的那些设计。
一、先读懂 NEWS.d 片段文件的组织方式
CPython 的 Misc/NEWS.d/ 目录存放"待合并的新闻条目",每个 .rst 文件是一组 blurb 片段,最终会被合入 Misc/NEWS(现在为 Misc/NEWS.d 按版本聚合)。以本文件中的单条记录为例:
.. bpo: 47212
.. date: 2022-04-05-11-29-21
.. nonce: leF4pz
.. release date: 2022-04-05
.. section: Core and Builtins
Raise :exc:`IndentationError` instead of :exc:`SyntaxError` for a bare
``except`` with no following indent. ...
字段含义:
bpo/gh:关联的 bug/issue 编号;date:改动提交/归档时间;release date:计划落入的发布版本;section:条目归类,本文涉及 Core and Builtins、Library、Documentation、Tests、Build、Windows、macOS、C API、Tools/Demos 共 9 类;nonce:blurb 生成的随机唯一标识,用于保证条目在合并时能精确对齐。
3.11.0a7 条目覆盖 2021 年 6 月至 2022 年 4 月初合并、最终随 Alpha 7 发布的改动,其中相当一部分与 3.11 的两个大主题直接相关:基于自适应专业化(specialization)的解释器加速(PEP 659 方向)与 faster-cpython 框架落地。下面按 section 顺序展开。
二、Core and Builtins:字节码、帧对象与解释器内核重构
1. 异常匹配与跳转指令的"检查 + 跳转"拆分(bpo-47186 / bpo-47120)
本周期内,编译器后端与解释器把原本"条件跳转一体"的指令拆成"先检查、后跳转"两步:
- 用
CHECK_EXC_MATCH+ 跳转替换JUMP_IF_NOT_EXC_MATCH(bpo-47186); - 用
CHECK_EG_MATCH+ 跳转替换JUMP_IF_NOT_EG_MATCH(bpo-47186),后者服务于except*的多异常组匹配; - 用相对跳转
JUMP_BACKWARD替换绝对跳转JUMP_ABSOLUTE(bpo-47120); - 用相对跳转
JUMP_BACKWARD_NO_INTERRUPT替换绝对跳转JUMP_NO_INTERRUPT(bpo-47120)。
这类改动的动机在 Include/internal/pycore_magic_number.h 的版本注释里留下了痕迹:3.11a6 的 magic 3490/3491 明确记录了 "remove JUMP_IF_NOT_EXC_MATCH, add CHECK_EXC_MATCH" 以及 "remove JUMP_IF_NOT_EG_MATCH, add CHECK_EG_MATCH, add JUMP_BACKWARD_NO_INTERRUPT, make JUMP_NO_INTERRUPT virtual"。把匹配判断从"跳转条件"中剥离,使指令语义更单一,方便后续把 CHECK_* 之类的纯检查操作放进**内联缓存与专业化(specialization)**框架中统一处理。
这一设计的"最终形态"至今仍保留在当前主线:在 Include/opcode_ids.h 中可以看到:
#define CHECK_EG_MATCH 5
#define CHECK_EXC_MATCH 6
...
#define JUMP_BACKWARD 71
#define JUMP_BACKWARD_NO_INTERRUPT 72
同时在 Include/internal/pycore_opcode_metadata.h 中,CHECK_EXC_MATCH、CHECK_EG_MATCH 被标记为带 HAS_ERROR_FLAG/HAS_ESCAPES_FLAG 的指令,而 JUMP_BACKWARD 在 uop 层面展开为 _CHECK_PERIODIC(周期性地检查信号/时钟)+ _JUMP_BACKWARD_NO_INTERRUPT 两个微操作。可以推断,当年"把跳转改为相对形式"的取舍,为后来跳转类指令被拆成微操作(uops)、并纳入解释器循环的周期性检查机制奠定了基础。
2. 自适应专业化基础设施成型(bpo-46841 系列、bpo-47127 等)
3.11 的目标之一是让解释器根据运行期观察到的类型动态"特化"指令。本片段里多条 Core 条目都在为这套机制铺路:
- 字节码原地快速化(quickening):bpo-46841 将快速化后的字节码直接存放在对应的
PyCodeObject中,从而避免维护一套并行的"加速字节码副本"结构; - 内联缓存全面接管:
STORE_SUBSCR改用内联缓存条目(而非其 oparg)作为自适应计数器(bpo-46841);PRECALL与CALL使用内联缓存,并移除了原先管理非内联缓存的内部机制(bpo-46841); - LOAD_GLOBAL 位标记优化:bpo-46329 使用
LOAD_GLOBAL的低位比特指示是否在全局对象之前压入一个NULL,以精简后续调用序列(这是为CALL指令在"待调用对象尚未确定"时预留槽位); - C 函数关键字调用提速 25%:bpo-47127 通过专业化使"以关键字参数调用 C 函数"提速约 25%(Patch by Kumar Aditya);
- 缩小去优化面:bpo-47053 减小了专业化指令
BINARY_OP_INPLACE_ADD_UNICODE的去优化(de-optimization)开销。
这些机制在后来演化为完整的"自适应字节码 + inline cache + 专业化守卫"体系。当前主线中 opcode 元数据与 uop 描述(见 Include/internal/pycore_opcode_metadata.h)以及 _Py_CODEUNIT 层面的 cache 布局,都可以追溯到这一时期确立的设计方向。
3. 帧对象重构:ownership 显式化与 f_locals 语义收敛
3.11 把 C 栈帧迁移到堆上的 _PyInterpreterFrame,本片段记录了这一步的关键调整:
- bpo-47045 从
_PyInterpreterFrame结构中删除f_state字段,新增owner字段,用"谁拥有这个帧"来显式表达所有权,从而简化帧与生成器(generator)在清理与释放(dealloc)时的逻辑; - bpo-42197 让
PyFrame_FastToLocalsWithError与PyFrame_LocalsToFast不再在 profile/trace 期间被调用,C 代码访问PyFrameObject的f_locals属性应通过公开 APIPyFrame_GetLocals完成; - bpo-40421 新增
PyFrame_GetBuiltins、PyFrame_GetGenerator、PyFrame_GetGlobals三个 C-API 函数,让 C 代码能安全读取帧对象的 globals/builtins 以及所属生成器。这三个函数目前仍声明在 Include/cpython/pyframe.h:
PyAPI_FUNC(PyObject *) PyFrame_GetGlobals(PyFrameObject *frame);
PyAPI_FUNC(PyObject *) PyFrame_GetBuiltins(PyFrameObject *frame);
PyAPI_FUNC(PyObject *) PyFrame_GetGenerator(PyFrameObject *frame);
从源码结构看,"profile/trace 不再触发 FastToLocals 同步"意味着 Python 层通过 sys.settrace/sys.setprofile 观察到的局部变量读写路径被收敛到统一的 f_locals 访问器上,属于 3.11 帧生命周期管理整体改造的一部分。
4. 报错信息与语法诊断打磨
错误诊断质量是 3.11 强调的方向之一,本片段包含多处提升:
- bare
except无缩进报IndentationError(bpo-47212):try: ... except:后若没有跟随缩进块,此前抛出的是宽泛的SyntaxError,现在改为更准确的IndentationError,并将"未加括号的生成器作为参数"(如f(x for x in y,)之类的拼写)的SyntaxError定位信息一并改进(Patch by Matthieu Dartiailh); - f-string 空表达式报错(bpo-47129):改进 f-string 语法错误中关于空表达式(如
f"{ }")的错误消息; - 非法函数定义(bpo-46838):改进函数定义写错时的语法错误定位(Patch by Pablo Galindo);
- 交互模式解码崩溃(bpo-47117):修复在交互模式下 tokenizer 缓冲区尚未初始化时解码失败导致的崩溃(Patch by Pablo Galindo);
- 具名 Unicode 字符二次初始化崩溃(bpo-47182):修复主解释器第二次初始化后使用
"\N{digit nine}"这类具名 Unicode 字符时的崩溃; - bpo-46838/bpo-47212 还附带说明:配套测试在 Lib/test 中有对应用例可查。
5. 常用容器与对象的内存/性能优化
- bytes/bytearray 迭代提速 30%(bpo-47012,Patch by Kumar Aditya);
- bytearray 由 list/tuple 构造提速 40%(bpo-46993,Patch by Kumar Aditya);
- list.append 与列表推导优化(bpo-47009):针对最常见"无需扩容"的场景做了专门优化(Patch by Dennis Sweeney)。此外 bpo-39829 移除了初始化 list 时的
__len__()调用,把初始化工作并入list_extend(Patch by Jeremiah Pascual); - repeat/inplace-repeat 统一实现(bpo-47070):
array、bytes、bytearray与unicodeobject的repeat/原地repeat重构为共用_PyBytes_Repeat,并通过减少memcpy调用次数提升array_inplace_repeat的性能; - bytearray_repeat 精简 memcpy(bpo-47005);
- latin1 字符静态分配(bpo-46881):单字节 latin1 字符改为静态分配并初始化,省去运行时构造开销;
- 代码对象比较零分配(bpo-46841 条目):避免比较 code object 时产生不必要的分配;
- 生成器抛异常提速(bpo-46944):配合
METH_FASTCALL调用约定加速向生成器抛入异常(Patch by Kumar Aditya)。
6. 跨平台内核适配:Emscripten 信号与函数指针跳板
3.11 的开发同步推进 WASM 平台(Emscripten/WASI)支持,两条 Core 条目直接相关:
- Emscripten 信号处理(bpo-47176):WASM 无法像原生平台那样处理信号。Python 现在可以在 Emscripten 上处理信号:嵌入方将
Module.Py_EmscriptenSignalBuffer设为一个单字节的SharedArrayBuffer,并把Py_EMSCRIPTEN_SIGNAL_HANDLING置为 1;随后向该 buffer 写入一个数字,就会把对应信号投递给 Python 线程。对应的实现在 Python/emscripten_signal.c,其内注释给出了接入方式,核心是每 50 条字节码(PY_EMSCRIPTEN_SIGNAL_INTERVAL)周期性调用_Py_CheckEmscriptenSignalsPeriodically(),读取 buffer 中的信号值并调用PyErr_SetInterruptEx完成中断。信号轮询在 Python/bytecodes.c 中以时钟倒计时的形式接入解释器主循环; - 函数指针调用跳板(trampoline)(bpo-47162):WebAssembly 不允许不同类型的函数指针互相转换(参数个数或类型不同即 UB)。为此引入
PY_CALL_TRAMPOLINE宏,开启后使用调用跳板规避 WASM 的函数指针类型限制;同类问题也影响 WASI。配套的汇编跳板可见于 Python/asm_trampoline_x86_64.S 等文件,虽然那是后来通用化机制的形态,但"为受限 ABI 提供跳板"这一思路由此确立。
7. 其他 Core 修正
- Windows errno 映射(bpo-46775):部分 Windows 系统错误码(>= 10000)现在能正确映射到 errno,从而可能抛出
OSError的恰当子类(Patch by Donghee Na); - PEP 646 语法落地(bpo-43224):为使
*tuple[int, str]之类变长泛型解包可用,先行修改了语法(Grammar/Python 层面的调整),typing 侧的实现见后文 Library 部分; - property 文档字符串修正(bpo-43721):修正
property.getter/setter/deleter的 docstring,明确它们会创建 property 的一份新拷贝。
三、Library:asyncio、re、typing 与更多标准库的现代化
Library 是 3.11.0a7 中条目最多的板块,其中 asyncio、re、typing、hashlib 四个模块的演进尤其值得关注。
1. asyncio:Runner、Barrier、timeout 与 API 收敛
asyncio.Runner上下文管理器(bpo-47062):新增统一管理事件循环运行期的 Runner 类,其实现位于 Lib/asyncio/runners.py,后来与asyncio.run的实现共用同一套"创建/运行/关闭循环"逻辑;
from asyncio import Runner
with Runner() as runner:
result = runner.run(coro) # 在统一的运行期内执行协程
- 同步原语补齐 Barrier(bpo-43352):asyncio 新增
asyncio.Barrier,与threading.Barrier、multiprocessing.Barrier对齐。当前实现见 Lib/asyncio/locks.py(同文件 349 行起是同样在本周期持续演化的asyncio.Semaphore); - 超时上下文管理器(bpo-464471):新增
asyncio.timeout()与asyncio.timeout_at()上下文管理器,提供 PEP 语义清晰、可嵌套的超时控制(Patch by Tin Tvrtković 与 Andrew Svetlov); - 原始数据报套接字 API(bpo-46805):为事件循环新增
sock_sendto、sock_recvfrom、sock_recvfrom_into三个数据报读写方法; - Ctrl+C 中断主任务(bpo-39622):asyncio 程序收到
KeyboardInterrupt时现在会中断主任务,改善命令行程序的手动终止体验; asyncio.Server公开暴露(bpo-46955):把asyncio.base_events.Server作为asyncio.Server导出(Patch by Stefan Zabka);- 破坏性变更与弃用:
- 禁止向
asyncio.wait直接传协程对象(bpo-34790),应包成 Task; Future.cancel/Task.cancel的 message 参数被弃用(bpo-46829);- 第三方 Task 实现若缺少
set_name,将发出弃用警告,计划在 Python 3.13 中设为强制(bpo-46995); - 允许覆盖未来的 compliance 检查(bpo-47167);
repr()归一化:未来/任务对象的 repr 统一格式(bpo-47039);
- 禁止向
- 行为修正:
loop.sock_connect只为AF_INET/AF_INET6解析主机名,避免对AF_BLUETOOTH、AF_UNIX等做无意义的解析(bpo-27929);Semaphore重新获取顺序改为 FIFO(bpo-45997);create_task接受显式的contextvars.Context(bpo-46994);Proactor 事件循环在底层 socket 句柄已失效时关闭 transport 不再崩溃(bpo-43253);FutureIter.throw()改用 FASTCALL 约定(bpo-47057)。
2. re 模块:包化、弃用 sre_*、原子组与占有量词
- 模块包化(bpo-47152):
re从单文件模块转为包(Lib/re),同时弃用sre_compile、sre_constants、sre_parse三个内部模块; - 原子组与占有量词(bpo-433030):正式支持
(?>...)原子组以及*+、++、?+、{m,n}+占有量词。这些语法在_sre引擎里有明确的内部操作码支持,见 Modules/_sre/sre.c 中的SRE_OP_POSSESSIVE_REPEAT_ONE、SRE_OP_POSSESSIVE_REPEAT、SRE_OP_ATOMIC_GROUP分支;
import re
# 占有量词:匹配成功后不再回溯
re.fullmatch(r'"[^"]*+"', '"abc"') # 匹配
re.search(r'a++a', 'aaa') # None:a++ 吃掉全部 a,无回溯
# 原子组
re.search(r'a(?>bc|b)c', 'abc') # None:原子组选定 bc 后不再尝试 b 分支
- 锚定优化(bpo-42885):对以
\A或^开头的正则,search/split/findall/finditer/sub不再做无谓的移动式尝试; - 内联 flags 收口(bpo-47066 + bpo-39394):全局内联 flags(如
(?i))只能出现在正则表达式开头(自 Python 3.6 起弃用),现在不在开头使用会得到报错;相关警告信息会包含 flags 的位置; - 健壮性修复:
finditer迭代器防重入(bpo-23691);匹配被信号或内存分配失败中断时修复内存泄漏(bpo-23689,Patch by Ma Lin);修复罕见情况下捕获组取到错误字符串的问题(bpo-35859)。
3. typing:PEP 675/646 与泛型打磨
typing.LiteralString(PEP 675)(bpo-47088):新增LiteralString类型,用于静态地保证某个值只来自"字面量/字符串插值",从而在类型检查层面防御 SQL 注入类错误。当前定义在 Lib/typing.py:
from typing import LiteralString
def run_query(sql: LiteralString) -> None: ...
run_query("SELECT * FROM t WHERE id = ?") # 类型检查通过
run_query(input()) # 类型检查拒绝:非字面量来源
- PEP 646 支持(变长泛型)(bpo-43224):
typing.py实现 PEP 646(TypeVarTuple 等)的同时,允许解包types.GenericAlias对象,例如*tuple[int, str]的赋值形态; typing.assert_type(bpo-46480):新增assert_type(val, typ),供类型检查器断言某个表达式的精确类型(Patch by Jelle Zijlstra);Any可被继承(bpo-46998):允许子类化typing.Any(Patch by Shantanu Jain);get_args修正(bpo-46981):typing.get_args(typing.Tuple[()])现在返回()而非((),);- 前向引用求值(bpo-41370):
typing.get_type_hints支持把字符串前向引用放进 PEP 585 泛型别名(如list["X"])中求值; - NewType 报错(bpo-46170):尝试子类化
typing.NewType实例时给出更清晰的错误消息; - ParamSpec 传播(bpo-46581):
GenericAlias的ParamSpec传播行为与Concatenate等对齐; - Annotated 放宽(bpo-46644):不再要求 typeform 必须可调用,使
typing.Annotated可以包裹ParamSpecArgs与dataclasses.InitVar(Patch by Gregory Beauregard)。
4. hashlib 与二进制/加密相关
hashlib.file_digest(bpo-45150):新增辅助函数,用于高效地对文件对象做哈希,避免手工分块读写的样板代码;实现见 Lib/hashlib.py:
import hashlib
with open("data.bin", "rb") as f:
digest = hashlib.file_digest(f, "sha256") # 分块读取,内存友好
- OpenSSL 3.0 算法可见性(bpo-47101):
hashlib.algorithms_available现在只列出激活的 crypto provider 提供的算法;除非把 legacy provider 载入默认 OSSL context,否则不列出遗留算法; - crc32 大输入修正(bpo-38256):
binascii.crc32在编译期采用 zlib 的 crc32 实现时,对 4 GiB 以上的输入不再返回错误结果;同时大输入计算时会释放 GIL(与zlib.crc32、hashlib 一致);Windows 上改用 zlib crc32 实现带来约 2~3 倍提速。条目原文还点出"标准库有两处 crc32 API 是历史遗留奇观",本次改动让两者向单一实现靠拢; _sha3换用 tiny_sha3(bpo-47098):内置_sha3模块的 Keccak 代码包(KCP)被 tiny_sha3 取代(作为无 OpenSSL 构建时的回退);_blake2优先使用外部 libb2(bpo-47095):内部_blake2模块优先链接 blake2.net 的 libb2,而非随附的 blake2 拷贝。
5. zipfile:metadata_encoding、mkdir 与线程安全
metadata_encoding参数(bpo-28080):zipfile.ZipFile构造函数新增metadata_encoding参数,CLI 新增--metadata-encoding选项,用于读取以非标准字符集编码文件名的 zip 归档;ZipFile.mkdir(bpo-4833):可以在归档中创建目录,当前签名见 Lib/zipfile/init.py(mode默认 0o777,即 511);- 线程安全(bpo-42369):修复多线程读取同一
ZipFile时_SharedFile.tell的竞态,消除偶发的zipfile.BadZipFile: Bad CRC-32 for file; - 写成员文件长度(bpo-44439):当输入对象支持 buffer protocol 时,修正
ZipFile成员文件.write()得到的长度可能错误的问题。
6. sqlite3 与 ctypes
sqlite3(bpo-44859)把异常对齐到 PEP 249:
SQLITE_MISUSE现在抛sqlite3.InterfaceError(而不是ProgrammingError);- 转 BLOB 失败时不再用
ValueError覆盖BufferError; - 一次
execute执行多条 SQL 抛ProgrammingError(而不是Warning); - SQL 查询含 NUL 字符时抛
ProgrammingError(而不是ValueError)。
此外 bpo-41930 为 sqlite3.Connection 增加了 serialize() / deserialize(),可把数据库整体序列化到内存并恢复(Patch by Erlend E. Aasland),配合 Modules/_sqlite 的底层实现使用。
ctypes 方面:bpo-33178 补上了文档中早有但一直未实现的 ctypes.BigEndianUnion 与 ctypes.LittleEndianUnion 联合体类;bpo-47208 允许厂商覆盖 CTYPES_MAX_ARGCOUNT 上限(作用于 Modules/_ctypes 的参数计数限制)。
7. tomllib 与 PEP 594 弃用大扫除
tomllib(PEP 680)(bpo-40059):新增 TOML 解析模块,标准库由此可以原生读取pyproject.toml;当前模块位于 Lib/tomllib。这是 3.11 最重要的库级新增之一;- PEP 594 弃用清单落地(bpo-47061):aifc、asynchat、asyncore、audioop、cgi、cgitb、chunk、crypt、imghdr、msilib、nntplib、nis、ossaudiodev、pipes、smtpd、sndhdr、spwd、sunau、telnetlib、uu、xdrlib 等模块统一进入弃用状态(其中 bpo-47022 专门更新了 asynchat/asyncore/smtpd 的文档与警告,明确它们将在 Python 3.12 移除);aifc 单独在 bpo-47061 中标注弃用。
8. 其他值得关注的 Library 条目
dataclasses:@dataclass(slots=True)现在会正确跳过基类中已定义的 slots(bpo-46382,Patch by Arie Bovenberg);subprocess:vfork 出错时自动回退到 fork(bpo-47151),使得在禁止 vfork 的内核/环境(如 seccomp 沙箱)下仍可用;select:每个空的 fdset 都向系统select传递NULL(bpo-40280),语义更接近 POSIX;logging:捕获的 warning 改为不带格式字符串记录,避免按 msg 分组的日志系统把所有 warning 聚成一组(bpo-46557);stacklevel参数在所有 logging 函数间行为一致(bpo-45171);math.nan恒可用(bpo-46917):math.nan常量总是可用(Patch by Victor Stinner);os.sysconf_names新增SC_MINSIGSTKSZ(bpo-46968),并配套给faulthandler动态确定信号处理栈大小:Linux 5.14+ 上通过getauxval(AT_MINSIGSTKSZ)查询内核允许的最小备用信号栈,从而让扩展能请求 Intel Sapphire Rapids 的 AMX_TILE 指令集(bpo-46968);faulthandler同时在编译期检查sys/auxv.h是否存在,避免无该头文件的系统编译失败(bpo-46968,Patch by Pablo Galindo);pwd模块可选化(bpo-46933):pwd变为可选模块,os.path.expanduser在缺少pwd时直接返回原路径;signal:不再假设SIG_IGN/SIG_DFL是小整数单例(bpo-23325);ensurepip:随附 pip 升级到 22.0.4(bpo-46985);importlib.metadata:应用 importlib_metadata 4.11.3 的修复,包括EntryPoint.extras误返回 match 对象而非 extras 字符串的问题(bpo-47004);cProfile:默认排序键改为 cumtime(bpo-34861);io.text_encoding:UTF-8 模式开启时返回"utf-8"(bpo-47000);configparser:为LegacyInterpolation添加DeprecationWarning(自 3.2 起 docstring 就在提示弃用),计划 3.13 移除(bpo-46607),建议改用BasicInterpolation/ExtendedInterpolation;GenericAlias调用优化(bpo-47067):用 PEP 590 vectorcall 优化 GenericAlias 调用,并以PyObject_SetAttr替换PyObject_SetAttrString;unittest:输出中包含完全限定的测试名(bpo-14265);python -m unittest遇以点开头的文件名不再误抛ValueError(bpo-46421);修复 traceback 偶尔丢失测试内异常帧的问题(bpo-24959);TestProgram.usageExit标记弃用(bpo-22859);doctest:修复使用 globals 的 doctest 多次运行时失败的问题(bpo-2604);shutil.rmtree新增可选dir_fd参数(bpo-46245);socket:新增 FreeBSD 常量LOCAL_CREDS、LOCAL_CREDS_PERSISTENT、SCM_CREDS2(bpo-46030);补齐非抽象 AF_UNIX 数据报套接字sockaddr_un长度中的终止 NUL(bpo-44493);urllib:URLopener的URLError消息中 "ftp error" 与其余部分之间补齐冒号(bpo-47099);同一 issue 下将Exception.with_traceback/sys.exc_info的链式写法改为 PEP 3134 的隐式异常链(Patch by Oleg Iarygin);MimeTypes.guess_type:修复大写扩展名(如.PNG)不一致的问题(bpo-20392,Patch by Kumar Aditya);pydoc:模块数据项中不再包含__future__导入(bpo-26120);支持泛型别名的展示(bpo-40296);binascii/zlib文档:澄清 crc32/adler32 的旧版本兼容性说明(bpo-47040,见 Doc/library/exceptions.rst 对异常体系的交叉引用改造——bpo-41233 把 Doc/library/errno.rst 与 exceptions 文档互链,此前仅 EINTR/InterruptedError有这种链接);- 内部 expat 升级到 2.4.7(bpo-46932)。
四、Documentation / Tests / Tools-Demos
Documentation 板块的条目偏向工程基建:
- 为内部 asyncio API 补文档(bpo-45099);
- 按 PEP 676 统一更新 PEP 的规范 URL 形式(bpo-47126);
- 澄清 Doc/library/exceptions.rst 中的 errno 说明与 errno 文档互相链接(bpo-41233);
- 阐明
for语句的执行语义(bpo-46033); - 修正 Doc/extending/newtypes_tutorial.rst 中关于
ob_base字段及其访问宏的表述(bpo-45790); - 文档说明:某些情况下
KeyboardInterrupt可能让程序进入不一致状态,并给出规避示例(bpo-42340)。
Tests 板块:测试套件在 Emscripten 平台上全部通过,fork/socket/subprocess 相关测试被跳过(bpo-40280);os.sched_getaffinity/sched_setaffinity 错误路径测试在 FreeBSD 上跳过(bpo-47205);strftime("%4Y") 在 Windows 跳过(避免 debug 构建断言,bpo-47037),并在平台不支持非可移植 glibc 扩展时跳过(bpo-46587);asyncio.to_thread 测试改用 IsolatedAsyncioTestCase(bpo-47104);内部跑测试时恢复 'descriptions'(bpo-46126);os.sendfile 的测试用例从被弃用的 asyncore 迁移到 asyncio(bpo-47015)。
Tools/Demos:bpo-40280 用 Katie Bell 在 python-wasm 项目中的 browser-ui REPL 替换了 Emscripten 的简易 shell,为后续把 CPython 跑在浏览器里提供更像样的交互环境。
五、Build / Windows / macOS:平台构建现代化
Build:
- 引入
--enable-wasm-dynamic-linkingconfigure 选项,为wasm32-emscripten开启dlopen与 MAIN_MODULE/SIDE_MODULE 支持(bpo-40280); - 32 位 WASM 新增 SOABI
wasm32-emscripten与wasm32-wasi,并配套 wasm64 形式(bpo-40280); - 构建 CPython 现在要求支持 IEEE 754 浮点(bpo-46917,Patch by Victor Stinner);
- 新增
regen-configuremake target,用于以官方容器镜像重新生成 configure 脚本(bpo-46973); configure会校验 sqlite3 扩展模块所需的全部 SQLite C API 是否存在(bpo-45774);makesetup自动检测并跳过重复的模块定义,先到先得(bpo-46023);tkinter现在要求 Tcl/Tk 8.5.12 或更新版本(bpo-46996)。
Windows:
- zlib 升级到 v1.2.12,修复 CVE-2018-25032(bpo-47194);bzip2 升级到 1.0.8,修复 CVE-2016-3189 与 CVE-2019-12900(bpo-44549);
- 安装器/构建用 OpenSSL 更新到 1.1.1n(bpo-47024);SQLite 升级到 3.38.1(bpo-46907);
- 允许在 Windows ARM64 上安装
py.exe启动器(bpo-47171); py启动器升级支持-V:company/tag参数以完整支持 PEP 514 注册,并能识别 ARM64 安装;-64后缀弃用但继续表示"任一非 32 位安装";设置PYLAUNCHER_ALLOW_INSTALL后,指定未安装的版本会尝试从 Microsoft Store 安装(bpo-46566);- 安装器改以松散 HTML 文件形式附带文档,而非单个
.chm(bpo-47086); - 修复"Add to PATH"选项在修复安装时可能写错路径的问题,从而规避 CVE-2022-26488(bpo-46948);
- 安装构建在部分失败时现在会以非零退出码正确失败(bpo-47032)。
macOS:修复 framework 构建中 sys._base_executable 的回归,进而修复此类构建下 venv 虚拟环境的问题(bpo-46890);安装器附带 SQLite 同步升级到 3.38.1(bpo-46907)。
六、C API:帧访问公开化与私有 API 收敛
3.11 对 C API 的总体姿态是"该公开的公开、该私有的移进内部头文件、该删的删干净":
- 公开新增:
PyFrame_GetLocals(bpo-42197 语义下用于取f_locals)与PyFrame_GetGlobals/PyFrame_GetBuiltins/PyFrame_GetGenerator(bpo-40421),后者仍见于 Include/cpython/pyframe.h;新增浮点打包/解包系列PyFloat_Pack2/4/8与PyFloat_Unpack2/4/8(bpo-46906,Patch by Victor Stinner),用于在 C 层面序列化/反序列化double; - 移入 internal C API:
_PyFrameEvalFunction类型及_PyInterpreterState_GetEvalFrameFunc()/SetEvalFrameFunc()迁入内部头文件,回调签名改用内部类型_PyInterpreterFrame(bpo-46850);_PyEval_EvalFrameDefault()同样内移并改用_PyInterpreterFrame(bpo-46850); - 删除私有未文档化函数:
_PyEval_CallTracing()(改用公开的sys.call_tracing,bpo-46850)、_PyEval_GetCoroutineOriginTrackingDepth()(改用sys.get_coroutine_origin_tracking_depth,bpo-46850)、_PyEval_GetAsyncGenFirstiter/Finalizer与_PyEval_SetAsyncGenFirstiter/Finalizer(改用sys.get_asyncgen_hooks/sys.set_asyncgen_hooks,bpo-46850)、_PySys_GetObjectId()/_PySys_SetObjectId()(bpo-46987)。
对第三方扩展作者而言,这段历史意味着:如果代码还在调用以上 _Py* 私有函数,在 3.11 之后将无法编译或链接;正确做法是改用上述公开 sys 函数或新增的 PyFrame_* 访问器。
七、结语:从 3.11.0a7 看 CPython 主线的演进方向
把本片段串起来看,3.11.0a7 处在两个重要转型期的交汇点:
-
解释器内核换代:异常匹配/跳转指令拆分、相对跳转化、内联缓存与字节码原地 quickening、帧对象 ownership 显式化,都是 faster-cpython 项目"为专业化与未来 JIT 做准备"的工程铺垫。今天主线上 Include/opcode_ids.h 与 Include/internal/pycore_opcode_metadata.h 中 opcode 的 uop 拆解、
_CHECK_PERIODIC与_JUMP_BACKWARD_NO_INTERRUPT的组合,正是这套设计的直系后代。 -
标准库与平台现代化:asyncio 收敛出 Runner/timeout/Barrier 等更易用的高层设施,re 包化并引入原子组/占有量词,typing 跟进 PEP 646/675,
tomllib加入阵营,一批 PEP 594 遗留模块进入退场倒计时——同时 Emscripten/WASI 被当作一等公民持续加固(信号轮询、调用跳板、SOABI、动态链接选项),为"Python 到处运行"扩展了版图。
对于想深入 3.11 时期的读者,建议将本文件与 Doc/whatsnew/3.11.rst(仓库中的正式 3.11 新特性文档)、Misc/NEWS.d/3.11.0a7.rst 及其前后版本片段对照阅读:NEWS 记录"改了什么",而源码与测试展示"现在长什么样",两者结合即可还原这一里程碑背后完整的设计取舍。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0632
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
video-shotcraftAI宣传片skill,使用 Remotion 制作电影级产品视频:提供106 张镜头配方卡和可复用的视频魔板。适用于 Claude Code 与 Codex以及所有其他智能体Markdown00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00