What’s New In Python 3.14 ノート¶
What’s New In Python 3.14 をたどりながら調査。興味のあるものしか読まない。
New features¶
PEP 750: Template string literals¶
定義方法や書式・変換指定は従来の f-string と同様だが、この形式で定義した文字列は実は文字列ではなく string.templatelib.TemplateString オブジェクトになる。
コードを見るほうが理解が早い:
name = "World"
t = t"Hello {name}"
assert t.strings[0] == "Hello "
assert t.interpolations[0].value == "World"
assert t.interpolations[0].expression == "name"
contents = list(t)
assert len(contents) == 2
assert contents[0] == "Hello "
assert contents[1].value == "World"
assert contents[1].expression == "name"
ここまで試して気付いたが、オブジェクトの最終形を普通の文字列として一発で出力する方法が用意されていない。それがこの新型クラスの狙いでもあるようだ。ユーザー入力を検証する処理と文字列を組み立てる処理が一体化したものをプログラマーが定義するのだ。
Improved error messages¶
インタプリターからの SyntaxError メッセージがわかりやすくなった。
インタプリターが Python キーワードに酷似した単語を検出すると、エラーメッセージ内で正しいキーワードを提案する。
else節に続くelif文に対しては専用のエラーメッセージが表示される。三項演算子の
else後の条件式に文が渡されたり、ifの前にpass,break,continueのいずれかが渡されたりした場合、式が必要な箇所をエラーメッセージ中で強調表示する。不正に閉じられた文字列が検出された場合、エラーメッセージがその文字列が意図的に文字列の部分であるかもしれないことを示唆する。
文字列の接頭辞が複数付いていてそれらに互換性がない場合のエラーメッセージ
次のような
asに関係するエラーメッセージ:import ... as ...from ... import ... as ...except ... as ...case ... as ...
ハッシュ化できない型のオブジェクトを
dictやsetに追加しようとした際のエラーメッセージ句
async withが適切な場所でwithを指定した場合、またはその反対の指定を行った場合のエラーメッセージ
Asyncio introspection capabilities¶
モジュール asyncio に CLI が搭載された。コマンドは ps と pstree の二つある。どちらもプロセスを ID の値で指定して、実行中の asyncio タスクに関する情報を標準出力に示すものだ。
この機能は長時間実行される、または停止した非同期プログラムの調査に有用だ。
タスクの情報は次で構成される:
タスクの名前
タスクのコルーチンスタック
タスクを待機しているタスクの集合
コマンド ps と pstree はこの情報を表形式と、非同期呼び出し関係に関する木形式でそれぞれ出力する。
引数はプロセス ID 一個のみだ。オプションは -h, --help しかない。
Todo
可能ならば、長時間実行の非同期プログラムを走らせて、コマンド
python -m asyncio pstree の実際の出力をここに記したい。
Other language changes¶
複素数の値に対して inf と nan を複合させた演算結果が C++11 におけるそれと適合するようになった。
Python の最適化オプション
-O絡みのSyntaxError検出精度が上がった。
Built-ins¶
メソッド
fromhex()の機能向上。クラスbytesとbytearrayのこれらのメソッドは、引数として ASCIIbytes値(実質的には ASCII 文字列値)やbytes風オブジェクトを受け容れる。クラスメソッド
from_number()の追加。クラスfloatとcomplexに対してこのメソッドが追加した。与える引数は実数でなければならない。コンストラクターのように扱いたい。文字列書式における浮動小数点表示形式の端数部分で、千の位区切り記号として
_と,を用いることが許される。例えばformat(123456.123456, '_._f')がエラーでなくなった。関数
int()は__trunc__()を呼び出さない。整数に変換したいクラスは次のいずれかを実装することが不可欠になった:__int__()__index__()
関数
map()にキーワード専用引数strictが追加。関数zip()のそれと同じ仕様だ。クラス
memoryviewが generic になった。つまり、型注釈を付けるときに何の型の器なのかを示せるようになった。ブール値の文脈で
NotImplementedを使用するとTypeErrorが発生するようになった。>>> if NotImplemented: ... pass ... Traceback (most recent call last): File "<python-input-18>", line 1, in <module> if NotImplemented: ^^^^^^^^^^^^^^ TypeError: NotImplemented should not be used in a boolean context
三引数
pow()は必要に応じて__rpow__()を試みるようになった。superオブジェクトはコピー可能かつ pickle 可能になった。
Command line and environment¶
コマンド python -c が実行前にコード引数のインデントを自動的に解除するようになった(コード文字列の各行から共通の先頭空白が取り除かれ、実行される)。
PEP 758: Allow except and except* expressions without brackets¶
except / except* 式のどちらにおいても、as 句が使用されていないような場合に、例外型を列挙するときに欠かせなかった囲む括弧が省略可能になった(もちろん囲んでもかまわない)。PEP 758 から例を引用する:
try:
...
except ExceptionA, ExceptionB, ExceptionC:
...
捕捉する例外に名前を付ける場合には括弧が必須であるのは変わらない理由は、試しに上のコードに括弧を加えぬままに as e を付けて、じっと眺めていればわかる。
PEP 765: Control flow in finally blocks¶
例外処理の finally 節が次の文を含むとき、それは SyntaxWarning を生じるようになった:
breakcontinuereturn
というのは、そのようなコードを書いて実際にこのような制御文が実行される場合、例外が再送出されない、つまり、例外が失われるという言語仕様があるのだ。
>>> def test_control_flow_in_finally_block():
... try:
... raise ValueError
... finally:
... return 1
... return 0
...
<python-input-0>:5: SyntaxWarning: 'return' in a 'finally' block
>>> test_control_flow_in_finally_block()
1
Default interactive shell¶
対話型シェルで Python 構文の強調表示がなされるようになった。オフにしたい場合には環境変数 PYTHON_BASIC_REPL を定義しろ。
Note
この環境変数を定義しなくても、Python はよそで用いられる次の環境変数を考慮して強調表示をやめる:
TERMNO_COLORFORCE_COLOR
さらに対話型シェルは import 文における自動補完を応援するようになった。例:
import coまでタイプして Tab を押すと、名前の先頭がcoから始まるモジュール一覧が候補として示される。from concurrent import iまでタイプして Tab を押すと、標準モジュールconcurrentのサブモジュールであって、名前の先頭がiで始まるものの一覧が候補として示される。
New modules¶
annotationlib次の注釈用の道具を含むモジュール:
関数
get_annotations()書式設定に用いる列挙型
クラス
ForwardRef関数
__annotate__を呼び出すための補助関数
compression圧縮関連モジュール用のパッケージ。Zstandard 圧縮形式を使用することが可能になる新モジュールを含む。
次の既存&新圧縮アルゴリズム搭載標準モジュール群を含む:
bz2gziplzmazlibcompression.zstd
concurrent.interpreters標準ライブラリーにあるインタプリター複数を使用することが可能となるモジュール。
string.templatelib先述の t-strings を使用可能にするモジュール。
Improved modules¶
興味のあるものや遭遇しそうな問題を含むモジュールに絞って記していく。
argparse¶
Click を使う場合は流し読みでいい。
ArgParserのプログラム名の既定値を、インタプリターが__main__モジュールコードを検索するように指示された方法に従って決まるようになった。つまり、コマンドラインで--help出力で示されるプログラム名称のことだが、次のように決定する:引数としてファイルが渡された場合は
basename sys.argv[0]相当引数としてディレクトリーまたは zip ファイルが渡された場合は
sys.argv[0]python -mで起動された場合、モジュールまたはパッケージの名前
ユーザーによる誤入力時に引数選択肢などの候補表示が可能になった。それには
ArgumentParserコンストラクターでオプション引数suggest_on_error=Trueを指定する。オブジェクト生成してからparse()するまでの頃合いならば、オブジェクトの属性値を直接Trueに代入することによっても、期待どおり動作する。ヘルプテキストの色強調表示がなされるようになった。これを従来どおりのオフにするには
ArgumentParserコンストラクターでcolor=Falseとすればいい。 先述の環境変数 を設定することでも切り替え可能だ。
asyncio¶
関数とメソッドで三種存在する
create_task()が任意のキーワード引数リストを受理するようになった。キーワード引数はすべて
Taskまたは自作ファクトリーに転送される。キーワード引数
nameおよびcontextに対する特別扱いは失われた。
関数
capture_call_graph()とprint_call_graph()が設けられた。呼び出し側がTaskまたはFutureオブジェクトを指定すると、その非同期呼び出しグラフオブジェクトが戻るか、当該グラフオブジェクトをファイルなどに出力する。
calendar¶
コマンド python -m calendar を実行したときに、今日が強調表示されるようになった。この挙動は環境変数 PYTHON_COLORS および 先述の環境変数 により変更することが可能だ。
configparser¶
読み取り不能設定ファイルへの書き込みを行わなくなった。
区切り文字を含むキーやセクションヘッダーパターンで始まるキーへの
write()を試みると例外InvalidWriteErrorが送出するようになった。
datetime¶
次のクラスにクラスメソッド strptime() が加わった:
datetime.datedatetime.time
datetime.time.strptime()¶>>> from datetime import import time
>>> time.strptime("2 時 50 分", "%H 時 %M 分")
datetime.time(2, 50)
decimal¶
クラスメソッド from_number() が加わった。戻り値の型を除けば、このメソッドは上述の float や complex のそれと同様に動作する。
算術演算環境として IEEEContext 型を新たに使用可能になった。
IEEEContext¶>>> 1 / 7
0.14285714285714285
>>> from decimal import Decimal, IEEEContext, localcontext
>>> print(Decimal('1.0') / Decimal('7.0'))
0.1428571428571428571428571429
>>> decimal.IEEEContext(64)
Context(prec=16, rounding=ROUND_HALF_EVEN, Emin=-383, Emax=384, capitals=1, clamp=1, flags=[], traps=[])
>>> ctx = _
>>> with localcontext(ctx):
... print(Decimal('1.0') / Decimal('7.0'))
...
0.1428571428571429
fractions¶
メソッド as_integer_ratio() を持つオブジェクトならば、何であってもそれから
Fraction オブジェクトを生成可能になった。
クラス Fraction にクラスメソッド from_number() が加わった。意味は先述の同名メソッドと同様にはたらくが、引数は次のいずれかを満たす必要がある:
値の型が
numbers.Integral,numbers.Rational,float,decimal.Decimalのいずれかである。オブジェクトがメソッド
as_integer_ratio()を有する。
functools¶
関数 reduce() の最初の引数をキーワード引数として渡せるようになった。
reduce()¶>>> from functools import reduce
>>> reduce(lambda x, y: x + y, range(5))
10
>>> reduce(lambda x, y: x + y, range(5), initial=-10)
0
getpass¶
関数 getpass() がキーワードオプション引数 echo_char を備えた。キーボードフィードバックを実現する。タイプするたびにダミー文字を表示し、削除されると消去する。
echo_char parameter¶from getpass import getpass
pin = getpass('Enter PIN: ', echo_char='*')
heapq¶
次の最大ヒープ関数を搭載した:
heapify_max()heappush_max()heappop_max()heapreplace_max()heappushpop_max()
公式文書にある、ストリーミング入力から中央値を求めるアルゴリズムコードは必読。
io¶
ファイルやその他のストリームから読み書きするための汎用プロトコルが追加:
Reader[T]Writer[T]
T は通常 str または bytes となるが、ストリームから読み書き可能である型ならば何でもかまわない。これらのプロトコルは typing.IO 系プロトコルのより簡素な代替型だ。
json¶
CLI が python -m json でいけるようになった。
math¶
このモジュールが示すエラーメッセージ math domain error が状況に応じた、より詳しい説明に改善した。
math からのエラーメッセージの違い¶$ mamba run -n python-3.13 python -c "import math; math.sqrt(-5)"
Traceback (most recent call last):
File "<string>", line 1, in <module>
import math; math.sqrt(-5)
~~~~~~~~~^^^^
ValueError: math domain error
$ mamba run -n python-3.14 python -c "import math; math.sqrt(-5)"
Traceback (most recent call last):
File "<string>", line 1, in <module>
import math; math.sqrt(-5)
~~~~~~~~~^^^^
ValueError: expected a nonnegative input, got -5.0
mimetypes¶
CLI が実装された。下の例のように利用できる:
python -m mimetypes¶$ python -m mimetypes filename.png
type: image/png encoding: None
$ python -m mimetypes --extension text/javascript
.js
operators¶
次の述語関数が加わった:
is_none()is_not_none()
os¶
関数 reload_environ() が加わった。この関数の目的は、プロセス外部で環境変数が変更されたときに、値 os.environ を更新できるようにするものだ。
pathlib¶
クラス Path にファイルとディレクトリーを再帰的に運ぶ次のメソッドが加わった:
copy(),move(): 宛先にファイルまたはディレクトリー木をコピーまたは移動copy_into(),move_into(): 宛先ディレクトリーの中にコピーまたは移動
性質をおおまかに整理しておく:
いずれも戻り値として
Pathオブジェクトを返す宛先が既存ファイルの場合は自身で上書きする
引数
preserve_metadataは既定値がFalseであることに注意したい{copy,move}_into()の宛先ディレクトリーは存在していることが必須
pdb¶
機能がたくさん増えたようだが、理解できるものが少ない。
コマンド
python -m pdb -p PIDを実行するとプロセス ID が PID である Python プロセスに対してデバッガーセッションを開始できるようになった。ユーザーがインラインモードでデバッグセッションを終了しようとすると、確認プロンプトが表示されるようになった。ユーザーが了承すると終了が確定され、関数
sys.exit()が呼び出されることで停止する。インラインブレイクポイントは、スキップパターンがあるような場合にはそれを無視し、呼び出しフレームでプログラムを停止するように変わった。
デバッグセッションでの複数行入力において、行頭にある Tab 文字は空白字四字分の字下げに変換されるように変わった。
デバッグセッションでの複数行入力において、自動字下げが機能するようになった。コードブロックを認識すると、次のどちらかに動作する:
最後の行の字下げを保つ
空白字四字分の字下げを施す
pdb.set_trace_async()が追加されたことで、asyncioコルーチンのデバッグをやりやすくなった。この関数を使用するのはawaitを使用したasync関数内だ。そして、この関数によってデバッガーが起動した場合、await文が使用可能になる。デバッグセッションでソースコードが構文強調表示されるようになった。この機能の構成方法は 上述 の対話型シェルと同様のものが採用可能であるほかに、
pdb.Pdbの引数colorizeでも制御可能だ。
読者ノート
python -m pdb を sudo 実行する場合には Python 環境がシステム本来のものに変わらないように配慮しろ。
re¶
メタキャラクター
zが使用可能になった。意味は大文字版と同じ。メタキャラクター
Bが空文字列に合致するようになった。これにより、このメタキャラクターの意味はいつでもメタキャラクターbと反対になる。
types¶
types.UnionType が typing.Union の別名に変わった。
`types.UnionType のほうが変わった¶>>> import types
>>> types.UnionType
<class 'typing.Union'>
typing¶
上述のように、
types.UnionTypeがtyping.Unionの別名となったことにより、旧式のUnion[int, str]と新式のint | strの両方が同一ランタイム型オブジェクトを生成する。これにより両構文の動作が統一した。ただし、実行時に型を introspect するような処理をするコードがある場合、影響を与える可能性のある動作上の差異は存在する。私は気にしなくていい。別名に対して星分割が効くようになった:
公式より引用¶>>> type Alias = tuple[int, str] >>> type Unpacked = tuple[bool, *Alias] >>> Unpacked.__value__ tuple[bool, typing.Unpack[Alias]]
unicodedata¶
Unicode データベースが Unicode 16.0.0 に更新した。
See also
unittest¶
uuid¶
CLI python -m uuid にオプション --count が使用可能になった。UUID を一度の実行で複数個生成する。これは uuidgen にない機能だ。
Optimizations¶
ここは一般プログラマーには重要ではないかもしれない。ほとんどチェックしていない。
Removed¶
asyncio¶
関数 get_event_loop() はイベントループが存在しない場合に暗黙的にイベントループを生成しないようになった。例外 RuntimeError を送出する。
万が一、古いコードで get_event_loop() を使用するものを持っているようならば、関数 run() を使ったコードに書き換えろ。
itertools¶
関数 copy(), deepcopy() などが取り除かれた。そもそも itertools が作り出す反復子オブジェクトを再帰的に複製することがこれらの関数は一般的にはできなかったらしい。
今度からは tee() を用いるのが良かろう。
Deprecated¶
古いやり方をいつまで経っても採用し続けないように、一通りチェックする。文書化されていない機能や特定のプラットフォーム固有の挙動に関するものがほとんどだ。
codecs.open()ではなく、単にopen()を使え。os.popen()およびos.spawn*系関数を新しいコードで使うな。モジュールsubprocessを使え。
Porting to Python 3.14¶
本節以降、個人的には対応項目なし。
興味がある項目は以上?