Python 3.15 有什么新变化¶
- 编者:
Hugo van Kemenade
本文介绍了 Python 3.15 相比 3.14 的新增特性。
详情请参阅 更新日志。
备注
预发布版用户应当了解到此文档目前处于草稿状态。 它将随着 Python 3.15 的发布进程不断更新,因此即使已经阅读过较早的版本也仍然值得再次查看。
摘要 -- 发布重点¶
Python 3.15 将是 Python 编程语言的最新稳定发布版,包含多项针对语言、实现和标准库的改变。 最大的变化包括 惰性导入, 冻结字典 和 哨兵 内置类型, UTF-8 作为默认编码格式, 推导式内解包,以及 针对自由线程构建版的稳定 ABI。
标准库的变化包括新的 性能分析软件包,其中有高频统计采样性能分析器 Tachyon,命令行输出具有 更丰富色彩,还有常规的弃用和移除,以及用户友好度和正确性方面的改进。
本文并不试图提供所有新特性的完整规范说明,而是给出一个方便的概览。 要了解完整细节请参阅相应文档,如 库参考 和 语言参考。 要了解某项改变的完整实现和设计理念,请参阅相应新特性的 PEP;但请注意一旦某项特性已完全实现则其 PEP 通常不会再保持更新。
请参阅 Porting to Python 3.15 了解关于从较早的 Python 版本进行升级的指导。
解释器的改进:
标准库中的重大改进:
新的类型标注特性:
C API 的改进:
PEP 803, 820, 793: 针对自由线程构建版的稳定 ABI 及相应的 C API
构建的改变:
发布包的变更:
新的特性¶
PEP 810: 显式惰性导入¶
大型 Python 应用程序经常会有启动时间缓慢的困扰 。此问题有很大一部分是来自导入系统:当一个模块被导入时,Python 必须定位文件,将其从磁盘读入,将其编译为字节码,并执行全部的最高层级代码。 对于具有较深依赖树的应用程序来说,此过程耗时将以秒计,即使在大部分被导入代码在某次运行期间从未被实际使用时也是如此。
开发者要绕过此问题可通过将导入移至函数内部,使用 importlib 按需加载模块,或重新调整代码结构以避免不需要的依赖项。 这些方式有一定效果但会使代码变得更难阅读和维护,使代码库中的 import 语句到处零星散布,并需要严格制定规则才能持续应用。
Python 现在会使用新的 lazy 软关键字通过显式的 lazy 导入提供一种更清晰的解决方案。Python 将延迟实际的模块加载直到所导入的名称首次被使用。 这在组织方面给予你在文件顶部声明所有导入的便利同时只付出你实际使用模块的加载耗时。
lazy 关键字同时适用于 import 和 from ... import 语句。 当你使用 lazy import heavy_module 的写法时,Python 不会立即加载该模块。 作为替代,它将创建一个轻量的代理对象。 实际的模块加载会在你首次访问该名称时透明地发生:
lazy import json
lazy from pathlib import Path
print("Starting up...") # json 和 pathlib 尚未加载
data = json.loads('{"key": "value"}') # json 在这里加载
p = Path(".") # pathlib 在这里加载
这种机制特别适用于在最高层级导入大批模块但在任何给定运行中仅使用它们的一个子集的应用程序。 延迟加载可减少启动反应时间而无需代码重新调整结构或在代码库中零散使用有条件的导入。
对于加载惰性导入模块失败的情况(例如,当模块不存在时),Python 会在首次使用时而不是导入时引发异常。 相关的回溯将同时包括名称被访问的位置和初始的 import 语句,以使对失败的诊断和调试更为直观。
对于在你希望全局启用惰性加载而不必修改源代码的场景,Python 提供了 -X lazy_imports 命令行选项和 PYTHON_LAZY_IMPORTS 环境变量。 两者均接受两种值: all 使所有导入默认为惰性的,而 normal (缺省值) 将遵循源代码中的 lazy 关键字。 sys.set_lazy_imports() 和 sys.get_lazy_imports() 函数现在允许在运行时修改和查询此模式。
想要更有选择性的控制,sys.set_lazy_imports_filter() 接受一个可调用对象决定是否应惰性加载特定的模块。 该过滤器接收三个参数:要导入模块的名称 (或 None),已导入模块的名称,以及 fromlist (或 None 表示用于常规导入)。它应返回 True 表示允许惰性导入,或 False 表示以强制立即加载。 这将允许只让你自己的应用的模块采用惰性导入而而让第三方依赖项采用立即导入的模式:
import sys
def myapp_filter(importing, imported, fromlist):
return imported.startswith("myapp.")
sys.set_lazy_imports_filter(myapp_filter)
sys.set_lazy_imports("all")
import myapp.slow_module # 惰性(匹配过滤器)
import json # 立即(不匹配过滤器)
对于需要以编程方式检测惰性导入的代码来说代理类型本身可通过 types.LazyImportType 访问。
在哪里可以使用 lazy 关键字是有一些限制的。 惰性导入仅在模块作用域上被允许;在函数、类语句体或 try/except/finally 语句块中使用 lazy 会引发 SyntaxError。 星号导入和 future 导入都不能是惰性的 (lazy from module import * 和 lazy from __future__ import ... 都会引发 SyntaxError)。
对于无法直接使用 lazy 关键字的代码(例如,在要支持早于 3.15 的 Python 版本而仍使用 3.15+ 的惰性导入时),一个模块可以定义 __lazy_modules__ 作为完整限定名称字符串的容器。 用于这些模块的常规 import 语句就会被视为惰性的,具有与 lazy 关键字一样的语义:
__lazy_modules__ = ["json", "pathlib"]
import json # 惰性
import os # 仍为立即型
(由 Pablo Galindo Salgado 和 Dino Viehland 在 gh-142349 中贡献。)
参见
完整规范说明及考量见 PEP 810。
PEP 814: 增加 frozendict 内置类型¶
在 builtins 模块中增加了一个新的 immutable 类型 frozendict。 它在创建之后就不允许修改。 frozendict 不是 dict 的子类;它直接继承自 object。 一个 frozendict 在它的键与值都是可哈希对象的情况下就将是 hashable 对象。 frozendict 会保持其插入顺序,但在比较时不会将顺序纳入考虑。
例如:
>>> a = frozendict(x=1, y=2)
>>> a
frozendict({'x': 1, 'y': 2})
>>> a['z'] = 3
Traceback (most recent call last):
File "<python-input-2>", line 1, in <module>
a['z'] = 3
~^^^^^
TypeError: 'frozendict' object does not support item assignment
>>> b = frozendict(y=2, x=1)
>>> hash(a) == hash(b)
True
>>> a == b
True
下述标准库模块已对应更新到接受 frozendict: copy,decimal,json,marshal,plistlib (仅在序列化时),pickle,pprint 和 xml.etree.ElementTree。
eval() 和 exec() 接受 frozendict 作为 globals,而 type() 和 str.maketrans() 接受 frozendict 作为 dict。
通过 isinstance(arg, dict) 检测 dict 类型的代码可以更新为 isinstance(arg, (dict, frozendict)) 以同时接受 frozendict,或更新为 isinstance(arg, collections.abc.Mapping) 以接受包括 MappingProxyType 在内的其他映射类型。
(由 Victor Stinner 和 Donghee Na 在 gh-141510 中贡献。)
参见
完整规范说明及考量见 PEP 814。
PEP 661: 增加 sentinel 内置类型¶
在 builtins 模块中新增 sentinel 类型用于创建带有精确表示的哨兵值。 哨兵对象在拷贝时会保留其标识号,支持在类型表达式中的 | 运算符,并在它们按模块和名称导入时可以被封存。
(由 Jelle Zijlstra 在 gh-148829 中贡献。;PEP 661 由 Tal Einat 撰写。)
参见
更多细节参见 PEP 661。
PEP 799: 专用的性能分析包¶
新增的 profiling 模块将 Python 的内置性能分析工具整合到单独的、统一的命名空间中。 该模块包含:
profiling.tracing: 确定型函数调用追踪(从cProfile重放置)。profiling.sampling: 新增的统计型采样性能分析器(名为 Tachyon)。
cProfile 模块仍作为一个别名保留用于向下兼容。 profile 模块已被弃用并将在 Python 3.17 中移除。
(由 Pablo Galindo 和 László Kiss Kollár 在 gh-138122 中贡献。)
参见
详情见 PEP 799。
Tachyon: 高频统计型采样性能分析器¶
新增一个采样型性能分析器 (Tachyon) 并以 profiling.sampling 作为模块。 此性能分析器将为运行中的 Python 进行启用低开销的性能分析而无需代码修改或进程重启。
不同于测量每次函数调用的确定型性能分析器 (如 profiling.tracing),采样型性能分析器会定期捕获来自运行中进程的栈追踪信息。 此方式可在实际零开销的情况下获得 最高 1,000,000 Hz 的采样率,使其成为 Python 中目前(在其发布时)最快的采样型性能分析器并适用于解决生产环境下的调试性能问题。 这种能力对于传统性能分析方式侵入性过高的生产系统的调试性能问题是理想的解决方案。
关键特性包括:
零开销性能分析: 附加到任何运行中的 Python 进程而不影响其性能。 对于不便重启或减慢的应用程序的生产环境调试来说非常理想。
无需代码修改: 对现有应用程序进行性能分析不必重启。 只需简单地将性能分析器按 PID 指向运行中的进程并开始收集数据。
灵活的目标模式:
按 PID 对运行中的进程进行性能分析 (
attach) - 附加到已运行的应用程序直接运行脚本并进行性能分析 (
run) - 从最初执行位置开始性能分析执行模块并进行性能分析 (
run -m) - 通过运行python -m module对包进行性能分析抓取运行中的进程的一次性快照 (
dump) - 打印每个线程的回溯风格栈信息(或使用--async-aware则为所有的 asyncio 任务)。 适用于调查挂起的进程。
多重性能分析模式: 基于你的性能调查选择衡量指标:
挂钟时间 (
--mode wall, 缺省值): 衡量真实花费时间包括 I/O, 网络等待和阻塞型操作。 使用此模式了解你的程序的实际耗时花费在哪里,包括对外部资源的等待。CPU 时间 (
--mode cpu): 仅衡量激活的 CPU 执行时间,不包括 I/O 等待和阻塞。 使用此模式来确定 CPU 密集型瓶颈并优化计算工作。GIL 持有时间 (
--mode gil): 衡量在持有 Python 的全局解释器锁的情况下花费的时间。 使用此模式来确定在多线程应用程序中哪个线程主导了 GIL 的使用。异常处理时间 (
--mode exception): 仅捕获来自有激活异常的线程的采样。 使用此模式来分析异常处理的开销。
线程感知性能分析: 选择对所有线程 (
-a) 或是只对主线程进行性能分析,在分析多线程应用程序行为时非常关键。多种输出格式: 选择最适合你的工作流程的可视化:
--pstats: 与pstats兼容的详细表格型统计。 显示包含直接和累积采样的函数级耗时。 适用于详细分析以及与现有 Python 性能分析工具的集成。--collapsed: 生成展开的栈追踪信息(每个栈一行)。 此格式专门设计用于通过外部工具如 Brendan Gregg 的 FlameGraph 脚本或 speedscope 来创建火焰图。--flamegraph: 使用 D3.js 生成自包含的交互式 HTML 火焰图。 直接在你的浏览器中打开进行即时可视化分析。 火焰图将显示调用层级结构其中宽度代表耗费的时间,可以很容易地一眼找出性能瓶颈。--gecko: 生成与 Firefox Profiler 兼容的 Gecko Profiler 格式。 将输出上传到 Firefox Profiler 用于基于时间线的分析包括栈图表、标记和网络活动等高级特性。--heatmap: 生成带有行级采样计数的交互式 HTML heatmap 可视化形式。 创建一个目录包含显示源代码层级时间耗费位置的每个 heatmap 文件。
实时交互模式: 具有与 top 类似界面的实时 TUI 性能分析器 (
--live)。 使你的应用程序在带有交互式排序和过滤的情况下运行并监视执行效率。异步感知性能分析: 使用基于任务的栈重建对 async/await 代码进行性能分析 (
--async-aware)。 查看哪些协程最为耗时,并可选择只显示运行中的任务或全部任务包括等待中的任务。操作码级性能分析: 收集字节码的操作码信息用于在指令层级进行性能分析 (
--opcodes)。 显示哪些字节码指令正在执行,包括来自适配解释器的专门化。
请参阅 profiling.sampling 获取完整文档,包括所有可用的输出格式、性能分析模式以及配置选项。
(由 Pablo Galindo 和 László Kiss Kollár 在 gh-135953 和 gh-138122 中贡献。).)
PEP 831: 默认启用帧指针¶
现在 CPython 会在受支持的平台上默认附带帧指针进行构建。 这将使用编译器旗标 -fno-omit-frame-pointer 和 -mno-omit-leaf-frame-pointer,使得原生栈展开更快速且对系统性能分析器、调试器、崩溃分析工具和基于 eBPF 观察能力工具来说更可靠。
这些旗标是通过 sysconfig 对外暴露的,因此由使用 Python 构建配置的工具所构建的扩展模块默认会继承帧指针。 这样的传播是有意设计的:混合 Python 与原生性能分析需要一个跨解释器、扩展模块、嵌入应用程序以及原生库的连续帧指针链。
重要
第三方构建后端和原生构建系统应当在它们使用 Pytho 的 sysconfig 值时保留这些旗标。 编译 C, C++, Rust 或其他原生代码而不继承 Python 的编译器旗标的构建系统应当自行启用等价的帧指针旗标。 只要有一个构建时不带帧指针的原生组件就可能破坏整个 Python 进程的栈展开。
(由 Pablo Galindo Salgado 和 Savannah Ostrowski 在 gh-149201 中贡献;PEP 831 由 Pablo Galindo Salgado, Ken Jin, Savannah Ostrowski 和 Diego Russo 撰写。)
参见
更多细节参见 PEP 831。
PEP 798: 推导式中的解包¶
列表、集合与字典推导式,以及生成器表达式现在都支持使用 * 和 ** 进行解包。 这将 PEP 448 的解包语法扩展到推导式,提供了将任意多个可迭代对象或字典合并至一个展平的结构的新语法。 这种新语法是嵌套推导式, itertools.chain() 和 itertools.chain.from_iterable() 等的直接替代物。 例如:
>>> lists = [[1, 2], [3, 4], [5]]
>>> [*L for L in lists] # 等价于 [x for L in lists for x in L]
[1, 2, 3, 4, 5]
>>> sets = [{1, 2}, {2, 3}, {3, 4}]
>>> {*s for s in sets} # 等价于 {x for s in sets for x in s}
{1, 2, 3, 4}
>>> dicts = [{'a': 1}, {'b': 2}, {'a': 3}]
>>> {**d for d in dicts} # 等价于 {k: v for d in dicts for k,v in d.items()}
{'a': 3, 'b': 2}
生成器表达式可以类似地进行解包从多个可迭代对象产生值:
>>> gen = (*L for L in lists) # 等价于 (x for L in lists for x in L)
>>> list(gen)
[1, 2, 3, 4, 5]
这项改变也将扩展至异步生成器表达式,举例来说,它使得 (*a async for a in agen()) 等价于 (x async for a in agen() for x in a)。
(由 Adam Hartz 在 gh-143055 中贡献。)
参见
详情见 PEP 798。
PEP 829: 包启动配置文件¶
当未给出 -S 时将由 site 模块加载,.pth 文件 可包含同时扩展 sys.path 和以 import 打头(跟一个空格或制表符)时执行任意代码的行。 后者的功能可能存在问题,因为难以确定在 Python 启动时会执行什么。
作为提升对预启动可执行代码审计能力的一个步骤,Python 3.15 引入了包含 pkg.mod:callable 形式的入口点规格说明的 .start 文件 其中 pkg.mod 是给定可调用对象的导入路径。 当 Python 启动时,将定位可调用对象并不带参数地进行调用。
在 .pth 文件中的添加 import 行的做法已被静默地弃用。 当找到匹配 .start 文件时,.pth 文件中的 import 行将被忽略。 .pth 文件中的 sys.path 扩展行没有改变。
site 模块还提供了 site.StartupState 用于多个 site 目录的批量启动处理,以确保所有静态路径扩展在执行任何启动代码之前被应用。 site.main() 会隐式地使用该类的实例在正常的解释器启动期间批量处理所有启动配置文件。 需要相同批处理行为的调用者可以直接构建一个 StartupState 并通过 addsitedir(), addusersitepackages() 和 addsitepackages() 驱动它,然后在批处理结束时调用 process() 一次。
PEP 803: 针对自由线程构建的稳定 ABI¶
以 稳定 ABI 作为目标的 C 扩展现在可以针对新的 自由线程构建版稳定 ABI (或称 abi3t) 进行编译,这将使其能兼容 CPython 的 自由线程构建版。 这通常需要对源代码进行不小的更改;具体而言:
切换至 PEP 697 中引入的 (Python 3.12),如取负值的
basicsize和PyObject_GetTypeData(),而不是将PyObject作为实例结构体的一部分;并且从
PyInit_函数切换至新的导出钩子PyModExport_*,它是在 PEP 793 中专门为此目的而引入的,使用新的在 PEP 820 中引入的PySlot结构体。
请注意稳定 ABI 并未提供 CPython 所必须提供的所有功能。 无法切换至 abi3t 的扩展应当继续分别针对现有的稳定 ABI (abi3) 以及自由线程版本专属 ABI (cp315t) 进行构建。
针对自由线程构建版的稳定 ABI 通常应当在构建工具中选择(举例来说,比如 Setuptools, meson-python, scikit-build-core 或 Maturin 等)。 在编写时,这些工具 并不 支持 abi3t。 如果你的工具是这种情况,则要为 cp315t 单独编译。 如果你没有使用构建工具 -- 或是正在编写这样的工具 -- 你可以像在 针对稳定 ABI 编译 中介绍的那样通过设置宏 Py_TARGET_ABI3T 来选择 abi3t。
一份关于切换到 abi3t 的实用 迁移指南。
参见
更多细节参见 PEP 803。
PEP 788: 围绕解释器终结化对 C API 的保护¶
在 C API 中,解释器终结化 对许多扩展来说都是一个问题,因为 附加 线程状态会永久性地挂起线程,导致死锁和其他出错问题。 此外,历史上在使用一个解释器之前安全地检测它是否激活是不可能的,当一个线程并发地删除另一个线程正尝试附加的解释器时会造成程序崩溃。
现在有几个新的 API 套件可以绕过这些问题:
此外 PyGILState 族中的 API (最主要的是 PyGILState_Ensure() 和 PyGILState_Release()) 已被设为 soft deprecated。 目前 没有 移除它们的计划,现有的代码将继续可用,但在未来的 Python 版本中将不会有新的 PyGILState。
(由 Peter Bierma 在 gh-149101 中贡献。)
参见
详情见 PEP 788。
改进的错误消息¶
现在当访问的属性不存在于某个对象上,但类似的属性可通过它的某个成员访问时解释器会在
AttributeError异常中提供更有帮助的建议。举例来说,如果对象具有的一个属性本身暴露了所请求的名称,错误消息将建议通过该内部属性来访问它:
from dataclasses import dataclass from math import pi @dataclass class Circle: radius: float @property def area(self) -> float: return pi * self.radius**2 class Container: def __init__(self, inner: Circle) -> None: self.inner = inner circle = Circle(radius=4.0) container = Container(circle) print(container.area)
现在运行此代码将产生更清楚的建议:
Traceback (most recent call last): File "example.py", line 18, in <module> print(container.area) ^^^^^^^^^^^^^^ AttributeError: 'Container' object has no attribute 'area'. Did you mean '.inner.area' instead of '.area'?
当内置类型上的
AttributeError没有莱文斯坦距离内的近似匹配时,错误消息现在会检查一个由其他语言(JavaScript、Java、Ruby、C#)中常见方法名称组成的静态表并建议 Python 的等价形式:>>> [1, 2, 3].push(4) Traceback (most recent call last): ... AttributeError: 'list' object has no attribute 'push'. Did you mean '.append'? >>> 'hello'.toUpperCase() Traceback (most recent call last): ... AttributeError: 'str' object has no attribute 'toUpperCase'. Did you mean '.upper'?
当 Python 等价形式是一个语言构造而非方法时,提示将直接描述该构造:
>>> {}.put("a", 1) Traceback (most recent call last): ... AttributeError: 'dict' object has no attribute 'put'. Use d[k] = v.
当在一个不可变类型上调用可变方法时,提示将建议相应的可变类型:
>>> (1, 2, 3).append(4) Traceback (most recent call last): ... AttributeError: 'tuple' object has no attribute 'append'. Did you mean to use a 'list' object?
这些提示也将作用于内置类型的子类。
(由 Matt Van Horn 在 gh-146406 中贡献。)
解释器现在会在
delattr()因属性缺失而失败时尝试提供建议。 当使用的属性名称非常接近现有的属性时,解释器将在错误消息中建议正确的属性名称。 例如:>>> class A: ... pass >>> a = A() >>> a.abcde = 1 >>> del a.abcdf Traceback (most recent call last): ... AttributeError: 'A' object has no attribute 'abcdf'. Did you mean: 'abcde'?
(由 Nikita Sobolev 和 Pranjal Prajapati 在 gh-136588 中贡献。)
一些不正确地使用术语 "argument" 的错误消息已被修正。 (由 Stan Ulbrych 在 gh-133382 中贡献。)
其他语言特性修改¶
Python 现在使用 UTF-8 作为默认编码格式,而不依赖于系统的环境。 这意味着未显式指定编码格式的 I/O 操作,例如
open('flying-circus.txt')将会使用 UTF-8。 UTF-8 是受到广泛支持的 Unicode 字符编码格式,它已成为用于表示文本的 事实 标准,包括因特网上几乎所有的网页、编程语言等等。此设置仅在未给出
encoding参数时会被应用。 为获得最佳的 Python 版本兼容性,请确保始终提供显式的encoding参数。 可选编码格式警告 可被用来标识可能受到此项更改影响的代码。 特殊的encoding='locale'参数将使用当前语言区域的编码格式,自 Python 3.10 起已受到支持。要保留之前版本的行为,Python 的 UTF-8 模式可通过
PYTHONUTF8=0环境变量或-X utf8=0命令行选项来禁用。(由 Adam Turner 在 gh-133711 中贡献;PEP 686 由 Inada Naoki 撰写。)
参见
更多细节参见 PEP 686。
解释器帮助 (如
python --help) 现在将以彩色显示。 这可通过 环境变量 来控制。 (由 Hugo van Kemenade 在 gh-148766 中贡献。)不可引发的异常现在默认以彩色高亮显示。 这可通过 环境变量 来控制。 (由 Peter Bierma 在 gh-134170 中贡献。)
在 argparse, ast, calendar, difflib, http.server, pickletools, PyREPL tab completion, python --help, sqlite3, timeit, tokenize, unraisable exceptions 和 stdlib (ast, compileall, doctest, gzip, inspect, json.tool, pdb, profiling.sampling, random, regrtest, sqlite3, timeit, tokenize, trace, unittest, uuid, zipapp, zipfile) 的 CLI 帮助中添加更多色彩。
现在
ImportError和ModuleNotFoundError的__repr__()当 "name" 和 "path" 在构造时作为关键字参数给出时会将其显示为name=<name>和path=<path>。 (由 Serhiy Storchaka, Oleg Iarygin 和 Yoav Nir 在 gh-74185 中贡献。)现在
__dict__和__weakref__描述器将使用每解释器单独描述器实例,并在所有需要它们的类型间共享。 这将加快类创建速度,并有助于避免引用循环。 (由 Petr Viktorin 在 gh-135228 中贡献。)现在
-W选项和PYTHONWARNINGS环境变量可以指定正则表达式代替字符串字面值来匹配警告消息和模块名称,这时相应的字段要以正斜杠 (/) 打头和结尾。 (由 Serhiy Storchaka 在 gh-134716 中贡献。)接受 timestamp 或 timeout 参数的函数现在可接受任意实数 (如
Decimal和Fraction),而不只是整数或浮点数,虽然这并不会提升精度。 (由 Serhiy Storchaka 在 gh-67795 中贡献。)
增加
bytearray.take_bytes(n=None, /)从bytearray获取字节串而无需拷贝。 这允许优化需要在处理可变字节缓冲区返回bytes的代码比如数据缓冲、网络协议解析、编码、解码和压缩等。 下面列出了可以用take_bytes()来优化的常见代码模式。建议的优化重构¶ 描述
旧写法
新写法
def read() -> bytes: buffer = bytearray(1024) ... return bytes(buffer)
def read() -> bytes: buffer = bytearray(1024) ... return buffer.take_bytes()
清空缓冲区并获取字节串
buffer = bytearray(1024) ... data = bytes(buffer) buffer.clear()
buffer = bytearray(1024) ... data = buffer.take_bytes()
以指定的分隔符拆分缓冲区
buffer = bytearray(b'abc\ndef') n = buffer.find(b'\n') data = bytes(buffer[:n + 1]) del buffer[:n + 1] assert data == b'abc\n' assert buffer == bytearray(b'def')
buffer = bytearray(b'abc\ndef') n = buffer.find(b'\n') data = buffer.take_bytes(n + 1)
以指定分隔符拆分缓冲区;丢弃分隔符之后的内容
buffer = bytearray(b'abc\ndef') n = buffer.find(b'\n') data = bytes(buffer[:n]) buffer.clear() assert data == b'abc' assert len(buffer) == 0
buffer = bytearray(b'abc\ndef') n = buffer.find(b'\n') buffer.resize(n) data = buffer.take_bytes()
(由 Cody Maloney 在 gh-139871 中贡献。)
许多与编译或解析 Python 代码相关的函数,比如
compile(),ast.parse(),symtable.symtable()和importlib.abc.InspectLoader.source_to_code()等,现在允许传入模块名称。 这在无歧义地基于模块名称 过滤 语法警告时是必需的。 (由 Serhiy Storchaka 在 gh-135801 中贡献。)允许为任何类定义 __dict__ 和 __weakref__ __slots__。 (由 Serhiy Storchaka 在 gh-41779 中贡献。)
允许为派生自
tuple的类(包括由collections.namedtuple()创建的类定义任何 __slots__。 (由 Serhiy Storchaka 在 gh-41779 中贡献。)现在
slice类型支持下标操作,使其成为 generic type。 (由 James Hilton-Balfe 在 gh-128335 中贡献。)现在
memoryview类支持 float complex 和 double complex C 类型:分别对应格式字符'Zf'和'Zd'。 (由 Victor Stinner 在 gh-146151 和 gh-148675 中贡献。)允许
bytes.replace()的 count 参数为关键字参数。 (由 Stan Ulbrych 在 gh-147856 中贡献。)现在
match字面值模式中可接受单目加号,对应对单目减号的现有支持。 (由 Bartosz Sławecki 在 gh-145239 中贡献。).)导入系统现在会以层级顺序获取每模块锁(父包在其子包之前)。 这修复了长期存在的一个导入
pkg.sub的线程和另一个导入pkg.sub.mod的线程在pkg/sub/__init__.py导入pkg.sub.mod时可能发生相互阻塞的死锁问题。 (由 Gregory P. Smith 在 gh-83065 中贡献。)使用
.so后缀的稳定 ABI 扩展的文件名现在可以包括由多架构标识组成的元组,例如foo.abi3-x86-64-linux-gnu.so。 这将允许针对多种架构的稳定 ABI 扩展同时安装在同一目录中,不会相互冲突,就像常规动态扩展一样。 (由 Stefano Rivera 在 gh-122931 中贡献。)模块上的
__cached__属性,自 3.13 版起被弃用,已不再被导入系统纳入考虑。 请改用__spec__.cached。 (由 Brett Cannon 在 gh-97879 中贡献。)请注意
__loader__和__package__属性也已被弃用并计划要移除。
默认的交互式 shell¶
现在 Tab 补全将按对象类别以彩色显示,该功能基于 fancycompleter。 设置
PYTHON_BASIC_COMPLETER可回退至rlcompleter。 颜色还可通过 环境变量 来控制。 (由 Antonio Cuni 和 Pablo Galindo 在 gh-130472 中贡献。)Tab 补全现在会在
from ... import语句中提供模块属性建议。 只有在模块被导入后才会有属性建议,因此 stdlib 模块将被自动导入;而对于其他模块,当第二次按下 Tab 时补全器才会导入它们。 (由 Loïc Simon 和 Pablo Galindo 在 gh-140870 中贡献。)
新增模块¶
math.integer¶
该模块提供对整数参数的数学函数的访问 (PEP 791)。 (由 Serhiy Storchaka 在 gh-81313 中贡献。)
改进的模块¶
argparse¶
现在
BooleanOptionalAction动作支持单连字符长选项和替代前缀字符。 (由 Serhiy Storchaka 在 gh-138525 中贡献。).)将
argparse.ArgumentParser的 suggest_on_error 形参默认值改为True。 这将默认启用为输入错误的参数提供建议。 (由 Jakob Schluse 在 gh-140450 中贡献。)在
ArgumentParser描述和结语文本中增加反引号标记支持以便在彩色输出被启用时高亮显示内联代码。 (由 Savannah Ostrowski 在 gh-142390 中贡献。)将反引号标记扩展至参数
help文本并增加对双重反引号(RST 内联字面值样式)的支持。 (由 Hugo van Kemenade 在 gh-149375 中贡献。)
array¶
ast¶
asyncio¶
增加
TaskGroup.cancel以允许提前终结任务分组,例如,当任务目标已达成或者其服务不再需要时。 在之前版本中这会涉及反直觉的特殊处理比如由一个额外任务引发自定义异常然后在退出任务分组时抑制该异常。 (由 John Belmonte 在 gh-127214 中贡献。).)
base64¶
在
z85encode()中增加 pad 形参。 (由 Hauke Dämpfling 在 gh-143103 中贡献。).)在
b32encode(),b32decode(),b32hexencode(),b32hexdecode(),b64encode(),b64decode(),urlsafe_b64encode()和urlsafe_b64decode()中增加 padded 形参。 (由 Serhiy Storchaka 在 gh-73613 中贡献。)在
b16encode(),b32encode(),b32hexencode(),b64encode(),b85encode()和z85encode()中增加 wrapcol 形参。 (由 Serhiy Storchaka 在 gh-143214 和 gh-146431 中贡献。)在
b16decode(),b32decode(),b32hexdecode(),b64decode(),b85decode()和z85decode()中增加 ignorechars 形参。 (由 Serhiy Storchaka 在 gh-144001 和 gh-146431 中贡献。)在
b32decode(),b32hexdecode(),b64decode(),a85decode(),b85decode()和z85decode()中增加 canonical 形参,用于拒绝具有非零填充位或其他非规范形式的编码格式。 (由 Gregory P. Smith 在 gh-146311 中贡献。)
binascii¶
增加针对 Base32 编码格式的函数:
(由 James Seo 在 gh-146192 中贡献。)
增加针对 Ascii85, Base85 和 Z85 编码格式的函数:
(由 James Seo 和 Serhiy Storchaka 在 gh-101178 中贡献。)
在
b2a_base32(),a2b_base32(),b2a_base64()和a2b_base64()中增加 padded 形参。 (由 Serhiy Storchaka 在 gh-73613 中贡献。)在
b2a_base64()中增加 wrapcol 形参。 (由 Serhiy Storchaka 在 gh-143214 中贡献。)在
b2a_base64()和a2b_base64()中增加 alphabet 形参。 (由 Serhiy Storchaka 在 gh-145980 中贡献。)在
a2b_hex(),unhexlify()和a2b_base64()中增加 ignorechars 形参。 (由 Serhiy Storchaka 在 gh-144001 和 gh-146431 中贡献。)在
a2b_base64()中增加 canonical 形参以拒绝带有非零填充位的编码格式。 (由 Gregory P. Smith 在 gh-146311 中贡献。)
calendar¶
calendar的 命令行 文本输出将使用更多彩色。 这可以通过 环境变量 来控制。 (由 Hugo van Kemenade 在 gh-148352 中贡献。)calendar的 命令行 HTML 输出现在接受 year-month 选项:python -m calendar -t html 2009 06。 (由 Pål Grønås Drange 在 gh-140212 中贡献。)由
calendar.HTMLCalendar类生成的日期页现在支持深色模式并已迁移至 HTML5 标准已提升可访问性。 (由 Jiahao Li 和 Hugo van Kemenade 在 gh-137634 中贡献。)
collections¶
concurrent.futures¶
改进了当
concurrent.futures.ProcessPoolExecutor中的子进程突然终结时的错误报告。 结果回溯信息现在会告诉你被终结进程的 PID 和退出代码。 (由 Jonathan Berg 在 gh-139486 中贡献。)
contextlib¶
在
ExitStack和contextlib.AsyncExitStack中增加对任意描述器__enter__(),__exit__(),__aenter__()和__aexit__()的支持,以便与with和async with语句保持一致。 (由 Serhiy Storchaka 在 gh-144386 中贡献。)现在
ContextDecorator和AsyncContextDecorator(以及被用作装饰器的contextmanager()和asynccontextmanager()) 能检测生成器函数、协程函数以及异常生成器函数并在迭代或 await 过程中使上下文管理器保持打开。 在此之前上下文管理器会在生成器或协程对象被创建后立即退出。 (由 Alex Grönholm 和 Gregory P. Smith 在 gh-125862 中贡献。)
ctypes¶
将
c_float_complex,c_double_complex和c_longdouble_complex的_type_从F,D和G更改为Zf,Zd和Zg以与 NumPy 兼容。 (由 Victor Stinner 在 gh-148675 中贡献。)
dataclasses¶
针对已生成
__init__方法的标注不再包括内部类型名称。 (由 David Ellis 在 gh-137530 中贡献。)
dbm¶
向
dbm.dumb和dbm.sqlite3添加新的reorganize()方法用于回收先前被已删除条目占用的未使用空闲空间。 (由 Andrea Oliveri 在 gh-134004 中贡献。).)
difflib¶
向
difflib.unified_diff()引入可选的 color 形参,启用类似于 git diff 的彩色输出。 这可通过 环境变量 来控制。 (由 Douglas Thor 在 gh-133725 中贡献。)改进了由
difflib.HtmlDiff类生成的 HTML diff 页面的样式,并将输出迁移至 HTML5 标准。 (由 Jiahao Li 在 gh-134580 中贡献。)
email¶
现在当
EmailMessage由于地址头中存在非 ASCII 邮箱地址 (mailbox) 而无法准确展平时邮箱生成器会引发一个错误。 用于支持 Email Address Internationalization (EAI) 的选项的相关讨论见EmailPolicy.utf8。 (由 R David Murray 和 Mike Edmunds 在 gh-122540 中贡献。)
faulthandler¶
在
faulthandler.enable(),faulthandler.dump_traceback(),faulthandler.dump_traceback_later()和faulthandler.register()中增加 max_threads 形参。 (由 Eric Froemling 在 gh-149085 中贡献。)
functools¶
现在
singledispatchmethod()支持非 descriptor 可调用对象。 (由 Serhiy Storchaka 在 gh-140873 中贡献。)现在
singledispatchmethod()会在它包装了一个常规方法并且作为类属性被调用时在第二个参数上执行分派。 (由 Bartosz Sławecki 在 gh-143535 中贡献。)
gc¶
hashlib¶
确保哈希函数肯定会作为
hashlib的属性存在并始终 可用 即使它们在运行时由于缺少后端实现而无法运作。 例如,hashlib.md5当 OpenSSL 不可用且 Python 构建不带 MD5 支持时将不再引发AttributeError。 (由 Bénédikt Tran 在 gh-136929 中贡献。)
http.client¶
向
HTTPConnection和HTTPSConnection构造器增加了新的 max_response_headers 仅限关键字形参。 该形参覆盖了允许的响应标头默认最大数量。 (由 Alexander Enrique Urieles Nieto 在 gh-131724 中贡献。)
http.server¶
由 命令行接口 所使用的
BaseHTTPRequestHandler日志记录默认显示彩色。 这可以通过 环境变量 来控制。 (由 Hugo van Kemenade 在 gh-146292 中贡献。)增加
default_content_type和--content-type命令行选项以允许对带有未知扩展的默认Content-Type标头进行自定义。 (由 John Comeau 和 Hugo van Kemenade 在 gh-113471 中贡献。)为
SimpleHTTPRequestHandler添加新的extra_response_headers关键字参数以支持 HTTP 响应中的自定义标头。 (由 Anton I. Sipos 在 gh-135057 中贡献。)为 python -m http.server 命令行接口添加
-H/--header选项以在 HTTP 响应中支持自定义标头。 (由 Anton I. Sipos 在 gh-135057 中贡献。)
importlib.metadata¶
在此之前,当访问一个不包含元数据文件的分发版元数据目录时,
metadata()和Distribution.metadata将会返回一个空的PackageMetadata对象就如同该文件存在但为空一样 。现在,则会引发MetadataNotFound异常。 请参阅 importlib_metadata#493 了解相关背景和理由并参阅 gh-143387 了解对于兼容性问题的思路。 (由 Jason R. Coombs 贡献。)
inspect¶
json¶
向
load()和loads()函数添加 array_hook 形参:允许针对 JSON 字面值数组类型的回调以便自定义作为结果的已解码对象中的 Python 列表。 将组合的frozendict传给 object_pairs_hook 形参并将tuple传给 array_hook 将产生一个深度嵌套的不可变 Python 结构来表示 JSON 数据。 (由 Joao S. O. Bueno 在 gh-146440 中贡献。)
locale¶
现在
setlocale()支持带@修饰符的语言代码。@修饰符将不会再从getlocale()中静默地移除,而是被包括在语言代码中。 (由 Serhiy Storchaka 在 gh-137729 中贡献。)弃用
locale.getdefaultlocale()函数。 (由 Victor Stinner 在 gh-130796 中贡献。)
math¶
增加
math.isnormal()和math.issubnormal()函数。 (由 Sergey B Kirpichev 在 gh-132908 中贡献。)增加
math.fmax(),math.fmin()和math.signbit()函数。 (由 Bénédikt Tran 在 gh-135853 中贡献。)
mimetypes¶
增加更多的 MIME 类型。 (由 Benedikt Johannes, Charlie Lin, Foolbar, Gil Forcada 和 John Franey 在 gh-144217, gh-145720, gh-140937, gh-139959, gh-145698, gh-145718, gh-145918 和 gh-144213 中贡献。)
将
application/x-texinfo重命名为application/texinfo。 (由 Charlie Lin 在 gh-140165 中贡献。)将
.ai文件的 MIME 类型更改为application/pdf。 (由 Stan Ulbrych 在 gh-141239 中贡献。)
mmap¶
现在
mmap.mmap在 Windows 上有一个 trackfd 形参;如果它是False,则对应于 fileno 的文件句柄将不会被复制。 (由 Serhiy Storchaka 在 gh-78502 中贡献。)增加
mmap.mmap.set_name()方法用于在 Linux 内核支持 PR_SET_VMA_ANON_NAME (Linux 5.17 或更新版本) 的情况下标注匿名内存映射。 (由 Donghee Na 在 gh-142419 中贡献。)
os¶
在带有 glibc 2.28 以上版本的 Linux 4.11 以上内核版本上增加
os.statx()。 (由 Jeffrey Bosboom 和 Victor Stinner 在 gh-83714 中贡献。)现在
os.makedirs()函数增加了一个 parent_mode 形参以允许指定中间目录的模式。 这可被用来通过传入parent_mode=mode与 Python 3.6 及更早版本的行为相匹配。 (由 Zackery Spytz 和 Gregory P. Smith 在 gh-86533 中贡献。)
os.path¶
在
realpath()中增加对 all-but-last 模式的支持。 (由 Serhiy Storchaka 在 gh-71189 中贡献。)传给
os.path.realpath()的 strict 形参接受一个新值os.path.ALLOW_MISSING。 如果使用该值,则FileNotFoundError以外的错误将被重新引发;结果路径可能会缺失但它将不会有符号链接。 (由 Petr Viktorin 为 CVE 2025-4517 贡献。)
pathlib¶
现在
pathlib.Path.mkdir()增加了 parent_mode 形参以允许在parents=True时指定中间目录的模式。 (由 Gregory P. Smith 在 gh-86533 中贡献。)
pdb¶
pickle¶
增加对封存私有方法和嵌套类的支持。 (由 Zackery Spytz 和 Serhiy Storchaka 在 gh-77188 中贡献。)
pickletools¶
pickletools命令行接口的输出默认使用彩色。 这可以通过 环境变量 进行控制。 (由 Hugo van Kemenade 在 gh-149026 中贡献。)
pprint¶
为
pprint.pprint(),pprint.pformat(),pprint.pp()增加 expand 关键字参数。 如为真值,当提供了 indent 时输出将使用类似美化打印的json.dumps()格式。 (由 Stefan Todoran, Semyon Moroz 和 Hugo van Kemenade 在 gh-112632 中贡献。)为
pprint增加 t-字符串支持。 (由 Loïc Simon 和 Hugo van Kemenade 在 gh-134551 中贡献。)
re¶
现在
re.prefixmatch()和相应的re.Pattern.prefixmatch()作为现有的已设为 soft deprecated 的re.match()和re.Pattern.match()API 的替代性的、更明白的显式名称被添加。 这样做的目的是为了遵循 Python 之禅的 "明白胜于隐晦" 原则以消除对 match 具体含义理解所造成的混淆。 大多数其他语言的正则表达式库都使用名为 match 的 API 来表示 Python 一直以来所称的 search。 (由 Gregory P. Smith 在 gh-86519 中贡献。)
resource¶
增加新的常量:
RLIMIT_NTHR,RLIMIT_UMTXP,RLIMIT_THREADS,RLIM_SAVED_CUR和RLIM_SAVED_MAX。 (由 Serhiy Storchaka 在 gh-137512 中贡献。)
shelve¶
socket¶
增加针对 ISO-TP CAN 协议的常量。 (由 Patrick Menschel 和 Stefan Tatschner 在 gh-86819 中贡献。)
sqlite3¶
ssl¶
通过
ssl.HAS_PSK_TLS13指明ssl模块是否支持 TLSv1.3 中的 "External PSKs",具体描述见 RFC 9258。 (由 Will Childs-Klein 在 gh-133624 中贡献。)增加一些新方法用于管理 SSL 密钥协议所使用的分组:
ssl.SSLContext.set_groups()用于设置允许执行密钥协商的分组,扩展了之前的ssl.SSLContext.set_ecdh_curve()方法。 这个新 API 提供了列出多个分组的功能并支持固定字段以及 ECDH 曲线以外的后量子群组。 此方法还可用于控制在 TLS 握手时要发送哪些密钥分量。ssl.SSLSocket.group()将返回在 TLS 握手完成后被选定用于对当前连接执行密钥协商的分组。 此调用需要 OpenSSL 3.2 或更高版本。ssl.SSLContext.get_groups()将返回一个与当前上下文中设置的最小和最大 TLS 版本兼容的所有可用密钥协商分组的列表。 此调用需要 OpenSSL 3.5 或更高版本。
(由 Ron Frederick 在 gh-136306 中贡献。)
新增一个
ssl.SSLContext.set_ciphersuites()方法用于设置 TLS 1.3 密码套件。 对于 TLS 1.2 或更早版本,应当继续使用ssl.SSLContext.set_ciphers()。 这两个调用均可在同一上下文中执行而所选的密码套件将取决于建立连接时协商的 TLS 版本。 (由 Ron Frederick 在 gh-137197 中贡献。)增加一些新方法用于管理签名算法:
ssl.get_sigalgs()将返回所有可用 TLS 签名算法的列表。 此调用需要 OpenSSL 3.4 或更高版本。ssl.SSLContext.set_client_sigalgs()可设置基于证书的客户身份验证所允许的签名算法。ssl.SSLContext.set_server_sigalgs()可设置服务器在完成 TLS 握手时允许使用的签名算法。ssl.SSLSocket.client_sigalg()将返回用于在当前连接上为客户端身份验证选择的签名算法。 此调用需要 OpenSSL 3.5 或更高版本。ssl.SSLSocket.server_sigalg()将返回在当前连接上为服务器完成 TLS 握手而选定的签名算法。 此调用需要 OpenSSL 3.5 或更高版本。
(由 Ron Frederick 在 gh-138252 中贡献。)
subprocess¶
subprocess.Popen.wait(): 在timeout不为None且平台支持时,将使用高效的事件驱动机制来等等进程终结:Linux >= 5.3 使用
os.pidfd_open()+select.poll()。macOS 及 BSD 变种使用
select.kqueue()+KQ_FILTER_PROC+KQ_NOTE_EXIT。Windows 继续使用
WaitForSingleObject(无变化)。
如果这些机制都不可用,该函数将回退到传统的忙状态循环(非阻塞调用和短暂休眠)。 (由 Giampaolo Rodola 在 gh-83069 中贡献。)
symtable¶
增加
symtable.Function.get_cells()和symtable.Symbol.is_cell()方法。 (由 Yashp002 在 gh-143504 中贡献。)
sys¶
增加
sys.abi_info命名空间来改善对 ABI 信息的访问。 (由 Klaus Zimmermann 在 gh-137476 中贡献。)
sys.monitoring¶
现在可以针对每个代码对象启用或禁用 其他事件 (
PY_THROW,PY_UNWIND,RAISE,EXCEPTION_HANDLED和RERAISE)。 对于这些事件之一从回调返回DISABLE将为整个代码对象(为当前工具)禁用事件,而不是像之前版本那样引发ValueError。 (由 Gabriele N. Tornetta 在 gh-146182 中贡献。)
tarfile¶
data_filter()现在会对符号链接目标进行规范化处理,以避免路径遍历攻击。(由 Petr Viktorin 在 gh-127987 和 CVE 2025-4138 中贡献。)当一个目录被移除或被另一种文件替代时
extractall()现在会跳过修复目录属性。 (由 Petr Viktorin 在 gh-127987 和 CVE 2024-12718 中贡献。).)在将一个链接(硬链接或符号链接)替换为另一个归档成员的副本,以及在修复目录属性时
extract()和extractall()现在会(重新)应用提取过滤器。 前者将引发一个新的异常,LinkFallbackError。 (由 Petr Viktorin 为 CVE 2025-4330 和 CVE 2024-12718 贡献。)当
errorlevel()为零时extract()和extractall()将不再提取被拒绝的成员。 (由 Matt Prodani 和 Petr Viktorin 在 gh-112887 和 CVE 2025-4435 中贡献。)现在
extract()和extractall()在 Windows 上会将符号链接目标中的斜杠替换为反斜杠以防止创建损坏的链接。 (由 Christoph Walcher 在 gh-57911 中贡献。)现在
gettarinfo()在 Windows 上会将符号链接目标中的反斜杠替换为斜杠以符合 tar 格式标准。 (由 Daniele Nicolodi 在 gh-151669 中贡献。)
threading¶
增加
serialize_iterator,synchronized_iterator()和concurrent_tee()以支持对生成器和迭代器的并发访问。 (由 Raymond Hettinger 在 gh-124397 中贡献。)
timeit¶
tkinter¶
现在
tkinter.Text.search()方法支持两个附加参数: nolinestop 允许跨越行边界继续搜索;以及 strictlimits 限制在指定范围内进行搜索。 (由 Rihaan Meher 在 gh-130848 中贡献。)引入一个新方法
tkinter.Text.search_all()。 此方法允许使用 Tcl 的-all和-overlap选项来搜索所有符合特定模式的匹配项。 (由 Rihaan Meher 在 gh-130848 中贡献。)新增
pack_content(),place_content()和grid_content()方法来使用具有新名称的 Tk 命令(在 Tk 8.6 中引入)以取代使用具有过时名称的 Tk 命令的*_slaves()方法。 (由 Serhiy Storchaka 在 gh-143754 中贡献。)增加
Event属性user_data用于 Tk 虚拟事件并增加detail用于Enter,Leave,FocusIn,FocusOut和ConfigureRequest事件。 (由 Matthias Kievernagel 和 Serhiy Storchaka 在 gh-47655 中贡献。)
tokenize¶
tomllib¶
现在
tomllib模块支持 TOML 1.1.0。 这是个向下兼容的更新,意味着所有合法的 TOML 1.0.0 文档都将以同样的方式被解析。根据 official TOML changelog,有下列改变:
允许在内联表格中使用换行符和末尾逗号。
在此之前内联表格必须位于单行内且不能以末尾逗号结束。 现在已放宽限制因此以下代码将是有效的:
tbl = { key = "a string", moar-tbl = { key = 1, }, }
为基础字符串添加
\xHH表示法用于 255 以下的码点,以及\e表示法用于转义字符:null = "null byte: \x00; letter a: \x61" csi = "\e["
现在 datetime 和 time 值中的秒数是可选的。 以下写法现在均有效:
dt = 2010-02-03 14:15 t = 14:15
(由 Taneli Hukkinen 在 gh-142956 中贡献。)
types¶
将穿透写入
locals()代理类型作为types.FrameLocalsProxyType对外暴露。 这代表frame.f_locals属性的类型,具体描述见 PEP 667。 (由 Peter Bierma 在 gh-136492 中贡献。).)
typing¶
PEP 747: 增加
TypeForm,这是一个新的用于标注本身属于类型表达式的值的特殊形式。TypeForm[T]表示 "一个描述T(或可赋值给T的类型) 的类型形式对象"。 在运行时,TypeForm(x)将简单地返回x,这将允许类型形式值的显式标注而无需更改行为。这有助于那些接受用户提供类型表达式 (例如
int,str | None,TypedDict的类工,或list[int]) 的库对外暴露精确的签名:from typing import Any, TypeForm def cast[T](typ: TypeForm[T], value: Any) -> T: ...
(由 Jelle Zijlstra 在 gh-145033 中的贡献。)
PEP 728: 在
TypedDict中添加对 closed 和 extra_items 类参数的支持。 如 closed 为真值则TypedDict不允许超出类代码体中指定范围的额外键,如TypedDict带有extra_items则允许值为指定类型的任意额外条目。 (由 Angela Liss 在 gh-137840 中贡献。)类似
class ExtraTypeVars(P1[S], Protocol[T, T2]): ...的代码现在将引发TypeError,因为S未在Protocol形参中列出。 (由 Nikita Sobolev 在 gh-137191 中贡献。)类似
class B2(A[T2], Protocol[T1, T2]): ...的代码现在会正确处理类型形参顺序:它将是(T1, T2),而非此前在运行时被错误地推断为的(T2, T1)。 (由 Nikita Sobolev 在 gh-137191 中贡献。)PEP 800: 添加
@typing.disjoint_base,这个新装饰器可将类标记为互斥基类。 这个高级特性的主要目的是允许类型检查器如实反映定义为内置对象或为已编译扩展的类型的运行时语义。 如果一个类C为互斥基类,那么该类的子类将无法自不是C的父类或子类的其他互斥基类继承。 (由 Jelle Zijlstra 在 gh-148639 中贡献。)现在
TypeVarTuple接受bound,covariant,contravariant和infer_variance关键字参数,与TypeVar和ParamSpec的接口相匹配。bound的语义在规范中尚未定义。
unicodedata¶
Unicode 数据库已更新为 Unicode 17.0.0。 (由 Benjamin Peterson 在 gh-138706 中贡献。)
增加
unicodedata.isxidstart()和unicodedata.isxidcontinue()函数用于检查某个字符是否开始或继续一个 Unicode 标准附录 #31 标识符。 (由 Stan Ulbrych 在 gh-129117 中贡献。)增加
iter_graphemes()函数用于根据在 Unicode 标准附录 #29, "Unicode 文本段" 中定义的规则对音素簇进行迭代。 增加grapheme_cluster_break(),indic_conjunct_break()和extended_pictographic()函数用于获取与上述算法相关的字符属性。 (由 Serhiy Storchaka 和 Guillaume Sanchez 在 gh-74902 中贡献。)增加
block()函数用于返回分配给字符的 Unicode 区块。 (由 Stan Ulbrych 在 gh-66802 中贡献。)
unittest¶
现在
unittest.TestCase.assertLogs()可接受一个格式化器来控制如何格式化消息。 (由 Garry Cairns 在 gh-134567 中贡献。)unittest.TestCase.assertWarns()和unittest.TestCase.assertWarnsRegex()不会再隐藏与指定类别或正则表达式不相匹配的警告。 嵌套的上下文管理器现在已受到支持。 (由 Serhiy Storchaka 在 gh-143231 中贡献。)
urllib.parse¶
为
urlsplit(),urlparse()和urldefrag()函数添加 missing_as_none 形参。 为urlunsplit()和urlunparse()函数添加 keep_empty 形参。 这允许在空的和未定义 URI 组件之间进行区分并保留空的组件。 (由 Serhiy Storchaka 在 gh-67041 中贡献。)
venv¶
在 POSIX 平台上,platlib 目录将在创建虚拟环境时根据需要被创建,而不是使用
lib64 -> lib符号链接。 这意味着在sys.platlibdir不等于lib的平台上虚拟环境的 purelib 和 platlib 将不再共享同一个lib目录。 (由 Rui Xi 在 gh-133951 中贡献。)
warnings¶
在
warnings.warn_explicit()中如果未传入 module 参数则会改进按模块过滤的操作。 现在它不但会针对去除.py的文件名,还会针对从与文件名不同的父目录开始构造的模块名称(去除/__init__.py,.py,在 Windows 上,.pyw也会被去除)测试警告过滤器中的模块正则表达式。 (由 Serhiy Storchaka 在 gh-135801 中贡献。)
wave¶
在
wave中增加对 IEEE 浮点 WAVE 音频 (WAVE_FORMAT_IEEE_FLOAT) 的支持。增加
wave.Wave_read.getformat(),wave.Wave_write.getformat()和wave.Wave_write.setformat()用于显式的帧格式处理。wave.Wave_write.setparams()同时接受包括format的 7 元组和用于向下兼容的 6 元组 (默认为WAVE_FORMAT_PCM)。现在
WAVE_FORMAT_IEEE_FLOAT输出将包括一个fact块,这是非 PCM WAVE 格式所要求的。
(由 Lionel Koenig 和 Michiel W. Beijen 在 gh-60729 中贡献。)
webbrowser¶
xml¶
增加
xml.is_valid_name()函数用于检测字符串是否可被用作 XML 中的元素或属性名称。 (由 Serhiy Storchaka 在 gh-139489 中贡献。)增加
xml.is_valid_text()函数用于检测字符串是否可被用于 XML 文档。 (由 Serhiy Storchaka 在 gh-139489 中贡献。)
xml.parsers.expat¶
为 xmlparser 对象添加
SetAllocTrackerActivationThreshold()和SetAllocTrackerMaximumAmplification()用于微调针对 Expat 解析器内部不适当的动态内存使用量的保护。 (由 Bénédikt Tran 在 gh-90949 中贡献。)为 xmlparser 对象添加
SetBillionLaughsAttackProtectionActivationThreshold()和SetBillionLaughsAttackProtectionMaximumAmplification()用于微调针对 billion laughs 攻击的防护。 (由 Bénédikt Tran 在 gh-90949 中贡献。)
zlib¶
允许通过
adler32_combine()来合并两个 Adler-32 校验和。 (由 Callum Attryde 和 Bénédikt Tran 在 gh-134635 中贡献。)允许通过
crc32_combine()来合并两个 CRC-32 校验和。 (由 Bénédikt Tran 在 gh-134635 中贡献。)
性能优化¶
现在
mimalloc被用作原始内存分配比如通过PyMem_RawMalloc()的进行的内存分配的默认分配器以在 自由线程构建上 上达到更好的性能。 (由 Kumar Aditya 在 gh-144914 中贡献。)
base64 和 binascii¶
现在得益于简单的 CPU 管线优化 CPython 的底层 base64 实现编码有 2x 的提速而解码有 3x 的提速。 (由 Gregory P. Smith 和 Serhiy Storchaka 在 gh-143262 中贡献。)
针对 Ascii85, Base85 和 Z85 编码格式的实现已用 C 语言重写。 编码和解码速度现在提升了两个数量级并且内存消耗也减少了两个数量级。 (由 James Seo 和 Serhiy Storchaka 在 gh-101178 中贡献。)
针对 Base32 的实现已用 C 语言重写。 编码和解码速度现在提升了两个数量级。 (由 James Seo 在 gh-146192 中贡献。).)
csv¶
现在
csv.Sniffer.sniff()定界符检测获得至多 1.6x 的加速。 (由 Maurycy Pawłowski-Wieroński 在 gh-137628 中贡献。)
升级的实验性 JIT 编译器¶
Results from the pyperformance
benchmark suite report a
7-8%
geometric mean performance improvement for the JIT over the standard CPython
interpreter built with all optimizations enabled on x86-64 Linux. On AArch64
macOS, the JIT has an
11-12%
speedup over the tail calling interpreter
with all optimizations enabled. The speedups for JIT
builds versus no JIT builds range from roughly 15% slowdown to over
100% speedup (ignoring the unpack_sequence microbenchmark) on
x86-64 Linux and AArch64 macOS systems.
对 JIT 的主要升级有:
LLVM 21 构建时依赖
新的追踪前端
JIT 中基本的注册分配
更多的 JIT 优化
GDB 和 GNU
backtrace()展开支持更好的机器码生成
LLVM 21 构建时依赖
现在 JIT 编译器将为构建时的 stencil 生成使用 LLVM 21。 与往常一样,LLVM 仅在启用 JIT 构建 CPython 时才是必需的;运行 Python 的最终用户无需安装 LLVM。 针对所有受支持平台安装 LLVM 的指导见 JIT 编译器文档。 (由 Savannah Ostrowski 在 gh-140973 中贡献。)
新的追踪前端
现在 JIT 编译器相比 Python 3.14 支持更多的字节码操作和控制流,从而能够在更多的代码上实现性能加速。 例如,现在 3.15 JIT 编译器能处理简单 Python 对象创建。 重载操作和生成器也得到部分支持。 这一改进得益于经过彻底重构能够记录代码实际执行路径的 JIT 追踪前端,而不是像之前的实现那样仅进行估算。 (由 Ken Jin 在 gh-139109 中贡献。 对 Windows 的支持由 Mark Shannon 在 gh-141703 中贡献。)
JIT 中基本的注册分配
已向 JIT 编译器的优化器添加一个基本的寄存器分配形式。 这使得 JIT 编译器能完全避免特定的栈操作而是直接在寄存器上操作。 这允许 JIT 通过避免对内存的读写操作来产生更高效的执行轨迹。 (由 Mark Shannon 在 gh-135379 中贡献。)
更多的 JIT 优化
现在会执行更多的`常量传播<https://en.wikipedia.org/wiki/Constant_folding>`__ 。这意味着当JIT编译器检测到某些用户代码会导致常量 时,JIT编译器可以对该代码进行简化。(由Ken Jin和Savannah Ostrowski在:gh:132732 中贡献。)
引用计数 会在确保安全的情况下尽量避免。 这通常会减少 Python 中大多数操作的开销。 (由 Ken Jin, Donghee Na, Zheao Li, Hai Zhu, Savannah Ostrowski, Reiden Ong, Noam Cohen, Tomas Roun, PuQing, Cajetan Rodrigues, 和 Sacul 在 gh-134584 中贡献。)
通过追踪对象的唯一引用,JIT 优化器现在可以略去引用计数更新并对整数和浮点数执行原地操作。 (由 Reiden Ong 和 Pieter Eendebak 在 gh-143414 和 gh-146306 中贡献。)
现在 JIT 优化器支持的操作数量相比 3.14 大幅增加。 (由 Kumar Aditya, Ken Jin, Jiahao Li 和 Sacul 在 gh-131798 中贡献。)
GDB 和 GNU backtrace() 展开支持
在受支持的 Linux ELF 平台上 JIT 编译器现在会将所生成的机器码的展开信息发布到 GDB 接口。 当 libgcc 帧注册功能可用时,同样的展开信息也会为 GNU backtrace() 栈遍历器执行注册。 这允许使用这些机制的原生调试器、崩溃处理器和诊断工具能通过 JIT 帧进行展开而不是在生成的机器码处停止。 (由 Diego Russo 和 Pablo Galindo Salgado 在 gh-146071 和 gh-149104 中贡献。)
更好的机器码生成
现在 JIT 编译器的机器码生成器可为 x86-64 和 AArch64 macOS 以及 Linux 目标平台生成更优质的机器码。 总体而言,与targets. In general, users should experience lower memory usage for generated machine code and more efficient machine code versus 3.14 相比用户相当能体验到生成的机器码内存占用更低且机器码运行效率更高。 (由 Brandt Bucher 在 gh-136528 和 gh-135905 中贡献。) 针对 AArch64 的实现由 Mark Shannon 在 gh-139855 中贡献。 针对 AArch64 的额外优化由 Mark Shannon 和 Diego Russo 在 gh-140683 和 gh-142305 中贡献。)
可维护性
JIT 优化器的操作已得到简化。 这是通过对 JIT 数据结构进行重构来实现的。 (由 Zhongtian Zheng 在 gh-148211 中以及 Hai Zhu 在 gh-143421 中贡献。)
移除¶
ast¶
当所需的参数被活力或是传入了无法映射到 AST 节点上的字段的关键字参数时 AST 节点 的构造器现在会引发
TypeError。 此前自 Python 3.13 开始这些情况会引发DeprecationWarning。 (由 Brian Schubert 和 Jelle Zijlstra 在 gh-137600 和 gh-105858 中贡献。)
collections.abc¶
collections.abc.ByteString已从collections.abc.__all__移除。collections.abc.ByteString自 Python 3.12 起已被弃用,并计划在 Python 3.17 中移除。 (由 Alex Waygood 在 gh-118803 中贡献。)
ctypes¶
移除了未写入文档的函数
ctypes.SetPointerType(),它自 Python 3.13 起已被弃用。 (由 Bénédikt Tran 在 gh-133866 中贡献。)
datetime¶
现在
strptime()会在格式字符串包含不带年份指示符的%d(月份日序号) 时引发ValueError。 这种做法自 Python 3.13 起已被弃用。 (由 Stan Ulbrych 和 Gregory P. Smith 在 gh-70647 中贡献。)
glob¶
移除了未写入文档的
glob.glob0()和glob.glob1()函数,它们自 Python 3.13 起已被弃用。 请改用glob.glob()并将一个目录传给其 root_dir 参数。 (由 Barney Gale 在 gh-137466 中贡献。)
http.server¶
移除
CGIHTTPRequestHandler类并从 python -m http.server 命令行接口移除--cgi旗标。 它们在 Python 3.13 中被弃用。 (由 Bénédikt Tran 在 gh-133810 中贡献。)
importlib¶
Loader及其子类的load_module()方法已被移除。 当其在自定义子类上被定义时将不再被导入系统所调用。 此方法自 Python 3.4 起已被弃用而应改用exec_module()。 (由 Brett Cannon 在 gh-97850 中贡献。)
importlib.resources¶
移除
importlib.resources.files()函数中已被弃用的package形参。 (由 Semyon Moroz 在 gh-138044 中贡献。).)
pathlib¶
移除已被弃用的
pathlib.PurePath.is_reserved()。 在 Windows 上请使用os.path.isreserved()来检测保留路径。 (由 Nikita Sobolev 在 gh-133875 中贡献。)
platform¶
移除了
platform.java_ver()函数,它自 Python 3.13 起已被弃用。 (由 Alexey Makridenko 在 gh-133604 中贡献。)
sre_*¶
移除了
sre_compile,sre_constants和sre_parse模块。 (由 Stan Ulbrych 在 gh-135994 中贡献。)
sysconfig¶
移除了
sysconfig.is_python_build()的 check_home 形参。 (由 Filipe Laíns 在 gh-92897 中贡献。)
threading¶
types¶
从
types.CodeType中移除了codeobject.co_lnotab,它自 Python 3.12 起已根据 PEP 626 弃用。 (由 Nikita Sobolev 在 gh-134690 中贡献。)
typing¶
typing.ByteString已从typing.__all__移除。typing.ByteString自 Python 3.9 起已被弃用,并计划在 Python 3.17 中移除。 (由 Alex Waygood 在 gh-118803 中贡献。)用于创建
NamedTuple类的未写入文档的关键字参数语法 (例如Point = NamedTuple("Point", x=int, y=int)) 已不再受支持。 请改用基于类的语法或函数式语法。 (由 Bénédikt Tran 在 gh-133817 中贡献。)使用
TD = TypedDict("TD")或TD = TypedDict("TD", None)来构造零字段的TypedDict类型已不再受支持。 请改用class TD(TypedDict): pass或TD = TypedDict("TD", {})。 (由 Bénédikt Tran 在 gh-133823 中贡献。)移除了被弃用的
@typing.no_type_check_decorator。 (由 Nikita Sobolev 在 gh-133601 中贡献。)
wave¶
移除了
Wave_read和Wave_write类的getmark(),setmark()和getmarkers()方法,它们自 Python 3.13 起已被弃用。 (由 Bénédikt Tran 在 gh-133873 中贡献。)
zipimport¶
移除已被弃用的
zipimport.zipimporter.load_module()。 请改用zipimport.zipimporter.exec_module()。 (由 Jiahao Li 在 gh-133656 中贡献。)
弃用¶
新的弃用¶
ast:-
在
b64decode()和urlsafe_b64decode()中接受+和/字符带替换字母表的做法现已被弃用。 在未来的 Python 版本中它们会成为严格模式下的错误并会在非严格模式下被丢弃。 (由 Serhiy Storchaka 在 gh-125346 中贡献。)
CLI:
弃用
-b和-bb命令行选项并计划在 Python 3.17 中将它们设为空操作。 它们是主要用于 Python 2 -> 3 转换的辅助工具。 从 Python 3.17,将不再针对这些情况引发BytesWarning;请改用类型检查器。(由 Nikita Sobolev 在 gh-136355 中贡献。)
-
在运行时以下语句现在将导致发出
DeprecationWarning:from collections.abc import ByteStringimport collections.abc; collections.abc.ByteString
如果
collections.abc.ByteString被子类化或是被用作传给isinstance()或issubclass()则DeprecationWarning会被发出,但如果只是被导入或是从collections.abc模块访问则不会提前发出。 (由 Alex Waygood 在 gh-118803 中贡献。)
-
Morsel.js_output和BaseCookie.js_output已被弃用并将在 Python 3.19 中移除。 请改用Morsel.output或BaseCookie.output。 (由 kishorhange111 在 gh-148849 中贡献。)
-
修改
IMAP4.file的做法现已被弃用并计划在 Python 3.19 中移除。 该属性现已不再使用并且修改其值 不会 显式地关闭当前文件。 (由 Bénédikt Tran 在 gh-142307 中贡献。)
-
profile模块已被弃用并将在 Python 3.17 中移除。 请改用profiling.tracing,它提供了兼容的 API。 详情参见 PEP 799。 (由 Pablo Galindo 和 László Kiss Kollár 在 gh-138122 中贡献。)
re:现在
re.match()和re.Pattern.match()已被设为 soft deprecated 而应改用新的re.prefixmatch()和re.Pattern.prefixmatch()API,它们作为替代性的、更明白的显式名称被添加进来。 这样做的目的是为了遵循 Python 之禅的 "明白胜于隐晦" 原则以消除对 match 具体含义理解所造成的混淆。 大多数其他语言的正则表达式库都使用名为 match 的 API 来表示to mean what Python 一直以来所称为的 search。我们 没有 计划移除旧的
match()名称,因为它已在代码中使用超过 30。 支持较旧 Python 的代码应当继续使用match(),而新的代码应当首选prefixmatch()。 参见 prefixmatch() vs. match()。(由 Gregory P. Smith 在 gh-86519 以及 Hugo van Kemenade 在 gh-148100 中贡献。)
-
调用
Struct.__new__()时不再必需参数的做法现已被弃用并将在 Python 3.20 中移除。 在已初始化的Struct对象上调用__init__()方法的做法已被弃用并将在 Python 3.20 中移除。(由 Sergey B Kirpichev 和 Serhiy Storchaka 在 gh-143715 中贡献。).)
使用
'F'和'D'类型代码的做法现已被设为 soft deprecated 并应改用两字母形式'Zf'和'Zd'。 (由 Sergey B Kirpichev 在 gh-121249 中贡献。).)
-
在运行时以下语句现在将导致发出
DeprecationWarning:from typing import ByteStringimport typing; typing.ByteString
如果
typing.ByteString被子类化或是被用作传给isinstance()或issubclass()的第二个参数则会发出``DeprecationWarning``,但如果只是从typing模块导入或访问则不会提前发出。 (由 Alex Waygood 在 gh-118803 中贡献。)在未显式地使用
runtime_checkable()来装饰但继承自运行时可检测协议类的协议类上调用isinstance()和issubclass()检测的做法已被弃用。 在 Python 3.20 中这会引发TypeError。(由 Bartosz Sławecki 在 gh-132604 中贡献。)
-
webbrowser.MacOSXOSAScript已被弃用而应改用webbrowser.MacOS并计划在 Python 3.17 中移除。 (由 Jeff Lyon 在 gh-137586 中贡献。)
__version__:在这些标准库模块中的
__version__,version和VERSION属性已被弃用并将在 Python 3.20 中移除。 请改用sys.version_info。ctypes.macholiblogging(__date__也已被弃用)xml.sax.expatreader
(由 Hugo van Kemenade 和 Stan Ulbrych 在 gh-76007 中贡献。)
计划在 Python 3.16 中移除¶
导入系统:
当设置
__spec__.loader失败时在模块上设置__loader__的做法已被弃用。在 Python 3.16 中,__loader__将不会再被设置或是被导入系统或标准库纳入考虑。
-
'u'格式代码 (wchar_t) 自 Python 3.3 起已在文档中弃用并自 Python 3.13 起在运行时弃用。对于 Unicode 字符请改用'w'格式代码 (Py_UCS4)。
-
asyncio.iscoroutinefunction()已被弃用并将在 Python 3.16 中移除,请改用inspect.iscoroutinefunction()。 (由李佳昊和 Kumar Aditya 在 gh-122875 中贡献。)asyncio策略系统已被弃用并将在 Python 3.16 中移除。具体而言,是弃用了下列类和函数:用户应当使用
asyncio.run()或asyncio.Runner并附带 loop_factory 以使用想要的事件循环实现。例如,在 Windows 上使用
asyncio.SelectorEventLoop:import asyncio async def main(): ... asyncio.run(main(), loop_factory=asyncio.SelectorEventLoop)
(由 Kumar Aditya 在 gh-127949 中贡献。)
-
对布尔类型
~True或~False执行按位取反的操作自 Python 3.12 起已被弃用,因为它会产生奇怪和不直观的结果 (-2和-1)。请改用not x来对布尔值执行逻辑否操作。 对于需要对下层整数执行按位取反操作的少数场合,请显式地将其转换为int(~int(x))。
-
调用
functools.reduce()的 Python 实现并传入 function 或 sequence 作为关键字参数的做法自 Python 3.14 起已被弃用。
-
使用 strm 参数对自定义日志记录处理器提供支持的做法已被弃用并计划在 Python 3.16 中移除。改为使用 stream 参数定义处理器。 (由 Mariusz Felisiak 在 gh-115032 中贡献。)
-
有效扩展以 '.' 开头或对于
mimetypes.MimeTypes.add_type()为空。未加点的扩展已弃用,在 Python 3.16 中将引发ValueError。 (由 Hugo van Kemenade 在 gh-75223 中贡献。)
-
ExecError异常自 Python 3.14 起已被弃用。它自 Python 3.4 起就未被shutil中的任何函数所使用,现在是RuntimeError的一个别名。
-
Class.get_methods方法自 Python 3.14 起被弃用。
sys:_enablelegacywindowsfsencoding()函数自 Python 3.13 起被弃用。请改用PYTHONLEGACYWINDOWSFSENCODING环境变量。
-
自 Python 3.14 起
sysconfig.expand_makefile_vars()函数已被弃用。请使用sysconfig.get_paths()的vars参数代替。
-
未写入文档也未被使用的
TarFile.tarfile属性自 Python 3.13 起被弃用。
计划在 Python 3.17 中移除¶
-
使用不带年份的包含
%e(月份日期序号) 的格式字符串的strptime()调用自 Python 3.15 起已被弃用。 (由 Stan Ulbrych 在 gh-70647 中贡献。)
-
collections.abc.ByteString计划在 Python 3.17 中移除。使用
isinstance(obj, collections.abc.Buffer)来在运行时测试obj是否实现了 缓冲区协议。要用于类型标注,则使用Buffer或者显式指明你的代码所支持的类型的并集 (例如bytes | bytearray | memoryview)。ByteString原本是想作为bytes和bytearray的超类型的抽象基类提供。 不过,由于该 ABC 从未有过任何方法,知道一个对象是ByteString的实例并不能真正告诉你有关该对象的任何有用信息。 其他常见缓冲区类型如memoryview同样不能被当作是ByteString的子类型(无论是在运行时还是对于静态类型检查器)。
-
将非 ascii encoding 名称传给
encodings.normalize_encoding()的做法已被弃用并计划在 Python 3.17 中移除。 (由 Stan Ulbrych 在 gh-136702 中贡献。)
-
profile模块已被弃用并将在 Python 3.17 中移除。 请改用profiling.tracing,它提供了兼容的 API。 详情参见 PEP 799。 (由 Pablo Galindo 和 László Kiss Kollár 在 gh-138122 中贡献。)
-
webbrowser.MacOSXOSAScript已被弃用并改用webbrowser.MacOS。 (gh-137586)
-
在 Python 3.14 之前,旧式的联合是通过私有类
typing._UnionGenericAlias实现的。实现已不再需要该类,但为向后兼容性保留了该类,并计划在 Python 3.17 中删除。用户应使用记录在案的内省助手函数,如typing.get_origin()和typing.get_args(),而不是依赖于私有的实现细节。typing.ByteString自 Python 3.9 起已被弃用,计划在 Python 3.17 中移除。使用
isinstance(obj, collections.abc.Buffer)来在运行时测试obj是否实现了 缓冲区协议。要用于类型标注,则使用Buffer或者显式指明你的代码所支持的类型的并集 (例如bytes | bytearray | memoryview)。ByteString原本是想作为bytes和bytearray的超类型的抽象基类提供。 不过,由于该 ABC 从未有过任何方法,知道一个对象是ByteString的实例并不能真正告诉你有关该对象的任何有用信息。 其他常见缓冲区类型如memoryview同样不能被当作是ByteString的子类型(无论是在运行时还是对于静态类型检查器)。
-
tkinter.Variable的方法trace_variable(),trace()(trace_variable()的别名),trace_vdelete()和trace_vinfo(),自 Python 3.14 起已被弃用,计划在 Python 3.17 中移除。 请改用trace_add(),trace_remove()和trace_info()。 (由 Serhiy Storchaka 在 gh-120220 中贡献。)
计划在 Python 3.18 中移除¶
计划在 Python 3.19 中移除¶
-
http.cookies.Morsel.js_output()已被弃用并将在 Python 3.19 中移除。http.cookies.BaseCookie.js_output()已被弃用并将在 Python 3.19 中移除。
-
修改
IMAP4.file的做法现已被弃用并计划在 Python 3.19 中移除。 该属性现已不再使用并且修改其值不会自动关闭当前文件。在 Python 3.14 之前,该属性被用于为
IMAP4实现相应的read()和readline()方法但在此之后情况已发生改变。
计划在 Python 3.20 中移除¶
调用
struct.Struct的__new__()方法不带 format 参数的做法已被弃用并将在 Python 3.20 中移除。 在已初始化的Struct对象上调用__init__()方法的做法已被弃用并将在 Python 3.20 中移除。(由 Sergey B Kirpichev 和 Serhiy Storchaka 在 gh-143715 中贡献。).)
在这些标准库模块中的
__version__,version和VERSION属性已被弃用并将在 Python 3.20 中移除。 请改用sys.version_info。ctypes.macholiblogging(__date__也已被弃用)xml.sax.expatreader
(由 Hugo van Kemenade 和 Stan Ulbrych 在 gh-76007 中贡献。)
由 PEP 829 定义的弃用:
为在
name.pth文件中找到的import行产生警告。name.pth文件将不再以默认语言区域编码格式解码。 它们 必须 使用utf-8-sig编码。
(由 Barry Warsaw 在 gh-148641 中贡献。)
ast:创建抽象 AST 节点 (如
ast.AST或ast.expr) 的做法已被弃用并将在 Python 3.20 中引发错误。
-
在未显式地使用
runtime_checkable()来装饰但继承自运行时可检测协议类的协议类上调用isinstance()和issubclass()检测的做法已被弃用。 在 Python 3.20 中这会引发TypeError。(由 Bartosz Sławecki 在 gh-132604 中贡献。)
计划在未来版本中移除¶
以下 API 将会被移除,尽管具体时间还未确定。
-
嵌套参数组和嵌套互斥组已被弃用。
将未写入文档的关键字参数 prefix_chars 传递给
add_argument_group()的做法现在已被弃用。argparse.FileType类型转换器已弃用。
-
生成器:
throw(type, exc, tb)和athrow(type, exc, tb)签名已被弃用:请改用throw(exc)和athrow(exc),即单参数签名。目前 Python 接受数字类字面值后面紧跟关键字的写法,例如
0in x,1or x,0if 1else 2。它允许像[0x1for x in y]这样令人困惑且有歧义的表达式 (它可以被解读为[0x1 for x in y]或者[0x1f or x in y])。如果数字类字面值后面紧跟关键字and,else,for,if,in,is和or中的一个将会引发语法警告。在未来的版本中它将改为语法错误。 (gh-87999)对
__index__()和__int__()方法返回非 int 类型的支持:将要求这些方法必须返回int的严格子类的实例。对
__float__()方法返回float的子类的支持:将要求这些方法必须返回float的实例。对
__complex__()方法返回complex的子类的支持:将要求这些方法必须返回complex的实例。传入一个复数作为
complex()构造器中的 real 或 imag 参数的做法现在已被弃用;它应当仅作为单个位置参数被传入。(由 Serhiy Storchaka 在 gh-109218 中贡献。)
calendar:calendar.January和calendar.February常量已被弃用并由calendar.JANUARY和calendar.FEBRUARY替代。 (由 Prince Roshan 在 gh-103636 中贡献。)codecs:codecs.open()请改用open()。 (gh-133038)codeobject.co_lnotab: 改用codeobject.co_lines()方法。-
utcnow(): 使用datetime.datetime.now(tz=datetime.UTC)。utcfromtimestamp(): 使用datetime.datetime.fromtimestamp(timestamp, tz=datetime.UTC)。
gettext: 复数值必须是一个整数。-
cache_from_source()debug_override 形参已被弃用:改用 optimization 形参。
-
EntryPoints元组接口。返回值中隐式的
None。
mailbox: 对 StringIO 输入和文本模式的使用已被弃用,改用 BytesIO 和二进制模式。os: 在多线程的进程中调用os.register_at_fork()。os.path:os.path.commonprefix()已弃用,对于路径前缀请使用os.path.commonpath()。os.path.commonprefix()函数被弃用是由于其误导性的名称和模块。 使用该函数获取路径前缀是不安全的,尽管它被包括在一个用于操作路径的模块中,使用此函数很容易意外地将路径遍历安全漏洞引入 Python 程序中。pydoc.ErrorDuringImport: 使用元组值作为 exc_info 形参的做法已被弃用,应使用异常实例。re: 现在对于正则表达式中的数字分组引用和分组名称将应用更严格的规则。现在只接受 ASCII 数字序列作为数字引用。 字节串模式和替换字符串中的分组名称现在只能包含 ASCII 字母和数字以及下划线。 (由 Serhiy Storchaka 在 gh-91760 中贡献。)shutil:rmtree()的 onerror 形参在 Python 3.12 中已被弃用;请改用 onexc 形参。ssl选项和协议:ssl.SSLContext不带 protocol 参数的做法已被弃用。ssl.SSLContext:set_npn_protocols()和selected_npn_protocol()已被弃用:请改用 ALPN。ssl.OP_NO_SSL*选项ssl.OP_NO_TLS*选项ssl.PROTOCOL_SSLv3ssl.PROTOCOL_TLSssl.PROTOCOL_TLSv1ssl.PROTOCOL_TLSv1_1ssl.PROTOCOL_TLSv1_2ssl.TLSVersion.SSLv3ssl.TLSVersion.TLSv1ssl.TLSVersion.TLSv1_1
threading的方法:threading.Condition.notifyAll(): 使用notify_all().threading.Event.isSet(): 使用is_set()。threading.Thread.isDaemon(),threading.Thread.setDaemon(): 使用threading.Thread.daemon属性。threading.Thread.getName(),threading.Thread.setName(): 使用threading.Thread.name属性。threading.currentThread(): 使用threading.current_thread()。threading.activeCount(): 使用threading.active_count()。
内部类
typing._UnionGenericAlias不再用于实现typing.Union。 为了保持与使用该私有类的用户的兼容性,将至少在 Python 3.17 之前提供兼容性垫片。 (由 Jelle Zijlstra 在 gh-105499 中贡献。)unittest.IsolatedAsyncioTestCase: 从测试用例返回不为None的值的做法已被弃用。urllib.parse已弃用的函数:改用urlparse()splitattr()splithost()splitnport()splitpasswd()splitport()splitquery()splittag()splittype()splituser()splitvalue()to_bytes()
wsgiref:SimpleHandler.stdout.write()不应执行部分写入。xml.etree.ElementTree: 对Element进行真值检测已被弃用。在未来的发布版中它将始终返回True。建议改用显式的len(elem)或elem is not None检测。sys._clear_type_cache()已弃用,请改用sys._clear_internal_caches()。
软弃用¶
尚无计划移除 soft deprecated API。
现在
re.match()和re.Pattern.match()已被设为 soft deprecated 而应改用新的re.prefixmatch()和re.Pattern.prefixmatch()API,它们作为替代性的、更明白的显式名称被添加进来。 这样做的目的是为了遵循 Python 之禅的 "明白胜于隐晦" 原则以消除对 match 具体含义理解所造成的混淆。 大多数其他语言的正则表达式库都使用名为 match 的 API 来表示to mean what Python 一直以来所称为的 search。我们 没有 计划移除旧的
match()名称,因为它已在代码中使用超过 30。 支持较旧 Python 的代码应当继续使用match(),而新的代码应当首选prefixmatch()。 参见 prefixmatch() vs. match()。(由 Gregory P. Smith 在 gh-86519 以及 Hugo van Kemenade 在 gh-148100 中贡献。)
使用
struct模块的'F'和'D'格式类型代码的做法现在已被设为 soft deprecated 并应改用两字母形式'Zf'和'Zd'。 (由 Sergey B Kirpichev 在 gh-121249 中贡献。)
C API 的变化¶
新的特性¶
添加
PyArg_ParseArray()和PyArg_ParseArrayAndKeywords()函数以使用METH_FASTCALL调用规范来解析函数的参数。 (由 Victor Stinner 在 gh-144175 中贡献。)增加下列函数用于新的
frozendict类型:(由 Victor Stinner 在 gh-141510 中贡献。)
将
PyObject_CallFinalizerFromDealloc()函数增加至受限 C API。 (由 Victor Stinner 在 gh-146063 中贡献。)增加
PySys_GetAttr(),PySys_GetAttrString(),PySys_GetOptionalAttr()和PySys_GetOptionalAttrString()等函数作为PySys_GetObject()的替代。 (由 Serhiy Storchaka 在 gh-108512 中贡献。)增加
PyUnstable_Unicode_GET_CACHED_HASH()以获取字符串的已缓存哈希值。 相关注意事项请参阅文档。 (由 Petr Viktorin 在 gh-131510 中贡献。)增加用于检测扩展模块的 ABI 兼容性的 API:
Py_mod_abi,PyABIInfo_Check()和PyABIInfo_VAR。 (由 Petr Viktorin 在 gh-137210 中贡献。)
实现 PEP 782,即 PyBytesWriter API。 增加函数:
(由 Victor Stinner 在 gh-129813 中贡献。)
将
PyCriticalSection及相关的函数添加到稳定 ABI。 (由 Petr Viktorin 在 gh-149225 中贡献。)新增
PyImport_CreateModuleFromInitfunc()C API 用于根据 spec 和 initfunc 创建模块。 (由 Itamar Oren 在 gh-116146 中贡献。)新增
PyTuple_FromArray()用于根据数组创建tuple。 (由 Victor Stinner 在 gh-111489 中贡献。)新增一个模块导出钩子
PyModExport_*。增加保证能在
tp_traverse处理器中安全使用的函数:PyObject_GetTypeData_DuringGC(),PyObject_GetItemData_DuringGC(),PyType_GetModuleState_DuringGC(),PyModule_GetState_DuringGC(),PyModule_GetToken_DuringGC(),PyType_GetBaseByToken_DuringGC(),PyType_GetModule_DuringGC(),PyType_GetModuleByToken_DuringGC()。 由 Petr Viktorin 在 gh-145925 中贡献。).)增加
PyObject_Dump()用于将对象转储至stderr。 应当仅用于调试。 (由 Victor Stinner 在 gh-141070 中贡献。).)实现 PEP 820:
PySlot-- 针对 C API 的统一槽位系统。 参见 定位槽位 文档。此系统添加了:
PySlot结构;新的槽位 ID:
Py_slot_end,Py_slot_invalid;Py_slot_subslots,Py_tp_slots,Py_mod_slots;Py_tp_name,Py_tp_basicsize,Py_tp_extra_basicsize,Py_tp_itemsize,Py_tp_flags,Py_tp_metaclass,Py_tp_module;便捷宏:
PySlot_DATA,PySlot_FUNC,PySlot_SIZE,PySlot_INT64,PySlot_UINT64,PySlot_STATIC_DATA,PySlot_END,PySlot_PTR,PySlot_PTR_STATIC。
PyModule_FromSlotsAndSpec()函数和PyModExport模块导出钩子 也会使用新的PySlot结构。以下函数已被设为 soft deprecated:
现在
Py_tp_bases和Py_tp_base槽位是等价的:它们可以被设为单个类型或类型的元组。Py_tp_bases槽位应作为首选;如果同时指定两者则另一个将被忽略。(由 Petr Viktorin 在 gh-149044 中贡献。)
增加
PyUnstable_ThreadState_SetStackProtection()和PyUnstable_ThreadState_ResetStackProtection()函数用于设置 Python 线程状态的栈保护基准地址和栈保护大小。 (由 Victor Stinner 在 gh-139653 中贡献。)增加
PyUnstable_SetImmortal()C API 函数用于将对象标记为 immortal。 (由 Kumar Aditya 在 gh-143300 中贡献。)恢复在在 Python 3.14 中移除的私有保留函数
_Py_InitializeMain()。 (由 Victor Stinner 在 gh-142417 中贡献。)添加
PyUnstable_DumpTraceback()和PyUnstable_DumpTracebackThreads()函数用于输出 Python 栈追踪。 (由 Alex Malyshev 在 gh-145559 中贡献。)
被改变的 C API¶
如果设置了
Py_TPFLAGS_MANAGED_DICT或Py_TPFLAGS_MANAGED_WEAKREF旗标则Py_TPFLAGS_HAVE_GC也必须被设置。 (由 Sergey Miryanov 在 gh-134786 中贡献。)现在
PyDateTime_IMPORT是线程安全的。 直接检查PyDateTimeAPI是否为NULL的代码应当更新为调用PyDateTime_IMPORT。 (由 Kumar Aditya 在 gh-141563 中贡献。)
被移除的 C API¶
移除已弃用的
PyUnicode函数:PyUnicode_AsDecodedObject(): 改用PyCodec_Decode()。PyUnicode_AsDecodedUnicode(): 改用PyCodec_Decode();请注意某些编解码器 (例如 "base64") 可能返回str以外的类型,比如bytes。PyUnicode_AsEncodedObject(): 改用PyCodec_Encode()。PyUnicode_AsEncodedUnicode(): 改用PyCodec_Encode();请注意某些编解码器 (例如 "base64") 可能返回bytes以外的类型,比如str。
(由 Stan Ulbrych 在 gh-133612 中贡献。)
PyImport_ImportModuleNoBlock(): 已弃用的PyImport_ImportModule()的别名。 (由 Bénédikt Tran 在 gh-133644 中贡献。)PyWeakref_GetObject()和PyWeakref_GET_OBJECT: 改用PyWeakref_GetRef()。 在 Python 3.12 及更旧的版本中可以使用 pythoncapi-compat project 来获取PyWeakref_GetRef()。 (由 Bénédikt Tran 在 gh-133644 中贡献。)移除了已弃用了
PySys_ResetWarnOptions()。 改为清除sys.warnoptions和warnings.filters。(由 Nikita Sobolev 在 gh-138886 中贡献。)
以下函数已被移除而应改用 PyConfig_Get()。 在 Python 3.13 及更旧的版本中可以使用 pythoncapi-compat project 来获取 PyConfig_Get()。
Python 初始化函数
Py_GetExecPrefix(): 改用PyConfig_Get("base_exec_prefix")(sys.base_exec_prefix)。 如果需要处理 虚拟环境 则应使用PyConfig_Get("exec_prefix")(sys.exec_prefix)。Py_GetPath(): 改用PyConfig_Get("module_search_paths")(sys.path)。Py_GetPrefix(): 改用PyConfig_Get("base_prefix")(sys.base_prefix)。 如果需要处理 虚拟环境 则使用PyConfig_Get("prefix")(sys.prefix)。Py_GetProgramFullPath(): 改用PyConfig_Get("executable")(sys.executable)。Py_GetProgramName(): 改用PyConfig_Get("executable")(sys.executable)。Py_GetPythonHome(): 改用PyConfig_Get("home")或PYTHONHOME环境变量。environment variable instead.
(由 Bénédikt Tran 在 gh-133644 中贡献。)
已弃用的 C API¶
弃用了 PEP 456 对提供字符串哈希方案外部定义的支持。 计划在 Python 3.19 中移除。
在之前版本中,嵌入方可以将
Py_HASH_ALGORITHM定义为Py_HASH_EXTERNAL以指明哈希方案是外部提供的但是此特性未写入文档、未经测试且几乎未被使用。(由 Bénédikt Tran 在 gh-141226 中贡献。)
对于
PyArg_ParseTuple()中的无符号整数格式,可接受大于 C 类型的最大值或小于对应的相同长度的有符号整数类型的最小值的 Python 整数值的做法现已被弃用。 (由 Serhiy Storchaka 在 gh-132629 中贡献。)PyBytes_FromStringAndSize(NULL, len)和_PyBytes_Resize()已设为 soft deprecated,请改用PyBytesWriterAPI。 (由 Victor Stinner 在 gh-129813 中贡献。).)_PyObject_CallMethodId(),_PyObject_GetAttrId()和_PyUnicode_FromId()自 Python 3.15 起已被弃用并将在 Python 3.20 中移除。 作为替代,请使用PyUnicode_InternFromString()并将结果缓存在模块状态中,然后调用PyObject_CallMethod()orPyObject_GetAttr()。 (由 Victor Stinner 在 gh-141049 中贡献。)弃用
PyComplexObject类型的cval字段。 请使用PyComplex_AsCComplex()和PyComplex_FromCComplex()在 Python 负数和 CPy_complex表示形式之进行转换。 (由 Sergey B Kirpichev 在 gh-128813 中贡献。)函数
_Py_c_sum(),_Py_c_diff(),_Py_c_neg(),_Py_c_prod(),_Py_c_quot(),_Py_c_pow()和_Py_c_abs()已被设为 soft deprecated。 (由 Sergey B Kirpichev 在 gh-128813 中贡献。).)bytes_warning自 Python 3.15 起已被弃用并将在 Python 3.17 中移除。 (由 Nikita Sobolev 在 gh-136355 中贡献。)Py_INFINITY宏已被设为 soft deprecated,请改用 C11 标准<math.h>INFINITY。 (由 Sergey B Kirpichev 在 gh-141004 中贡献。)下列宏已设为 soft deprecated:
Py_ALIGNED: 应改用alignas。PY_FORMAT_SIZE_T: 直接使用"z"。PY_LONG_LONG,PY_LLONG_MIN,PY_LLONG_MAX,PY_ULLONG_MAX,PY_INT32_T,PY_UINT32_T,PY_INT64_T,PY_UINT64_T,PY_SIZE_MAX: 使用 C99 类型/限制。Py_UNICODE_SIZE: 直接使用sizeof(wchar_t)。Py_VA_COPY: 直接使用va_copy。
计划要移除的
Py_UNICODE_WIDE宏,已被设为 soft deprecated。(由 Petr Viktorin 在 gh-146175 中贡献。)
Py_MATH_El和Py_MATH_PIl自 Python 3.15 起已被弃用并将在 Python 3.20 中移除。 (由 Sergey B Kirpichev 在 gh-141004 中贡献。)
构建的改变¶
移除隐式回退至捆绑的
libmpdec库副本的设置。 现在该设置应当通过将--with-system-libmpdec设为no或通过--without-system-libmpdec来显式地启用。 (由 Sergey B Kirpichev 在 gh-115119 中贡献。)新的配置选项
--with-missing-stdlib-config=FILE允许分发方针对缺失或分开打包的 standard library 模块传递一个包含自定义错误消息的 JSON 配置文件。 (由 Stan Ulbrych 和 Petr Viktorin 在 gh-139707 中贡献。)新的配置选项
--with-pymalloc-hugepages可为 pymalloc 区域启用巨大分页支持。 当启用时,区域大小将提高至 2 MiB 且分配将使用MAP_HUGETLB(Linux) 或MEM_LARGE_PAGES(Windows) 并可自动回退至常规分页。 在 Windows 上,请使用build.bat --pymalloc-hugepages。 在运行时,巨大分页必须通过将PYTHON_PYMALLOC_HUGEPAGES环境变量设为1来显式地启用。 (由 Pablo Galindo Salgado 在 gh-144319 中贡献。)现在如果 Linux 内核支持 PR_SET_VMA_ANON_NAME (Linux 5.17 或更新版本) 则标注匿名 mmap 的用法将被支持。 如果内核支持此特性并已将
-X dev传入 Python,或者 Python 是使用 调试模式 构建的则标注将在``/proc/<pid>/maps`` 中可见。 (由 Donghee Na 在 gh-141770 中贡献。)现在 CPython 构建默认将启用帧指针 (PEP 831)。 传入
--without-frame-pointers可禁用此特性。C 扩展以及使用自定义构建系统构建的原生库的作者应当确保展开链完整无缺。 这通常可通过将
-fno-omit-frame-pointer及类似的旗标添加到CFLAGS来实现。 有关 Python 所使用的具体旗标请参阅--without-frame-pointers文档。(由 Pablo Galindo Salgado 和 Savannah Ostrowski 在 gh-149201 中贡献。).)
使用 Visual Studio 2026 (MSVC 18) 的 64 位构建版现在可以使用新的 尾调用型解释器。 报告 AMD Ryzen 7 5800X 机器的 Windows x86-64 系统上 pyperformance 的几何平均计算在 Visual Studio 18.1.1 中相比 switch-case 型解释器提速的几何平均值在 15-20% 之间。 我们观察到在 Windows 上的提速幅度从大型纯 Python 库的 14% 到长期运行的小型纯 Python 脚本的 40% 不等。 这一成绩是通过在 MSVC 18 中引入的新特性实现的,现在已被 python.org 上的官方 Windows 64 位二进制版所使用。 (由 Chris Eibl, Ken Jin 和 Brandt Bucher 在 gh-143068 中贡献。 特别致谢 Steve Dower 和 MSVC 团队包括 Hulon Jenkins。)
移植到 Python 3.15¶
本节列出了先前描述的更改以及可能需要更改代码的其他错误修正。
sqlite3.ConnectionAPI 已进行了清理。现在
sqlite3.connect()除 database 外所有形参都是仅限关键字形参。现在
create_function()和create_aggregate()方法的前三个形参是仅限位置形参。现在
set_authorizer(),set_progress_handler()和set_trace_callback()等方法的第一个形参是仅限位置形参。
(由 Serhiy Storchaka 在 gh-133595 中贡献。)
resource.RLIM_INFINITY现在总是为正值。 将对应其旧值(如-1或-3,取决于具体平台)的负整数值传给resource.setrlimit()和resource.prlimit()的做法现已弃用。 (由 Serhiy Storchaka 在 gh-137044 中贡献。)mmap.mmap.resize()已中不支持相应底层 syscall 的平台中移除,而不是引发SystemError。 (由 An Long 在 gh-138205 中贡献。).)现在对于打开了文件的未关闭
xml.etree.ElementTree.iterparse()迭代器将发出资源警告。 请使用其close()方法或contextlib.closing()上下文管理器来关闭它。 (由 Osama Abdelkader 和 Serhiy Storchaka 在 gh-140601 中贡献。)如果将一个短选项和一个单连字符长选项传给
argparse.ArgumentParser.add_argument(),dest 现在会根据单连字符长选项推出。 例如,在add_argument('-f', '-foo')中,dest 现在将为'foo'而不是'f'。 请传入显式的 dest 参数以保持旧行为。 (由 Serhiy Storchaka 在 gh-138697 中贡献。)在
base64.urlsafe_b64decode()不再要求对输入进行填充。 传入新增参数padded=True或使用base64.b64decode()并附带参数altchars=b'-_'(这适用于较旧的 Python 版本) 以要求填充。 (由 Serhiy Storchaka 在 gh-73613 中贡献。)由于
unittest.TestCase.assertWarns()和unittest.TestCase.assertWarnsRegex()不会再屏蔽与指定类别或正则表达式不匹配的警告,你的测试可能会开始泄漏某些之前被掩盖的警告。 请使用警告过滤器屏蔽它们或使用额外的assertWarns*()来捕获并检查它们。 (由 Serhiy Storchaka 在 gh-143231 中贡献。)