Python 3.5 中的新功能

編輯:

Elvis Pranskevichus <elvis@magic.io>, Yury Selivanov <yury@magic.io>

本文介紹了 Python 3.5 相對於 3.4 的新功能。Python 3.5 於 2015 年 9 月 13 日釋出。有關完整的更改列表,請參閱變更日誌

另請參閱

PEP 478 - Python 3.5 釋出計劃

摘要 – 版本亮點

新語法特性

  • PEP 492,帶有 async 和 await 語法的協程。

  • PEP 465,新的矩陣乘法運算子:a @ b

  • PEP 448,額外的解包泛化。

新庫模組

新的內建特性

  • bytes % args, bytearray % args: PEP 461 – 向 bytes 和 bytearray 新增 % 格式化。

  • 新的 bytes.hex(), bytearray.hex()memoryview.hex() 方法。(由 Arnon Yaari 在 bpo-9951 中貢獻。)

  • memoryview 現在支援元組索引(包括多維)。(由 Antoine Pitrou 在 bpo-23632 中貢獻。)

  • 生成器有一個新的 gi_yieldfrom 屬性,它返回 yield from 表示式迭代的物件。(由 Benno Leslie 和 Yury Selivanov 在 bpo-24450 中貢獻。)

  • 當達到最大遞迴深度時,現在會引發一個新的 RecursionError 異常。(由 Georg Brandl 在 bpo-19235 中貢獻。)

CPython 實現改進

  • LC_TYPE 區域設定為 POSIX 區域(C 區域)時,sys.stdinsys.stdout 現在使用 surrogateescape 錯誤處理程式,而不是 strict 錯誤處理程式。(由 Victor Stinner 在 bpo-19977 中貢獻。)

  • .pyo 檔案不再使用,並已被更靈活的方案取代,該方案在 .pyc 名稱中顯式包含最佳化級別。(請參閱PEP 488 概述。)

  • 內建模組和擴充套件模組現在以多階段過程初始化,這類似於 Python 模組的載入方式。(請參閱PEP 489 概述。)

標準庫中的重大改進

安全改進

  • SSLv3 現在已在整個標準庫中停用。 仍然可以透過手動例項化 ssl.SSLContext 來啟用它。(有關更多詳細資訊,請參閱 bpo-22638;此更改已向後移植到 CPython 3.4 和 2.7。)

  • 為了防止潛在的注入攻擊,HTTP cookie 解析現在更加嚴格。(由 Antoine Pitrou 在 bpo-22796 中貢獻。)

Windows 改進

  • 一個新的 Windows 安裝程式已取代舊的 MSI。有關更多資訊,請參閱 在 Windows 上使用 Python

  • Windows 構建現在使用 Microsoft Visual C++ 14.0,擴充套件模組應使用相同的版本。

請繼續閱讀以獲取面向使用者的更改的全面列表,其中包括許多其他小的改進、CPython 最佳化、棄用和潛在的移植問題。

新功能

PEP 492 - 具有 async 和 await 語法的協程

PEP 492 透過新增 可等待物件協程函式非同步迭代非同步上下文管理器,極大地改進了 Python 中對非同步程式設計的支援。

協程函式使用新的 async def 語法宣告

>>> async def coro():
...     return 'spam'

在協程函式內部,可以使用新的 await 表示式來掛起協程的執行,直到結果可用。 只要物件透過定義 __await__() 方法來實現 可等待 協議,就可以 _await_ 任何物件。

PEP 492 還添加了 async for 語句,以便方便地遍歷非同步可迭代物件。

使用新語法編寫的簡陋 HTTP 客戶端的示例

import asyncio

async def http_get(domain):
    reader, writer = await asyncio.open_connection(domain, 80)

    writer.write(b'\r\n'.join([
        b'GET / HTTP/1.1',
        b'Host: %b' % domain.encode('latin-1'),
        b'Connection: close',
        b'', b''
    ]))

    async for line in reader:
        print('>>>', line)

    writer.close()

loop = asyncio.get_event_loop()
try:
    loop.run_until_complete(http_get('example.com'))
finally:
    loop.close()

與非同步迭代類似,還有一種用於非同步上下文管理器的新語法。 以下指令碼

import asyncio

async def coro(name, lock):
    print('coro {}: waiting for lock'.format(name))
    async with lock:
        print('coro {}: holding the lock'.format(name))
        await asyncio.sleep(1)
        print('coro {}: releasing the lock'.format(name))

loop = asyncio.get_event_loop()
lock = asyncio.Lock()
coros = asyncio.gather(coro(1, lock), coro(2, lock))
try:
    loop.run_until_complete(coros)
finally:
    loop.close()

將輸出

coro 2: waiting for lock
coro 2: holding the lock
coro 1: waiting for lock
coro 2: releasing the lock
coro 1: holding the lock
coro 1: releasing the lock

請注意,async forasync with 只能在用 async def 宣告的協程函式內部使用。

協程函式旨在在相容的事件迴圈(例如 asyncio 迴圈)內執行。

注意

在 3.5.2 版本中更改:從 CPython 3.5.2 開始,__aiter__ 可以直接返回 非同步迭代器。 返回 可等待 物件將導致 PendingDeprecationWarning

有關更多詳細資訊,請參閱 非同步迭代器 文件部分。

另請參閱

PEP 492 – 具有 async 和 await 語法的協程

由 Yury Selivanov 編寫和實現的 PEP。

PEP 465 - 用於矩陣乘法的專用中綴運算子

PEP 465 為矩陣乘法添加了 @ 中綴運算子。 目前,沒有內建的 Python 型別實現新的運算子,但是可以透過為常規、反射和就地矩陣乘法定義 __matmul__()__rmatmul__()__imatmul__() 來實現。 這些方法的語義類似於定義其他中綴算術運算子的方法的語義。

矩陣乘法在數學、科學、工程的許多領域中都是一項非常常見的運算,而 @ 的新增允許編寫更簡潔的程式碼

S = (H @ beta - r).T @ inv(H @ V @ H.T) @ (H @ beta - r)

而不是

S = dot((dot(H, beta) - r).T,
        dot(inv(dot(dot(H, V), H.T)), dot(H, beta) - r))

NumPy 1.10 支援新運算子

>>> import numpy

>>> x = numpy.ones(3)
>>> x
array([ 1., 1., 1.])

>>> m = numpy.eye(3)
>>> m
array([[ 1., 0., 0.],
       [ 0., 1., 0.],
       [ 0., 0., 1.]])

>>> x @ m
array([ 1., 1., 1.])

另請參閱

PEP 465 – 用於矩陣乘法的專用中綴運算子

由 Nathaniel J. Smith 撰寫;由 Benjamin Peterson 實現的 PEP。

PEP 448 - 額外的解包泛化

PEP 448 擴充套件了 * 可迭代解包運算子和 ** 字典解包運算子的允許用法。 現在可以在 函式呼叫 中使用任意數量的解包

>>> print(*[1], *[2], 3, *[4, 5])
1 2 3 4 5

>>> def fn(a, b, c, d):
...     print(a, b, c, d)
...

>>> fn(**{'a': 1, 'c': 3}, **{'b': 2, 'd': 4})
1 2 3 4

類似地,元組、列表、集合和字典顯示允許多次解包(請參閱 表示式列表字典顯示

>>> *range(4), 4
(0, 1, 2, 3, 4)

>>> [*range(4), 4]
[0, 1, 2, 3, 4]

>>> {*range(4), 4, *(5, 6, 7)}
{0, 1, 2, 3, 4, 5, 6, 7}

>>> {'x': 1, **{'y': 2}}
{'x': 1, 'y': 2}

另請參閱

PEP 448 – 額外的解包泛化

由 Joshua Landau 撰寫;由 Neil Girdhar、Thomas Wouters 和 Joshua Landau 實現的 PEP。

PEP 461 - 對位元組和 bytearray 的百分比格式化支援

PEP 461bytesbytearray 添加了對 % 插值運算子 的支援。

雖然插值通常被認為是字串操作,但在某些情況下,對 bytesbytearrays 進行插值是有意義的,而彌補這種缺失功能所需的工作會降低程式碼的整體可讀性。 在處理線格式協議時,此問題尤其重要,這些協議通常是二進位制和 ASCII 相容文字的混合。

示例

>>> b'Hello %b!' % b'World'
b'Hello World!'

>>> b'x=%i y=%f' % (1, 2.5)
b'x=1 y=2.500000'

%b 不允許使用 Unicode,但 %a 接受它(相當於 repr(obj).encode('ascii', 'backslashreplace')

>>> b'Hello %b!' % 'World'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: %b requires bytes, or an object that implements __bytes__, not 'str'

>>> b'price: %a' % '10€'
b"price: '10\\u20ac'"

請注意,%s%r 轉換型別雖然受支援,但應僅在需要與 Python 2 相容的程式碼庫中使用。

另請參閱

PEP 461 – 向位元組和 bytearray 新增 % 格式化

由 Ethan Furman 撰寫;由 Neil Schemenauer 和 Ethan Furman 實現的 PEP。

PEP 484 - 型別提示

函式註釋語法自 3.0 版 (PEP 3107) 以來一直是 Python 的一項功能,但是註釋的語義一直未定義。

經驗表明,大多數函式註釋用途是為函式引數和返回值提供型別提示。 很明顯,如果標準庫包含型別註釋的基本定義和工具,這對 Python 使用者將是有益的。

PEP 484 引入了一個 臨時模組,以提供這些標準定義和工具,以及一些在註釋不可用的情況下的約定。

例如,這是一個簡單的函式,其引數和返回型別在註釋中宣告

def greeting(name: str) -> str:
    return 'Hello ' + name

雖然這些註釋在執行時可以透過通常的 __annotations__ 屬性獲得,但執行時不會發生自動型別檢查。 相反,假設會使用單獨的離線型別檢查器(例如 mypy)進行按需原始碼分析。

型別系統支援聯合、泛型型別和一種名為 Any 的特殊型別,該型別與所有型別一致(即,可分配給所有型別和從所有型別分配)。

另請參閱

  • typing 模組文件

  • PEP 484 – 型別提示

    由 Guido van Rossum、Jukka Lehtosalo 和 Łukasz Langa 撰寫;由 Guido van Rossum 實現的 PEP。

  • PEP 483 – 型別提示理論

    由 Guido van Rossum 撰寫

PEP 471 - os.scandir() 函式 – 更好更快的目錄迭代器

PEP 471 向標準庫添加了一個新的目錄迭代函式 os.scandir()。 此外,現在使用 scandir 來實現 os.walk(),這使得它在 POSIX 系統上快 3 到 5 倍,在 Windows 系統上快 7 到 20 倍。 這主要是透過大大減少遍歷目錄樹所需的 os.stat() 呼叫次數來實現的。

此外,scandir 返回一個迭代器,而不是返回檔名列表,這提高了在遍歷非常大的目錄時的記憶體效率。

以下示例展示了 os.scandir() 的一個簡單用法,它用於顯示給定 路徑 中所有不以 '.' 開頭的檔案(不包括目錄)。entry.is_file() 呼叫通常不會產生額外的系統呼叫。

for entry in os.scandir(path):
    if not entry.name.startswith('.') and entry.is_file():
        print(entry.name)

另請參閱

PEP 471 – os.scandir() 函式 – 一個更好更快的目錄迭代器

本 PEP 由 Ben Hoyt 編寫並實現,Victor Stinner 協助完成。

PEP 475: 重試因 EINTR 失敗的系統呼叫

當一個等待 I/O 的系統呼叫被訊號中斷時,會返回一個 errno.EINTR 錯誤程式碼。之前,在這種情況下,Python 會引發 InterruptedError。這意味著,在編寫 Python 應用程式時,開發人員有兩個選擇:

  1. 忽略 InterruptedError

  2. 處理 InterruptedError,並在每次呼叫時嘗試重新啟動被中斷的系統呼叫。

第一個選項會導致應用程式間歇性失敗。第二個選項會新增大量的樣板程式碼,使得程式碼幾乎無法閱讀。比較一下

print("Hello World")

while True:
    try:
        print("Hello World")
        break
    except InterruptedError:
        continue

PEP 475 實現了在 EINTR 上自動重試系統呼叫。這消除了在大多數情況下使用者程式碼中處理 EINTRInterruptedError 的負擔,並使包括標準庫在內的 Python 程式更加健壯。請注意,只有當訊號處理程式沒有引發異常時,系統呼叫才會重試。

以下是現在在被訊號中斷時會重試的函式列表:

另請參閱

PEP 475 – 重試因 EINTR 失敗的系統呼叫

本 PEP 和實現由 Charles-François Natali 和 Victor Stinner 編寫,Antoine Pitrou(法國關係)協助完成。

PEP 479: 更改生成器內部 StopIteration 的處理方式

在 Python 3.4 及更早版本中,生成器和 StopIteration 的互動有時令人驚訝,並且可能會隱藏一些晦澀的錯誤。以前,在生成器函式內部意外引發的 StopIteration 會被驅動生成器的迴圈結構解釋為迭代的結束。

PEP 479 更改了生成器的行為:當在生成器內部引發 StopIteration 異常時,它會在退出生成器幀之前被替換為 RuntimeError。此更改的主要目標是簡化在以下情況下除錯:一個未受保護的 next() 呼叫引發 StopIteration,並導致由生成器控制的迭代靜默終止。這與 yield from 構造結合使用時尤其有害。

這是一個不向後相容的更改,因此要啟用新行為,必須使用 __future__ 匯入:

>>> from __future__ import generator_stop

>>> def gen():
...     next(iter([]))
...     yield
...
>>> next(gen())
Traceback (most recent call last):
  File "<stdin>", line 2, in gen
StopIteration

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: generator raised StopIteration

如果沒有 __future__ 匯入,每當在生成器內部引發 StopIteration 異常時,都會引發 PendingDeprecationWarning

另請參閱

PEP 479 – 更改生成器內部 StopIteration 的處理方式

本 PEP 由 Chris Angelico 和 Guido van Rossum 編寫。由 Chris Angelico、Yury Selivanov 和 Nick Coghlan 實現。

PEP 485:用於測試近似相等性的函式

PEP 485 添加了 math.isclose()cmath.isclose() 函式,用於判斷兩個值是否近似相等或彼此“接近”。是否認為兩個值接近取決於給定的絕對和相對容差。相對容差是 isclose 引數之間允許的最大差異,相對於較大的絕對值

>>> import math
>>> a = 5.0
>>> b = 4.99998
>>> math.isclose(a, b, rel_tol=1e-5)
True
>>> math.isclose(a, b, rel_tol=1e-6)
False

也可以使用絕對容差比較兩個值,絕對容差必須是非負值

>>> import math
>>> a = 5.0
>>> b = 4.99998
>>> math.isclose(a, b, abs_tol=0.00003)
True
>>> math.isclose(a, b, abs_tol=0.00001)
False

另請參閱

PEP 485 – 用於測試近似相等性的函式

此 PEP 由 Christopher Barker 撰寫;由 Chris Barker 和 Tal Einat 實現。

PEP 486:使 Python 啟動器能夠感知虛擬環境

PEP 486 使 Windows 啟動器(請參閱 PEP 397)能夠感知活動的虛擬環境。當使用預設直譯器並且設定了 VIRTUAL_ENV 環境變數時,將使用虛擬環境中的直譯器。

另請參閱

PEP 486 – 使 Python 啟動器能夠感知虛擬環境

此 PEP 由 Paul Moore 撰寫和實現。

PEP 488:消除 PYO 檔案

PEP 488 廢除了 .pyo 檔案的概念。這意味著 .pyc 檔案既表示未最佳化的位元組碼,也表示最佳化的位元組碼。為了防止需要不斷重新生成位元組碼檔案,.pyc 檔案現在在名稱中有一個可選的 opt- 標籤,表示位元組碼已最佳化。這樣做帶來的副作用是在 -O-OO 下執行時,不會再發生位元組碼檔名衝突。因此,從 -O-OO 生成的位元組碼檔案現在可以同時存在。importlib.util.cache_from_source() 更新了 API 以幫助進行此更改。

另請參閱

PEP 488 – 消除 PYO 檔案

此 PEP 由 Brett Cannon 撰寫和實現。

PEP 489:多階段擴充套件模組初始化

PEP 489 更新了擴充套件模組初始化,以利用 Python 3.4 中 PEP 451 引入的兩步模組載入機制。

此更改使選擇使用新機制的擴充套件模組的匯入語義更接近於 Python 原始碼和位元組碼模組的匯入語義,包括能夠使用任何有效的識別符號作為模組名稱,而不是僅限於 ASCII。

另請參閱

PEP 489 – 多階段擴充套件模組初始化

此 PEP 由 Petr Viktorin、Stefan Behnel 和 Nick Coghlan 撰寫;由 Petr Viktorin 實現。

其他語言更改

對核心 Python 語言所做的一些較小的更改如下

  • 添加了 "namereplace" 錯誤處理程式。"backslashreplace" 錯誤處理程式現在可以用於解碼和翻譯。(由 Serhiy Storchaka 在 bpo-19676bpo-22286 中貢獻。)

  • -b 選項現在會影響 bytesint 的比較。(由 Serhiy Storchaka 在 bpo-23681 中貢獻。)

  • 新的哈薩克語 kz1048 和塔吉克語 koi8_t 編解碼器。(由 Serhiy Storchaka 在 bpo-22682bpo-22681 中貢獻。)

  • 屬性文件字串現在是可寫的。這對於 collections.namedtuple() 文件字串特別有用。(由 Berker Peksag 在 bpo-24064 中貢獻。)

  • 現在支援涉及相對匯入的迴圈匯入。(由 Brett Cannon 和 Antoine Pitrou 在 bpo-17636 中貢獻。)

新模組

typing

新的 typing 臨時 模組為函式型別註釋提供標準定義和工具。有關更多資訊,請參閱 型別提示

zipapp

新的 zipapp 模組(在 PEP 441 中指定)提供了一個 API 和命令列工具,用於建立可執行的 Python Zip 應用程式,該應用程式在 Python 2.6 中透過 bpo-1739468 引入,但當時或此後都沒有得到很好的宣傳。

使用新模組,打包應用程式就像將所有檔案(包括 __main__.py 檔案)放入 myapp 目錄並執行一樣簡單

$ python -m zipapp myapp
$ python myapp.pyz

該模組的實現由 Paul Moore 在 bpo-23491 中貢獻。

另請參閱

PEP 441 – 改進 Python ZIP 應用程式支援

改進的模組

argparse

ArgumentParser 類現在允許透過將 allow_abbrev 設定為 False 來停用長選項的 縮寫用法。(由 Jonathan Paugh、Steven Bethard、paul j3 和 Daniel Eriksson 在 bpo-14910 中貢獻。)

asyncio

由於 asyncio 模組是 臨時的,因此 Python 3.5 中引入的所有更改也都向後移植到了 Python 3.4.x。

自 Python 3.4.0 以來,asyncio 模組中的顯著更改

3.5.1 中的更新

3.5.2 中的更新

bz2

BZ2Decompressor.decompress 方法現在接受一個可選的 max_length 引數,以限制解壓縮資料的最大大小。(由 Nikolaus Rath 在 bpo-15955 中貢獻。)

cgi

FieldStorage 類現在支援 上下文管理器 協議。(由 Berker Peksag 在 bpo-20289 中貢獻。)

cmath

新增函式 isclose() 提供了一種測試近似相等的方法。(由 Chris Barker 和 Tal Einat 在 bpo-24270 中貢獻。)

code

InteractiveInterpreter.showtraceback() 方法現在會列印完整的鏈式回溯,就像互動式直譯器一樣。(由 Claudiu Popa 在 bpo-17442 中貢獻。)

collections

OrderedDict 類現在用 C 實現,這使其速度提高了 4 到 100 倍。(由 Eric Snow 在 bpo-16991 中貢獻。)

OrderedDict.items(), OrderedDict.keys(), OrderedDict.values() 檢視現在支援 reversed() 迭代。(由 Serhiy Storchaka 在 bpo-19505 中貢獻。)

deque 類現在定義了 index(), insert()copy(),並支援 +* 運算子。這允許將 deques 識別為 MutableSequence,並提高它們對列表的替代性。(由 Raymond Hettinger 在 bpo-23704 中貢獻。)

namedtuple() 生成的文件字串現在可以更新

Point = namedtuple('Point', ['x', 'y'])
Point.__doc__ += ': Cartesian coordinate'
Point.x.__doc__ = 'abscissa'
Point.y.__doc__ = 'ordinate'

(由 Berker Peksag 在 bpo-24064 中貢獻。)

UserString 類現在實現了 __getnewargs__(), __rmod__(), casefold(), format_map(), isprintable()maketrans() 方法,以匹配 str 的相應方法。(由 Joe Jevnik 在 bpo-22189 中貢獻。)

collections.abc

Sequence.index() 方法現在接受 startstop 引數,以匹配 tuple, list 等的相應方法。(由 Devin Jeanpierre 在 bpo-23086 中貢獻。)

新增 Generator 抽象基類。(由 Stefan Behnel 在 bpo-24018 中貢獻。)

新增 Awaitable, Coroutine, AsyncIteratorAsyncIterable 抽象基類。(由 Yury Selivanov 在 bpo-24184 中貢獻。)

對於早期的 Python 版本,新 ABC 的向後移植版本可在一個外部 PyPI 包 中獲得。

compileall

新的 compileall 選項 -j N 允許同時執行 N 個工作程序以執行並行位元組碼編譯。 compile_dir() 函式具有相應的 workers 引數。(由 Claudiu Popa 在 bpo-16104 中貢獻。)

另一個新選項 -r 允許控制子目錄的最大遞迴級別。(由 Claudiu Popa 在 bpo-19628 中貢獻。)

現在可以多次指定 -q 命令列選項,在這種情況下,所有輸出(包括錯誤)都將被抑制。compile_dir()compile_file()compile_path() 中的相應 quiet 引數現在可以接受一個整數值,該值指示輸出抑制的級別。(由 Thomas Kluyver 在 bpo-21338 中貢獻。)

concurrent.futures

當使用 ProcessPoolExecutor() 時,Executor.map() 方法現在接受一個 chunksize 引數以允許批次處理任務,從而提高效能。(由 Dan O’Reilly 在 bpo-11271 中貢獻。)

ThreadPoolExecutor 建構函式中的工作程序數量現在是可選的。 預設值為 CPU 數量的 5 倍。(由 Claudiu Popa 在 bpo-21527 中貢獻。)

configparser

現在,configparser 提供了一種透過在 ConfigParser 建構函式中指定轉換器字典,或透過在 ConfigParser 子類中將它們定義為方法來定製值的轉換。在解析器例項中定義的轉換器由其節代理繼承。

示例

>>> import configparser
>>> conv = {}
>>> conv['list'] = lambda v: [e.strip() for e in v.split() if e.strip()]
>>> cfg = configparser.ConfigParser(converters=conv)
>>> cfg.read_string("""
... [s]
... list = a b c d e f g
... """)
>>> cfg.get('s', 'list')
'a b c d e f g'
>>> cfg.getlist('s', 'list')
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> section = cfg['s']
>>> section.getlist('list')
['a', 'b', 'c', 'd', 'e', 'f', 'g']

(由 Łukasz Langa 在 bpo-18159 中貢獻。)

contextlib

新的 redirect_stderr() 上下文管理器(類似於 redirect_stdout())使實用程式指令碼更容易處理將其輸出寫入 sys.stderr 且不提供任何重定向選項的僵化 API

>>> import contextlib, io, logging
>>> f = io.StringIO()
>>> with contextlib.redirect_stderr(f):
...     logging.warning('warning')
...
>>> f.getvalue()
'WARNING:root:warning\n'

(由 Berker Peksag 在 bpo-22389 中貢獻。)

csv

writerow() 方法現在支援任意可迭代物件,而不僅僅是序列。(由 Serhiy Storchaka 在 bpo-23171 中貢獻。)

curses

新的 update_lines_cols() 函式更新 LINESCOLS 模組變數。這對於檢測手動螢幕調整大小很有用。(由 Arnon Yaari 在 bpo-4254 中貢獻。)

dbm

當標誌的值為 "n" 時,dumb.open 總是建立一個新的資料庫。(由 Claudiu Popa 在 bpo-18039 中貢獻。)

difflib

現在可以透過使用新的僅關鍵字引數 charset 來自定義 HtmlDiff.make_file() 生成的 HTML 文件的字元集。HTML 文件的預設字元集從 "ISO-8859-1" 更改為 "utf-8"。(由 Berker Peksag 在 bpo-2052 中貢獻。)

現在 diff_bytes() 函式可以比較位元組字串列表。 這修復了 Python 2 中的一個迴歸。(由 Terry J. Reedy 和 Greg Ward 在 bpo-17445 中貢獻。)

distutils

buildbuild_ext 命令現在都接受 -j 選項來啟用擴充套件模組的並行構建。(由 Antoine Pitrou 在 bpo-5309 中貢獻。)

distutils 模組現在支援 xz 壓縮,並且可以透過將 xztar 作為引數傳遞給 bdist --format 來啟用。(由 Serhiy Storchaka 在 bpo-16314 中貢獻。)

doctest

如果 module 不包含文件字串,則 DocTestSuite() 函式返回一個空的 unittest.TestSuite,而不是引發 ValueError。(由 Glenn Jones 在 bpo-15916 中貢獻。)

email

一個新的策略選項 Policy.mangle_from_ 控制郵件正文中以 "From " 開頭的行是否在生成器中被新增 ">" 字元作為字首。對於 compat32,預設值為 True,對於所有其他策略,預設值為 False。(由 Milan Oberkirch 在 bpo-20098 中貢獻。)

一個新的 Message.get_content_disposition() 方法提供了一種簡單的方式來訪問 Content-Disposition 標頭的規範值。(由 Abhilash Raj 在 bpo-21083 中貢獻。)

一個新的策略選項 EmailPolicy.utf8 可以設定為 True,以便使用 UTF-8 字元集對電子郵件標頭進行編碼,而不是使用編碼字。這使得 Messages 可以根據 RFC 6532 進行格式化,並與支援 RFC 6531 SMTPUTF8 擴充套件的 SMTP 伺服器一起使用。(由 R. David Murray 在 bpo-24211 中貢獻。)

mime.text.MIMEText 建構函式現在接受一個 charset.Charset 例項。(由 Claude Paroz 和 Berker Peksag 在 bpo-16324 中貢獻。)

enum

如果只提供 names,則 Enum 可呼叫物件有一個新的引數 start,用於指定列舉值的初始數字

>>> Animal = enum.Enum('Animal', 'cat dog', start=10)
>>> Animal.cat
<Animal.cat: 10>
>>> Animal.dog
<Animal.dog: 11>

(由 Ethan Furman 在 bpo-21706 中貢獻。)

faulthandler

enable()register()dump_traceback()dump_traceback_later() 函式現在除了接受類檔案物件外,還接受檔案描述符。(由 Wei Wu 在 bpo-23566 中貢獻。)

functools

lru_cache() 的大部分機制現在在 C 中實現,這使其速度顯著加快。(由 Matt Joiner、Alexey Kachayev 和 Serhiy Storchaka 在 bpo-14373 中貢獻。)

glob

iglob()glob() 函式現在支援使用 "**" 模式在子目錄中進行遞迴搜尋。(由 Serhiy Storchaka 在 bpo-13968 中貢獻。)

gzip

GzipFile 建構函式的 mode 引數現在接受 "x" 以請求獨佔建立。(由 Tim Heaney 在 bpo-19222 中貢獻。)

heapq

現在可以透過在新的可選 key 關鍵字引數中傳遞一個 鍵函式 來定製 merge() 中的元素比較,並且可以使用新的可選 reverse 關鍵字引數來反轉元素比較

>>> import heapq
>>> a = ['9', '777', '55555']
>>> b = ['88', '6666']
>>> list(heapq.merge(a, b, key=len))
['9', '88', '777', '6666', '55555']
>>> list(heapq.merge(reversed(a), reversed(b), key=len, reverse=True))
['55555', '6666', '777', '88', '9']

(由 Raymond Hettinger 在 bpo-13742 中貢獻。)

http

一個新的 HTTPStatus 列舉,它定義了一組 HTTP 狀態程式碼、原因短語和英文編寫的長描述。(由 Demian Brecht 在 bpo-21793 中貢獻。)

http.client

當遠端伺服器連線意外關閉時,HTTPConnection.getresponse() 現在會引發 RemoteDisconnected 異常。此外,如果引發 ConnectionErrorRemoteDisconnected 是其子類),客戶端套接字現在會自動關閉,並在下一次請求時重新連線

import http.client
conn = http.client.HTTPConnection('www.python.org')
for retries in range(3):
    try:
        conn.request('GET', '/')
        resp = conn.getresponse()
    except http.client.RemoteDisconnected:
        pass

(由 Martin Panter 在 bpo-3566 中貢獻。)

idlelib 和 IDLE

由於 idlelib 實現了 IDLE shell 和編輯器,並且不打算被其他程式匯入,因此它會在每次釋出時得到改進。有關自 3.4.0 以來的累積更改列表以及未來 3.5.x 版本中所做的更改,請參閱 Lib/idlelib/NEWS.txt。此檔案也可以從 IDLE 幫助 ‣ 關於 IDLE 對話方塊中獲得。

imaplib

IMAP4 類現在支援 上下文管理器 協議。當在 with 語句中使用時,IMAP4 LOGOUT 命令將在塊的末尾自動呼叫。(由 Tarek Ziadé 和 Serhiy Storchaka 在 bpo-4972 中貢獻。)

imaplib 模組現在透過 IMAP4.enable() 方法支援 RFC 5161 (ENABLE 擴充套件) 和 RFC 6855 (UTF-8 支援)。一個新的 IMAP4.utf8_enabled 屬性跟蹤是否啟用了 RFC 6855 支援。(由 Milan Oberkirch、R. David Murray 和 Maciej Szulik 在 bpo-21800 中貢獻。)

imaplib 模組現在會自動使用 UTF-8 編碼非 ASCII 字串使用者名稱和密碼,正如 RFC 推薦的那樣。(由 Milan Oberkirch 在 bpo-21800 中貢獻。)

imghdr

what() 函式現在可以識別 OpenEXR 格式(由 Martin Vignali 和 Claudiu Popa 在 bpo-20295 中貢獻)和 WebP 格式(由 Fabrice Aneche 和 Claudiu Popa 在 bpo-20197 中貢獻。)

importlib

util.LazyLoader 類允許在啟動時間很重要的應用程式中延遲載入模組。(由 Brett Cannon 在 bpo-17621 中貢獻。)

abc.InspectLoader.source_to_code() 方法現在是一個靜態方法。這使得透過執行 exec(code, module.__dict__) 來初始化一個使用字串編譯而來的程式碼的模組物件變得更加容易。(由 Brett Cannon 在 bpo-21156 中貢獻。)

現在推薦使用新的 util.module_from_spec() 函式來建立新的模組。與直接建立 types.ModuleType 例項不同,這個新的函式將根據傳入的 spec 物件設定各種受匯入控制的屬性。(由 Brett Cannon 在 bpo-20383 中貢獻。)

inspect

SignatureParameter 類現在都是可 pickle 和可雜湊的。(由 Yury Selivanov 在 bpo-20726bpo-20334 中貢獻。)

新的 BoundArguments.apply_defaults() 方法提供了一種為缺失的引數設定預設值的方法

>>> def foo(a, b='ham', *args): pass
>>> ba = inspect.signature(foo).bind('spam')
>>> ba.apply_defaults()
>>> ba.arguments
OrderedDict([('a', 'spam'), ('b', 'ham'), ('args', ())])

(由 Yury Selivanov 在 bpo-24190 中貢獻。)

新的類方法 Signature.from_callable() 使 Signature 的子類化變得更加容易。(由 Yury Selivanov 和 Eric Snow 在 bpo-17373 中貢獻。)

signature() 函式現在接受一個可選的關鍵字引數 *follow_wrapped*,當設定為 False 時,停用自動跟蹤 __wrapped__ 連結。(由 Yury Selivanov 在 bpo-20691 中貢獻。)

添加了一組新的函式來檢查協程函式協程物件iscoroutine()iscoroutinefunction()isawaitable()getcoroutinelocals()getcoroutinestate()。(由 Yury Selivanov 在 bpo-24017bpo-24400 中貢獻。)

stack()trace()getouterframes()getinnerframes() 函式現在返回命名元組的列表。(由 Daniel Shahaf 在 bpo-16808 中貢獻。)

io

新的 BufferedIOBase.readinto1() 方法,最多使用一次對底層原始流的 RawIOBase.read()RawIOBase.readinto() 方法的呼叫。(由 Nikolaus Rath 在 bpo-20578 中貢獻。)

ipaddress

IPv4NetworkIPv6Network 類現在都接受 (address, netmask) 元組引數,以便於從現有地址構建網路物件

>>> import ipaddress
>>> ipaddress.IPv4Network(('127.0.0.0', 8))
IPv4Network('127.0.0.0/8')
>>> ipaddress.IPv4Network(('127.0.0.0', '255.0.0.0'))
IPv4Network('127.0.0.0/8')

(由 Peter Moody 和 Antoine Pitrou 在 bpo-16531 中貢獻。)

IPv4NetworkIPv6Network 類新的 reverse_pointer 屬性返回反向 DNS PTR 記錄的名稱

>>> import ipaddress
>>> addr = ipaddress.IPv4Address('127.0.0.1')
>>> addr.reverse_pointer
'1.0.0.127.in-addr.arpa'
>>> addr6 = ipaddress.IPv6Address('::1')
>>> addr6.reverse_pointer
'1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa'

(由 Leon Weber 在 bpo-20480 中貢獻。)

json

json.tool 命令列介面現在保留輸入中 JSON 物件中鍵的順序。新的 --sort-keys 選項可用於按字母順序對鍵進行排序。(由 Berker Peksag 在 bpo-21650 中貢獻。)

JSON 解碼器現在引發 JSONDecodeError 而不是 ValueError,以提供關於錯誤的更好上下文資訊。(由 Serhiy Storchaka 在 bpo-19361 中貢獻。)

linecache

新的 lazycache() 函式可用於捕獲關於非基於檔案的模組的資訊,以便允許稍後透過 getline() 獲取其行。這避免了在實際需要一行之前執行 I/O,而無需無限期地攜帶模組全域性變數。(由 Robert Collins 在 bpo-17911 中貢獻。)

locale

新的 delocalize() 函式可用於將字串轉換為規範化的數字字串,同時考慮 LC_NUMERIC 設定

>>> import locale
>>> locale.setlocale(locale.LC_NUMERIC, 'de_DE.UTF-8')
'de_DE.UTF-8'
>>> locale.delocalize('1.234,56')
'1234.56'
>>> locale.setlocale(locale.LC_NUMERIC, 'en_US.UTF-8')
'en_US.UTF-8'
>>> locale.delocalize('1,234.56')
'1234.56'

(由 Cédric Krier 在 bpo-13918 中貢獻。)

logging

所有日誌記錄方法(Logger log()exception()critical()debug() 等)現在接受異常例項作為 *exc_info* 引數,除了布林值和異常元組之外

>>> import logging
>>> try:
...     1/0
... except ZeroDivisionError as ex:
...     logging.error('exception', exc_info=ex)
ERROR:root:exception

(由 Yury Selivanov 在 bpo-20537 中貢獻。)

handlers.HTTPHandler 類現在接受一個可選的 ssl.SSLContext 例項來配置 HTTP 連線中使用的 SSL 設定。(由 Alex Gaynor 在 bpo-22788 中貢獻。)

現在,handlers.QueueListener 類接受一個名為 respect_handler_level 的關鍵字引數。如果設定為 True,則會將訊息傳遞給考慮處理程式級別的處理程式。(由 Vinay Sajip 貢獻。)

lzma

現在,LZMADecompressor.decompress() 方法接受一個可選的 max_length 引數,以限制解壓縮資料的最大大小。(由 Martin Panter 在 bpo-15955 中貢獻。)

math

math 模組中添加了兩個新常量:infnan。(由 Mark Dickinson 在 bpo-23185 中貢獻。)

新函式 isclose() 提供了一種測試近似相等性的方法。(由 Chris Barker 和 Tal Einat 在 bpo-24270 中貢獻。)

添加了一個新的 gcd() 函式。現在 fractions.gcd() 函式已被棄用。(由 Mark Dickinson 和 Serhiy Storchaka 在 bpo-22486 中貢獻。)

multiprocessing

sharedctypes.synchronized() 物件現在支援 上下文管理器 協議。(由 Charles-François Natali 在 bpo-21565 中貢獻。)

operator

現在,attrgetter()itemgetter()methodcaller() 物件支援 pickle 操作。(由 Josh Rosenberg 和 Serhiy Storchaka 在 bpo-22955 中貢獻。)

新的 matmul()imatmul() 函式用於執行矩陣乘法。(由 Benjamin Peterson 在 bpo-21176 中貢獻。)

os

添加了新的 scandir() 函式,該函式返回 DirEntry 物件的迭代器。如果可能,scandir() 會在掃描目錄時提取檔案屬性,從而無需執行後續系統呼叫來確定檔案型別或屬性,這可能會顯著提高效能。(由 Ben Hoyt 在 Victor Stinner 的幫助下,在 bpo-22524 中貢獻。)

在 Windows 上,現在可以使用新的 stat_result.st_file_attributes 屬性。它對應於 GetFileInformationByHandle() 返回的 BY_HANDLE_FILE_INFORMATION 結構的 dwFileAttributes 成員。(由 Ben Hoyt 在 bpo-21719 中貢獻。)

現在,urandom() 函式在 Linux 3.17 或更高版本上使用 getrandom() 系統呼叫,在 OpenBSD 5.6 或更高版本上使用 getentropy(),從而無需使用 /dev/urandom 並避免因潛在的檔案描述符耗盡而導致的失敗。(由 Victor Stinner 在 bpo-22181 中貢獻。)

新的 get_blocking()set_blocking() 函式允許獲取和設定檔案描述符的阻塞模式 (O_NONBLOCK)。 (由 Victor Stinner 在 bpo-22054 中貢獻。)

現在,Windows 上支援 truncate()ftruncate() 函式。(由 Steve Dower 在 bpo-23668 中貢獻。)

有一個新的 os.path.commonpath() 函式,返回每個傳遞的路徑名的最長公共子路徑。與 os.path.commonprefix() 函式不同,它始終返回有效的路徑。

>>> os.path.commonprefix(['/usr/lib', '/usr/local/lib'])
'/usr/l'

>>> os.path.commonpath(['/usr/lib', '/usr/local/lib'])
'/usr'

(由 Rafik Draoui 和 Serhiy Storchaka 在 bpo-10395 中貢獻。)

pathlib

新的 Path.samefile() 方法可用於檢查路徑是否指向與另一個路徑相同的檔案,該路徑可以是另一個 Path 物件或字串。

>>> import pathlib
>>> p1 = pathlib.Path('/etc/hosts')
>>> p2 = pathlib.Path('/etc/../etc/hosts')
>>> p1.samefile(p2)
True

(由 Vajrasky Kok 和 Antoine Pitrou 在 bpo-19775 中貢獻。)

現在,Path.mkdir() 方法接受一個新的可選引數 exist_ok,以匹配 mkdir -pos.makedirs() 的功能。(由 Berker Peksag 在 bpo-21539 中貢獻。)

有一個新的 Path.expanduser() 方法來擴充套件 ~~user 字首。(由 Serhiy Storchaka 和 Claudiu Popa 在 bpo-19776 中貢獻。)

可以使用新的 Path.home() 類方法來獲取表示使用者主目錄的 Path 例項。(由 Victor Salgado 和 Mayank Tripathi 在 bpo-19777 中貢獻。)

新的 Path.write_text()Path.read_text()Path.write_bytes()Path.read_bytes() 方法簡化了檔案的讀/寫操作。

以下程式碼片段將建立或重寫現有檔案 ~/spam42

>>> import pathlib
>>> p = pathlib.Path('~/spam42')
>>> p.expanduser().write_text('ham')
3

(由 Christopher Welborn 在 bpo-20218 中貢獻。)

pickle

現在,可以使用早於協議版本 4 的 pickle 協議 來 pickle 巢狀物件,例如未繫結方法或巢狀類。協議版本 4 已經支援這些情況。(由 Serhiy Storchaka 在 bpo-23611 中貢獻。)

poplib

新的 POP3.utf8() 命令支援 RFC 6856(國際化電子郵件),如果 POP 伺服器支援它。(由 Milan OberKirch 在 bpo-21804 中貢獻。)

re

現在允許在後向斷言中使用對固定長度組的引用和條件引用。

>>> import re
>>> pat = re.compile(r'(a|b).(?<=\1)c')
>>> pat.match('aac')
<_sre.SRE_Match object; span=(0, 3), match='aac'>
>>> pat.match('bbc')
<_sre.SRE_Match object; span=(0, 3), match='bbc'>

(由 Serhiy Storchaka 在 bpo-9179 中貢獻。)

正則表示式中捕獲組的數量不再限制為 100。(由 Serhiy Storchaka 在 bpo-22437 中貢獻。)

sub()subn() 函式現在將未匹配的組替換為空字串,而不是引發異常。(由 Serhiy Storchaka 在 bpo-1519638 中貢獻。)

re.error 異常具有新的屬性,msg, pattern, pos, linenocolno,這些屬性提供了關於錯誤的更好的上下文資訊。

>>> re.compile("""
...     (?x)
...     .++
... """)
Traceback (most recent call last):
   ...
sre_constants.error: multiple repeat at position 16 (line 3, column 7)

(由 Serhiy Storchaka 在 bpo-22578 中貢獻。)

readline

新的 append_history_file() 函式可用於將歷史記錄中指定數量的尾隨元素附加到給定的檔案中。(由 Bruno Cauet 在 bpo-22940 中貢獻。)

selectors

新的 DevpollSelector 支援在 Solaris 上高效的 /dev/poll 輪詢。(由 Giampaolo Rodola’ 在 bpo-18931 中貢獻。)

shutil

move() 函式現在接受一個 *copy_function* 引數,例如,允許使用 copy() 函式而不是預設的 copy2(),如果需要在移動時忽略檔案元資料。(由 Claudiu Popa 在 bpo-19840 中貢獻。)

make_archive() 函式現在支援 *xztar* 格式。(由 Serhiy Storchaka 在 bpo-5411 中貢獻。)

signal

在 Windows 上,set_wakeup_fd() 函式現在也支援套接字控制代碼。(由 Victor Stinner 在 bpo-22018 中貢獻。)

signal 模組中的各種 SIG* 常量已轉換為 Enums。 這允許在除錯期間列印有意義的名稱,而不是整數“魔術數字”。(由 Giampaolo Rodola’ 在 bpo-21076 中貢獻。)

smtpd

SMTPServerSMTPChannel 類現在都接受 *decode_data* 關鍵字引數,以確定 SMTP 事務的 DATA 部分是否使用 "utf-8" 編解碼器解碼,或者是否作為位元組字串提供給 SMTPServer.process_message() 方法。 為了向後相容,預設為 True,但在 Python 3.6 中將更改為 False。 如果 *decode_data* 設定為 False,則 process_message 方法必須準備好接受關鍵字引數。(由 Maciej Szulik 在 bpo-19662 中貢獻。)

如果 *decode_data* 已設定為 TrueSMTPServer 類現在會通告 8BITMIME 擴充套件 (RFC 6152)。 如果客戶端在 MAIL 命令上指定了 BODY=8BITMIME,它會透過 *mail_options* 關鍵字傳遞給 SMTPServer.process_message()。(由 Milan Oberkirch 和 R. David Murray 在 bpo-21795 中貢獻。)

SMTPServer 類現在也支援 SMTPUTF8 擴充套件 (RFC 6531: 國際化電子郵件)。 如果客戶端在 MAIL 命令上指定了 SMTPUTF8 BODY=8BITMIME,它們會透過 *mail_options* 關鍵字傳遞給 SMTPServer.process_message()process_message 方法負責正確處理 SMTPUTF8 資料。(由 Milan Oberkirch 在 bpo-21725 中貢獻。)

現在可以在 SMTPServer 建構函式中直接或透過名稱解析提供 IPv6 地址,並使其成功連線。(由 Milan Oberkirch 在 bpo-14758 中貢獻。)

smtplib

新的 SMTP.auth() 方法提供了一種方便的方法來實現自定義身份驗證機制。(由 Milan Oberkirch 在 bpo-15014 中貢獻。)

SMTP.set_debuglevel() 方法現在接受一個額外的除錯級別 (2),它會在除錯訊息中啟用時間戳。(由 Gavin Chappell 和 Maciej Szulik 在 bpo-16914 中貢獻。)

SMTP.sendmail()SMTP.send_message() 方法現在都支援 RFC 6531 (SMTPUTF8)。(由 Milan Oberkirch 和 R. David Murray 在 bpo-22027 中貢獻。)

sndhdr

what()whathdr() 函式現在返回一個 namedtuple()。(由 Claudiu Popa 在 bpo-18615 中貢獻。)

socket

具有超時功能的函式現在使用單調時鐘,而不是系統時鐘。(由 Victor Stinner 在 bpo-22043 中貢獻。)

新的 socket.sendfile() 方法允許透過使用 UNIX 上高效能的 os.sendfile() 函式透過套接字傳送檔案,從而使上傳速度比使用普通的 socket.send() 快 2 到 3 倍。(由 Giampaolo Rodola’ 在 bpo-17552 中貢獻。)

socket.sendall() 方法不再在每次接收或傳送位元組時重置套接字超時。 套接字超時現在是傳送所有資料的最大總持續時間。(由 Victor Stinner 在 bpo-23853 中貢獻。)

socket.listen() 方法的 backlog 引數現在是可選的。 預設情況下,它設定為 SOMAXCONN128,以較小者為準。(由 Charles-François Natali 在 bpo-21455 中貢獻。)

ssl

記憶體 BIO 支援

(由 Geert Jansen 在 bpo-21965 中貢獻。)

添加了新的 SSLObject 類,以便在 SSLSocket 的網路 I/O 功能不是必需的或不是最佳的情況下,提供 SSL 協議支援。 SSLObject 表示一個 SSL 協議例項,但不實現任何網路 I/O 方法,而是提供一個記憶體緩衝區介面。 新的 MemoryBIO 類可用於在 Python 和 SSL 協議例項之間傳遞資料。

記憶體 BIO SSL 支援主要用於實現非同步 I/O 的框架,在這種框架中,SSLSocket 的就緒模型(“select/poll”)效率較低。

可以使用新的 SSLContext.wrap_bio() 方法來建立一個新的 SSLObject 例項。

應用層協議協商支援

(由 Benjamin Peterson 在 bpo-20188 中貢獻。)

如果存在 OpenSSL 支援,則 ssl 模組現在實現了 應用層協議協商 TLS 擴充套件,如 RFC 7301 中所述。

新的 SSLContext.set_alpn_protocols() 可用於指定套接字在 TLS 握手期間應通告的協議。

新的 SSLSocket.selected_alpn_protocol() 返回在 TLS 握手期間選擇的協議。 HAS_ALPN 標誌指示是否存在 ALPN 支援。

其他更改

有一個新的 SSLSocket.version() 方法來查詢正在使用的實際協議版本。(由 Antoine Pitrou 在 bpo-20421 中貢獻。)

SSLSocket 類現在實現一個 SSLSocket.sendfile() 方法。(由 Giampaolo Rodola' 在 bpo-17552 中貢獻。)

如果操作會阻塞, SSLSocket.send() 方法現在會在非阻塞套接字上引發 ssl.SSLWantReadErrorssl.SSLWantWriteError 異常。 以前,它會返回 0。(由 Nikolaus Rath 在 bpo-20951 中貢獻。)

根據 RFC 5280cert_time_to_seconds() 函式現在將輸入時間解釋為 UTC 而不是本地時間。此外,返回值始終為 int。(由 Akira Li 在 bpo-19940 中貢獻。)

新的 SSLObject.shared_ciphers()SSLSocket.shared_ciphers() 方法返回客戶端在握手期間傳送的密碼列表。(由 Benjamin Peterson 在 bpo-23186 中貢獻。)

SSLSocket.do_handshake(), SSLSocket.read(), SSLSocket.shutdown(), 和 SSLSocket.write() SSLSocket 類的方法不再在每次接收或傳送位元組時重置套接字超時。 套接字超時現在是該方法的最大總持續時間。(由 Victor Stinner 在 bpo-23853 中貢獻。)

match_hostname() 函式現在支援 IP 地址的匹配。(由 Antoine Pitrou 在 bpo-23239 中貢獻。)

sqlite3

Row 類現在完全支援序列協議,特別是 reversed() 迭代和切片索引。(由 Claudiu Popa 在 bpo-10203 中貢獻;由 Lucas Sinclair、Jessica McKellar 和 Serhiy Storchaka 在 bpo-13583 中貢獻。)

subprocess

添加了新的 run() 函式。 它執行指定的命令並返回一個 CompletedProcess 物件,該物件描述已完成的程序。 新的 API 更一致,並且是在不需要與早期 Python 版本保持相容的 Python 程式碼中呼叫子程序的推薦方法。(由 Thomas Kluyver 在 bpo-23342 中貢獻。)

示例

>>> subprocess.run(["ls", "-l"])  # doesn't capture output
CompletedProcess(args=['ls', '-l'], returncode=0)

>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
  ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

>>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')

sys

一個新的 set_coroutine_wrapper() 函式允許設定一個全域性鉤子,該鉤子將在透過 async def 函式建立 協程物件 時呼叫。 相應的 get_coroutine_wrapper() 可用於獲取當前設定的包裝器。 這兩個函式都是 臨時的,並且僅用於除錯目的。(由 Yury Selivanov 在 bpo-24017 中貢獻。)

可以使用新的 is_finalizing() 函式來檢查 Python 直譯器是否正在關閉。(由 Antoine Pitrou 在 bpo-22696 中貢獻。)

sysconfig

Windows 上使用者指令碼目錄的名稱現在包含 Python 版本的前兩個組成部分。(由 Paul Moore 在 bpo-23437 中貢獻。)

tarfile

現在,open() 函式的 mode 引數接受 "x" 來請求獨佔建立。(由 Berker Peksag 在 bpo-21717 中貢獻。)

TarFile.extractall()TarFile.extract() 方法現在接受一個關鍵字引數 numeric_owner。如果設定為 True,則提取的檔案和目錄將由 tar 檔案中的數字 uidgid 擁有。如果設定為 False(預設值,並且是 3.5 之前版本中的行為),它們將由 tar 檔案中命名的使用者和組擁有。(由 Michael Vogt 和 Eric Smith 在 bpo-23193 中貢獻。)

TarFile.list() 現在接受一個可選的 members 關鍵字引數,該引數可以設定為 TarFile.getmembers() 返回的列表的子集。(由 Serhiy Storchaka 在 bpo-21549 中貢獻。)

threading

Lock.acquire()RLock.acquire() 方法現在都使用單調時鐘進行超時管理。(由 Victor Stinner 在 bpo-22043 中貢獻。)

time

monotonic() 函式現在始終可用。(由 Victor Stinner 在 bpo-22043 中貢獻。)

timeit

可以使用新的命令列選項 -u--unit=U 來指定計時器輸出的時間單位。支援的選項是 usecmsecsec。(由 Julian Gindi 在 bpo-18983 中貢獻。)

timeit() 函式有一個新的 globals 引數,用於指定程式碼將在其中執行的名稱空間。(由 Ben Roberts 在 bpo-2527 中貢獻。)

tkinter

用於在 Windows 上設定 Tcl/Tk 環境的 tkinter._fix 模組已被 _tkinter 模組中的私有函式替換,該函式不會對環境變數進行永久更改。(由 Zachary Ware 在 bpo-20035 中貢獻。)

traceback

新的 walk_stack()walk_tb() 函式,方便地遍歷幀和 traceback 物件。(由 Robert Collins 在 bpo-17911 中貢獻。)

新的輕量級類:TracebackExceptionStackSummaryFrameSummary。(由 Robert Collins 在 bpo-17911 中貢獻。)

print_tb()print_stack() 函式現在都支援 limit 引數的負值。(由 Dmitry Kazakov 在 bpo-22619 中貢獻。)

types

一個新的 coroutine() 函式,用於將 生成器類生成器 物件轉換為 可等待物件。(由 Yury Selivanov 在 bpo-24017 中貢獻。)

一個名為 CoroutineType 的新型別,用於由 async def 函式建立的 協程 物件。(由 Yury Selivanov 在 bpo-24400 中貢獻。)

unicodedata

unicodedata 模組現在使用來自 Unicode 8.0.0 的資料。

unittest

TestLoader.loadTestsFromModule() 方法現在接受一個僅限關鍵字的引數 pattern,該引數作為第三個引數傳遞給 load_tests。現在會檢查詢到的包中是否存在 load_tests,無論其路徑是否與 pattern 匹配,因為包名稱不可能與預設模式匹配。(由 Robert Collins 和 Barry A. Warsaw 在 bpo-16662 中貢獻。)

Unittest 發現錯誤現在暴露在 TestLoader.errors 屬性中,該屬性是 TestLoader 例項的屬性。(由 Robert Collins 在 bpo-19746 中貢獻。)

一個新的命令列選項 --locals 用於在回溯中顯示區域性變數。(由 Robert Collins 在 bpo-22936 中貢獻。)

unittest.mock

Mock 類具有以下改進

  • 類建構函式有一個新的 unsafe 引數,該引數使模擬物件在屬性名稱以 "assert" 開頭時引發 AttributeError。(由 Kushal Das 在 bpo-21238 中貢獻。)

  • 一個新的 Mock.assert_not_called() 方法,用於檢查是否呼叫了模擬物件。(由 Kushal Das 在 bpo-21262 中貢獻。)

現在,MagicMock 類支援 __truediv__()__divmod__()__matmul__() 運算子。(由 Johannes Baiter 在 bpo-20968 中貢獻,以及 Håkan Lövdahl 在 bpo-23581bpo-23568 中貢獻。)

現在,當修補內建名稱時,不再需要顯式地傳遞 create=Truepatch() 函式。(由 Kushal Das 在 bpo-17660 中貢獻。)

urllib

新的 request.HTTPPasswordMgrWithPriorAuth 類允許管理 HTTP 基本身份驗證憑據,從而消除不必要的 401 響應處理,或者在第一次請求時無條件傳送憑據,以便與返回 404 響應而不是 401 的伺服器通訊(如果未傳送 Authorization 標頭)。(由 Matej Cepl 在 bpo-19494 中貢獻,以及 Akshit Khurana 在 bpo-7159 中貢獻。)

parse.urlencode() 函式新增了一個 quote_via 引數,用於在需要時控制查詢部分的編碼。(由 Samwyse 和 Arnon Yaari 在 bpo-13866 中貢獻。)

request.urlopen() 函式接受一個 ssl.SSLContext 物件作為 context 引數,該物件將用於 HTTPS 連線。(由 Alex Gaynor 在 bpo-22366 中貢獻。)

parse.urljoin() 已更新為使用 RFC 3986 語義來解析相對 URL,而不是 RFC 1808RFC 2396。(由 Demian Brecht 和 Senthil Kumaran 在 bpo-22118 中貢獻。)

wsgiref

headers.Headers 類建構函式的 headers 引數現在是可選的。(由 Pablo Torres Navarrete 和 SilentGhost 在 bpo-5800 中貢獻。)

xmlrpc

client.ServerProxy 類現在支援上下文管理器協議。(由 Claudiu Popa 在 bpo-20627 中貢獻。)

client.ServerProxy 建構函式現在接受一個可選的 ssl.SSLContext 例項。(由 Alex Gaynor 在 bpo-22960 中貢獻。)

xml.sax

SAX 解析器現在支援 xmlreader.InputSource 物件的字元流。(由 Serhiy Storchaka 在 bpo-2175 中貢獻。)

parseString() 現在接受一個 str 例項。(由 Serhiy Storchaka 在 bpo-10590 中貢獻。)

zipfile

現在可以將 ZIP 輸出寫入不可查詢的流。(由 Serhiy Storchaka 在 bpo-23252 中貢獻。)

ZipFile.open() 方法的 mode 引數現在接受 "x" 以請求獨佔建立。(由 Serhiy Storchaka 在 bpo-21717 中貢獻。)

其他模組級更改

mmapossaudiodevsocketsslcodecs 模組中的許多函式現在接受可寫的類位元組物件。(由 Serhiy Storchaka 在 bpo-23001 中貢獻。)

最佳化

在 POSIX 系統上,os.walk() 函式的速度提高了 3 到 5 倍,在 Windows 上提高了 7 到 20 倍。這是透過新的 os.scandir() 函式完成的,該函式公開了來自底層 readdirFindFirstFile/FindNextFile 系統呼叫的檔案資訊。(由 Ben Hoyt 在 Victor Stinner 的幫助下於 bpo-23605 中貢獻。)

bytes(int) (填充零位元組) 的構造速度更快,並且對於大型物件使用的記憶體更少。使用 calloc() 而不是 malloc() 為這些物件分配記憶體。(由 Victor Stinner 在 bpo-21233 中貢獻。)

ipaddress IPv4NetworkIPv6Network 的某些操作進行了大幅加速,例如 subnets()supernet()summarize_address_range()collapse_addresses()。速度提升範圍為 3 到 15 倍。(由 Antoine Pitrou、Michel Albert 和 Markus 在 bpo-21486bpo-21487bpo-20826bpo-23266 中貢獻。)

優化了 ipaddress 物件的序列化,以產生明顯更小的輸出。(由 Serhiy Storchaka 在 bpo-23133 中貢獻。)

現在 io.BytesIO 上的許多操作的速度提高了 50% 到 100%。(由 Serhiy Storchaka 在 bpo-15381 中貢獻,以及 David Wilson 在 bpo-22003 中貢獻。)

marshal.dumps() 函式現在更快了:在典型資料上,使用版本 3 和 4 時速度提高 65–85%,使用版本 0 到 2 時速度提高 20–25%,在最佳情況下速度提高高達 5 倍。(由 Serhiy Storchaka 在 bpo-20416bpo-23344 中貢獻。)

UTF-32 編碼器現在速度快了 3 到 7 倍。(由 Serhiy Storchaka 在 bpo-15027 中貢獻。)

現在,正則表示式的解析速度提高了高達 10%。(由 Serhiy Storchaka 在 bpo-19380 中貢獻。)

優化了 json.dumps() 函式,使其在 ensure_ascii=False 下的執行速度與 ensure_ascii=True 下的執行速度一樣快。(由 Naoki Inada 在 bpo-23206 中貢獻。)

在常見情況下,當第二個引數的元類為type時,PyObject_IsInstance()PyObject_IsSubclass() 函式的速度得到了提升。(由 Georg Brandl 在 bpo-22540 中貢獻。)

方法快取略有改進,在某些基準測試中效能提升高達 5%。 (由 Antoine Pitrou 在 bpo-22847 中貢獻.)

random 模組中的物件在 64 位構建版本上使用的記憶體減少了 50%。 (由 Serhiy Storchaka 在 bpo-23488 中貢獻.)

property() 獲取器呼叫速度提高了高達 25%。(由 Joe Jevnik 在 bpo-23910 中貢獻.)

fractions.Fraction 的例項化速度現在提高了高達 30%。(由 Stefan Behnel 在 bpo-22464 中貢獻.)

字串方法 find()rfind()split()partition()in 字串運算子在搜尋單字元子字串時現在明顯更快。(由 Serhiy Storchaka 在 bpo-23573 中貢獻.)

構建和 C API 變更

添加了新的 calloc 函式

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

新的編碼/解碼輔助函式

(由 Victor Stinner 在 bpo-18395 中貢獻.)

一個新的 PyCodec_NameReplaceErrors() 函式,用於將 Unicode 編碼錯誤替換為 \N{...} 轉義符。(由 Serhiy Storchaka 在 bpo-19676 中貢獻.)

一個新的 PyErr_FormatV() 函式,類似於 PyErr_Format(),但接受 va_list 引數。(由 Antoine Pitrou 在 bpo-18711 中貢獻.)

一個新的 PyExc_RecursionError 異常。(由 Georg Brandl 在 bpo-19235 中貢獻.)

新的 PyModule_FromDefAndSpec()PyModule_FromDefAndSpec2()PyModule_ExecDef() 函式由 PEP 489 引入 – 多階段擴充套件模組初始化。(由 Petr Viktorin 在 bpo-24268 中貢獻.)

新的 PyNumber_MatrixMultiply()PyNumber_InPlaceMatrixMultiply() 函式用於執行矩陣乘法。(由 Benjamin Peterson 在 bpo-21176 中貢獻。 另見 PEP 465 以瞭解詳情。)

PyTypeObject.tp_finalize 插槽現在是穩定 ABI 的一部分。

Windows 版本現在需要 Microsoft Visual C++ 14.0,它可以作為 Visual Studio 2015 的一部分提供。

擴充套件模組現在在某些平臺上在其檔名中包含平臺資訊標籤(該標籤是可選的,CPython 將匯入沒有它的擴充套件,但是如果存在該標籤並且不匹配,則不會載入該擴充套件)

  • 在 Linux 上,擴充套件模組的檔名以 .cpython-<major><minor>m-<architecture>-<os>.pyd 結尾

    • <major> 是 Python 版本的主版本號; 對於 Python 3.5,它是 3

    • <minor> 是 Python 版本的次版本號;對於 Python 3.5,它是 5

    • <architecture> 是擴充套件模組構建所針對的硬體架構。 它最常見的是 32 位 Intel 平臺的 i386 或 64 位 Intel(和 AMD)平臺的 x86_64

    • <os> 始終為 linux-gnu,除非為在 64 位平臺上與 32 位 ABI 對話而構建的擴充套件,在這種情況下,它為 linux-gnu32 (並且 <architecture> 將為 x86_64)。

  • 在 Windows 上,擴充套件模組的檔名以 <debug>.cp<major><minor>-<platform>.pyd 結尾

    • <major> 是 Python 版本的主版本號; 對於 Python 3.5,它是 3

    • <minor> 是 Python 版本的次版本號;對於 Python 3.5,它是 5

    • <platform> 是擴充套件模組構建所針對的平臺, Win32 的 win32, Win64 的 win_amd64,Windows Itanium 64 的 win_ia64, 以及 Windows on ARM 的 win_arm

    • 如果在除錯模式下構建,<debug> 將為 _d,否則將為空白。

  • 在 OS X 平臺上,擴充套件模組的檔名現在以 -darwin.so 結尾。

  • 在所有其他平臺上,擴充套件模組的檔名與 Python 3.4 中的相同。

已棄用

新關鍵字

不建議將 asyncawait 用作變數、類、函式或模組名稱。 由 PEP 492 在 Python 3.5 中引入,它們將在 Python 3.7 中成為適當的關鍵字。

已棄用的 Python 行為

在生成器內部引發 StopIteration 異常現在將生成一個無聲的 PendingDeprecationWarning,它將在 Python 3.6 中成為非靜默的棄用警告,並在 Python 3.7 中觸發 RuntimeError。 有關詳細資訊,請參閱 PEP 479:更改生成器內部的 StopIteration 處理

不支援的作業系統

Windows XP 不再受 Microsoft 支援,因此根據 PEP 11,CPython 3.5 不再正式支援此作業系統。

已棄用的 Python 模組、函式和方法

formatter 模組現在已完全棄用,並且仍計劃在 Python 3.6 中刪除。

asyncio.async() 函式已棄用,轉而使用 ensure_future()

smtpd 模組過去總是使用 utf-8 編解碼器解碼電子郵件訊息的 DATA 部分。 現在可以使用 SMTPServer 的新 *decode_data* 關鍵字來控制它。 預設值為 True,但是此預設值已被棄用。 使用適當的值指定 *decode_data* 關鍵字以避免棄用警告。

直接為 keyvaluecoded_value 屬性賦值 http.cookies.Morsel 物件已被棄用。請改用 set() 方法。此外,set() 的未文件化引數 LegalChars 也已被棄用,現在會被忽略。

將格式化字串作為關鍵字引數 format_string 傳遞給 format() 方法(string.Formatter 類)已被棄用。(由 Serhiy Storchaka 在 bpo-23671 中貢獻。)

platform.dist()platform.linux_distribution() 函式現在已被棄用。Linux 發行版使用太多不同的方式來描述自己,因此該功能留給軟體包處理。(由 Vajrasky Kok 和 Berker Peksag 在 bpo-1322 中貢獻。)

inspect.Signature 的先前未文件化的 from_functionfrom_builtin 方法已被棄用。請改用新的 Signature.from_callable() 方法。(由 Yury Selivanov 在 bpo-24248 中貢獻。)

inspect.getargspec() 函式已被棄用,並計劃在 Python 3.6 中移除。(有關詳細資訊,請參閱 bpo-20438。)

inspect getfullargspec()getcallargs()formatargspec() 函式已被棄用,推薦使用 inspect.signature() API。(由 Yury Selivanov 在 bpo-20438 中貢獻。)

getargvalues()formatargvalues() 函式在 Python 3.5.0 版本釋出時被無意地標記為已棄用。

現在不建議將 re.LOCALE 標誌與 str 模式或 re.ASCII 一起使用。(由 Serhiy Storchaka 在 bpo-22407 中貢獻。)

在正則表示式模式和替換模式中使用由 '\' 和一個 ASCII 字母組成的不識別的特殊序列現在會引發棄用警告,並在 Python 3.6 中被禁止。(由 Serhiy Storchaka 在 bpo-23622 中貢獻。)

unittest.TestLoader.loadTestsFromModule() 方法的未文件化和非官方的 use_load_tests 預設引數現在已被棄用且被忽略。(由 Robert Collins 和 Barry A. Warsaw 在 bpo-16662 中貢獻。)

已移除

API 和功能移除

以下過時的和先前已棄用的 API 和功能已被移除

  • email 包中已刪除 __version__ 屬性。email 程式碼已經很久沒有從 stdlib 單獨釋出了,並且 __version__ 字串在最近的幾個版本中都沒有更新。

  • ftplib 模組中的內部 Netrc 類在 3.4 中被棄用,現在已被移除。(由 Matt Chaput 在 bpo-6623 中貢獻。)

  • .pyo 檔案的概念已被移除。

  • 臨時 asyncio 模組中的 JoinableQueue 類在 3.4.4 中被棄用,現在已被移除。(由 A. Jesse Jiryu Davis 在 bpo-23464 中貢獻。)

移植到 Python 3.5

本節列出了先前描述的更改和其他可能需要更改程式碼的錯誤修復。

Python 行為的改變

  • 由於疏忽,早期的 Python 版本錯誤地接受了以下語法

    f(1 for x in [1], *args)
    f(1 for x in [1], **kwargs)
    

    Python 3.5 現在會正確引發 SyntaxError,因為生成器表示式如果不是函式的唯一引數,則必須放在括號中。

Python API 中的更改

  • PEP 475: 現在,當系統呼叫被訊號中斷時,如果 Python 訊號處理程式沒有引發異常,則會重試系統呼叫,而不是引發 InterruptedError

  • 在 Python 3.5 之前,如果 datetime.time 物件表示 UTC 時間午夜,則該物件被認為是 false。這種行為被認為是晦澀難懂且容易出錯的,已在 Python 3.5 中刪除。有關完整詳細資訊,請參閱 bpo-13936

  • 如果操作會阻塞,ssl.SSLSocket.send() 方法現在會在非阻塞套接字上引發 ssl.SSLWantReadErrorssl.SSLWantWriteError。之前,它會返回 0。(由 Nikolaus Rath 在 bpo-20951 中貢獻。)

  • 生成器的 __name__ 屬性現在從函式名稱設定,而不是從程式碼名稱設定。使用 gen.gi_code.co_name 檢索程式碼名稱。生成器還有一個新的 __qualname__ 屬性(限定名稱),現在用於表示生成器 (repr(gen))。(由 Victor Stinner 在 bpo-21205 中貢獻。)

  • 已刪除 HTMLParser 的已棄用的“strict”模式和引數、HTMLParser.error()HTMLParserError 異常。(由 Ezio Melotti 在 bpo-15114 中貢獻。)HTMLParserconvert_charrefs 引數現在預設為 True。(由 Berker Peksag 在 bpo-21047 中貢獻。)

  • 雖然它不是 API 的正式組成部分,但為了移植目的(即:修復測試),值得注意的是,以前形式為“'sometype' does not support the buffer protocol”的錯誤訊息現在形式為 “a bytes-like object is required, not ‘sometype’”。(由 Ezio Melotti 在 bpo-16518 中貢獻。)

  • 如果當前目錄被設定為一個不再存在的目錄,那麼將不再引發 FileNotFoundError 異常,而是 find_spec() 將返回 None並且不會sys.path_importer_cache 中快取 None,這與通常的情況不同 (bpo-22834)。

  • 來自 http.clienthttp.server 的 HTTP 狀態碼和訊息被重構為一個公共的 HTTPStatus 列舉。 為了向後相容,http.clienthttp.server 中的值仍然可用。(由 Demian Brecht 在 bpo-21793 中貢獻。)

  • 當匯入載入器定義了 importlib.machinery.Loader.exec_module() 時,現在也需要定義 create_module()(現在會引發一個 DeprecationWarning,在 Python 3.6 中將成為錯誤)。 如果載入器繼承自 importlib.abc.Loader,則無需執行任何操作,否則只需定義 create_module() 以返回 None。(由 Brett Cannon 在 bpo-23014 中貢獻。)

  • re.split() 函式始終忽略空模式匹配,因此 "x*" 模式的工作方式與 "x+" 相同,而 "\b" 模式從未起作用。 現在,如果模式可以匹配空字串,則 re.split() 會引發警告。 為了相容性,請使用永遠不匹配空字串的模式(例如,使用 "x+" 而不是 "x*")。 只能匹配空字串的模式(例如 "\b")現在會引發錯誤。(由 Serhiy Storchaka 在 bpo-22818 中貢獻。)

  • http.cookies.Morsel 的類字典介面已變得自洽:morsel 比較現在會考慮 keyvaluecopy() 現在會生成一個 Morsel 例項,而不是一個 dict,並且如果更新字典中的任何鍵無效,則 update() 現在將引發異常。此外,set() 的未文件化的 LegalChars 引數已被棄用,現在將被忽略。(由 Demian Brecht 在 bpo-2211 中貢獻。)

  • PEP 488 從 Python 中刪除了 .pyo 檔案,並在 .pyc 檔名中引入了可選的 opt- 標籤。importlib.util.cache_from_source() 獲得了一個 optimization 引數,以幫助控制 opt- 標籤。因此,該函式的 debug_override 引數現在已被棄用。 .pyo 檔案也不再作為 Python 直譯器的檔案引數支援,因此在單獨分發時(即,無原始碼分發)沒有任何用途。 由於 Python 3.5 中位元組碼的魔術數字已更改,因此來自早期版本 Python 的所有舊 .pyo 檔案都是無效的,無論此 PEP 如何。

  • socket 模組現在在 Linux 3.6 及更高版本上匯出 CAN_RAW_FD_FRAMES 常量。

  • 根據 RFC 5280ssl.cert_time_to_seconds() 函式現在將輸入時間解釋為 UTC 時間,而不是本地時間。 此外,返回值始終為 int。(由 Akira Li 在 bpo-19940 中貢獻。)

  • pygettext.py 工具現在在 POT-Creation-Date 標頭中使用標準的 +NNNN 格式表示時區。

  • smtplib 模組現在使用 sys.stderr 而不是以前的模組級 stderr 變數進行除錯輸出。 如果你的(測試)程式依賴於修補模組級變數以捕獲除錯輸出,則你需要更新它以捕獲 sys.stderr。

  • 當發現空字串且索引完全超出範圍時,str.startswith()str.endswith() 方法不再返回 True。(由 Serhiy Storchaka 在 bpo-24284 中貢獻。)

  • inspect.getdoc() 函式現在返回從基類繼承的文件字串。 如果繼承的文件是合適的,則不再需要重複文件字串。 若要抑制繼承的字串,必須指定一個空字串(或者可以填寫文件)。 此更改會影響 pydoc 模組和 help() 函式的輸出。(由 Serhiy Storchaka 在 bpo-15582 中貢獻。)

  • 巢狀的 functools.partial() 呼叫現在被扁平化。 如果你依賴於先前的行為,現在可以向 functools.partial() 物件新增一個屬性,或者可以建立 functools.partial() 的子類。(由 Alexander Belopolsky 在 bpo-7830 中貢獻。)

C API 中的更改

  • 已刪除(非公共的)PyMemoryViewObject 結構的未文件化的 format 成員。 所有依賴於 memoryobject.h 中相關部分的擴充套件都必須重新構建。

  • PyMemAllocator 結構體已重新命名為 PyMemAllocatorEx,並添加了一個新的 calloc 欄位。

  • 移除了未文件化的宏 PyObject_REPR(),該宏會導致引用洩露。在類似 PyUnicode_FromFormat() 的函式中使用格式字元 %R 來格式化物件的 repr()。(Serhiy Storchaka 在 bpo-22453 中貢獻。)

  • 由於缺少 __module__ 屬性會破壞 pickle 和內省,現在對於沒有 __module__ 屬性的內建型別會引發棄用警告。未來這將是一個 AttributeError。(Serhiy Storchaka 在 bpo-20204 中貢獻。)

  • 作為 PEP 492 實現的一部分,PyTypeObjecttp_reserved 插槽被替換為 tp_as_async 插槽。有關新型別、結構和函式,請參閱 協程物件

Python 3.5.4 中的顯著變化

新的 make regen-all 構建目標

為了簡化交叉編譯,並確保 CPython 可以在不需要現有 Python 版本的情況下可靠地編譯,基於 autotools 的構建系統不再嘗試基於檔案修改時間隱式地重新編譯生成的檔案。

相反,添加了一個新的 make regen-all 命令,以便在需要時強制重新生成這些檔案(例如,在基於預先生成的版本已經構建了初始版本的 Python 之後)。

還定義了更具選擇性的重新生成目標 - 詳情請參閱 Makefile.pre.in

(Victor Stinner 在 bpo-23404 中貢獻。)

在 3.5.4 版本中新增。

移除 make touch 構建目標

之前用於透過更新修改時間來請求隱式重新生成生成檔案的 make touch 構建目標已被移除。

它已被新的 make regen-all 目標替換。

(Victor Stinner 在 bpo-23404 中貢獻。)

在 3.5.4 版本中更改。