Python 3.10 新變化

編輯:

Pablo Galindo Salgado

本文件解釋了 Python 3.10 相對於 3.9 的新功能。Python 3.10 於 2021 年 10 月 4 日釋出。有關完整詳細資訊,請參閱 變更日誌

摘要 – 釋出亮點

新語法功能

  • PEP 634, 結構化模式匹配:規範

  • PEP 635, 結構化模式匹配:動機和原理

  • PEP 636, 結構化模式匹配:教程

  • bpo-12782, 括號包圍的上下文管理器現已正式允許。

標準庫新功能

  • PEP 618, 向 zip 新增可選的長度檢查。

直譯器的改進

  • PEP 626, 為除錯和其他工具提供精確的行號。

新的型別特性

  • PEP 604, 允許使用 X | Y 形式書寫聯合型別

  • PEP 612, 引數規範變數

  • PEP 613, 顯式類型別名

  • PEP 647, 使用者定義的型別守衛

重要的棄用、移除或限制

  • PEP 644, 要求 OpenSSL 1.1.1 或更高版本

  • PEP 632, 棄用 distutils 模組。

  • PEP 623, 棄用 PyUnicodeObject 中的 wstr 成員併為此做準備。

  • PEP 624, 移除 Py_UNICODE 編碼器 API

  • PEP 597, 新增可選的 EncodingWarning

新功能

括號包圍的上下文管理器

現在支援使用包含括號來跨越多行延續上下文管理器。這允許以與之前匯入語句類似的方式格式化多行中的長上下文管理器集合。例如,以下所有示例現在都有效

with (CtxManager() as example):
    ...

with (
    CtxManager1(),
    CtxManager2()
):
    ...

with (CtxManager1() as example,
      CtxManager2()):
    ...

with (CtxManager1(),
      CtxManager2() as example):
    ...

with (
    CtxManager1() as example1,
    CtxManager2() as example2
):
    ...

在包含組的末尾使用尾隨逗號也是可能的

with (
    CtxManager1() as example1,
    CtxManager2() as example2,
    CtxManager3() as example3,
):
    ...

這種新語法利用了新解析器的非 LL(1) 功能。有關更多詳細資訊,請參閱 PEP 617

(由 Guido van Rossum、Pablo Galindo 和 Lysandros Nikolaou 在 bpo-12782bpo-40334 中貢獻。)

更好的錯誤訊息

SyntaxErrors

當解析包含未閉合括號或方括號的程式碼時,直譯器現在會包含未閉合方括號或括號的位置,而不是顯示 *SyntaxError: unexpected EOF while parsing* 或指向某個不正確的位置。例如,考慮以下程式碼(注意未閉合的‘{‘)

expected = {9: 1, 18: 2, 19: 2, 27: 3, 28: 3, 29: 3, 36: 4, 37: 4,
            38: 4, 39: 4, 45: 5, 46: 5, 47: 5, 48: 5, 49: 5, 54: 6,
some_other_code = foo()

舊版本直譯器報告了令人困惑的語法錯誤位置

File "example.py", line 3
    some_other_code = foo()
                    ^
SyntaxError: invalid syntax

但在 Python 3.10 中,會發出更具資訊性的錯誤

File "example.py", line 1
    expected = {9: 1, 18: 2, 19: 2, 27: 3, 28: 3, 29: 3, 36: 4, 37: 4,
               ^
SyntaxError: '{' was never closed

類似地,涉及未閉合字串字面量(單引號和三引號)的錯誤現在會指向字串的開頭,而不是報告 EOF/EOL。

這些改進受到了 PyPy 直譯器先前工作的啟發。

(由 Pablo Galindo 在 bpo-42864 和 Batuhan Taskaya 在 bpo-40176 中貢獻。)

由直譯器引發的 SyntaxError 異常現在將突出顯示構成語法錯誤的表示式的完整錯誤範圍,而不僅僅是檢測到問題的位置。這樣,在 Python 3.10 之前,而不是顯示:

>>> foo(x, z for z in range(10), t, w)
  File "<stdin>", line 1
    foo(x, z for z in range(10), t, w)
           ^
SyntaxError: Generator expression must be parenthesized

現在 Python 3.10 將顯示異常為:

>>> foo(x, z for z in range(10), t, w)
  File "<stdin>", line 1
    foo(x, z for z in range(10), t, w)
           ^^^^^^^^^^^^^^^^^^^^
SyntaxError: Generator expression must be parenthesized

此改進由 Pablo Galindo 在 bpo-43914 中貢獻。

已包含大量新的 SyntaxError 異常的專用訊息。其中一些最值得注意的是:

  • 塊前缺少 ‘:’

    >>> if rocket.position > event_horizon
      File "<stdin>", line 1
        if rocket.position > event_horizon
                                          ^
    SyntaxError: expected ':'
    

    (由 Pablo Galindo 在 bpo-42997 中貢獻。)

  • 推導式目標中缺少括號的元組

    >>> {x,y for x,y in zip('abcd', '1234')}
      File "<stdin>", line 1
        {x,y for x,y in zip('abcd', '1234')}
         ^
    SyntaxError: did you forget parentheses around the comprehension target?
    

    (由 Pablo Galindo 在 bpo-43017 中貢獻。)

  • 集合字面量中以及表示式之間缺少逗號

    >>> items = {
    ... x: 1,
    ... y: 2
    ... z: 3,
      File "<stdin>", line 3
        y: 2
           ^
    SyntaxError: invalid syntax. Perhaps you forgot a comma?
    

    (由 Pablo Galindo 在 bpo-43822 中貢獻。)

  • 多個異常型別未用括號括起來

    >>> try:
    ...     build_dyson_sphere()
    ... except NotEnoughScienceError, NotEnoughResourcesError:
      File "<stdin>", line 3
        except NotEnoughScienceError, NotEnoughResourcesError:
               ^
    SyntaxError: multiple exception types must be parenthesized
    

    (由 Pablo Galindo 在 bpo-43149 中貢獻。)

  • 字典字面量中缺少 ‘:’ 和值

    >>> values = {
    ... x: 1,
    ... y: 2,
    ... z:
    ... }
      File "<stdin>", line 4
        z:
         ^
    SyntaxError: expression expected after dictionary key and ':'
    
    >>> values = {x:1, y:2, z w:3}
      File "<stdin>", line 1
        values = {x:1, y:2, z w:3}
                            ^
    SyntaxError: ':' expected after dictionary key
    

    (由 Pablo Galindo 在 bpo-43823 中貢獻。)

  • 不帶 except 或 finally 塊的 try 塊

    >>> try:
    ...     x = 2
    ... something = 3
      File "<stdin>", line 3
        something  = 3
        ^^^^^^^^^
    SyntaxError: expected 'except' or 'finally' block
    

    (由 Pablo Galindo 在 bpo-44305 中貢獻。)

  • 在比較中使用 ‘=’ 而不是 ‘==’

    >>> if rocket.position = event_horizon:
      File "<stdin>", line 1
        if rocket.position = event_horizon:
                           ^
    SyntaxError: cannot assign to attribute here. Maybe you meant '==' instead of '='?
    

    (由 Pablo Galindo 在 bpo-43797 中貢獻。)

  • 在 f-string 中使用 ‘*’

    >>> f"Black holes {*all_black_holes} and revelations"
      File "<stdin>", line 1
        (*all_black_holes)
         ^
    SyntaxError: f-string: cannot use starred expression here
    

    (由 Pablo Galindo 在 bpo-41064 中貢獻。)

IndentationErrors

許多 IndentationError 異常現在提供了更多關於期望縮排的塊型別的上下文,包括語句的位置

>>> def foo():
...    if lel:
...    x = 2
  File "<stdin>", line 3
    x = 2
    ^
IndentationError: expected an indented block after 'if' statement in line 2

AttributeErrors

列印 AttributeError 時,PyErr_Display() 將提供與引發異常的物件中相似的屬性名稱的建議

>>> collections.namedtoplo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'collections' has no attribute 'namedtoplo'. Did you mean: namedtuple?

(由 Pablo Galindo 在 bpo-38530 中貢獻。)

警告

請注意,如果未呼叫 PyErr_Display() 來顯示錯誤,這可能發生在某些 REPL(如 IPython)中,這種情況將無效。這是某些 REPL(如 IPython)中常見的情況。

NameErrors

列印直譯器引發的 NameError 時,PyErr_Display() 將提供與引發異常的函式中相似的變數名稱的建議

>>> schwarzschild_black_hole = None
>>> schwarschild_black_hole
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'schwarschild_black_hole' is not defined. Did you mean: schwarzschild_black_hole?

(由 Pablo Galindo 在 bpo-38530 中貢獻。)

警告

請注意,如果未呼叫 PyErr_Display() 來顯示錯誤,這可能發生在某些 REPL(如 IPython)中,這種情況將無效。這是某些 REPL(如 IPython)中常見的情況。

PEP 626:為除錯和其他工具提供精確的行號

PEP 626 為除錯、分析和覆蓋率工具帶來了更精確和可靠的行號。將為執行的所有程式碼行生成正確的行號的跟蹤事件,並且僅為已執行的程式碼行生成。

幀物件的 f_lineno 屬性將始終包含預期的行號。

程式碼物件的 co_lnotab 屬性已被棄用,並將在 3.12 中移除。需要從偏移量轉換為行號的程式碼應改用新的 co_lines() 方法。

PEP 634:結構化模式匹配

結構化模式匹配已新增,形式為 *match 語句* 和 *case 語句*,其中包含具有關聯操作的模式。模式包括序列、對映、基本資料型別以及類例項。模式匹配使程式能夠從複雜資料型別中提取資訊,根據資料結構進行分支,並根據不同形式的資料應用特定操作。

語法和操作

模式匹配的一般語法是

match subject:
    case <pattern_1>:
        <action_1>
    case <pattern_2>:
        <action_2>
    case <pattern_3>:
        <action_3>
    case _:
        <action_wildcard>

match 語句接受一個表示式,並將其值與按順序提供的、由一個或多個 case 塊組成的模式進行比較。具體來說,模式匹配透過以下方式工作:

  1. 使用具有型別和形狀的資料(*subject*)

  2. 在 *match* 語句中計算 *subject*

  3. 從上到下將 subject 與 *case* 語句中的每個模式進行比較,直到確認匹配。

  4. 執行與已確認匹配的模式關聯的操作

  5. 如果未確認完全匹配,則使用最後一個 case,即萬用字元 *_*(如果提供了)。如果未確認完全匹配且不存在萬用字元 case,則整個 match 塊將不執行任何操作。

宣告式方法

讀者可能透過將主體(資料物件)與字面量(模式)匹配的簡單示例,在 C、Java 或 JavaScript(以及許多其他語言)的 switch 語句中瞭解模式匹配。通常,switch 語句用於將物件/表示式與包含字面量的 case 語句進行比較。

在 Scala 和 Elixir 等語言中可以找到更強大的模式匹配示例。透過結構化模式匹配,方法是“宣告式”的,並明確說明資料匹配的條件(模式)。

雖然可以使用使用巢狀“if”語句的“命令式”一系列指令來完成類似於結構化模式匹配的任務,但它不如“宣告式”方法清晰。相反,“宣告式”方法說明了匹配要滿足的條件,並且透過其顯式模式更具可讀性。雖然結構化模式匹配可以用於其最簡單的形式,即在 case 語句中將變數與字面量進行比較,但它對 Python 的真正價值在於其對 subject 的型別和形狀的處理。

簡單模式:匹配字面量

讓我們看一個模式匹配最簡單的形式的例子:一個值(subject)與幾個字面量(patterns)進行匹配。在下面的示例中,*status* 是 match 語句的主題。模式是每個 case 語句,其中字面量代表請求狀態碼。在匹配後執行與 case 關聯的操作

def http_error(status):
    match status:
        case 400:
            return "Bad request"
        case 404:
            return "Not found"
        case 418:
            return "I'm a teapot"
        case _:
            return "Something's wrong with the internet"

如果將狀態碼 418 傳遞給上面的函式,將返回“I’m a teapot”。如果將狀態碼 500 傳遞給上面的函式,將匹配帶有 *_* 的 case 語句作為萬用字元,並返回“Something’s wrong with the internet”。請注意最後一個塊:變數名 *_* 用作*萬用字元*,並確保 subject 始終匹配。*_* 的使用是可選的。

您可以使用 *|*(“或”)將多個字面量組合在一個模式中

case 401 | 403 | 404:
    return "Not allowed"
無萬用字元的行為

如果我們透過刪除最後一個 case 塊來修改上面的示例,示例將變成

def http_error(status):
    match status:
        case 400:
            return "Bad request"
        case 404:
            return "Not found"
        case 418:
            return "I'm a teapot"

如果不使用 *_* 在 case 語句中,則可能不存在匹配。如果不存在匹配,則行為是無操作。例如,如果傳遞狀態碼 500,則會發生無操作。

帶字面量和變數的模式

模式可以看起來像解包賦值,並且可以使用模式來繫結變數。在此示例中,資料點可以解包為其 x 座標和 y 座標

# point is an (x, y) tuple
match point:
    case (0, 0):
        print("Origin")
    case (0, y):
        print(f"Y={y}")
    case (x, 0):
        print(f"X={x}")
    case (x, y):
        print(f"X={x}, Y={y}")
    case _:
        raise ValueError("Not a point")

第一個模式包含兩個字面量 *(0, 0)*,可以將其視為上面字面量模式的擴充套件。接下來的兩個模式結合了一個字面量和一個變數,該變數*繫結*了 subject(*point*)中的值。第四個模式捕獲了兩個值,這使得它在概念上類似於解包賦值 *(x, y) = point*。

模式和類

如果您使用類來組織資料,則可以使用類名後跟類似於建構函式的引數列表作為模式。此模式能夠將例項屬性捕獲到變數中

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

def location(point):
    match point:
        case Point(x=0, y=0):
            print("Origin is the point's location.")
        case Point(x=0, y=y):
            print(f"Y={y} and the point is on the y-axis.")
        case Point(x=x, y=0):
            print(f"X={x} and the point is on the x-axis.")
        case Point():
            print("The point is located somewhere else on the plane.")
        case _:
            print("Not a point")
帶位置引數的模式

您可以將位置引數與提供屬性順序的某些內建類(例如 dataclasses)一起使用。您還可以透過在類中設定 *__match_args__* 特殊屬性來為模式中的屬性定義特定位置。如果它設定為(“x”,“y”),則以下模式都是等效的(並且都將 *y* 屬性繫結到 *var* 變數)

Point(1, var)
Point(1, y=var)
Point(x=1, y=var)
Point(y=var, x=1)

巢狀模式

模式可以任意巢狀。例如,如果我們的資料是點的簡短列表,則可以這樣匹配

match points:
    case []:
        print("No points in the list.")
    case [Point(0, 0)]:
        print("The origin is the only point in the list.")
    case [Point(x, y)]:
        print(f"A single point {x}, {y} is in the list.")
    case [Point(0, y1), Point(0, y2)]:
        print(f"Two points on the Y axis at {y1}, {y2} are in the list.")
    case _:
        print("Something else is found in the list.")

複雜模式和萬用字元

到目前為止,示例在最後一個 case 語句中僅使用了 *_*。萬用字元可以在更復雜的模式中使用,例如 *('error', code, _)*。例如

match test_variable:
    case ('warning', code, 40):
        print("A warning has been received.")
    case ('error', code, _):
        print(f"An error {code} occurred.")

在上面的情況下,*test_variable* 將匹配 ('error', code, 100) 和 ('error', code, 800)。

Guard

我們可以向模式新增一個 *if* 子句,稱為“guard”。如果 guard 為 false,*match* 將繼續嘗試下一個 case 塊。請注意,值捕獲發生在 guard 評估之前

match point:
    case Point(x, y) if x == y:
        print(f"The point is located on the diagonal Y=X at {x}.")
    case Point(x, y):
        print(f"Point is not on the diagonal.")

其他主要功能

其他幾個主要功能

  • 與解包賦值類似,元組和列表模式的含義完全相同,並且實際上匹配任意序列。技術上,subject 必須是序列。因此,一個重要的例外是模式不匹配迭代器。此外,為了防止常見錯誤,序列模式不匹配字串。

  • 序列模式支援萬用字元:*[*x*, *y*, ***rest**]* 和 *(*x*, *y*, ***rest**)* 的工作方式類似於解包賦值中的萬用字元。* 後面的名稱也可以是 *_*,因此 *(*x*, *y*, ***_*)* 匹配至少有兩個項的序列,而不繫結其餘項。

  • 對映模式:*{"bandwidth": b, "latency": l}* 從 dict 中捕獲 *"bandwidth"* 和 *"latency"* 的值。與序列模式不同,額外的鍵會被忽略。也支援萬用字元 ***rest**。(*但 **_* 是多餘的,因此不允許*)。

  • 可以使用 *as* 關鍵字捕獲子模式

    case (Point(x1, y1), Point(x2, y2) as p2): ...
    

    這將像您期望的那樣繫結 x1、y1、x2、y2(不帶 *as* 子句),並將 p2 繫結到 subject 的第二個項的整個部分。

  • 大多數字面量透過相等性進行比較。但是,單例 *True*、*False* 和 *None* 透過身份進行比較。

  • 命名常量可以在模式中使用。這些命名常量必須是點分名稱,以防止常量被解釋為捕獲變數

    from enum import Enum
    class Color(Enum):
        RED = 0
        GREEN = 1
        BLUE = 2
    
    color = Color.GREEN
    match color:
        case Color.RED:
            print("I see red!")
        case Color.GREEN:
            print("Grass is green")
        case Color.BLUE:
            print("I'm feeling the blues :(")
    

有關完整規範,請參閱 PEP 634。動機和原理在 PEP 635 中,更長的教程在 PEP 636 中。

可選的 EncodingWarningencoding="locale" 選項

TextIOWrapperopen() 的預設編碼是平臺和區域設定相關的。由於 UTF-8 在大多數 Unix 平臺上使用,因此在開啟 UTF-8 檔案(例如 JSON、YAML、TOML、Markdown)時省略 *encoding* 選項是一個非常常見的錯誤。例如

# BUG: "rb" mode or encoding="utf-8" should be used.
with open("data.json") as f:
    data = json.load(f)

為了查詢這種型別的錯誤,添加了一個可選的 EncodingWarning。當 *sys.flags.warn_default_encoding* 為 true 且使用特定於區域設定的預設編碼時,會發出此警告。

添加了 *-X warn_default_encoding* 選項和 PYTHONWARNDEFAULTENCODING 來啟用警告。

有關更多資訊,請參閱 文字編碼

其他語言更改

  • *int* 型別有一個新方法 *int.bit_count()*,它返回給定整數的二進位制展開中 1 的數量,也稱為族計數。(由 Niklas Fiekas 在 bpo-29882 中貢獻。)

  • *dict.keys()*、*dict.values()* 和 *dict.items()* 返回的檢視現在都有一個 *mapping* 屬性,該屬性提供一個包裝原始字典的 *types.MappingProxyType* 物件。(由 Dennis Sweeney 在 bpo-40890 中貢獻。)

  • PEP 618:*zip()* 函式現在有一個可選的 *strict* 標誌,用於要求所有可迭代物件具有相同的長度。

  • 接受整數引數的內建和擴充套件函式不再接受 *Decimal*、*Fraction* 和其他只能透過損失(例如,具有 *__int__* 方法但沒有 *__index__* 方法)轉換為整數的物件。(由 Serhiy Storchaka 在 bpo-37999 中貢獻。)

  • 如果 *object.__ipow__()* 返回 *NotImplemented*,則該運算子將正確地回退到 *object.__pow__()* 和 *object.__rpow__()*,如預期。(由 Alex Shkop 在 bpo-38302 中貢獻。)

  • 賦值表示式現在可以在不帶括號的情況下用於集合字面量和集合推導式,以及在序列索引(但不是切片)中使用。

  • 函式具有新的 *__builtins__* 屬性,用於在函式執行時查詢內建符號,而不是查詢 *__globals__['__builtins__']*。如果存在,則該屬性從 *__globals__["__builtins__"]* 初始化,否則從當前內建項初始化。(由 Mark Shannon 在 bpo-42990 中貢獻。)

  • 添加了兩個新的內建函式 — *aiter()* 和 *anext()*,分別作為 *iter()* 和 *next()* 的非同步對應項。(由 Joshua Bronson、Daniel Pope 和 Justin Wang 在 bpo-31861 中貢獻。)

  • 靜態方法(*@staticmethod*)和類方法(*@classmethod*)現在繼承方法屬性(*__module__*、*__name__*、*__qualname__*、*__doc__*、*__annotations__*),並具有新的 *__wrapped__* 屬性。此外,靜態方法現在可以像常規函式一樣呼叫。(由 Victor Stinner 在 bpo-43682 中貢獻。)

  • 對於複雜目標(PEP 526 定義的 *simple name* 目標之外的所有內容),使用 *from __future__ import annotations* 時,註解不再產生任何執行時效果。(由 Batuhan Taskaya 在 bpo-42737 中貢獻。)

  • 類和模組物件現在按需惰性建立空註解字典。為了向後相容,註解字典儲存在物件的 *__dict__* 中。這改進了處理 *__annotations__* 的最佳實踐;有關更多資訊,請參閱 註解最佳實踐。(由 Larry Hastings 在 bpo-43901 中貢獻。)

  • 在 *from __future__ import annotations* 下,包含 *yield*、*yield from*、*await* 或命名錶達式的註解現已被禁止,因為它們會產生副作用。(由 Batuhan Taskaya 在 bpo-42725 中貢獻。)

  • 未繫結變數、*super()* 和其他可能改變符號表處理的表示式(如註解)現在在 *from __future__ import annotations* 下被渲染為無效。(由 Batuhan Taskaya 在 bpo-42725 中貢獻。)

  • *float* 型別和 *decimal.Decimal* 型別的 NaN 值的雜湊現在取決於物件標識。以前,它們總是雜湊為 0,即使 NaN 值彼此不相等。這在建立包含多個 NaN 的字典和集合時,由於過度的雜湊衝突,可能導致二次方執行時間行為。(由 Raymond Hettinger 在 bpo-43475 中貢獻。)

  • 刪除 *__debug__* 常量時將引發 *SyntaxError*(而不是 *NameError*)。(由 Donghee Na 在 bpo-45000 中貢獻。)

  • *SyntaxError* 異常現在具有 *end_lineno* 和 *end_offset* 屬性。如果未確定,它們將為 *None*。(由 Pablo Galindo 在 bpo-43914 中貢獻。)

新模組

  • 無。

改進的模組

asyncio

添加了 missing *asyncio.loop.connect_accepted_socket()* 方法。(由 Alex Grönholm 在 bpo-41332 中貢獻。)

argparse

argparse 幫助中將誤導性短語“optional arguments”替換為“options”。如果某些測試依賴於精確的輸出匹配,則可能需要進行調整。(由 Raymond Hettinger 在 bpo-9694 中貢獻。)

array

*array.array* 的 *index()* 方法現在具有可選的 *start* 和 *stop* 引數。(由 Anders Lorentsen 和 Zackery Spytz 在 bpo-31956 中貢獻。)

asynchat, asyncore, smtpd

自 Python 3.6 起,這些模組已在其模組文件中被標記為已棄用。現在已為這三個模組添加了匯入時 *DeprecationWarning*。

base64

添加了 *base64.b32hexencode()* 和 *base64.b32hexdecode()* 以支援帶擴充套件十六進位制字母的 Base32 編碼。

bdb

添加了 *clearBreakpoints()* 方法以重置所有設定的斷點。(由 Irit Katriel 在 bpo-24160 中貢獻。)

bisect

在 *bisect* 模組的 API 中添加了提供 *key* 函式的可能性。(由 Raymond Hettinger 在 bpo-4356 中貢獻。)

codecs

添加了 *codecs.unregister()* 函式以登出編解碼器搜尋函式。(由 Hai Shi 在 bpo-41842 中貢獻。)

collections.abc

用於 *collections.abc.Callable* 的*引數化泛型*的 *__args__* 現在與 *typing.Callable* 一致。*collections.abc.Callable* 泛型現在會展平型別引數,類似於 *typing.Callable* 目前所做的。這意味著 *collections.abc.Callable[[int, str], str]* 將具有 *(int, str, str)* 的 *__args__*;以前這是 *([int, str], str)*。為了允許此更改,*types.GenericAlias* 現在可以被子類化,並且在下標 *collections.abc.Callable* 型別時將返回子類。請注意,在 Python 3.9 中可能已默默透過的無效的 *collections.abc.Callable* 引數化形式可能會引發 *TypeError*。(由 Ken Jin 在 bpo-42195 中貢獻。)

contextlib

添加了 *contextlib.aclosing()* 上下文管理器,以安全地關閉非同步生成器和代表非同步釋放資源的物件。(由 Joongi Kim 和 John Belmonte 在 bpo-41229 中貢獻。)

為 *contextlib.nullcontext()* 添加了非同步上下文管理器支援。(由 Tom Gringauz 在 bpo-41543 中貢獻。)

添加了 *AsyncContextDecorator*,用於支援將非同步上下文管理器用作裝飾器。

curses

ncurses 6.1 中新增的擴充套件顏色函式將被 *curses.color_content()*、*curses.init_color()*、*curses.init_pair()* 和 *curses.pair_content()* 透明使用。一個新函式 *curses.has_extended_color_support()* 指示底層 curses 庫是否提供擴充套件顏色支援。(由 Jeffrey Kintscher 和 Hans Petter Jansson 在 bpo-36982 中貢獻。)

如果底層 curses 庫提供,*curses* 模組現在將公開 *BUTTON5_* 常量。(由 Zackery Spytz 在 bpo-39273 中貢獻。)

dataclasses

__slots__

在 *dataclasses.dataclass()* 裝飾器中添加了 *slots* 引數。(由 Yurii Karabas 在 bpo-42269 中貢獻)

僅關鍵字引數欄位

dataclasses 現在支援在生成的 __init__ 方法中僅透過關鍵字引數指定的欄位。有多種方法可以指定僅關鍵字引數欄位。

您可以宣告所有欄位都是僅關鍵字引數

from dataclasses import dataclass

@dataclass(kw_only=True)
class Birthday:
    name: str
    birthday: datetime.date

生成的 __init__ 方法的 *name* 和 *birthday* 都是僅關鍵字引數。

您可以按欄位指定僅關鍵字引數

from dataclasses import dataclass, field

@dataclass
class Birthday:
    name: str
    birthday: datetime.date = field(kw_only=True)

這裡只有 *birthday* 是僅關鍵字引數。如果您為單個欄位設定了 *kw_only*,請注意由於僅關鍵字引數需要跟在非僅關鍵字引數之後,因此存在重新排序欄位的規則。有關詳細資訊,請參閱完整的 dataclasses 文件。

您還可以指定 KW_ONLY 標記之後的所有欄位都是僅關鍵字引數。這可能是最常見的用法

from dataclasses import dataclass, KW_ONLY

@dataclass
class Point:
    x: float
    y: float
    _: KW_ONLY
    z: float = 0.0
    t: float = 0.0

這裡,*z* 和 *t* 是僅關鍵字引數,而 *x* 和 *y* 不是。(由 Eric V. Smith 在 bpo-43532 中貢獻。)

distutils

整個 *distutils* 包已被棄用,將在 Python 3.12 中移除。其用於指定包構建的功能已被第三方包 *setuptools* 和 *packaging* 完全取代,並且大多數其他常用 API 在標準庫的其他地方(如 *platform*、*shutil*、*subprocess* 或 *sysconfig*)都有提供。沒有計劃從 *distutils* 遷移任何其他功能,並且正在使用其他功能的應用程式應計劃製作程式碼的私有副本。有關討論,請參閱 PEP 632

Python 3.8 中已棄用的 *bdist_wininst* 命令已被移除。現在建議使用 *bdist_wheel* 命令在 Windows 上分發二進位制包。(由 Victor Stinner 在 bpo-42802 中貢獻。)

doctest

當模組未定義 *__loader__* 時,將回退到 *__spec__.loader*。(由 Brett Cannon 在 bpo-42133 中貢獻。)

encodings

*encodings.normalize_encoding()* 現在會忽略非 ASCII 字元。(由 Hai Shi 在 bpo-39337 中貢獻。)

enum

*Enum* 的 *__repr__()* 現在返回 *enum_name.member_name*,而 *__str__()* 現在返回 *member_name*。作為模組常量可用的標準庫列舉具有 *module_name.member_name* 的 *repr()*。(由 Ethan Furman 在 bpo-40066 中貢獻。)

添加了 *enum.StrEnum*,用於所有成員都是字串的列舉。(由 Ethan Furman 在 bpo-41816 中貢獻。)

fileinput

在 *fileinput.input()* 和 *fileinput.FileInput* 中添加了 *encoding* 和 *errors* 引數。(由 Inada Naoki 在 bpo-43712 中貢獻。)

當 *mode* 為“r”且檔案已壓縮時,*fileinput.hook_compressed()* 現在返回 *TextIOWrapper* 物件,就像未壓縮檔案一樣。(由 Inada Naoki 在 bpo-5758 中貢獻。)

faulthandler

*faulthandler* 模組現在可以檢測垃圾回收期間是否發生致命錯誤。(由 Victor Stinner 在 bpo-44466 中貢獻。)

gc

為 *gc.get_objects()*、*gc.get_referrers()* 和 *gc.get_referents()* 添加了審計掛鉤。(由 Pablo Galindo 在 bpo-43439 中貢獻。)

glob

在 *glob.glob()* 和 *glob.iglob()* 中添加了 *root_dir* 和 *dir_fd* 引數,它們允許指定搜尋的根目錄。(由 Serhiy Storchaka 在 bpo-38144 中貢獻。)

hashlib

hashlib 模組需要 OpenSSL 1.1.1 或更高版本。(由 Christian Heimes 在 PEP 644bpo-43669 中貢獻。)

hashlib 模組對 OpenSSL 3.0.0 具有初步支援。(由 Christian Heimes 在 bpo-38820 和其他問題中貢獻。)

純 Python 回退的 *hashlib.pbkdf2_hmac()* 已棄用。未來 PBKDF2-HMAC 僅在 Python 已使用 OpenSSL 支援構建時可用。(由 Christian Heimes 在 bpo-43880 中貢獻。)

hmac

hmac 模組現在內部使用 OpenSSL 的 HMAC 實現。(由 Christian Heimes 在 bpo-40645 中貢獻。)

IDLE 和 idlelib

讓 IDLE 在啟動時(不帶“-n”選項)呼叫 sys.excepthook()。之前使用者自定義的鉤子會被忽略。(由 Ken Hilton 在 bpo-43008 中貢獻)

重新組織了設定對話方塊。將“常規”選項卡拆分為“視窗”和“Shell/編輯”選項卡。將擴充套件幫助選單的幫助源移至“擴充套件”選項卡。為新選項騰出空間並縮短對話方塊。後者使對話方塊更適合小螢幕。(由 Terry Jan Reedy 在 bpo-40468 中貢獻)將縮排空格設定從“字型”選項卡移至新的“視窗”選項卡。(由 Mark Roseman 和 Terry Jan Reedy 在 bpo-33962 中貢獻)

上述更改已向後移植到 3.9 的維護版本。

添加了 Shell 側邊欄。將主提示符(“>>>”)移至側邊欄。將輔助提示符(“...”)新增到側邊欄。左鍵單擊和可選的拖動可以選擇一行或多行文字,類似於編輯器行號側邊欄。在選擇文字行後右鍵單擊會顯示一個上下文選單,其中包含“複製帶提示符”選項。此選項將側邊欄中的提示符與選定文字中的行合併。此選項也出現在文字的上下文選單中。(由 Tal Einat 在 bpo-37903 中貢獻)

使用空格而非製表符縮排互動式程式碼。這使得互動式程式碼條目“看起來正確”。實現這一點是新增 shell 側邊欄的主要動機。(由 Terry Jan Reedy 在 bpo-37892 中貢獻)

突出顯示新的 軟關鍵字 matchcase_ 在模式匹配語句中。但是,此突出顯示並非完美,在某些罕見情況下會出現錯誤,包括 case 模式中的某些 _。(由 Tal Einat 在 bpo-44010 中貢獻)

在 3.10 維護版本中新增。

.pyi 檔案應用語法高亮。(由 Alex Waygood 和 Terry Jan Reedy 在 bpo-45447 中貢獻。)

儲存 Shell 輸入和輸出時包含提示符。(由 Terry Jan Reedy 在 gh-95191 中貢獻)

importlib.metadata

importlib_metadata 4.6 功能對等(歷史)。

importlib.metadata entry points 現在透過新的 importlib.metadata.EntryPoints 類,提供更友好的按組和名稱選擇入口點的體驗。有關棄用和用法的更多資訊,請參閱文件中的相容性說明。

添加了 importlib.metadata.packages_distributions(),用於將頂層 Python 模組和包解析到它們的 importlib.metadata.Distribution

inspect

當模組未定義 *__loader__* 時,將回退到 *__spec__.loader*。(由 Brett Cannon 在 bpo-42133 中貢獻。)

新增 inspect.get_annotations(),可安全地計算物件上定義的註解。它能處理各種型別物件的註解訪問的怪癖,並且對它所檢查的物件所做的假設非常少。 inspect.get_annotations() 還可以正確地取消字串化註解。 inspect.get_annotations() 現在被認為是訪問任何 Python 物件上定義的註解字典的最佳實踐;有關處理註解最佳實踐的更多資訊,請參閱 註解最佳實踐。相關地,inspect.signature()inspect.Signature.from_callable()inspect.Signature.from_function() 現在會呼叫 inspect.get_annotations() 來檢索註解。這意味著 inspect.signature()inspect.Signature.from_callable() 現在也可以取消字串化註解。(由 Larry Hastings 在 bpo-43817 中貢獻)

itertools

新增 itertools.pairwise()。(由 Raymond Hettinger 在 bpo-38200 中貢獻)

linecache

當模組未定義 *__loader__* 時,將回退到 *__spec__.loader*。(由 Brett Cannon 在 bpo-42133 中貢獻。)

os

新增 os.cpu_count() 對 VxWorks RTOS 的支援。(由 Peixing Xin 在 bpo-41440 中貢獻)

添加了一個新函式 os.eventfd() 和相關輔助函式,用於包裝 Linux 上的 eventfd2 系統呼叫。(由 Christian Heimes 在 bpo-41001 中貢獻)

新增 os.splice(),它允許在兩個檔案描述符之間移動資料,而無需在核心地址空間和使用者地址空間之間複製,其中一個檔案描述符必須引用一個管道。(由 Pablo Galindo 在 bpo-41625 中貢獻)

為 macOS 添加了 O_EVTONLYO_FSYNCO_SYMLINKO_NOFOLLOW_ANY。(由 Donghee Na 在 bpo-43106 中貢獻)

os.path

os.path.realpath() 現在接受一個僅限關鍵字的 `strict` 引數。當設定為 True 時,如果路徑不存在或遇到符號連結迴圈,則會引發 OSError。(由 Barney Gale 在 bpo-43757 中貢獻)

pathlib

PurePath.parents 添加了切片支援。(由 Joshua Cannon 在 bpo-35498 中貢獻)

PurePath.parents 添加了負索引支援。(由 Yaroslav Pankovych 在 bpo-21041 中貢獻)

添加了 Path.hardlink_to 方法,它取代了 link_to()。新方法具有與 symlink_to() 相同的引數順序。(由 Barney Gale 在 bpo-39950 中貢獻)

pathlib.Path.stat()chmod() 現在接受一個僅限關鍵字的 `follow_symlinks` 引數,以與 os 模組中的相應函式保持一致。(由 Barney Gale 在 bpo-39906 中貢獻)

platform

新增 platform.freedesktop_os_release(),用於從 freedesktop.org os-release 標準檔案檢索作業系統標識。(由 Christian Heimes 在 bpo-28468 中貢獻)

pprint

pprint.pprint() 現在接受一個新的 `underscore_numbers` 關鍵字引數。(由 sblondon 在 bpo-42914 中貢獻)

pprint 現在可以漂亮地列印 dataclasses.dataclass 例項。(由 Lewis Gaul 在 bpo-43080 中貢獻)

py_compile

py_compile 的命令列介面添加了 --quiet 選項。(由 Gregory Schevchenko 在 bpo-38731 中貢獻)

pyclbr

pyclbr.readmodule()pyclbr.readmodule_ex() 返回的樹中的 `Function` 和 `Class` 物件添加了 `end_lineno` 屬性。它與現有的(開始)`lineno` 匹配。(由 Aviral Srivastava 在 bpo-38307 中貢獻)

shelve

在建立 shelf 時,shelve 模組現在預設使用 pickle.DEFAULT_PROTOCOL 而不是 pickle 協議 3。(由 Zackery Spytz 在 bpo-34204 中貢獻)

statistics

添加了 `covariance()`、Pearson 的 `correlation()` 和簡單的 `linear_regression()` 函式。(由 Tymoteusz Wołodźko 在 bpo-38490 中貢獻)

site

當模組未定義 *__loader__* 時,將回退到 *__spec__.loader*。(由 Brett Cannon 在 bpo-42133 中貢獻。)

socket

異常 socket.timeout 現在是 TimeoutError 的別名。(由 Christian Heimes 在 bpo-42413 中貢獻)

新增建立 MPTCP 套接字(使用 `IPPROTO_MPTCP`)的選項(由 Rui Cunha 在 bpo-43571 中貢獻)

新增 `IP_RECVTOS` 選項以接收服務型別(ToS)或 DSCP/ECN 欄位(由 Georg Sauthoff 在 bpo-44077 中貢獻)

ssl

ssl 模組需要 OpenSSL 1.1.1 或更高版本。(由 Christian Heimes 在 PEP 644bpo-43669 中貢獻)

ssl 模組對 OpenSSL 3.0.0 提供了初步支援,並增加了新選項 OP_IGNORE_UNEXPECTED_EOF。(由 Christian Heimes 在 bpo-38820bpo-43794bpo-43788bpo-43791bpo-43799bpo-43920bpo-43789bpo-43811 中貢獻)

已棄用的函式和已棄用的常量的使用現在會導致 DeprecationWarningssl.SSLContext.options 預設設定了 OP_NO_SSLv2OP_NO_SSLv3,因此無法警告再次設定標誌。 棄用部分 包含已棄用功能的列表。(由 Christian Heimes 在 bpo-43880 中貢獻)

ssl 模組現在具有更安全/更強的預設設定。預設情況下停用不具有前向保密性或 SHA-1 MAC 的密碼。安全級別 2 禁止使用安全性低於 112 位的弱 RSA、DH 和 ECC 金鑰。 SSLContext 預設使用最低協議版本 TLS 1.2。設定基於 Hynek Schlawack 的研究。(由 Christian Heimes 在 bpo-43998 中貢獻)

已棄用的協議 SSL 3.0、TLS 1.0 和 TLS 1.1 不再受官方支援。Python 不會主動阻止它們。但是,OpenSSL 的構建選項、發行版配置、供應商補丁和密碼套件可能會阻止成功的握手。

ssl.get_server_certificate() 函式添加了 `timeout` 引數。(由 Zackery Spytz 在 bpo-31870 中貢獻)

ssl 模組使用堆型別和多階段初始化。(由 Christian Heimes 在 bpo-42333 中貢獻)

添加了一個新的驗證標誌 VERIFY_X509_PARTIAL_CHAIN。(由 l0x 在 bpo-40849 中貢獻)

sqlite3

為 `connect()`、`enable_load_extension()` 和 `load_extension()` 添加了審計事件。(由 Erlend E. Aasland 在 bpo-43762 中貢獻)

sys

添加了 `sys.orig_argv` 屬性:傳遞給 Python 可執行檔案的原始命令列引數列表。(由 Victor Stinner 在 bpo-23427 中貢獻)

添加了 `sys.stdlib_module_names`,包含標準庫模組名稱的列表。(由 Victor Stinner 在 bpo-42955 中貢獻)

_thread

`_thread.interrupt_main()` 現在接受一個可選的訊號編號來模擬(預設值仍為 signal.SIGINT)。(由 Antoine Pitrou 在 bpo-43356 中貢獻)

threading

添加了 `threading.gettrace()` 和 `threading.getprofile()`,用於檢索由 `threading.settrace()` 和 `threading.setprofile()` 分別設定的函式。(由 Mario Corchero 在 bpo-42251 中貢獻)

添加了 `threading.__excepthook__`,允許在 `threading.excepthook()` 被設定為損壞或不同的值時檢索其原始值。(由 Mario Corchero 在 bpo-42308 中貢獻)

traceback

`format_exception()`、`format_exception_only()` 和 `print_exception()` 函式現在可以將異常物件作為位置引數傳遞。(由 Zackery Spytz 和 Matthias Bussonnier 在 bpo-26389 中貢獻)

types

重新引入了 `types.EllipsisType`、`types.NoneType` 和 `types.NotImplementedType` 類,提供了一套新的、可被型別檢查器輕鬆解釋的型別。(由 Bas van Beek 在 bpo-41810 中貢獻)

typing

對於主要更改,請參閱 與型別提示相關的新功能

`typing.Literal` 的行為已更改,以符合 PEP 586,並匹配 PEP 中指定的靜態型別檢查器的行為。

  1. `Literal` 現在會去重引數。

  2. `Literal` 物件之間的相等比較現在與順序無關。

  3. `Literal` 比較現在會尊重型別。例如,`Literal[0] == Literal[False]` 以前評估為 `True`。現在是 `False`。為了支援此更改,內部使用的型別快取現在支援區分型別。

  4. `Literal` 物件在相等比較期間如果其任何引數不是 可雜湊 的,現在將引發 `TypeError` 異常。請注意,使用不可雜湊引數宣告 `Literal` 不會引發錯誤。

    >>> from typing import Literal
    >>> Literal[{0}]
    >>> Literal[{0}] == Literal[{False}]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unhashable type: 'set'
    

(由 Yurii Karabas 在 bpo-42345 中貢獻)

添加了新函式 `typing.is_typeddict()`,用於內省一個註解是否為 `typing.TypedDict`。(由 Patrick Reader 在 bpo-41792 中貢獻)

僅聲明瞭資料變數的 `typing.Protocol` 的子類,在與 `isinstance` 檢查時將引發 `TypeError`,除非它們被 `@runtime_checkable()` 裝飾。以前,這些檢查會靜默透過。如果使用者想要執行時協議,他們應該用 `@runtime_checkable()` 裝飾器裝飾他們的子類。(由 Yurii Karabas 在 bpo-38908 中貢獻)

從 `typing.io` 和 `typing.re` 子模組匯入現在會發出 `DeprecationWarning`。這些子模組自 Python 3.8 起已棄用,將在未來版本的 Python 中移除。屬於這些子模組的任何內容都應直接從 typing 匯入。(由 Sebastian Rittau 在 bpo-38291 中貢獻)

unittest

在 `unittest.TestCase` 中添加了新方法 `assertNoLogs()`,以補充現有的 `assertLogs()`。(由 Kit Yan Choi 在 bpo-39385 中貢獻)

urllib.parse

Python 版本早於 Python 3.10 時,在 urllib.parse.parse_qs()urllib.parse.parse_qsl() 中允許使用 `;` 和 `&` 作為查詢引數分隔符。出於安全考慮,併為了符合新的 W3C 建議,此行為已更改為僅允許單個分隔符鍵,預設為 `&`。此更改也影響 `cgi.parse()` 和 `cgi.parse_multipart()`,因為它們在內部使用了受影響的函式。有關更多詳細資訊,請參閱各自的文件。(由 Adam Goldschmidt、Senthil Kumaran 和 Ken Jin 在 bpo-42967 中貢獻)

URL 部分中的換行符或製表符的存在可能導致某些形式的攻擊。遵循 WHATWG 規範(更新了 RFC 3986),ASCII 換行符 `\n`、`\r` 和製表符 `\t` 字元將從 URL 中被解析器移除,以防止此類攻擊。移除字元由新的模組級變數 `urllib.parse._UNSAFE_URL_BYTES_TO_REMOVE` 控制。(參見 gh-88048

xml

在 `xml.sax.handler` 模組中添加了 `LexicalHandler` 類。(由 Jonathan Gossage 和 Zackery Spytz 在 bpo-35018 中貢獻)

zipimport

添加了與 PEP 451 相關的函式:`zipimport.zipimporter.find_spec()`、`zipimport.zipimporter.create_module()` 和 `zipimport.zipimporter.exec_module()`。(由 Brett Cannon 在 bpo-42131 中貢獻)

添加了 `zipimport.zipimporter.invalidate_caches()` 方法。(由 Desmond Cheong 在 bpo-14678 中貢獻)

最佳化

  • 建構函式 `str()`、`bytes()` 和 `bytearray()` 現在更快(對於小型物件來說約快 30-40%)。(由 Serhiy Storchaka 在 bpo-41334 中貢獻)

  • `runpy` 模組現在匯入的模組更少。`python3 -m module-name` 命令的啟動時間平均快 1.4 倍。在 Linux 上,`python3 -I -m module-name` 在 Python 3.9 中匯入 69 個模組,而在 Python 3.10 中僅匯入 51 個模組(減少 18 個)。(由 Victor Stinner 在 bpo-41006bpo-41718 中貢獻)

  • `LOAD_ATTR` 指令現在使用新的“每操作碼快取”機制。它現在對於常規屬性來說速度提高了約 36%,對於 slot 來說速度提高了 44%。(由 Pablo Galindo 和 Yury Selivanov 在 bpo-42093 和 Guido van Rossum 在 bpo-42927 中貢獻,基於最初在 PyPy 和 MicroPython 中實現的想法)

  • 使用 `--enable-optimizations` 構建 Python 時,現在會在編譯和連結行中新增 `-fno-semantic-interposition`。這使用 `gcc` 構建使用 `--enable-shared` 的 Python 直譯器速度提高了高達 30%。有關更多詳細資訊,請參閱 這篇文章。(由 Victor Stinner 和 Pablo Galindo 在 bpo-38980 中貢獻)

  • 為 `bz2` / `lzma` / `zlib` 模組使用了新的輸出緩衝區管理程式碼,併為 `_compression.DecompressReader` 類添加了 `.readall()` 函式。bz2 解壓縮現在快 1.09 到 1.17 倍,lzma 解壓縮快 1.20 到 1.32 倍,`GzipFile.read(-1)` 快 1.11 到 1.18 倍。(由 Ma Lin 貢獻,Gregory P. Smith 審閱,在 bpo-41486

  • 在使用字串化註解時,函式的註解字典不再在函式建立時建立。取而代之的是,它們被儲存為字串元組,然後在需要時由函式物件惰性地將其轉換為註解字典。此最佳化將定義帶註解函式的 CPU 時間減少了一半。(由 Yurii Karabas 和 Inada Naoki 在 bpo-42202 中貢獻)

  • 子字串搜尋函式,如 `str1 in str2` 和 `str2.find(str1)`,現在有時會使用 Crochemore & Perrin 的“Two-Way”字串搜尋演算法,以避免在長字串上出現二次行為。(由 Dennis Sweeney 在 bpo-41972 中貢獻)

  • 對 `_PyType_Lookup()` 添加了微最佳化,以在快取命中等常見情況下提高型別屬性查詢效能。這使得直譯器平均快 1.04 倍。(由 Dino Viehland 在 bpo-43452 中貢獻)

  • 以下內建函式現在支援更快的 PEP 590 vectorcall 呼叫約定:`map()`、`filter()`、`reversed()`、`bool()` 和 `float()`。(由 Donghee Na 和 Jeroen Demeyer 在 bpo-43575bpo-43287bpo-41922bpo-41873bpo-41870 中貢獻)

  • `BZ2File` 的效能透過移除內部 `RLock` 得到改善。這使得 `BZ2File` 在多執行緒同時讀寫時不像其在 `gzip` 和 `lzma` 中的等效類那樣是執行緒安全的。 (由 Inada Naoki 在 bpo-43785 中貢獻)

已棄用

  • 當前 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` 中的一個,則會發出棄用警告。在未來的版本中,它將變為語法警告,最後變為語法錯誤。(由 Serhiy Storchaka 在 bpo-43833 中貢獻)

  • 從本版本開始,將開始清理舊的匯入語義,這些語義是為了相容 Python 2.7 而保留的。具體來說,`find_loader()`/`find_module()`(已被 `importlib.abc.MetaPathFinder.find_spec()` 取代)、`load_module()`(已被 `importlib.abc.Loader.exec_module()` 取代)、`module_repr()`(匯入系統會為您處理)、`__package__` 屬性(已被 `__spec__.parent` 取代)、`__loader__` 屬性(已被 `__spec__.loader` 取代)和 `__cached__` 屬性(已被 `__spec__.cached` 取代)將緩慢移除(以及 `importlib` 中的其他類和方法)。`ImportWarning` 和/或 `DeprecationWarning` 將適時發出,以幫助在過渡期間識別需要更新的程式碼。

  • 整個 `distutils` 名稱空間已被棄用,將在 Python 3.12 中移除。有關更多資訊,請參閱 模組更改 部分。

  • 向 `random.randrange()` 傳遞非整數引數已被棄用。`ValueError` 已被棄用,取而代之的是 `TypeError`。(由 Serhiy Storchaka 和 Raymond Hettinger 在 bpo-37319 中貢獻)

  • 自 Python 3.6 起,`importlib` 的各種 `load_module()` 方法已被記錄為棄用,但現在也會觸發 `DeprecationWarning`。請使用 `exec_module()`。(由 Brett Cannon 在 bpo-26131 中貢獻)

  • `zipimport.zipimporter.load_module()` 已棄用,優先使用 `exec_module()`。(由 Brett Cannon 在 bpo-26131 中貢獻)

  • 匯入系統對 `load_module()` 的使用現在會觸發 `ImportWarning`,因為 `exec_module()` 更受歡迎。(由 Brett Cannon 在 bpo-26131 中貢獻)

  • 匯入系統對 `importlib.abc.MetaPathFinder.find_module()` 和 `importlib.abc.PathEntryFinder.find_module()` 的使用現在會觸發 `ImportWarning`,因為分別更受歡迎的是 `importlib.abc.MetaPathFinder.find_spec()` 和 `importlib.abc.PathEntryFinder.find_spec()`。您可以使用 `importlib.util.spec_from_loader()` 來幫助遷移。(由 Brett Cannon 在 bpo-42134 中貢獻)

  • 匯入系統對 `importlib.abc.PathEntryFinder.find_loader()` 的使用現在會觸發 `ImportWarning`,因為更受歡迎的是 `importlib.abc.PathEntryFinder.find_spec()`。您可以使用 `importlib.util.spec_from_loader()` 來幫助遷移。(由 Brett Cannon 在 bpo-43672 中貢獻)

  • 各種 `importlib.abc.MetaPathFinder.find_module()` 的實現( `importlib.machinery.BuiltinImporter.find_module()`、`importlib.machinery.FrozenImporter.find_module()`、`importlib.machinery.WindowsRegistryFinder.find_module()`、`importlib.machinery.PathFinder.find_module()`、`importlib.abc.MetaPathFinder.find_module()`)、`importlib.abc.PathEntryFinder.find_module()`( `importlib.machinery.FileFinder.find_module()` )和 `importlib.abc.PathEntryFinder.find_loader()`( `importlib.machinery.FileFinder.find_loader()` )現在會引發 `DeprecationWarning`,並計劃在 Python 3.12 中移除(以前它們在 Python 3.4 中被記錄為棄用)。(由 Brett Cannon 在 bpo-42135 中貢獻)

  • `importlib.abc.Finder` 已棄用(包括其唯一的 `find_module()` 方法)。`importlib.abc.MetaPathFinder` 和 `importlib.abc.PathEntryFinder` 不再繼承自該類。使用者應根據需要繼承這兩個類之一。(由 Brett Cannon 在 bpo-42135 中貢獻)

  • `imp`、`importlib.find_loader()`、`importlib.util.set_package_wrapper()`、`importlib.util.set_loader_wrapper()`、`importlib.util.module_for_loader()`、`pkgutil.ImpImporter` 和 `pkgutil.ImpLoader` 的棄用已被更新為將 Python 3.12 列為計劃移除版本(它們在以前的 Python 版本中就開始發出 `DeprecationWarning`)。(由 Brett Cannon 在 bpo-43720 中貢獻)

  • 匯入系統現在在使用 `__spec__` 屬性之前,會回退到使用 `module_repr()` 來獲取模組的 `__repr__()` 方法。`module_repr()` 的使用計劃在 Python 3.12 中移除。(由 Brett Cannon 在 bpo-42137 中貢獻)

  • `importlib.abc.Loader.module_repr()`、`importlib.machinery.FrozenLoader.module_repr()` 和 `importlib.machinery.BuiltinLoader.module_repr()` 已棄用,並計劃在 Python 3.12 中移除。(由 Brett Cannon 在 bpo-42136 中貢獻)

  • `sqlite3.OptimizedUnicode` 自 Python 3.3 起已不再被文件化且已過時,當時它被設為 `str` 的別名。現在它已被棄用,計劃在 Python 3.12 中移除。(由 Erlend E. Aasland 在 bpo-42264 中貢獻)

  • 未文件化的內建函式 `sqlite3.enable_shared_cache` 已被棄用,計劃在 Python 3.12 中移除。SQLite3 文件強烈不建議使用它。有關更多詳細資訊,請參閱 SQLite3 文件。如果必須使用共享快取,請使用 `cache=shared` 查詢引數以 URI 模式開啟資料庫。(由 Erlend E. Aasland 在 bpo-24464 中貢獻)

  • 以下 `threading` 方法現已棄用

    (由 Jelle Zijlstra 在 gh-87889 中貢獻)

  • `pathlib.Path.link_to()` 已棄用,並計劃在 Python 3.12 中移除。請使用 `pathlib.Path.hardlink_to()`。(由 Barney Gale 在 bpo-39950 中貢獻)

  • `cgi.log()` 已棄用,並計劃在 Python 3.12 中移除。(由 Inada Naoki 在 bpo-41139 中貢獻)

  • 以下 `ssl` 功能自 Python 3.6、Python 3.7 或 OpenSSL 1.1.0 起已棄用,並將在 3.11 中移除

    • `OP_NO_SSLv2`、`OP_NO_SSLv3`、`OP_NO_TLSv1`、`OP_NO_TLSv1_1`、`OP_NO_TLSv1_2` 和 `OP_NO_TLSv1_3` 被 `ssl.SSLContext.minimum_version` 和 `ssl.SSLContext.maximum_version` 取代。

    • `PROTOCOL_SSLv2`、`PROTOCOL_SSLv3`、`PROTOCOL_SSLv23`、`PROTOCOL_TLSv1`、`PROTOCOL_TLSv1_1`、`PROTOCOL_TLSv1_2` 和 `PROTOCOL_TLS` 已棄用,優先使用 `ssl.PROTOCOL_TLS_CLIENT` 和 `ssl.PROTOCOL_TLS_SERVER`

    • `wrap_socket()` 被 `ssl.SSLContext.wrap_socket()` 取代

    • match_hostname()

    • `RAND_pseudo_bytes()`、`RAND_egd()`

    • NPN 功能,如 `ssl.SSLSocket.selected_npn_protocol()` 和 `ssl.SSLContext.set_npn_protocols()`,被 ALPN 取代。

  • 執行緒除錯(`PYTHONTHREADDEBUG` 環境變數)已在 Python 3.10 中棄用,並將在 Python 3.12 中移除。此功能需要 Python 的 除錯版本。(由 Victor Stinner 在 bpo-44584 中貢獻)

  • typing.iotyping.re 子模組匯入現在會發出 DeprecationWarning。這些子模組將在未來的 Python 版本中被移除。屬於這些子模組的任何內容都應直接從 typing 匯入。(由 Sebastian Rittau 在 bpo-38291 中貢獻。)

已移除

  • 移除了 complex 類的特殊方法 __int__, __float__, __floordiv__, __mod__, __divmod__, __rfloordiv__, __rmod____rdivmod__。它們總是引發 TypeError。(由 Serhiy Storchaka 在 bpo-41974 中貢獻。)

  • 私有且未文件化的 _markupbase 模組中的 ParserBase.error() 方法已被移除。html.parser.HTMLParserParserBase 的唯一子類,並且其 error() 實現已在 Python 3.5 中移除。(由 Berker Peksag 在 bpo-31844 中貢獻。)

  • 移除了 unicodedata.ucnhash_CAPI 屬性,它是一個內部 PyCapsule 物件。相關的私有 _PyUnicode_Name_CAPI 結構已移至內部 C API。(由 Victor Stinner 在 bpo-42157 中貢獻。)

  • 移除了 parser 模組,該模組在 3.9 版本中因切換到新的 PEG 解析器而被棄用,以及所有僅供舊解析器使用的 C 原始碼和標頭檔案,包括 node.h, parser.h, graminit.hgrammar.h

  • 移除了在 3.9 版本中因切換到新的 PEG 解析器而被棄用的公共 C API 函式 PyParser_SimpleParseStringFlags, PyParser_SimpleParseStringFlagsFilename, PyParser_SimpleParseFileFlagsPyNode_Compile

  • 移除了 formatter 模組,該模組在 Python 3.4 中被棄用。它有些過時,使用很少,且未經測試。它原定於 Python 3.6 中移除,但此類移除推遲到 Python 2.7 EOL 之後。現有使用者應將他們使用的類複製到他們的程式碼中。(由 Donghee Na 和 Terry J. Reedy 在 bpo-42299 中貢獻。)

  • 移除了 PyModule_GetWarningsModule() 函式,由於 _warnings 模組在 2.6 中已轉換為內建模組,因此該函式已無用。(由 Hai Shi 在 bpo-42599 中貢獻。)

  • collections 模組中移除了到 Collections Abstract Base Classes 的已棄用別名。(由 Victor Stinner 在 bpo-37324 中貢獻。)

  • 繼 Python 3.8 中棄用之後,loop 引數已從 asyncio 的大部分 高層 API 中移除。此更改的動機是多方面的:

    1. 這簡化了高層 API。

    2. 自 Python 3.7 起,高層 API 中的函式一直隱式獲取當前執行緒執行的事件迴圈。在大多數正常用例中,無需將事件迴圈傳遞給 API。

    3. 事件迴圈傳遞容易出錯,尤其是在處理不同執行緒中執行的迴圈時。

    請注意,低層 API 仍接受 loop。有關如何替換現有程式碼的示例,請參閱 Python API 的更改

    (由 Yurii Karabas, Andrew Svetlov, Yury Selivanov 和 Kyle Stanley 在 bpo-42392 中貢獻。)

移植到 Python 3.10

本節列出了前面描述過的變更以及其他可能需要修改程式碼的 bug 修復。

Python 語法中的更改

  • 當編譯之前有效的語法,並且數字字面量後面緊跟關鍵字時(例如 0in x),現在會發出棄用警告。在未來的版本中,它將被改為語法警告,最終成為語法錯誤。要消除警告並使程式碼與未來版本相容,只需在數字字面量和後面的關鍵字之間新增一個空格即可。(由 Serhiy Storchaka 在 bpo-43833 中貢獻。)

Python API 的變化

  • traceback 模組中的 format_exception()format_exception_only()print_exception() 函式的 etype 引數已重新命名為 exc。(由 Zackery Spytz 和 Matthias Bussonnier 在 bpo-26389 中貢獻。)

  • atexit:在 Python 退出時,如果使用 atexit.register() 註冊的回撥函式失敗,其異常現在會被記錄。之前,只有部分異常會被記錄,最後一個異常總是被靜默忽略。(由 Victor Stinner 在 bpo-42639 中貢獻。)

  • collections.abc.Callable 泛型現在會展平型別引數,類似於 typing.Callable 的當前行為。這意味著 collections.abc.Callable[[int, str], str]__args__ 將是 (int, str, str);之前是 ([int, str], str)。透過 typing.get_args()__args__ 訪問引數的程式碼需要考慮此更改。此外,對於引數化 collections.abc.Callable 的無效形式,可能會引發 TypeError,這些形式在 Python 3.9 中可能被靜默透過。(由 Ken Jin 在 bpo-42195 中貢獻。)

  • socket.htons()socket.ntohs() 現在如果給定的引數不適合 16 位無符號整數,則會引發 OverflowError 而不是 DeprecationWarning。(由 Erlend E. Aasland 在 bpo-42393 中貢獻。)

  • 繼 Python 3.8 中棄用之後,loop 引數已從 asyncio 的大部分 高層 API 中移除。

    一個協程,當前看起來像這樣

    async def foo(loop):
        await asyncio.sleep(1, loop=loop)
    

    應該被替換為這樣

    async def foo():
        await asyncio.sleep(1)
    

    如果 foo() 是專門設計為在當前執行緒的執行事件迴圈中執行(例如,在另一個執行緒的事件迴圈中執行),請考慮使用 asyncio.run_coroutine_threadsafe()

    (由 Yurii Karabas, Andrew Svetlov, Yury Selivanov 和 Kyle Stanley 在 bpo-42392 中貢獻。)

  • types.FunctionType 建構函式現在會繼承當前內建模組,如果 globals 字典沒有 "__builtins__" 鍵,而不是使用 {"None": None} 作為內建模組:行為與 eval()exec() 函式相同。在 Python 中定義一個函式,如 def function(...): ...,不受影響,使用此語法無法覆蓋全域性變數:它也會繼承當前的內建模組。(由 Victor Stinner 在 bpo-42990 中貢獻。)

C API 的變化

  • C API 函式 PyParser_SimpleParseStringFlags, PyParser_SimpleParseStringFlagsFilename, PyParser_SimpleParseFileFlags, PyNode_Compile 以及這些函式使用的型別 struct _node,由於切換到新的 PEG 解析器而被移除。

    原始碼現在應直接使用例如 Py_CompileString() 編譯為程式碼物件。然後可以使用例如 PyEval_EvalCode() 來評估生成的程式碼物件。

    具體來說

    • 呼叫 PyParser_SimpleParseStringFlags 後跟 PyNode_Compile 可以透過呼叫 Py_CompileString() 來替換。

    • 沒有直接替代 PyParser_SimpleParseFileFlags 的方法。要從 FILE * 引數編譯程式碼,您需要用 C 讀取檔案並將結果緩衝區傳遞給 Py_CompileString()

    • 要使用 char * 檔名編譯檔案,請顯式開啟檔案,讀取它並編譯結果。一種方法是使用 io 模組,並結合 PyImport_ImportModule(), PyObject_CallMethod(), PyBytes_AsString()Py_CompileString(),如下例所示。(宣告和錯誤處理已省略。)

      io_module = Import_ImportModule("io");
      fileobject = PyObject_CallMethod(io_module, "open", "ss", filename, "rb");
      source_bytes_object = PyObject_CallMethod(fileobject, "read", "");
      result = PyObject_CallMethod(fileobject, "close", "");
      source_buf = PyBytes_AsString(source_bytes_object);
      code = Py_CompileString(source_buf, filename, Py_file_input);
      
    • 對於 FrameObject 物件,f_lasti 成員現在代表一個 wordcode 偏移量,而不是位元組碼字串中的簡單偏移量。這意味著需要將此數字乘以 2 才能用於期望位元組偏移量的 API(例如,對於 PyCode_Addr2Line())。請注意,FrameObject 物件的 f_lasti 成員不被認為是穩定的:請改用 PyFrame_GetLineNumber()

CPython 位元組碼變更

  • MAKE_FUNCTION 指令現在接受字典或字串元組作為函式的註解。(由 Yurii Karabas 和 Inada Naoki 在 bpo-42202 中貢獻。)

構建更改

  • PEP 644:Python 現在要求 OpenSSL 1.1.1 或更高版本。不再支援 OpenSSL 1.0.2。(由 Christian Heimes 在 bpo-43669 中貢獻。)

  • C99 函式 snprintf()vsnprintf() 現在是構建 Python 所必需的。(由 Victor Stinner 在 bpo-36020 中貢獻。)

  • sqlite3 要求 SQLite 3.7.15 或更高版本。(由 Sergey Fedoseev 和 Erlend E. Aasland 在 bpo-40744bpo-40810 中貢獻。)

  • atexit 模組現在必須始終構建為內建模組。(由 Victor Stinner 在 bpo-42639 中貢獻。)

  • configure 指令碼添加了 --disable-test-modules 選項:不構建或安裝測試模組。(由 Xavier de Gaye, Thomas Petazzoni 和 Peixing Xin 在 bpo-27640 中貢獻。)

  • ./configure 指令碼添加了 --with-wheel-pkg-dir=PATH 選項。如果指定了該選項,ensurepip 模組將在此目錄中查詢 setuptoolspip wheel 包:如果兩者都存在,則使用這些 wheel 包代替 ensurepip 捆綁的 wheel 包。

    一些 Linux 發行版的打包策略建議不要捆綁依賴項。例如,Fedora 將 wheel 包安裝在 /usr/share/python-wheels/ 目錄中,並且不安裝 ensurepip._bundled 包。

    (由 Victor Stinner 在 bpo-42856 中貢獻。)

  • 添加了一個新的 configure --without-static-libpython 選項,以不構建 libpythonMAJOR.MINOR.a 靜態庫,也不安裝 python.o 物件檔案。

    (由 Victor Stinner 在 bpo-43103 中貢獻。)

  • 現在 configure 指令碼使用 pkg-config 工具(如果可用)來檢測 Tcl/Tk 標頭檔案和庫的位置。與之前一樣,可以使用 --with-tcltk-includes--with-tcltk-libs 配置選項顯式指定這些位置。(由 Manolis Stamatogiannakis 在 bpo-42603 中貢獻。)

  • configure 指令碼添加了 --with-openssl-rpath 選項。該選項簡化了使用自定義 OpenSSL 安裝構建 Python 的過程,例如 ./configure --with-openssl=/path/to/openssl --with-openssl-rpath=auto。(由 Christian Heimes 在 bpo-43466 中貢獻。)

C API 更改

PEP 652:維護穩定 ABI

現在明確定義了擴充套件模組或嵌入 Python 的穩定 ABI(應用程式二進位制介面)。C API 穩定性 描述了 C API 和 ABI 的穩定性保證以及使用穩定 ABI 的最佳實踐。

(由 Petr Viktorin 在 PEP 652bpo-43795 中貢獻。)

新功能

移植到 Python 3.10

  • 現在必須定義 PY_SSIZE_T_CLEAN 宏才能使用 PyArg_ParseTuple()Py_BuildValue() 格式,這些格式使用 #es#, et#, s#, u#, y#, z#, U#Z#。請參閱 解析引數和構建值PEP 353。(由 Victor Stinner 在 bpo-40943 中貢獻。)

  • 由於 Py_REFCNT() 已更改為內聯靜態函式,Py_REFCNT(obj) = new_refcnt 必須替換為 Py_SET_REFCNT(obj, new_refcnt):請參閱 Py_SET_REFCNT()(自 Python 3.9 起可用)。為了向後相容,可以使用此宏

    #if PY_VERSION_HEX < 0x030900A4
    #  define Py_SET_REFCNT(obj, refcnt) ((Py_REFCNT(obj) = (refcnt)), (void)0)
    #endif
    

    (由 Victor Stinner 在 bpo-39573 中貢獻。)

  • 出於歷史原因,呼叫 PyDict_GetItem() 時不持有 GIL 是允許的。現在不再允許。(由 Victor Stinner 在 bpo-40839 中貢獻。)

  • PyUnicode_FromUnicode(NULL, size)PyUnicode_FromStringAndSize(NULL, size) 現在會發出 DeprecationWarning。使用 PyUnicode_New() 來分配不帶初始資料的 Unicode 物件。(由 Inada Naoki 在 bpo-36346 中貢獻。)

  • PyCapsule API unicodedata.ucnhash_CAPI 的私有 _PyUnicode_Name_CAPI 結構已移至內部 C API。(由 Victor Stinner 在 bpo-42157 中貢獻。)

  • Py_GetPath(), Py_GetPrefix(), Py_GetExecPrefix(), Py_GetProgramFullPath(), Py_GetPythonHome()Py_GetProgramName() 函式現在會在 Py_Initialize()(Python 初始化之前)呼叫之前返回 NULL。使用新的 Python 初始化配置 API 來獲取 Python 路徑配置。(由 Victor Stinner 在 bpo-42260 中貢獻。)

  • PyList_SET_ITEM(), PyTuple_SET_ITEM()PyCell_SET() 宏現在不能用作左值或右值。例如,x = PyList_SET_ITEM(a, b, c)PyList_SET_ITEM(a, b, c) = x 現在會導致編譯器錯誤。這可以防止 if (PyList_SET_ITEM (a, b, c) < 0) ... 這種測試中的錯誤。(由 Zackery Spytz 和 Victor Stinner 在 bpo-30459 中貢獻。)

  • 非限制 API 檔案 odictobject.h, parser_interface.h, picklebufobject.h, pyarena.h, pyctype.h, pydebug.h, pyfpe.hpytime.h 已移至 Include/cpython 目錄。這些檔案不應被直接包含,因為它們已經被包含在 Python.h 中;請參閱 包含檔案。如果已被直接包含,請考慮改為包含 Python.h。(由 Nicholas Sim 在 bpo-35134 中貢獻。)

  • 使用 Py_TPFLAGS_IMMUTABLETYPE 型別標誌來建立不可變型別物件。不要依賴 Py_TPFLAGS_HEAPTYPE 來決定型別物件是否可變;而是檢查是否設定了 Py_TPFLAGS_IMMUTABLETYPE。(由 Victor Stinner 和 Erlend E. Aasland 在 bpo-43908 中貢獻。)

  • 未文件化的函式 Py_FrozenMain 已從有限 API 中移除。該函式主要用於自定義 Python 構建。(由 Petr Viktorin 在 bpo-26241 中貢獻。)

已棄用

已移除

  • 移除了操作 Py_UNICODE* 字串的 PyUnicode_str* 函式。(由 Inada Naoki 在 bpo-41123 中貢獻。)

  • 移除了 PyUnicode_GetMax()。請遷移到新的(PEP 393)API。(由 Inada Naoki 在 bpo-41103 中貢獻。)

  • 移除了 PyLong_FromUnicode()。請遷移到 PyLong_FromUnicodeObject()。(由 Inada Naoki 在 bpo-41103 中貢獻。)

  • 移除了 PyUnicode_AsUnicodeCopy()。請使用 PyUnicode_AsUCS4Copy()PyUnicode_AsWideCharString() (由 Inada Naoki 在 bpo-41103 中貢獻。)

  • 移除了 _Py_CheckRecursionLimit 變數:它已被 PyInterpreterState 結構中的 ceval.recursion_limit 替換。(由 Victor Stinner 在 bpo-41834 中貢獻。)

  • 移除了未文件化的宏 Py_ALLOW_RECURSIONPy_END_ALLOW_RECURSION 以及 PyInterpreterState 結構中的 recursion_critical 欄位。(由 Serhiy Storchaka 在 bpo-41936 中貢獻。)

  • 移除了未文件化的函式 PyOS_InitInterrupts()。初始化 Python 已經隱式安裝了訊號處理程式:請參閱 PyConfig.install_signal_handlers。(由 Victor Stinner 在 bpo-41713 中貢獻。)

  • 移除 PyAST_Validate() 函式。現在無法透過公共 C API 構建 AST 物件(mod_ty 型別)。該函式已經被排除在有限 C API 之外(PEP 384)。(由 Victor Stinner 在 bpo-43244 中貢獻。)

  • 移除 symtable.h 標頭檔案和未文件化的函式

    • PyST_GetScope()

    • PySymtable_Build()

    • PySymtable_BuildObject()

    • PySymtable_Free()

    • Py_SymtableString()

    • Py_SymtableStringObject()

    Py_SymtableString() 函式是穩定 ABI 的一部分,但它無法使用,因為 symtable.h 標頭檔案被排除了有限 C API 之外。

    請改用 Python 的 symtable 模組。(由 Victor Stinner 在 bpo-43244 中貢獻。)

  • 從有限 C API 標頭檔案和提供 Windows 上穩定 ABI 的庫 python3.dll 中移除了 PyOS_ReadlineFunctionPointer()。由於該函式接受 FILE* 引數,其 ABI 穩定性無法保證。(由 Petr Viktorin 在 bpo-43868 中貢獻。)

  • 移除了 ast.h, asdl.hPython-ast.h 標頭檔案。這些函式未文件化且被排除在有限 C API 之外。這些標頭檔案定義的大多數名稱都沒有 Py 字首,因此可能產生名稱衝突。例如,Python-ast.h 定義了一個 Yield 宏,這與 Windows <winbase.h> 標頭檔案使用的 Yield 名稱衝突。請改用 Python 的 ast 模組。(由 Victor Stinner 在 bpo-43244 中貢獻。)

  • 移除了使用 struct _mod 型別的編譯器和解析器函式,因為公共 AST C API 已被移除

    • PyAST_Compile()

    • PyAST_CompileEx()

    • PyAST_CompileObject()

    • PyFuture_FromAST()

    • PyFuture_FromASTObject()

    • PyParser_ASTFromFile()

    • PyParser_ASTFromFileObject()

    • PyParser_ASTFromFilename()

    • PyParser_ASTFromString()

    • PyParser_ASTFromStringObject()

    這些函式未文件化且被排除在有限 C API 之外。(由 Victor Stinner 在 bpo-43244 中貢獻。)

  • 移除 pyarena.h 標頭檔案及其函式

    • PyArena_New()

    • PyArena_Free()

    • PyArena_Malloc()

    • PyArena_AddPyObject()

    這些函式未文件化,被排除了有限 C API 之外,並且僅由編譯器內部使用。(由 Victor Stinner 在 bpo-43244 中貢獻。)

  • 已移除 PyThreadState.use_tracing 成員以最佳化 Python。(由 Mark Shannon 在 bpo-43760 中貢獻。)

3.10.7 中的安全特性

intstr 轉換為除 2(二進位制)、4、8(八進位制)、16(十六進位制)或 32(例如十進位制)以外的基數,現在如果字串形式的數字位數超過一個限制,會引發 ValueError,以避免因演算法複雜性而導致的潛在拒絕服務攻擊。這是對 CVE 2020-10735 的緩解措施。此限制可以透過環境變數、命令列標誌或 sys API 進行配置或停用。請參閱 整數字符串轉換長度限制 文件。預設限制為 4300 位數字。

3.10.8 中的安全特性

已棄用的 mailcap 模組現在拒絕將不安全文字(檔名、MIME 型別、引數)注入到 shell 命令中。它會發出警告並假裝未找到匹配項(或對於測試命令,假裝測試失敗),而不是使用此類文字。(由 Petr Viktorin 在 gh-98966 中貢獻。)

3.10.12 中的重要更改

tarfile

  • tarfile 模組中的提取方法,以及 shutil.unpack_archive(),現在有一個新的 filter 引數,允許限制 tar 的一些可能令人驚訝或危險的功能,例如在目標目錄之外建立檔案。有關詳細資訊,請參閱 提取過濾器。在 Python 3.12 中,不帶 filter 引數的用法將顯示 DeprecationWarning。在 Python 3.14 中,預設值將切換到 'data'。(由 Petr Viktorin 在 PEP 706 中貢獻。)