What's New In Python 3.8

編集者:

Raymond Hettinger

この記事では Python 3.7 と比較した Python 3.8 の新機能を解説します。 Python 3.8 は 2019 年 10 月 14 日にリリースされました。 詳しくは 変更履歴 を参照してください。

概要 -- リリースハイライト

新しい機能

代入式

大きな構文の一部として、変数に値を割り当てる新しい構文 := が追加されました。 この構文は セイウチの目と牙 に似ているため、「セイウチ演算子」の愛称で知られています。

以下の例では、代入式により len() 関数を二重に呼びだすことを回避しています:

if (n := len(a)) > 10:
    print(f"List is too long ({n} elements, expected <= 10)")

同様の利点が、マッチがしたかどうかの判定とサブグループの取得とで2回マッチオブジェクトが必要になる、正規表現によるマッチでも、発揮されます:

discount = 0.0
if (mo := re.search(r'(\d+)% discount', advertisement)):
    discount = float(mo.group(1)) / 100.0

この演算子は、生成した値をループ終了の判定とループ本体の両方で使用するような while 文においても、有用です:

# 固定長のブロックを繰り返し処理する
while (block := f.read(256)) != '':
    process(block)

動機となったもう 1 つのユースケースは、リスト内包表記においてフィルター条件の中で計算した値が式の本体でも必要になるところから出てきます:

[clean_name.title() for name in names
 if (clean_name := normalize('NFC', name)) in allowed_names]

セイウチ演算子の使用は、複雑さを減らしたり可読性を向上させる綺麗なケースに限るよう努めてください。

完全な説明は PEP 572 を参照してください。

(Emily Morehouse の貢献による bpo-35224)

位置専用引数

関数のパラメータに新しい構文 / が追加され、一部のパラメータを位置引数としてのみ指定でき、キーワード引数では指定できないことを示せるようになりました。 これは Larry Hastings の Argument Clinic ツールでアノテーションを付けた C 関数に対し、help() が表示する表記と同じです。

以下の例では、引数 a と b が位置専用、 c と d が位置引数でもキーワード引数でも可、e と f はキーワード引数専用です:

def f(a, b, /, c, d, *, e, f):
    print(a, b, c, d, e, f)

以下は正しい関数呼び出しです:

f(10, 20, 30, d=40, e=50, f=60)

一方、以下は不正です:

f(10, b=20, c=30, d=40, e=50, f=60)   # b はキーワード引数にできない
f(10, 20, 30, 40, 50, f=60)           # e はキーワード引数でなければならない

この表記の用途の一つは、純粋な Python の関数で既存の C 実装の関数の動作を完全に再現することです。 例えば、組み込みの divmod() 関数はキーワード引数を受け付けません。

def divmod(a, b, /):
    "Emulate the built in divmod() function"
    return (a // b, a % b)

もう一つのユースケースは、引数名が有用ではない場合にキーワード引数としての利用を排除することです。例えば組み込み関数 len() は len(obj, /) というシグニチャです。これにより、以下のようなぎこちない呼び出しが排除されます:

len(obj='hello')  # "obj" キーワード引数は読みやすさを損なう

引数を位置専用とすることは、のちに引数名を変更する際に呼び出し側のコードを壊してしまう心配がないという利点があります。例えば、statistics モジュールでは、dist という引数名が将来変更される可能性があります。これは、関数が以下のような定義だからこそ可能なことです:

def quantiles(dist, /, *, n=4, method='exclusive'):
    ...

/ の左に置かれた引数はキーワード引数には使用されませんが、それゆえに同じ名前が **kwargs に出現することがあり得ます:

>>> def f(a, b, /, **kwargs):
...     print(a, b, kwargs)
...
>>> f(10, 20, a=1, b=2, c=3)         # a と b を二通りに使用
10 20 {'a': 1, 'b': 2, 'c': 3}

これにより、任意のキーワード引数を受け取る関数やメソッドを定義するのが、ぐんとシンプルになります。例えば、これは collections モジュールから抜き出したコードです:

class Counter(dict):

    def __init__(self, iterable=None, /, **kwds):
        # "iterable" はキーワード引数にも使えることに注意

詳細は PEP 570 を参照してください。

(Pablo Galindo の貢献による bpo-36540。)

コンパイル済みのバイトコードファイルのキャッシュを併存させるファイルシステム

暗黙のバイトコードキャッシュは、デフォルトでは各ソースコードのディレクトリ内の __pycache__ サブディレクトリを使用しますが、新たに追加された環境変数 PYTHONPYCACHEPREFIX (またはコマンドラインオプション -X pycache_prefix) を指定すると、ソースコードと分離されたディレクトリツリーに格納されるようになります。

キャッシュの場所は sys.pycache_prefix で参照できます(__pycache__ を使用する場合は None になります)。

(Carl Meyer の貢献による bpo-33499)

デバッグビルドとリリースビルドのABI 共通化

Python の デバッグビルド の ABI がリリースビルドと互換になりました。 Unix でデバッグモードの Python をビルドした場合、リリースモードでビルドした C 拡張や、安定 ABI を使ってビルドした C 拡張を読み込めます。 ただし逆は成り立ちません。 デバッグビルドは、リリースビルドにはない追加のシンボルを公開するためです。

Py_DEBUG マクロを定義しても、ABI 非互換の唯一の原因だった Py_TRACE_REFS マクロは暗黙に定義されなくなりました。 sys.getobjects() 関数と環境変数 PYTHONDUMPREFS を追加する Py_TRACE_REFS マクロは、新しいビルドオプション ./configure --with-trace-refs で設定できます。 (Contributed by Victor Stinner in bpo-36465.)

Unix においては、Android とCygwin を除き、C拡張モジュールはlibpython にリンクされなくなりました。静的リンクされたPython は、Python 共有ライブラリを用いてビルドされたC拡張モジュールを読み込めます。(Victor Stinner の貢献による bpo-21536.)

Unix において、Python がデバッグモードでビルドされている場合、インポートは、リリースモードで、あるいは安定ABI を用いて、ビルドされたC拡張モジュールを探すようになりました。(Victor Stinner の貢献による bpo-36722.)

Python をアプリケーション内に組み込むためには、新しい --embed オプションを有効にして python3-config --libs --embed とすると、 -lpython3.8 を有効にできます。(アプリケーションがlibpython にリンクされます) Python3.8 以前との互換性を保つためには、 python3-config --libs --embed をまず試みてから、失敗した場合 python3-config --libs (--embed なし) にフォールバックしてください。

Python をアプリケーションに組み込むために、python-3.8-embed pkg-config モジュールが追加されました: pkg-config python-3.8-embed --libs の出力は、-lpython3.8 を含みます。 Python3.8 以前との互換性を保つためには、pkg-config python-X.Y-embed --libs をまず試みてから、失敗した場合 pkg-config python-X.Y --libs (--embed なし) にフォールバックしてください。(X.Y を使用するPython のバージョンに置き換えてください)

一方で、pkg-config python3.8 --libs は出力に -lpython3.8 を含まなくなりました。C拡張モジュールは、libpython にリンクされるべきではありません。 (スクリプトによって処理される、Android とCygwin を除く) この変更では、意図的に後方互換性をなくしています。(Victor Stinner の貢献による bpo-36721)

f-string での = を用いたオブジェクトの表現

フォーマット済み文字列リテラル(f-string) において = 指定子が有効になりました。f'{expr=}' のようなf-string は、f-string に書かれた式、イコール記号、式を評価されたものの文字列表現、の順で表示されます。例えば:

>>> import datetime as dt
>>> user = 'eric_idle'
>>> member_since = dt.date(1975, 7, 31)
>>> f'{user=} {member_since=}'
"user='eric_idle' member_since=datetime.date(1975, 7, 31)"

通常の f-string 書式指定子 を用いると、より柔軟に式の結果の表示方法を変えられます:

>>> delta = dt.date.today() - member_since
>>> f'{user=!s}  {delta.days=:,d}'
'user=eric_idle  delta.days=16,075'

= 指定子は式すべてを表示するので、次のような計算も表示できます:

>>> print(f'{theta=}  {cos(radians(theta))=:.3f}')
theta=30  cos(radians(theta))=0.866

(Eric V. Smith, Larry Hastings の貢献による bpo-36817)

PEP 578: Pythonランタイムの監査フック

このPEP は、監査用フックと信頼された Open のためのフックを追加します。これらは Python およびネイティブコードから利用できます。純粋に Python で書かれたフレームワークやアプリケーションはコードに関する追加情報を得ることができ、システム管理者や埋め込みでの利用者は Python のビルドを常に監査が有効な状態で利用できます。

詳細は PEP 578 を参照してください。

PEP 587: Python 初期化設定

PEP 587 による C API の改善により、Python 初期化時に、すべての初期化設定に対するより良い制御と改善されたエラー報告が得られます。

新たな構造体:

新たな関数:

このPEP は、_PyRuntimeState.preconfig (PyPreConfig 型) と PyInterpreterState.config (PyConfig 型) を内部構造体に加えます。PyInterpreterState.config は新たな参照設定となり、グローバル設定や他の内部変数を置き換えます。

Python 初期化設定 も参照してください。

詳細は PEP 587 を参照してください。

(Victor Stinner の貢献による bpo-36763)

PEP 590: Vectorcall: CPython の高速な呼び出しプロトコル

Python/C API に vectorcall プロトコル が追加されました。 さまざまなクラスで既に行われていた最適化を、正式な仕組みとして定めるものです。 呼び出し可能オブジェクトを実装する任意の 静的型 がこのプロトコルを使えます。

これは現在、暫定版です。Python3.9 から公開で使われることを目ざしています。

詳細は PEP 590 を参照してください。

(Jeroen Demeyer、Mark Shannon、Petr Viktorin による貢献、bpo-36974。)

Pickle プロトコルバージョン 5 による帯域外データバッファ

pickle モジュールが Python のプロセス間での大容量データ転送でマルチコアないしマルチマシンでの利点を得るためには、メモリコピーの削減のほか、データ種別に応じた圧縮などの個別に合わせた最適化が重要です。

pickle プロトコルバージョン5 は、PEP 3118 互換であるようなデータが、メインのpickle ストリームとは別の独立した通信レイヤで転送されるような、帯域外バッファを提供します。

詳細は PEP 574 を参照してください。

(Antoine Pitrou の貢献による bpo-36785)

その他の言語変更

  • 実装上の問題により、finally 節での continue 文は不正でした。Python3.8 では、この制限は取り除かれています。 (Serhiy Storchaka の貢献による bpo-32489)

  • bool, int, fractions.Fraction タイプは、float や decimal.Decimal と同様の as_integer_ratio() メソッドを持つようになりました。このAPI の拡張によって、numerator, denominator = x.as_integer_ratio() のようなコードがより多くの数値型で動作します。 (Lisa Roach の貢献による bpo-33073 および Raymond Hettinger の貢献による bpo-37819)

  • int, float, complex のコンストラクタは、可能ならば __index__() 特殊メソッドを利用し、その場合は対応する __int__(), __float__() や __complex__() は使用できません。(Serhiy Storchaka の貢献による bpo-20092)

  • 正規表現 で \N{name} エスケープをサポートしました。

    >>> notice = 'Copyright © 2019'
    >>> copyright_year_pattern = re.compile(r'\N{copyright sign}\s*(\d{4})')
    >>> int(copyright_year_pattern.search(notice).group(1))
    2019
    

    (Jonathan Eunice, Serhiy Storchaka の貢献による bpo-30688)

  • dict と dictview は、reversed() を使って逆順でイテレートすることが可能になりました。(Rémi Lapeyre の貢献による bpo-33462)

  • 関数内でのキーワード名に関する構文の制限が強化されました。具体的には、f((keyword)=arg) の表現が許容されなくなりました。キーワード引数への代入の際、左側にキーワードそのまま以外の表現を許可する意図は、以前からありませんでした。 (Benjamin Peterson の貢献による bpo-34641)

  • yield 文と return 文における一般化されたイテラブルへの展開のために、全体を覆うかっこが不要になりました。これは yield と return の表現を、一般の展開と同様のわかりやすい形式にします:

    >>> def parse(family):
    ...     lastname, *members = family.split()
    ...     return lastname.upper(), *members
    ...
    >>> parse('simpsons homer marge bart lisa maggie')
    ('SIMPSONS', 'homer', 'marge', 'bart', 'lisa', 'maggie')
    

    (David Cuthbert, Jordan Chapman の貢献による bpo-32117)

  • [(10, 20) (30, 40)] のようなコードでコンマが無い場合、コンパイラは SyntaxWarning を、分かりやすい形式で表示します。これで、最初のタプルが呼び出し可能ではないことを TypeError で表示するよりもわかりやすくなります。(Serhiy Storchaka の貢献による bpo-15248)

  • datetime.date, datetime.datetime, datetime.timedelta オブジェクトのサブクラス間の算術演算は、基底クラスではなくサブクラスのインスタンスを返すようになりました。この変更は、astimezone() のような、datetime.timedelta に対する算術演算を直接ないし間接的に使用する実装の戻り値の型に影響します。(Paul Ganssle の貢献による bpo-32417)

  • Python インタープリタがCtrl-C (SIGINT) によって中断され、KeyboardInterrupt 例外の結果が捕捉されなかった場合、Python プロセスはSIGINT シグナルか、呼び出したプロセスが、Ctrl-C によって終了したことを判別できるような適切な終了コードで終了するようになりました。 POSIX とWindows 上のシェルは、非対話セッション内でスクリプトの終了処理を適切に行うために、これを利用できます。(Gregory P. Smith を通してGoogle の貢献による bpo-1054041)

  • 先進的なプログラミングにおいて、既存の関数の types.CodeType オブジェクトを更新する必要が生じます。code オブジェクトはイミュータブルなので、既存のオブジェクトがあるにもかかわらず、新しい code オブジェクトを生成する必要がありました。パラメータが19もあるので、一から作成するのは非合理的です。新しい replace() メソッドを使えば、更新すべきパラメータを書くだけで、新しいクローンを作成することができます。

    ここでは、statistics.mean() 関数がキーワード引数として data を使えないように変更する例を見てみましょう:

    >>> from statistics import mean
    >>> mean(data=[10, 20, 90])
    40
    >>> mean.__code__ = mean.__code__.replace(co_posonlyargcount=1)
    >>> mean(data=[10, 20, 90])
    Traceback (most recent call last):
      ...
    TypeError: mean() got some positional-only arguments passed as keyword arguments: 'data'
    

    (Victor Stinner の貢献による bpo-37032)

  • 整数に対する 3 引数形式の pow() は、底と法が互いに素の場合、負の指数を指定できるようになりました。 指数が -1 の場合は法に対する底の逆数を、それ以外の負の指数ではその逆数の適切なべき乗を計算します。 例えば、137 を法とする 38 の 乗法逆元 を計算するには次のように書きます。

    >>> pow(38, -1, 137)
    119
    >>> 119 * 38 % 137
    1
    

    法に対する逆数は、線形ディオファントス方程式 を解く際に現れます。 例えば 4258𝑥 + 147𝑦 = 369 の整数解を求めるには、まず 4258𝑥 ≡ 369 (mod 147) と書き直してから解きます:

    >>> x = 369 * pow(4258, -1, 147) % 147
    >>> y = (4258 * x - 369) // -147
    >>> 4258 * x + 147 * y
    369
    

    (Mark Dickinson の貢献による bpo-36027)

  • 辞書内包表現は辞書リテラルと同期されたため、まずキーが解釈され、次に値が解釈されます:

    >>> # 辞書内包表記
    >>> cast = {input('role? '): input('actor? ') for i in range(2)}
    role? King Arthur
    actor? Chapman
    role? Black Knight
    actor? Cleese
    
    >>> # 辞書リテラル
    >>> cast = {input('role? '): input('actor? ')}
    role? Sir Robin
    actor? Eric Idle
    

    この実行順の保証は代入式の役に立ち、キーの表現で代入されたものは、値の表現で使用することができます:

    >>> names = ['Martin von Löwis', 'Łukasz Langa', 'Walter Dörwald']
    >>> {(n := normalize('NFC', name)).casefold() : n for name in names}
    {'martin von löwis': 'Martin von Löwis',
     'łukasz langa': 'Łukasz Langa',
     'walter dörwald': 'Walter Dörwald'}
    

    (Jörn Heissler の貢献による bpo-35224)

  • object.__reduce__() メソッドが、2〜6 要素のタプルを返せるようになりました。 以前の上限は 5 要素でした。 省略可能な新しい第 6 要素は、シグネチャが (obj, state) の呼び出し可能オブジェクトです。 これにより、特定のオブジェクトの状態更新の動作を直接制御できます。 None でない場合、この呼び出し可能オブジェクトはオブジェクトの __setstate__() メソッドより優先されます。 (Contributed by Pierre Glaser and Olivier Grisel in bpo-35900.)

新たなモジュール

  • 新しい importlib.metadata モジュールは、サードパーティパッケージからのメタデータ読み込みをサポートします。これは暫定版です。例えば、インストールされたパッケージのバージョンを得たり、エントリーポイントの一覧を得たりできます:

    >>> # 以下の例には広く使われている "requests" パッケージの
    >>> # インストールが必要です。
    >>>
    >>> from importlib.metadata import version, requires, files
    >>> version('requests')
    '2.22.0'
    >>> list(requires('requests'))
    ['chardet (<3.1.0,>=3.0.2)']
    >>> list(files('requests'))[:5]
    [PackagePath('requests-2.22.0.dist-info/INSTALLER'),
     PackagePath('requests-2.22.0.dist-info/LICENSE'),
     PackagePath('requests-2.22.0.dist-info/METADATA'),
     PackagePath('requests-2.22.0.dist-info/RECORD'),
     PackagePath('requests-2.22.0.dist-info/WHEEL')]
    

    (Barry Warsaw, Jason R. Coombs の貢献による bpo-34632)

改良されたモジュール

ast

AST ノードは end_lineno と end_col_offset の属性を持つようになりました。これは、正確なノードの終端位置を提供します。(これは、lineno と col_offset の属性を持つノードにのみ有効です)

新しい ast.get_source_segment() 関数は、特定の AST ノードのソースコードを返します。

(Ivan Levkivskyi の貢献による bpo-33416)

ast.parse() 関数の新しいフラグが有効になりました:

  • type_comments=True は、そのAST ノードに関連する、PEP 484 と PEP 526 に規定されるような型コメントを返します;

  • mode='func_type' can be used to parse PEP 484 "signature type comments" (returned for function definition AST nodes);

  • feature_version=(3, N) を使うと、以前の Python 3 バージョンを指定できます。例えば、feature_version=(3, 4) とすると、async と await キーワードは、予約語ではないとして扱われます。

(Guido van Rossum の貢献による bpo-35766)

asyncio

asyncio.run() は暫定から安定API に移動しました。この関数は coroutine の実行と、イベントループを管理しながら自動的に結果を返すことに使用できます。例えば:

import asyncio

async def main():
    await asyncio.sleep(0)
    return 42

asyncio.run(main())

これは、だいたい次と等価です

import asyncio

async def main():
    await asyncio.sleep(0)
    return 42

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
    loop.run_until_complete(main())
finally:
    asyncio.set_event_loop(None)
    loop.close()

実装はこれよりもずっと複雑なものになっています。ですが、 asyncio.run() は非同期IOプログラムを動かす際にまず選ぶべき選択肢です。

(Yury Selivanov の貢献による bpo-32314)

python -m asyncio を実行すると、ネイティブ async 対話型インタプリタが起動します。高水準キーワード await を使うコードの試験を簡単に行えます。すべての呼び出しに対して新しいイベントループを作る asyncio.run() を呼び出す必要はありません:

$ python -m asyncio
asyncio REPL 3.8.0
Use "await" directly instead of "asyncio.run()".
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio
>>> await asyncio.sleep(10, result='hello')
hello

(Yury Selivanov の貢献による bpo-37028)

asyncio.CancelledError 例外は Exception ではなく BaseException を継承し、concurrent.futures.CancelledError を継承しなくなりました。 (Contributed by Yury Selivanov in bpo-32528.)

Windows では、イベントループのデフォルトが ProactorEventLoop になりました。(Victor Stinner の貢献による bpo-34687)

ProactorEventLoop はUDP もサポートするようになりました。(Adam Meily, Andrew Svetlov の貢献による bpo-29883)

ProactorEventLoop は KeyboardInterrupt ("CTRL+C") によって中断できるようになりました。(Vladimir Matveev の貢献による bpo-23057)

asyncio.Task 内で、内包されたコルーチンを得られる asyncio.Task.get_coro() メソッドが追加されました。(Alex Grönholm の貢献による bpo-36999)

asyncio.create_task() 関数か create_task() の name 引数を指定するか、もしくはタスクに対して set_name() メソッドを呼ぶことによって、asyncio タスクに名前をつけることができます。タスクの名前は、asyncio.Task の repr() 出力で、または get_name() メソッドで確認することができます。(Alex Grönholm の貢献による bpo-34270)

asyncio.loop.create_connection() は、Happy Eyeballs をサポートするようになりました。挙動を定義するため、2つの新しいパラメータ: happy_eyeballs_delay と interleave が加えられます。Happy Eyeballs アルゴリズムは、アプリケーションが IPv4 と IPv6 をサポートする場合、その両方を使って接続を保つことによって、アプリケーションの応答性を向上させます。(twisteroid ambassador の貢献による bpo-33530)

builtins

組み込み関数 compile() が、ast.PyCF_ALLOW_TOP_LEVEL_AWAIT フラグを受け取るようになりました。このフラグが有効である場合、compile() は、一般には有効な公文ではない、トップレベルの await, async for, async with 構文が有効になります。この場合、CO_COROUTINE フラグを持つ非同期コードオブジェクトが返されるでしょう。(Matthias Bussonnier の貢献による bpo-34616)

collections

collections.namedtuple() の _asdict() メソッドは、collections.OrderedDict ではなく dict を返すようになりました。Python 3.7 からは一般に辞書の順番が保証されるため、このような変更が可能です。OrderedDict 特有の機能を使いたい場合は、結果を OrderedDict(nt._asdict()) 型にキャストして使用することを推奨します。(Raymond Hettinger の貢献による bpo-35864)

cProfile

cProfile.Profile クラスは、コンテキストマネージャとして使用できるようになりました。このようにしてコードブロックをプロファイルします:

import cProfile

with cProfile.Profile() as profiler:
      # プロファイル対象のコード
      ...

(Scott Sanderson の貢献による bpo-29235)

csv

csv.DictReader は、collections.OrderedDict ではなく dict のインスタンスを返すようになりました。この変更によって、順序を保ちながら、より高速にかつメモリの使用量を減らして実行できます。(Michael Selik の貢献による bpo-34003)

curses

ncurses ライブラリの、構造化されたバージョン情報を保持する変数を追加しました: ncurses_version  (Serhiy Storchaka の貢献による bpo-31680)

ctypes

Windows では、CDLL とそのサブクラスが winmode 引数を受け取り、根底の LoadLibraryEx 呼び出しのフラグを指定できるようになりました。デフォルトでは、フラグは (フルパスか部分パスが初期DLL を読み込むのに使われていた場合) そのDLL が保存されている場所を含んだ信頼済みの場所と、add_dll_directory() によって加えられた場所からのみ、DLL を読み込むようになっています。(Steve Dower の貢献による bpo-36085)

datetime

新しい代替コンストラクタ datetime.date.fromisocalendar() と datetime.datetime.fromisocalendar() が追加されました。 ISO の年、週番号、曜日から、それぞれ date と datetime オブジェクトを作成します。 各クラスの isocalendar メソッドの逆操作です。 (Contributed by Paul Ganssle in bpo-36004.)

functools

@functools.lru_cache は、デコレータを返す関数としてだけでなく、デコレータそのものとしても使えるようになりました。 次の両方がサポートされます。

@lru_cache
def f(x):
    ...

@lru_cache(maxsize=256)
def f(x):
    ...

(Raymond Hettinger の貢献による bpo-36772)

計算結果のプロパティをインスタンスの寿命の間キャッシュする @functools.cached_property デコレータが追加されました。

import functools
import statistics

class Dataset:
   def __init__(self, sequence_of_numbers):
      self.data = sequence_of_numbers

   @functools.cached_property
   def variance(self):
      return statistics.variance(self.data)

(Carl Meyer の貢献による bpo-21145)

single dispatch を利用して、メソッドを ジェネリック関数 に変換する functools.singledispatchmethod() デコレータが追加されました:

from functools import singledispatchmethod
from contextlib import suppress

class TaskManager:

    def __init__(self, tasks):
        self.tasks = list(tasks)

    @singledispatchmethod
    def discard(self, value):
        with suppress(ValueError):
            self.tasks.remove(value)

    @discard.register(list)
    def _(self, tasks):
        targets = set(tasks)
        self.tasks = [x for x in self.tasks if x not in targets]

(Ethan Smith の貢献による bpo-32380)

gc

get_objects() は、オブジェクトを得る世代を指定するオプションのパラメータ引数 generation を受け取るようになりました。(Pablo Galindo の貢献による bpo-36016)

gettext

pgettext() を含む、類似のいくつかの関数が追加されました。 (Franz Glasner, Éric Araujo, Cheryl Sabella の貢献による bpo-2504)

gzip

出力の再現性のために、gzip.compress() に mtime パラメータが追加されました。 (Guo Ci Teo の貢献による bpo-34898)

不正な、あるいは破損した gzip ファイルのうち、所定の種類のものについて、OSError にかわって BadGzipFile 例外が送出されるようになりました。(Filip Gruszczyński, Michele Orrù, Zackery Spytz の貢献による bpo-6584)

IDLE と idelelib

N 行 (デフォルトは 50 行) を超える出力は、一つのボタンに折り畳まれます。 N は設定ダイアログの General ページにある PyShell セクションで変更できます。 行数が少なくても各行が非常に長い場合などは、出力を右クリックして折り畳めます。 折り畳んだ出力は、ボタンのダブルクリックでその場に展開でき、右クリックでクリップボードや別のウィンドウに展開できます。 (Contributed by Tal Einat in bpo-1529353.)

Run メニューに、設定を変更してモジュールを実行する "Run Customized" が追加されました。 入力したコマンドライン引数は sys.argv に追加され、次回のカスタム実行時にも入力欄に表示されます。 通常行われる Shell のメインモジュールの再起動を抑制することもできます。 (Contributed by Cheryl Sabella, Terry Jan Reedy, and others in bpo-5680 and bpo-37627.)

IDLE のエディターウィンドウに、必要に応じて行番号を表示できるようになりました。 設定ダイアログの General タブで指定しない限り、行番号なしでウィンドウが開きます。 既存のウィンドウの行番号は Options メニューで表示、非表示を切り替えられます。 (Contributed by Tal Einat and Saimadhav Heblikar in bpo-17535.)

Python の文字列と Tcl オブジェクトの相互変換に、OS ネイティブのエンコーディングを使うようになりました。 これにより IDLE で絵文字などの BMP 外の文字を扱えるようになり、表示やクリップボードへのコピー、クリップボードからの貼り付けが可能になります。 Tcl から Python への文字列変換とその逆は、もはや失敗しません。 (8 年間にわたって多くの人が取り組み、最終的に Serhiy Storchaka が bpo-13153 で解決しました。)

3.8.1 の新機能:

カーソルの点滅を無効にするオプションが追加されました。 (Contributed by Zackery Spytz in bpo-4603.)

Escape キーで IDLE の補完ウィンドウを閉じられるようになりました。 (Contributed by Johnny Najera in bpo-38944.)

上で挙げた変更は 3.7 のメンテナンスリリースにバックポートされました。

モジュール名の補完候補のリストにキーワードが追加されました。 (Contributed by Terry J. Reedy in bpo-37765.)

inspect

inspect.getdoc() 関数は、__slots__ 属性が docstring を値に持つ dict であれば、各スロットの docstring を取得できるようになりました。 これにより @property、@classmethod、@staticmethod と同様の方法でドキュメントを付けられます。

class AudioClip:
    __slots__ = {'bit_rate': 'expressed in kilohertz to one decimal place',
                 'duration': 'in seconds, rounded up to an integer'}
    def __init__(self, bit_rate, duration):
        self.bit_rate = round(bit_rate / 1000.0, 1)
        self.duration = ceil(duration)

(Raymond Hettinger の貢献による bpo-36326)

io

In development mode (-X dev) and in debug build, the io.IOBase finalizer now logs the exception if the close() method fails. The exception is ignored silently by default in release build. (Contributed by Victor Stinner in bpo-18748.)

itertools

itertools.accumulate() 関数に、初期値を定める、オプションの initial キーワード引数が追加されました:

>>> from itertools import accumulate
>>> list(accumulate([10, 5, 30, 15], initial=1000))
[1000, 1010, 1015, 1045, 1060]

(Lisa Roach の貢献による bpo-34659)

json.tool

一行ごとに別々の JSON オブジェクトへ解析をする --json-lines オプションが追加されました。(Weipeng Hong の貢献による bpo-31553)

logging

logging.basicConfig() に force キーワード引数が追加されました。 真に設定すると、ほかの引数で指定した設定を行う前に、ルートロガーに取り付けられた既存のハンドラーをすべて取り外して閉じます。

これは長年の問題を解決するものです。 一度ロガーまたは basicConfig() を呼び出すと、それ以降の basicConfig() の呼び出しは何も通知せず無視されていました。 そのため、対話型プロンプトや Jupyter notebook でログ設定の各種オプションを更新、試行、説明することが難しくなっていました。

(Raymond Hettinger による提案、Donghee Na による実装、Vinay Sajip によるレビュー、bpo-33897。)

math

二点間のユークリッド距離を計算する math.dist() 関数が追加されました。(Raymond Hettinger の貢献による bpo-33089)

math.hypot() 関数は、3次元以上を扱えるように拡張されました。以前は、二次元の場合のみに対応していました。(Raymond Hettinger の貢献による bpo-33089)

sum() に類似する関数として、初期値(デフォルトは1) に対してイテレート可能なオブジェクトの数を掛けていく math.prod() 関数が追加されました:

>>> prior = 0.8
>>> likelihoods = [0.625, 0.84, 0.30]
>>> math.prod(likelihoods, start=prior)
0.126

(Pablo Galindo の貢献による bpo-35606)

2つの組み合わせの関数 math.perm() と math.comb() が追加されました:

>>> math.perm(10, 3)    # 10 個から 3 個を取る順列
720
>>> math.comb(10, 3)    # 10 個から 3 個を取る組み合わせ
120

(Yash Aggarwal, Keller Fuchs, Serhiy Storchaka, Raymond Hettinger の貢献による bpo-37128, bpo-37178, bpo-35431)

浮動小数点数を介することなく、正確な整数の二乗根を計算する関数 math.isqrt() が追加されました。この関数は、巨大な整数にも使用できます。floor(sqrt(n)) より高速ですが、math.sqrt() より少し遅いです:

>>> r = 650320427
>>> s = r ** 2
>>> isqrt(s - 1)         # 正しい
650320426
>>> floor(sqrt(s - 1))   # 誤り
650320427

(Mark Dickinson の貢献による bpo-36887)

math.factorial() 関数は、引数に int、またはそれに類似するもの以外を受け取らなくなりました。(Pablo Galindo の貢献による bpo-33083)

mmap

mmap.mmap クラスに、madvise() システムコールを使う madvise() メソッドが追加されました。 (Contributed by Zackery Spytz in bpo-32941.)

multiprocessing

multiprocessing.shared_memory モジュールが追加されました。 (Contributed by Davin Potts in bpo-35813.)

macOS では spawn 開始方式がデフォルトになりました。 (Contributed by Victor Stinner in bpo-33725.)

os

Windows に add_dll_directory() 関数が追加されました。 拡張モジュールのインポートや ctypes による DLL の読み込みで、ネイティブの依存ライブラリの検索パスを追加できます。 (Contributed by Steve Dower in bpo-36085.)

memfd_create() システムコールをラップする os.memfd_create() 関数が追加されました。 (Contributed by Zackery Spytz and Christian Heimes in bpo-26836.)

Windows では、再解析ポイント (シンボリックリンクやディレクトリジャンクションを含む) を扱う独自のロジックの多くを OS に委譲しました。 具体的には、os.stat() は OS がサポートするものをすべてたどります。 一方 os.lstat() は "name surrogates" と識別される再解析ポイントだけを直接開き、それ以外は os.stat() と同じように開きます。 いずれの場合も os.stat_result.st_mode の S_IFLNK が設定されるのはシンボリックリンクだけで、ほかの種類の再解析ポイントには設定されません。 ほかの種類を識別するには、新しい os.stat_result.st_reparse_tag 属性を確認してください。

Windows で os.readlink() がディレクトリジャンクションを読み取れるようになりました。 ただし islink() はジャンクションに対して False を返すため、先に islink を調べるコードは引き続きディレクトリとして扱います。 一方、os.readlink() のエラーを処理するコードは、ジャンクションをリンクとして扱う場合があります。

(Steve Dower による貢献、bpo-37834。)

os.path

os.path の exists()、lexists()、isdir()、isfile()、islink()、ismount() など、ブール値を返す関数の動作が変わりました。 OS レベルで表現できない文字やバイトを含むパスに対して、ValueError やそのサブクラスの UnicodeEncodeError、UnicodeDecodeError を送出せず、False を返します。 (Contributed by Serhiy Storchaka in bpo-33721.)

Windows の expanduser() は環境変数 USERPROFILE を優先し、通常のユーザーアカウントでは通常設定されない HOME を使わなくなりました。 (Contributed by Anthony Sottile in bpo-36264.)

Windows の isdir() は、存在しないディレクトリへのリンクに対して True を返さなくなりました。

Windows の realpath() は、シンボリックリンクやディレクトリジャンクションを含む再解析ポイントを解決するようになりました。

(Steve Dower による貢献、bpo-37834。)

pathlib

pathlib.Path の exists()、is_dir()、is_file()、is_mount()、is_symlink()、is_block_device()、is_char_device()、is_fifo()、is_socket() など、ブール値を返すメソッドの動作が変わりました。 OS レベルで表現できない文字を含むパスに対して、ValueError やそのサブクラスの UnicodeEncodeError を送出せず、False を返します。 (Contributed by Serhiy Storchaka in bpo-33721.)

パスを指すハードリンクを作成する pathlib.Path.link_to() が追加されました。 (Joannah Nanjekye による貢献、bpo-26978。) ただし link_to は 3.10 で非推奨になり、3.12 で削除されました。 代わりに、既存の symlink_to と意味を揃えた hardlink_to メソッドが 3.10 で追加されています。

pickle

C で最適化された Pickler をサブクラス化する pickle の拡張は、特殊メソッド reducer_override() を定義することで、関数やクラスの pickle 化のロジックをオーバーライドできるようになりました。 (Contributed by Pierre Glaser and Olivier Grisel in bpo-35900.)

plistlib

plistlib.UID が追加され、NSKeyedArchiver でエンコードされたバイナリ plist の読み書きに対応しました。 (Contributed by Jon Janzen in bpo-26707.)

pprint

pprint モジュールの複数の関数に sort_dicts パラメータが追加されました。 デフォルトでは、引き続き辞書を並べ替えてから文字列表現を作成、表示します。 ただし sort_dicts を偽にすると、辞書はキーの挿入順を維持します。 デバッグ時に JSON 入力と比較する場合などに便利です。

さらに便利な新しい関数 pprint.pp() が追加されました。 pprint.pprint() と似ていますが、sort_dicts のデフォルトは False です。

>>> from pprint import pprint, pp
>>> d = dict(source='input.txt', operation='filter', destination='output.txt')
>>> pp(d, width=40)                  # 元の順序
{'source': 'input.txt',
 'operation': 'filter',
 'destination': 'output.txt'}
>>> pprint(d, width=40)              # キーをアルファベット順に並べ替え
{'destination': 'output.txt',
 'operation': 'filter',
 'source': 'input.txt'}

(Rémi Lapeyre による貢献、bpo-30670。)

py_compile

py_compile.compile() がサイレントモードに対応しました。 (Contributed by Joannah Nanjekye in bpo-22640.)

shlex

新しい shlex.join() 関数は shlex.split() の逆操作を行います。 (Contributed by Bo Bayles in bpo-32102.)

shutil

shutil.copytree() に dirs_exist_ok キーワード引数が追加されました。 (Contributed by Josh Bronson in bpo-20849.)

shutil.make_archive() は、tarfile の対応する変更を受け、新しいアーカイブに新しい pax (POSIX.1-2001) 形式をデフォルトで使うようになりました。 移植性と標準への準拠を改善します。 (Contributed by C.A.M. Gerlach in bpo-30661.)

Windows の shutil.rmtree() は、ディレクトリジャンクションの内容を先に再帰的に削除することなく、ジャンクションだけを削除するようになりました。 (Contributed by Steve Dower in bpo-37834.)

socket

サーバーソケットの作成に通常必要な処理を自動化する便利な関数 create_server() と has_dualstack_ipv6() が追加されました。 同じソケットで IPv4 と IPv6 の両方の接続を受け付ける処理も含まれます。 (Contributed by Giampaolo Rodolà in bpo-17561.)

socket.if_nameindex()、socket.if_nametoindex()、socket.if_indextoname() 関数が Windows に実装されました。 (Contributed by Zackery Spytz in bpo-37007.)

ssl

TLS 1.3 のハンドシェイク後認証を有効にする post_handshake_auth と、それを開始する verify_client_post_handshake() が追加されました。 (Contributed by Christian Heimes in bpo-34670.)

statistics

statistics.mean() の高速な浮動小数点版 statistics.fmean() が追加されました。 (Contributed by Raymond Hettinger and Steven D'Aprano in bpo-35904.)

statistics.geometric_mean() が追加されました。 (Contributed by Raymond Hettinger in bpo-27181.)

最も出現頻度の高い値のリストを返す statistics.multimode() が追加されました。 (Contributed by Raymond Hettinger in bpo-35892.)

データや分布を同じ確率の区間 (四分位、十分位、百分位など) に分ける statistics.quantiles() が追加されました。 (Contributed by Raymond Hettinger in bpo-36546.)

確率変数の正規分布を作成、操作するための statistics.NormalDist が追加されました。 (Contributed by Raymond Hettinger in bpo-36018.)

>>> temperature_feb = NormalDist.from_samples([4, 12, -3, 2, 7, 14])
>>> temperature_feb.mean
6.0
>>> temperature_feb.stdev
6.356099432828281

>>> temperature_feb.cdf(3)            # 3 度未満になる確率
0.3184678262814532
>>> # 7 度と 10 度での確率密度の比
>>> temperature_feb.pdf(7) / temperature_feb.pdf(10)
1.2039930378537762

>>> el_niño = NormalDist(4, 2.5)
>>> temperature_feb += el_niño        # 気候の影響を加える
>>> temperature_feb
NormalDist(mu=10.0, sigma=6.830080526611674)

>>> temperature_feb * (9/5) + 32      # 華氏に変換
NormalDist(mu=50.0, sigma=12.294144947901014)
>>> temperature_feb.samples(3)        # ランダムな標本を生成
[7.672102882379219, 12.000027119750287, 4.647488369766392]

sys

新しい sys.unraisablehook() 関数が追加され、オーバーライドすることで「送出できない例外」の処理を制御できます。 例外が発生しても Python が処理できない場合に呼ばれます。 例えば、デストラクタが例外を送出した場合や、ガベージコレクション (gc.collect()) 中の例外などです。 (Contributed by Victor Stinner in bpo-36829.)

tarfile

tarfile モジュールは、新しいアーカイブのデフォルト形式を従来の GNU 固有の形式から、新しい pax (POSIX.1-2001) 形式に変更しました。 標準化された拡張可能な形式で一貫したエンコーディング (UTF-8) を使うため、プラットフォーム間の移植性が改善され、ほかにも利点があります。 (Contributed by C.A.M. Gerlach in bpo-36268.)

threading

threading.Thread.run() の捕捉されなかった例外を処理する threading.excepthook() 関数が追加されました。 これをオーバーライドすると、threading.Thread.run() の捕捉されなかった例外の処理を制御できます。 (Contributed by Victor Stinner in bpo-1230540.)

Add a new threading.get_native_id() function and a native_id attribute to the threading.Thread class. These return the native integral Thread ID of the current thread assigned by the kernel. This feature is only available on certain platforms, see get_native_id for more information. (Contributed by Jake Tesler in bpo-36084.)

tokenize

tokenize モジュールは、末尾に改行のない入力に対して暗黙に NEWLINE トークンを出力するようになりました。 これにより C のトークナイザーの内部動作と一致します。 (Contributed by Ammar Askar in bpo-33899.)

tkinter

tkinter.Spinbox クラスに selection_from()、selection_present()、selection_range()、selection_to() メソッドが追加されました。 (Contributed by Juliette Monsel in bpo-34829.)

tkinter.Canvas クラスに moveto() メソッドが追加されました。 (Contributed by Juliette Monsel in bpo-23831.)

tkinter.PhotoImage クラスに transparency_get() と transparency_set() メソッドが追加されました。 (Contributed by Zackery Spytz in bpo-25451.)

time

macOS 10.12 向けに新しいクロック CLOCK_UPTIME_RAW が追加されました。 (Contributed by Joannah Nanjekye in bpo-35702.)

typing

typing モジュールに、いくつかの新機能が追加されました:

  • キーごとに型を指定する辞書型。 PEP 589 と typing.TypedDict を参照してください。 TypedDict のキーは文字列だけです。 デフォルトではすべてのキーが必須です。 "total=False" を指定すると、キーを省略可能にできます。

    class Location(TypedDict, total=False):
        lat_long: tuple
        grid_square: str
        xy_coordinate: tuple
    
  • リテラル型。 PEP 586 と typing.Literal を参照してください。 リテラル型は、パラメータや戻り値を一つ以上の特定のリテラル値に制限することを示します。

    def get_status(port: int) -> Literal['connected', 'disconnected']:
        ...
    
  • "Final" な変数、関数、メソッド、クラス。 PEP 591、typing.Final、@typing.final を参照してください。 final 指定は、サブクラス化、オーバーライド、再代入を制限するよう静的型検査ツールに指示します。

    pi: Final[float] = 3.1415926536
    
  • プロトコルの定義。 PEP 544、typing.Protocol、@typing.runtime_checkable を参照してください。 typing.SupportsInt のような単純な ABC は Protocol のサブクラスになりました。

  • 新しいプロトコルクラス typing.SupportsIndex。

  • 新しい関数 typing.get_origin() と typing.get_args()。

unicodedata

unicodedata モジュールが Unicode 12.1.0 のリリースを使うよう更新されました。

新しい is_normalized() 関数で、文字列が特定の正規形かどうかを確認できます。 実際に正規化するより大幅に速い場合が多くあります。 (Contributed by Max Belanger, David Euresti, and Greg Price in bpo-32285 and bpo-37966)

unittest

Mock の非同期版として AsyncMock が追加されました。 テスト用の対応する assert 関数も追加されました。 (Contributed by Lisa Roach in bpo-26467)

unittest に addModuleCleanup() と addClassCleanup() が追加され、setUpModule() と setUpClass() の後始末をサポートしました。 (Contributed by Lisa Roach in bpo-24412.)

モックのいくつかの assert 関数は、失敗時に実際の呼び出しの一覧も表示するようになりました。 (Contributed by Petter Strandmark in bpo-35047.)

unittest モジュールは unittest.IsolatedAsyncioTestCase を使うことで、コルーチンをテストケースとして使えるようになりました。 (Contributed by Andrew Svetlov in bpo-32972.)

以下はプログラム例です:

import unittest


class TestRequest(unittest.IsolatedAsyncioTestCase):

    async def asyncSetUp(self):
        self.connection = await AsyncConnection()

    async def test_get(self):
        response = await self.connection.get("https://example.com")
        self.assertEqual(response.status_code, 200)

    async def asyncTearDown(self):
        await self.connection.close()


if __name__ == "__main__":
    unittest.main()

venv

venv はすべてのプラットフォームに Activate.ps1 スクリプトを含め、PowerShell Core 6.1 で仮想環境を有効化できるようになりました。 (Contributed by Brett Cannon in bpo-32718.)

weakref

weakref.proxy() が返すプロキシオブジェクトは、ほかの数値演算子に加えて行列乗算の @ と @= にも対応しました。 (Contributed by Mark Dickinson in bpo-36669.)

xml

DTD や外部実体の取得による問題を軽減するため、xml.dom.minidom と xml.sax モジュールはデフォルトでは外部実体を処理しなくなりました。 (Contributed by Christian Heimes in bpo-17239.)

xml.etree.ElementTree の .find*() メソッドがワイルドカード検索に対応しました。 例えば {*}tag は名前空間を無視し、{namespace}* は指定した名前空間のすべてのタグを返します。 (Contributed by Stefan Behnel in bpo-28238.)

xml.etree.ElementTree モジュールに C14N 2.0 を実装する canonicalize() 関数が追加されました。 (Contributed by Stefan Behnel in bpo-13611.)

xml.etree.ElementTree.XMLParser のターゲットオブジェクトは、新しいコールバックメソッド start_ns() と end_ns() で名前空間宣言のイベントを受信できます。 また xml.etree.ElementTree.TreeBuilder ターゲットは、コメントや処理命令のイベントを処理し、生成されるツリーに含めるよう設定できるようになりました。 (Contributed by Stefan Behnel in bpo-36676 and bpo-36673.)

xmlrpc

xmlrpc.client.ServerProxy に省略可能な headers キーワード引数が追加され、各リクエストで送る HTTP ヘッダーのシーケンスを指定できます。 例えば、デフォルトの Basic 認証から高速なセッション認証への切り替えが可能になります。 (Contributed by Cédric Krier in bpo-35153.)

最適化

  • subprocess モジュールは、一部の場合に os.posix_spawn() 関数を使って性能を改善できるようになりました。 現時点では macOS と Linux (glibc 2.24 以降) で、次のすべての条件を満たす場合にのみ使われます:

    • close_fds が偽である。

    • preexec_fn、pass_fds、cwd、start_new_session パラメータが設定されていない。

    • executable のパスにディレクトリが含まれる。

    (Joannah Nanjekye と Victor Stinner による貢献、bpo-35537。)

  • shutil.copyfile()、shutil.copy()、shutil.copy2()、shutil.copytree()、shutil.move() は、Linux と macOS でプラットフォーム固有の「高速コピー」システムコールを使い、より効率的にファイルをコピーするようになりました。 「高速コピー」とはカーネル内でコピーを行い、outfd.write(infd.read()) のような Python のユーザー空間のバッファを使わないことを意味します。 Windows の shutil.copyfile() はデフォルトのバッファサイズを 16 KiB から 1 MiB に増やし、shutil.copyfileobj() の memoryview() を使う変形を利用します。 同じパーティション内での 512 MiB のファイルのコピーは、Linux で約 26%、macOS で約 50%、Windows で約 40% 高速になります。 CPU サイクルの消費も大幅に減ります。 プラットフォーム依存の効率的なコピー操作 を参照してください。 (Contributed by Giampaolo Rodolà in bpo-33671.)

  • shutil.copytree() は os.scandir() 関数を使い、それに依存するすべてのコピー関数はキャッシュされた os.stat() の値を使うようになりました。 8000 個のファイルがあるディレクトリのコピーは、Linux で約 9%、Windows で約 20%、Windows の SMB 共有で約 30% 高速になります。 os.stat() システムコールの回数も 38% 減り、特にネットワークファイルシステムで shutil.copytree() が高速になります。 (Contributed by Giampaolo Rodolà in bpo-33695.)

  • pickle モジュールのデフォルトプロトコルが、Python 3.4 で導入されたプロトコル 4 になりました。 Python 3.0 から利用できるプロトコル 3 と比べ、性能がよく、サイズも小さくなります。

  • PyGC_Head から Py_ssize_t のメンバーが一つ削除されました。 GC が追跡するすべてのオブジェクト (tuple、list、dict など) のサイズが 4 または 8 バイト減りました。 (Contributed by Inada Naoki in bpo-33597.)

  • uuid.UUID は __slots__ を使い、メモリ使用量を減らすようになりました。 (Contributed by Wouter Bolsterlee and Tal Einat in bpo-30977)

  • operator.itemgetter() の性能が 33% 改善されました。 引数処理を最適化し、タプルに対して単一の非負整数のインデックスを使う一般的な場合 (標準ライブラリの典型的な用途) に、高速な処理経路を追加しました。 (Contributed by Raymond Hettinger in bpo-35664.)

  • collections.namedtuple() のフィールド検索が 2 倍以上高速になり、Python のインスタンス変数の検索方法の中で最も高速になりました。 (Contributed by Raymond Hettinger, Pablo Galindo, and Joe Jevnik, Serhiy Storchaka in bpo-32492.)

  • list コンストラクタは、入力のイテラブルの長さが分かる場合 (__len__ を実装している場合)、内部の要素バッファを余分に確保しなくなりました。 生成されるリストは平均 12% 小さくなります。 (Contributed by Raymond Hettinger and Pablo Galindo in bpo-33234.)

  • クラス変数への書き込みが 2 倍高速になりました。 両端がダブルアンダースコアでない属性の更新時に、不要なスロット更新の呼び出しが行われていました。 (Contributed by Stefan Behnel, Pablo Galindo Salgado, Raymond Hettinger, Neil Schemenauer, and Serhiy Storchaka in bpo-36012.)

  • 多くの組み込み関数やメソッドに渡される引数の変換のオーバーヘッドが減りました。 単純な組み込み関数やメソッドの一部の呼び出しが最大 20〜50% 高速になりました。 (Contributed by Serhiy Storchaka in bpo-23867, bpo-35582 and bpo-36127.)

  • LOAD_GLOBAL 命令が新しい「オペコードごとのキャッシュ」機構を使い、約 40% 高速になりました。 (Contributed by Yury Selivanov and Inada Naoki in bpo-26219.)

ビルドならびに C API の変更

  • デフォルトの sys.abiflags は空文字列になりました。 pymalloc の有無で ABI が互換であるため、pymalloc を表す m フラグが不要となり削除されました。 (Contributed by Victor Stinner in bpo-36707.)

    変更の例:

    • python3.8 プログラムだけがインストールされ、python3.8m プログラムはなくなりました。

    • python3.8-config スクリプトだけがインストールされ、python3.8m-config スクリプトはなくなりました。

    • 動的ライブラリのファイル名の接尾辞から m フラグが削除されました。 標準ライブラリの拡張モジュールも、PyPI からダウンロードしたパッケージなどのサードパーティーパッケージが生成、インストールするものも対象です。 例えば Linux では Python 3.7 の接尾辞 .cpython-37m-x86_64-linux-gnu.so が、Python 3.8 で .cpython-38-x86_64-linux-gnu.so になりました。

  • API の種類をより明確に分けるため、ヘッダーファイルが再編成されました:

    • Include/*.h は、移植性のある公開の安定 C API を置く場所です。

    • Include/cpython/*.h は、CPython 固有の不安定な C API を置く場所です。 公開 API と、_Py または _PY で始まる一部の非公開 API を含みます。

    • Include/internal/*.h は、CPython に特化した非公開の内部 C API です。 後方互換性の保証はなく、CPython の外で使うべきではありません。 関数を呼ばずに CPython 内部へアクセスする必要があるデバッガーやプロファイラーなど、ごく特定の用途のためだけに公開されています。 この API は make install でインストールされるようになりました。

    (Victor Stinner による貢献、bpo-35134、bpo-35081。この取り組みは Python 3.7 で Eric Snow が始めました。)

  • 一部のマクロが静的インライン関数に変換されました。 パラメータと戻り値の型が明確に定まり、マクロ固有の問題がなく、変数がローカルスコープを持つようになります。 例:

    (Victor Stinner による貢献、bpo-35059。)

  • PyByteArray_Init() と PyByteArray_Fini() 関数が削除されました。 Python 2.7.4 と Python 3.2.0 以降は何もせず、制限付き API (安定 ABI) からも除外され、文書化されていませんでした。 (Contributed by Victor Stinner in bpo-35713.)

  • PyExceptionClass_Name() の戻り値の型が char * から const char * に変わりました。 (Contributed by Serhiy Storchaka in bpo-33818.)

  • Modules/Setup.dist と Modules/Setup の二重構成がなくなりました。 以前は CPython のソースツリーを更新すると、上流の変更を反映するために、ソースツリー内の Modules/Setup.dist をビルドツリー内の Modules/Setup に手動でコピーする必要がありました。 これはパッケージ作成者には少し便利でしたが、コピーを忘れるとビルドに失敗することがあり、CPython の開発を追う開発者には頻繁な負担になっていました。

    ビルドシステムは、常にソースツリー内の Modules/Setup を読むようになりました。 このファイルを変更したい場合は、ソースツリーへのほかの変更と同様に、CPython の git フォークやパッチファイルで変更を管理することを推奨します。

    (Antoine Pitrou による貢献、bpo-32430。)

  • PyLong_AsLong() などの Python の数値を C の整数に変換する関数や、PyArg_ParseTuple() などで 'i' のような整数変換用の書式単位を使う引数解析では、利用可能であれば __int__() の代わりに __index__() 特殊メソッドを使うようになりました。 Decimal や Fraction など、__int__() はあっても __index__() がないオブジェクトには非推奨の警告を出します。 PyNumber_Check() は、__index__() を実装するオブジェクトに 1 を返すようになりました。 PyNumber_Long()、PyNumber_Float()、PyFloat_AsDouble() も、利用可能であれば __index__() を使うようになりました。 (Contributed by Serhiy Storchaka in bpo-36048 and bpo-20092.)

  • ヒープに割り当てられた型オブジェクトの参照カウントは、PyType_GenericAlloc() ではなく PyObject_Init() (および対応する PyObject_INIT マクロ) で増加するようになりました。 インスタンスの割り当てや解放を変更する型は、調整が必要になる場合があります。 (Contributed by Eddie Elizondo in bpo-35810.)

  • 新しい PyCode_NewWithPosOnlyArgs() 関数は PyCode_New() と同様にコードオブジェクトを作成しますが、位置専用引数の数を示す posonlyargcount パラメータが追加されています。 (Contributed by Pablo Galindo in bpo-37221.)

  • Py_SetPath() now sets sys.executable to the program full path (Py_GetProgramFullPath()) rather than to the program name (Py_GetProgramName()). (Contributed by Victor Stinner in bpo-38234.)

非推奨

API と機能の削除

次の機能と API が Python 3.8 から削除されました:

  • Python 3.3 から collections からの ABC のインポートは非推奨であり、collections.abc からインポートする必要があります。 collections からのインポートは 3.8 で削除予定でしたが、3.9 に延期されました (gh-81134 を参照)。

  • Python 3.7 で非推奨になった macpath モジュールが削除されました。 (Contributed by Victor Stinner in bpo-35471.)

  • Python 3.3 から非推奨だった platform.popen() 関数が削除されました。 代わりに os.popen() を使ってください。 (Contributed by Victor Stinner in bpo-35345.)

  • Python 3.3 から非推奨だった time.clock() 関数が削除されました。 動作を明確にするため、用途に応じて time.perf_counter() または time.process_time() を使ってください。 (Contributed by Matthias Bussonnier in bpo-36895.)

  • pyvenv スクリプトがどの Python インタープリタに対応するかという混乱を避けるため、スクリプトは削除され、代わりに python3.8 -m venv を使うようになりました。 (Contributed by Brett Cannon in bpo-25427.)

  • cgi モジュールから parse_qs、parse_qsl、escape が削除されました。 これらは Python 3.2 以前から非推奨でした。 代わりに urllib.parse と html モジュールからインポートしてください。

  • tarfile モジュールから filemode 関数が削除されました。 文書化されておらず、Python 3.3 から非推奨でした。

  • XMLParser のコンストラクタは html 引数を受け付けなくなりました。 この引数は元から効果がなく、Python 3.4 で非推奨になっていました。 ほかのパラメータはすべて キーワード専用 になりました。 (Contributed by Serhiy Storchaka in bpo-29209.)

  • XMLParser の doctype() メソッドが削除されました。 (Contributed by Serhiy Storchaka in bpo-29209.)

  • "unicode_internal" コーデックが削除されました。 (Contributed by Inada Naoki in bpo-36297.)

  • sqlite3 モジュールの Cache と Statement オブジェクトはユーザーに公開されなくなりました。 (Contributed by Aviv Palivoda in bpo-30262.)

  • fileinput.input() と fileinput.FileInput() の bufsize キーワード引数が削除されました。 Python 3.6 から無視され、非推奨になっていました (bpo-36952)。 (Contributed by Matthias Bussonnier.)

  • Python 3.7 で非推奨になった sys.set_coroutine_wrapper() と sys.get_coroutine_wrapper() 関数が削除されました (bpo-36933)。 (Contributed by Matthias Bussonnier.)

Python 3.8 への移植

このセクションでは前述の変更とバグフィックスにより必要となるかもしれないコードの変更を列挙します:

Python の挙動の変更

  • 内包表記とジェネレータ式では、最も左の for 節のイテラブル式を除き、yield 式 (yield と yield from の両方) を使えなくなりました。 (Contributed by Serhiy Storchaka in bpo-10544.)

  • 同一性の検査 (is と is not) を文字列や数値などの特定のリテラルに使うと、コンパイラが SyntaxWarning を出すようになりました。 CPython では偶然動くことがありますが、言語仕様では保証されません。 警告では、代わりに等価性の検査 (== と !=) を使うよう案内します。 (Contributed by Serhiy Storchaka in bpo-34850.)

  • CPython インタープリタは、状況によっては例外を握りつぶすことがあります。 Python 3.8 ではそのような場合が減りました。 特に、型の辞書から属性を取得するときに発生した例外を無視しなくなりました。 (Contributed by Serhiy Storchaka in bpo-35459.)

  • 組み込み型の bool、int、float、complex と、標準ライブラリのいくつかのクラスから __str__ の実装が削除されました。 これらは object から __str__() を継承します。 その結果、これらのサブクラスで __repr__() を定義すると文字列表現に影響するようになります。 (Contributed by Serhiy Storchaka in bpo-36793.)

  • AIX では sys.platform にメジャーバージョンが含まれなくなりました。 'aix3'〜'aix7' ではなく、常に 'aix' になります。 古い Python ではバージョン番号を含むため、常に sys.platform.startswith('aix') を使うことを推奨します。 (Contributed by M. Felt in bpo-36588.)

  • PyEval_AcquireLock() と PyEval_AcquireThread() は、インタープリタの終了処理中に呼ぶと現在のスレッドを終了するようになりました。 PyEval_RestoreThread()、Py_END_ALLOW_THREADS()、PyGILState_Ensure() と同じ動作になります。 これを望まない場合は、_Py_IsFinalizing() または sys.is_finalizing() を確認して呼び出しを保護してください。 (Contributed by Joannah Nanjekye in bpo-36475.)

Python API の変更

  • Windows の os.getcwdb() 関数が、ANSI コードページではなく UTF-8 エンコーディングを使うようになりました。 理由については PEP 529 を参照してください。 この関数は Windows でも非推奨ではなくなりました。 (Contributed by Victor Stinner in bpo-37412.)

  • subprocess.Popen は、一部の場合に os.posix_spawn() を使って性能を改善できるようになりました。 Windows Subsystem for Linux と QEMU のユーザーエミュレーションでは、os.posix_spawn() を使う Popen コンストラクタは、「プログラムが見つからない」などのエラーで例外を送出しなくなりました。 代わりに子プロセスがゼロ以外の returncode で失敗します。 (Contributed by Joannah Nanjekye and Victor Stinner in bpo-35537.)

  • subprocess.Popen の preexec_fn 引数はサブインタープリタでは使えなくなりました。 サブインタープリタで指定すると RuntimeError を送出します。 (Contributed by Eric Snow in bpo-34651, modified by Christian Heimes in bpo-37951.)

  • imaplib.IMAP4.logout() は、任意の例外を通知なく無視することをやめました。 (Contributed by Victor Stinner in bpo-36348.)

  • Python 3.3 から非推奨だった platform.popen() 関数が削除されました。 代わりに os.popen() を使ってください。 (Contributed by Victor Stinner in bpo-35345.)

  • statistics.mode() は、最頻値が複数あるデータでも例外を送出せず、入力データで最初に現れた最頻値を返すようになりました。 (Contributed by Raymond Hettinger in bpo-35892.)

  • tkinter.ttk.Treeview の selection() メソッドは引数を受け付けなくなりました。 引数を渡して選択を変更する使い方は Python 3.6 で非推奨になっていました。 選択を変更するには selection_set() などの専用メソッドを使ってください。 (Contributed by Serhiy Storchaka in bpo-31508.)

  • xml.dom.minidom の writexml()、toxml()、toprettyxml() と、xml.etree.ElementTree の write() は、ユーザーが指定した属性の順序を保持するようになりました。 (Contributed by Diego Rojas and Raymond Hettinger in bpo-34160.)

  • フラグ 'r' で開いた dbm.dumb データベースは読み取り専用になりました。 dbm.dumb.open() は 'r' と 'w' の場合、データベースが存在しなくても作成しなくなりました。 (Contributed by Serhiy Storchaka in bpo-32749.)

  • XMLParser のサブクラスに定義した doctype() は呼ばれなくなり、DeprecationWarning ではなく RuntimeWarning を出します。 XML の doctype 宣言を処理するには、ターゲットに doctype() を定義してください。 (Contributed by Serhiy Storchaka in bpo-29209.)

  • 独自のメタクラスが type.__new__ に渡す名前空間に __classcell__ エントリーを含めない場合、RuntimeError が発生するようになりました。 Python 3.6〜3.7 では DeprecationWarning でした。 (Contributed by Serhiy Storchaka in bpo-23722.)

  • cProfile.Profile クラスをコンテキストマネージャーとして使えるようになりました。 (Contributed by Scott Sanderson in bpo-29235.)

  • shutil.copyfile()、shutil.copy()、shutil.copy2()、shutil.copytree()、shutil.move() がプラットフォーム固有の「高速コピー」システムコールを使うようになりました (プラットフォーム依存の効率的なコピー操作 を参照)。

  • Windows の shutil.copyfile() のデフォルトのバッファサイズが 16 KiB から 1 MiB に変わりました。

  • PyGC_Head 構造体が全面的に変更されました。 そのメンバーに触れるコードはすべて書き直す必要があります (bpo-33597 を参照)。

  • PyInterpreterState 構造体は「内部」ヘッダーファイル (具体的には Include/internal/pycore_pystate.h) に移されました。 不透明な PyInterpreterState は、引き続き公開 API (および安定 ABI) の一部として利用できます。 どのフィールドも公開ではないことは文書に明記されているため、使われていないことを期待しています。 ただし、これらの非公開フィールドに依存し、代替手段がない場合は BPO の issue を作成してください。 公開 API へのアクセサー関数の追加なども含め、移行を支援します (bpo-35886 を参照)。

  • mmap.flush() はすべてのプラットフォームで、成功時に None を返し、エラー時に例外を送出するようになりました。 以前はプラットフォーム依存で、Windows では成功時に非ゼロ、エラー時にゼロを返していました。 Unix では成功時にゼロを返し、エラー時に例外を送出していました。 (Contributed by Berker Peksag in bpo-2122.)

  • xml.dom.minidom と xml.sax モジュールは、デフォルトでは外部実体を処理しなくなりました。 (Contributed by Christian Heimes in bpo-17239.)

  • 読み取り専用の dbm データベース (dbm.dumb、dbm.gnu、dbm.ndbm) からキーを削除すると、KeyError ではなく error (dbm.dumb.error、dbm.gnu.error、dbm.ndbm.error) を送出します。 (Contributed by Xiang Zhang in bpo-33106.)

  • リテラルの AST が簡素化され、すべての定数が ast.Constant インスタンスで表されるようになりました。 古い Num、Str、Bytes、NameConstant、Ellipsis クラスをインスタンス化すると Constant のインスタンスを返します。 (Contributed by Serhiy Storchaka in bpo-32892.)

  • Windows の expanduser() は環境変数 USERPROFILE を優先し、通常のユーザーアカウントでは通常設定されない HOME を使わなくなりました。 (Contributed by Anthony Sottile in bpo-36264.)

  • asyncio.CancelledError 例外は Exception ではなく BaseException を継承し、concurrent.futures.CancelledError を継承しなくなりました。 (Contributed by Yury Selivanov in bpo-32528.)

  • asyncio.wait_for() 関数は、asyncio.Task インスタンスを使う場合、キャンセルが完了するまで正しく待つようになりました。 以前は timeout に達するとキャンセルして直ちに戻っていました。 (Contributed by Elvis Pranskevichus in bpo-32751.)

  • asyncio.BaseTransport.get_extra_info() は、name パラメータに 'socket' を渡すと、安全に使えるソケットオブジェクトを返すようになりました。 (Contributed by Yury Selivanov in bpo-37027.)

  • asyncio.BufferedProtocol が安定 API になりました。

  • Windows で、拡張モジュールと ctypes で読み込んだ DLL の依存 DLL が、より安全に解決されるようになりました。 読み込み時の依存ライブラリの検索対象は、システムパス、DLL または PYD ファイルのあるディレクトリ、add_dll_directory() で追加したディレクトリだけです。 特に PATH と現在の作業ディレクトリは使われなくなり、これらを変更しても通常の DLL 解決に影響しません。 この仕組みに依存するアプリケーションは add_dll_directory() の有無を確認し、あればライブラリを読み込む間、DLL のディレクトリを追加してください。 Windows 7 では Windows Update KB2533623 がインストール済みであることを確認する必要があります (インストーラーでも確認します)。 (Contributed by Steve Dower in bpo-36085.)

  • pgen が純粋な Python の実装に置き換えられたため、関連するヘッダーファイルと関数が削除されました。 (Contributed by Pablo Galindo in bpo-36623.)

  • types.CodeType のコンストラクタの第 2 パラメータとして posonlyargcount が追加され、PEP 570 の位置専用引数をサポートしました。 第 1 パラメータの argcount は、位置専用引数を含む位置引数の合計数を表します。 types.CodeType の新しい replace() メソッドを使うと、将来の変更に強いコードにできます。

  • hmac.new() の digestmod パラメータは、デフォルトで MD5 ダイジェストを使わなくなりました。

C API の変更

  • PyCompilerFlags に cf_feature_version フィールドが追加されました。 PY_MINOR_VERSION で初期化する必要があります。 デフォルトでは無視され、cf_flags に PyCF_ONLY_AST フラグが設定されている場合に限って使われます。 (Contributed by Guido van Rossum in bpo-35766.)

  • PyEval_ReInitThreads() が C API から削除されました。 明示的に呼ぶべき関数ではありません。 代わりに PyOS_AfterFork_Child() を使ってください。 (Contributed by Victor Stinner in bpo-36728.)

  • Unix では Android と Cygwin を除き、C 拡張は libpython にリンクしなくなりました。 Python を埋め込む場合、libpython は RTLD_LOCAL ではなく RTLD_GLOBAL で読み込む必要があります。 以前から RTLD_LOCAL では、Modules/Setup の *shared* 節でビルドした標準ライブラリの拡張など、libpython にリンクしていない C 拡張は読み込めませんでした。 (Contributed by Victor Stinner in bpo-21536.)

  • 値の解析や構築 (PyArg_ParseTuple()、Py_BuildValue()、PyObject_CallFunction() など) で、PY_SSIZE_T_CLEAN を定義せずに # 付きの書式を使うと DeprecationWarning が発生するようになりました。 この使い方は 3.10 または 4.0 で削除されます。 詳しくは 引数の解釈と値の構築 を参照してください。 (Contributed by Inada Naoki in bpo-36381.)

  • PyType_FromSpec() などで作成したヒープ型のインスタンスは、その型オブジェクトへの参照を保持します。 型オブジェクトの参照カウントを増やす処理は PyType_GenericAlloc() から、より低水準の PyObject_Init() と PyObject_INIT に移されました。 これにより PyType_FromSpec() で作成した型が、マネージコード内のほかのクラスと同様に動作します。

    静的に割り当てられた型 は影響を受けません。

    ほとんどの場合、副作用はないはずです。 ただし、インスタンスの割り当て後に手動で参照カウントを増やす型 (バグを回避するためにそうしていた場合など) は、解放されなくなる可能性があります。 避けるには、インスタンスの解放時に型オブジェクトに対して Py_DECREF を呼ぶ必要があります。

    これらの型を 3.8 に正しく移行するには、次の変更を行ってください:

    • インスタンス割り当て後に型オブジェクトに対して Py_INCREF を呼んでいれば削除してください。 PyObject_New、PyObject_NewVar、PyObject_GC_New()、PyObject_GC_NewVar()、または PyObject_Init() や PyObject_INIT を使う独自のアロケータを呼んだ後などが該当します。

      例:

      static foo_struct *
      foo_new(PyObject *type) {
          foo_struct *foo = PyObject_GC_New(foo_struct, (PyTypeObject *) type);
          if (foo == NULL)
              return NULL;
      #if PY_VERSION_HEX < 0x03080000
          // Workaround for Python issue 35810; no longer necessary in Python 3.8
          PY_INCREF(type)
      #endif
          return foo;
      }
      
    • ヒープ型の独自の tp_dealloc 関数が、すべて型の参照カウントを減らすことを確認してください。

      例:

      static void
      foo_dealloc(foo_struct *instance) {
          PyObject *type = Py_TYPE(instance);
          PyObject_GC_Del(instance);
      #if PY_VERSION_HEX >= 0x03080000
          // Python 3.8 より前には不要だった (Python issue 35810)
          Py_DECREF(type);
      #endif
      }
      

    (Eddie Elizondo による貢献、bpo-35810。)

  • Py_DEPRECATED() マクロが MSVC 向けに実装されました。 このマクロはシンボル名の前に置く必要があります。

    例:

    Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void);
    

    (Zackery Spytz による貢献、bpo-33407。)

  • インタープリタは、拡張型の機能リリース間でのバイナリ互換性をサポートしているかのように振る舞うことをやめました。 サードパーティーの拡張モジュールが公開する PyTypeObject は、tp_finalize を含め、現在の Python バージョンで期待されるすべてのスロットを持つ必要があります。 tp_finalize を読む前に Py_TPFLAGS_HAVE_FINALIZE を確認しなくなりました。

    (Antoine Pitrou による貢献、bpo-32388。)

  • PyNode_AddChild() と PyParser_AddToken() 関数に、int 型の引数 end_lineno と end_col_offset が追加されました。

  • MinGW ツールが python38.dll に直接リンクするための libpython38.a は、通常の Windows 配布物に含まれなくなりました。 必要な場合は、MinGW binutils パッケージの gendef と dlltool で生成できます:

    gendef - python38.dll > tmp.def
    dlltool --dllname python38.dll --def tmp.def --output-lib libpython38.a
    

    インストールされた pythonXY.dll の場所は、インストールオプションと Windows のバージョンや言語によって異なります。 詳しくは Windows で Python を使う を参照してください。 生成したライブラリは pythonXY.lib と同じディレクトリに置いてください。 通常は Python のインストール先の libs ディレクトリです。

    (Steve Dower による貢献、bpo-37351。)

CPython バイトコードの変更

  • ブロックのスタックを巻き戻すロジックをコンパイラに移すことで、インタープリタのループが簡素化されました。 コンパイラは break、continue、return に対して、値スタックを調整して後始末のコードを呼ぶ命令を明示的に出力します。

    BREAK_LOOP、CONTINUE_LOOP、SETUP_LOOP、SETUP_EXCEPT オペコードが削除されました。 ROT_FOUR、BEGIN_FINALLY、CALL_FINALLY、POP_FINALLY が追加されました。 END_FINALLY と WITH_CLEANUP_START の動作が変わりました。

    (Mark Shannon、Antoine Pitrou、Serhiy Storchaka による貢献、bpo-17611。)

  • async for ループで次の要素を待つ際に発生する例外を処理する、新しい END_ASYNC_FOR オペコードが追加されました。 (Contributed by Serhiy Storchaka in bpo-33041.)

  • MAP_ADD は、スタックの第 1 要素を値、第 2 要素をキーとみなすようになりました。 PEP 572 の提案どおり、辞書内包表記でキーを常に値より先に評価するための変更です。 (Contributed by Jörn Heissler in bpo-35224.)

デモとツール

変数にアクセスする各種の方法を計測するベンチマークスクリプト Tools/scripts/var_access_benchmark.py が追加されました。 (Contributed by Raymond Hettinger in bpo-35884.)

Python 3.3 以降の性能改善の概要です:

Python version                       3.3     3.4     3.5     3.6     3.7     3.8
--------------                       ---     ---     ---     ---     ---     ---

Variable and attribute read access:
    read_local                       4.0     7.1     7.1     5.4     5.1     3.9
    read_nonlocal                    5.3     7.1     8.1     5.8     5.4     4.4
    read_global                     13.3    15.5    19.0    14.3    13.6     7.6
    read_builtin                    20.0    21.1    21.6    18.5    19.0     7.5
    read_classvar_from_class        20.5    25.6    26.5    20.7    19.5    18.4
    read_classvar_from_instance     18.5    22.8    23.5    18.8    17.1    16.4
    read_instancevar                26.8    32.4    33.1    28.0    26.3    25.4
    read_instancevar_slots          23.7    27.8    31.3    20.8    20.8    20.2
    read_namedtuple                 68.5    73.8    57.5    45.0    46.8    18.4
    read_boundmethod                29.8    37.6    37.9    29.6    26.9    27.7

Variable and attribute write access:
    write_local                      4.6     8.7     9.3     5.5     5.3     4.3
    write_nonlocal                   7.3    10.5    11.1     5.6     5.5     4.7
    write_global                    15.9    19.7    21.2    18.0    18.0    15.8
    write_classvar                  81.9    92.9    96.0   104.6   102.1    39.2
    write_instancevar               36.4    44.6    45.8    40.0    38.9    35.5
    write_instancevar_slots         28.7    35.6    36.1    27.3    26.6    25.7

Data structure read access:
    read_list                       19.2    24.2    24.5    20.8    20.8    19.0
    read_deque                      19.9    24.7    25.5    20.2    20.6    19.8
    read_dict                       19.7    24.3    25.7    22.3    23.0    21.0
    read_strdict                    17.9    22.6    24.3    19.5    21.2    18.9

Data structure write access:
    write_list                      21.2    27.1    28.5    22.5    21.6    20.0
    write_deque                     23.8    28.7    30.1    22.7    21.8    23.5
    write_dict                      25.9    31.4    33.3    29.3    29.2    24.7
    write_strdict                   22.9    28.4    29.9    27.5    25.2    23.1

Stack (or queue) operations:
    list_append_pop                144.2    93.4   112.7    75.4    74.2    50.8
    deque_append_pop                30.4    43.5    57.0    49.4    49.2    42.5
    deque_append_popleft            30.8    43.7    57.3    49.7    49.7    42.8

Timing loop:
    loop_overhead                    0.3     0.5     0.6     0.4     0.3     0.3

ベンチマークは Intel® Core™ i7-4960HQ プロセッサー で、python.org の macOS 64 ビットビルドを使って計測しました。 スクリプトは時間をナノ秒単位で表示します。

Python3.8.1 での重要な変更点

セキュリティ上の重大な懸念により、asyncio.loop.create_datagram_endpoint() での reuse_address 引数は無効になりました。これはソケットオプション SO_REUSEADDR のUDP における挙動が原因です。詳しくは、loop.create_datagram_endpoint() のドキュメントを参照してください。(Kyle Stanley, Antoine Pitrou, Yury Selivanov による貢献 bpo-37228)

Python3.8.2 での重要な変更点

shutil.copytree() の ignore コールバックのリグレッションが修正されました。 引数の型は再び str と List[str] になりました。 (Contributed by Manuel Barkhau and Giampaolo Rodola in gh-83571.)

Python 3.8.3 の注目すべき変更

__future__ モジュールの future フラグの定数値が、コンパイラフラグとの衝突を避けるために更新されました。 以前は PyCF_ALLOW_TOP_LEVEL_AWAIT が CO_FUTURE_DIVISION と衝突していました。 (Contributed by Batuhan Taskaya in gh-83743)

Python3.8.8 での重要な変更点

以前の Python では urllib.parse.parse_qs() と urllib.parse.parse_qsl() のクエリパラメータの区切りに ; と & の両方を使えました。 セキュリティ上の懸念と、新しい W3C 勧告への準拠のため、区切りは 1 種類のみとなり、デフォルトは & に変更されました。 これらの関数を内部で使う cgi.parse() と cgi.parse_multipart() も影響を受けます。 詳しくは各関数のドキュメントを参照してください。 (Contributed by Adam Goldschmidt, Senthil Kumaran and Ken Jin in bpo-42967.)

Python 3.8.9 の注目すべき変更

セキュリティ修正により、ftplib.FTP はパッシブデータチャネルを確立するとき、リモートサーバーから送られた IPv4 アドレスを信頼しなくなりました。 代わりに FTP サーバーの IP アドレスを再利用します。 従来の動作が必要な特殊なコードでは、FTP インスタンスの trust_server_pasv_ipv4_address 属性を True に設定してください (gh-87451 を参照)。

Python 3.8.10 の注目すべき変更

macOS 11.0 (Big Sur) と Appleシリコンの Mac のサポート

3.8.10 から、macOS 11 (Big Sur) と Apple Silicon Mac (ARM64 アーキテクチャ) でのビルドと実行をサポートしました。 新しいユニバーサルビルド universal2 により、一組の実行ファイルで ARM64 と Intel 64 の両方をネイティブにサポートできます。 ただし、新しい macOS 向けのバイナリをビルドし、実行時に不足する機能を確認することで古い macOS でも正しく動作させる「弱いリンク」のサポートは、Python 3.9 からのこのバックポートには含まれません。 複数の macOS バージョンに対応するには、引き続き対象のうち最も古いバージョン向けに、そのバージョン上でビルドしてください。

(Ronald Oussoren と Lawrence D'Anna による元の貢献、gh-85272。FX Coudert と Eli Rykoff による修正を含み、Maxime Bélanger と Ned Deily が 3.8 にバックポートしました。)

Python 3.8.10 の注目すべき変更

urllib.parse

URL の一部に改行やタブ文字が含まれると、特定の攻撃が可能になります。 RFC 3986 を更新する WHATWG 仕様に従い、urllib.parse のパーサーは ASCII の改行 \n、\r とタブ \t を URL から取り除き、このような攻撃を防ぐようになりました。 削除対象の文字は新しいモジュール変数 urllib.parse._UNSAFE_URL_BYTES_TO_REMOVE で制御します (bpo-43882 を参照)。

Python 3.8.12 の注目すべき変更

Python API の変更

Python 3.8.12 から ipaddress は、IPv4 アドレス文字列の先頭のゼロを一切受け付けなくなりました。 先頭のゼロは曖昧で、一部のライブラリは 8 進表記と解釈します。 例えば従来の socket.inet_aton() は先頭のゼロを 8 進表記として扱います。 新しい inet_pton() の glibc 実装は、先頭のゼロを一切受け付けません。

(Christian Heimes による元の貢献、bpo-36384。Achraf Merzouki が 3.8 にバックポートしました。)

3.8.14 の注目すべきセキュリティ機能

2 (2 進数)、4、8 (8 進数)、16 (16 進数)、32 以外の基数、例えば 10 (10 進数) で int と str を相互変換する際、文字列表記の桁数が上限を超えると ValueError を送出するようになりました。 アルゴリズムの計算量を悪用したサービス拒否攻撃を防ぐためで、CVE 2020-10735 の緩和策です。 この上限は、環境変数、コマンドラインフラグ、sys の API で設定または無効化できます。 整数の文字列変換の長さ制限 のドキュメントを参照してください。 デフォルトの上限は文字列表記で 4300 桁です。

3.8.17 の注目すべき変更

tarfile

  • tarfile の展開メソッドと shutil.unpack_archive() に filter 引数が追加されました。 これにより、展開先ディレクトリの外にファイルを作成するなど、予想外の動作や危険な動作を招く tar の機能を制限できます。 詳しくは 展開フィルター を参照してください。 Python 3.12 では filter 引数を指定せずに使うと DeprecationWarning が表示されます。 Python 3.14 ではデフォルトが 'data' に変わります。 (Petr Viktorin による PEP 706 での貢献。)