What’s New In Python 3.13 ノート

What’s New In Python 3.13 をたどりながら調査。興味のあるものしか読まない。

New Features

A better interactive interpreter

対話型シェルが刷新された:

  • 履歴を保持した複数行編集。

  • help, exit, quit のような REPL 固有のコマンドを関数として呼び出すことなく直接サポート。

  • 色を有効にしたプロンプトとトレースバック。

  • 独立したコマンド履歴を持つ、F1 による対話的なヘルプ閲覧。

  • F2 を使用した履歴閲覧。

  • F3 による「貼り付けモード」。より大きなコード塊の貼り付けが簡単になった。

従来のシェルを使うには環境変数 PYTHON_BASIC_REPL を 1 にあらかじめ定義しておく。

Improved error messages

端末でトレースバックを表示する際に、色を使用するようになった。

標準ライブラリーモジュールと同じ名前のスクリプトを書いてしまうと、より親切なエラーメッセージが現れるようになった。同様に、スクリプトがインポートしようとするサードパーティー製モジュールと同じ名前を持ち、その結果エラーが発生する場合にも、より親切なエラーメッセージが現れる。

誤ったキーワード引数が関数に渡された場合、エラーメッセージが正しいキーワード引数を持ちかけるようになった。

Defined mutation semantics for locals()

関数 locals() が返すオブジェクトが、現在割り当てられているローカル変数の独立したスナップショットであることが保証される(実装によっては値を書き換えることが可能だった)。

Other Language Changes

コンパイラーは docstring の各行から共通する同じ長さの先頭空白を取り除くことにした。これにより .pyc ファイルなどのサイズが約 5% 削減される。

例外構文において、else ブロック内で global 宣言が使用される場合には except ブロック内で global 宣言が許可されるようになった。

ファイル .python_history のパスを環境変数 PYTHON_HISTORY で指定可能になった。

読者ノート

この環境変数の追加は重要だ。Python スタータップスクリプトで履歴ファイルのパスに関して XDG Base Directory 対応をしている場合にはこれを最優先するような修正をする。

組み込み関数 exec() および eval()globals および locals 引数をキーワードとして受け付ける(引数リストが以前と微妙に変化した)。

例外 PythonFinalizationError を追加した。RuntimeError の派生型だ。特に、 subprocess.Popen() などが RuntimeError の代わりに PythonFinalizationError を送出するようになる(既存の例外処理コードを書き換える必要はまずなさそうだ)。

文字列メソッド replace()count 引数はキーワード引数として指定できる(引数リストが以前と微妙に変化した)。

ファイル記述子の引数に真偽値が渡される事例において、多くの関数が警告を発するようになった。従来は:

あまりにも作為的な例
In [1]: import os.path

In [2]: os.path.exists(False)
Out[2]: True

New Modules

使いそうなものはない。

Improved Modules

興味のあるものや遭遇しそうな問題を含むモジュールに絞って記していく。

argparse

メソッド add_argument() および add_parser() に引数 deprecated が追加。

引数やオプションを廃止する前の段階として、これが将来削除されるものであることを使用者に知らせる必要がある。その場合に用いる。引数やオプションを deprecated=True で定義し、その引数やオプションがコマンドラインで使用されると警告が sys.stderr に出力される。

array

メソッド clear() が実装された。これにより array.array が名実ともに collections.abc.MutableSequence であることになる。

asyncio

as_completed() が非同期反復子でもあり、awaitable の(同期)反復子でもあるオブジェクトを返す。

新方式である非同期処理の例
# tasks: Iterable[Task]
async for task in as_completed(tasks):
     result = await task
従来の方式
# tasks: Iterable[Task]
for task in as_completed(tasks):
    result = await task

非同期反復によって返される awaitables には渡された元の TaskFuture オブジェクトが含まれるため、完了した Task と結果を関連付けるのが容易になる。上の例で言えば、仮に tasksSequence ならば``task`` と tasks[0] を比較することは正当だ。

通常の反復子として用いる従来式の場合、各反復では結果を返す新しい coroutine を生成するか、次に完了した awaitable の例外を送出する。


メソッド Queue.shutdown() が追加。それに伴い例外 QueueShutDown が追加。キューをシャットダウンし、get()put() でこの例外が送出する。

concurrent.futures

仕事スレッドとプロセスの既定個数が os.cpu_count() ではなく os.process_cpu_count() を使って決定されるように変更。

configparser

ConfigParser は無名区画を扱えるようになった。最上位のキーと値の対を使用できる。新引数 allow_unnamed_section で作動させる。

無名区画にあるオプションを読み込む例
from configparser import ConfigParser, UNNAMED_SECTION

unnamed = configparser.ConfigParser(allow_unnamed_section=True)
unnamed.read_string("...")
unnamed.get(UNNAMED_SECTION, 'option')

doctest

出力が着色する。環境変数 PYTHON_COLORS と正規の環境変数である NO_COLOR および FORCE_COLOR で制御可能。Python インタプリターでのみ色出力を制御するなら PYTHON_COLORS を使え。この変数を NO_COLOR よりも優先し、NO_COLORFORCE_COLOR よりも優先する。

DocTestRunner のメソッド run() にスキップしたテストの数を勘定する動作が追加。それに伴い属性 skips が追加。さらに TestResultsskipped が追加。

fractions

Fraction オブジェクトに対する f-string 書式仕様の拡充。

読者ノート

Python 3.12 以前だと f-string や format() で次の指定が効かない場合があった:

  • fill

  • align

  • sign

  • width

  • grouping_option

glob

関数 translate() を追加。シェル様式のワイルドカードを含むパス指定を正規表現に変換する。

Todo

インストールしたら関数インターフェイスを確認する。

itertools

関数 zip() における引数 strict と同様のものが関数 batched() に追加。最終部分が指定サイズより短い場合に``ValueError`` が送出する。

math

関数 fma(x, y, z) が追加。演算 x * y + z を、一回の丸め誤差を含む浮動小数点数で返す。中間的な精度の低下を避けることができる。

multiprocessing

前述のとおり、仕事スレッドとプロセスの既定数は os.cpu_count() ではなく os.process_cpu_count() を使って決定される。次の節も見ろ。

os

関数 process_cpu_count() が追加。現在のプロセスの呼び出しスレッドが使用可能である論理 CPU コア数を返す。

関数 cpu_count() および process_cpu_count() は環境変数 PYTHON_CPU_COUNT またはコマンドラインオプション -X cpu_count によってオーバーライド可能となった。これが便利であるのは、アプリケーションコードやコンテナー自体を変更することなく、コンテナーシステムの CPU 資源を制限する必要がある使用者だ。

pathlib

例外 UnsupportedOperation が追加。従来実装されていないパス操作により送出されていた NotImplementedError に代わるものだ。


file:/// から始まるパス文字列から Path オブジェクトを作成するクラスメソッド Path.from_uri() が追加した。


PurePath.full_match() 追加。再帰ワイルドカード ** を含むシェル型ワイルドカードでパスを合致する。

>>> PurePath('/a/b/c.py').full_match('/a/**')
True
>>> PurePath('/a/b/c.py').full_match('**/*.py')
True

メソッド Path.glob() および Path.rglob() にキーワード限定引数 recurse_symlinks が追加。この値を True に指定すると ** 展開を除けばシンボリックリンクにつねに従うようになる。

これらのメソッドに ** で終わるパターンが指定された場合に、ディレクトリーだけでなくファイルも返すように改善した。


キーワード限定引数 follow_symlinks をクラス Path の次のメソッドに追加:

  • is_file()

  • is_dir()

  • owner()

  • group()

これらのメソッドは通常シンボリックをたどる。

pdb

組み込み関数 breakpoint() と関数 pdb.set_trace() が実行されるコードの次の行ではなく、即座にデバッガーに入るように変更。この変更は breakpoint() がコンテキストの最後に配置されたときに、コンテキスト外でデバッガーが break するのを防止する。


新コマンド exceptions 追加。pm() での死後デバッグ中に連鎖した例外間を移動する機能だ。

読者ノート

運用としては、何か例外が送出されたときに import pdb; pdb.pm() を実行して Pdb セッションを開始する。そこでコマンド exceptions N で例外間を渡り歩けるというものだ。引数なしで実行すれば例外一覧を示す。


接頭辞が pdb コマンドである式や文が正しく識別され、実行されるように改善。つまり、 Python コード中に例えば jump, step, up などという名前のオブジェクトが含まれていて、こういうものを参照するときに動作するようになったと述べている。

queue

前述のとおり、キューの終了を管理するメソッド Queue.shutdown() と例外 ShutDown が追加。

random

CLI が搭載された。適当に alias を定義しておくと使いでが良いと考えられる。

Examples of python -m random
$ python -m random 6
6
$ python -m random --integer 6
3
$ python -m random --integer 6
5
$ python -m random 1.8
1.7080016272295635
$ python -m random --float 1.8
1.5666339105010318
$ python -m random --float 6
3.1942323316565915

オプション --choice と標本を指定する方式もある。

re

わかりやすさのために re.errorPatternError に改名した。従来の名前も後方互換性のために利用可能だ。

typing

Todo

このモジュールはいつものように後回し。

unicodedata

Unicode データベースがバージョン 15.1.0 に更新した。

読者ノート

このバージョンにはおもしろい文字が何かある気配を感じる。

Optimizations

ここは一般プログラマーには重要ではないかもしれない。ほとんどチェックしていない。

Removed Modules And APIs

2to3

プログラム 2to3 とモジュール lib2to3 が削除。

builtins

連鎖した @classmethod の維持を削除。この手法は @property のような他の記述子をラップするのにもはや使えない。

locale

関数 resetlocale() が削除。 代わりに setlocale(LC_ALL, "") としろ。

読者ノート

Ubuntu の do-release-upgrade にまさにこの処理が存在するので控えておく。

pathlib

Path オブジェクトを context manager として使用する謎機能が存在したが、それが削除。

Path オブジェクトを context manager として用いたときの挙動例
In [1]: from pathlib import Path

In [2]: with Path('/tmp'):
   ...:     pass
   ...:
<ipython-input-3-a0cb68af6698>:1: DeprecationWarning: pathlib.Path.__enter__() is deprecated and scheduled for removal in Python 3.13; Path objects as a context manager is a no-op
  with Path('/tmp'):

unittest

以下の関数が削除:

  • findTestCases()

  • makeSuite(): これを使っていた記憶がある

  • getTestCaseNames()

New Deprecations

古いやり方をいつまで経っても採用し続けないように、一通りチェックする。文書化されていない機能や特定のプラットフォーム固有の挙動に関するものがほとんどだ。

Porting to Python 3.13

本節以降、個人的には対応項目なし。

関数 getpass.getuser() で使用者名の取得に失敗した場合、送出する例外が OSError になった。以前はプラットフォームやパスワードデータベースの条件により異なる型の例外が送出していた。

前述のように、クラス pathlib.Path のメソッド glob() および rglob()** で終わるパターンが指定された場合、ディレクトリーのみではなくファイルとディレクトリーの両方を返すようになった。末尾に / を追加すると以前の動作が維持され、ディレクトリーのみに合致する。


興味がある項目は以上?