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 is the latest stable release of the Python programming language, with a mix of changes to the language and the standard library. The library changes focus on cleaning up deprecated APIs, usability, and correctness. Of note, the distutils package has been removed from the standard library. Filesystem support in os and pathlib has seen a number of improvements, and several modules have better performance.

The language changes focus on usability, as f-strings have had many limitations removed and 'Did you mean ...' suggestions continue to improve. The new type parameter syntax and type statement improve ergonomics for using generic types and type aliases with static type checkers.

This article doesn't attempt to provide a complete specification of all new features, but instead gives a convenient overview. For full details, you should refer to the documentation, such as the Library Reference and Language Reference. If you want to understand the complete implementation and design rationale for a change, refer to the PEP for a particular new feature; but note that PEPs usually are not kept up-to-date once a feature has been fully implemented.


新的语法特性:

新的语法特性:

解释器的改进:

对 Python 数据模型的改进:

标准库中的重大改进:

安全改进:

  • Replace the builtin hashlib implementations of SHA1, SHA3, SHA2-384, SHA2-512, and MD5 with formally verified code from the HACL* project. These builtin implementations remain as fallbacks that are only used when OpenSSL does not provide them.

C API 的改进:

CPython 实现的改进:

  • PEP 709, comprehension inlining

  • CPython support for the Linux perf profiler

  • Implement stack overflow protection on supported platforms

新的类型标注特性:

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

  • PEP 623: Remove wstr from Unicode objects in Python's C API, reducing the size of every str object by at least 8 bytes.

  • PEP 632: Remove the distutils package. See the migration guide for advice replacing the APIs it provided. The third-party Setuptools package continues to provide distutils, if you still require it in Python 3.12 and beyond.

  • gh-95299: Do not pre-install setuptools in virtual environments created with venv. This means that distutils, setuptools, pkg_resources, and easy_install will no longer available by default; to access these run pip install setuptools in the activated virtual environment.

  • The asynchat, asyncore, and imp modules have been removed, along with several unittest.TestCase method aliases.

新的特性

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]

新语法允许声明 TypeVarTupleParamSpec 形参,以及带边界或约束的 TypeVar 形参:

type IntFunc[**P] = Callable[P, int]  # ParamSpec
type LabeledTuple[*Ts] = tuple[str, *Ts]  # TypeVarTuple
type HashableSequence[T: Hashable] = Sequence[T]  # TypeVar with bound
type IntOrStrSequence[T: (int, str)] = Sequence[T]  # TypeVar with constraints

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

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

为了支持这些作用域定义,引入了一种新的作用域,即 标注作用域。 标注作用域的行为在很大程度上类似于函数作用域,但与封闭类作用作用域的交互方式不同。 在 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;
}
/* The new interpeter is now active in the current thread. */

有关如何将 C-API 用于子解释器和解释器级 GIL 的更多示例,请参见 Modules/_xxsubinterpretersmodule.c

(由 Eric Snow 在 gh-104210 等中贡献。)

PEP 669:针对 CPython 的低影响监控

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

(Contributed by Mark Shannon in 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()
      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
      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'?
    

其他语言特性修改

  • 解析器现在在解析包含空字节的源代码时引发 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 中贡献。)

  • 所有期望布尔参数的内置和扩展可调用函数现在都接受任何类型的参数,而不仅仅是 boolint。 (由 Serhiy Storchaka 在 gh-60203 中贡献。)

  • memoryview now supports the half-float type (the "e" format code). (Contributed by Donghee Na and Antoine Pitrou in gh-90751.)

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

  • sum() now uses Neumaier summation to improve accuracy and commutativity when summing floats or mixed ints and floats. (Contributed by Raymond Hettinger in 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

asyncio

calendar

csv

dis

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

  • Add the dis.hasexc collection to signify instructions that set an exception handler. (Contributed by Irit Katriel in gh-94216.)

fractions

importlib.resources

inspect

itertools

  • Add itertools.batched() for collecting into even-sized tuples where the last batch may be shorter than the rest. (Contributed by Raymond Hettinger in gh-98363.)

math

  • Add math.sumprod() for computing a sum of products. (Contributed by Raymond Hettinger in gh-100485.)

  • Extend math.nextafter() to include a steps argument for moving up or down multiple steps at a time. (By Matthias Goergens, Mark Dickinson, and Raymond Hettinger in 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

pathlib

pdb

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

random

shutil

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

  • shutil.rmtree() 现在接受一个新的参数 onexc ,它是一个类似 onerror 的错误处理器,但它需要一个异常实例,而不是一个 (typ, val, tb) 三元组。 onerror 已弃用,并将在 Python 3.14 中移除。 (由 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

statistics

  • Extend statistics.correlation() to include as a ranked method for computing the Spearman correlation of ranked data. (Contributed by Raymond Hettinger in gh-95861.)

sys

tempfile

threading

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

types

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)  # unchanged, even though HasX now also has a "y" attribute
    True
    

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

  • 针对 运行时可检测协议isinstance() 检测的性能表现有显著的改进。 对于具有少量成员的协议的 isinstance() 检测相比 3.11 应当至少有 2x 的提速,有些可能会有 20x 或更多的提速。 但是,对于具有十四个或更多成员的协议的 isinstance() 检测可能会慢于 Python 3.11。 (由 Alex Waygood 在 gh-74690gh-103193 中贡献。)

  • 现在所有 typing.TypedDicttyping.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

Add a --durations command line option, showing the N slowest test cases:

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)

(Contributed by Giampaolo Rodola in gh-48330)

uuid

性能优化

  • Remove wstr and wstr_length members from Unicode objects. It reduces object size by 8 or 16 bytes on 64bit platform. (PEP 623) (Contributed by Inada Naoki in gh-92536.)

  • Add experimental support for using the BOLT binary optimizer in the build process, which improves performance by 1-5%. (Contributed by Kevin Modzelewski in gh-90536 and tuned by Donghee Na in 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 字节码的改变

演示和工具

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

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

弃用

计划在 Python 3.13 中移除

以下模块和 API 已在之前的 Python 发布版中弃用,并将在 Python 3.13 中移除。

模块 (参见 PEP 594):

其他模块:

  • lib2to3,以及 2to3 程序 (gh-84540)

API:

计划在 Python 3.14 中移除

The following APIs have been deprecated and will be removed in Python 3.14.

  • argparse: The type, choices, and metavar parameters of argparse.BooleanOptionalAction

  • ast:

    • ast.Num

    • ast.Str

    • ast.Bytes

    • ast.NameConstant

    • ast.Ellipsis

  • asyncio:

    • asyncio.MultiLoopChildWatcher

    • asyncio.FastChildWatcher

    • asyncio.AbstractChildWatcher

    • asyncio.SafeChildWatcher

    • asyncio.set_child_watcher()

    • asyncio.get_child_watcher(),

    • asyncio.AbstractEventLoopPolicy.set_child_watcher()

    • asyncio.AbstractEventLoopPolicy.get_child_watcher()

  • collections.abc: collections.abc.ByteString.

  • email: the isdst parameter in email.utils.localtime().

  • importlib.abc:

    • importlib.abc.ResourceReader

    • importlib.abc.Traversable

    • importlib.abc.TraversableResources

  • itertools: Support for copy, deepcopy, and pickle operations.

  • pkgutil:

    • pkgutil.find_loader()

    • pkgutil.get_loader().

  • pty:

    • pty.master_open()

    • pty.slave_open()

  • shutil: The onerror argument of shutil.rmtree()

  • typing: typing.ByteString

  • xml.etree.ElementTree: Testing the truth value of an xml.etree.ElementTree.Element.

  • The __package__ and __cached__ attributes on module objects.

  • The co_lnotab attribute of code objects.

计划在未来版本中移除

下列 API 在更早的 Python 版本中已被弃用并将被移除,但目前还没有确定它们的移除日期。

  • array'u' 格式代码 (gh-57281)

  • typing.Text (gh-92332)

  • 目前 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)

移除

asynchat 和 asyncore

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

configparser

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, setuptoolsdistutils 包,因为它们是 setuptools 包的组成部分。 对于在运行时依赖这些包的项目,应当将 setuptools 项目声明为依赖项之一并单独安装(通常是使用 pip)。

    (由 Pradyun Gedam 在 gh-95299 中贡献。)

enum

  • 移除了 enumEnumMeta.__getattr__,枚举属性访问已不再需要它。 (由 Ethan Furman 在 gh-95083 中贡献。)

ftplib

  • 移除了 ftplibFTP_TLS.ssl_version 类属性:请改用 context 形参。 (由 Victor Stinner 在 gh-94172 中贡献。)

gzip

  • 移除了 gzipgzip.GzipFilefilename 属性,自 Python 2.6 起该属性已被弃用,请改用 name 属性。 在可写模式下,如果 filename 属性没有 '.gz' 文件扩展名则会添加它。 (由 Victor Stinner 在 gh-94196 中贡献。)

hashlib

  • 移除了 hashlibhashlib.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_loaderimportlib.util.module_for_loader 均已被移除。 (由 Brett Cannon 和 Nikita Sobolev 在 gh-65961gh-97850 中贡献。)

    • find_loader()find_module() API 的支持已被移除。 (由 Barry Warsaw 在 gh-98040 中贡献。)

    • importlib.abc.Finder, pkgutil.ImpImporterpkgutil.ImpLoader 已被移除。 (由 Barry Warsaw 在 gh-98040 中贡献。)

imp

  • imp 模块已被移除。 (由 Barry Warsaw 在 gh-98040 中贡献。)

    To migrate, consult the following correspondence table:

    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_SUFFIXESimportlib.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()

    See below

    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)
        # The module is always executed and not cached in sys.modules.
        # Uncomment the following line to cache the module.
        # sys.modules[module.__name__] = module
        loader.exec_module(module)
        return module
    
  • Remove imp functions and attributes with no replacements:

    • Undocumented functions:

      • 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

  • 移除了 localelocale.format() 函数,它在 Python 3.7 中已被弃用:请改用 locale.format_string()。 (由 Victor Stinner 在 gh-94226 中贡献。)

  • 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

  • 移除了 sslssl.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: 不正确的证书验证问题的影响。 (由 Victor Stinner 在 gh-94199 中贡献。)

unittest

webbrowser

  • Remove support for obsolete browsers from webbrowser. The removed browsers include: Grail, Mosaic, Netscape, Galeon, Skipstone, Iceape, Firebird, and Firefox versions 35 and below (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

  • 移除了 zipimportfind_loader()find_module() 方法,它们在 Python 3.10 中已被弃用:请改用 find_spec() 方法。 请参阅 PEP 451 了解相关说明。 (由 Victor Stinner 在 gh-94379 中贡献。)

其他事项

  • Remove the suspicious rule from the documentation Makefile and Doc/tools/rstlint.py, both in favor of sphinx-lint. (Contributed by Julien Palard in gh-98179.)

  • 移除了 ftplibimaplibpoplibsmtplib 模块中的 keyfilecertfile 形参数,以及 http.client 模块中的 key_filecert_filecheck_hostname 形参,它们自 Python 3.6 起都已被弃用。 请改用 context 形参(在 imaplib 中为 ssl_context 形参)。 (由 Victor Stinner 在 gh-94172 中贡献。).)

移植到 Python 3.12

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

Python API 的变化

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

  • Remove randrange() functionality deprecated since Python 3.10. Formerly, randrange(10.0) losslessly converted to randrange(10). Now, it raises a TypeError. Also, the exception raised for non-integer values such as randrange(10.5) or randrange('10') has been changed from ValueError to TypeError. This also prevents bugs where randrange(1e25) would silently select from a larger range than randrange(10**25). (Originally suggested by Serhiy Storchaka gh-86388.)

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

  • Remove the asyncore-based smtpd module deprecated in Python 3.4.7 and 3.5.4. A recommended replacement is the asyncio-based aiosmtpd PyPI module.

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

  • os 模块不再接受类似字节串的路径,如 bytearraymemoryview 类型:只接受明确的 bytes 类型字节串。 (由 Victor Stinner 在 gh-98393 中贡献。)

  • syslog.openlog() and syslog.closelog() now fail if used in subinterpreters. syslog.syslog() may still be used in subinterpreters, but now only if syslog.openlog() has already been called in the main interpreter. These new restrictions do not apply to the main interpreter, so only a very small set of users might be affected. This change helps with interpreter isolation. Furthermore, syslog is a wrapper around process-global resources, which are best managed from the main interpreter. (Contributed by Donghee Na in gh-99127.)

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

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

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

  • 由于在 PEP 701 中引入的更改 tokenize.tokenize()tokenize.generate_tokens() 函数的输出现在发生了改变。 这意味着不再为 f-字符输出 STRING 词元而是改为产生 PEP 701 中描述的词元:除了用于对表达式组件进行分词的适当词元外现在还有 FSTRING_START, FSTRING_MIDDLEFSTRING_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

构建变化

  • Python no longer uses setup.py to build shared C extension modules. Build parameters like headers and libraries are detected in configure script. Extensions are built by Makefile. Most extensions use pkg-config and fall back to manual detection. (Contributed by Christian Heimes in gh-93939.)

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

  • CPython now uses the ThinLTO option as the default link time optimization policy if the Clang compiler accepts the flag. (Contributed by Donghee Na in gh-89536.)

  • Add COMPILEALL_OPTS variable in Makefile to override compileall options (default: -j0) in make install. Also merged the 3 compileall commands into a single command to build .pyc files for all optimization levels (0, 1, 2) at once. (Contributed by Victor Stinner in 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 683: Introduce Immortal Objects, which allows objects to bypass reference counts, and related changes to the 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

      objects that have been interned. This is now needed for refleak.py to correctly track reference counts and allocated blocks

    (由 Eddie Elizondo 在 gh-84436 中贡献。)

  • PEP 684: Add the new Py_NewInterpreterFromConfig() function and PyInterpreterConfig, which may be used to create sub-interpreters with their own GILs. (See PEP 684: 解释器级 GIL for more info.) (Contributed by Eric Snow in 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, esU

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

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

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

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

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

  • Fix wrong sign placement in PyUnicode_FromFormat() and PyUnicode_FromFormatV(). (Contributed by Philip Georgi in gh-95504.)

  • 希望添加 __dict__ 或弱引用槽位的扩展类应分别使用 Py_TPFLAGS_MANAGED_DICTPy_TPFLAGS_MANAGED_WEAKREF 来代替 tp_dictoffsettp_weaklistoffset。 目前仍支持使用 tp_dictoffsettp_weaklistoffset,但并不完全支持多重继承 (gh-95589),而且性能可能会变差。 声明了 Py_TPFLAGS_MANAGED_DICT 的类应当调用 _PyObject_VisitManagedDict()_PyObject_ClearManagedDict() 来遍历并清除它们的实例的字典。 要清除弱引用,请像之前一样调用 PyObject_ClearWeakRefs()

  • PyUnicode_FSDecoder() 函数不再接受类似字节串的路径,如 bytearraymemoryview 类型:只接受明确的 bytes 类型字节字符串。 (由 Victor Stinner 在 gh-98393 中贡献。)

  • Py_CLEARPy_SETREFPy_XSETREF 宏现在只会对其参数求值一次。如果参数有附带影响,这些附带影响将不会再重复。 (由 Victor Stinner 在 gh-98724 中贡献。)

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

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

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

    创建具有重载了 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_InputHookPyOS_ReadlineFunctionPointer 将不再在 子解释器 中被调用。 这是因为客户端通常依赖进程级的全局状态(而这些回调没有办法恢复扩展模块状态)。

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

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

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

弃用

计划在 Python 3.14 中移除

Pending Removal in Python 3.15

计划在未来版本中移除

The following APIs are deprecated and will be removed, although there is currently no date scheduled for their removal.

移除

  • Remove the token.h header file. There was never any public tokenizer C API. The token.h header file was only designed to be used by Python internals. (Contributed by Victor Stinner in 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 中贡献。).)

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

  • ctypes 模块移除了 _use_broken_old_ctypes_structure_semantics_ 旗标。 (由 Nikita Sobolev 在 gh-99285 中贡献。)