Python 3.15 有什么新变化

编者:

Hugo van Kemenade

本文介绍了 Python 3.15 相比 3.14 的新增特性。

详情请参阅 更新日志

备注

预发布版用户应当了解到此文档目前处于草稿状态。 它将随着 Python 3.15 的发布进程不断更新,因此即使已经阅读过较早的版本也仍然值得再次查看。

摘要 -- 发布重点

新的特性

PEP 810: 显式惰性导入

大型 Python 应用程序经常会有启动时间缓慢的困扰 。此问题有很大一部分是来自导入系统:当一个模块被导入时,Python 必须定位文件,将其从磁盘读入,将其编译为字节码,并执行全部的最高层级代码。 对于具有较深依赖树的应用程序来说,此过程耗时将以秒计,即使在大部分被导入代码在某次运行期间从未被实际使用时也是如此。

开发者要绕过此问题可通过将导入移至函数内部,使用 importlib 按需加载模块,或重新调整代码结构以避免不需要的依赖项。 这些方式有一定效果但会使代码变得更难阅读和维护,使代码库中的 import 语句到处零星散布,并需要严格制定规则才能持续应用。

Python 现在会使用新的 lazy 软关键字通过显式的 lazy 导入提供一种更清晰的解决方案。Python 将延迟实际的模块加载直到所导入的名称首次被使用。 这在组织方面给予你在文件顶部声明所有导入的便利同时只付出你实际使用模块的加载耗时。

lazy 关键字同时适用于 importfrom ... 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       # 仍为立即型

参见

完整规范说明及考量见 PEP 810

(由 Pablo Galindo Salgado 和 Dino Viehland 在 gh-142349 中贡献。)

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: copydecimaljsonmarshalplistlib (仅在序列化时),picklepprintxml.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 在内的其他映射类型。

参见

完整规范说明及考量见 PEP 814

(由 Victor Stinner 和 Donghee Na 在 gh-141510 中贡献。)

PEP 661: 增加 sentinel 内置类型

builtins 模块中新增 sentinel 类型用于创建带有精确表示的哨兵值。 哨兵对象在拷贝时会保留其标识号,支持在类型表达式中的 | 运算符,并在它们按模块和名称导入时可以被封存。

(PEP 由 Tal Einat 撰写;由 Jelle Zijlstra 在 gh-148829 中贡献。)

参见

更多细节参见 PEP 661

PEP 799: 专用的性能分析包

新增的 profiling 模块将 Python 的内置性能分析工具整合到单独的、统一的命名空间中。 该模块包含:

cProfile 模块仍作为一个别名保留用于向下兼容。 profile 模块已被弃用并将在 Python 3.17 中移除。

参见

详情见 PEP 799

(由 Pablo Galindo 和 László Kiss Kollár 在 gh-138122 中贡献。)

Tachyon: 高频统计型采样性能分析器

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-135953gh-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)

参见

详情见 PEP 798

(由 Adam Hartz 在 gh-143055 中贡献。)

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() 一次。

(由 Barry Warsaw 在 gh-148641gh-150228 中贡献。)

PEP 803 -- 自由线程构建版的稳定 ABI

稳定 ABI 作为目标的 C 扩展现在可以针对新的 自由线程构建版稳定 ABI (或称 abi3t) 进行编译,这将使其能兼容 CPython 的 自由线程构建版。 这通常需要对源代码进行不小的更改;具体而言:

请注意稳定 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 套件可以绕过这些问题:

  • 解释器守卫,它可以阻止解释器被终结。

  • 解释器视图,它允许线程安全地访问可能被并发地终结或删除的解释器。

  • 具有内置防终结保护的 新 API 用于自动附加和分离线程状态。

此外 PyGILState 族中的 API (最主要的是 PyGILState_Ensure()PyGILState_Release()) 已被设为 soft deprecated。 目前 没有 移除它们的计划,现有的代码将继续可用,但在未来的 Python 版本中将不会有新的 PyGILState

参见

详情见 PEP 788

(由 Peter Bierma 在 gh-149101 中贡献。)

改进的错误消息

  • 现在当访问的属性不存在于某个对象上,但类似的属性可通过它的某个成员访问时解释器会在 AttributeError 异常中提供更有帮助的建议。

    举例来说,如果对象具有的一个属性本身暴露了所请求的名称,错误消息将建议通过该内部属性来访问它:

    @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 "/home/pablogsal/github/python/main/lel.py", line 42, 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 命令行选项来禁用。

    参见

    更多细节参见 PEP 686

    (由 Adam Turner 在 gh-133711 中贡献;PEP 686 由 Inada Naoki 撰写。)

  • 解释器帮助 (如 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 exceptionsstdlib (ast, compileall, doctest, gzip, inspect, json.tool, pdb, profiling.sampling, random, regrtest, sqlite3, timeit, tokenize, trace, unittest, uuid, zipapp, zipfile) 的 CLI 帮助中添加更多色彩。

  • 现在 ImportErrorModuleNotFoundError__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 参数的函数现在可接受任意实数 (如 DecimalFraction),而不只是整数或浮点数,虽然这并不会提升精度。 (由 Serhiy Storchaka 在 gh-67795 中贡献。)

  • 增加 bytearray.take_bytes(n=None, /)bytearray 获取字节串而无需拷贝。 这允许优化需要在处理可变字节缓冲区返回 bytes 的代码比如数据缓冲、网络协议解析、编码、解码和压缩等。 下面列出了可以用 take_bytes() 来优化的常见代码模式。

    建议的优化重构

    描述

    旧写法

    新写法

    在操作 bytearray 之后返回 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 complexdouble complex C 类型:分别对应格式字符 'Zf''Zd'。 (由 Victor Stinner 在 gh-146151gh-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 中贡献。)

默认的交互式 shell

新增模块

math.integer

该模块提供对整数参数的数学函数的访问 (PEP 791)。 (由 Serhiy Storchaka 在 gh-81313 中贡献。)

改进的模块

argparse

  • 现在 BooleanOptionalAction 动作支持单连字符长选项和替代前缀字符。 (由 Serhiy Storchaka 在 gh-138525 中贡献。).)

  • argparse.ArgumentParsersuggest_on_error 形参默认值改为 True。 这将默认启用为输入错误的参数提供建议。 (由 Jakob Schluse 在 gh-140450 中贡献。)

  • ArgumentParser 描述和结语文本中增加反引号标记支持以便在彩色输出被启用时高亮显示内联代码。 (由 Savannah Ostrowski 在 gh-142390 中贡献。)

  • 将反引号标记扩展至参数 help 文本并增加对双重反引号(RST 内联字面值样式)的支持。 (由 Hugo van Kemenade 在 gh-149375 中贡献。)

array

  • 支持 float complexdouble complex C 类型:分别对应格式字符 'Zf''Zd'。 (由 Victor Stinner 在 gh-146151gh-148675 中贡献。)

  • 支持半精度浮点数(16 位 IEEE 754 二进制交换格式):对应格式字符 'e'。 (由 Sergey B Kirpichev 在 gh-146238 中贡献。)

  • array.typecodes 类型从 str 更改为 tuple 以支持多于 1 个字符的类型代码 (ZfZd)。 (由 Victor Stinner 在 gh-148675 中贡献。)

ast

  • dump() 增加 color 形参。 如果为 True,则返回的字符串将使用 ANSI 转义序列设置语法高亮。 如果为 False (默认值),则始终禁用彩色输出。 (由 Stan Ulbrych 在 gh-148981 中贡献。)

  • 现在 命令行 输出默认使用语法高亮。 这可以 使用环境变量来控制。 (由 Stan Ulbrych 在 gh-148981 中贡献。)

asyncio

  • 增加 TaskGroup.cancel 以允许提前终结任务分组,例如,当任务目标已达成或者其服务不再需要时。 在之前版本中这会涉及反直觉的特殊处理比如由一个额外任务引发自定义异常然后在退出任务分组时抑制该异常。 (由 John Belmonte 在 gh-127214 中贡献。).)

base64

binascii

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

  • 增加 collections.Counter.__xor__()collections.Counter.__ixor__() 用于计算 Counter 对象间的对称差。 (由 Raymond Hettinger 在 gh-138682 中贡献。)

concurrent.futures

contextlib

dataclasses

  • 针对生成 __init__ 方法的标注不再包括内部类型名称。

dbm

  • dbm.dumbdbm.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

functools

gc

  • Python 3.14.0-3.14.4 使用了新的增量式垃圾收集器。 不过,由于大量在生产环境中出现显著内存压力的 报告,它已被改回 3.13 中的世代式 GC。 这是目前 Python 3.14.5 更新之后以及 Python 3.15 中使用的 GC。

hashlib

  • Ensure that hash functions guaranteed to be always available exist as attributes of hashlib even if they will not work at runtime due to missing backend implementations. For instance, hashlib.md5 will no longer raise AttributeError if OpenSSL is not available and Python has been built without MD5 support. (Contributed by Bénédikt Tran in gh-136929.)

http.client

  • A new max_response_headers keyword-only parameter has been added to HTTPConnection and HTTPSConnection constructors. This parameter overrides the default maximum number of allowed response headers. (Contributed by Alexander Enrique Urieles Nieto in gh-131724.)

http.server

importlib.metadata

  • Previously, when accessing a distribution metadata directory not containing a metadata file, metadata() and Distribution.metadata() would return an empty PackageMetadata object as if the file was present but empty. Now, a MetadataNotFound exception is raised. See importlib_metadata#493 for background and rationale and gh-143387 for rationale on the compatibility concerns. (Contributed by Jason R. Coombs.)

inspect

  • Add parameters inherit_class_doc and fallback_to_class_doc for getdoc(). (Contributed by Serhiy Storchaka in gh-132686.)

json

  • Add the array_hook parameter to load() and loads() functions: allow a callback for JSON literal array types to customize Python lists in the resulting decoded object. Passing combined frozendict to object_pairs_hook param and tuple to array_hook will yield a deeply nested immutable Python structure representing the JSON data. (Contributed by Joao S. O. Bueno in gh-146440.)

locale

math

mimetypes

mmap

  • mmap.mmap now has a trackfd parameter on Windows; if it is False, the file handle corresponding to fileno will not be duplicated. (Contributed by Serhiy Storchaka in gh-78502.)

  • Added the mmap.mmap.set_name() method to annotate an anonymous memory mapping if Linux kernel supports PR_SET_VMA_ANON_NAME (Linux 5.17 or newer). (Contributed by Donghee Na in gh-142419.)

os

  • Add os.statx() on Linux kernel versions 4.11 and later with glibc versions 2.28 and later. (Contributed by Jeffrey Bosboom and Victor Stinner in gh-83714.)

  • os.makedirs() function now has a parent_mode parameter that allows specifying the mode for intermediate directories. This can be used to match the behavior from Python 3.6 and earlier by passing parent_mode=mode. (Contributed by Zackery Spytz and Gregory P. Smith in gh-86533.)

os.path

pdb

  • Use the new interactive shell as the default input shell for pdb. (Contributed by Tian Gao in gh-145379.)

pickle

  • Add support for pickling private methods and nested classes. (Contributed by Zackery Spytz and Serhiy Storchaka in gh-77188.)

pickletools

pprint

re

  • re.prefixmatch() and a corresponding re.Pattern.prefixmatch() have been added as alternate, more explicit names for the existing and now soft deprecated re.match() and re.Pattern.match() APIs. These are intended to be used to alleviate confusion around what match means by following the Zen of Python's "Explicit is better than implicit" mantra. Most other language regular expression libraries use an API named match to mean what Python has always called search. (Contributed by Gregory P. Smith in gh-86519.)

resource

shelve

  • Added new reorganize() method to shelve used to recover unused free space previously occupied by deleted entries. (Contributed by Andrea Oliveri in gh-134004.)

  • Add support for custom serialization and deserialization functions in the shelve module. (Contributed by Furkan Onder in gh-99631.)

shutil

socket

  • Add constants for the ISO-TP CAN protocol. (Contributed by Patrick Menschel and Stefan Tatschner in gh-86819.)

sqlite3

  • The command-line interface has several new features:

    • SQL keyword completion on <tab>. (Contributed by Long Tan in gh-133393.)

    • Prompts, error messages, and help text are now colored. This is enabled by default, see 控制颜色 for details. (Contributed by Stan Ulbrych and Łukasz Langa in gh-133461.)

    • Table, index, trigger, view, column, function, and schema completion on <tab>. (Contributed by Long Tan in gh-136101.)

ssl

  • Indicate through ssl.HAS_PSK_TLS13 whether the ssl module supports "External PSKs" in TLSv1.3, as described in RFC 9258. (Contributed by Will Childs-Klein in gh-133624.)

  • Added new methods for managing groups used for SSL key agreement

    • ssl.SSLContext.set_groups() sets the groups allowed for doing key agreement, extending the previous ssl.SSLContext.set_ecdh_curve() method. This new API provides the ability to list multiple groups and supports fixed-field and post-quantum groups in addition to ECDH curves. This method can also be used to control what key shares are sent in the TLS handshake.

    • ssl.SSLSocket.group() returns the group selected for doing key agreement on the current connection after the TLS handshake completes. This call requires OpenSSL 3.2 or later.

    • ssl.SSLContext.get_groups() returns a list of all available key agreement groups compatible with the minimum and maximum TLS versions currently set in the context. This call requires OpenSSL 3.5 or later.

    (Contributed by Ron Frederick in gh-136306.)

  • Added a new method ssl.SSLContext.set_ciphersuites() for setting TLS 1.3 ciphers. For TLS 1.2 or earlier, ssl.SSLContext.set_ciphers() should continue to be used. Both calls can be made on the same context and the selected cipher suite will depend on the TLS version negotiated when a connection is made. (Contributed by Ron Frederick in gh-137197.)

  • Added new methods for managing signature algorithms:

    (Contributed by Ron Frederick in gh-138252.)

subprocess

  • subprocess.Popen.wait(): when timeout is not None and the platform supports it, an efficient event-driven mechanism is used to wait for process termination:

    If none of these mechanisms are available, the function falls back to the traditional busy loop (non-blocking call and short sleeps). (Contributed by Giampaolo Rodola in gh-83069.)

symtable

sys

  • Add sys.abi_info namespace to improve access to ABI information. (Contributed by Klaus Zimmermann in gh-137476.)

sys.monitoring

tarfile

threading

timeit

  • The output of the timeit command-line interface is colored by default. This can be controlled with environment variables. (Contributed by Hugo van Kemenade in gh-146609.)

  • The command-line interface now colorizes error tracebacks by default. This can be controlled with environment variables. (Contributed by Yi Hong in gh-139374.)

  • Make the target time of timeit.Timer.autorange() configurable and add --target-time option to the command-line interface. (Contributed by Alessandro Cucci and Miikka Koskinen in gh-80642.)

tkinter

  • The tkinter.Text.search() method now supports two additional arguments: nolinestop which allows the search to continue across line boundaries; and strictlimits which restricts the search to within the specified range. (Contributed by Rihaan Meher in gh-130848.)

  • A new method tkinter.Text.search_all() has been introduced. This method allows for searching for all matches of a pattern using Tcl's -all and -overlap options. (Contributed by Rihaan Meher in gh-130848.)

  • Added new methods pack_content(), place_content() and grid_content() which use Tk commands with new names (introduced in Tk 8.6) instead of *_slaves() methods which use Tk commands with outdated names. (Contributed by Serhiy Storchaka in gh-143754.)

  • Added Event attributes user_data for Tk virtual events and detail for Enter, Leave, FocusIn, FocusOut, and ConfigureRequest events. (Contributed by Matthias Kievernagel and Serhiy Storchaka in gh-47655.)

tokenize

tomllib

  • The tomllib module now supports TOML 1.1.0. This is a backwards compatible update, meaning that all valid TOML 1.0.0 documents are parsed the same way.

    The changes, according to the official TOML changelog, are:

    • Allow newlines and trailing commas in inline tables.

      Previously an inline table had to be on a single line and couldn't end with a trailing comma. This is now relaxed so that the following is valid:

      tbl = {
         key      = "a string",
         moar-tbl =  {
            key = 1,
         },
      }
      
    • Add \xHH notation to basic strings for codepoints under 255, and the \e escape for the escape character:

      null = "null byte: \x00; letter a: \x61"
      csi = "\e["
      
    • Seconds in datetime and time values are now optional. The following are now valid:

      dt = 2010-02-03 14:15
      t  = 14:15
      

    (Contributed by Taneli Hukkinen in gh-142956.)

types

typing

  • PEP 747: Add TypeForm, a new special form for annotating values that are themselves type expressions. TypeForm[T] means "a type form object describing T (or a type assignable to T)". At runtime, TypeForm(x) simply returns x, which allows explicit annotation of type-form values without changing behavior.

    This helps libraries that accept user-provided type expressions (for example int, str | None, TypedDict classes, or list[int]) expose precise signatures:

    from typing import Any, TypeForm
    
    def cast[T](typ: TypeForm[T], value: Any) -> T: ...
    

    (Contributed by Jelle Zijlstra in gh-145033.)

  • PEP 728: Add support in TypedDict for the closed and extra_items class arguments. A closed TypedDict does not allow extra keys beyond those specified in the class body, while a TypedDict with extra_items allows arbitrary extra items where the values are of the specified type. (Contributed by Angela Liss in gh-137840.)

  • Code like class ExtraTypeVars(P1[S], Protocol[T, T2]): ... now raises a TypeError, because S is not listed in Protocol parameters. (Contributed by Nikita Sobolev in gh-137191.)

  • Code like class B2(A[T2], Protocol[T1, T2]): ... now correctly handles type parameters order: it is (T1, T2), not (T2, T1) as it was incorrectly inferred at runtime before. (Contributed by Nikita Sobolev in gh-137191.)

  • PEP 800: Add @typing.disjoint_base, a new decorator marking a class as a disjoint base. This is an advanced feature primarily intended to allow type checkers to faithfully reflect the runtime semantics of types defined as builtins or in compiled extensions. If a class C is a disjoint base, then child classes of that class cannot inherit from other disjoint bases that are not parent or child classes of C. (Contributed by Jelle Zijlstra in gh-148639.)

  • TypeVarTuple now accepts bound, covariant, contravariant, and infer_variance keyword arguments, matching the interface of TypeVar and ParamSpec. bound semantics remain undefined in the specification.

unicodedata

unittest

urllib.parse

venv

  • On POSIX platforms, platlib directories will be created if needed when creating virtual environments, instead of using a lib64 -> lib symlink. This means purelib and platlib of virtual environments no longer share the same lib directory on platforms where sys.platlibdir is not equal to lib. (Contributed by Rui Xi in gh-133951.)

warnings

  • Improve filtering by module in warnings.warn_explicit() if no module argument is passed. It now tests the module regular expression in the warnings filter not only against the filename with .py stripped, but also against module names constructed starting from different parent directories of the filename (with /__init__.py, .py and, on Windows, .pyw stripped). (Contributed by Serhiy Storchaka in gh-135801.)

wave

(由 Lionel Koenig 和 Michiel W. Beijen 在 gh-60729 中贡献。)

webbrowser

  • 在 macOS 上,新的 webbrowser.MacOS 类可通过 /usr/bin/open 打开 URL 而不是通过 osascript 构造并执行 AppleScript。 默认的浏览器是使用 plistlib 从 LaunchServices 首选项文件中检测到的,在新安装系统中将以 com.apple.Safari 作为回退项。 对于非 HTTP(S) URL,会使用 open -b <bundle-id> 通过浏览器而不是 OS 文件处理器对 URL 执行路由,以防止文件注册攻击。 (由 Jeff Lyon 在 gh-137586 中贡献。)

xml

  • Add the xml.is_valid_name() function to check whether a string can be used as an element or attribute name in XML. (Contributed by Serhiy Storchaka in gh-139489.)

  • Add the xml.is_valid_text() function, which allows to check whether a string can be used in the XML document. (Contributed by Serhiy Storchaka in gh-139489.)

xml.parsers.expat

zlib

性能优化

base64 和 binascii

  • CPython's underlying base64 implementation now encodes 2x faster and decodes 3x faster thanks to simple CPU pipelining optimizations. (Contributed by Gregory P. Smith and Serhiy Storchaka in gh-143262.)

  • Implementation for Ascii85, Base85, and Z85 encoding has been rewritten in C. Encoding and decoding is now two orders of magnitude faster and consumes two orders of magnitude less memory. (Contributed by James Seo and Serhiy Storchaka in gh-101178.)

  • Implementation for Base32 has been rewritten in C. Encoding and decoding is now two orders of magnitude faster. (Contributed by James Seo in gh-146192.)

csv

升级的 JIT 编译器

Results from the pyperformance benchmark suite report 8-9% 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 a 12-13% 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 构建时依赖

The JIT compiler now uses LLVM 21 for build-time stencil generation. As always, LLVM is only needed when building CPython with the JIT enabled; end users running Python do not need LLVM installed. Instructions for installing LLVM can be found in the JIT compiler documentation for all supported platforms. (Contributed by Savannah Ostrowski in gh-140973.)

新的追踪前端

The JIT compiler now supports significantly more bytecode operations and control flow than in Python 3.14, enabling speedups on a wider variety of code. For example, simple Python object creation is now understood by the 3.15 JIT compiler. Overloaded operations and generators are also partially supported. This was made possible by an overhauled JIT tracing frontend that records actual execution paths through code, rather than estimating them as the previous implementation did. (Contributed by Ken Jin in gh-139109. Support for Windows added by Mark Shannon in gh-141703.)

JIT 中基本的注册分配

A basic form of register allocation has been added to the JIT compiler's optimizer. This allows the JIT compiler to avoid certain stack operations altogether and instead operate on registers. This allows the JIT to produce more efficient traces by avoiding reads and writes to memory. (Contributed by Mark Shannon in gh-135379.)

更多的 JIT 优化

More constant-propagation is now performed. This means when the JIT compiler detects that certain user code results in constants, the code can be simplified by the JIT. (Contributed by Ken Jin and Savannah Ostrowski in gh-132732.)

Reference counts are avoided whenever it is safe to do so. This generally reduces the cost of most operations in Python. (Contributed by Ken Jin, Donghee Na, Zheao Li, Hai Zhu, Savannah Ostrowski, Reiden Ong, Noam Cohen, Tomas Roun, PuQing, Cajetan Rodrigues, and Sacul in gh-134584.)

By tracking unique references to objects, the JIT optimizer can now eliminate reference count updates and perform in-place operations on ints and floats. (Contributed by Reiden Ong, and Pieter Eendebak in gh-143414 and gh-146306.)

The JIT optimizer now supports significantly more operations than in 3.14. (Contributed by Kumar Aditya, Ken Jin, Jiahao Li, and Sacul in gh-131798.)

GDB 和 GNU backtrace() 展开支持

The JIT compiler now publishes unwind information for generated machine code to the GDB interface on supported Linux ELF platforms. When libgcc frame registration is available, the same unwind information is also registered for GNU backtrace() stack walkers. This allows native debuggers, crash handlers, and diagnostic tools using these mechanisms to unwind through JIT frames instead of stopping at generated code. (Contributed by Diego Russo and Pablo Galindo Salgado in gh-146071 and gh-149104.)

更好的机器码生成

The JIT compiler's machine code generator now produces better machine code for x86-64 and AArch64 macOS and Linux targets. In general, users should experience lower memory usage for generated machine code and more efficient machine code versus 3.14. (Contributed by Brandt Bucher in gh-136528 and gh-135905. Implementation for AArch64 contributed by Mark Shannon in gh-139855. Additional optimizations for AArch64 contributed by Mark Shannon and Diego Russo in gh-140683 and gh-142305.)

可维护性

The JIT optimizer's operations have been simplified. This was made possible by a refactoring of JIT data structures. (Contributed by Zhongtian Zheng in gh-148211 and Hai Zhu in gh-143421.)

移除

ast

  • The constructors of AST nodes now raise a TypeError when a required argument is omitted or when a keyword argument that does not map to a field on the AST node is passed. These cases had previously raised a DeprecationWarning since Python 3.13. (Contributed by Brian Schubert and Jelle Zijlstra in gh-137600 and gh-105858.)

collections.abc

  • collections.abc.ByteString has been removed from collections.abc.__all__. collections.abc.ByteString has been deprecated since Python 3.12, and is scheduled for removal in Python 3.17.

ctypes

datetime

  • strptime() now raises ValueError when the format string contains %d (day of month) without a year directive. This has been deprecated since Python 3.13. (Contributed by Stan Ulbrych and Gregory P. Smith in gh-70647.)

glob

  • Removed the undocumented glob.glob0() and glob.glob1() functions, which have been deprecated since Python 3.13. Use glob.glob() and pass a directory to its root_dir argument instead. (Contributed by Barney Gale in gh-137466.)

http.server

  • Removed the CGIHTTPRequestHandler class and the --cgi flag from the python -m http.server command-line interface. They were deprecated in Python 3.13. (Contributed by Bénédikt Tran in gh-133810.)

importlib.resources

pathlib

  • pathlib.Path.mkdir() now has a parent_mode parameter that allows specifying the mode for intermediate directories when parents=True. (Contributed by Gregory P. Smith in gh-86533.)

  • Removed deprecated pathlib.PurePath.is_reserved(). Use os.path.isreserved() to detect reserved paths on Windows. (Contributed by Nikita Sobolev in gh-133875.)

平台

  • Removed the platform.java_ver() function, which was deprecated since Python 3.13. (Contributed by Alexey Makridenko in gh-133604.)

sre_*

  • Removed sre_compile, sre_constants and sre_parse modules. (Contributed by Stan Ulbrych in gh-135994.)

sysconfig

threading

  • Remove support for arbitrary positional or keyword arguments in the C implementation of RLock objects. This was deprecated in Python 3.14. (Contributed by Bénédikt Tran in gh-134087.)

types

typing

  • typing.ByteString has been removed from typing.__all__. typing.ByteString has been deprecated since Python 3.9, and is scheduled for removal in Python 3.17.

  • The undocumented keyword argument syntax for creating NamedTuple classes (for example, Point = NamedTuple("Point", x=int, y=int)) is no longer supported. Use the class-based syntax or the functional syntax instead. (Contributed by Bénédikt Tran in gh-133817.)

  • Using TD = TypedDict("TD") or TD = TypedDict("TD", None) to construct a TypedDict type with zero fields is no longer supported. Use class TD(TypedDict): pass or TD = TypedDict("TD", {}) instead. (Contributed by Bénédikt Tran in gh-133823.)

  • Deprecated @typing.no_type_check_decorator has been removed. (Contributed by Nikita Sobolev in gh-133601.)

wave

  • Removed the getmark(), setmark() and getmarkers() methods of the Wave_read and Wave_write classes, which were deprecated since Python 3.13. (Contributed by Bénédikt Tran in gh-133873.)

zipimport

弃用

新的弃用

  • ast

    • 创建抽象 AST 节点 (如 ast.ASTast.expr) 的做法已被弃用并将在 Python 3.20 中引发错误。

      (由 Brian Schubert 在 gh-116021 中贡献。)

  • base64:

    • Accepting the + and / characters with an alternative alphabet in b64decode() and urlsafe_b64decode() is now deprecated. In future Python versions they will be errors in the strict mode and discarded in the non-strict mode. (Contributed by Serhiy Storchaka in gh-125346.)

  • CLI:

    • Deprecate -b and -bb command-line options and schedule them to become no-ops in Python 3.17. These were primarily helpers for the Python 2 -> 3 transition. Starting with Python 3.17, no BytesWarning will be raised for these cases; use a type checker instead.

      (由 Nikita Sobolev 在 gh-136355 中贡献。)

  • collections.abc

    • 在运行时以下语句现在将导致发出 DeprecationWarning:

      • from collections.abc import ByteString

      • import collections.abc; collections.abc.ByteString

      DeprecationWarnings were already emitted if collections.abc.ByteString was subclassed or used as the second argument to isinstance() or issubclass(), but warnings were not previously emitted if it was merely imported or accessed from the collections.abc module.

  • hashlib:

    • In hash function constructors such as new() or the direct hash-named constructors such as md5() and sha256(), the optional initial data parameter could also be passed as a keyword argument named data= or string= in various hashlib implementations.

      Support for the string keyword argument name is now deprecated and is slated for removal in Python 3.19. Prefer passing the initial data as a positional argument for maximum backwards compatibility.

      (Contributed by Bénédikt Tran in gh-134978.)

  • http.cookies:

  • imaplib:

    • Altering IMAP4.file is now deprecated and slated for removal in Python 3.19. This property is now unused and changing its value does not explicitly close the current file.

  • 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:

    • 调用 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 中贡献。)

  • typing:

    • 在运行时以下语句现在将导致发出 DeprecationWarning:

      • from typing import ByteString

      • import typing; typing.ByteString

      如果 typing.ByteString 被子类化或被用作传给 isinstance()issubclass() 的第二个参数则会发出 DeprecationWarning,但如果只是从 typing 模块导入或访问则不会提前发出。

  • webbrowser:

    • webbrowser.MacOSXOSAScript 已被弃用而应改用 webbrowser.MacOS 并计划在 Python 3.17 中移除。 (由 Jeff Lyon 在 gh-137586 中贡献。)

  • __version__

计划在 Python 3.16 中移除

  • 导入系统:

    • 当设置 __spec__.loader 失败时在模块上设置 __loader__ 的做法已被弃用。在 Python 3.16 中,__loader__ 将不会再被设置或是被导入系统或标准库纳入考虑。

    • Setting __package__ on a module while failing to set __spec__.parent is deprecated. In Python 3.16, __package__ will cease to be taken into consideration by the import system or standard library. (gh-97879)

  • The bundled copy of libmpdec.

  • array:

    • 'u' 格式代码 (wchar_t) 自 Python 3.3 起已在文档中弃用并自 Python 3.13 起在运行时弃用。对于 Unicode 字符请改用 'w' 格式代码 (Py_UCS4)。

  • asyncio:

    • asyncio.iscoroutinefunction() 已被弃用并将在 Python 3.16 中移除,请改用 inspect.iscoroutinefunction()。 (由李佳昊和 Kumar Aditya 在 gh-122875 中贡献。)

    • asyncio 策略系统已被弃用并将在 Python 3.16 中移除。具体而言,是弃用了下列类和函数:

      • asyncio.AbstractEventLoopPolicy

      • asyncio.DefaultEventLoopPolicy

      • asyncio.WindowsSelectorEventLoopPolicy

      • asyncio.WindowsProactorEventLoopPolicy

      • asyncio.get_event_loop_policy()

      • asyncio.set_event_loop_policy()

      用户应当使用 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 中贡献。)

  • builtins:

    • 对布尔类型 ~True~False 执行按位取反的操作自 Python 3.12 起已被弃用,因为它会产生奇怪和不直观的结果 (-2-1)。请改用 not x 来对布尔值执行逻辑否操作。 对于需要对下层整数执行按位取反操作的少数场合,请显式地将其转换为 int (~int(x))。

  • functools:

    • 调用 functools.reduce() 的 Python 实现并传入 functionsequence 作为关键字参数的做法自 Python 3.14 起已被弃用。

  • logging:

    • 使用 strm 参数对自定义日志记录处理器提供支持的做法已被弃用并计划在 Python 3.16 中移除。改为使用 stream 参数定义处理器。 (由 Mariusz Felisiak 在 gh-115032 中贡献。)

  • mimetypes:

  • shutil:

    • ExecError 异常自 Python 3.14 起已被弃用。它自 Python 3.4 起就未被 shutil 中的任何函数所使用,现在是 RuntimeError 的一个别名。

  • symtable:

    • The symtable.Class.get_methods() method has been deprecated since Python 3.14.

  • sys:

    • The _enablelegacywindowsfsencoding() function has been deprecated since Python 3.13. Use the PYTHONLEGACYWINDOWSFSENCODING environment variable instead.

  • sysconfig:

    • 自 Python 3.14 起 sysconfig.expand_makefile_vars() 函数已被弃用。请使用 sysconfig.get_paths()vars 参数代替。

  • tarfile:

    • The undocumented and unused TarInfo.tarfile attribute has been deprecated since Python 3.13.

计划在 Python 3.17 中移除

  • datetime:

    • 使用不带年份的包含 %e (月份日期序号) 的格式字符串的 strptime() 调用自 Python 3.15 起已被弃用。 (由 Stan Ulbrych 在 gh-70647 中贡献。)

  • collections.abc:

    • collections.abc.ByteString 计划在 Python 3.17 中移除。

      使用 isinstance(obj, collections.abc.Buffer) 来在运行时测试 obj 是否实现了 缓冲区协议。要用于类型标注,则使用 Buffer 或者显式指明你的代码所支持的类型的并集 (例如 bytes | bytearray | memoryview)。

      ByteString 原本是想作为 bytesbytearray 的超类型的抽象基类提供。 不过,由于该 ABC 从未有过任何方法,知道一个对象是 ByteString 的实例并不能真正告诉你有关该对象的任何有用信息。 其他常见缓冲区类型如 memoryview 同样不能被当作是 ByteString 的子类型(无论是在运行时还是对于静态类型检查器)。

      请参阅 PEP 688 了解详情。 (由 Shantanu Jain 在 gh-91896 中贡献。)

  • encodings:

  • webbrowser:

    • webbrowser.MacOSXOSAScript 已被弃用并改用 webbrowser.MacOS。 (gh-137586)

  • typing:

    • 在 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 原本是想作为 bytesbytearray 的超类型的抽象基类提供。 不过,由于该 ABC 从未有过任何方法,知道一个对象是 ByteString 的实例并不能真正告诉你有关该对象的任何有用信息。 其他常见缓冲区类型如 memoryview 同样不能被当作是 ByteString 的子类型(无论是在运行时还是对于静态类型检查器)。

      请参阅 PEP 688 了解详情。 (由 Shantanu Jain 在 gh-91896 中贡献。)

  • tkinter:

    • 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 中移除

  • 当需要一个文件描述符时将不再接受布尔值。 (由 Serhiy Storchaka 在 gh-82626 中贡献。)

  • decimal:

    • 非标准且未写入文档的 Decimal 格式说明符 'N',它仅在 decimal 模块的 C 实现中受到支持,自 Python 3.13 起已被弃用。 (由 Serhiy Storchaka 在 gh-89902 中贡献。)

  • PEP 829 定义的弃用:

    • name.pth 文件中的 import 行会被静默地忽略。

    (由 Barry Warsaw 在 gh-148641 中贡献。)

计划在 Python 3.19 中移除

  • ctypes:

    • 在非 Windows 平台上,通过设置 _pack_ 而非 _layout_,隐式切换到与 MSVC 兼容的结构布局。

  • hashlib:

    • 在哈希函数构造器如 new() 或者直接使用哈希算法名称的构造器如 md5()sha256() 中,它们可选的初始数据形参在不同的 hashlib 实现中也可使用名为 data=string= 的关键字参数形式传入。

      string 关键字参数名称的支持现已被弃用并计划在 Python 3.19 中移除。

      在 Python 3.13 之前,string 关键字形参没有根据哈希函数的后端实现得到正确的支持。 建议将初始数据作为位置参数传入以获得最大的向下兼容性。

  • http.cookies:

  • imaplib:

    • 修改 IMAP4.file 的做法现已被弃用并计划在 Python 3.19 中移除。 该属性现已不再使用并且修改其值不会自动关闭当前文件。

      在 Python 3.14 之前,该属性被用于为 IMAP4 实现相应的 read()readline() 方法但在此之后情况已发生改变。

  • tkinter:

计划在 Python 3.20 中移除

Pending removal in Python 3.21

计划在未来版本中移除

以下 API 将会被移除,尽管具体时间还未确定。

  • argparse:

    • 嵌套参数组和嵌套互斥组已被弃用。

    • 将未写入文档的关键字参数 prefix_chars 传递给 add_argument_group() 的做法现在已被弃用。

    • argparse.FileType 类型转换器已弃用。

  • builtins:

    • 生成器: 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, isor 中的一个将会引发语法警告。在未来的版本中它将改为语法错误。 (gh-87999)

    • __index__()__int__() 方法返回非 int 类型的支持:将要求这些方法必须返回 int 的严格子类的实例。

    • __float__() 方法返回 float 的子类的支持:将要求这些方法必须返回 float 的实例。

    • __complex__() 方法返回 complex 的子类的支持:将要求这些方法必须返回 complex 的实例。

    • 传入一个复数作为 complex() 构造器中的 realimag 参数的做法现在已被弃用;它应当仅作为单个位置参数被传入。(由 Serhiy Storchaka 在 gh-109218 中贡献。)

  • calendar: calendar.Januarycalendar.February 常量已被弃用并由 calendar.JANUARYcalendar.FEBRUARY 替代。 (由 Prince Roshan 在 gh-103636 中贡献。)

  • codecs: codecs.open() 请改用 open() 。 (gh-133038)

  • codeobject.co_lnotab: 改用 codeobject.co_lines() 方法。

  • datetime:

    • utcnow(): 使用 datetime.datetime.now(tz=datetime.UTC)

    • utcfromtimestamp(): 使用 datetime.datetime.fromtimestamp(timestamp, tz=datetime.UTC)

  • gettext: 复数值必须是一个整数。

  • importlib:

  • importlib.metadata:

    • EntryPoints 元组接口。

    • 返回值中隐式的 None

  • logging: warn() 方法自 Python 3.3 起已被弃用,请改用 warning().

  • 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_SSLv3

    • ssl.PROTOCOL_TLS

    • ssl.PROTOCOL_TLSv1

    • ssl.PROTOCOL_TLSv1_1

    • ssl.PROTOCOL_TLSv1_2

    • ssl.TLSVersion.SSLv3

    • ssl.TLSVersion.TLSv1

    • ssl.TLSVersion.TLSv1_1

  • threading 的方法:

  • typing.Text (gh-92332).

  • 内部类 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 中贡献。)

C API 的变化

新的特性

被改变的 C API

被移除的 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.warnoptionswarnings.filters

    (由 Nikita Sobolev 在 gh-138886 中贡献。)

以下函数已被移除而应改用 PyConfig_Get()。 在 Python 3.13 及更旧的版本中可以使用 pythoncapi-compat project 来获取 PyConfig_Get()

已弃用的 C API

构建的改变

  • Removed implicit fallback to the bundled copy of the libmpdec library. Now this should be explicitly enabled with --with-system-libmpdec set to no or with --without-system-libmpdec. (Contributed by Sergey B Kirpichev in gh-115119.)

  • 新的配置选项 --with-missing-stdlib-config=FILE 允许分发方针对缺失或分开打包的 standard library 模块传递一个包含自定义错误消息的 JSON 配置文件。 (由 Stan Ulbrych 和 Petr Viktorin 在 gh-139707 中贡献。)

  • 新的配置选项 --with-pymalloc-hugepagespymalloc 区域启用巨大分页支持。 当启用时,区域大小将提高到 2 MiB 且分配将使用 MAP_HUGETLB (Linux) 或 MEM_LARGE_PAGES (Windows) 并可自动回退至常规分页。 在 Windows 上,请使用 build.bat --pymalloc-hugepages。 在运行时,巨大分页支持必须通过将 PYTHON_PYMALLOC_HUGEPAGES 环境变量设为 1 来显式地启用。

  • 现在如果 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

本节列出了先前描述的更改以及可能需要更改代码的其他错误修正。