侧边栏壁纸
博主头像
noerror

虚灵不寐,众理具而万事出。

  • 累计撰写 239 篇文章
  • 累计创建 9 个标签
  • 累计收到 2 条评论
标签搜索

目 录CONTENT

文章目录

Python 3.11新特性尽览

noerror
2022-09-23 / 0 评论 / 0 点赞 / 274 阅读 / 15,570 字 / 正在检测是否收录...

本文介绍了 Python 3.11 与 3.10 相比的新功能。

有关完整详细信息,请参阅更改日志

发布亮点

  • Python 3.11 比 Python 3.10 快 10-60%。平均而言,我们测量了标准基准套件的 1.25 倍加速。有关详细信息,请参阅更快的 CPython

新的语法特性:

新的内置功能:

  • PEP 678:使用注释丰富异常。

新的标准库模块:

  • PEP 680 :tomllib— 支持在标准库中解析 TOML。

解释器改进:

  • PEP 657:在回溯中包含细粒度的错误位置。

  • 新的-P命令行选项和PYTHONSAFEPATH环境变量以禁用自动将潜在不安全路径(工作目录或脚本目录,取决于调用)添加到sys.path.

类型相关的新功能:

  • PEP 646:可变参数泛型。

  • PEP 655:将单个 TypedDict 项目标记为需要或可能丢失。

  • PEP 673Self类型。

  • PEP 675:任意文字字符串类型。

  • PEP 681:数据类转换。

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

  • PEP 594:从标准库中移除没电的电池。

  • PEP 624:删除Py_UNICODE编码器 API。

  • PEP 670:将宏转换为 Python C API 中的函数。

新功能

PEP 657:回溯中增强的错误位置

打印回溯时,解释器现在将指向导致错误的确切表达式,而不仅仅是行。例如:

Traceback (most recent call last):
  File "distance.py", line 11, in <module>
    print(manhattan_distance(p1, p2))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "distance.py", line 6, in manhattan_distance
    return abs(point_1.x - point_2.x) + abs(point_1.y - point_2.y)
                           ^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'x'

以前版本的解释器只会指向该行,从而使对象是None. dict在处理深度嵌套的对象和多个函数调用时,这些增强的错误也很有帮助:

Traceback (most recent call last):
  File "query.py", line 37, in <module>
    magic_arithmetic('foo')
  File "query.py", line 18, in magic_arithmetic
    return add_counts(x) / 25
           ^^^^^^^^^^^^^
  File "query.py", line 24, in add_counts
    return 25 + query_user(user1) + query_user(user2)
                ^^^^^^^^^^^^^^^^^
  File "query.py", line 32, in query_user
    return 1 + query_count(db, response['a']['b']['c']['user'], retry=True)
                               ~~~~~~~~~~~~~~~~~~^^^^^
TypeError: 'NoneType' object is not subscriptable

以及复杂的算术表达式:

Traceback (most recent call last):
  File "calculation.py", line 54, in <module>
    result = (x / y / z) * (a / b / c)
              ~~~~~~^~~
ZeroDivisionError: division by zero

此外,增强回溯功能使用的信息可通过通用 API 获得,可用于将 字节码 指令与源代码位置相关联。可以使用以下方法检索此信息:

PEP 657了解更多详情。(由 Pablo Galindo、Batuhan Taskaya 和 Ammar Askar 在bpo-43950中贡献。)

PEP 654:异常组和except*

PEP 654引入了语言特性,使程序能够同时引发和处理多个不相关的异常。内置类型ExceptionGroupBaseExceptionGroup 可以将异常分组并将它们一起引发,并且新except*语法可以泛化 except以匹配异常组的子组。

PEP 654了解更多详情。

(由 Irit Katriel 在bpo-45292中贡献。PEP由 Irit Katriel、Yury Selivanov 和 Guido van Rossum 编写。)

PEP 678:可以用注释来丰富异常

add_note()方法被添加到BaseException. 它可用于使用在引发异常时不可用的上下文信息来丰富异常。添加的注释出现在默认回溯中。

PEP 678了解更多详情。

(由 Irit Katriel 在bpo-45607中提供。PEP由 Zac Hatfield-Dodds 编写。)

其他语言变化

其他 CPython 实现更改

  • 特殊方法complex.__complex__()bytes.__bytes__()实现支持typing.SupportsComplextyping.SupportsBytes协议。(由 Mark Dickinson 和 Dong-hee Na 在bpo-24234中贡献。)

  • siphash13被添加为新的内部散列算法。它具有类似的安全属性,siphash24但对于长输入来说速度稍快。str,bytes和其他一些类型现在使用它作为hash().PEP 552 基于散列的 pyc 文件现在siphash13也使用 . (由 Inada Naoki 在bpo-29410中贡献。)

  • 当不带参数的语句重新引发活动异常时raise,附加到此异常的回溯现在始终为sys.exc_info()[1].__traceback__. 这意味着对当前except子句中的回溯所做的更改会反映在重新引发的异常中。(由 Irit Katriel 在bpo-45711中贡献。)

  • 解释器状态表示的已处理异常(又名 exc_info 或 _PyErr_StackItem)现在只有该exc_value字段,exc_type并且exc_traceback 已被删除,因为它们的值可以从exc_value. (由 Irit Katriel 在bpo-45711中贡献。)

  • 为 Windows 安装程序AppendPath添加了一个新的命令行选项。它的行为类似于PrependPath但附加了 install 和 scripts 目录,而不是预先添加它们。(由 Bastian Neuburger 在bpo-44934中贡献。)

  • PyConfig.module_search_paths_set字段现在必须设置为 1 才能用于PyConfig.module_search_paths初始化 sys.path。否则,初始化将重新计算路径并替换添加到module_search_paths.

  • --help选项的输出更改为适合 50 行和 80 列。有关Python 环境变量的信息 ,可通过 new或 标志和. (由 Éric Araujo 在bpo-46142中贡献。)-X options--help-env--help-xoptions--help-all

  • 在 2(二进制)、4、8(八进制)、16(十六进制)或 32(如以 10(十进制)为基数)以外的基数之间进行转换现在会引发 aint如果字符串形式的位数超过避免的限制由于算法复杂性,潜在的拒绝服务攻击。这是针对CVE-2020-10735的缓解措施。可以通过环境变量、命令行标志或API 配置或禁用此限制。请参阅整数字符串转换长度限制文档。默认限制为字符串形式的 4300 位数字。strValueErrorsys

新模块

  • 添加了一个新模块,tomllib用于解析 TOML。(由 Taneli Hukkinen 在bpo-40059中贡献。)

  • wsgiref.types,包含用于静态类型检查的特定于 WSGI 的类型,已添加。(由 Sebastian Rittau 在bpo-42012中贡献。)

改进的模块

asyncio

  • 将原始数据报套接字函数添加到事件循环 sock_sendto()sock_recvfrom()sock_recvfrom_into(). (由 Alex Grönholm 在bpo-46805中贡献。)

  • 添加start_tls()将现有的基于流的连接升级到 TLS 的方法。(由 Ian Good 在 bpo-34975中贡献。)

  • Barrier类添加到 asyncio 库的同步原语中。(由 Yves Duprat 和 Andrew Svetlov 在 gh-87518中提供。)

  • 添加TaskGroup类,一个异步上下文管理器 ,其中包含一组任务,这些任务将在退出时等待所有任务。(由 Yury Seliganov 等人提供。)

contextlib

添加了非并行安全chdir()上下文管理器以更改当前工作目录,然后在退出时恢复它。简单的包装chdir()。(由 Filipe Laíns 在bpo-25625中贡献)

dataclasses

  • 更改字段默认可变性检查,仅允许可 散列的默认值,而不是任何不是 dict,list或实例的对象set。(由 Eric V. Smith 在 bpo-44674中贡献。)

datetime

enum

  • EnumMeta重命名为EnumTypeEnumMeta保留为别名)。

  • StrEnum添加——枚举成员是并且必须是字符串。

  • ReprEnum添加 - 仅导致__repr__被修改,而不是 __str____format__

  • FlagBoundary添加 - 控制为标志提供无效值时的行为。

  • EnumCheck添加 - 用于verify确保各种约束。

  • verify添加了 – 确保给定EnumCheck约束的功能。

  • member添加 - 装饰器以确保将给定对象转换为枚举成员。

  • nonmember添加 - 装饰器以确保给定对象不会转换为枚举成员。

  • property添加 - 使用而不是types.DynamicClassAttribute.

  • global_enum添加了——枚举装饰器来调整__repr____str__ 显示全局上下文中的成员——参见re.RegexFlag示例。

  • Flag增强:成员支持长度、迭代和包含检查。

  • Enum/Flag修复:成员现在被定义之前__init_subclass__ 被调用;dir()现在包括来自混合数据类型的方法等。

  • Flag修复:只有主值(2 的幂)被认为是规范的,而复合值(3、6、10 等)被认为是别名;倒置标志被强制转换为正等值。

  • IntEnum//修复IntFlagStrEnum这些现在继承自, ReprEnum因此str()输出现在匹配format()输出,即数据类型(所以两者str(AnIntEnum.ONE)format(AnIntEnum.ONE)等于'1')。

fractions

  • 支持PEP 515Fraction -从字符串初始化(由 Sergey B Kirpichev 在bpo-44258中贡献。)

  • Fraction现在实现一个__int__方法,以便检查通过。(由 Mark Dickinson 在bpo-44547中贡献。)isinstance(some_fraction, typing.SupportsInt)

functools

  • functools.singledispatch()现在支持types.UnionTypetyping.Union作为 dispatch 参数的注解。:

    >>>

    >>> from functools import singledispatch
    >>> @singledispatch
    ... def fun(arg, verbose=False):
    ...     if verbose:
    ...         print("Let me just say,", end=" ")
    ...     print(arg)
    ...
    >>> @fun.register
    ... def _(arg: int | float, verbose=False):
    ...     if verbose:
    ...         print("Strength in numbers, eh?", end=" ")
    ...     print(arg)
    ...
    >>> from typing import Union
    >>> @fun.register
    ... def _(arg: Union[list, set], verbose=False):
    ...     if verbose:
    ...         print("Enumerate this:")
    ...     for i, elem in enumerate(arg):
    ...         print(i, elem)
    ...
    
    

    (由 Yurii Karabas 在bpo-46014中贡献。)

hashlib

  • hashlib.blake2b()hashlib.blake2s()现在更喜欢libb2而 不是 Python 的 vendored 副本。(由 Christian Heimes 在bpo-47095中贡献。)

  • 带有 SHA3 和 SHAKE 算法的内部_sha3模块现在使用 _tiny_sha3_而不是_Keccak 代码包_来减少代码和二进制大小。该hashlib模块更喜欢 OpenSSL 的优化 SHA3 和 SHAKE 实现。此更改仅影响不支持 OpenSSL 的安装。(由 Christian Heimes 在bpo-47098中贡献。)

  • Add hashlib.file_digest(),一个用于有效散列文件或类似文件的对象的辅助函数。(由 Christian Heimes 在gh-89313中提供。)

空闲和空闲库

  • 对.pyi文件应用语法高亮。(由 Alex Waygood 和 Terry Jan Reedy 在bpo-45447中贡献。)

  • 在保存带有输入和输出的 Shell 时包括提示。(由 Terry Jan Reedy 在gh-95191中提供。)

inspect

locale

math

  • math.exp2():返回 2 的 x 次方。(由 Gideon Mitchell 在bpo-45917中贡献。)

  • 添加math.cbrt():返回 x 的立方根。(由 Ajith Ramachandran 在bpo-44357中贡献。)

  • math.pow()为了与 IEEE 754 规范保持一致,更改了两个极端情况的行为。操作 ,现在返回 。以前他们提出了. (由 Mark Dickinson 在bpo-44339中贡献。)math.pow(0.0, -math.inf)``math.pow(-0.0, -math.inf)``infValueError

  • math.nan值现在始终可用。(由 Victor Stinner 在bpo-46917中贡献。)

operator

  • 添加了一个新功能operator.call,例如 . (由 Antony Lee 在bpo-44019中贡献。)operator.call(obj, *args, **kwargs) == obj(*args, **kwargs)

os

  • 在 Windows 上,os.urandom()现在使用BCryptGenRandom(),而不是CryptGenRandom()已弃用。(由 Dong-hee Na 在bpo-44611中提供。)

pathlib

re

  • 正则表达式现在支持原子分组 ( (?>...)) 和所有格量词 ( *+, ++, ?+, )。{m,n}+(由 Jeffrey C. Jacobs 和 Serhiy Storchaka 在bpo-433030中贡献。)

shutil

socket

  • 添加对 NetBSD 的 CAN Socket 支持。(由 Thomas Klausner 在bpo-30512中贡献。)

  • create_connection()如果连接失败,可以选择引发一个ExceptionGroup包含所有错误的选项,而不是只引发最后一个错误。(由 Irit Katriel 在bpo-29980中贡献。)

sqlite3

sys

  • sys.exc_info()现在从(异常实例)派生typeandtraceback字段value,因此当异常在处理过程中被修改时,更改会反映在对 . 的后续调用的结果中exc_info()。(由 Irit Katriel 在bpo-45711中贡献。)

  • 添加sys.exception()返回活动异常实例(相当于sys.exc_info()[1])。(由 Irit Katriel 在bpo-46328中贡献。)

  • 添加sys.flags.safe_path标志。(由 Victor Stinner 在gh-57684中提供。)

sysconfig

  • 添加了三个新的安装方案posix_venvnt_venv_和_venv),并在 Python 创建新的虚拟环境或从虚拟环境运行时使用。前两个方案(posix_venv_和_nt_venv)是针对非 Windows 和 Windows的操作系统,根据 Python 运行的操作系统, _venv本质上是其中一个的别名。_这对于修改 sysconfig.get_preferred_scheme(). 创建新虚拟环境的第三方代码应该使用新的 _venv_安装方案来确定路径,就像venv. (由 Miro Hrončok 在bpo-45413中贡献.)

threading

time

  • 在 Unix 上,time.sleep()现在使用clock_nanosleep()or nanosleep()函数(如果可用),其分辨率为 1 纳秒(10 -9秒),而不是使用select()其分辨率为 1 微秒(10 -6秒)。(由 Benjamin Szőke 和 Victor Stinner 在bpo-21302中贡献。)

  • 在 Windows 8.1 和更新版本上,time.sleep()现在使用基于高分辨率计时器的可等待计时器 ,其分辨率为 100 纳秒(10 -7秒)。以前,它的分辨率为 1 毫秒(10 -3秒)。(由 Benjamin Szőke、Dong-hee Na、Eryk Sun 和 Victor Stinner 在bpo-21302bpo-45429 中贡献。)

traceback

typing

有关重大更改,请参阅与类型提示相关的新功能

  • 添加typing.assert_never()typing.Nevertyping.assert_never()对于要求类型检查器确认无法访问某行代码很有用。在运行时,它会引发一个 AssertionError. (由 Jelle Zijlstra 在gh-90633中提供。)

  • 添加typing.reveal_type(). 这对于询问类型检查器它为给定表达式推断出的类型很有用。在运行时,它会打印接收到的值的类型。(由 Jelle Zijlstra 在gh-90572中提供。)

  • 添加typing.assert_type(). 这对于要求类型检查器确认它为给定表达式推断的类型是否与给定类型匹配很有用。在运行时,它只是返回接收到的值。(由 Jelle Zijlstra 在gh-90638中提供。)

  • typing.TypedDict类型现在可以是通用的。(由 Samodya Abeysiriwardane 在gh-89026中提供。)

  • NamedTuple类型现在可以是通用的。(由 Serhiy Storchaka 在bpo-43923中贡献。)

  • 允许子类化typing.Any. 这对于避免与高度动态类相关的类型检查器错误很有用,例如模拟。(由 Shantanu Jain 在gh-91154中提供。)

  • typing.final()装饰器现在设置被装饰对象的属性__final__。(由 Jelle Zijlstra 在gh-90500中提供。)

  • typing.get_overloads()函数可用于内省函数的重载。typing.clear_overloads()可用于清除函数的所有已注册重载。(由 Jelle Zijlstra 在gh-89263中提供。)

  • 现在保留了子类的__init__()方法。Protocol(由 Adrian Garcia Badarasco 在gh-88970中提供。)

  • 空元组类型 ( Tuple[()]) 的表示被简化了。这会影响内省,例如get_args(Tuple[()])现在评估为()而不是((),). (由 Serhiy Storchaka 在gh-91137中提供。)

  • typing._type_check通过删除私有函数中的可调用检查来放松类型注释的运行时要求。(由 Gregory Beauregard 在gh-90802中提供。)

  • typing.get_type_hints()现在支持将字符串评估为PEP 585 通用别名中的前向引用。(由 Niklas Rosenstein 在gh-85542中提供。)

  • typing.get_type_hints()不再默认添加Optional 到参数中。None(由 Nikita Sobolev 在gh-90353中提供。)

  • typing.get_type_hints()现在支持评估裸字符串化 ClassVar注释。(由 Gregory Beauregard 在gh-90711中提供。)

  • typing.no_type_check()不再修改外部类和函数。它现在还正确地将类方法标记为不进行类型检查。(由 Nikita Sobolev 在gh-90729中提供。)

tkinter

  • 添加info_patchlevel()了将 Tcl 库的确切版本作为命名元组返回的方法,类似于sys.version_info. (由 Serhiy Storchaka 在gh-91827中提供。)

unicodedata

  • Unicode 数据库已更新至版本 14.0.0。(由 Benjamin Peterson 在bpo-45190中贡献)。

unittest

venv

  • 创建新的 Python 虚拟环境时,使用_venv_ sysconfig 安装方案来确定环境内部的路径。Python在虚拟环境中运行时,默认安装方案相同。这意味着下游分销商可以在不改变虚拟环境行为的情况下更改默认的 sysconfig 安装方案。也创建新虚拟环境的第三方代码也应该这样做。(由 Miro Hrončok 在bpo-45413中贡献。)

warnings

zipfile

  • 添加了对指定成员名称编码以读取 zipfile 目录和文件头中的元数据的支持。(由 Stephen J. Turnbull 和 Serhiy Storchaka 在bpo-28080中贡献。)

fcntl

  • 在 FreeBSD 上,F_DUP2FDF_DUP2FD_CLOEXECflags 分别被支持,前者相当于dup2使用,后者FD_CLOEXEC额外设置了 flag。

Optimizations

  • 编译器现在使用仅包含格式代码的文字格式优化简单的 C 样式格式%s%r%a使其与相应的 f 字符串表达式一样快。(由 Serhiy Storchaka 在bpo-28307中贡献。)

  • 实施“零成本”例外。try当不引发异常时,语句的成本几乎可以消除。(由 Mark Shannon 在bpo-40222中贡献。)

  • 纯 ASCII 字符串现在在常数时间内通过unicodedata.normalize(). (由 Dong-hee Na 在bpo-44987中提供。)

  • math函数comb()perm()现在对于大参数来说速度提高了 10 倍或更多(对于较大的_k_速度更快)。(由 Serhiy Storchaka 在bpo-37295中贡献。)

  • 当所有插入的键都是 Unicode 对象时,字典不存储哈希值。这减少了字典大小。例如,sys.getsizeof(dict.fromkeys("abcdefg")) 在 64 位平台上从 352 字节变为 272 字节。(由 Inada Naoki 在bpo-46845中贡献。)

  • re的正则表达式匹配引擎已部分重构,现在在支持的平台上使用计算的 goto(或“线程代码”)。因此,Python 3.11 执行pyperformance 正则表达式基准的速度比 Python 3.10 快 10%。

更快的 CPython

当使用pyperformance基准套件测量并在 Ubuntu Linux 上使用 GCC 编译时, CPython 3.11 平均 比 CPython 3.10 快 25% 。根据您的工作量,加速可能会快 10-60%。

该项目专注于 Python 的两个主要领域:更快的启动和更快的运行时。不在此项目下的其他优化在优化中列出。

更快的启动

冻结导入/静态代码对象

Python 在__pycache__目录中缓存字节码以加速模块加载。

在 3.10 之前的版本中,Python 模块执行如下所示:

Read __pycache__ -> Unmarshal -> Heap allocated code object -> Evaluate

在 Python 3.11 中,Python 启动所必需的核心模块被“冻结”了。这意味着它们的代码对象(和字节码)是由解释器静态分配的。这将模块执行过程中的步骤减少到:

Statically allocated code object -> Evaluate

在 Python 3.11 中,解释器的启动速度现在提高了 10-15%。这对使用 Python 的短期运行程序有很大的影响。

(由 Eric Snow、Guido van Rossum 和 Kumar Aditya 在多个问题中提供。)

更快的运行时间

更便宜、更懒的 Python 框架

每当 Python 调用 Python 函数时,都会创建 Python 帧。该帧保存执行信息。以下是新的帧优化:

  • 简化了框架创建过程。

  • 通过大量重用 C 堆栈上的帧空间来避免内存分配。

  • 简化了内部框架结构以仅包含基本信息。以前的帧包含额外的调试和内存管理信息。

旧式框架对象现在仅在调试器或 Python 自省函数(如sys._getframe或 )请求时创建inspect.currentframe。对于大多数用户代码,根本不会创建框架对象。结果,几乎所有 Python 函数调用都显着加快了速度。我们测量了 3-7% 的 pyperformance 加速。

(由 Mark Shannon 在bpo-44590中贡献。)

内联 Python 函数调用

在 Python 函数调用期间,Python 将调用评估 C 函数来解释该函数的代码。这有效地将纯 Python 递归限制在对 C 堆栈安全的范围内。

在 3.11 中,当 CPython 检测到 Python 代码调用另一个 Python 函数时,它会设置一个新框架,并“跳转”到新框架内的新代码。这完全避免了调用 C 解释函数。

大多数 Python 函数调用现在不消耗 C 堆栈空间。这加快了大多数此类呼叫。在像斐波那契或阶乘这样的简单递归函数中,观察到了 1.7 倍的加速。这也意味着递归函数可以递归得更深(如果用户增加递归限制)。我们测量了 pyperformance 提高了 1-3%。

(由 Pablo Galindo 和 Mark Shannon 在bpo-45256中贡献。)

PEP 659:专门的自适应解释器

PEP 659是更快的 CPython 项目的关键部分之一。一般的想法是,虽然 Python 是一种动态语言,但大多数代码都有对象和类型很少更改的区域。这个概念被称为_类型稳定性_。

在运行时,Python 将尝试在执行代码中寻找常见模式和类型稳定性。然后,Python 将用更专业的操作替换当前操作。这种专门的操作使用仅适用于那些用例/类型的快速路径,这些用例/类型通常优于它们的通用对应物。这也带来了另一个称为_内联缓存_的概念,其中 Python 将昂贵操作的结果直接缓存在字节码中。

专门化者还将某些常用指令对组合成一个超指令。这减少了执行期间的开销。

Python 只有在看到“热”(多次执行)的代码时才会专门化。这可以防止 Python 将时间浪费在运行一次的代码上。当代码过于动态或用途发生变化时,Python 也可以去专门化。定期尝试专业化,并且专业化尝试不会太昂贵。这使专业化能够适应新的环境。

(由 Mark Shannon 撰写的 PEP,灵感来自 Stefan Brunthaler。见PEP 659了解更多信息。Mark Shannon 和 Brandt Bucher 在 Irit Katriel 和 Dennis Sweeney 的帮助下实施。)

操作 形式 详细描述 操作加速(最多) 贡献者
二元运算 x+x; x*x; x-x; 常见类型(例如 , int)的二进制加法、乘法和减法float,并str为其基础类型采用自定义快速路径。 10% 马克·香农、娜东熙、布兰特·布彻、丹尼斯·斯威尼
下标 a[i] 下标容器类型,例如list, tupledict直接索引底层数据结构。下标自定义__getitem__ 也是内联的,类似于内联Python 函数调用 10-25% 伊瑞特·卡特里尔,马克·香农
存储下标 a[i] = z 类似于上面的下标专业化。 10-25% 丹尼斯·斯威尼
来电 f(arg) C(arg) len调用常见的内置 © 函数和类型,例如str直接调用其底层 C 版本。这避免了通过内部调用约定。 20% 马克·香农、肯·金
加载全局变量 print len globals/builtins 命名空间中的对象索引被缓存。加载全局变量和内置函数需要零命名空间查找。 1 马克香农
加载属性 o.attr 类似于加载全局变量。类/对象命名空间内的属性索引被缓存。在大多数情况下,属性加载将需要零命名空间查找。 2 马克香农
调用的加载方法 o.meth() 方法的实际地址被缓存。方法加载现在没有命名空间查找——即使对于具有长继承链的类也是如此。 10-20% 金肯,马克·香农
店铺属性 o.attr = z 类似于负载属性优化。 2% 的性能 马克香农
解包序列 *seq 专门用于常见容器,例如listtuple。避免内部调用约定。 8% 布兰特·布赫

1

自 Python 3.8 以来已经存在类似的优化。3.11 专门针对更多形式并减少了一些开销。

2

自 Python 3.10 以来已经存在类似的优化。3.11 专门针对更多形式。此外,所有属性加载都应该由bpo-45947 加速

Misc

  • 由于延迟创建的对象命名空间,对象现在需要更少的内存。他们的命名空间字典现在也更自由地共享键。(在bpo-45340bpo-40116中贡献了 Mark Shannon 。)

  • 解释器中更简洁的异常表示将捕获异常所需的时间减少了约 10%。(由 Irit Katriel 在bpo-45711中贡献。)

FAQ

问:我应该如何编写代码来利用这些加速?

答:您不必更改代码。编写遵循常见最佳实践的 Pythonic 代码。Faster CPython 项目针对我们观察到的常见代码模式进行了优化。

问:CPython 3.11 会使用更多内存吗?

答:也许不是。我们预计内存使用不会超过 3.10 的 20%。如上所述,这被框架对象和对象字典的内存优化所抵消。

问:我的工作量没有任何加速。为什么?

答:某些代码不会有明显的好处。如果您的代码将大部分时间花在 I/O 操作上,或者已经在 numpy 之类的 C 扩展库中进行了大部分计算,则不会有显着的加速。该项目目前最有利于纯 Python 工作负载。

此外,pyperformance 数字是几何平均值。即使在 pyperformance 基准测试中,某些基准测试速度也略有下降,而其他基准测试速度则加快了近 2 倍!

问:有 JIT 编译器吗?

答:没有。我们仍在探索其他优化。

About

Faster CPython 探索了CPython的优化。主要团队由微软资助全职工作。Pablo Galindo Salgado 也得到了 Bloomberg LP 的资助,以兼职从事该项目。最后,许多贡献者是来自社区的志愿者。

CPython 字节码更改

Deprecated

  • 现在不推荐使用链接classmethod描述符(在bpo-19072中引入)。它不能再用于包装其他描述符,例如property. 此功能的核心设计存在缺陷,并导致了许多下游问题。要“传递” a classmethod,请考虑使用__wrapped__Python 3.10 中添加的属性。(由 Raymond Hettinger 在gh-89519中提供。)

  • 字符串和字节文字中的八进制转义值大于0o377现在产生的值DeprecationWarning。在未来的 Python 版本中,它们将是 aSyntaxWarning并且最终是SyntaxError. (由 Serhiy Storchaka 在gh-81548中提供。)

  • lib2to3包和2to3工具现已弃用,可能无法解析 Python 3.10 或更高版本。见PEP 617(CPython 的新 PEG 解析器)。(由 Victor Stinner 在bpo-40360中贡献。)

  • 未记录的模块sre_compilesre_constants现在sre_parse 已弃用。(由 Serhiy Storchaka 在bpo-47152中贡献。)

  • webbrowser.MacOSX已弃用并将在 Python 3.13 中删除。它未经测试和未记录,也没有被 webbrowser 本身使用。(由 Dong-hee Na 在bpo-42255中提供。)

  • 从 aTestCaseIsolatedAsyncioTestCasetest 方法返回值的行为(默认None值除外)现在已弃用。

  • 已弃用以下unittest函数,计划在 Python 3.13 中删除:

    • unittest.findTestCases()

    • unittest.makeSuite()

    • unittest.getTestCaseNames()

    改用TestLoader方法:

    (由 Erlend E. Aasland 在bpo-5846中贡献。)

  • turtle.RawTurtle.settiltangle()Python 3.1 起已弃用,现在它会发出弃用警告,并将在 Python 3.13 中删除。改为使用 turtle.RawTurtle.tiltangle()(它之前被错误地标记为已弃用,现在更正了它的文档字符串)。(由 Hugo van Kemenade 在bpo-45837中贡献。)

  • int()to的委托__trunc__()现在已被弃用。调用 int(a)何时type(a)实现__trunc__()但未 实现__int__()__index__()现在会引发DeprecationWarning. (由 Zackery Spytz 在bpo-44977中贡献。)

  • configparser自 Python 3.2 起,以下内容已被弃用。他们的弃用警告现在已经更新,注意他们将在 Python 3.12 中删除:

    • configparser.SafeConfigParser班级_

    • configparser.ParsingError.filename财产_

    • configparser.RawConfigParser.readfp()方法_

    (由 Hugo van Kemenade 在bpo-45173中贡献。)

  • configparser.LegacyInterpolation自 Python 3.2 起已在文档字符串中弃用。它现在发出 aDeprecationWarning并将在 Python 3.13 中删除。使用configparser.BasicInterpolationconfigparser.ExtendedInterpolation代替。(由 Hugo van Kemenade 在bpo-46607中贡献。)

  • locale.getdefaultlocale()函数已弃用,将在 Python 3.13 中删除。改用locale.setlocale(), locale.getpreferredencoding(False)locale.getlocale()函数。(由 Victor Stinner 在gh-90817中提供。)

  • locale.resetlocale()函数已弃用,将在 Python 3.13 中删除。改为使用。(由 Victor Stinner 在gh-90817中提供。)locale.setlocale(locale.LC_ALL, "")

  • 和模块至少从 Python 3.6 开始就被弃用了 asynchat。他们的文档和弃用警告现已更新,注意它们将在 Python 3.12 中删除(asyncoresmtpd594)。(由 Hugo van Kemenade 在bpo- 47022 中贡献。)

  • PEP 594导致以下模块被弃用,这些模块计划在 Python 3.13 中删除:

    (由 Brett Cannon 在bpo-47061和 Victor Stinner 在 gh-68966中贡献。)

  • 现在将在未来的 Python 版本中对正则表达式中的数字组引用和组名应用更严格的规则。现在只接受 ASCII 数字序列作为数字参考。字节模式和替换字符串中的组名只能包含 ASCII 字母和数字以及下划线。目前,针对此类语法会发出弃用警告。(由 Serhiy Storchaka 在gh-91760中提供。)

  • typing.Text,它的存在只是为了提供 Python 2 和 Python 3 代码之间的兼容性支持,现在已被弃用。目前没有计划将其移除,但鼓励用户str尽可能使用它。(由 Alex Waygood 在gh-92332中提供。)

  • TypedDict现在不推荐使用用于构造类型的关键字参数语法。支持将在 Python 3.13 中删除。(由叶景琛在gh-90224 供稿。)

  • re.template()函数和相应的re.TEMPLATEre.T标志已被弃用,因为它们没有被记录在案并且缺乏明显的用途。它们将在 Python 3.13 中被移除。(由 Serhiy Storchaka 和 Miro Hrončok 在gh-92728中贡献。)

Python 3.12 中的待删除

以下 API 在早期的 Python 版本中已被弃用,并将在 Python 3.12 中删除。

Python API:

C API:

Removed

  • smtpd.MailmanProxy现在已删除,因为没有外部模块就无法使用mailman. (由 Dong-hee Na 在bpo-35800中提供。)

  • binhex模块在 Python 3.9 中已弃用,现在已删除。在 Python 3.9 中不推荐使用的以下binascii函数现在也被删除:

    • a2b_hqx(), b2a_hqx();

    • rlecode_hqx(), rledecode_hqx().

    binascii.crc_hqx()功能仍然可用。

    (由 Victor Stinner 在bpo-45085中贡献。)

  • bdist_msi在 Python 3.9 中不推荐使用的 distutils命令现在已被删除。改用bdist_wheel(车轮包)。(由 Hugo van Kemenade 在bpo-45124中贡献。)

  • 由于重大的安全问题, Python 3.9 中禁用的 的_reuse_address_参数 asyncio.loop.create_datagram_endpoint()现在已完全删除。这是因为 SO_REUSEADDRUDP 中套接字选项的行为。(由 Hugo van Kemenade 在bpo-45129中贡献。)

  • 自Python 3.9 起已不推荐使用和 的__getitem__()方法 。(由 Hugo van Kemenade 在bpo-45132中贡献。)xml.dom.pulldom.DOMEventStreamwsgiref.util.FileWrapperfileinput.FileInput

  • gettext 模块中删除了以下不推荐使用的函数和方法:lgettext()ldgettext()和 。lngettext()``ldngettext()

    Function bind_textdomain_codeset()、 methods output_charset()set_output_charset()以及函数的_codeset_ 参数translation()and install()也被删除,因为它们仅用于l*gettext()函数。(由 Dong-hee Na 和 Serhiy Storchaka 在bpo-44235中贡献。)

  • 使基于生成器的旧协程与 async/await 代码兼容的@asyncio.coroutine 装饰器。该函数自 Python 3.8 起已被弃用,最初计划在 Python 3.10 中删除。改为使用。(由 Illia Volochii 在bpo-43216中贡献。)async def

  • asyncio.coroutines.CoroWrapper用于在调试模式下包装遗留的基于生成器的协程对象。(由 Illia Volochii 在bpo-43216中贡献。)

  • 删除了已弃用split()_tkinter.TkappType. (由 Erlend E. Aasland 在bpo-38371中贡献。)

  • inspect模块中删除:

    (由 Hugo van Kemenade 在bpo-45320中贡献。)

  • 从 unittest 发现中删除命名空间包支持。它是在 Python 3.4 中引入的,但自 Python 3.7 以来已被破坏。(由 Inada Naoki 在bpo-23882中贡献。)

  • 从 中删除__class_getitem__方法pathlib.PurePath,因为在以前的版本中没有使用和错误添加。(由 Nikita Sobolev 在bpo-46483中贡献。)

  • 删除未记录的私有方法,以前在 Python 3.7 中float.__set_format__()称为。float.__setformat__()它的文档字符串说:“你可能不想使用这个函数。它的存在主要是为了在 Python 的测试套件中使用。” (由 Victor Stinner 在bpo-46852中贡献。)

  • --experimental-isolated-subinterpreters配置标志(和相应的EXPERIMENTAL_ISOLATED_SUBINTERPRETERS)已被删除。

移植到 Python 3.11

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

Python API 的变化

  • 禁止传递非concurrent.futures.ThreadPoolExecutor 执行者loop.set_default_executor()遵循 Python 3.8 中的弃用。(由 Illia Volochii 在bpo- 43234 中贡献。)

  • open(), io.open(),codecs.open()并且 在文件模式下fileinput.FileInput不再接受'U'(“通用换行符”)。此标志自 Python 3.3 起已弃用。在 Python 3 中,当文件以文本模式打开时,默认使用“通用换行符”。的 换行参数open()控制通用换行的工作方式。(由 Victor Stinner 在bpo-37330中贡献。)

  • pdb模块现在读取带有编码的.pdbrc配置文件。'utf-8'(由 Srinivas Reddy Thatiparthy 在bpo-41137中贡献。)

  • calendar:如果未指定语言环境,则calendar.LocaleTextCalendarand calendar.LocaleHTMLCalendar类现在使用 locale.getlocale(),而不是 using 。locale.getdefaultlocale()(由 Victor Stinner 在bpo-46659中贡献。)

  • 全局内联标志(例如(?i))现在只能在正则表达式的开头使用。自 Python 3.6 以来,不推荐在表达式开头使用它们。(由 Serhiy Storchaka 在bpo-47066中贡献。)

  • re模块:修复了一些长期存在的错误,在极少数情况下,捕获组可能会得到错误的结果。所以结果可能与以前不同。(由马林在bpo-35859中贡献。)

  • 的_人口_参数random.sample()必须是一个序列。不再支持将集合自动转换为列表。如果样本大小大于总体大小,ValueError则提高 a。(由 Raymond Hettinger 在bpo-40465中贡献。)

  • ast.ASTcompile()现在在提供给和其他相关功能时验证节点位置 。如果检测到无效位置,ValueError将引发 a。(由 Pablo Galindo 在gh-93351中提供)

  • tp_dictoffset应被视为只写。可以设置为向VM描述C扩展类,但阅读时应视为无意义。改为获取指向对象字典调用的指针 PyObject_GenericGetDict()

构建更改

  • 构建 Python 现在需要 C11 编译器。不需要可选的 C11 功能。(由 Victor Stinner 在bpo-46656中贡献。)

  • 构建 Python 现在需要支持 IEEE 754 浮点数。(由 Victor Stinner 在bpo-46917中贡献。)

  • 现在可以使用 ThinLTO 选项通过--with-lto=thin. (由 Dong-hee Na 和 Brett Holman 在bpo-44340中贡献。)

  • libpython 不再与 libcrypt 链接。(由 Mike Gilbert 在bpo-45433中贡献。)

  • 构建 Python 现在需要一个<math.h>提供以下函数的 C99 头文件:copysign(), hypot(), isfinite(), isinf(), isnan(), round(). (由 Victor Stinner 在bpo-45440中贡献。)

  • 构建 Python 现在需要一个<math.h>提供NAN常量或__builtin_nan()内置函数的 C99 头文件。(由 Victor Stinner 在bpo-46640中贡献。)

  • 构建 Python 现在需要支持浮点非数字 (NaN):删除Py_NO_NAN宏。(由 Victor Stinner 在bpo-46656中贡献。)

  • 现在可以禁用对象结构的空闲列表。一个新的配置 选项--without-freelists可用于禁用除空元组单例之外的所有空闲列表。(由 Christian Heimes 在bpo-45522中贡献。)

  • Modules/SetupModules/makesetup进行了改进和捆绑。扩展模块现在可以通过makesetup. 除了一些测试模块之外的所有模块都可以静态链接到主二进制文件或库中。(由 Brett Cannon 和 Christian Heimes 在bpo-45548bpo-45570bpo-45571bpo-43974 中贡献。)

  • configure现在可以检测大多数 stdlib 扩展模块的构建依赖项、编译器标志和链接器标志。libffi、libnsl、libsqlite3、zlib、bzip2、liblzma、libcrypt、Tcl/Tk 和 uuid 标志由pkg-config(如果可用)检测。tkinter现在需要pkg-config命令来检测 Tcl/Tk 头文件和库的开发设置。(由 Christian Heimes 和 Erlend Egeberg Aasland 在 bpo-45847bpo-45747bpo-45763 中贡献。)

    备注

    使用环境变量TCLTK_CFLAGSTCLTK_LIBS手动指定 Tcl/Tk 头文件和库的位置。配置选项和已被删除--with-tcltk-includes--with-tcltk-libs

    在 RHEL 7 和 CentOS 7 上,开发包不提供tcl.pctk.pc,使用TCLTK_LIBS="-ltk8.5 -ltkstub8.5 -ltcl8.5". 该目录Misc/rhel7包含.pc如何使用 RHEL 7 和 CentOS 7 的 Tcl/Tk 和 OpenSSL 构建 Python 的文件和说明。

  • CPython 现在有PEP 11第 3 层支持交叉编译到 WebAssembly 平台wasm32-unknown-emscripten(浏览器中的 Python)。这项工作受到了Pyodide等先前工作的启发。Emscripten 提供了有限的 POSIX API 子集。与网络、进程、线程、信号、mmap 和用户/组相关的 Python 标准库功能和模块不可用或不起作用。(由 Christian Heimes 和 Ethan Smith 在gh-84461 中贡献,在 gh-95085推广)

  • CPython 现在有PEP 11第 3 层支持交叉编译到 WebAssembly 平台wasm32-unknown-wasi(WebAssembly 系统接口)。与 Emscripten 一样,WASI 上只有 Python 标准库的一个子集。(由 Christian Heimes 在gh-90473中贡献,在gh-95085中推广)

  • CPython 现在将默认使用 30 位数字来int 实现 Python。以前,默认是在带有 的平台上使用 30 位数字,否则使用 15 位数字。仍然可以通过配置脚本的选项或(对于 Windows)中的 变量显式请求使用 15 位数字 ,但将来可能会删除此选项。(由 Mark Dickinson 在 bpo-45569中贡献。)SIZEOF_VOID_P >= 8``--enable-big-digits``PYLONG_BITS_IN_DIGIT``PC/pyconfig.h

  • tkinter软件包现在需要 Tcl/Tk 版本 8.5.12 或更高版本。(由 Serhiy Storchaka 在bpo-46996中贡献。)

C API 更改

新功能

移植到 Python 3.11

  • PyErr_SetExcInfo()不再使用typeand参数,解释器现在从异常实例(参数)traceback 派生这些值。value该函数仍然窃取所有三个参数的引用。(由 Irit Katriel 在bpo-45711中贡献。)

  • PyErr_GetExcInfo()现在 从异常实例(字段)派生结果的type和字段。(由 Irit Katriel 在bpo-45711中贡献。)traceback``value

  • _frozen有一个新is_package字段来指示冻结的模块是否是一个包。以前,该字段中的负值size是指标。现在只有非负值用于size. (由 Kumar Aditya 在bpo-46608中贡献。)

  • _PyFrameEvalFunction()现在将_PyInterpreterFrame* 其作为第二个参数,而不是PyFrameObject*. 看PEP 523有关如何使用此函数指针类型的更多详细信息。

  • PyCode_New()现在PyCode_NewWithPosOnlyArgs()采取一个额外的exception_table论点。如果可能的话,应该避免使用这些函数。获取自定义代码对象:使用编译器创建代码对象,然后使用该replace方法获取修改后的版本。

  • PyCodeObject不再具有co_codeco_varnamesco_cellvars字段co_freevars。相反,使用 、 和PyCode_GetCode()分别PyCode_GetVarnames()通过 C API 访问它们。(由 Brandt Bucher 在bpo-46841和 Ken Jin 在gh-92154gh-94936 中贡献。)PyCode_GetCellvars()PyCode_GetFreevars()

  • 旧的垃圾桶宏 ( Py_TRASHCAN_SAFE_BEGIN/ Py_TRASHCAN_SAFE_END) 现在已弃用。它们应该被新的宏 Py_TRASHCAN_BEGINPy_TRASHCAN_END.

    具有旧宏的 tp_dealloc 函数,例如:

    static void
    mytype_dealloc(mytype *p)
    {
        PyObject_GC_UnTrack(p);
        Py_TRASHCAN_SAFE_BEGIN(p);
        ...
        Py_TRASHCAN_SAFE_END
    }
    
    

    应迁移到新的宏,如下所示:

    static void
    mytype_dealloc(mytype *p)
    {
        PyObject_GC_UnTrack(p);
        Py_TRASHCAN_BEGIN(p, mytype_dealloc)
        ...
        Py_TRASHCAN_END
    }
    
    

    请注意,Py_TRASHCAN_BEGIN第二个参数应该是它所在的释放函数。

    为了在同一个代码库中支持较旧的 Python 版本,您可以定义以下宏并在整个代码中使用它们(信用:这些是从mypy代码库中复制的):

    #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 8
    #  define CPy_TRASHCAN_BEGIN(op, dealloc) Py_TRASHCAN_BEGIN(op, dealloc)
    #  define CPy_TRASHCAN_END(op) Py_TRASHCAN_END
    #else
    #  define CPy_TRASHCAN_BEGIN(op, dealloc) Py_TRASHCAN_SAFE_BEGIN(op)
    #  define CPy_TRASHCAN_END(op) Py_TRASHCAN_SAFE_END(op)
    #endif
    
    
  • 现在,如果使用设置的标志定义类型但没有遍历函数 ( ) ,则该PyType_Ready()函数会引发错误。(由 Victor Stinner 在bpo-44263中贡献。)Py_TPFLAGS_HAVE_GCPyTypeObject.tp_traverse

  • 带有标志的堆类型Py_TPFLAGS_IMMUTABLETYPE现在可以继承PEP 590向量调用协议。以前,这仅适用于 静态类型。(由 Erlend E. Aasland 在bpo-43908中贡献)

  • 由于Py_TYPE()更改为内联静态函数, 因此必须替换为 :查看函数(自 Python 3.9 起可用)。为了向后兼容,可以使用此宏:Py_TYPE(obj) = new_type``Py_SET_TYPE(obj, new_type)Py_SET_TYPE()

    #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE)
    static inline void _Py_SET_TYPE(PyObject *ob, PyTypeObject *type)
    { ob->ob_type = type; }
    #define Py_SET_TYPE(ob, type) _Py_SET_TYPE((PyObject*)(ob), type)
    #endif
    
    

    (由 Victor Stinner 在bpo-39573中贡献。)

  • 由于Py_SIZE()更改为内联静态函数, 因此必须替换为 :查看函数(自 Python 3.9 起可用)。为了向后兼容,可以使用此宏:Py_SIZE(obj) = new_size``Py_SET_SIZE(obj, new_size)Py_SET_SIZE()

    #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE)
    static inline void _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)
    { ob->ob_size = size; }
    #define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size)
    #endif
    
    

    (由 Victor Stinner 在bpo-39573中贡献。)

  • <Python.h>不再包含头文件, 和<stdlib.h><stdio.h>宏设置 为(Python 3.11) 或更高版本时。C 扩展应该在. (由 Victor Stinner 在bpo-45434中贡献。)<errno.h>``<string.h>``Py_LIMITED_API``0x030b0000``#include <Python.h>

  • 不受限制的 API 文件、cellobject.hclassobject.hcode.hcontext.hfuncobject.h已移至目录。此外,头文件已被删除。这些文件不能直接包含,因为它们已经包含在:Include Files中。如果它们已被直接包含,请考虑改为包含。(由 Victor Stinner 在bpo-35134中贡献。)genobject.h``longintrepr.h``Include/cpython``eval.h``Python.hPython.h

  • PyUnicode_CHECK_INTERNED()宏已从有限的 C API 中排除。它在那里永远无法使用,因为它使用了有限的 C API 中不可用的内部结构。(由 Victor Stinner 在bpo-46007中贡献。)

  • 现在可以直接使用以下框架功能和类型 ,不再需要添加 :#include <Python.h>``#include <frameobject.h>

    (由 Victor Stinner 在gh-93937中提供。)

  • PyFrameObject结构成员已从公共 C API 中删除。

    虽然文档指出这些PyFrameObject字段随时可能发生变化,但它们已经稳定了很长时间,并被用于几个流行的扩展中。

    在 Python 3.11 中,frame 结构被重新组织以允许性能优化。一些字段被完全删除,因为它们是旧实现的细节。

    PyFrameObject领域:

    Python 框架对象现在是延迟创建的。一个副作用是 f_back不能直接访问该成员,因为它的值现在也是延迟计算的。PyFrame_GetBack()必须改为调用该函数。

    f_locals直接访问的调试器_必须_调用 PyFrame_GetLocals()。他们不再需要调用 PyFrame_FastToLocalsWithError()or PyFrame_LocalsToFast(),事实上他们不应该调用那些函数。框架的必要更新现在由虚拟机管理。

    PyFrame_GetCode()在 Python 3.8 和更早版本上定义的代码:

    #if PY_VERSION_HEX < 0x030900B1
    static inline PyCodeObject* PyFrame_GetCode(PyFrameObject *frame)
    {
        Py_INCREF(frame->f_code);
        return frame->f_code;
    }
    #endif
    
    

    PyFrame_GetBack()在 Python 3.8 和更早版本上定义的代码:

    #if PY_VERSION_HEX < 0x030900B1
    static inline PyFrameObject* PyFrame_GetBack(PyFrameObject *frame)
    {
        Py_XINCREF(frame->f_back);
        return frame->f_back;
    }
    #endif
    
    

    或者使用pythoncapi_compat 项目在较旧的 Python 版本上获取这两个函数。

  • PyThreadState结构成员的变化:

    PyThreadState_GetFrame()在 Python 3.8 和更早版本上定义的代码:

    #if PY_VERSION_HEX < 0x030900B1
    static inline PyFrameObject* PyThreadState_GetFrame(PyThreadState *tstate)
    {
        Py_XINCREF(tstate->frame);
        return tstate->frame;
    }
    #endif
    
    

    代码定义PyThreadState_EnterTracing()PyThreadState_LeaveTracing()Python 3.10 及更早版本:

    #if PY_VERSION_HEX < 0x030B00A2
    static inline void PyThreadState_EnterTracing(PyThreadState *tstate)
    {
        tstate->tracing++;
    #if PY_VERSION_HEX >= 0x030A00A1
        tstate->cframe->use_tracing = 0;
    #else
        tstate->use_tracing = 0;
    #endif
    }
    
    static inline void PyThreadState_LeaveTracing(PyThreadState *tstate)
    {
        int use_tracing = (tstate->c_tracefunc != NULL || tstate->c_profilefunc != NULL);
        tstate->tracing--;
    #if PY_VERSION_HEX >= 0x030A00A1
        tstate->cframe->use_tracing = use_tracing;
    #else
        tstate->use_tracing = use_tracing;
    #endif
    }
    #endif
    
    

    或者使用pythoncapi_compat 项目在旧的 Python 函数上获取这些函数。

  • 鼓励分销商使用优化的 Blake2 库libb2构建 Python 。

  • PyConfig.module_search_paths_set字段现在必须设置为 1 才能用于PyConfig.module_search_paths初始化 sys.path。否则,初始化将重新计算路径并替换添加到module_search_paths.

  • PyConfig_Read()不再计算初始搜索路径,并且不会将任何值填充到PyConfig.module_search_paths. 要计算默认路径然后修改它们,完成初始化并使用作为 Python 列表对象PySys_GetObject() 检索并直接修改它。sys.path

Deprecated

Removed

  • PyFrame_BlockSetup()PyFrame_BlockPop()已被删除。(由 Mark Shannon 在bpo-40222中贡献。)

  • errno使用变量删除以下数学宏:

    • Py_ADJUST_ERANGE1()

    • Py_ADJUST_ERANGE2()

    • Py_OVERFLOWED()

    • Py_SET_ERANGE_IF_OVERFLOW()

    • Py_SET_ERRNO_ON_MATH_ERROR()

    (由 Victor Stinner 在bpo-45412中贡献。)

  • 删除Py_UNICODE_COPY()Py_UNICODE_FILL()宏,自 Python 3.3 起已弃用。使用PyUnicode_CopyCharacters()memcpy()wchar_t*字符串)和PyUnicode_Fill()函数代替。(由 Victor Stinner 在bpo-41123中贡献。)

  • 删除pystrhex.h头文件。它只包含私有函数。C 扩展应该只包含主<Python.h>头文件。(由 Victor Stinner 在bpo-45434中贡献。)

  • 删除Py_FORCE_DOUBLE()宏。它被 Py_IS_INFINITY()宏使用。(由 Victor Stinner 在bpo-45440中贡献。)

  • Py_LIMITED_API 以下项目在定义时不再可用:

    这些不是受限 API的一部分。

    (由 Victor Stinner 在bpo-45474中贡献。)

  • PyWeakref_GET_OBJECT()从受限的 C API 中排除。由于PyWeakReference结构在有限的 C API 中是不透明的,因此它从未起作用。(由 Victor Stinner 在bpo-35134中贡献。)

  • 删除PyHeapType_GET_MEMBERS()宏。它被错误地暴露在公共 C API 中,只能由 Python 内部使用。请改用该PyTypeObject.tp_members成员。(由 Victor Stinner 在bpo-40170中贡献。)

  • 删除HAVE_PY_SET_53BIT_PRECISION宏(移至内部 C API)。(由 Victor Stinner 在bpo-45412中贡献。)

  • 删除Py_UNICODE编码器 API,因为它们自 Python 3.3 以来已被弃用,很少使用并且相对于推荐的替代方案效率低下。

    删除的功能是:

    • PyUnicode_Encode()

    • PyUnicode_EncodeASCII()

    • PyUnicode_EncodeLatin1()

    • PyUnicode_EncodeUTF7()

    • PyUnicode_EncodeUTF8()

    • PyUnicode_EncodeUTF16()

    • PyUnicode_EncodeUTF32()

    • PyUnicode_EncodeUnicodeEscape()

    • PyUnicode_EncodeRawUnicodeEscape()

    • PyUnicode_EncodeCharmap()

    • PyUnicode_TranslateCharmap()

    • PyUnicode_EncodeDecimal()

    • PyUnicode_TransformDecimalToASCII()

    PEP 624了解详情和 迁移指导。(由 Inada Naoki 在bpo-44029中提供。)

0

评论区