首页
/ CPython 3.11.0a7 变更全景:异常匹配字节码重构、解释器提速与标准库现代化

CPython 3.11.0a7 变更全景:异常匹配字节码重构、解释器提速与标准库现代化

2026-09-08 21:26:24作者:郦嵘贵Just

本文以 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_MATCHCHECK_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);PRECALLCALL 使用内联缓存,并移除了原先管理非内联缓存的内部机制(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_FastToLocalsWithErrorPyFrame_LocalsToFast 不再在 profile/trace 期间被调用,C 代码访问 PyFrameObjectf_locals 属性应通过公开 API PyFrame_GetLocals 完成;
  • bpo-40421 新增 PyFrame_GetBuiltinsPyFrame_GetGeneratorPyFrame_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):arraybytesbytearrayunicodeobjectrepeat/原地 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.Barriermultiprocessing.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_sendtosock_recvfromsock_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_BLUETOOTHAF_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_compilesre_constantssre_parse 三个内部模块;
  • 原子组与占有量词(bpo-433030):正式支持 (?>...) 原子组以及 *+++?+{m,n}+ 占有量词。这些语法在 _sre 引擎里有明确的内部操作码支持,见 Modules/_sre/sre.c 中的 SRE_OP_POSSESSIVE_REPEAT_ONESRE_OP_POSSESSIVE_REPEATSRE_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):GenericAliasParamSpec 传播行为与 Concatenate 等对齐;
  • Annotated 放宽(bpo-46644):不再要求 typeform 必须可调用,使 typing.Annotated 可以包裹 ParamSpecArgsdataclasses.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.pymode 默认 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.BigEndianUnionctypes.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_CREDSLOCAL_CREDS_PERSISTENTSCM_CREDS2(bpo-46030);补齐非抽象 AF_UNIX 数据报套接字 sockaddr_un 长度中的终止 NUL(bpo-44493);
  • urllibURLopenerURLError 消息中 "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-linking configure 选项,为 wasm32-emscripten 开启 dlopen 与 MAIN_MODULE/SIDE_MODULE 支持(bpo-40280);
  • 32 位 WASM 新增 SOABI wasm32-emscriptenwasm32-wasi,并配套 wasm64 形式(bpo-40280);
  • 构建 CPython 现在要求支持 IEEE 754 浮点(bpo-46917,Patch by Victor Stinner);
  • 新增 regen-configure make 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/8PyFloat_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 处在两个重要转型期的交汇点:

  1. 解释器内核换代:异常匹配/跳转指令拆分、相对跳转化、内联缓存与字节码原地 quickening、帧对象 ownership 显式化,都是 faster-cpython 项目"为专业化与未来 JIT 做准备"的工程铺垫。今天主线上 Include/opcode_ids.hInclude/internal/pycore_opcode_metadata.h 中 opcode 的 uop 拆解、_CHECK_PERIODIC_JUMP_BACKWARD_NO_INTERRUPT 的组合,正是这套设计的直系后代。

  2. 标准库与平台现代化: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 记录"改了什么",而源码与测试展示"现在长什么样",两者结合即可还原这一里程碑背后完整的设计取舍。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
docsdocs
暂无描述
Markdown
900
5.83 K
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
927
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
603
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
397
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.04 K
525