Python 3.14 新特性

編輯:

Adam Turner and Hugo van Kemenade

本文解釋了 Python 3.14 相比 3.13 版本的新特性。Python 3.14 於 2025 年 10 月 7 日釋出。要了解全部細節,請參閱更新日誌

參見

PEP 745 – Python 3.14 釋出計劃

摘要 – 釋出亮點

Python 3.14 是 Python 程式語言的最新穩定版本,對語言、實現和標準庫進行了一系列更改。最大的變化包括模板字串字面量延遲求值的註解,以及在標準庫中支援子直譯器

庫方面的變更包括顯著增強了 asyncio 中的內省 功能,透過新的 compression.zstd 模組支援 Zstandard,在 REPL 中實現了語法高亮,以及常規的棄用和移除,並改進了使用者友好性和正確性。

本文不試圖對所有新特性提供完整的規範,而是提供一個方便的概述。要了解全部細節,請參閱文件,如庫參考語言參考。要理解某項變更的完整實現和設計理念,請參閱該新特性對應的 PEP;但請注意,PEP 通常在特性完全實現後便不再更新。關於從早期版本的 Python 升級的指導,請參閱移植到 Python 3.14


直譯器的改進

標準庫的重大改進

C API 的改進

平臺支援

釋出變更

新特性

PEP 649 & PEP 749: 延遲求值的註解

函式、類和模組上的註解不再被即時求值。相反,註解被儲存在專用的註解函式中,並且僅在必要時才進行求值(除非使用了 from __future__ import annotations)。

這一變更旨在大多數情況下提高 Python 中註解的效能和可用性。定義註解的執行時成本被最小化,但仍然可以在執行時內省註解。如果註解包含前向引用,也不再需要將其用字串括起來。

新的 annotationlib 模組提供了檢查延遲註解的工具。註解可以按 VALUE 格式(將註解求值為執行時值,類似於早期 Python 版本的行為)、FORWARDREF 格式(用特殊標記替換未定義的名稱),以及 STRING 格式(將註解作為字串返回)進行求值。

此示例展示了這些格式的行為

>>> from annotationlib import get_annotations, Format
>>> def func(arg: Undefined):
...     pass
>>> get_annotations(func, format=Format.VALUE)
Traceback (most recent call last):
  ...
NameError: name 'Undefined' is not defined
>>> get_annotations(func, format=Format.FORWARDREF)
{'arg': ForwardRef('Undefined', owner=<function func at 0x...>)}
>>> get_annotations(func, format=Format.STRING)
{'arg': 'Undefined'}

移植部分包含了因這些變更可能需要進行的修改的指導,儘管在大多數情況下,程式碼將繼續按原樣工作。

(由 Jelle Zijlstra 在 PEP 749gh-119180 中貢獻;PEP 649 由 Larry Hastings 編寫。)

參見

PEP 649

使用描述符延遲求值註解

PEP 749

實現 PEP 649

PEP 734: 標準庫中的多直譯器

CPython 執行時支援在同一程序中同時執行多個 Python 副本,這一功能已經存在超過 20 年。這些獨立的副本中的每一個都稱為一個“直譯器”。然而,該功能此前僅能透過 C-API 使用。

在 Python 3.14 中,隨著新的 concurrent.interpreters 模組的引入,這一限制被移除了。

使用多直譯器至少有兩個顯著的優點

  • 它們支援一種新的(對 Python 而言)、對人類友好的併發模型

  • 真正的多核並行

對於某些用例,軟體中的併發可以提高效率並簡化設計,從高層次上看是這樣。但與此同時,實現和維護除了最簡單的併發之外的任何東西,通常對人腦來說都是一種挑戰。這尤其適用於普通的執行緒(例如 threading),其中所有記憶體都在所有執行緒之間共享。

透過多個隔離的直譯器,你可以利用一類併發模型,如通訊順序程序(CSP)或 Actor 模型,這些模型已在其他程式語言(如 Smalltalk、Erlang、Haskell 和 Go)中取得了成功。可以將多直譯器看作是執行緒,但具有可選的共享機制。

關於多核並行:從 Python 3.12 開始,直譯器之間已經足夠隔離,可以並行使用(參見 PEP 684)。這為 Python 解鎖了各種受限於全域性直譯器鎖 (GIL) 的 CPU 密集型用例。

在許多方面,使用多直譯器與 multiprocessing 類似,因為它們都提供了可以並行執行且預設不共享的隔離邏輯“程序”。然而,使用多直譯器時,應用程式將使用更少的系統資源,並且執行更高效(因為它停留在同一個程序內)。可以將多直譯器看作是具有程序的隔離性和執行緒的效率。

儘管該功能已存在數十年,但由於認知度低且缺乏標準庫模組,多直譯器並未被廣泛使用。因此,它們目前存在幾個顯著的侷限性,預計隨著該功能的主流化將得到顯著改善。

當前限制

  • 每個直譯器的啟動尚未最佳化

  • 每個直譯器使用的記憶體比必要的要多(直譯器之間廣泛的內部共享工作仍在繼續)

  • 在直譯器之間真正共享物件或其他資料的選項不多(除了 memoryview

  • PyPI 上的許多第三方擴充套件模組尚不相容多直譯器(所有標準庫擴充套件模組都相容的)

  • 目前,Python 使用者對編寫使用多個隔離直譯器的應用程式的方法大多不熟悉

這些限制的影響將取決於未來的 CPython 改進、直譯器的使用方式以及社群透過 PyPI 包解決的問題。根據具體用例,這些限制可能影響不大,所以不妨一試!

此外,未來的 CPython 版本將減少或消除開銷,並提供不太適合放在 PyPI 上的實用工具。在此期間,大多數限制也可以透過擴充套件模組來解決,這意味著 PyPI 包可以填補 3.14 的任何空白,甚至可以回溯到 3.12,那時直譯器最終被正確隔離並停止共享 GIL。同樣,預計 PyPI 上會出現基於直譯器的高階抽象庫。

關於擴充套件模組,正在進行更新一些 PyPI 專案以及像 Cython、pybind11、nanobind 和 PyO3 等工具的工作。隔離擴充套件模組的步驟可以在隔離擴充套件模組中找到。隔離一個模組與支援自由執行緒所需的工作有很多重疊之處,因此社群在該領域正在進行的工作將有助於加速對多直譯器的支援。

3.14 中還新增了:concurrent.futures.InterpreterPoolExecutor

(由 Eric Snow 在 gh-134939 中貢獻。)

參見

PEP 734

PEP 750: 模板字串字面量

模板字串是自定義字串處理的一種新機制。它們共享 f-string 熟悉的語法,但與 f-string 不同,它們返回一個表示字串靜態和插值部分的物件,而不是一個簡單的 str

要編寫一個 t-string,請使用 't' 字首而不是 'f'

>>> variety = 'Stilton'
>>> template = t'Try some {variety} cheese!'
>>> type(template)
<class 'string.templatelib.Template'>

Template 物件提供了在字串的靜態和插值(在大括號中)部分組合之前訪問它們的能力。遍歷 Template 例項以按順序訪問其各個部分

>>> list(template)
['Try some ', Interpolation('Stilton', 'variety', None, ''), ' cheese!']

編寫(或呼叫)程式碼來處理 Template 例項很容易。例如,這裡有一個函式,它將靜態部分渲染為小寫,並將 Interpolation 例項渲染為大寫

from string.templatelib import Interpolation

def lower_upper(template):
    """Render static parts lowercase and interpolations uppercase."""
    parts = []
    for part in template:
        if isinstance(part, Interpolation):
            parts.append(str(part.value).upper())
        else:
            parts.append(part.lower())
    return ''.join(parts)

name = 'Wenslydale'
template = t'Mister {name}'
assert lower_upper(template) == 'mister WENSLYDALE'

因為 Template 例項在執行時區分靜態字串和插值,所以它們對於清理使用者輸入很有用。編寫一個對 HTML 中的使用者輸入進行轉義的 html() 函式是留給讀者的一個練習!模板處理程式碼可以提供更好的靈活性。例如,一個更高階的 html() 函式可以直接在模板中接受一個 HTML 屬性的 dict

attributes = {'src': 'limburger.jpg', 'alt': 'lovely cheese'}
template = t'<img {attributes}>'
assert html(template) == '<img src="limburger.jpg" alt="lovely cheese" />'

當然,模板處理程式碼不需要返回一個類似字串的結果。一個高階的 html() 可以返回一個表示類似 DOM 結構的自定義型別。

有了 t-string,開發者可以編寫系統來清理 SQL、進行安全的 shell 操作、改進日誌記錄、處理 Web 開發中的現代思想(HTML、CSS 等),並實現輕量級的自定義業務 DSL。

(由 Jim Baker, Guido van Rossum, Paul Everitt, Koudai Aono, Lysandros Nikolaou, Dave Peck, Adam Turner, Jelle Zijlstra, Bénédikt Tran, 和 Pablo Galindo Salgado 在 gh-132661 中貢獻。)

參見

PEP 750.

PEP 768: 安全的外部偵錯程式介面

Python 3.14 引入了一個零開銷的除錯介面,允許偵錯程式和效能分析器安全地附加到正在執行的 Python 程序,而無需停止或重啟它們。這是對 Python 除錯能力的重大增強,意味著不再需要不安全的替代方案。

新介面為附加偵錯程式程式碼提供了安全的執行點,而不會修改直譯器的正常執行路徑或在執行時增加任何開銷。因此,工具現在可以即時檢查和與 Python 應用程式互動,這對於高可用性系統和生產環境來說是一項至關重要的能力。

為方便起見,此介面在 sys.remote_exec() 函式中實現。例如

import sys
from tempfile import NamedTemporaryFile

with NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
    script_path = f.name
    f.write(f'import my_debugger; my_debugger.connect({os.getpid()})')

# Execute in process with PID 1234
print('Behold! An offering:')
sys.remote_exec(1234, script_path)

此函式允許傳送 Python 程式碼,在目標程序的下一個安全執行點執行。然而,工具作者也可以直接實現 PEP 中描述的協議,該協議詳細說明了用於安全附加到正在執行的程序的底層機制。

除錯介面在設計時仔細考慮了安全性,幷包括幾種控制訪問的機制

(由 Pablo Galindo Salgado, Matt Wozniski, and Ivona Stojanovic 在 gh-131591 中貢獻。)

參見

PEP 768.

一種新型直譯器

CPython 新增了一種直譯器。它在實現單個 Python 操作碼的小型 C 函式之間使用尾呼叫,而不是一個大的 C case 語句。對於某些較新的編譯器,這種直譯器提供了顯著更好的效能。初步基準測試表明,在標準的 pyperformance 基準測試套件上,幾何平均速度提高了 3-5%,具體取決於平臺和架構。基準是使用 Clang 19 構建的 Python 3.14,但未使用這種新直譯器。

目前,這種直譯器僅適用於 Clang 19 及更新版本,在 x86-64 和 AArch64 架構上。然而,預計未來版本的 GCC 也將支援此功能。

該功能目前為可選啟用。在使用新直譯器時,強烈建議啟用配置檔案引導最佳化(PGO),因為這是唯一經過測試和驗證能提高效能的配置。更多資訊,請參閱 --with-tail-call-interp

備註

這不應與 Python 函式的尾呼叫最佳化相混淆,後者目前未在 CPython 中實現。

這種新的直譯器型別是 CPython 直譯器的內部實現細節。它完全不改變 Python 程式的可見行為。它可以提高它們的效能,但不改變其他任何東西。

(由 Ken Jin 在 gh-128563 中貢獻,其在 CPython 中實現的思路來自 Mark Shannon, Garrett Gu, Haoran Xu, 和 Josh Haberman。)

自由執行緒模式的改進

CPython 的自由執行緒模式(PEP 703),最初在 3.13 中新增,在 Python 3.14 中得到了顯著改進。PEP 703 中描述的實現已經完成,包括 C API 的更改,並且直譯器中的臨時變通方法被更永久的解決方案所取代。專精化自適應直譯器(PEP 659)現在在自由執行緒模式下啟用,這與許多其他最佳化一起極大地提高了其效能。在自由執行緒模式下,單執行緒程式碼的效能損失現在大約為 5-10%,具體取決於平臺和 C 編譯器。

從 Python 3.14 開始,在 Windows 上為自由執行緒構建的 CPython 編譯擴充套件模組時,預處理器變數 Py_GIL_DISABLED 現在需要由構建後端指定,因為它將不再由 C 編譯器自動確定。對於正在執行的直譯器,可以使用 sysconfig.get_config_var() 找到編譯時使用的設定。

新的 -X context_aware_warnings 標誌控制是否啟用併發安全的警告控制。對於自由執行緒構建,該標誌預設為 true,對於啟用 GIL 的構建,預設為 false。

新增了一個 thread_inherit_context 標誌,如果啟用,意味著用 threading.Thread 建立的執行緒將以 start() 呼叫者的 Context() 的副本啟動。最重要的是,這使得由 catch_warnings 建立的警告過濾上下文被在該上下文中啟動的執行緒(或 asyncio 任務)“繼承”。它也影響其他使用上下文變數的模組,例如 decimal 上下文管理器。對於自由執行緒構建,該標誌預設為 true,對於啟用 GIL 的構建,預設為 false。

(由 Sam Gross, Matt Page, Neil Schemenauer, Thomas Wouters, Donghee Na, Kirill Podoprigora, Ken Jin, Itamar Oren, Brett Simmers, Dino Viehland, Nathan Goldbaum, Ralf Gommers, Lysandros Nikolaou, Kumar Aditya, Edgar Margffoy, 和許多其他人貢獻。其中一些貢獻者受僱於 Meta,該公司繼續為支援該專案提供重要的工程資源。)

改進的錯誤訊息

  • 當檢測到 Python 關鍵字的拼寫錯誤時,直譯器現在會提供有用的建議。當遇到一個與 Python 關鍵字非常相似的單詞時,直譯器會在錯誤訊息中建議正確的關鍵字。此功能有助於程式設計師快速識別和修復常見的輸入錯誤。例如

    >>> whille True:
    ...     pass
    Traceback (most recent call last):
      File "<stdin>", line 1
        whille True:
        ^^^^^^
    SyntaxError: invalid syntax. Did you mean 'while'?
    

    雖然該功能側重於最常見的情況,但某些拼寫錯誤的變體可能仍會導致常規的語法錯誤。(由 Pablo Galindo 在 gh-132449 中貢獻。)

  • 跟在 else 塊後面的 elif 語句現在有了特定的錯誤訊息。(由 Steele Farnsworth 在 gh-129902 中貢獻。)

    >>> if who == "me":
    ...     print("It's me!")
    ... else:
    ...     print("It's not me!")
    ... elif who is None:
    ...     print("Who is it?")
    File "<stdin>", line 5
      elif who is None:
      ^^^^
    SyntaxError: 'elif' block follows an 'else' block
    
  • 如果在else之後向條件表示式傳遞了語句,或者在if之前傳遞了passbreakcontinue之一,那麼錯誤訊息會高亮顯示需要表示式的位置。(由 Sergey Miryanov 在 gh-129515 中貢獻。)

    >>> x = 1 if True else pass
    Traceback (most recent call last):
      File "<string>", line 1
        x = 1 if True else pass
                           ^^^^
    SyntaxError: expected expression after 'else', but statement is given
    
    >>> x = continue if True else break
    Traceback (most recent call last):
      File "<string>", line 1
        x = continue if True else break
            ^^^^^^^^
    SyntaxError: expected expression before 'if', but statement is given
    
  • 當檢測到未正確閉合的字串時,錯誤訊息會建議該字串可能意在成為字串的一部分。(由 Pablo Galindo 在 gh-88535 中貢獻。)

    >>> "The interesting object "The important object" is very important"
    Traceback (most recent call last):
    SyntaxError: invalid syntax. Is this intended to be part of the string?
    
  • 當字串具有不相容的字首時,錯誤現在會顯示哪些字首是不相容的。(由 Nikita Sobolev 在 gh-133197 中貢獻。)

    >>> ub'abc'
      File "<python-input-0>", line 1
        ub'abc'
        ^^
    SyntaxError: 'u' and 'b' prefixes are incompatible
    
  • 改進了在以下情況中使用 as 與不相容目標時的錯誤訊息

    • 匯入:import ... as ...

    • From 匯入:from ... import ... as ...

    • Except 處理程式:except ... as ...

    • 模式匹配 case:case ... as ...

    (由 Nikita Sobolev 在 gh-123539gh-123562gh-123440 中貢獻。)

  • 改進了嘗試將不可雜湊型別的例項新增到 dictset 時的錯誤訊息。(由 CF Bolz-Tereick 和 Victor Stinner 在 gh-132828 中貢獻。)

    >>> s = set()
    >>> s.add({'pages': 12, 'grade': 'A'})
    Traceback (most recent call last):
      File "<python-input-1>", line 1, in <module>
        s.add({'pages': 12, 'grade': 'A'})
        ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    TypeError: cannot use 'dict' as a set element (unhashable type: 'dict')
    >>> d = {}
    >>> l = [1, 2, 3]
    >>> d[l] = 12
    Traceback (most recent call last):
      File "<python-input-4>", line 1, in <module>
        d[l] = 12
        ~^^^
    TypeError: cannot use 'list' as a dict key (unhashable type: 'list')
    
  • 改進了當支援同步上下文管理器協議的物件使用 async with 而不是 with 進入,以及非同步上下文管理器協議反之亦然時的錯誤訊息。(由 Bénédikt Tran 在 gh-128398 中貢獻。)

PEP 784: 標準庫中的 Zstandard 支援

新的 compression 包包含了 compression.lzmacompression.bz2compression.gzipcompression.zlib 模組,它們分別重新匯出了 lzmabz2gzipzlib 模組。從 Python 3.14 開始,compression 下的新匯入名稱是匯入這些壓縮模組的首選名稱。然而,現有的模組名稱尚未被棄用。任何對現有壓縮模組的棄用或移除,都不會早於 3.14 釋出後的五年。

新的 compression.zstd 模組透過繫結 Meta 的 zstd 庫,為 Zstandard 格式提供了壓縮和解壓 API。Zstandard 是一種被廣泛採用、高效且快速的壓縮格式。除了在 compression.zstd 中引入的 API 之外,還向 tarfilezipfileshutil 模組添加了對讀寫 Zstandard 壓縮歸檔的支援。

這是一個使用新模組壓縮一些資料的例子

from compression import zstd
import math

data = str(math.pi).encode() * 20
compressed = zstd.compress(data)
ratio = len(compressed) / len(data)
print(f"Achieved compression ratio of {ratio}")

可以看出,該 API 與 lzmabz2 模組的 API 類似。

(由 Emma Harper Smith, Adam Turner, Gregory P. Smith, Tomas Roun, Victor Stinner, 和 Rogdham 在 gh-132983 中貢獻。)

參見

PEP 784.

Asyncio 內省功能

新增了一個命令列介面,用於檢查使用非同步任務的正在執行的 Python 程序,可透過 python -m asyncio ps PIDpython -m asyncio pstree PID 使用。

ps 子命令檢查給定的程序 ID (PID) 並顯示當前執行的 asyncio 任務的資訊。它輸出一個任務表:所有任務的扁平列表,包括它們的名稱、協程堆疊,以及哪些任務正在等待它們。

pstree 子命令獲取相同的資訊,但會渲染一個視覺化的非同步呼叫樹,以層級格式顯示協程關係。此命令對於除錯長時間執行或卡住的非同步程式特別有用。它可以幫助開發者快速識別程式在哪裡被阻塞,哪些任務正在等待,以及協程是如何連結在一起的。

例如,給定此程式碼

import asyncio

async def play_track(track):
    await asyncio.sleep(5)
    print(f'🎵 Finished: {track}')

async def play_album(name, tracks):
    async with asyncio.TaskGroup() as tg:
        for track in tracks:
            tg.create_task(play_track(track), name=track)

async def main():
    async with asyncio.TaskGroup() as tg:
        tg.create_task(
          play_album('Sundowning', ['TNDNBTG', 'Levitate']),
          name='Sundowning')
        tg.create_task(
          play_album('TMBTE', ['DYWTYLM', 'Aqua Regia']),
          name='TMBTE')

if __name__ == '__main__':
    asyncio.run(main())

在正在執行的程序上執行新工具將產生一個如下所示的表格

python -m asyncio ps 12345

tid        task id              task name            coroutine stack                                    awaiter chain                                      awaiter name    awaiter id
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1935500    0x7fc930c18050       Task-1               TaskGroup._aexit -> TaskGroup.__aexit__ -> main                                                                       0x0
1935500    0x7fc930c18230       Sundowning           TaskGroup._aexit -> TaskGroup.__aexit__ -> album   TaskGroup._aexit -> TaskGroup.__aexit__ -> main    Task-1          0x7fc930c18050
1935500    0x7fc93173fa50       TMBTE                TaskGroup._aexit -> TaskGroup.__aexit__ -> album   TaskGroup._aexit -> TaskGroup.__aexit__ -> main    Task-1          0x7fc930c18050
1935500    0x7fc93173fdf0       TNDNBTG              sleep -> play                                      TaskGroup._aexit -> TaskGroup.__aexit__ -> album   Sundowning      0x7fc930c18230
1935500    0x7fc930d32510       Levitate             sleep -> play                                      TaskGroup._aexit -> TaskGroup.__aexit__ -> album   Sundowning      0x7fc930c18230
1935500    0x7fc930d32890       DYWTYLM              sleep -> play                                      TaskGroup._aexit -> TaskGroup.__aexit__ -> album   TMBTE           0x7fc93173fa50
1935500    0x7fc93161ec30       Aqua Regia           sleep -> play                                      TaskGroup._aexit -> TaskGroup.__aexit__ -> album   TMBTE           0x7fc93173fa50

或一棵如下所示的樹

python -m asyncio pstree 12345

└── (T) Task-1
    └──  main example.py:13
        └──  TaskGroup.__aexit__ Lib/asyncio/taskgroups.py:72
            └──  TaskGroup._aexit Lib/asyncio/taskgroups.py:121
                ├── (T) Sundowning
                   └──  album example.py:8
                       └──  TaskGroup.__aexit__ Lib/asyncio/taskgroups.py:72
                           └──  TaskGroup._aexit Lib/asyncio/taskgroups.py:121
                               ├── (T) TNDNBTG
                                  └──  play example.py:4
                                      └──  sleep Lib/asyncio/tasks.py:702
                               └── (T) Levitate
                                   └──  play example.py:4
                                       └──  sleep Lib/asyncio/tasks.py:702
                └── (T) TMBTE
                    └──  album example.py:8
                        └──  TaskGroup.__aexit__ Lib/asyncio/taskgroups.py:72
                            └──  TaskGroup._aexit Lib/asyncio/taskgroups.py:121
                                ├── (T) DYWTYLM
                                   └──  play example.py:4
                                       └──  sleep Lib/asyncio/tasks.py:702
                                └── (T) Aqua Regia
                                    └──  play example.py:4
                                        └──  sleep Lib/asyncio/tasks.py:702

如果在非同步等待圖中檢測到迴圈(這可能表示程式設計問題),該工具會引發錯誤並列出阻止樹構建的迴圈路徑

python -m asyncio pstree 12345

ERROR: await-graph contains cycles - cannot print a tree!

cycle: Task-2  Task-3  Task-2

(由 Pablo Galindo, Łukasz Langa, Yury Selivanov, 和 Marta Gomez Macias 在 gh-91048 中貢獻。)

併發安全的警告控制

warnings.catch_warnings 上下文管理器現在可以選擇性地使用上下文變數來處理警告過濾器。透過設定 context_aware_warnings 標誌來啟用此功能,可以使用 -X 命令列選項或環境變數。這在將 catch_warnings 與多執行緒或非同步任務結合使用時,提供了可預測的警告控制。對於自由執行緒構建,該標誌預設為 true,對於啟用 GIL 的構建,預設為 false。

(由 Neil Schemenauer 和 Kumar Aditya 在 gh-130010 中貢獻。)

其他語言變更

  • 現在,所有 Windows 內碼表在 Windows 上都作為 ‘cpXXX’ 編解碼器得到支援。(由 Serhiy Storchaka 在 gh-123803 中貢獻。)

  • 實現了自 C99 以來 C 標準指定的組合實數和複數的混合模式算術規則。(由 Sergey B Kirpichev 在 gh-69639 中貢獻。)

  • 現在,無論最佳化級別和 -O 命令列選項如何,都會檢測到更多的語法錯誤。這包括對 __debug__ 的寫入、不正確使用 await,以及在非同步函式之外使用非同步推導式。例如,python -O -c 'assert (__debug__ := 1)'python -O -c 'assert await 1' 現在會產生 SyntaxError。(由 Irit Katriel 和 Jelle Zijlstra 在 gh-122245 & gh-121637 中貢獻。)

  • 在子類化一個純 C 型別時,如果新型別的 C 槽在子類中沒有被顯式覆蓋,它們在類建立時將不再被替換為包裝版本。(由 Tomasz Pytel 在 gh-132284 中貢獻。)

內建函式

命令列和環境

  • 匯入時間標誌現在可以透過新的 -X importtime=2 來跟蹤已載入(“快取”)的模組。當匯入這樣的模組時,selfcumulative 時間將被字串 cached 替換。

    大於 2-X importtime 值現在保留供將來使用。

    (由 Noah Kim 和 Adam Turner 在 gh-118655 中貢獻。)

  • 命令列選項 -c 現在在執行前會自動對其程式碼引數進行反縮排。自動反縮排的行為與 textwrap.dedent() 相同。(由 Jon Crall 和 Steven Sun 在 gh-103998 中貢獻。)

  • -J 不再是為 Jython 保留的標誌,現在沒有特殊含義。(由 Adam Turner 在 gh-133336 中貢獻。)

PEP 758: 允許不帶括號的 exceptexcept* 表示式

當有多個異常型別且未使用 as 子句時,exceptexcept* 表示式現在允許省略括號。例如

try:
    connect_to_server()
except TimeoutError, ConnectionRefusedError:
    print('The network has ceased to be!')

(由 Pablo Galindo 和 Brett Cannon 在 PEP 758gh-131831 中貢獻。)

PEP 765: finally 程式碼塊中的控制流

returnbreakcontinue 語句的效果是離開 finally 程式碼塊時,編譯器現在會發出一個 SyntaxWarning。這一變更在 PEP 765 中有詳細說明。

在這一變更不方便的情況下(例如,由於程式碼檢查導致警告是多餘的),可以使用警告過濾器來關閉所有語法警告,方法是新增 ignore::SyntaxWarning 作為過濾器。這可以與一個將其他警告轉換為錯誤的過濾器結合指定(例如,傳遞 -Werror -Wignore::SyntaxWarning 作為命令列選項,或設定 PYTHONWARNINGS=error,ignore::SyntaxWarning)。

請注意,在執行時使用 warnings 模組應用這樣的過濾器,只會抑制在過濾器調整之後編譯的程式碼中的警告。在過濾器調整之前編譯的程式碼(例如,匯入模組時)仍會發出語法警告。

(由 Irit Katriel 在 gh-130080 中貢獻。)

增量式垃圾回收

迴圈垃圾回收器現在是增量式的。這意味著對於較大的堆,最大暫停時間減少了一個數量級或更多。

現在只有兩代:年輕代和老年代。當不直接呼叫 gc.collect() 時,GC 的呼叫頻率會稍微降低。當被呼叫時,它會收集年輕代和老年代的一個增量部分,而不是收集一個或多個完整的代。

gc.collect() 的行為略有變化

  • gc.collect(1): 執行一次增量垃圾回收,而不是收集第 1 代。

  • gc.collect() 的其他呼叫保持不變。

(由 Mark Shannon 在 gh-108362 中貢獻。)

預設互動式終端

  • 預設的互動式終端現在會高亮顯示 Python 語法。該功能預設啟用,除非設定了 PYTHON_BASIC_REPL 或任何其他停用顏色的環境變數。詳情請參閱控制顏色

    語法高亮的預設顏色主題力求良好的對比度,並專門使用 4 位 VGA 標準 ANSI 顏色程式碼以實現最大的相容性。可以使用實驗性 API _colorize.set_theme() 自定義主題。這可以在互動式會話中或在 PYTHONSTARTUP 指令碼中呼叫。請注意,此函式沒有穩定性保證,可能會更改或被移除。

    (由 Łukasz Langa 在 gh-131507 中貢獻。)

  • 預設的互動式終端現在支援匯入自動補全。這意味著輸入 import co 並按下 <Tab> 將會建議以 co 開頭的模組。類似地,輸入 from concurrent import i 將會建議 concurrent 中以 i 開頭的子模組。請注意,目前不支援模組屬性的自動補全。(由 Tomas Roun 在 gh-69605 中貢獻。)

新增模組

  • annotationlib: 用於內省註解。更多細節請參見 PEP 749。(由 Jelle Zijlstra 在 gh-119180 中貢獻。)

  • compression (包括 compression.zstd): 一個用於壓縮相關模組的包,包括一個支援 Zstandard 壓縮格式的新模組。更多細節請參見 PEP 784。(由 Emma Harper Smith, Adam Turner, Gregory P. Smith, Tomas Roun, Victor Stinner, 和 Rogdham 在 gh-132983 中貢獻。)

  • concurrent.interpreters: 在標準庫中支援多直譯器。更多細節請參見 PEP 734。(由 Eric Snow 在 gh-134939 中貢獻。)

  • string.templatelib: 支援模板字串字面量(t-string)。更多細節請參見 PEP 750。(由 Jim Baker, Guido van Rossum, Paul Everitt, Koudai Aono, Lysandros Nikolaou, Dave Peck, Adam Turner, Jelle Zijlstra, Bénédikt Tran, 和 Pablo Galindo Salgado 在 gh-132661 中貢獻。)

改進的模組

argparse

  • argparse.ArgumentParser程式名稱的預設值現在反映了 Python 直譯器被指示查詢 __main__ 模組程式碼的方式。(由 Serhiy Storchaka 和 Alyssa Coghlan 在 gh-66436 中貢獻。)

  • argparse.ArgumentParser 引入了可選的 suggest_on_error 形參,當用戶輸入錯誤時,可以為引數選項和子解析器名稱提供建議。(由 Savannah Ostrowski 在 gh-124456 中貢獻。)

  • 為幫助文字啟用顏色,可以透過向 argparse.ArgumentParser 傳入可選的 color 引數來停用。這也可以透過環境變數來控制。(由 Hugo van Kemenade 在 gh-130645 中貢獻。)

ast

  • 新增 compare(),一個用於比較兩個 AST 的函式。(由 Batuhan Taskaya 和 Jeremy Hylton 在 gh-60191 中貢獻。)

  • 為 AST 節點新增對 copy.replace() 的支援。(由 Bénédikt Tran 在 gh-121141 中貢獻。)

  • 在最佳化級別 2 中,文件字串現在會從最佳化的 AST 中移除。(由 Irit Katriel 在 gh-123958 中貢獻。)

  • AST 節點的 repr() 輸出現在包含更多資訊。(由 Tomas Roun 在 gh-116022 中貢獻。)

  • 當使用 AST 作為輸入呼叫時,parse() 函式現在總是驗證根節點型別是否適當。(由 Irit Katriel 在 gh-130139 中貢獻。)

  • 向命令列介面新增新選項:--feature-version--optimize--show-empty。(由 Semyon Moroz 在 gh-133367 中貢獻。)

asyncio

calendar

  • 預設情況下,在 calendar命令列文字輸出中,今天的日期會以彩色高亮顯示。這可以透過環境變數來控制。(由 Hugo van Kemenade 在 gh-128317 中貢獻。)

concurrent.futures

  • 添加了一個新的執行器類 InterpreterPoolExecutor,它將同一程序中的多個 Python 直譯器('子直譯器')暴露給 Python 程式碼。它使用一個獨立的 Python 直譯器池來非同步執行呼叫。

    這與 PEP 734 引入的新的 interpreters 模組是分開的。(由 Eric Snow 在 gh-124548 中貢獻。)

  • 在除 macOS 之外的 Unix 平臺上,‘forkserver’ 現在是 ProcessPoolExecutor 的預設啟動方法 (取代了 ‘fork’)。此更改不影響 Windows 或 macOS,在這兩個平臺上,‘spawn’ 仍然是預設的啟動方法。

    如果需要與執行緒不相容的 fork 方法,你必須透過向 ProcessPoolExecutor 提供一個多程序上下文 mp_context 來顯式請求它。

    有關 fork 方法的資訊和差異,以及此更改可能如何影響具有可變全域性共享變數和/或無法自動 pickled 的共享物件的現有程式碼,請參閱forkserver 限制

    (由 Gregory P. Smith 在 gh-84559 中貢獻。)

  • ProcessPoolExecutor 添加了兩個新方法,terminate_workers()kill_workers(),用於終止或殺死給定池中所有存活的工作程序。(由 Charles Machalow 在 gh-130849 中貢獻。)

  • Executor.map 添加了可選的 buffersize 引數,以限制已提交但結果尚未產生的任務數量。如果緩衝區已滿,對 iterables 的迭代將暫停,直到從緩衝區中產生一個結果。(由 Enzo Bonnal 和 Josh Rosenberg 在 gh-74028 中貢獻。)

configparser

  • configparser 將不再寫入它無法讀取的配置檔案,以提高安全性。嘗試 write() 包含分隔符或以節頭模式開頭的鍵將引發一個 InvalidWriteError。(由 Jacob Lincoln 在 gh-129270 中貢獻。)

contextvars

ctypes

curses

datetime

decimal

difflib

  • HtmlDiff 類生成的高亮顯示更改的比較頁面現在支援“暗黑模式”。(由 Jiahao Li 在 gh-129939 中貢獻。)

dis

errno

faulthandler

fnmatch

  • 新增 filterfalse(),一個用於拒絕與給定模式匹配的名稱的函式。(由 Bénédikt Tran 在 gh-74598 中貢獻。)

fractions

functools

getopt

  • 新增對帶有可選引數的選項的支援。(由 Serhiy Storchaka 在 gh-126374 中貢獻。)

  • 新增支援按順序返回混合的選項和非選項引數。(由 Serhiy Storchaka 在 gh-126390 中貢獻。)

getpass

  • 透過僅關鍵字的可選引數 echo_chargetpass() 函式中支援鍵盤反饋。每當輸入一個字元時,都會渲染佔位符字元,刪除字元時則移除。(由 Semyon Moroz 在 gh-77065 中貢獻。)

graphlib

heapq

hmac

  • 使用來自 HACL* 專案的經過形式化驗證的程式碼,為 HMAC (RFC 2104) 添加了內建實現。當 OpenSSL 的 HMAC 實現不可用時,此實現將用作後備。(由 Bénédikt Tran 在 gh-99108 中貢獻。)

http

imaplib

inspect

io

json

  • 為 JSON 序列化錯誤新增異常註釋,以幫助識別錯誤的來源。(由 Serhiy Storchaka 在 gh-122163 中貢獻。)

  • 允許使用 -m 開關將 json 模組作為指令碼使用:python -m json。現在推薦使用此方式,而不是 python -m json.tool,後者已被軟棄用。請參閱 JSON 命令列介面 文件。(由 Trey Hunner 在 gh-122873 中貢獻。)

  • 預設情況下,JSON 命令列介面的輸出會以彩色高亮顯示。這可以透過環境變數來控制。(由 Tomas Roun 在 gh-131952 中貢獻。)

linecache

  • getline() 現在可以檢索凍結模組的原始碼。(由 Tian Gao 在 gh-131638 中貢獻。)

logging.handlers

math

  • 為模組中的域錯誤添加了更詳細的錯誤訊息。(由 Charlie Zhao 和 Sergey B Kirpichev 在 gh-101410 中貢獻。)

mimetypes

  • 為模組添加了一個公共的命令列,透過 python -m mimetypes 呼叫。(由 Oleg Iarygin 和 Hugo van Kemenade 在 gh-93096 中貢獻。)

  • 根據 RFC 和常見用法添加了幾個新的 MIME 型別

    微軟和 RFC 8081 的字型 MIME 型別

    • 嵌入式 OpenType: application/vnd.ms-fontobject

    • OpenType 佈局 (OTF) font/otf

    • TrueType: font/ttf

    • WOFF 1.0 font/woff

    • WOFF 2.0 font/woff2

    RFC 9559 Matroska 音影片資料容器結構的 MIME 型別

    • 無影片的音訊: audio/matroska (.mka)

    • 影片: video/matroska (.mkv)

    • 立體影片: video/matroska-3d (.mk3d)

    帶 RFC 的影像

    • RFC 1494: CCITT Group 3 (.g3)

    • RFC 3362: 即時傳真, T.38 (.t38)

    • RFC 3745: JPEG 2000 (.jp2)、擴充套件 (.jpx) 和複合 (.jpm)

    • RFC 3950: 標記影像檔案格式傳真擴充套件, TIFF-FX (.tfx)

    • RFC 4047: 靈活影像傳輸系統 (.fits)

    • RFC 7903: 增強型圖元檔案 (.emf) 和 Windows 圖元檔案 (.wmf)

    其他 MIME 型別的新增和更改

    • RFC 2361: 將 .avi 的型別更改為 video/vnd.avi,將 .wav 的型別更改為 audio/vnd.wave

    • RFC 4337: 新增 MPEG-4 audio/mp4 (.m4a)

    • RFC 5334: 新增 Ogg 媒體 (.oga, .ogg.ogx)

    • RFC 6713: 新增 gzip application/gzip (.gz)

    • RFC 9639: 新增 FLAC audio/flac (.flac)

    • RFC 9512 YAML 檔案的 application/yaml MIME 型別 (.yaml.yml)

    • 新增 7z application/x-7z-compressed (.7z)

    • 當非嚴格模式時,新增 Android 包 application/vnd.android.package-archive (.apk)

    • 新增 deb application/x-debian-package (.deb)

    • 新增 glTF 二進位制 model/gltf-binary (.glb)

    • 新增 glTF JSON/ASCII model/gltf+json (.gltf)

    • 新增 M4V video/x-m4v (.m4v)

    • 新增 PHP application/x-httpd-php (.php)

    • 新增 RAR application/vnd.rar (.rar)

    • 新增 RPM application/x-rpm (.rpm)

    • 新增 STL model/stl (.stl)

    • 新增 Windows Media Video video/x-ms-wmv (.wmv)

    • 事實標準: 新增 WebM audio/webm (.weba)

    • ECMA-376: 新增 .docx.pptx.xlsx 型別

    • OASIS: 新增 OpenDocument .odg.odp.ods.odt 型別

    • W3C: 新增 EPUB application/epub+zip (.epub)

    (由 Sahil Prajapati 和 Hugo van Kemenade 在 gh-84852 中貢獻,由 Sasha “Nelie” Chernykh 和 Hugo van Kemenade 在 gh-132056 中貢獻,以及由 Hugo van Kemenade 在 gh-89416gh-85957gh-129965 中貢獻。)

multiprocessing

  • 在除 macOS 之外的 Unix 平臺上,‘forkserver’ 現在是預設的啟動方法 (取代了 ‘fork’)。此更改不影響 Windows 或 macOS,在這兩個平臺上,‘spawn’ 仍然是預設的啟動方法。

    如果需要與執行緒不相容的 fork 方法,你必須透過 get_context() 的上下文顯式請求它(推薦),或者透過 set_start_method() 更改預設值。

    有關 fork 方法的資訊和差異,以及此更改可能如何影響具有可變全域性共享變數和/或無法自動 pickled 的共享物件的現有程式碼,請參閱forkserver 限制

    (由 Gregory P. Smith 在 gh-84559 中貢獻。)

  • multiprocessing'forkserver' 啟動方法現在對其控制套接字進行身份驗證,以避免僅僅依賴檔案系統許可權來限制其他程序可能導致 forkserver 派生工作程序和執行程式碼。(由 Gregory P. Smith 為 gh-97514 貢獻。)

  • 多程序代理物件listdict 型別獲得了以前被忽略的缺失方法:

    • list 代理的 clear()copy()

    • dict 代理的 fromkeys()reversed(d)d | {}{} | dd |= {'b': 2}

    (由 Roy Hyunjin Han 為 gh-103134 貢獻。)

  • 透過 SyncManager.set() 新增對共享 set 物件的支援。Manager() 方法中的 set() 現在可用。(由 Mingyu Park 在 gh-129949 中貢獻。)

  • multiprocessing.Process 物件添加了 interrupt() 方法,該方法透過傳送 SIGINT 來終止子程序。這使得 finally 子句能夠為被終止的程序列印堆疊跟蹤。(由 Artem Pulkin 在 gh-131913 中貢獻。)

operator

  • 新增 is_none()is_not_none() 作為一對函式,使得 operator.is_none(obj) 等價於 obj is None,而 operator.is_not_none(obj) 等價於 obj is not None。(由 Raymond Hettinger 和 Nico Mexis 在 gh-115808 中貢獻。)

os

os.path

pathlib

  • pathlib.Path 添加了用於遞迴複製或移動檔案和目錄的方法:

    • copy() 將檔案或目錄樹複製到目標位置。

    • copy_into() 複製目標目錄中。

    • move() 將檔案或目錄樹移動到目標位置。

    • move_into() 移動目標目錄中。

    (由 Barney Gale 在 gh-73991 中貢獻。)

  • 新增 info 屬性,它儲存一個實現新的 pathlib.types.PathInfo 協議的物件。該物件支援查詢檔案型別並在內部快取 stat() 結果。由 iterdir() 生成的 Path 物件會用從掃描父目錄中收集的檔案型別資訊進行初始化。(由 Barney Gale 在 gh-125413 中貢獻。)

pdb

  • pdb 模組現在支援使用新的 -p PID 命令列選項遠端附加到正在執行的 Python 程序:

    python -m pdb -p 1234
    

    這將連線到具有給定 PID 的 Python 程序,並允許您以互動方式對其進行除錯。請注意,由於 Python 直譯器的工作方式,附加到在系統呼叫中阻塞或等待 I/O 的遠端程序,只有在執行下一個位元組碼指令或程序收到訊號時才會起作用。

    此功能使用 PEP 768 和新的 sys.remote_exec() 函式來附加到遠端程序並向其傳送 PDB 命令。

    (由 Matt Wozniski 和 Pablo Galindo 在 gh-131591 中貢獻。)

  • 硬編碼斷點 (breakpoint()set_trace()) 現在會重用呼叫 set_trace() 的最近一個 Pdb 例項,而不是每次都建立一個新的。因此,所有例項特定的資料,如 displaycommands,在硬編碼斷點之間都會被保留。(由 Tian Gao 在 gh-121450 中貢獻。)

  • pdb.Pdb 添加了一個新引數 mode。當 pdb 處於 inline 模式時,停用 restart 命令。(由 Tian Gao 在 gh-123757 中貢獻。)

  • 當用戶嘗試在 inline 模式下退出 pdb 時,會顯示一個確認提示。yY<Enter>EOF 將確認退出並呼叫 sys.exit(),而不是引發 bdb.BdbQuit。(由 Tian Gao 在 gh-124704 中貢獻。)

  • breakpoint()pdb.set_trace() 這樣的內聯斷點將始終在呼叫幀處停止程式,忽略 skip 模式(如果存在)。(由 Tian Gao 在 gh-130493 中貢獻。)

  • pdb 多行輸入的行首按 <tab> 現在將填充一個 4 空格的縮排,而不是插入一個 \t 字元。(由 Tian Gao 在 gh-130471 中貢獻。)

  • pdb 多行輸入中引入了自動縮排。它將保持上一行的縮排,或者在檢測到新程式碼塊時插入一個 4 空格的縮排。(由 Tian Gao 在 gh-133350 中貢獻。)

  • 添加了 $_asynctask 以在適用時訪問當前的 asyncio 任務。(由 Tian Gao 在 gh-124367 中貢獻。)

  • 添加了 pdb.set_trace_async() 以支援除錯 asyncio 協程。此函式支援 await 語句。(由 Tian Gao 在 gh-132576 中貢獻。)

  • pdb 中顯示的原始碼將進行語法高亮。此功能可以使用與預設互動式 shell 相同的方法來控制,此外還新增了 pdb.Pdbcolorize 引數。(由 Tian Gao 和 Łukasz Langa 在 gh-133355 中貢獻。)

pickle

  • pickle 模組上的預設協議版本設定為 5。更多詳情,請參閱pickle 協議

  • 為 pickle 序列化錯誤新增異常註釋,以幫助識別錯誤的來源。(由 Serhiy Storchaka 在 gh-122213 中貢獻。)

platform

  • 新增 invalidate_caches(),一個用於使 platform 模組中的快取結果無效的函式。(由 Bénédikt Tran 在 gh-122549 中貢獻。)

pydoc

  • 幫助輸出中的註解現在通常以更接近原始原始碼的格式顯示。(由 Jelle Zijlstra 在 gh-101552 中貢獻。)

re

  • 正則表示式 中支援將 \z 作為 \Z 的同義詞。與 \Z 不同(後者有細微的行為差異),\z 在許多其他正則表示式引擎中被明確地解釋。 (由 Serhiy Storchaka 在 gh-133306 中貢獻。)

  • 正則表示式 中的 \B 現在會匹配空輸入字串,這意味著它現在總是與 \b 相反。 (由 Serhiy Storchaka 在 gh-124130 中貢獻。)

socket

  • 改進並修復了對藍牙套接字的支援。

    • 修復了在 NetBSD 和 DragonFly BSD 上對藍牙套接字的支援。 (由 Serhiy Storchaka 在 gh-132429 中貢獻。)

    • 修復了在 FreeBSD 上對 BTPROTO_HCI 的支援。 (由 Victor Stinner 在 gh-111178 中貢獻。)

    • 在 FreeBSD 上增加了對 BTPROTO_SCO 的支援。 (由 Serhiy Storchaka 在 gh-85302 中貢獻。)

    • 在 FreeBSD 上為 BTPROTO_L2CAP 的地址增加了對 cidbdaddr_type 的支援。 (由 Serhiy Storchaka 在 gh-132429 中貢獻。)

    • 在 Linux 上為 BTPROTO_HCI 的地址增加了對 channel 的支援。 (由 Serhiy Storchaka 在 gh-70145 中貢獻。)

    • 在 Linux 上接受一個整數作為 BTPROTO_HCI 的地址。 (由 Serhiy Storchaka 在 gh-132099 中貢獻。)

    • BTPROTO_L2CAPgetsockname() 中返回 cid。 (由 Serhiy Storchaka 在 gh-132429 中貢獻。)

    • 添加了許多新常量。 (由 Serhiy Storchaka 在 gh-132734 中貢獻。)

ssl

  • 透過布林值 HAS_PHA 指示 ssl 模組是否支援 TLSv1.3 握手後客戶端認證 (PHA)。 (由 Will Childs-Klein 在 gh-128036 中貢獻。)

struct

  • struct 模組中支援 C 語言的 float complexdouble complex 型別(格式化字元分別為 'F''D')。 (由 Sergey B Kirpichev 在 gh-121249 中貢獻。)

symtable

sys

  • 之前未寫入文件的特殊函式 sys.getobjects(),僅存在於 Python 的特定構建版本中,現在可能返回來自其呼叫所在直譯器之外的其他直譯器的物件。 (由 Eric Snow 在 gh-125286 中貢獻。)

  • 添加了 sys._is_immortal() 用於判斷一個物件是否是 不可變 (immortal) 物件。 (由 Peter Bierma 在 gh-128509 中貢獻。)

  • 在 FreeBSD 上,sys.platform 不再包含主版本號。它始終為 'freebsd',而不是 'freebsd13''freebsd14'。 (由 Michael Osipov 在 gh-129393 中貢獻。)

  • sys._clear_type_cache() 引發 DeprecationWarning。該函式在 Python 3.13 中被棄用,但當時並未引發執行時警告。

  • 添加了 sys.remote_exec() 以實現新的外部偵錯程式介面。詳見 PEP 768。 (由 Pablo Galindo Salgado, Matt Wozniski 和 Ivona Stojanovic 在 gh-131591 中貢獻。)

  • 添加了 sys._jit 名稱空間,包含用於內省即時編譯的工具。 (由 Brandt Bucher 在 gh-133231 中貢獻。)

sys.monitoring

sysconfig

tarfile

threading

tkinter

  • 使得 tkinter 部件的方法 after()after_idle() 接受關鍵字引數。 (由 Zhikang Yan 在 gh-126899 中貢獻。)

  • 增加了為 tkinter.OptionMenutkinter.ttk.OptionMenu 指定名稱的功能。 (由 Zhikang Yan 在 gh-130482 中貢獻。)

turtle

types

typing

  • types.UnionTypetyping.Union 型別現在互為別名,這意味著舊式聯合型別(用 Union[int, str] 建立)和新式聯合型別(int | str)現在都會建立相同執行時型別的例項。這統一了兩種語法之間的行為,但也導致了一些行為差異,可能會影響在執行時對型別進行內省的使用者。

    • 現在,建立聯合型別的兩種語法在 repr() 中會產生相同的字串表示。例如,repr(Union[int, str]) 現在是 "int | str",而不是 "typing.Union[int, str]"

    • 使用舊語法建立的聯合型別不再被快取。以前,多次執行 Union[int, str] 會返回同一個物件(Union[int, str] is Union[int, str] 會是 True),但現在會返回兩個不同的物件。應使用 == 來比較聯合型別的相等性,而不是 is。新式聯合型別從未以這種方式被快取。對於使用大量透過對 typing.Union 進行下標操作建立的聯合型別的程式,此更改可能會增加記憶體使用量。然而,有幾個因素可以抵消這一成本:由於 PEP 649,Python 3.14 中預設不再對註解中使用的聯合型別進行求值;types.UnionType 的一個例項本身比之前 Python 版本中 Union[] 返回的物件小得多;移除快取也節省了一些空間。因此,此更改不太可能對大多數使用者造成顯著的記憶體使用增加。

    • 以前,舊式聯合型別是使用私有類 typing._UnionGenericAlias 實現的。這個類現在不再需要用於實現,但為了向後相容而保留,計劃在 Python 3.17 中移除。使用者應使用有文件的內省輔助函式,如 get_origin()typing.get_args(),而不是依賴於私有的實現細節。

    • 現在可以在 isinstance() 檢查中使用 typing.Union 本身。例如,isinstance(int | str, typing.Union) 將返回 True;以前這會引發 TypeError

    • typing.Union 物件的 __args__ 屬性不再是可寫的。

    • 現在不再可以在 Union 物件上設定任何屬性。這在以前的版本中僅對 dunder 屬性有效,從未被文件化為有效,並且在許多情況下存在細微的錯誤。

    (由 Jelle Zijlstra 在 gh-105499 中貢獻。)

  • TypeAliasType 現在支援星號解包。

unicodedata

  • Unicode 資料庫已更新至 Unicode 16.0.0。

unittest

urllib

  • 透過支援 RFC 7616 中指定的 SHA-256 摘要認證,升級了 urllib.request 的 HTTP 摘要認證演算法。 (由 Calvin Bui 在 gh-128193 中貢獻。)

  • 在解析和生成 file: URL 時,改善了易用性和標準合規性。

    url2pathname()

    • 當新的 require_scheme 引數設定為 true 時,接受一個完整的 URL。

    • 如果 URL 授權方與本地主機名匹配,則丟棄 URL 授權方。

    • 當新的 resolve_host 引數設定為 true 時,如果 URL 授權方解析為本地 IP 地址,則丟棄 URL 授權方。

    • 丟棄 URL 查詢和片段元件。

    • 如果 URL 授權方不是本地的,則引發 URLError,除非在 Windows 上,我們像以前一樣返回一個 UNC 路徑。

    pathname2url()

    • 當新的 add_scheme 引數設定為 true 時,返回一個完整的 URL。

    • 當路徑以斜槓開頭時,包含一個空的 URL 授權方。例如,路徑 /etc/hosts 被轉換為 URL ///etc/hosts

    在 Windows 上,驅動器號不再轉換為大寫,並且不在驅動器號後面的 : 字元不再導致引發 OSError 異常。

    (由 Barney Gale 在 gh-125866 中貢獻。)

uuid

webbrowser

  • BROWSER 環境變數中的名稱現在可以引用 webbrowser 模組中已註冊的瀏覽器,而不是總是生成一個新的瀏覽器命令。

    這使得可以將 BROWSER 設定為 macOS 上支援的某個瀏覽器的值。

zipfile

最佳化

asyncio

  • 由於為 原生任務 實現了一個新的每執行緒雙向連結串列,標準基準測試結果提高了 10-20%,同時也減少了記憶體使用。這使得外部內省工具(如 python -m asyncio pstree)能夠內省所有執行緒中執行的 asyncio 任務的呼叫圖。 (由 Kumar Aditya 在 gh-107803 中貢獻。)

  • 該模組現在對 自由執行緒構建 (free-threading builds) 提供了一流的支援。這使得多個事件迴圈可以在不同執行緒上並行執行,並隨執行緒數量線性擴充套件。 (由 Kumar Aditya 在 gh-128002 中貢獻。)

base64

  • b16decode() 的速度現在快了高達六倍。 (由 Bénédikt Tran, Chris Markiewicz, 和 Adam Turner 在 gh-118761 中貢獻。)

bdb

  • 基礎偵錯程式現在有了一個基於 sys.monitoring 的後端,可以透過將 'monitoring' 傳遞給 Bdb 類的新 backend 引數來選擇。 (由 Tian Gao 在 gh-124533 中貢獻。)

difflib

  • IS_LINE_JUNK() 函式的速度現在快了高達兩倍。 (由 Adam Turner 和 Semyon Moroz 在 gh-130167 中貢獻。)

gc

  • 新的增量垃圾回收器意味著對於較大的堆,最大暫停時間減少了一個數量級或更多。

    由於此最佳化,get_threshold()set_threshold() 的結果含義發生了變化,get_count()get_stats() 也是如此。

    • 為了向後相容,get_threshold() 繼續返回一個三元組。第一個值是年輕代回收的閾值,和以前一樣;第二個值決定了老年代被掃描的速率(預設為 10,更高的值意味著老年代被掃描得更慢)。第三個值現在沒有意義,並且總是零。

    • set_threshold() 現在會忽略第二個之後的所有項。

    • get_count()get_stats() 繼續返回相同格式的結果。唯一的區別是,結果不再指代年輕代、老化代和老年代,而是指代年輕代以及老年代的老化空間和回收空間。

    總而言之,試圖操縱迴圈垃圾回收器行為的程式碼可能無法完全按預期工作,但很可能不會造成危害。所有其他程式碼都將正常工作。

    (由 Mark Shannon 在 gh-108362 中貢獻。)

io

  • 開啟和讀取檔案現在執行的系統呼叫更少。完整讀取一個小的作業系統快取檔案,速度提高了高達 15%。 (由 Cody Maloney 和 Victor Stinner 在 gh-120754gh-90102 中貢獻。)

pathlib

  • Path.read_bytes 現在使用無緩衝模式開啟檔案,完整讀取速度提高了 9% 到 17%。 (由 Cody Maloney 在 gh-120754 中貢獻。)

pdb

uuid

  • 對於 16 位元組的名稱,uuid3()uuid5() 現在都快了大約 40%;對於 1024 位元組的名稱,快了 20%。對於更長的名稱,效能保持不變。 (由 Bénédikt Tran 在 gh-128150 中貢獻。)

  • uuid4() 現在快了約 30%。 (由 Bénédikt Tran 在 gh-128150 中貢獻。)

zlib

  • 在 Windows 上,zlib-ng 現在被用作預設二進位制檔案中 zlib 模組的實現。在 zlib-ng 和之前使用的 zlib 實現之間沒有已知的相容性問題。這應該會在所有壓縮級別上帶來更好的效能。

    值得注意的是,zlib.Z_BEST_SPEED (1) 可能會導致比以前的實現壓縮率顯著降低,同時壓縮時間也顯著減少。

    (由 Steve Dower 在 gh-91349 中貢獻。)

已移除

argparse

  • 移除了 BooleanOptionalActiontypechoicesmetavar 引數。這些引數自 Python 3.12 起已被棄用。 (由 Nikita Sobolev 在 gh-118805 中貢獻。)

  • 在引數組上呼叫 add_argument_group() 現在會引發 ValueError。同樣,在互斥組上呼叫 add_argument_group()add_mutually_exclusive_group() 現在都會引發 ValueError。這種“巢狀”從未被支援,經常無法正常工作,並且是透過繼承無意中暴露出來的。該功能自 Python 3.11 起已被棄用。 (由 Savannah Ostrowski 在 gh-127186 中貢獻。)

ast

  • 移除了以下類,它們自 Python 3.8 起是 Constant 的棄用別名,並自 Python 3.12 起發出棄用警告

    • Bytes

    • Ellipsis

    • NameConstant

    • Num

    • Str

    由於這些移除,當 NodeVisitor 子類訪問 AST 時,自定義 NodeVisitor 子類上使用者定義的 visit_Numvisit_Strvisit_Bytesvisit_NameConstantvisit_Ellipsis 方法將不再被呼叫。請改用定義 visit_Constant 方法。

    (由 Alex Waygood 在 gh-119562 中貢獻。)

  • 移除了 ast.Constant 上以下已棄用的屬性,這些屬性是為了與現已移除的 AST 類相容而存在的

    • Constant.n

    • Constant.s

    請改用 Constant.value。 (由 Alex Waygood 在 gh-119562 中貢獻。)

asyncio

  • 移除了以下自 Python 3.12 起已被棄用的類、方法和函式

    • AbstractChildWatcher

    • FastChildWatcher

    • MultiLoopChildWatcher

    • PidfdChildWatcher

    • SafeChildWatcher

    • ThreadedChildWatcher

    • AbstractEventLoopPolicy.get_child_watcher()

    • AbstractEventLoopPolicy.set_child_watcher()

    • get_child_watcher()

    • set_child_watcher()

    (由 Kumar Aditya 在 gh-120804 中貢獻。)

  • 如果沒有當前的事件迴圈,asyncio.get_event_loop() 現在會引發 RuntimeError,並且不再隱式建立事件迴圈。

    (由 Kumar Aditya 在 gh-126353 中貢獻。)

    有一些使用 asyncio.get_event_loop() 的模式,其中大多數可以用 asyncio.run() 替代。

    如果你正在執行一個非同步函式,只需使用 asyncio.run()

    之前

    async def main():
        ...
    
    
    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(main())
    finally:
        loop.close()
    

    之後

    async def main():
        ...
    
    asyncio.run(main())
    

    如果你需要啟動某個東西,例如,一個監聽套接字的伺服器,然後永遠執行,請使用 asyncio.run() 和一個 asyncio.Event

    之前

    def start_server(loop): ...
    
    loop = asyncio.get_event_loop()
    try:
        start_server(loop)
        loop.run_forever()
    finally:
        loop.close()
    

    之後

    def start_server(loop): ...
    
    async def main():
        start_server(asyncio.get_running_loop())
        await asyncio.Event().wait()
    
    asyncio.run(main())
    

    如果你需要在事件迴圈中執行某個東西,然後在它周圍執行一些阻塞程式碼,請使用 asyncio.Runner

    之前

    async def operation_one(): ...
    def blocking_code(): ...
    async def operation_two(): ...
    
    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(operation_one())
        blocking_code()
        loop.run_until_complete(operation_two())
    finally:
        loop.close()
    

    之後

    async def operation_one(): ...
    def blocking_code(): ...
    async def operation_two(): ...
    
    with asyncio.Runner() as runner:
        runner.run(operation_one())
        blocking_code()
        runner.run(operation_two())
    

email

  • 移除了 email.utils.localtime()isdst 引數,該引數在 Python 3.12 中被棄用並一直被忽略。 (由 Hugo van Kemenade 在 gh-118798 中貢獻。)

importlib.abc

itertools

  • 移除了對 itertools 迭代器的複製、深複製和序列化操作的支援。這些操作自 Python 3.12 起已發出 DeprecationWarning。 (由 Raymond Hettinger 在 gh-101588 中貢獻。)

pathlib

  • 移除了對向 Path 傳遞額外關鍵字引數的支援。在以前的版本中,任何此類引數都會被忽略。 (由 Barney Gale 在 gh-74033 中貢獻。)

  • 移除了對向 PurePath.relative_to()is_relative_to() 傳遞額外位置引數的支援。在以前的版本中,任何此類引數都會被連線到 other 上。 (由 Barney Gale 在 gh-78707 中貢獻。)

pkgutil

  • 移除了 get_loader()find_loader() 函式,這些函式自 Python 3.12 起已被棄用。 (由 Bénédikt Tran 在 gh-97850 中貢獻。)

pty

  • 移除了 master_open()slave_open() 函式,這些函式自 Python 3.12 起已被棄用。請改用 pty.openpty()。 (由 Nikita Sobolev 在 gh-118824 中貢獻。)

sqlite3

urllib

  • urllib.parse 中移除了 Quoter 類,該類自 Python 3.11 起已被棄用。 (由 Nikita Sobolev 在 gh-118827 中貢獻。)

  • urllib.request 中移除了 URLopenerFancyURLopener 類,這些類自 Python 3.3 起已被棄用。

    myopener.open() 可以用 urlopen() 替換。myopener.retrieve() 可以用 urlretrieve() 替換。對 opener 類的自定義可以透過向 build_opener() 傳遞自定義處理程式來替換。 (由 Barney Gale 在 gh-84850 中貢獻。)

已棄用

新的棄用項

將在 Python 3.15 中移除

  • 匯入系統

    • 在模組上設定 __cached__ 但未設定 __spec__.cached 的做法已被棄用。在 Python 3.15 中,匯入系統或標準庫將不再設定或考慮 __cached__。(gh-97879)

    • 在模組上設定 __package__ 但未設定 __spec__.parent 的做法已被棄用。在 Python 3.15 中,匯入系統或標準庫將不再設定或考慮 __package__。(gh-97879)

  • ctypes:

    • 未寫入文件的 ctypes.SetPointerType() 函式自 Python 3.13 起已被棄用。

  • http.server:

    • 已過時且很少使用的 CGIHTTPRequestHandler 自 Python 3.13 起已被棄用。沒有直接的替代品。在將 Web 伺服器與請求處理程式連線方面,任何方式 都比 CGI 更好。

    • python -m http.server 命令列介面的 --cgi 旗標自 Python 3.13 起已被棄用。

  • importlib:

    • load_module() 方法:請改用 exec_module()

  • locale:

  • pathlib:

  • platform:

    • java_ver() 自 Python 3.13 起已被棄用。此函式僅對 Jython 支援有用,其 API 令人困惑,且基本未經測試。

  • sysconfig:

  • threading:

    • RLock() 在 Python 3.15 中將不接受任何引數。傳遞任何引數的做法自 Python 3.14 起已被棄用,因為 Python 版本不允許任何引數,但 C 版本允許任意數量的位置或關鍵字引數,並忽略所有引數。

  • types:

  • typing:

    • 用於建立 NamedTuple 類的未寫入文件的關鍵字引數語法(例如,Point = NamedTuple("Point", x=int, y=int))自 Python 3.13 起已被棄用。請改用基於類的語法或函式式語法。

    • 當使用 TypedDict 的函式式語法時,未向 fields 引數傳遞值 (TD = TypedDict("TD")) 或傳遞 None (TD = TypedDict("TD", None)) 的做法自 Python 3.13 起已被棄用。要建立一個沒有欄位的 TypedDict,請使用 class TD(TypedDict): passTD = TypedDict("TD", {})

    • typing.no_type_check_decorator() 裝飾器函式自 Python 3.13 起已被棄用。在 typing 模組中存在八年後,它仍未被任何主流型別檢查器支援。

  • wave:

  • zipimport:

將在 Python 3.16 中移除

將在 Python 3.17 中移除

  • collections.abc:

    • collections.abc.ByteString 計劃在 Python 3.17 中移除。

      使用 isinstance(obj, collections.abc.Buffer) 在執行時測試 obj 是否實現了緩衝區協議。在型別註解中使用時,請使用 Buffer 或明確指定程式碼支援的型別的聯合型別(例如,bytes | bytearray | memoryview)。

      ByteString 最初旨在作為一個抽象類,作為 bytesbytearray 的超型別。然而,由於該 ABC 從未有過任何方法,知道一個物件是 ByteString 的例項實際上並不能告訴你任何關於該物件的有用資訊。其他常見的緩衝區型別,如 memoryview,也從未被理解為 ByteString 的子型別(無論是在執行時還是由靜態型別檢查器)。

      更多細節請參閱 PEP 688。 (由 Shantanu Jain 在 gh-91896 中貢獻。)

  • typing:

    • 在 Python 3.14 之前,舊式聯合型別是使用私有類 typing._UnionGenericAlias 實現的。該類不再是實現所必需的,但為了向後相容而保留,計劃在 Python 3.17 中移除。使用者應使用已寫入文件的內省輔助工具,如 typing.get_origin()typing.get_args(),而不是依賴於私有的實現細節。

    • typing.ByteString,自 Python 3.9 起被棄用,計劃在 Python 3.17 中移除。

      使用 isinstance(obj, collections.abc.Buffer) 在執行時測試 obj 是否實現了緩衝區協議。在型別註解中使用時,請使用 Buffer 或明確指定程式碼支援的型別的聯合型別(例如,bytes | bytearray | memoryview)。

      ByteString 最初旨在作為一個抽象類,作為 bytesbytearray 的超型別。然而,由於該 ABC 從未有過任何方法,知道一個物件是 ByteString 的例項實際上並不能告訴你任何關於該物件的有用資訊。其他常見的緩衝區型別,如 memoryview,也從未被理解為 ByteString 的子型別(無論是在執行時還是由靜態型別檢查器)。

      更多細節請參閱 PEP 688。 (由 Shantanu Jain 在 gh-91896 中貢獻。)

將在 Python 3.19 中移除

  • ctypes:

    • 在非 Windows 平臺上,透過設定 _pack_ 但不設定 _layout_ 來隱式切換到與 MSVC 相容的結構佈局。

將在未來版本中移除

以下 API 將在未來被移除,但目前尚未確定移除日期。

  • argparse:

    • 巢狀引數組和巢狀互斥組的做法已被棄用。

    • add_argument_group() 傳遞未寫入文件的關鍵字引數 prefix_chars 的做法現已棄用。

    • argparse.FileType 型別轉換器已被棄用。

  • builtins:

    • 生成器:throw(type, exc, tb)athrow(type, exc, tb) 簽名已被棄用:請改用 throw(exc)athrow(exc),即單引數簽名。

    • 目前 Python 接受數字字面量緊跟關鍵字,例如 0in x1or x0if 1else 2。這允許了令人困惑和有歧義的表示式,如 [0x1for x in y](可以解釋為 [0x1 for x in y][0x1f or x in y])。如果數字字面量緊跟關鍵字 andelseforifinisor,則會引發語法警告。在未來的版本中,這將改為語法錯誤。 (gh-87999)

    • __index__()__int__() 方法返回非 int 型別的支援:這些方法將被要求返回 int 的嚴格子類的例項。

    • __float__() 方法返回 float 的嚴格子類的支援:這些方法將被要求返回 float 的例項。

    • __complex__() 方法返回 complex 的嚴格子類的支援:這些方法將被要求返回 complex 的例項。

    • int() 委託給 __trunc__() 方法。

    • complex() 建構函式中將複數作為 realimag 引數傳遞的做法現已棄用;它應該只作為單個位置引數傳遞。 (由 Serhiy Storchaka 在 gh-109218 中貢獻。)

  • calendar: calendar.Januarycalendar.February 常量已被棄用,並由 calendar.JANUARYcalendar.FEBRUARY 替代。 (由 Prince Roshan 在 gh-103636 中貢獻。)

  • codecs: 請使用 open() 代替 codecs.open()。 (gh-133038)

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

  • datetime:

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

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

  • gettext: 複數值必須是整數。

  • importlib:

  • importlib.metadata:

    • EntryPoints 元組介面。

    • 返回值的隱式 None

  • logging: warn() 方法自 Python 3.3 起已被棄用,請改用 warning()

  • mailbox: 使用 StringIO 輸入和文字模式的做法已被棄用,請改用 BytesIO 和二進位制模式。

  • os: 在多執行緒程序中呼叫 os.register_at_fork()

  • pydoc.ErrorDuringImport: 為 exc_info 引數使用元組值的做法已被棄用,請改用異常例項。

  • re: 現在對正則表示式中的數字組引用和組名應用了更嚴格的規則。只有 ASCII 數字序列現在被接受為數字引用。位元組模式和替換字串中的組名現在只能包含 ASCII 字母、數字和下劃線。 (由 Serhiy Storchaka 在 gh-91760 中貢獻。)

  • sre_compilesre_constantssre_parse 模組。

  • shutil: rmtree()onerror 引數在 Python 3.12 中已被棄用;請改用 onexc 引數。

  • ssl 選項和協議

    • 不帶協議引數的 ssl.SSLContext 已被棄用。

    • ssl.SSLContext: set_npn_protocols()selected_npn_protocol() 已被棄用:請改用 ALPN。

    • ssl.OP_NO_SSL* 選項

    • ssl.OP_NO_TLS* 選項

    • ssl.PROTOCOL_SSLv3

    • ssl.PROTOCOL_TLS

    • ssl.PROTOCOL_TLSv1

    • ssl.PROTOCOL_TLSv1_1

    • ssl.PROTOCOL_TLSv1_2

    • ssl.TLSVersion.SSLv3

    • ssl.TLSVersion.TLSv1

    • ssl.TLSVersion.TLSv1_1

  • threading 方法

  • typing.Text (gh-92332)。

  • 內部類 typing._UnionGenericAlias 不再用於實現 typing.Union。為了保持與使用此私有類的使用者的相容性,將提供一個相容性墊片,直到至少 Python 3.17。 (由 Jelle Zijlstra 在 gh-105499 中貢獻。)

  • unittest.IsolatedAsyncioTestCase: 從測試用例返回非 None 的值的做法已被棄用。

  • urllib.parse 已棄用的函式:請改用 urlparse()

    • splitattr()

    • splithost()

    • splitnport()

    • splitpasswd()

    • splitport()

    • splitquery()

    • splittag()

    • splittype()

    • splituser()

    • splitvalue()

    • to_bytes()

  • wsgiref: SimpleHandler.stdout.write() 不應進行部分寫入。

  • xml.etree.ElementTree: 測試 Element 的真值已被棄用。在未來的版本中,它將始終返回 True。請優先使用顯式的 len(elem)elem is not None 測試。

  • sys._clear_type_cache() 已被棄用:請改用 sys._clear_internal_caches()

CPython 位元組碼變更

偽指令

  • 新增 ANNOTATIONS_PLACEHOLDER 偽指令,以支援透過延遲求值註解來處理部分執行的模組級註解。 (由 Jelle Zijlstra 在 gh-130907 中貢獻。)

  • 新增 BINARY_OP_EXTEND 偽指令,它執行從內聯快取中訪問的一對函式(保護函式和特化函式)。 (由 Irit Katriel 在 gh-100239 中貢獻。)

  • CALL_KW 新增三個特化版本;CALL_KW_PY 用於呼叫 Python 函式,CALL_KW_BOUND_METHOD 用於呼叫繫結方法,CALL_KW_NON_PY 用於所有其他呼叫。 (由 Mark Shannon 在 gh-118093 中貢獻。)

  • 新增 JUMP_IF_TRUEJUMP_IF_FALSE 偽指令,它們是不影響棧的條件跳轉。被 COPY 1TO_BOOLPOP_JUMP_IF_TRUE/FALSE 序列所取代。 (由 Irit Katriel 在 gh-124285 中貢獻。)

  • 新增 LOAD_CONST_MORTAL 偽指令。 (由 Mark Shannon 在 gh-128685 中貢獻。)

  • 新增 LOAD_CONST_IMMORTAL 偽指令,其功能與 LOAD_CONST 相同,但對於不朽物件更高效。 (由 Mark Shannon 在 gh-125837 中貢獻。)

  • 新增 NOT_TAKEN 偽指令,由 sys.monitoring 用於記錄分支事件(如 BRANCH_LEFT)。 (由 Mark Shannon 在 gh-122548 中貢獻。)

C API 變更

Python 配置 C API

新增一個 PyInitConfig C API,用於配置 Python 初始化,而不依賴於 C 結構體,並能夠在未來進行 ABI 相容的更改。

透過新增 PyInitConfig_AddModule() 來完善 PEP 587PyConfig C API,該函式可用於新增內建擴充套件模組;這個功能之前被稱為“inittab”。

新增 PyConfig_Get()PyConfig_Set() 函式,以獲取和設定當前執行時配置。

PEP 587 “Python 初始化配置”統一了所有配置 Python 初始化的方式。此 PEP 還將 Python 的預初始化和初始化的配置統一到單個 API 中。此外,此 PEP 只為嵌入 Python 提供了一個單一的選擇,而不是像(PEP 587)那樣提供“Python”和“Isolated”兩個選擇,從而進一步簡化了 API。

對於需要與 CPython 實現細節有更高耦合度的用例(例如模擬 CPython CLI 的全部功能,包括其配置機制),較低級別的 PEP 587 PyConfig API 仍然可用。

(由 Victor Stinner 在 gh-107954 中貢獻。)

參見

PEP 741PEP 587

C API 中的新功能

受限 C API 變更

已移除的 C API

  • 在 Python 3.12 中,使用可變基類建立 不可變型別 已被棄用,現在會引發 TypeError。(由 Nikita Sobolev 在 gh-119775 中貢獻。)

  • 移除在 Python 3.12 中已棄用的 PyDictObject.ma_version_tag 成員。請改用 PyDict_AddWatcher() API。(由 Sam Gross 在 gh-124296 中貢獻。)

  • 移除私有函式 _Py_InitializeMain()。這是 PEP 587 在 Python 3.8 中新增的一個臨時 API。(由 Victor Stinner 在 gh-129033 中貢獻。)

  • 移除未在文件中載明的 API Py_C_RECURSION_LIMITPyThreadState.c_recursion_remaining。它們是在 3.13 中新增的,現已被移除而未經過棄用流程。請使用 Py_EnterRecursiveCall() 來防止 C 程式碼中出現失控遞迴。(由 Petr Viktorin 在 gh-133079 中移除,另請參閱 gh-130396。)

已棄用的 C API

將在 Python 3.15 中移除

將在 Python 3.16 中移除

  • 捆綁的 libmpdec 副本。

將在 Python 3.18 中移除

將在未來版本中移除

以下 API 已被棄用,並將在未來被移除,但目前尚未確定移除日期。

構建方面的變化

  • PEP 776:Emscripten 現在是第 3 級的官方支援平臺。作為這項工作的一部分,修復了 Emscripten libc 中的 25 個以上錯誤。Emscripten 現在支援 ctypestermiosfcntl,並對新的預設互動式 Shell 提供了實驗性支援。(由 R. Hood Chatham 在 gh-127146gh-127683gh-136931 中貢獻。)

  • 現在 python.org 上提供了官方的 Android 二進位制發行版。

  • 現在需要 GNU Autoconf 2.72 來生成 configure。(由 Erlend Aasland 在 gh-115765 中貢獻。)

  • wasm32-unknown-emscripten 現在是PEP 11 的第 3 級平臺。(由 R. Hood Chatham 在 gh-127146gh-127683gh-136931 中貢獻。)

  • 現在可以透過 Py_NO_LINK_LIB 關閉基於 #pragma 的與 python3*.lib 的連結。(由 Jean-Christophe Fillion-Robin 在 gh-82909 中貢獻。)

  • CPython 現在預設啟用一組推薦的編譯器選項以提高安全性。使用 --disable-safety configure 選項可停用它們,或使用 --enable-slower-safety 選項以啟用更大範圍的編譯器選項,但這會帶來效能開銷。

  • WITH_FREELISTS 宏和 --without-freelists configure 選項已被移除。

  • 新的 configure 選項 --with-tail-call-interp 可用於啟用實驗性的尾呼叫直譯器。更多細節請參閱一種新型直譯器

  • 要停用新的遠端除錯支援,請使用 --without-remote-debug configure 選項。出於安全原因,這可能很有用。

  • iOS 和 macOS 應用程式現在可以配置為將 stdoutstderr 的內容重定向到系統日誌。(由 Russell Keith-Magee 在 gh-127592 中貢獻。)

  • iOS 測試平臺現在能夠在測試執行時流式傳輸測試輸出。該測試平臺還可用於執行 CPython 以外的專案的測試套件。(由 Russell Keith-Magee 在 gh-127592 中貢獻。)

build-details.json

Python 的安裝現在包含一個新檔案 build-details.json。這是一個靜態 JSON 文件,包含 CPython 的構建細節,以便在無需執行程式碼的情況下進行內省。這對於 Python 啟動器、交叉編譯等用例很有幫助。

build-details.json 必須安裝在平臺無關的標準庫目錄中。這對應於 ‘stdlib’ sysconfig 安裝路徑,可透過執行 sysconfig.get_path('stdlib') 找到。

參見

PEP 739build-details.json 1.0 – 一個描述 Python 構建細節的靜態檔案

停止使用 PGP 簽名

Python 3.14 或未來版本的釋出將不再提供 PGP (Pretty Good Privacy) 簽名。要驗證 CPython 的構建產物,使用者必須使用 Sigstore 驗證材料。自 Python 3.11 起,釋出版本已開始使用 Sigstore 進行簽名。

釋出流程的這一變化在 PEP 761 中有詳細說明。

自由執行緒 Python 獲官方支援

Python 的自由執行緒構建版本現在已獲得支援,不再是實驗性的。這是 第二階段 的開始,自由執行緒 Python 獲得官方支援,但仍然是可選的。

自由執行緒團隊相信該專案正走在正確的道路上,並感謝所有為使自由執行緒在 Python 社群中得到更廣泛應用而持續奉獻的人們。

隨著這些建議和此 PEP 的接受,Python 開發者社群應廣泛宣傳自由執行緒現在和將來都是一個受支援的 Python 構建選項,並且在沒有適當的棄用時間表的情況下不會被移除。

任何關於進入 第三階段,將自由執行緒作為 Python 的預設或唯一構建版本的決定都尚未確定,這取決於 CPython 內部和社群的許多因素。這個決定留待未來。

實驗性即時編譯器的二進位制發行版

官方的 macOS 和 Windows 二進位制發行版現在包含一個*實驗性*的即時 (JIT) 編譯器。雖然它**不**推薦用於生產環境,但可以透過設定環境變數 PYTHON_JIT=1 來進行測試。下游的原始碼構建和再分發者可以使用 --enable-experimental-jit=yes-off 配置選項以獲得類似的行為。

JIT 仍處於早期階段,並在積極開發中。因此,啟用它對效能的典型影響範圍從慢 10% 到快 20% 不等,具體取決於工作負載。為了幫助測試和評估,sys._jit 名稱空間中提供了一組內省函式。sys._jit.is_available() 可用於確定當前可執行檔案是否支援 JIT 編譯,而 sys._jit.is_enabled() 可用於判斷當前程序是否已啟用 JIT 編譯。

目前,最主要的功能缺失是,像 gdbperf 這樣的原生偵錯程式和效能分析器無法透過 JIT 幀進行堆疊回溯(Python 偵錯程式和效能分析器,如 pdbprofile,則可以繼續正常工作)。自由執行緒構建版本不支援 JIT 編譯。

如果您遇到任何錯誤或重大的效能迴歸,請報告!

參見

PEP 744

移植到 Python 3.14

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

Python API 的變化

  • 在除 macOS 以外的 Unix 平臺上,forkserver 現在是 multiprocessingProcessPoolExecutor 的預設啟動方法,取代了 fork

    詳情請見 (1)(2)

    如果您遇到來自 multiprocessingconcurrent.futuresNameError 或 pickling 錯誤,請參閱forkserver 限制

    此更改不影響 Windows 或 macOS,在這兩個平臺上 ‘spawn’ 仍然是預設的啟動方法。

  • functools.partial 現在是一個方法描述符。如果您想保留舊的行為,請用 staticmethod() 包裝它。(由 Serhiy Storchaka 和 Dominykas Grigonis 在 gh-121027 中貢獻。)

  • 垃圾回收器現在是增量式的,這意味著 gc.collect() 的行為略有變化

    • gc.collect(1): 執行一次增量垃圾回收,而不是收集第 1 代。

    • gc.collect() 的其他呼叫保持不變。

  • locale.nl_langinfo() 函式現在在某些情況下會臨時設定 LC_CTYPE locale。這種臨時更改會影響其他執行緒。(由 Serhiy Storchaka 在 gh-69998 中貢獻。)

  • types.UnionType 現在是 typing.Union 的別名,導致某些行為發生變化。更多細節請參閱上文。(由 Jelle Zijlstra 在 gh-105499 中貢獻。)

  • 註解的執行時行為在多個方面發生了變化;詳情請見上文。雖然大多數與註解互動的程式碼應能繼續工作,但一些未在文件中載明的細節可能會有不同的表現。

  • 作為將 mimetypes CLI 公開的一部分,它現在在失敗時以 1 退出,而不是 0,在命令列引數不正確時以 2 退出,而不是 1。錯誤訊息現在會列印到 stderr。

  • 正則表示式中的 \B 模式現在在作為整個模式給出時匹配空字串,這可能會導致行為變化。

  • 在 FreeBSD 上,sys.platform 不再包含主版本號。

註解的變化 (PEP 649PEP 749)

本節提供了關於註解或與註解互動或內省的 Python 程式碼可能需要進行的更改的指導,這些更改是由於註解的延遲求值相關的變化所致。

在大多數情況下,舊版本 Python 中的有效程式碼不需要任何更改。

對帶註解程式碼的影響

如果您在程式碼中定義了註解(例如,用於靜態型別檢查器),那麼此更改可能不會影響您:您可以像在以前版本的 Python 中一樣繼續編寫註解。

您很可能可以移除註解中的帶引號字串,這些字串通常用於前向引用。類似地,如果您使用 from __future__ import annotations 來避免在註解中編寫字串,那麼一旦您只支援 Python 3.14 及更高版本,您很可能可以移除該匯入。但是,如果您依賴於讀取註解的第三方庫,這些庫可能需要進行更改以支援不帶引號的註解,才能按預期工作。

__annotations__ 讀取者的影響

如果您的程式碼讀取物件上的 __annotations__ 屬性,您可能需要進行更改以支援依賴於註解延遲求值的程式碼。例如,您可能希望使用帶 FORWARDREF 格式的 annotationlib.get_annotations(),就像 dataclasses 模組現在所做的那樣。

外部 typing_extensions 包提供了對 annotationlib 模組部分功能的向後移植,例如 Format 列舉和 get_annotations() 函式。這些可以用於編寫利用 Python 3.14 中新行為的跨版本程式碼。

from __future__ import annotations

在 Python 3.7 中,PEP 563 引入了 from __future__ import annotations future 語句,它將所有註解都轉換為字串。

但是,此語句現已棄用,並預計將在未來的 Python 版本中移除。此移除將不會在 Python 3.13(最後一個不支援註解延遲求值的 Python 版本)於 2029 年結束生命週期之後發生。

在 Python 3.14 中,使用 from __future__ import annotations 的程式碼的行為保持不變。

C API 的變化

  • Py_Finalize() 現在會刪除所有駐留字串。這對於任何在呼叫 Py_Finalize() 後仍持有駐留字串,並在呼叫 Py_Initialize() 後重新使用的 C 擴充套件都是向後不相容的。由此行為引起的任何問題通常會導致在後續呼叫 Py_Initialize() 時因訪問未初始化的記憶體而崩潰。要修復此問題,請使用地址消毒劑來識別任何來自駐留字串的釋放後使用,並在模組關閉期間釋放它。(由 Eddie Elizondo 在 gh-113601 中貢獻。)

  • 如果Unicode 異常物件 C API 的異常引數不是 UnicodeError 物件,它現在會引發 TypeError。(由 Bénédikt Tran 在 gh-127691 中貢獻。)