# Python 3.12 有什么新变化

编者:

  Adam Turner

本文介绍 Python 3.12 相比 3.11 增加的新特性。 Python 3.12 已于 2023 年 10 月 2 日发布。 要获取详细信息，可参阅 changelog。

参见

PEP 693 -- Python 3.12 发布计划

## 摘要 -- 发布重点

Python 3.12 是 Python 编程语言的一个稳定发布版，包含一系列对语言和标准库的改变。 库的改变主要集中在清理已弃用的 API、易用性和正确性等方面。 值得注意的是，`distutils` 包已从标准库中移除。 `os` 和 `pathlib` 中的文件系统支持得到了许多改进，一些模块的性能也得到了提升。

语言的改变主要集中在可用性方面，如 f-字符串 的许多限制已被移除，而 'Did you mean ...' 提示消息继续得到改进。 新的 类型形参语法 和 `type` 语句提升了 泛型类型 和 类型别名 配合静态类型检查器使用时的效率。

本文并不试图提供所有新功能的完整规范说明，而是提供一个方便的概览。 如需了解完整细节，请参阅相应文档，如 标准库参考 和 语言参考。 如果你想了解某项改变的完整实现和设计理念，请参阅相应新特性的 PEP；但请注意一旦某项特性已完全实现则相应 PEP 通常不会再继续更新。

新的语法特性：

- PEP 695，类型形参语法和 `type` 语句

新的语法特性：

- PEP 701，f-字符串 语法的改进

解释器的改进：

- PEP 684，单独的每解释器 GIL

- PEP 669，低开销的监控

- 针对 `NameError`, `ImportError` 和 `SyntaxError` 异常 改进了 'Did you mean ...' 提示消息。

对 Python 数据模型的改进：

- PEP 688，使用 Python 的 缓冲区协议

标准库中的重大改进：

- `pathlib.Path` 类现在支持子类化

- `os` 模块获得了多项针对 Windows 支持的改进

- 在 `sqlite3` 模块中添加了 命令行界面。

- 基于 `运行时可检测协议` 的 `isinstance()` 检测获得了 2 至 20 倍的提速

- `asyncio` 包的性能获得了多项改进，一些基准测试显示有 75% 的提速。

- 在 `uuid` 模块中添加了 命令行界面。

- 由于 PEP 701 中的更改，通过 `tokenize` 模块生成令牌（token）的速度最多可提高 64%。

安全改进：

- 用来自 HACL* 项目的经过正式验证的代码替代 SHA1, SHA3, SHA2-384, SHA2-512 和 MD5 的内置 `hashlib` 实现。 这些内置实现保留作为仅在当 OpenSSL 未提供它们时使用的回退选项。

C API 的改进：

- PEP 697，不稳定 C API 层

- PEP 683，永生对象

CPython 实现的改进：

- PEP 709，推导式内联化

- 对 Linux `perf` 性能分析器的 CPython 支持

- 在受支持的平台上实现栈溢出保护

新的类型标注特性：

- PEP 692，使用 `TypedDict` 来标注 **kwargs

- PEP 698，`typing.override()` 装饰器

重要的弃用、移除或限制：

- PEP 623: 在 Python 的 C API 中移除 Unicode 对象中的 `wstr`，使每个 `str` 对象的大小缩减至少 8 个字节。

- PEP 632: 移除 `distutils` 包。 请参阅 迁移指南 了解有关替换其所提供的 API 的建议。 第三方 Setuptools 包将继续提供 `distutils`，如果你在 Python 3.12 及更高版本中仍然需要它的话。

- gh-95299: 不在使用 `venv` 创建的虚拟环境中预装 `setuptools`。 这意味着 `distutils`、`setuptools`、`pkg_resources` 和 `easy_install` 默认将不再可用；要访问这些工具请在 激活的 虚拟环境中运行 `pip install setuptools`。

- 移除了 `asynchat`、`asyncore` 和 `imp` 模块，以及一些 `unittest.TestCase` 方法别名。

## 新的特性

### PEP 695: 类型形参语法

PEP 484 下的泛型类和函数是使用详细语法声明的，这使得类型参数的范围不明确，并且需要显式声明变化。

PEP 695 引入了一种新的、更紧凑、更明确的方式来创建 泛型类 和 函数:

    def max[T](args: Iterable[T]) -> T:
        ...

    class list[T]:
        def __getitem__(self, index: int, /) -> T:
            ...

        def append(self, element: T) -> None:
            ...

此外，该 PEP 引入了一种新的方法来使用 `type` 语句声明 类型别名，该语句会创建 `TypeAliasType` 的实例:

    type Point = tuple[float, float]

类型别名也可以是 generic:

    type Point[T] = tuple[T, T]

新语法允许声明 `TypeVarTuple` 和 `ParamSpec` 形参，以及带边界或约束的 `TypeVar` 形参:

    type IntFunc[**P] = Callable[P, int]  # ParamSpec
    type LabeledTuple[*Ts] = tuple[str, *Ts]  # TypeVarTuple
    type HashableSequence[T: Hashable] = Sequence[T]  # 带边界的 TypeVar
    type IntOrStrSequence[T: (int, str)] = Sequence[T]  # 带约束的 TypeVar

类型别名的值以及通过此语法创建的类型变量的边界和约束仅在需要时才进行求值 (参见 惰性求值)。 这意味着类型别名可以引用稍后在文件中定义的其他类型。

通过类型参数列表声明的类型参数在声明的作用域和任何嵌套的作用域内都可见，但在外部作用域内不可见。 例如，它们可以用于泛型类的方法的类型注解或类体中。 但是，在定义类之后，不能在模块范围中使用它们。 有关类型参数的运行时语义的详细描述，请参见 类型形参列表。

为了支持这些作用域定义，引入了一种新的作用域，即 标注作用域。 标注作用域的行为在很大程度上类似于函数作用域，但与封闭类作用作用域的交互方式不同。 在 Python 3.13 中，标注 也将在标注作用域中进行求值。

更多细节请参见 PEP 695。

（PEP由 Eric Traut 撰写。 由 Jelle Zijlstra、Eric Traut 和其他人在 gh-103764 中实现。）

### PEP 701：f-字符串的句法形式化

PEP 701 取消了对 f-字符串 使用的一些限制。 f-字符串内部的表达式部分现在可以是任何有效的 Python 表达式，包括重用了与标记 f-字符串本身相同的引号的字符串、多行表达式、注释、反斜杠以及 unicode 转义序列。 让我们详细介绍一下：

- 引号重用：在 Python 3.11 中，重用与标记 f-字符串本身相同的引号会引发 `SyntaxError`，迫使用户使用其他可用的引号（如在 f-字符串使用单引号时使用双引号或三重引号）。 在 Python 3.12 中，你现在可以这样做了：

      >>> songs = ['Take me back to Eden', 'Alkaline', 'Ascensionism']
      >>> f"This is the playlist: {", ".join(songs)}"
      'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'

  请注意，在这一更改之前，对f-字符串的嵌套方式没有明确的限制，但字符串引号不能在f-字符串的表达式组件中重复使用，这使得不可能任意嵌套f-字符串。事实上，这是可以编写的嵌套最多的f-字符串：

      >>> f"""{f'''{f'{f"{1+1}"}'}'''}"""
      '2'

  由于现在f-字符串可以在表达式组件中包含任何有效的Python表达式，因此现在可以任意嵌套f-字符串：

      >>> f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}"
      '2'

- 多行表达式和注释：在 Python 3.11 中，f-字符串表达式必须在一行中完成定义，即使 f-字符串中的表达式在正常情况下可以跨多行（如在多行中定义的列表字面值），这使得它们更难被读懂。 在 Python 3.12 中，你现在可以定义跨越多行的 f-字符串并添加内联注释：

      >>> f"This is the playlist: {", ".join([
      ...     'Take me back to Eden',  # My, my, those eyes like fire
      ...     'Alkaline',              # Not acid nor alkaline
      ...     'Ascensionism'           # Take to the broken skies at last
      ... ])}"
      'This is the playlist: Take me back to Eden, Alkaline, Ascensionism'

- 反斜杠和 unicode 字符：在 Python 3.12 之前，f-字符串表达式不能包含任何 `\` 字符。 这也影响了 unicode 转义序列 (如 `\N{snowman}`)，因为这些序列包含 `\N` 部分，而这部分以前不能作为 f-字符串表达式组件的一部分。 现在，你可以这样定义表达式：

      >>> print(f"This is the playlist: {"\n".join(songs)}")
      This is the playlist: Take me back to Eden
      Alkaline
      Ascensionism
      >>> print(f"This is the playlist: {"\N{BLACK HEART SUIT}".join(songs)}")
      This is the playlist: Take me back to Eden♥Alkaline♥Ascensionism

更多细节请参见 PEP 701。

实现此特性的一个正面的附带影响是（通过使用 PEG 解析器 来解析 f-字符串），现在 f-字符串的错误消息会更加精确，包括错误的确切位置。例如，在 Python 3.11 中，下面的 f-字符串将引发一个 `SyntaxError` ：

    >>> my_string = f"{x z y}" + f"{1 + 1}"
      File "<stdin>", line 1
        (x z y)
         ^^^
    SyntaxError: f-string: invalid syntax. Perhaps you forgot a comma?

但是错误消息不包括错误在行中的确切位置，而且表达式被人为地用括号括起来。在Python 3.12中，由于f-字符串是用PEG解析器解析的，因此错误消息可以更精确，并显示整行：

    >>> my_string = f"{x z y}" + f"{1 + 1}"
      File "<stdin>", line 1
        my_string = f"{x z y}" + f"{1 + 1}"
                       ^^^
    SyntaxError: invalid syntax. Perhaps you forgot a comma?

（由 Pablo Galindo、Batuhan Taskaya、 Lysandros Nikolaou、Cristián Maureira-Fredes 和 Marta Gómez 在 gh-102856 中贡献。 PEP 由 Pablo Galindo、 Batuhan Taskaya、 Lysandros Nikolaou 和 Marta Gómez 撰写）。

### PEP 684: 每解释器 GIL

PEP 684 引入了每解释器 GIL，使得现在可以创建带有单独的每解释器 GIL 的子解释器。 这将允许 Python 程序充分利用多个 CPU 核心。 此特性目前仅能通过 C-API 使用，不过相应的 Python API 预计将在 3.13 中添加。

使用新的 `Py_NewInterpreterFromConfig()` 函数来创建具有单独 GIL 的解释器：

    PyInterpreterConfig config = {
        .check_multi_interp_extensions = 1,
        .gil = PyInterpreterConfig_OWN_GIL,
    };
    PyThreadState *tstate = NULL;
    PyStatus status = Py_NewInterpreterFromConfig(&tstate, &config);
    if (PyStatus_Exception(status)) {
        return -1;
    }
    /* 新解释器现已在当前线程中激活。 */

有关如何将For further examples how to use the C-API 用于具有每解释器 GIL 的子解释器的更多示例，请参见 `Modules/_xxsubinterpretersmodule.c`。

（由 Eric Snow 在 gh-104210 等中贡献。）

### PEP 669：针对 CPython 的低影响监控

PEP 669 定义了一个新的 `API` 用于性能分析器、调试器和其他在 CPython 中监控事件的工具。 它覆盖了大范围的事件，包括调用、返回、行、异常、跳转等等。 这意味着你将只为你所使用的东西付出开销，提供了对近乎零开销的调试器和覆盖工具的支持。 请参阅 `sys.monitoring` 了解详情。

（由 Mark Shannon 在 gh-103082 中贡献。）

### PEP 688: 使缓冲区协议在Python中可访问

PEP 688 引入了一种在 Python 代码中使用 缓冲区协议 的方法。实现 `__buffer__()` 方法的类现在可以作为缓冲区类型使用。

新的 `collections.abc.Buffer` ABC（抽象基类）提供了一种表示缓冲区对象的标准方法，例如在类型注释中。 新的 `inspect.BufferFlags` 枚举表示可用于自定义缓冲区创建的标志。 （由 Jelle Zijlstra 在 gh-102500 中贡献。）

### PEP 709：推导式内联

字典、列表和集合推导式现在都是内联的，而不是为每次执行推导式都创建一个新的一次性函数对象。 这样可以将推导式的执行速度提高最多两倍。 更多细节请参阅 PEP 709。

推导式迭代变量将保持隔离而不会覆盖外作用域中的同名变量，在离开推导式后也不再可见。 内联确实会导致一些可见的行为变化：

- 回溯中的推导式不再有单独的帧，跟踪/评测也不再将推导式显示为函数调用。

- `symtable` 模块将不再为每个推导式产生子符号表；取而代之的是，推导式的 locals 将包括在父函数的符号表中。

- 在推导式内部调用 `locals()` 现在包括该推导式外部外部的变量，而不再包括推导式“参数”导致的 `.0` 合成变量。

- 一个直接迭代 `locals()` 的推导式 (例如 `[k for k in locals()]`) 在启动追踪 (例如检测代码覆盖度) 的情况下运行时可能导致 "RuntimeError: dictionary changed size during iteration"。 此行为与现有的 `for k in locals():` 等代码保持一致。 要避免此错误，可先创建一个由键组成的列表用于迭代: `keys = list(locals()); [k for k in keys]`。

（由 Carl Meyer 和 Vladimir Matveev 在 PEP 709 中贡献。）

### 改进的错误消息

- 当引发的 `NameError` 传播到最高层级时，解释器显示的错误消息可能将标准库中的模块作为建议的一部分。 （由 Pablo Galindo 在 gh-98254 中贡献。）

      >>> sys.version_info
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      NameError: name 'sys' is not defined. Did you forget to import 'sys'?

- 改进针对实例的 `NameError` 异常的错误建议。 现在如果在方法中引发了 `NameError` 而实例具有与异常中的名称完全相同的属性，建议将会包括 `self.<NAME>` 而不是方法作用域中最接近的匹配项。 （由 Pablo Galindo 在 gh-99139 中贡献。）

      >>> class A:
      ...    def __init__(self):
      ...        self.blech = 1
      ...
      ...    def foo(self):
      ...        somethin = blech
      ...
      >>> A().foo()
      Traceback (most recent call last):
        File "<stdin>", line 1
          somethin = blech
                     ^^^^^
      NameError: name 'blech' is not defined. Did you mean: 'self.blech'?

- 改进了当用户输入 `import x from y` 而不是 `from y import x` 时产生的 `SyntaxError` 错误消息。 （由 Pablo Galindo 在 gh-98931 中贡献。）

      >>> import a.y.z from b.y.z
      Traceback (most recent call last):
        File "<stdin>", line 1
          import a.y.z from b.y.z
          ^^^^^^^^^^^^^^^^^^^^^^^
      SyntaxError: Did you mean to use 'from ... import ...' instead?

- 由失败的 `from <module> import <name>` 语句引发的 `ImportError` 异常现在会包括根据 `<module>` 中的可用名称对 `<name>` 的值提出的建议。 （由 Pablo Galindo 在 gh-91058 中贡献。）

      >>> from collections import chainmap
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      ImportError: cannot import name 'chainmap' from 'collections'. Did you mean: 'ChainMap'?

## 有关类型提示的新增特性

本节介绍了影响 类型提示 和 `typing` 模块的主要更改。

### PEP 692: 使用 `TypedDict` 进行更精确的 `**kwargs` 类型标注

在函数签名中的 `**kwargs` 类型标注（由 PEP 484 引入）只允许在所有 `**kwargs` 都属于同一类型的情况下进行有效标注。

PEP 692 通过依赖类型化的字典规定了一种更精确的针对 `**kwargs` 的类型标注方式:

    from typing import TypedDict, Unpack

    class Movie(TypedDict):
      name: str
      year: int

    def foo(**kwargs: Unpack[Movie]): ...

更多细节请参见 PEP 692。

（由 Franek Magiera 在 gh-103629 中贡献。）

### PEP 698：覆盖静态类型的装饰器

一个新的装饰器 `typing.override()` 已添加到 `typing` 模块中。 它向类型检查器指示该方法旨在重写超类中的方法。 这允许类型检查器在打算重写基类中的某个方法实际上没有重写的情况下捕获错误。

示例：

    from typing import override

    class Base:
      def get_color(self) -> str:
        return "blue"

    class GoodChild(Base):
      @override  # 正确：重写 Base.get_color
      def get_color(self) -> str:
        return "yellow"

    class BadChild(Base):
      @override  # 类型检查错误：不能重写 Base.get_color
      def get_colour(self) -> str:
        return "red"

更多细节参见 PEP 698。

（由 Steven Troxler 在 gh-101561 中贡献。）

## 其他语言特性修改

- 解析器现在在解析包含空字节的源代码时引发 `SyntaxError`。 （由 Pablo Galindo 在 gh-96670 中贡献 。）

- 不是有效转义序列的反斜杠加字符组合现在会生成 `SyntaxWarning`，而不是 `DeprecationWarning`。 例如，`re.compile("\d+\.\d+")` 现在会发出 `SyntaxWarning` (`"\d"` 是一个无效的转义序列，请使用原始字符串来表示正则表达式: `re.compile(r"\d+\.\d+")`)。 在未来的 Python 版本中，最终将引发 `SyntaxError`，而不是 `SyntaxWarning`。 （由 Victor Stinner 在 gh-98401 中贡献。）

- 值大于 `0o377` (例如: `"\477"`) 的八进制转义序列，在 Python 3.11 中已弃用，现在会产生 `SyntaxWarning`，而不是 `DeprecationWarning`。 在未来的 Python 版本中，它们最终将是 `SyntaxError`。 （由 Victor Stinner 在 gh-98401 中贡献。）

- 未存储在推导式目标部分中的变量现在可以在赋值表达式 (`:=`) 中使用。 例如，在 `[(b := 1) for a, b.prop in some_iter]` 中，现在允许对 `b` 进行赋值。 请注意，根据 PEP 572，仍然不允许向存储在推导式目标部分中的变量 (如 `a`) 赋值。 （由 Nikita Sobolev 在 gh-100581 中贡献。）

- 在类或类型对象的 `__set_name__` 方法中引发的异常不再由 `RuntimeError` 来包装。 上下文信息将作为 PEP 678 注释添加到异常中。 （由 Irit Katriel 在 gh-77757 中贡献。）

- 当 `try-except*` 构造处理整个 `ExceptionGroup` 并引发另一个异常时，该异常不再封装在 `ExceptionGroup` 中。 在 3.11.4 版中也进行了更改。 （由 Irit Katriel 在 gh-103590 中贡献。）

- 垃圾回收器现在只在 Python 字节码评估循环的 eval-breaker 机制上运行，而不是在对象分配上运行。 垃圾回收也可以在调用 `PyErr_CheckSignals()` 时运行，因此需要长时间运行而不执行任何 Python 代码的 C 扩展也有机会定期执行垃圾回收。 （由 Pablo Galindo 在 gh-97922 中贡献。）

- 所有期望布尔参数的内置和扩展可调用函数现在都接受任何类型的参数，而不仅仅是 `bool` 和 `int`。 （由 Serhiy Storchaka 在 gh-60203 中贡献。）

- `memoryview` 现在支持半精度浮点类型（"e" 格式代码）。 （由 Donghee Na 和 Antoine Pitrou 在 gh-90751 中贡献。）

- `slice` 对象现在是可哈希的，允许它们用作字典的键和集合项。 （由 Will Bradshaw、Furkan Onder 和 Raymond Hettinger 在 gh-101264 中贡献。）

- `sum()` 现在使用 Neumaier 求和算法以改善对浮点数或混合了整数和浮点数时求和运算的准确性和可换算性。 （由 Raymond Hettinger 在 gh-100425 中贡献。）

- `ast.parse()` 现在会在解析包含空字节的源代码时引发 `SyntaxError` 而不是 `ValueError`。 （由 Pablo Galindo 在 gh-96670 中贡献 。）

- `tarfile` 中的提取方法和 `shutil.unpack_archive()` 有一个新的 filter 参数，它允许限制可能令人惊讶或危险的 tar 功能，例如在目标目录之外创建文件。 相关细节请参阅 tarfile 提取过滤器。 在 Python 3.14 中。默认值将切换为 `'data'`。 （由 Petr Viktorin 在 PEP 706 中贡献。）

- 如果底层映射是可哈希的，那么 `types.MappingProxyType` 实例现在是可哈希的。 （由 Serhiy Storchaka 在 gh-87995 中贡献。）

- 通过新的环境变量 `PYTHONPERFSUPPORT` 和命令行选项 `-X perf` 以及新的 `sys.activate_stack_trampoline()`, `sys.deactivate_stack_trampoline()` 和 `sys.is_stack_trampoline_active()` 函数添加了对 perf 性能分析器的支持。 （由 Pablo Galindo 设计。 由 Pablo Galindo 和 Christian Heimes 在 gh-96123 中贡献并包含来自 Gregory P. Smith [Google] 和 Mark Shannon 的帮助。）

## 新增模块

- 无。

## 改进的模块

### array

- `array.array` 类现在支持下标，使其成为 generic type。 （由 Jelle Zijlstra 在 gh-98658 中贡献。）

### asyncio

- 在 `asyncio` 中写入套接字的性能得到了显著提高。 `asyncio` 现在可以避免在写入套接字时进行不必要的复制，并在平台支持的情况下使用 `sendmsg()`。 （由 Kumar Aditya 在 gh-91166 中贡献。）

- 添加了 `asyncio.eager_task_factory()` 和 `asyncio.create_eager_task_factory()` 函数以允许在主动型任务执行中选择事件循环，使某些用例的速度提升了 2 至 5 倍。 （由 Jacob Bower 和 Itamar Oren 在 gh-102853, gh-104140 和 gh-104138 中贡献。）

- 在 Linux 上，如果 `os.pidfd_open()` 可用且能工作则 `asyncio` 默认会使用 `asyncio.PidfdChildWatcher` 而不是 `asyncio.ThreadedChildWatcher`。 （由 Kumar Aditya 在 gh-98024 中贡献。）

- 现在事件循环会针对每个平台使用最佳的可用子监视器（在受支持的情况下使用 `asyncio.PidfdChildWatcher`，否则使用 `asyncio.ThreadedChildWatcher`），因此不建议手动配置子监视器。 （由 Kumar Aditya 在 gh-94597 中贡献。）

- 为 `asyncio.run()` 添加了形参 loop_factory，以允许指定自定义事件循环工厂。 （由 Kumar Aditya 在 gh-99388 中贡献。）

- 添加了 `asyncio.current_task()` 的 C 实现以实现 4 - 6 倍的加速。 （由 Itamar Oren 和 Pranav Thulasiram Bhat 在 gh-100344 中贡献。）

- `asyncio.iscoroutine()` 现在为生成器返回 `False`，因为 `asyncio` 不支持传统的基于生成器的协程。 （由 Kumar Aditya 在 gh-102748 中贡献。）

- `asyncio.wait()` 和 `asyncio.as_completed()` 现在接受生成器 yield 任务。 （由 Kumar Aditya 在 gh-78530 中贡献。）

### calendar

- 添加了枚举 `calendar.Month` 和 `calendar.Day` 来定义年份中的每一月和星期中的每一日。 （由 Prince Roshan 在 gh-103636 中贡献。）

### csv

- 增加了 `csv.QUOTE_NOTNULL` 和 `csv.QUOTE_STRINGS` 旗标以通过 `reader` 和 `writer` 对象来提供对 `None` 和空字符串更细粒度的控制。

### dis

- 伪指令操作码（由编译器使用但不会出现在可执行字节码中）现在将暴露在 `dis` 模块中。 `HAVE_ARGUMENT` 仍然与实际的操作码相关，但对伪指令来说没有用处。 请改用新的 `dis.hasarg` 多项集。 （由 Irit Katriel 在 gh-94216 中贡献。）

- 添加了 `dis.hasexc` 多项集来表示设置异常处理器的指令。 （由 Irit Katriel 在 gh-94216 中贡献。）

### fractions

- 类型为 `fractions.Fraction` 的对象现在支持浮点格式。 （由 Mark Dickinson 在 gh-100161 中贡献。）

### importlib.resources

- `importlib.resources.as_file()` 现在将支持资源目录。 （由 Jason R. Coombs 在 gh-97930 中贡献。）

- 将 `importlib.resources.files()` 的第一个形参重命名为 anchor。 （由 Jason R. Coombs 在 gh-100598 中贡献。）

### inspect

- 增加了 `inspect.markcoroutinefunction()` 来标记返回 coroutine 的同步函数以便与 `inspect.iscoroutinefunction()` 一起使用。 （由 Carlton Gibson 在 gh-99247 中贡献。）

- 添加 `inspect.getasyncgenstate()` 和 `inspect.getasyncgenlocals()` 用来确定异步发生器的当前状态。 （由 Thomas Krennwallner 在 gh-79940 中贡献。）

- `inspect.getattr_static()` 的性能已得到显著提升。 对该函数的大多数调用相比 Python 3.11 至少应有 2 倍的加速。 （由 Alex Waygood 在 gh-103193 中贡献。）

### itertools

- 增加了 `itertools.batched()` 用来将数据收集为相同大小的元组，其中最后一个批次的长度可能会比其余的批次短。 （由 Raymond Hettinger 在 gh-98363 中贡献。）

### math

- 添加了 `math.sumprod()` 用于计算乘积之和。 （由 Raymond Hettinger 在 gh-100485 中贡献。）

- 扩展了 `math.nextafter()` 以包括一个 steps 参数用于一次性向上或向下移动多步。 （由 Matthias Goergens, Mark Dickinson 和 Raymond Hettinger 在 gh-94906 中贡献。）

### os

- 增加了 `os.PIDFD_NONBLOCK` 以在非阻塞模式下打开具有 `os.pidfd_open()` 的进程的文件描述符。 （由 Kumar Aditya 在 gh-93312 中贡献。）

- `os.DirEntry` 现在包括一个 `os.DirEntry.is_junction()` 方法来检查该条目是否为目录联接。 （由 Charles Machalow 在 gh-99547 中贡献。）

- 在 Windows 版中添加 `os.listdrives()`、`os.listvolumes()` 和 `os.listmounts()` 函数，用于枚举驱动器、卷和挂载点。 （由 Steve Dower 在 gh-102519 中贡献。）

- `os.stat()` 和 `os.lstat()` 现在在 Windows 系统上更准确了。 `st_birthtime` 字段现在将使用文件的创建时间，`st_ctime` 已弃用，但仍包含创建时间（但为了与其他平台保持一致，将来将返回最后一次元数据更改时间）。 `st_dev` 可以高达 64 位，`st_ino` 可以高达 128 位，具体取决于你的文件系统，并且 `st_rdev` 始终设置为零，而非不正确的值。 这两个函数在较新版本的 Windows 上将会明显更快。 （由 Steve Dower 在 gh-99726 中贡献。）

### os.path

- 添加 `os.path.isjunction()` 以检查给定路径是否为目录联接。 （由 Charles Machalow 在 gh-99547 中贡献。）

- 添加 `os.path.splitroot()` 以将路径拆分为三元组 `(drive, root, tail)`。（由 Barney Gale 在 gh-101000 中贡献。）

### pathlib

- 增加对子类化 `pathlib.PurePath` 和 `pathlib.Path`，加上它们的 Posix 和 Windows 专属变体形式的支持。 子类可以重载 `pathlib.PurePath.with_segments()` 方法来在路径实例之间传递信息。

- 添加 `pathlib.Path.walk()` 用于遍历目录树并生成其中的所有文件或目录名，类似于 `os.walk()`。 （由 Stanislav Zmiev 在 gh-90385 中贡献。）

- 在 `pathlib.PurePath.relative_to()` 中添加了 walk_up 可选形参以允许在结果中插入 `..` 条目；此行为与 `os.path.relpath()` 更为一致。（由 Domenico Ragusa 在 gh-84538 中贡献。）

- 添加 `pathlib.Path.is_junction()` 作为 `os.path.isjunction()` 的代理。 （由 Charles Machalow 在 gh-99547 中贡献。）

- 为 `pathlib.Path.glob()`、`pathlib.Path.rglob()` 和 `pathlib.PurePath.match()` 添加可选形参 case_sensitive，以匹配路径的大小写敏感性，从而对匹配过程进行更精确的控制。

### platform

- 增加了对 Windows 11 和 Windows Server 2012 之后的发行版的检测。 在之前版本中，在 Windows Server 2012 以上的 Windows Server 平台和 Windows 11 上的查询将返回 `Windows-10`。 （由 Steve Dower 在 gh-89545 中贡献。）

### pdb

- 添加便利变量以临时保存调试会话的值，并提供对当前帧或返回值等值的快速访问。 （由高天在 gh-103693 中贡献。）

### random

- 添加了 `random.binomialvariate()`。 （由 Raymond Hettinger 在 gh-81620 中贡献。）

- 在 `random.expovariate()` 中添加默认值 `lambd=1.0` 。 （由 Raymond Hettinger 在 gh-100234 中贡献。）

### shutil

- `shutil.make_archive()` 现在将 rootdir 参数传递给支持它的自定义存档程序。 在这种情况下，它不再临时将进程的当前工作目录更改为 rootdir 来执行存档。 （由 Serhiy Storchaka 在 gh-74696 中贡献。）

- `shutil.rmtree()` 现在接受一个新的参数 onexc，它是一个类似 onerror 的错误处理器，但它接受一个异常实例而不是一个 (typ, val, tb) 三元组。 onerror 已被弃用。 （由 Irit Katriel 在 gh-102828 中贡献。）

- `shutil.which()` 现在即使给定的 cmd 包含目录组件，在 Windows 系统上也会参考 PATHEXT 环境变量在 PATH 中查找匹配项。 （由 Charles Machalow 在 gh-103179 中贡献。）

  `shutil.which()` 将在 Windows 上查询可执行文件时调用 `NeedCurrentDirectoryForExePathW`，以确定是否应将当前工作目录预先设置为搜索路径。 （由 Charles Machalow 在 gh-103179 中贡献。）

  在 Windows 上 `shutil.which()` 将在搜索路径的其他地方直接匹配之前返回 cmd 与来自 `PATHEXT` 的组件相匹配的路径。 （由 Charles Machalow 在 gh-103179 中贡献。）

### sqlite3

- 增加了一个 命令行接口。 （由 Erlend E. Aasland 在 gh-77617 中贡献。）

- 向 `sqlite3.Connection` 添加 `sqlite3.Connection.autocommit` 属性并向 `sqlite3.connect()` 添加 autocommit 形参用于控制兼容 PEP 249 的 事务处理。 （由 Erlend E. Aasland 在 gh-83638 中贡献。）

- 向 `sqlite3.Connection.load_extension()` 添加 entrypoint 仅限关键字形参，用于覆盖 SQLite 扩展入口点。 （由 Erlend E. Aasland 在 gh-103015 中贡献。）

- 向 `sqlite3.Connection` 添加 `sqlite3.Connection.getconfig()` 和 `sqlite3.Connection.setconfig()` 用于对数据库连接进行配置修改。 （由 Erlend E. Aasland 在 gh-103489 中贡献。）

### statistics

- 扩展 `statistics.correlation()` 以 `ranked` 方法的形式包括对分级数据的斯皮尔曼相关性计算。 （由 Raymond Hettinger 在 gh-95861 中贡献。）

### sys

- 添加了 `sys.monitoring` 命名空间以公开新的 PEP 669 监控 API。 （由 Mark Shannon 在 gh-103082 中贡献。）

- 增加了 `sys.activate_stack_trampoline()` 和 `sys.deactivate_stack_trampoline()` 用于激活和停用栈性能分析器 trampoline，以及 `sys.is_stack_trampoline_active()` 用于查询栈性能分析器 trampoline 是否激活。 （基于 Gregory P. Smith [Google] 和 Mark Shannon 的贡献由 Pablo Galindo 和 Christian Heimes 在 gh-96123 中贡献。）

- 增加了 `sys.last_exc` 用于保存最新引发的未处理异常（针对事后调试的应用场景）。 弃用了以三个字段来保存相同信息的旧形式: `sys.last_type`, `sys.last_value` 和 `sys.last_traceback`。 （由 Irit Katriel 在 gh-102778 中贡献。）

- 现在 `sys._current_exceptions()` 将返回从线程 ID 到异常实例的映射，而不是到 `(typ, exc, tb)` 元组的映射。 （由 Irit Katriel 在 gh-103176 中贡献。）

- `sys.setrecursionlimit()` 和 `sys.getrecursionlimit()`。 递归限制现在只应用于 Python 代码。 内置函数不使用该递归限制，但受到另一种可防止递归导致虚拟机崩溃的机制保护。

### tempfile

- `tempfile.NamedTemporaryFile` 函数增加了一个新的可选形参 delete_on_close。 （由 Evgeny Zorin 在 gh-58451 中贡献。）

- `tempfile.mkdtemp()` 现在将总是返回一个绝对路径，即使提供给 dir 形参的参数是一个相对路径。

### threading

- 增加了 `threading.settrace_all_threads()` 和 `threading.setprofile_all_threads()` 以允许在所运行的全部线程中设置追踪和性能分析函数而不是只在调用方线程中。 （由 Pablo Galindo 在 gh-93503 中贡献。）

### tkinter

- 现在 `tkinter.Canvas.coords()` 会展平其参数。 它现在不仅接受单独参数形式的坐标 (`x1, y1, x2, y2, ...`) 以及由坐标组成的序列 (`[x1, y1, x2, y2, ...]`)，也接受成对分组 (`(x1, y1), (x2, y2), ...` 和 `[(x1, y1), (x2, y2), ...]`) 形式的坐标，就像 `create_*()` 方法一样。 （由 Serhiy Storchaka 在 gh-94473 中贡献。）

### tokenize

- `tokenize` 模块包括了 PEP 701 所引入的更改。 （由 Marta Gómez Macías 和 Pablo Galindo 在 gh-102856 中贡献。） 请参阅 移植到 Python 3.12 了解有关对 `tokenize` 模块的更改详情。

### types

- 增加了 `types.get_original_bases()` 以允许在子类化时继续对 用户定义的泛型类型 进行内省。 （由 James Hilton-Balfe 和 Alex Waygood 在 gh-101827 中贡献。）

### typing

- 针对 `运行时可检测协议` 的 `isinstance()` 检测现在会使用 `inspect.getattr_static()` 而不是 `hasattr()` 来查找属性是否存在。 这意味着描述器和 `__getattr__()` 方法在针对运行时可检测协议的 `isinstance()` 检测期间不会被意外地求值。 但是，这也意味着某些原来被视为运行时可检测协议的实例的对象在 Python 3.12+ 上将不再被视为运行时可检测协议的实例，反之亦然。 大部分用户都不太可能受到这一改变的影响。 （由 Alex Waygood 在 gh-102433 中贡献。）

- 现在运行时可检测协议的成员在运行时一旦创建了相应的类就将被视为“已冻结”。 作用于运行时可检测协议的猴子补丁属性将仍然可用，但不会再影响将对象与协议进行比较的 `isinstance()` 检测中。 例如:

      >>> from typing import Protocol, runtime_checkable
      >>> @runtime_checkable
      ... class HasX(Protocol):
      ...     x = 1
      ...
      >>> class Foo: ...
      ...
      >>> f = Foo()
      >>> isinstance(f, HasX)
      False
      >>> f.x = 1
      >>> isinstance(f, HasX)
      True
      >>> HasX.y = 2
      >>> isinstance(f, HasX)  # 无变化，虽然 HasX 现在也有一个 "y" 属性
      True

  应用这项改变是为了提高针对运行时可检测协议的 `isinstance()` 检测速度。

- 针对 `运行时可检测协议` 的 `isinstance()` 检测的性能表现有显著的改进。 对于仅有少量成员的协议的大部分 `isinstance()` 检测相比 3.11 应当至少有 2 倍的加速。 不过，对于具有大量成员的协议的 `isinstance()` 检测可能会慢于 Python 3.11。 （由 Alex Waygood 在 gh-74690 和 gh-103193 中贡献。）.)

- 现在所有 `typing.TypedDict` 和 `typing.NamedTuple` 类都具有 `__orig_bases__` 属性。 （由 Adrian Garcia Badaracco 在 gh-103699 中贡献。）

- 向 `typing.dataclass_transform()` 添加了 `frozen_default` 形参。 （由 Erik De Bonte 在 gh-99957 中贡献。）

### unicodedata

- Unicode 数据库已更新到 15.0.0 版。 （由 Benjamin Peterson 在 gh-96734 中贡献。）

### unittest

增加了 `--durations` 命令行选项，显示 N 个最慢的测试用例:

    python3 -m unittest --durations=3 lib.tests.test_threading
    .....
    Slowest test durations
    ----------------------------------------------------------------------
    1.210s     test_timeout (Lib.test.test_threading.BarrierTests)
    1.003s     test_default_timeout (Lib.test.test_threading.BarrierTests)
    0.518s     test_timeout (Lib.test.test_threading.EventTests)

    (0.000 durations hidden.  Use -v to show these durations.)
    ----------------------------------------------------------------------
    Ran 158 tests in 9.869s

    OK (skipped=3)

（由 Giampaolo Rodola 在 gh-48330 中贡献。）

### uuid

- 增加了一个 命令行接口。 （由 Adam Chhina 在 gh-88597 中贡献。）

## 性能优化

- 从 Unicode 对象中移除了 `wstr` 和 `wstr_length` 成员。 这使得对象大小在 64 位平台上减少了 8 个或 16 个字节。 (PEP 623) （由 Inada Naoki 在 gh-92536 中贡献。）

- 增加了在构建进程中使用 BOLT 二进制优化器的实验性支持，这将使得性能提升 1-5%。 （由 Kevin Modzelewski 在 gh-90536 中贡献并由 Donghee Na 在 gh-101525 中微调。 ）

- 对于包含分组引用的替换字符串的正则表达式替换（包括 `re.sub()` 和 `re.subn()` 函数及对应的 `re.Pattern` 方法）可加速 2--3 倍。 （由 Serhiy Storchaka 在 gh-91524 中贡献。）

- 通过推迟高消耗的字符串格式化来加速 `asyncio.Task` 的创建的。 （由 Itamar Oren 在 gh-103793 中贡献。）

- 作为在 `tokenize` 模块中应用 PEP 701 所要求的更改的附带效果，`tokenize.tokenize()` 和 `tokenize.generate_tokens()` 函数可加速至多 64%。 （由 Marta Gómez Macías 和 Pablo Galindo 在 gh-102856 中贡献。）

- 通过新的 `LOAD_SUPER_ATTR` 指令加速 `super()` 方法调用和属性加载。 （由 Carl Meyer 和 Vladimir Matveev 在 gh-103497 中贡献。）

## CPython 字节码的改变

- 移除了 `LOAD_METHOD` 指令。 它已被合并至 `LOAD_ATTR`。 现在如果设置了 `LOAD_ATTR` 的 oparg 比特位则它的行为将类似原来的 `LOAD_METHOD`。 （由 Ken Jin 在 gh-93429 中贡献。）

- 移除了 `JUMP_IF_FALSE_OR_POP` 和 `JUMP_IF_TRUE_OR_POP` 指令。 （由 Irit Katriel 在 gh-102859 中贡献。）

- 移除了 `PRECALL` 指令。 （由 Mark Shannon 在 gh-92925 中贡献。）

- 添加了 `BINARY_SLICE` 和 `STORE_SLICE` 指令。 （由 Mark Shannon 在 gh-94163 中贡献。）

- 添加了 `CALL_INTRINSIC_1` 指令。 （由 Mark Shannon 在 gh-99005 中贡献。）

- 添加了 `CALL_INTRINSIC_2` 指令。 （由 Irit Katriel 在 gh-101799 中贡献。）

- 添加了 `CLEANUP_THROW` 指令。 （由 Brandt Bucher 在 gh-90997 中贡献。）

- 添加了 `END_SEND` 指令。 （由 Mark Shannon 在 gh-103082 中贡献。）

- 增加了 `LOAD_FAST_AND_CLEAR` 指令作为 PEP 709 的实现的组成部分。 （由 Carl Meyer 在 gh-101441 中贡献。）

- 添加了 `LOAD_FAST_CHECK` 指令。 （由 Dennis Sweeney 在 gh-93143 中贡献。）

- 增加了 `LOAD_FROM_DICT_OR_DEREF`, `LOAD_FROM_DICT_OR_GLOBALS` 和 `LOAD_LOCALS` 操作码作为 PEP 695 的组成部分。 移除了 `LOAD_CLASSDEREF` 操作码，它可以用 `LOAD_LOCALS` 加 `LOAD_FROM_DICT_OR_DEREF` 来代替。 （由 Jelle Zijlstra 在 gh-103764 中贡献。）

- 增加了 `LOAD_SUPER_ATTR` 指令。 （由 Carl Meyer 和 Vladimir Matveev 在 gh-103497 中贡献。）

- 添加了 `RETURN_CONST` 指令。（由 Wenyang Wang 在 gh-101632 中贡献。）

## 演示和工具

- 移除了包含旧演示脚本的 `Tools/demo/` 目录。 其副本可在 old-demos project 中找到。 （由 Victor Stinner 在 gh-97681 中贡献。）

- 移除了 `Tools/scripts/` 目录下过时的示例脚本。 其副本可在 old-demos project 中找到。 （由 Victor Stinner 在 gh-97669 中贡献。）

## 弃用

- `argparse`: `argparse.BooleanOptionalAction` 的 type, choices 和 metavar 形参已被弃用并将在 3.14 中移除。 （由 Nikita Sobolev 在 gh-92248 中贡献。）

- `ast`: 以下 `ast` 特性自 Python 3.8 起已在文档中声明弃用，现在当运行时如果它们被访问或使用将发出 `DeprecationWarning`，并将在 Python 3.14 中移除:

  - `ast.Num`

  - `ast.Str`

  - `ast.Bytes`

  - `ast.NameConstant`

  - `ast.Ellipsis`

  请改用 `ast.Constant`。 （由 Serhiy Storchaka 在 gh-90953 中贡献。）

- `asyncio`:

  - 子监视器类 `asyncio.MultiLoopChildWatcher`、`asyncio.FastChildWatcher`、`asyncio.AbstractChildWatcher` 和 `asyncio.SafeChildWatcher` 已被弃用并将在 Python 3.14 中移除。 （由 Kumar Aditya 在 gh-94597 中贡献。）

  - `asyncio.set_child_watcher()`、`asyncio.get_child_watcher()`、`asyncio.AbstractEventLoopPolicy.set_child_watcher()` 和 `asyncio.AbstractEventLoopPolicy.get_child_watcher()` 已弃用，并将在 Python 3.14 中移除。（由 Kumar Aditya 在 gh-94597 中贡献。）

  - 现在默认事件循环策略的 `get_event_loop()` 方法在当前事件循环未设置并决定创建一个时将发出 `DeprecationWarning`。 （由 Serhiy Storchaka 和 Guido van Rossum 在 gh-100160 中贡献。）

- `calendar`: `calendar.January` 和 `calendar.February` 常量已被弃用并由 `calendar.JANUARY` 和 `calendar.FEBRUARY` 替代。 （由 Prince Roshan 在 gh-103636 中贡献。）

- `collections.abc`: 弃用 `collections.abc.ByteString`。

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

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

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

- `datetime`: `datetime.datetime` 的 `utcnow()` 和 `utcfromtimestamp()` 已被弃用并将在未来的版本中移除。 请改用可感知时区的对象以 UTC 来表示日期时间：分别调用 `now()` 和 `fromtimestamp()` 并设置 tz 形参为 `datetime.UTC`。 （由 Paul Ganssle 在 gh-103857 中贡献。）

- `email`: 已弃用 `email.utils.localtime()` 中的 isdst 形参。 （由 Alan Williams 在 gh-72346 中贡献。）

- `importlib.abc`: 已弃用下列类，计划在 Python 3.14 中移除:

  - `importlib.abc.ResourceReader`

  - `importlib.abc.Traversable`

  - `importlib.abc.TraversableResources`

  使用 `importlib.resources.abc` 类代替:

  - `importlib.resources.abc.Traversable`

  - `importlib.resources.abc.TraversableResources`

  （由 Jason R. Coombs 和 Hugo van Kemenade 在 gh-93963 中贡献。）

- `itertools`: 已弃用对 copy、deepcopy 和 pickle 操作的支持，它们未被写入文档、效率低下、历史上充满问题且缺乏一致性。 这将在 3.14 中移除以显著减少代码量和维护负担。 （由 Raymond Hettinger 在 gh-101588 中贡献。）

- `multiprocessing`: 在 Python 3.14 中，默认的 `multiprocessing` 启动方法将在 Linux、BSD 和其他非 macOS 的 POSIX 平台上改为更安全的方法，在这些平台上目前默认为 `'fork'` (gh-84559)。 在运行时添加相关警告被认为干扰性太大因为大部分代码都不会在意这个问题。 当你的代码 需要 `'fork'` 时请使用 `get_context()` 或 `set_start_method()` API 显式地指明。 参见 上下文和启动方法。

- `pkgutil`：`pkgutil.find_loader()` 和 `pkgutil.get_loader()` 已被弃用并将在 Python 3.14 中移除；请改用 `importlib.util.find_spec()`。 （由 Nikita Sobolev 在 gh-97850 中贡献。）

- `pty`: 该模块有两个未写入文档的 `master_open()` 和 `slave_open()` 函数自 Python 2 起即已被弃用但直到 3.12 才添加了相应的 `DeprecationWarning`。 它们将在 3.14 中移除。 （由 Soumendra Ganguly 和 Gregory P. Smith 在 gh-85984 中贡献。）.)

- `os`:

  - 在 Windows 上由 `os.stat()` 和 `os.lstat()` 返回的 `st_ctime` 字段已被弃用。 在未来的发布版中，它们将包含最近的元数据修改时间，以与其他平台保持一致。 目前，它们仍然包含创建时间，该值也可通过新的 `st_birthtime` 字段获取。 （由 Steve Dower 在 gh-99726 中贡献。）

  - 在 POSIX 平台上，当 `os.fork()` 能检测到被多线程的进程调用时现在会引发 `DeprecationWarning`。 当在 POSIX 平台上这样做时总是会存在基础性的不兼容。 即使这样的代码 appeared 看起来有效。 我们添加该警告是为了引起注意，因为这种做法遇到的问题越来越频繁。 请参阅 `os.fork()` 文档了解详情并查看 这个关于 fork 与线程不兼容问题的讨论 以了解 为什么 现在我们要向开发者揭示这一长期存在的平台兼容性问题。

  当由于使用 `multiprocessing` 或 `concurrent.futures` 而出现此警告时的解决办法是使用其他的 `multiprocessing` 启动方法如 `"spawn"` 或 `"forkserver"`。

- `shutil`: `shutil.rmtree()` 的 onerror 参数已被弃用；请改用 onexc。 （由 Irit Katriel 在 gh-102828 中贡献。）

- `sqlite3`:

  - 默认适配器和转换器 现在已被弃用，请使用 适配器和转换器范例程序 并根据你的需要调整它们。 （由 Erlend E. Aasland 在 gh-90016 中贡献。）

  - 在 `execute()` 中，现在当 命名占位符 与作为 sequence 而不是 `dict` 提供的形参一起使用时将发出 `DeprecationWarning`。 从 Python 3.14 开始，当命名占位符与作为序列提供的形参一起使用时将引发 `ProgrammingError`。 （由 Erlend E. Aasland 在 gh-101698 中贡献。）

- `sys`: `sys.last_type`, `sys.last_value` 和 `sys.last_traceback` 字段已被弃用。 请改用 `sys.last_exc`。 （由 Irit Katriel 在 gh-102778 中贡献。）

- `tarfile`: 提取 tar 归档而不指定 filter 的做法已被弃用直到 Python 3.14，在该版本中 `'data'` 将成为默认过滤器。 请参阅 解压缩过滤器 了解详情。

- `typing`:

  - `typing.Hashable` 和 `typing.Sized`，分别为 `collections.abc.Hashable` 和 `collections.abc.Sized` 的别名，现已被弃用。 (gh-94309。)

  - `typing.ByteString` 自 Python 3.9 起已被弃用，现在当被使用时将会发出 `DeprecationWarning`。 （由 Alex Waygood 在 gh-91896 中贡献。）

- `xml.etree.ElementTree`: 现在该模块在对 `xml.etree.ElementTree.Element` 执行真值测试时将发出 `DeprecationWarning`。 在之前，Python 实现会发出 `FutureWarning`，而 C 实现则不会发出任何警告。 （由 Jacob Walls 在 gh-83122 中贡献。）

- `coroutine throw()`, `generator throw()` 和 `async generator throw()` 的三参数签名形式 (type, value, traceback) 已被弃用并可能在未来的 Python 版本中移除。 请改用这些函数的单参数版本。 （由 Ofey Chan 在 gh-89874 中贡献。）

- 现在当一个模块的 `__package__` 不同于 `__spec__.parent` 时将引发 `DeprecationWarning` (在之前版本中则为 `ImportWarning`)。 （由 Brett Cannon 在 gh-65961 中贡献。）

- Setting `__package__` or `__cached__` on a module is deprecated, and will cease to be set or taken into consideration by the import system in Python 3.14. (Contributed by Brett Cannon in gh-65961.)

- 对布尔值的按位取反运算符 (`~`) 已被弃用。 它在 Python 3.16 中将抛出错误。 请改用 `not` 来执行布尔值的逻辑非运算。 在你确实需要对下层的 `int` 执行按位取反运算的少数场景下，请显式地将其转换为整数值: `~int(x)`。 （由 Tim Hoffmann 在 gh-103487 中贡献。）

- 在代码对象上访问 `co_lnotab` 的做法在 Python 3.10 中已根据 PEP 626 被弃用，但直到在 3.12 中才添加了适当的 `DeprecationWarning`。 可能会在 3.15 中移除。 （由 Nikita Sobolev 在 gh-101866 中贡献。）

### 计划在 Python 3.13 中移除

模块 (参见 PEP 594):

- `aifc`

- `audioop`

- `cgi`

- `cgitb`

- `chunk`

- `crypt`

- `imghdr`

- `mailcap`

- `msilib`

- `nis`

- `nntplib`

- `ossaudiodev`

- `pipes`

- `sndhdr`

- `spwd`

- `sunau`

- `telnetlib`

- `uu`

- `xdrlib`

其他模块：

- `lib2to3`，以及 2to3 程序 (gh-84540)

API:

- `configparser.LegacyInterpolation` (gh-90765)

- `locale.resetlocale()` (gh-90817)

- `turtle.RawTurtle.settiltangle()` (gh-50096)

- `unittest.findTestCases()` (gh-50096)

- `unittest.getTestCaseNames()` (gh-50096)

- `unittest.makeSuite()` (gh-50096)

- `unittest.TestProgram.usageExit()` (gh-67048)

- `webbrowser.MacOSX` (gh-86421)

- `classmethod` 描述器串联 (gh-89519)

### 计划在 Python 3.14 中移除

- `argparse`: `argparse.BooleanOptionalAction` 的 type, choices 和 metavar 形参已被弃用并将在 3.14 中移除。 （由 Nikita Sobolev 在 gh-92248 中贡献。）

- `ast`: 以下特性自 Python 3.8 起已在文档中声明弃用，现在当运行时如果它们被访问或使用时将发出 `DeprecationWarning`，并将在 Python 3.14 中移除：

  - `ast.Num`

  - `ast.Str`

  - `ast.Bytes`

  - `ast.NameConstant`

  - `ast.Ellipsis`

  请改用 `ast.Constant`。 （由 Serhiy Storchaka 在 gh-90953 中贡献。）

- `asyncio`:

  - 子监视器类 `asyncio.MultiLoopChildWatcher`、`asyncio.FastChildWatcher`、`asyncio.AbstractChildWatcher` 和 `asyncio.SafeChildWatcher` 已被弃用并将在 Python 3.14 中移除。 （由 Kumar Aditya 在 gh-94597 中贡献。）

  - `asyncio.set_child_watcher()`、`asyncio.get_child_watcher()`、`asyncio.AbstractEventLoopPolicy.set_child_watcher()` 和 `asyncio.AbstractEventLoopPolicy.get_child_watcher()` 已弃用，并将在 Python 3.14 中移除。（由 Kumar Aditya 在 gh-94597 中贡献。）

  - 现在默认事件循环策略的 `get_event_loop()` 方法在当前事件循环未设置并决定创建一个时将发出 `DeprecationWarning`。 （由 Serhiy Storchaka 和 Guido van Rossum 在 gh-100160 中贡献。）

- `email`: 已弃用 `email.utils.localtime()` 中的 isdst 形参。 （由 Alan Williams 在 gh-72346 中贡献。）

- `importlib.abc` 中已弃用的类：

  - `importlib.abc.ResourceReader`

  - `importlib.abc.Traversable`

  - `importlib.abc.TraversableResources`

  使用 `importlib.resources.abc` 类代替:

  - `importlib.resources.abc.Traversable`

  - `importlib.resources.abc.TraversableResources`

  （由 Jason R. Coombs 和 Hugo van Kemenade 在 gh-93963 中贡献。）

- `itertools` 具有对 copy, deepcopy 和 pickle 等操作的未写入文档的、低效的、历史上充满问题的且不稳定的支持。 这将在 3.14 中移除以显著减少代码量和维护负担。 （由 Raymond Hettinger 在 gh-101588 中贡献。）

- `multiprocessing`: 默认的启动方法在目前默认使用 `'fork'` 的 Linux, BSD 和其他非 macOS POSIX 平台上将改为更安全的方法 (gh-84559)。 为此添加运行时警告将带来糟糕的体验因为大部分代码并不会关心这个问题。 当你的代码 需要 `'fork'` 时请使用 `get_context()` 或 `set_start_method()` API 来显式地指明。 参见 上下文和启动方法。

- `pathlib`: `is_relative_to()` 和 `relative_to()`: 传入额外参数的做法已被弃用。

- `pkgutil`: 现在 `pkgutil.find_loader()` 和 `pkgutil.get_loader()` 将引发 `DeprecationWarning`；请改用 `importlib.util.find_spec()`。 （由 Nikita Sobolev 在 gh-97850 中贡献。）

- `pty`:

  - `master_open()`: 使用 `pty.openpty()`。

  - `slave_open()`: 使用 `pty.openpty()`。

- `sqlite3`:

  - `version` 和 `version_info`。

  - 如果使用了 命名占位符 且 parameters 是一个序列而不是 `dict` 则选择 `execute()` 和 `executemany()`。

- `urllib`: `urllib.parse.Quoter` 已被弃用：它不应被作为公有 API。 （由 Gregory P. Smith 在 gh-88168 中贡献。）

### 计划在 Python 3.15 中移除

- 导入系统：

  - Setting `__cached__` on a module while failing to set `__spec__.cached` is deprecated. In Python 3.15, `__cached__` will cease to be set or take into consideration by the import system or standard library. (gh-97879)

  - 当设备 `__spec__.parent` 失败时在模块上设置 `__package__` 的做法已被弃用。 在 Python 3.15 中，`__package__` 将不会再被导入系统或标准库纳入考虑。 (gh-97879)

- `ctypes`:

  - 未写入文档的 `ctypes.SetPointerType()` 函数自 Python 3.13 起已被弃用。

- `http.server`:

  - The obsolete and rarely used `CGIHTTPRequestHandler` has been deprecated since Python 3.13. No direct replacement exists. Anything is better than CGI to interface a web server with a request handler.

  - 用于 python -m http.server 命令行界面的 `--cgi` 旗标自 Python 3.13 起已被弃用。

- `importlib`:

  - `load_module()` 方法：改用 `exec_module()`。

- `pathlib`:

  - `.PurePath.is_reserved()` has been deprecated since Python 3.13. Use `os.path.isreserved()` to detect reserved paths on Windows.

- `platform`:

  - `platform.java_ver()` has been deprecated since Python 3.13. This function is only useful for Jython support, has a confusing API, and is largely untested.

- `sysconfig`:

  - `sysconfig.is_python_build()` 的 check_home 参数自 Python 3.12 起已被弃用。

- `threading`:

  - 在 Python 3.15 中 `RLock()` 将不再接受参数。 传入参数的做法自 Python 3.14 起已被弃用，因为 Python 版本不接受任何参数，而 C 版本允许任意数量的位置或关键字参数，但会忽略所有参数。

- `types`:

  - `types.CodeType`: 访问 `co_lnotab` 的做法自 3.10 起已根据 PEP 626 被弃用并曾计划在 3.12 中移除，但在 3.12 中实际仅设置了 `DeprecationWarning`。 可能会在 3.15 中移除。 （由 Nikita Sobolev 在 gh-101866 中贡献。）

- `typing`:

  - 未写入文档的用于创建 `NamedTuple` 类的关键字参数语法（例如 `Point = NamedTuple("Point", x=int, y=int)`）自 Python 3.13 起已被弃用。 请改用基于类的语法或函数语法。

  - 当使用 `TypedDict` 的函数式语法时，不向 fields 形参传递值 (`TD = TypedDict("TD")`) 或传递 `None` (`TD = TypedDict("TD", None)`) 的做法自 Python 3.13 起已被弃用。 请改用 `class TD(TypedDict): pass` 或 `TD = TypedDict("TD", {})` 来创建一个零字段的 TypedDict。

  - The `typing.no_type_check_decorator()` decorator function has been deprecated since Python 3.13. After eight years in the `typing` module, it has yet to be supported by any major type checker.

- `sre_compile`, `sre_constants` 和 `sre_parse` 模块。

- `wave`:

  - The `getmark()`, `setmark()` and `getmarkers()` methods of the `Wave_read` and `Wave_write` classes have been deprecated since Python 3.13.

- `zipimport`:

  - `zipimport.zipimporter.load_module()` has been deprecated since Python 3.10. Use `exec_module()` instead. (gh-125746.)

### 计划在 Python 3.16 中移除

- 导入系统：

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

- `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` and `-1`)。 请改用 `not x` 来对布尔值执行逻辑否操作。 对于需要对下层整数执行按位取反操作的少数场合，请显式地将其转换为 `int` (`~int(x)`)。

- `functools`：

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

- `logging`：

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

- `mimetypes`:

  - 有效扩展以 ". " 开头或在 `mimetypes.MimeTypes.add_type()` 为空。 未加点的扩展已弃用，在 Python 3.16 中将引发 `ValueError`。 （由 Hugo van Kemenade 在 gh-75223 中贡献。）

- `shutil`:

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

- `symtable`:

  - `Class.get_methods` 方法自 Python 3.14 起被弃用。

- `sys`:

  - `_enablelegacywindowsfsencoding()` 函数自 Python 3.13 起被弃用。 请改用 `PYTHONLEGACYWINDOWSFSENCODING` 环境变量。

- `sysconfig`:

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

- `tarfile`:

  - 未写入文档也未被使用的 `TarFile.tarfile` 属性自 Python 3.13 起被弃用。

### 计划在 Python 3.17 中移除

- `collections.abc`:

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

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

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

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

- `encodings`:

  - Passing non-ascii encoding names to `encodings.normalize_encoding()` is deprecated and scheduled for removal in Python 3.17. (Contributed by Stan Ulbrych in gh-136702)

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

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

### Pending removal in Python 3.19

- `ctypes`:

  - Implicitly switching to the MSVC-compatible struct layout by setting `_pack_` but not `_layout_` on non-Windows platforms.

- `hashlib`:

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

    Support for the `string` keyword argument name is now deprecated and slated for removal in Python 3.19.

    Before Python 3.13, the `string` keyword parameter was not correctly supported depending on the backend implementation of hash functions. Prefer passing the initial data as a positional argument for maximum backwards compatibility.

### Pending removal in Python 3.20

- The `__version__`, `version` and `VERSION` attributes have been deprecated in these standard library modules and will be removed in Python 3.20. Use `sys.version_info` instead.

  - `argparse`

  - `csv`

  - `ctypes`

  - `ctypes.macholib`

  - `decimal` (use `decimal.SPEC_VERSION` instead)

  - `http.server`

  - `imaplib`

  - `ipaddress`

  - `json`

  - `logging` (`__date__` also deprecated)

  - `optparse`

  - `pickle`

  - `platform`

  - `re`

  - `socketserver`

  - `tabnanny`

  - `tkinter.font`

  - `tkinter.ttk`

  - `wsgiref.simple_server`

  - `xml.etree.ElementTree`

  - `xml.sax.expatreader`

  - `xml.sax.handler`

  - `zlib`

  (Contributed by Hugo van Kemenade and Stan Ulbrych in gh-76007.)

### 计划在未来版本中移除

以下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`, `is` 和 `or` 中的一个将会引发语法警告。 在未来的版本中它将改为语法错误。 (gh-87999)

  - 对 `__index__()` 和 `__int__()` 方法返回非 int 类型的支持：将要求这些方法必须返回 `int` 的子类的实例。

  - 对 `__float__()` 方法返回 `float` 的子类的支持：将要求这些方法必须返回 `float` 的实例。

  - 对 `__complex__()` 方法返回 `complex` 的子类的支持：将要求这些方法必须返回 `complex` 的实例。

  - 将 `int()` 委托给 `__trunc__()` 方法。

  - 传入一个复数作为 `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()` 方法。

- `datetime`:

  - `utcnow()`: 使用 `datetime.datetime.now(tz=datetime.UTC)`。

  - `utcfromtimestamp()`: 使用 `datetime.datetime.fromtimestamp(timestamp, tz=datetime.UTC)`。

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

- `importlib`:

  - `cache_from_source()` debug_override 形参已被弃用：改用 optimization 形参。

- `importlib.metadata`:

  - `EntryPoints` 元组接口。

  - 返回值中隐式的 `None`。

- `logging`: `warn()` 方法自 Python 3.3 起已被弃用，请改用 `warning()`。

- `mailbox`: 对 StringIO 输入和文本模式的使用已被弃用，改用 BytesIO 和二进制模式。

- `os`: Calling `os.register_at_fork()` in a multi-threaded process.

- `os.path`: `os.path.commonprefix()` is deprecated, use `os.path.commonpath()` for path prefixes. The `os.path.commonprefix()` function is being deprecated due to having a misleading name and module. The function is not safe to use for path prefixes despite being included in a module about path manipulation, meaning it is easy to accidentally introduce path traversal vulnerabilities into Python programs by using this function.

- `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` 的方法：

  - `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.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()` 。

## 移除

### asynchat 和 asyncore

- 这两个模块已根据 PEP 594 中的时间表被移除，它们从 Python 3.6 起已被弃用。 请改用 `asyncio`。 （由 Nikita Sobolev 在 gh-96580 中贡献。）

### configparser

- `configparser` 中的几个从 3.2 起已被弃用的名称已根据 gh-89336 被移除：

  - `configparser.ParsingError` 不再具有 `filename` 属性或参数。 请改用 `source` 属性和参数。

  - `configparser` 不再具有 `SafeConfigParser` 类。 请改用更简短的名称 `ConfigParser`。

  - `configparser.ConfigParser` 不再具有 `readfp` 方法。 请改用 `read_file()`。

### distutils

- 移除了 `distutils` 包。 它已在 Python 3.10 中根据 PEP 632 "Deprecate distutils module" 被弃用。 对于仍然使用 `distutils` 且无法升级为使用其他工具的项目，可以安装 `setuptools` 项目：它仍然提供了 `distutils`。 （由 Victor Stinner 在 gh-92584 中贡献。）

### ensurepip

- 从 `ensurepip` 中移除了捆绑的 setuptools wheel，并停止在由 `venv` 创建的环境中安装 setuptools。

  `pip (>= 22.1)` 不再要求在环境中安装 setuptools。 基于 `setuptools` (和基于 `distutils`) 的包仍然可通过 `pip install` 来使用，因为 pip 将在它用于构建包的构建环境中提供 `setuptools`。

  在默认情况下由 `venv` 创建或通过 `ensurepip` 初始化的环境将不再提供 `easy_install`, `pkg_resources`, `setuptools` 和 `distutils` 包，因为它们是 `setuptools` 包的组成部分。 对于在运行时依赖这些包的项目，应当将 `setuptools` 项目声明为依赖项之一并单独安装（通常是使用 pip）。

  （由 Pradyun Gedam 在 gh-95299 中贡献。）

### enum

- 移除了 `enum` 的 `EnumMeta.__getattr__`，枚举属性访问已不再需要它。 （由 Ethan Furman 在 gh-95083 中贡献。）

### ftplib

- 移除了 `ftplib` 的 `FTP_TLS.ssl_version` 类属性：请改用 context 形参。 （由 Victor Stinner 在 gh-94172 中贡献。）

### gzip

- 移除了 `gzip` 中 `gzip.GzipFile` 的 `filename` 属性，自 Python 2.6 起该属性已被弃用，请改用 `name` 属性。 在可写模式下，如果 `filename` 属性没有 `'.gz'` 文件扩展名则会添加它。 （由 Victor Stinner 在 gh-94196 中贡献。）

### hashlib

- 移除了 `hashlib` 中 `hashlib.pbkdf2_hmac()` 的纯 Python 实现，它在 Python 3.10 中已被弃用。 Python 3.10 及更新版本需要 OpenSSL 1.1.1 (PEP 644)：该 OpenSSL 版本提供了 `pbkdf2_hmac()` 的更快速的 C 实现。 （由 Victor Stinner 在 gh-94199 中贡献。）

### importlib

- `importlib` 中许多先前已弃用对象的清理工作现已完成：

  - 对 `module_repr()` 的引用以及支持已被移除。 （由 Barry Warsaw 在 gh-97850 中贡献。）

  - `importlib.util.set_package`, `importlib.util.set_loader` 和 `importlib.util.module_for_loader` 均已被移除。 （由 Brett Cannon 和 Nikita Sobolev 在 gh-65961 和 gh-97850 中贡献。）

  - 对 `find_loader()` 和 `find_module()` API 的支持已被移除。 （由 Barry Warsaw 在 gh-98040 中贡献。）

  - `importlib.abc.Finder`, `pkgutil.ImpImporter` 和 `pkgutil.ImpLoader` 已被移除。 （由 Barry Warsaw 在 gh-98040 中贡献。）

### imp

- `imp` 模块已被移除。 （由 Barry Warsaw 在 gh-98040 中贡献。）

  要进行迁移，请参考以下对照表：

  > imp | importlib
  > --- | ---
  > `imp.NullImporter` | 将 `None` 插入到 `sys.path_importer_cache`
  > `imp.cache_from_source()` | `importlib.util.cache_from_source()`
  > `imp.find_module()` | `importlib.util.find_spec()`
  > `imp.get_magic()` | `importlib.util.MAGIC_NUMBER`
  > `imp.get_suffixes()` | `importlib.machinery.SOURCE_SUFFIXES`, `importlib.machinery.EXTENSION_SUFFIXES` 和 `importlib.machinery.BYTECODE_SUFFIXES`
  > `imp.get_tag()` | `sys.implementation.cache_tag`
  > `imp.load_module()` | `importlib.import_module()`
  > `imp.new_module(name)` | `types.ModuleType(name)`
  > `imp.reload()` | `importlib.reload()`
  > `imp.source_from_cache()` | `importlib.util.source_from_cache()`
  > `imp.load_source()` | 见下文

  将 `imp.load_source()` 替换为:

      import importlib.util
      import importlib.machinery

      def load_source(modname, filename):
          loader = importlib.machinery.SourceFileLoader(modname, filename)
          spec = importlib.util.spec_from_file_location(modname, filename, loader=loader)
          module = importlib.util.module_from_spec(spec)
          # 模块将总是被执行而不缓存在 sys.modules 中。
          # 取消对下一行的注释以缓存此模块。
          # sys.modules[module.__name__] = module
          loader.exec_module(module)
          return module

- 已移除 `imp` 的函数和属性并且没有替代选项:

  - 未写入文档的函数：

    - `imp.init_builtin()`

    - `imp.load_compiled()`

    - `imp.load_dynamic()`

    - `imp.load_package()`

  - `imp.lock_held()`,``imp.acquire_lock()``,``imp.release_lock()``: 加锁方案在 Python 3.3 中已改为模块级锁。

  - `imp.find_module()` 常量: `SEARCH_ERROR`, `PY_SOURCE`, `PY_COMPILED`, `C_EXTENSION`, `PY_RESOURCE`, `PKG_DIRECTORY`, `C_BUILTIN`, `PY_FROZEN`, `PY_CODERESOURCE`, `IMP_HOOK`。

### io

- 移除了 `io` 中的 `io.OpenWrapper` 和 `_pyio.OpenWrapper`，它们在 Python 3.10 中已被弃用：请改用 `open()`。 `open()` (`io.open()`) 函数是一个内置函数。 自 Python 3.10 起，`_pyio.open()` 也是一个静态方法。 （由 Victor Stinner 在 gh-94169 中贡献。）.)

### locale

- 移除了 `locale` 的 `locale.format()` 函数，它在 Python 3.7 中已被弃用：请改用 `locale.format_string()`。 （由 Victor Stinner 在 gh-94226 中贡献。）

### smtpd

- `smtpd` 模块已按照 PEP 594 中的计划表被移除，它在 Python 3.4.7 和 3.5.4 中已被弃用。 请改用 aiosmtpd PyPI 模块或任何其他基于 `asyncio` 的服务器。 （由 Oleg Iarygin 在 gh-93243 中贡献。）

### sqlite3

- 以下未写入文档的 `sqlite3` 特性，在 Python 3.10 中已被弃用，现在已被移除：

  - `sqlite3.enable_shared_cache()`

  - `sqlite3.OptimizedUnicode`

  如果必须使用共享缓存，请在以 URI 模式打开数据库时使用 `cache=shared` 查询参数。

  `sqlite3.OptimizedUnicode` 文本工厂函数自 Python 3.3 起已成为 `str` 的一个别名。 之前将文本工厂设为 `OptimizedUnicode` 的代码可以显式地使用 `str`，或者依赖同样为 `str` 的默认值。

  （由 Erlend E. Aasland 在 gh-92548 中贡献。）

### ssl

- 移除了 `ssl` 的 `ssl.RAND_pseudo_bytes()` 函数，它在 Python 3.6 中已被弃用：请改用 `os.urandom()` 或 `ssl.RAND_bytes()`。 （由 Victor Stinner 在 gh-94199 中贡献。）

- 移除了 `ssl.match_hostname()` 函数。 它在 Python 3.7 中已被弃用。 OpenSSL 自 Python 3.7 起将会执行主机名匹配，Python 已不再使用 `ssl.match_hostname()` 函数。 （由 Victor Stinner 在 gh-94199 中贡献。）

- 移除了 `ssl.wrap_socket()` 函数，它在 Python 3.7 中已被弃用：应改为创建一个 `ssl.SSLContext` 对象并调用其 `ssl.SSLContext.wrap_socket` 方法。 任何仍然使用 `ssl.wrap_socket()` 的包都是已不适用且不安全的。 该函数既不会发送 SNI TLS 扩展也不会验证服务器主机名。 其代码会受到 CWE 295 (Improper Certificate Validation) 的影响。 （由 Victor Stinner 在 gh-94199 中贡献。）

### unittest

- 移除了许多早已弃用的 `unittest` 特性：

  - 一些 `TestCase` 方法的别名:

    已弃用的别名 | 方法名 | 弃用于
    --- | --- | ---
    `failUnless` | `assertTrue()` | 3.1
    `failIf` | `assertFalse()` | 3.1
    `failUnlessEqual` | `assertEqual()` | 3.1
    `failIfEqual` | `assertNotEqual()` | 3.1
    `failUnlessAlmostEqual` | `assertAlmostEqual()` | 3.1
    `failIfAlmostEqual` | `assertNotAlmostEqual()` | 3.1
    `failUnlessRaises` | `assertRaises()` | 3.1
    `assert_` | `assertTrue()` | 3.2
    `assertEquals` | `assertEqual()` | 3.2
    `assertNotEquals` | `assertNotEqual()` | 3.2
    `assertAlmostEquals` | `assertAlmostEqual()` | 3.2
    `assertNotAlmostEquals` | `assertNotAlmostEqual()` | 3.2
    `assertRegexpMatches` | `assertRegex()` | 3.2
    `assertRaisesRegexp` | `assertRaisesRegex()` | 3.2
    `assertNotRegexpMatches` | `assertNotRegex()` | 3.5

    您可以使用 https://github.com/isidentical/teyit 来自动更新你的单元测试。

  - 未写入文档且已不可用的 `TestCase` 方法 `assertDictContainsSubset`。 （在 Python 3.2 中已弃用。）

  - 未写入文档的 `TestLoader.loadTestsFromModule` 形参 use_load_tests。 （自 Python 3.5 起已弃用并会被忽略。）

  - `TextTestResult` 类的一个别名: `_TextTestResult`。 （在 Python 3.2 中已弃用。）

  （由 Serhiy Storchaka 在 gh-89325 中贡献。）

### webbrowser

- 从 `webbrowser` 移除了对过时浏览器的支持。 被移除的浏览器包括：Grail、Mosaic、Netscape、Galeon、Skipstone、Iceape、Firebird 和 Firefox 35 及以下的版本 (gh-102871)。

### xml.etree.ElementTree

- 移除了纯 Python 实现的 `ElementTree.Element.copy()` 方法，该方法在 Python 3.10 中已被弃用，请改用 `copy.copy()` 函数。 `xml.etree.ElementTree` 的 C 实现没有 `copy()` 方法，只有 `__copy__()` 方法。 （由 Victor Stinner 在 gh-94383 中贡献。）

### zipimport

- 移除了 `zipimport` 的 `find_loader()` 和 `find_module()` 方法，它们在 Python 3.10 中已被弃用：请改用 `find_spec()` 方法。 请参阅 PEP 451 了解相关说明。 （由 Victor Stinner 在 gh-94379 中贡献。）

### 其他事项

- 从文档 `Makefile` 和 `Doc/tools/rstlint.py` 中移除了 `suspicious` 规则，请改用 sphinx-lint。 （由 Julien Palard 在 gh-98179 中贡献。）

- 移除了 `ftplib`、`imaplib`、`poplib` 和 `smtplib` 模块中的 keyfile 和 certfile 形参数，以及 `http.client` 模块中的 key_file、cert_file 和 check_hostname 形参，它们自 Python 3.6 起都已被弃用。 请改用 context 形参（在 `imaplib` 中为 ssl_context 形参）。 （由 Victor Stinner 在 gh-94172 中贡献。）.)

- 从多个标准库模块和测试中移除了 `Jython` 兼容性处理。 （由 Nikita Sobolev 在 gh-99482 中贡献。）

- 从 `ctypes` 模块移除了 `_use_broken_old_ctypes_structure_semantics_` 旗标。 （由 Nikita Sobolev 在 gh-99285 中贡献。）

## 移植到 Python 3.12

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

### Python API 的变化

- 现在对于正则表达式中的数字分组引用和分组名称将应用更严格的规则。 现在只接受 ASCII 数字序列作为数字引用。 字节串模式和替换字符串中的分组名称现在只能包含 ASCII 字母、数字和下划线。 （由 Serhiy Storchaka 在 gh-91760 中贡献。）

- 移除了自 Python 3.10 起已被弃用的 `randrange()` 功能。 以前，`randrange(10.0)` 会无损地转换为 `randrange(10)`。 现在，它将引发 `TypeError`。 此外，对于非整数值如 `randrange(10.5)` 或 `randrange('10')` 所引发的异常已从 `ValueError` 改为 `TypeError`。 这也防止了 `randrange(1e25)` 会从比 `randrange(10**25)` 更大的范围中静默选择的问题。 （最初由 Serhiy Storchaka 在 gh-86388 中提议。）

- `argparse.ArgumentParser` 将从文件（例如 `fromfile_prefix_chars` 选项）读取参数的编码格式和错误处理器从默认的文本编码格式（例如 `locale.getpreferredencoding(False)` 调用）改为 filesystem encoding and error handler。 在 Windows 系统中参数文件应使用 UTF-8 而不是 ANSI 代码页来编码。

- 移除了在 Python 3.4.7 和 3.5.4 中已被弃用的基于 `asyncore` 的 `smtpd` 模块。 推荐的替代是基于 `asyncio` 的 aiosmtpd PyPI 模块。

- `shlex.split()`: 传入 `None` 作为 s 参数现在将引发异常，而不是读取 `sys.stdin`。 该特性在 Python 3.9 中已被弃用。 （由 Victor Stinner 在 gh-94352 中贡献。）

- `os` 模块不再接受类似字节串的路径，如 `bytearray` 和 `memoryview` 类型：只接受明确的 `bytes` 类型字节串。 （由 Victor Stinner 在 gh-98393 中贡献。）

- 现在 `syslog.openlog()` 和 `syslog.closelog()` 如果在子解释器中使用将失败。 `syslog.syslog()` 仍可在子解释器中使用，但前提是 `syslog.openlog()` 已在主解释器中被调用。 这些新限制不适用于主解释器，因此只有少数用户可能会受到影响。 这一改变有助于实现解释器隔离。 此外，`syslog` 是一个针对进程全局资源的包装器，而这些资源最好是由主解释器来管理。 （由 Donghee Na 在 gh-99127 中贡献。）

- 未写入文档的 `cached_property()` 的锁定行为已被移除，因为该行为会在类的所有实例中锁定，从而导致高锁定争用。 这意味着如果两个线程同时运行，缓存属性获取函数现在可以在单个实例中运行不止一次。 对于大多数简单的缓存属性（例如那些幂等的并且只需根据实例的其他属性计算一个值的属性）来说这是没有问题的。 如果需要同步，可在缓存属性获取函数中或多线程访问点周围实现锁定操作。

- 现在 `sys._current_exceptions()` 将返回从线程 ID 到异常实例的映射，而不是到 `(typ, exc, tb)` 元组的映射。 （由 Irit Katriel 在 gh-103176 中贡献。）

- 当使用 `tarfile` 或 `shutil.unpack_archive()` 提取 tar 文件时，请传入 filter 参数来限制可能令人感到意外或危险的特性。 请参阅 解压缩过滤器 了解详情。

- 由于在 PEP 701 中引入的更改 `tokenize.tokenize()` 和 `tokenize.generate_tokens()` 函数的输出现在发生了改变。 这意味着不再为 f-字符输出 `STRING` 词元而是改为产生 PEP 701 中描述的词元：除了用于对表达式组件进行分词的适当词元外现在还有 `FSTRING_START`, `FSTRING_MIDDLE` 和 `FSTRING_END` 会被用于 f-字符串的“字符串”部分。 例如对于 f-字符串 `f"start {1+1} end"` 旧版本的分词器会生成:

      1,0-1,18:           STRING         'f"start {1+1} end"'

  而新版本将生成:

      1,0-1,2:            FSTRING_START  'f"'
      1,2-1,8:            FSTRING_MIDDLE 'start '
      1,8-1,9:            OP             '{'
      1,9-1,10:           NUMBER         '1'
      1,10-1,11:          OP             '+'
      1,11-1,12:          NUMBER         '1'
      1,12-1,13:          OP             '}'
      1,13-1,17:          FSTRING_MIDDLE ' end'
      1,17-1,18:          FSTRING_END    '"'

  此外，支持 PEP 701 所需的改变还可能会导致一些细微的行为改变。 这些变化包括:

  - 在对一些无效 Python 字符如 `!` 进行分词时相应词元的 `type` 属性已从 `ERRORTOKEN` 变为 `OP`。

  - 不完整的单行字符串现在也会像不完整的多行字符串一样引发 `tokenize.TokenError`。

  - 某些不完整或无效的 Python 代码现在会引发 `tokenize.TokenError` 而不是在执行分词时返回任意的 `ERRORTOKEN` 词元。

  - 在同一文件中混合使用制表符和空格作为缩进不再受到支持而是会引发 `TabError`。

- 现在 `threading` 模块会预期 `_thread` 模块具有 `_is_main_interpreter` 属性。 它是一个不带参数的函数并会在当前解释器为主解释器时返回 `True`。

  任何提供了自定义 `_thread` 模块的库或应用程序都应当提供 `_is_main_interpreter()`。 （参见 gh-112826。）

## 构建变化

- Python 不再使用 `setup.py` 来构建共享的 C 扩展模块。 头文件和库等编译参数在 `configure` 脚本中检测。 扩展将由 `Makefile` 来构建。 大多数扩展使用 `pkg-config` 并回退为手动检测。 （由 Christian Heimes 在 gh-93939 中贡献。）

- 现在需要用带有两个形参的 `va_start()`，如 `va_start(args, format),` 来构建 Python。 现在将不会再调用单个形参的 `va_start()`。 （由 Kumar Aditya 在 gh-93207 中贡献。）

- 现在如果 Clang 编译器接受 ThinLTO 选项则 CPython 会将其作为默认的链接时间优化策略。 （由 Donghee Na 在 gh-89536 中贡献。）

- 在 `Makefile` 中添加了 `COMPILEALL_OPTS` 变量以覆盖 `make install` 中的 `compileall` 选项 (默认值: `-j0`)。 并将 3 条 `compileall` 命令合并为单条命令以便一次性构建所有优化级别 (0, 1, 2) 的 .pyc 文件。 （由 Victor Stinner 在 gh-99289 中贡献。）

- 为 64 位 LoongArch 添加了平台三选项:

  - loongarch64-linux-gnusf

  - loongarch64-linux-gnuf32

  - loongarch64-linux-gnu

  （由 Zhang Na 在 gh-90656 中贡献。）.)

- `PYTHON_FOR_REGEN` 现在需要 Python 3.10 或更新版本。

- 现在需要有 autoconf 2.71 和 aclocal 1.16.4 才能重新生成 `configure`。（由 Christian Heimes 在 gh-89886 中贡献。）

- 来自 python.org 的 Windows 版本和 macOS 安装程序现在使用 OpenSSL 3.0。

## C API 的变化

### 新的特性

- PEP 697: 引入了 不稳定 C API 层，用于调试器和 JIT 编译器等低层级工具。 该 API 可能会在 CPython 的每个次要版本中发生变化而但发出弃用警告。 其内容在名称中以 `PyUnstable_` 前缀标记。

  代码对象构造器:

  - `PyUnstable_Code_New()` (由 `PyCode_New` 改名而来)

  - `PyUnstable_Code_NewWithPosOnlyArgs()` (由 `PyCode_NewWithPosOnlyArgs` 改名而来)

  代码对象的额外存储 (PEP 523):

  - `PyUnstable_Eval_RequestCodeExtraIndex()` (由 `_PyEval_RequestCodeExtraIndex` 改名而来)

  - `PyUnstable_Code_GetExtra()` (由 `_PyCode_GetExtra` 改名而来)

  - `PyUnstable_Code_SetExtra()` (由 `_PyCode_SetExtra` 改名而来)

  原有名称将继续可用直到对应的 API 发生改变。

  （由 Petr Viktorin 在 gh-101101 中贡献。）

- PEP 697: 添加了用于扩展实例内存布局不透明的类型的 API:

  - `PyType_Spec.basicsize` 可以为零或负数，用于以指定继承或扩展基类的大小。

  - 增加了 `PyObject_GetTypeData()` 和 `PyType_GetTypeDataSize()` 以允许访问特定子类的实例数据。

  - 添加了 `Py_TPFLAGS_ITEMS_AT_END` 和 `PyObject_GetItemData()` 以允许安全地扩展某些可变大小的类型，包括 `PyType_Type`。

  - 添加了 `Py_RELATIVE_OFFSET` 以允许用特定于子类的结构体来定义 `成员`。

  （由 Petr Viktorin 在 gh-103509 中贡献。）

- 添加了新的 受限 C API 函数 `PyType_FromMetaclass()`，它使用了额外的 metaclass 参数对现有的 `PyType_FromModuleAndSpec()` 进行了泛化。 （由 Wenzel Jakob 在 gh-93012 中贡献。）

- 在 受限 中添加了用于创建可使用 vectorcall 协议 来调用的对象的 API:

  - `Py_TPFLAGS_HAVE_VECTORCALL`

  - `PyVectorcall_NARGS()`

  - `PyVectorcall_Call()`

  - `vectorcallfunc`

  现在当一个类的 `__call__()` 方法被重新赋值时，该类的 `Py_TPFLAGS_HAVE_VECTORCALL` 旗标将被移除。 这使得 vectorcall 可以安全地用于可变类型（即没有不可变旗标 `Py_TPFLAGS_IMMUTABLETYPE` 的堆类型）。 未重载 `tp_call` 的可变类型现在继承了 `Py_TPFLAGS_HAVE_VECTORCALL` 旗标。 （由 Petr Viktorin 在 gh-93274 中贡献。）

  新增了 `Py_TPFLAGS_MANAGED_DICT` 和 `Py_TPFLAGS_MANAGED_WEAKREF` 旗标。 这将允许扩展类以更少的记录消耗来支持对象 `__dict__` 和弱引用，占用更少内存并加快访问速度。

- 在 受限 API 中添加了使用 vectorcall 协议 执行调用的 API:

  - `PyObject_Vectorcall()`

  - `PyObject_VectorcallMethod()`

  - `PY_VECTORCALL_ARGUMENTS_OFFSET`

  这意味着 vectorcall 调用协议的传入端和传出端现在都可以在 受限 API 中使用。 （由 Wenzel Jakob 在 gh-98586 中贡献。）

- 添加了两个新的公共函数 `PyEval_SetProfileAllThreads()` 和 `PyEval_SetTraceAllThreads()`，允许在调用的同时在所有运行线程中设置追踪和性能分析函数。 （由 Pablo Galindo 在 gh-93503 中贡献。）

- 为 C API 添加了新函数 `PyFunction_SetVectorcall()` 用于设置给定 `PyFunctionObject` 的 vectorcall 字段。 （由 Andrew Frost 在 gh-92257 中贡献。）

- C API 现在允许通过 `PyDict_AddWatcher()`、`PyDict_Watch()` 和相关 API 注册回调，以便在字典被修改时调用。 这主要用于优化解释器、JIT 编译器或调试器。 （由 Carl Meyer 在 gh-91052 中贡献。）

- 添加了 `PyType_AddWatcher()` 和 `PyType_Watch()` API 用于注册回调以接收类型变更通知。 （由 Carl Meyer 在 gh-91051 中贡献。）

- 添加了 `PyCode_AddWatcher()` 和 `PyCode_ClearWatcher()` API 用于注册回调以接收代码对象创建和销毁时的通知。 （由 Itamar Oren 在 gh-91054 中贡献。）

- 添加了 `PyFrame_GetVar()` 和 `PyFrame_GetVarString()` 函数用于通过名称来获取帧变量。 （由 Victor Stinner 在 gh-91248 中贡献。）

- 添加 `PyErr_GetRaisedException()` 和 `PyErr_SetRaisedException()` 用于保存和恢复当前异常。 这些函数返回并接受单个异常对象，而不是像现在已弃用的 `PyErr_Fetch()` 和 `PyErr_Restore()` 那样的三个参数。 这样不容易出错并且更为高效。 （由 Mark Shannon 在 gh-101578 中贡献。）

- 添加了 `_PyErr_ChainExceptions1`，它接受一个异常实例，用于取代旧式 API `_PyErr_ChainExceptions`，后者现已被弃用。 （由 Mark Shannon 在 gh-101578 中贡献。）

- 添加了 `PyException_GetArgs()` 和 `PyException_SetArgs()` 作为便捷函数用于检索和修改传递给异常的构造函数的 `args`。 （由 Mark Shannon 在 gh-101578 中贡献。）

- 添加了 `PyErr_DisplayException()`，它接受一个异常实例，用于取代旧式 API `PyErr_Display()`。 （由 Irit Katriel 在 gh-102755 中贡献。）

- PEP 683: 引入了 永生对象，它允许对象绕过引用计数，并对 C-API 进行相应修改：

  - `_Py_IMMORTAL_REFCNT`: 定义对象的引用计数

      为永生对象。

  - `_Py_IsImmortal` 检测一个对象是否具有永生引用计数。

  - `PyObject_HEAD_INIT` 这将把引用计数初始化为

      `_Py_IMMORTAL_REFCNT` 当配合 `Py_BUILD_CORE` 使用时。

  - `SSTATE_INTERNED_IMMORTAL` 一个针对内部 unicode 对象的标识符

      为永生对象。

  - `SSTATE_INTERNED_IMMORTAL_STATIC` 一个针对内部 unicode

      为永生且静态的对象

  - `sys.getunicodeinternedsize` 这将返回总计的 unicode

      被管理的对象。现在 `refleak.py` 需要这样才能正确地追踪引用计数和分配的块

  （由 Eddie Elizondo 在 gh-84436 中贡献。）

- PEP 684: 新增了 `Py_NewInterpreterFromConfig()` 函数和 `PyInterpreterConfig`，可用于创建具有单独 GIL 的子解释器。 （更多信息参见 PEP 684: 每解释器 GIL。） （由 Eric Snow 在 gh-104110 中贡献。）

- 在 3.12 版的受限 C API 中，`Py_INCREF()` 和 `Py_DECREF()` 函数现在使用不透明函数调用的方式实现以隐藏实现细节。 （由 Victor Stinner 在 gh-105387 中贡献。）

### 移植到 Python 3.12

- 基于 `Py_UNICODE*` 表示形式的旧式 Unicode API 已被移除。 请迁移到基于 UTF-8 或 `wchar_t*` 的 API。

- `PyArg_ParseTuple()` 等参数解析函数不再支持基于 `Py_UNICODE*` 的格式（例如 `u`, `Z` 等）。 请迁移到其他 Unicode 格式如 `s`, `z`, `es` 和 `U`。

- `tp_weaklist` 对于所有静态内置类型将始终为 `NULL`。 这是 `PyTypeObject` 上的一个内部专属字段，但我们还是要指出这一变化以防有人碰巧仍然直接访问到该字段。 为避免出现中断，请考虑改用现有的公共 C-API，或在必要时使用（仅限内部使用的）宏 `_PyObject_GET_WEAKREFS_LISTPTR()`。

- 现在这个内部专用的 `PyTypeObject.tp_subclasses` 可能不是一个有效的对象指针。 为了反映这一点我们将其类型改为 void*。 我们提到这一点是为了防止有人碰巧直接访问到这个内部专用字段。

  要获取子类的列表，可调用 Python 方法 `__subclasses__()` (例如使用 `PyObject_CallMethod()`)。

- 在 `PyUnicode_FromFormat()` 和 `PyUnicode_FromFormatV()` 中添加对更多格式选项（左对齐、八进制、大写十六进制、`intmax_t`、`ptrdiff_t`、`wchar_t` C 字符串、可变宽度和精度）的支持。 （由 Serhiy Storchaka 在 gh-98836 中贡献。）

- `PyUnicode_FromFormat()` 和 `PyUnicode_FromFormatV()` 中未被识别的格式字符现在会设置一个 `SystemError`。 在之前的版本中它会导致格式字符串的所有其他部分被原样复制到结果字符串中，并丢弃任何额外的参数。 （由 Serhiy Storchaka 在 gh-95781 中贡献。）

- 修复了 `PyUnicode_FromFormat()` 和 `PyUnicode_FromFormatV()` 中错误的标志位置。 （由 Philip Georgi 在 gh-95504 中贡献。）

- 想要添加 `__dict__` 或弱引用槽位的扩展类应当分别使用 `Py_TPFLAGS_MANAGED_DICT` 和 `Py_TPFLAGS_MANAGED_WEAKREF` 来代替 `tp_dictoffset` 和 `tp_weaklistoffset`。 `tp_dictoffset` 和 `tp_weaklistoffset` 的使用仍然受到支持，但并不完全支持多重继承 (gh-95589)，而且性能可能会变差。 声明了 `Py_TPFLAGS_MANAGED_DICT` 的类必须调用 `_PyObject_VisitManagedDict()` 和 `_PyObject_ClearManagedDict()` 来遍历并清空其实例的字典。 要清空弱引用，请像之前一样调用 `PyObject_ClearWeakRefs()`。

- `PyUnicode_FSDecoder()` 函数不再接受类似字节串的路径，如 `bytearray` 和 `memoryview` 类型：只接受明确的 `bytes` 类型字节字符串。 （由 Victor Stinner 在 gh-98393 中贡献。）

- `Py_CLEAR`、`Py_SETREF` 和 `Py_XSETREF` 宏现在只会对其参数求值一次。如果参数有附带影响，这些附带影响将不会再重复。 （由 Victor Stinner 在 gh-98724 中贡献。）

- 解释器的错误指示器现在总是规范化的。 这意味着 `PyErr_SetObject()`、`PyErr_SetString()` 以及其他设置错误指示器的函数在保存异常之前都会将其规范化。 （由 Mark Shannon 在 gh-101578 中贡献。）

- `_Py_RefTotal` 已不再具有重要性而保留它只是为了 ABI 的兼容性。 请注意，这是一个内部全局变量并且仅在调试版本中可用。 如果你碰巧要使用它那么你需要开始使用 `_Py_GetGlobalRefTotal()`。

- 下面的函数将为新创建的类型选择一个合适的元类:

  - `PyType_FromSpec()`

  - `PyType_FromSpecWithBases()`

  - `PyType_FromModuleAndSpec()`

  创建具有重载了 `tp_new` 的元类的类的做法已被弃用，在 Python 3.14+ 中将被禁止。 请注意这些函数会忽略元类的 `tp_new`，从而可能导致不完整的初始化。

  请注意 `PyType_FromMetaclass()` (在 Python 3.12 中新增) 已禁止创建具有重载了 `tp_new` (在 Python 中为 `__new__()` ) 的元类的类。

  由于 `tp_new` 重载了 `PyType_From*` 函数的几乎所有内容，因此两者互不兼容。 现有的行为 -- 在创建类型的一些步骤中忽略元类 -- 通常都是不安全的，因为（元）类会假定 `tp_new` 已被调用。 目前还没有简单通用的绕过方式。 以下办法之一可能对你有用：

  - 如果你控制着元类，请避免在其中使用 `tp_new`:

    - 如初始化可被跳过，则可以改在 `tp_init` 中完成。

    - 如果元类不需要从 Python 执行实例化，则使用 `Py_TPFLAGS_DISALLOW_INSTANTIATION` 旗标将其 `tp_new` 设为 `NULL`。 这将使其可被 `PyType_From*` 函数接受。

  - 避免使用 `PyType_From*` 函数：如果不需要 C 专属的特性（槽位或设置实例大小），请通过 调用 元类来创建类型。

  - 如果你 知道 可以安全地跳过 `tp_new`，就使用 Python 中的 `warnings.catch_warnings()` 过滤掉弃用警告。

- `PyOS_InputHook` 和 `PyOS_ReadlineFunctionPointer` 将不再在 子解释器 中被调用。 这是因为客户端通常依赖进程级的全局状态（而这些回调没有办法恢复扩展模块状态）。

  这也避免了扩展程序在不支持（或尚未被加载）的子解释器中运行的情况。 请参阅 gh-104668 了解更多信息。

- `PyLongObject` 对其内部字段进行了修改以提高性能。 虽然 `PyLongObject` 的内部字段是私有的，但某些扩展模块会使用它们。 内部字段不应再被直接访问，而应改用以 `PyLong_...` 打头的 API 函数。 新增了两个 暂定 API 函数用于高效访问适配至单个机器字的 `PyLongObject` 的值:

  - `PyUnstable_Long_IsCompact()`

  - `PyUnstable_Long_CompactValue()`

- 通过 `PyMem_SetAllocator()` 设置的自定义分配器现在必须是线程安全的，无论内存域是什么。 没有自己的状态的分配器，包括“钩子”将不会受影响。 如果你的自定义分配器还不是线程安全的且你需要指导则请创建一个新的 GitHub 问题并抄送给 `@ericsnowcurrently`。

### 弃用

- 根据 PEP 699 的要求，`PyDictObject` 中的 `ma_version_tag` 字段对于扩展模块已被弃用。 访问该字段将在编译时生成编译器警告。 该字段将在 Python 3.14 中移除。 （由 Ramvikrams 和 Kumar Aditya 在 gh-101193 中贡献。 PEP 由 Ken Jin 撰写。）

- 已弃用的全局配置变量:

  - `Py_DebugFlag`: 使用 `PyConfig.parser_debug`

  - `Py_VerboseFlag`: 使用 `PyConfig.verbose`

  - `Py_QuietFlag`: 使用 `PyConfig.quiet`

  - `Py_InteractiveFlag`: 使用 `PyConfig.interactive`

  - `Py_InspectFlag`: 使用 `PyConfig.inspect`

  - `Py_OptimizeFlag`: 使用 `PyConfig.optimization_level`

  - `Py_NoSiteFlag`: 使用 `PyConfig.site_import`

  - `Py_BytesWarningFlag`: 使用 `PyConfig.bytes_warning`

  - `Py_FrozenFlag`: 使用 `PyConfig.pathconfig_warnings`

  - `Py_IgnoreEnvironmentFlag`: 使用 `PyConfig.use_environment`

  - `Py_DontWriteBytecodeFlag`: 使用 `PyConfig.write_bytecode`

  - `Py_NoUserSiteDirectory`: 使用 `PyConfig.user_site_directory`

  - `Py_UnbufferedStdioFlag`: 使用 `PyConfig.buffered_stdio`

  - `Py_HashRandomizationFlag`: 使用 `PyConfig.use_hash_seed` 和 `PyConfig.hash_seed`

  - `Py_IsolatedFlag`: 使用 `PyConfig.isolated`

  - `Py_LegacyWindowsFSEncodingFlag`: 使用 `PyPreConfig.legacy_windows_fs_encoding`

  - `Py_LegacyWindowsStdioFlag`: 使用 `PyConfig.legacy_windows_stdio`

  - `Py_FileSystemDefaultEncoding`: 使用 `PyConfig.filesystem_encoding`

  - `Py_HasFileSystemDefaultEncoding`: 使用 `PyConfig.filesystem_encoding`

  - `Py_FileSystemDefaultEncodeErrors`: 使用 `PyConfig.filesystem_errors`

  - `Py_UTF8Mode`: 使用 `PyPreConfig.utf8_mode` (参见 `Py_PreInitialize()`)

  `Py_InitializeFromConfig()` API 应当改为使用 `PyConfig`。 （由 Victor Stinner 在 gh-77782 中贡献。）

- 使用可变的基类创建 `不可变类型` 的做法已被弃用并将在 Python 3.14 中被禁用。 (gh-95388)

- `structmember.h` 头文件已被弃用，不过它仍可继续使用也没有计划将其移除。

  现在只需包括 `Python.h` 即可获得其内容，如果找不到请添加 `Py` 前缀：

  - `PyMemberDef`, `PyMember_GetOne()` 和 `PyMember_SetOne()`

  - 类型宏如 `Py_T_INT`, `Py_T_DOUBLE` 等（之前为 `T_INT`, `T_DOUBLE` 等）

  - 旗标 `Py_READONLY` (之前为 `READONLY`) 和 `Py_AUDIT_READ` (之前为全大写形式)

  `Python.h` 上有几个项目没有暴露：

  - `T_OBJECT` (使用 `Py_T_OBJECT_EX`)

  - `T_NONE` (之前未写入文档，并且相当怪异)

  - 不进行任何操作的宏 `WRITE_RESTRICTED`。

  - `RESTRICTED` 和 `READ_RESTRICTED` 宏，等同于 `Py_AUDIT_READ`。

  - 在某些配置中， `Python.h` 未包含 `<stddef.h>` 。使用 `offsetof()` 时，应手动将其包含在内。

  已被弃用的头文件将继续以原来的名称提供原来的内容。 你的旧代码可以保持不变，除非额外的包括指令和无命名空间宏会给你带来很大困扰。

  （由 Petr Viktorin 在 gh-47146 中贡献，基于 Alexander Belopolsky 和 Matthias Braun 在先前的工作。）.)

- `PyErr_Fetch()` 和 `PyErr_Restore()` 已被弃用。请使用 `PyErr_GetRaisedException()` 和 `PyErr_SetRaisedException()` 代替。 （由 Mark Shannon 在 gh-101578 贡献。）

- `PyErr_Display()` 已被弃用，请改用 `PyErr_DisplayException()`。 （由 Irit Katriel 在 gh-102755 中贡献。）

- `_PyErr_ChainExceptions` 已被弃用。 请改用 `_PyErr_ChainExceptions1`。 （由 Irit Katriel 在 gh-102192 中贡献。）

- 使用 `PyType_FromSpec()`, `PyType_FromSpecWithBases()` 或 `PyType_FromModuleAndSpec()` 来创建所属元类重载了 `tp_new` 的类的做法已被弃用。 请改为调用相应元类。is deprecated. Call the metaclass instead.

#### 计划在 Python 3.14 中移除

- `PyDictObject` 中的 `ma_version_tag` 字段用于扩展模块 ( PEP 699 ; gh-101193 )。

- 创建 `immutable types` 的可变基础 ( gh-95388 )。

#### 计划在 Python 3.15 中移除

- The `PyImport_ImportModuleNoBlock()`: Use `PyImport_ImportModule()` instead.

- `PyWeakref_GetObject()` and `PyWeakref_GET_OBJECT()`: Use `PyWeakref_GetRef()` instead. The pythoncapi-compat project can be used to get `PyWeakref_GetRef()` on Python 3.12 and older.

- `Py_UNICODE` 类型和 `Py_UNICODE_WIDE` 宏：改用 `wchar_t`。

- `PyUnicode_AsDecodedObject()`: 改用 `PyCodec_Decode()`。

- `PyUnicode_AsDecodedUnicode()`: 改用 `PyCodec_Decode()`；请注意某些编解码器 (例如 "base64") 可能返回 `str` 以外的类型，比如 `bytes`。

- `PyUnicode_AsEncodedObject()`: 改用 `PyCodec_Encode()`。

- `PyUnicode_AsEncodedUnicode()`: 使用 `PyCodec_Encode()` 代替；请注意，某些编解码器（如 "base64"）可能返回 `bytes` 之外的类型，如 `str`。

- Python 初始化函数， Python 3.13 中弃用：

  - `Py_GetPath()`: Use `PyConfig_Get("module_search_paths")` (`sys.path`) instead.

  - `Py_GetPrefix()`: Use `PyConfig_Get("base_prefix")` (`sys.base_prefix`) instead. Use `PyConfig_Get("prefix")` (`sys.prefix`) if virtual environments need to be handled.

  - `Py_GetExecPrefix()`: Use `PyConfig_Get("base_exec_prefix")` (`sys.base_exec_prefix`) instead. Use `PyConfig_Get("exec_prefix")` (`sys.exec_prefix`) if virtual environments need to be handled.

  - `Py_GetProgramFullPath()`: Use `PyConfig_Get("executable")` (`sys.executable`) instead.

  - `Py_GetProgramName()`: Use `PyConfig_Get("executable")` (`sys.executable`) instead.

  - `Py_GetPythonHome()`: Use `PyConfig_Get("home")` or the `PYTHONHOME` environment variable instead.

  在 Python 3.13 和更旧的版本中可以使用 pythoncapi-compat 项目 来获取 `PyConfig_Get()` 。

- 用于配置 Python 的初始化的函数，在 Python 3.11 中已弃用：

  - `PySys_SetArgvEx()`: 改为设置 `PyConfig.argv`。

  - `PySys_SetArgv()`: 改为设置 `PyConfig.argv`。

  - `Py_SetProgramName()`: 改为设置 `PyConfig.program_name`。

  - `Py_SetPythonHome()`: 改为设置 `PyConfig.home`。

  - `PySys_ResetWarnOptions()`: Clear `sys.warnoptions` and `warnings.filters` instead.

  `Py_InitializeFromConfig()` API 应与 `PyConfig` 一起使用。

- 全局配置变量：

  - `Py_DebugFlag`: 改用 `PyConfig.parser_debug` 或 `PyConfig_Get("parser_debug")`。

  - `Py_VerboseFlag`: 改用 `PyConfig.verbose` 或 `PyConfig_Get("verbose")`。

  - `Py_QuietFlag`: 改用 `PyConfig.quiet` 或 `PyConfig_Get("quiet")`。

  - `Py_InteractiveFlag`: 改用 `PyConfig.interactive` 或 `PyConfig_Get("interactive")`。

  - `Py_InspectFlag`: 改用 `PyConfig.inspect` 或 `PyConfig_Get("inspect")`。

  - `Py_OptimizeFlag`: 改用 `PyConfig.optimization_level` or `PyConfig_Get("optimization_level")`。

  - `Py_NoSiteFlag`: 改用 `PyConfig.site_import` 或 `PyConfig_Get("site_import")`。

  - `Py_BytesWarningFlag`: 改用 `PyConfig.bytes_warning` or `PyConfig_Get("bytes_warning")`。

  - `Py_FrozenFlag`: 使用 `PyConfig.pathconfig_warnings` 或 `PyConfig_Get("pathconfig_warnings")` 代替。

  - `Py_IgnoreEnvironmentFlag`: 使用 `PyConfig.use_environment` 或 `PyConfig_Get("use_environment")` 代替。

  - `Py_DontWriteBytecodeFlag`: 使用 `PyConfig.write_bytecode` 或 `PyConfig_Get("write_bytecode")` 代替。

  - `Py_NoUserSiteDirectory`: 使用 `PyConfig.user_site_directory` 或 `PyConfig_Get("user_site_directory")` 代替。

  - `Py_UnbufferedStdioFlag`: 使用 `PyConfig.buffered_stdio` 或 `PyConfig_Get("buffered_stdio")` 代替。

  - `Py_HashRandomizationFlag`: 使用 `PyConfig.use_hash_seed` 和 `PyConfig.hash_seed` 或 `PyConfig_Get("hash_seed")` 代替。

  - `Py_IsolatedFlag`: 使用 `PyConfig.isolated` 或 `PyConfig_Get("isolated")` 代替。

  - `Py_LegacyWindowsFSEncodingFlag`: 使用 `PyPreConfig.legacy_windows_fs_encoding` 或 `PyConfig_Get("legacy_windows_fs_encoding")` 代替。

  - `Py_LegacyWindowsStdioFlag`: 使用 `PyConfig.legacy_windows_stdio` 或 `PyConfig_Get("legacy_windows_stdio")` 代替。

  - `Py_FileSystemDefaultEncoding`, `Py_HasFileSystemDefaultEncoding`: 使用 `PyConfig.filesystem_encoding` 或 `PyConfig_Get("filesystem_encoding")` 代替。

  - `Py_FileSystemDefaultEncodeErrors`: 使用 `PyConfig.filesystem_errors` 或 `PyConfig_Get("filesystem_errors")` 代替。

  - `Py_UTF8Mode`: 使用 `PyPreConfig.utf8_mode` 或 `PyConfig_Get("utf8_mode")` 代替。 (参见 `Py_PreInitialize()`)。

  `Py_InitializeFromConfig()` API 应与 `PyConfig` 一起使用，以设置这些选项。或者使用 `PyConfig_Get()` 在运行时获取这些选项。

#### 计划在 Python 3.16 中移除

- 捆绑的 `libmpdec` 副本。

#### 计划在未来版本中移除

以下 API 已被弃用，将被移除，但目前尚未确定移除日期。

- `Py_TPFLAGS_HAVE_FINALIZE`: 自 Python 3.8 起不再需要。

- `PyErr_Fetch()`: 改用 `PyErr_GetRaisedException()`。

- `PyErr_NormalizeException()`: 改用 `PyErr_GetRaisedException()`。

- `PyErr_Restore()`: 改用 `PyErr_SetRaisedException()`。

- `PyModule_GetFilename()`: 改用 `PyModule_GetFilenameObject()`。

- `PyOS_AfterFork()`: 改用 `PyOS_AfterFork_Child()`。

- `PySlice_GetIndicesEx()`: 改用 `PySlice_Unpack()` and `PySlice_AdjustIndices()`。

- `PyUnicode_READY()`: 自 Python 3.12 起不再需要

- `PyErr_Display()`: 改用 `PyErr_DisplayException()`。

- `_PyErr_ChainExceptions()`: 改用 `_PyErr_ChainExceptions1()`。

- `PyBytesObject.ob_shash` 成员：改为调用 `PyObject_Hash()`。

- 线程本地存储 (TLS) API：

  - `PyThread_create_key()`: 改用 `PyThread_tss_alloc()`。

  - `PyThread_delete_key()`: 改用 `PyThread_tss_free()`。

  - `PyThread_set_key_value()`: 改用 `PyThread_tss_set()`。

  - `PyThread_get_key_value()`: 改用 `PyThread_tss_get()`。

  - `PyThread_delete_key_value()`: 改用 `PyThread_tss_delete()`。

  - `PyThread_ReInitTLS()`: 自 Python 3.7 起不再需要。

### 移除

- 移除 `token.h` 头文件。从来就没有任何公开的 C 语言标记程序接口。 `token.h` 头文件只是为 Python 内部使用而设计的。(由 Victor Stinner 在 gh-92651 提供）。

- 旧式 Unicode API 已被移除。 请参阅 PEP 623 了解详情。for detail.

  - `PyUnicode_WCHAR_KIND`

  - `PyUnicode_AS_UNICODE()`

  - `PyUnicode_AsUnicode()`

  - `PyUnicode_AsUnicodeAndSize()`

  - `PyUnicode_AS_DATA()`

  - `PyUnicode_FromUnicode()`

  - `PyUnicode_GET_SIZE()`

  - `PyUnicode_GetSize()`

  - `PyUnicode_GET_DATA_SIZE()`

- 移除了 `PyUnicode_InternImmortal()` 函数宏。 （由 Victor Stinner 在 gh-85858 中贡献。）.)