Python 3.15 默认 UTF-8、frozendict 进 builtins:rc1 里会影响现有代码的改动
Python 3.15 是 3.14 之后的下一个稳定版本。rc1 于 2026-08-04 发布,rc2 计划在 2026-09-01;进入 rc 阶段后只接受经过审查的明确 bug 修复,此后 3.15 系列不再有 ABI 变化。对有 C 扩展的项目来说,这是一个可以开始跑 CI 的时间点。
来源:What's new in Python 3.15、Python Insider 发布公告。
PEP 686:默认编码改为 UTF-8,open() 不写 encoding 也走 UTF-8
Python 现在使用 UTF-8 作为默认编码,独立于系统环境变量。不带显式 encoding 的 I/O 操作会使用 UTF-8:
open('flying-circus.txt') # 3.15 起按 UTF-8 打开
open('flying-circus.txt', encoding='utf-8') # 显式写法,跨版本行为一致
这是本次对现有代码影响最直接的一条。在 locale 不是 UTF-8 的机器上(例如 LANG=C、LC_ALL=zh_CN.GBK 的 Linux,或默认代码页非 65001 的 Windows),3.14 及更早版本的 open('f.txt') 会按 locale 编码读写,而 3.15 一律按 UTF-8。结果是原本能跑通、读写 GBK/CP1252 内容的代码,升级后读到同样的字节会抛 UnicodeDecodeError,或者写出的字节序列和以前不一样。
排查这类问题不需要改逻辑,只要把每个隐式依赖 locale 的 open() 补上 encoding=,以及 str.encode()/bytes.decode()、subprocess 文本模式、pathlib.Path.read_text()/write_text() 这些同样吃默认编码的调用点。反过来,如果代码本来就假定 UTF-8,升级后反而不需要再显式传参。
PEP 810:显式惰性导入
显式惰性导入(lazy imports)用于加快启动时间。对启动时间敏感的命令行工具,这条比多数语法变化更值得测。
PEP 814 与 PEP 661:两个新内置类型
PEP 814 — frozendict。 它是 builtins 模块里的不可变类型,创建后不允许修改;不是 dict 的子类,直接继承自 object。当所有键和值都可哈希时,frozendict 可哈希;保留插入顺序,但比较时不考虑顺序。可以直接用作字典键、放进 set,或者当作模块级常量。
PEP 661 — sentinel。 新增 sentinel 内置类型,用于创建表示唯一的哨兵值,表示简洁。哨兵对象在复制时保持 identity,可在类型表达式中配合 | 运算符使用,且当可按模块和名称导入时可被 pickle。
PEP 798:推导式里支持解包
PEP 448 的解包语法扩展到了列表、集合、字典推导式,可以用 * 把任意数量的可迭代对象/字典合并进去:
[*part for part in parts] # 列表推导里解包
{**d for d in dicts} # 字典推导里合并
以前需要在推导式外面套一层 chain() 或多次 update() 的场景,写法可以简化。
PEP 799:profiling 包与 Tachyon 采样剖析器
新增专门的 profiling 包,把 Python 内置剖析工具组织到统一的命名空间下。其中 Tachyon 是高频统计采样剖析器,以 profiling.sampling 提供,可在不修改代码、不重启进程的情况下,对运行中的 Python 进程做低开销性能分析。容器里跑着的服务想临时看一眼热点,不用改启动参数就能采。
PEP 831:默认启用 frame pointers
默认启用 frame pointers,改善系统级可观测性。用 perf、eBPF 之类的系统工具抓 Python 进程栈时,帧链更完整。
JIT 与官方二进制
JIT 编译器有显著升级:相对标准解释器,x86-64 Linux 上有 8–9% 的几何平均性能提升;相对 tail-calling 解释器,AArch64 macOS 上有 12–13% 加速。
官方 Windows 64 位二进制现在使用 tail-calling 解释器;官方 macOS 二进制现在默认安装 free-threading 支持。也就是说 macOS 上的自由线程能力不用再单独处理安装方式,但依赖 GIL 假设的扩展需要自己确认兼容性。
其他这次一起进的改动
- PEP 829:包启动配置文件。
- PEP 728:带类型化额外项的 TypedDict。
- PEP 747:用 TypeForm 标注类型形式。
- PEP 800:类型系统中的不相交基类。
- PEP 782:新的
PyBytesWriterC API,用于创建 Python bytes 对象。 - PEP 803、PEP 820、PEP 793:free-threaded 构建的 Stable ABI(abi3t)及相关 C API。
- PEP 788:C API 防止解释器终结时的使用。
- 改进的错误信息,CLI 输出更多颜色。
已有的包如果带 C 扩展,rc 阶段是验证 abi3t 与 frame pointers/JIT 交互的窗口;纯 Python 项目优先级最高的仍是先把默认编码相关的调用点梳理一遍。