Python3.7の新機能
はじめに
Python3.5の新機能、Python3.6の新機能に引き続きPython3.7の新機能に関してもまとめて行きたいと思う。まずは開発ロードマップ(PEP-537)。
- 3.7.0 alpha 1: 2017-09-19 (完了)
- 3.7.0 alpha 2: 2017-10-17 (完了)
- 3.7.0 alpha 3: 2017-12-05 (完了)
- 3.7.0 alpha 4: 2018-01-09 (完了)
- 3.7.0 beta 1: 2018-01-31 (完了)
- 3.7.0 beta 2: 2018-02-26 (完了)
- 3.7.0 beta 3: 2018-03-29 (完了)
- 3.7.0 beta 4: 2018-05-02 (完了)
- 3.7.0 beta 5: 2018-05-30 (完了)
- 3.7.0 candidate 1: 2018-06-12 (完了)
- 3.7.0 final: 2018-06-27 (完了!!)
この記事を書き始めたのが去年(2017年)の11月だからほぼ7ヶ月かかりましたが、ようやく6/27に3.7.0最終版が出ました。What’s New In Python 3.7の内容を追いかけて来ましたがこれが最後の更新になります。
更新履歴
2017.11.23
最初のバージョン。3.7.0a2を元にしています。
2017.12.06
3.7.0a3を元に以下を修正。
- unittestの変更を追記
- 開発者モード(developer mode)を開発モード(development mode)に改称
-
sys.flags.dev_modeに関して追記 - 内包表記とジェネレータ式内でのyield式の非推奨について追記
-
re.splitのサポートパターン追加を追記。
2018.01.10
3.7.0a4を元に以下を修正。
- ハッシュを利用したpycファイルに関して追記
- -X devの記述を更新
- PEP-540 「UTF-8モードの追加」を追記
- contextlibの変更の記述を更新
- 定数畳み込み最適化に関する変更を追記
- PEP-562 「モジュール属性へのアクセスをカスタマイズ」を追記
- subprocessの変更を追記
- importlib.resources を追記
- pdbの記述を追加
- PEP-565 「__main__で非推奨警告を出す」を追記
2018.02.12
3.7.0b1を元に以下を修正。
- PEP-563 「アノテーションの評価を遅らせる」を追記
- PEP-557 「データクラス」を追加
- 「collections.abc モジュールの仮想ベースクラス」を非推奨に追加
-
contextlibdistutilshmacimportliblocalepy_compilesslsystkinterwarningsモジュールの改善点を追記 - 動作変更の欄に PEP-479が発動した件を追記
- 削除されたサポートプラットフォームにFreeBSD 9を追加
2018.03.02
3.7.0b2を元に以下を修正。
- PEP-567 「コンテキスト変数」を追加
- types.TracebackTypeの変更を「その他の言語の変更」に追加
- 「abcモジュールの関数とメソッドをCで再実装」、「
datetime.dateとdatetime.datetimeのコンストラクタを変更」を「最適化」に追加 - sslモジュールの改善点を追記
- deprecated を「非推奨」と訳すようにしました。
2018.07.12
3.7.0を元に以下を修正。
- リリースハイライトを追加
- PEP-560 「
typingモジュールとジェネリック型のコアサポート」を追記 -
asyncio、collections、compileall、datetime、dbm、decimal、enum、functools、gc、idlelib/IDLE、io、ipaddress、itertools、logging、mimetypes、msilib、multiprocessing、pydoc、queue、signal、socket、socketserver、sqlite3、tracemalloc、types、uuid、zipfileモジュールの改善点を追記 - 長くなりすぎたので「ビルドとC APIの変更」、「最適化」、「その他のCPython実装の変更」、「非推奨」、「削除済み」、「Python 3.7へのポーティング」、「ドキュメンテーション」を削除
- 最新版に合わせて項目の順序を変更
変更内容
リリースハイライト
新たな文法を導入した変更
- PEP-563 アノテーションの評価を遅らせる
過去互換性のない文法変更
-
asyncとawaitは予約語になりました。
新たなライブラリモジュール
新たな組み込み機能
- PEP-553 組み込みブレークポイント
Pythonデータモデルの改善
- PEP-562 モジュール属性へのアクセスをカスタマイズ
-
PEP-560
typingモジュールとジェネリック型のコアサポート - 辞書型オブジェクトが挿入順を保持する事が正式にPython言語の仕様として宣言された
標準ライブラリの特筆すべき改善
-
asyncioモジュールは新機能の追加やユーザビリティ及び性能の改善が行われた -
timeモジュールはナノ秒解像度の関数のサポートが追加された
CPython実装の改善
C APIの改善
PEP-539 スレッド局所記憶にアクセスするための新たなC言語API
ドキュメントの改善
このリリースでは多くの箇所で特筆すべき性能改善を行なっている。詳細は「最適化」を参照。
過去バージョンとの互換に影響を与えるような変更については「Python 3.7へのポーティング」を参照ください。
新機能
PEP-563 アノテーションの評価を遅らせる
PEP-3107で提案されPEP-0526で改善されたアノテーション機能により型ヒントを与えられるようになった。だがそれによって二つの少し目立つユーザビリティの問題が起こった。
- アノテーションはすでに定義された名前に対してのみ付けられる。つまり、定義前の名前にアノテーションは付けられない(前方参照できない)
- アノテーション付きのソースコードはPythonプログラムのスタート時間に悪影響がある
この問題を解決するために、アノテーションの評価をコンパイル時から実行時に必要な時のみ行われるよう変更した。 これにより、前方参照もできるようになったし、スタート時間も早くなった。
これにより以下の前方参照の例も文法的に許容されるようになった(クラスCのvalidate_bというメソッドでその後に定義されているクラスBを参照している)。
class C:
@classmethod
def from_string(cls, source: str) -> C:
...
def validate_b(self, obj: B) -> bool:
...
class B:
...
ただし、これは非互換性の変更なので、この動作を有効にするためには以下のimport文を入れる必要がある。
from __future__ import annotations
そしてこの機能はPython 4.0で標準動作になる予定。
PEP-538 過去の遺物であるCロケールの抑制
Pythonインタプリターのコマンドラインインターフェースで、Cロケール(POSIXロケール)を設定していたとしても、強制的にC.UTF-8、C.utf8、UTF-8のどれかに変更して実行を行うというもの。これにより、ロケールを解釈するC拡張モジュール(readlineなど)はASCIIの代りにUTF-8をデフォルトエンコーディングとして動作する。この動作は新たに導入されるPYTHONCOERCECLOCALEという環境変数によって制御が可能(0にすると以前のバージョンの動作に戻る)。また、これに伴い、stdinとstdoutのデフォルトエラーハンドラーはsurrogateescapeになる。stderrはロケールに関わらずbackslashreplaceのまま。
PEP-540 UTF-8モードの追加
UTF-8モードが追加された。このモードではLocaleは無視してUTF-8エンコーディングが用いられる。そして、標準入出力のエラー処理には surrogateescapeが使用されます。このモードはPOSIX Locale以外ではデフォルトでオフになっているが、コマンドラインで -X utf8を付けるか、PYTHONUTF8環境変数を設定することでオンにすることができる。
PEP-553 組み込みブレークポイント
breakpoint()という組み込み関数を追加して、簡単に一貫性のある方法でデバッガを起動できるようにする。この関数はsys. breakpointhook()を呼び出す。このフックはデフォルトでは、pdbをインポートしてpdb.set_trace()を呼び出すという動作をするが、自分で他の関数をバインドすることも可能。あるいは、新設のPYTHONBREAKPOINT環境変数に同様にセットすることも可能だし、この環境変数を0に設定すればbreakpoint()機能を無効化もできる。
PEP-539 スレッド局所記憶にアクセスするための新たなC言語API
一つのプロセス内のスレッドは通常アドレス空間を共有しているが、スレッド毎に独立した記憶領域が欲しい場合がある。その為に各種プラットフォームで用意されている仕組みが
スレッド局所記憶(Thread local storage)である。Pythonでは従来Thread Local Storage(TLS) API というAPIでこれにアクセスしていたが、Keyの値が整数であるという想定を置いていた。これは全てのプラットフォームで成り立つ想定ではないため、新たにThread Specific Storage (TSS) APIを定義し、これによってTLS APIを置き換えることとした。
PEP-562 モジュール属性へのアクセスをカスタマイズ
モジュールレベルで__getattr__()を定義することができ、それによってモジュール属性へのアクセスをコントロールできるようになった。それにより、例えば非推奨の属性に対するアクセスが有った場合に警告メッセージをこれまでよりも容易に出せるようになった。
PEP-564 ナノ秒の精度を持つ新たな時間関数
従来の時間関数のナノ秒精度を持つバージョンが追加された。
- time.clock_gettime_ns()
- time.clock_settime_ns()
- time.monotonic_ns()
- time.perf_counter_ns()
- time.process_time_ns()
- time.time_ns()
PEP-565 __main__で非推奨の警告を出す
Python 2.7と3.2で非推奨警告をデフォルトで出さない変更を加えたが、非互換の変更に事前に気がつくという本来の目的を果たせなくなっていた。そこで、そのモジュールが __main__で呼び出された時には非推奨警告を出すようにした。
PEP-560 typingモジュールとジェネリック型のコアサポート
当初、PEP-484はCPythonのコアに変更を加えずに導入できるよう設計されていた。ところが最近になり、型ヒントやtypingモジュールがコミュニティの中で広く使われるようになってきたので、この制限を取り払うこととした。このPEPで、__class_getitem__()と__mro_entries__という二つのメソッドを導入し、typingモジュールのほとんどの構成要素から使うようにした。結果として、型に関する様々な操作が最大7倍早くなり、ジェネリック型をメタクラスの衝突無しに利用したりできるようになった。またこれにより、長い間解決されずにいたバグのいくつかが修正された。
開発実行時モードの追加: -X dev
コマンドライン・オプションに -X dev が追加され、サポートする環境変数にもPYTHONDEVMODE が追加された。これらを指定すると、デフォルトで有効にするにはオーバーヘッドのかかりすぎる実行時チェックなどが追加で実行される。
PEP-552ハッシュを利用したpycファイル
Pythonはバイトコードコンパイルした結果をpycファイルにキャッシュとして格納する。その際に、元ファイルの最終更新時刻とサイズをpycファイルのヘッダに記録しておき、再コンパイルが必要かどうかを判断するのに使っていた。これは効率的ではあるが欠点もある。ファイルシステムの時刻の解像度が荒かったりすると再コンパイルが必要なのにしなかったりして混乱をもたらす可能性がある。また、時刻をキャッシュファイルに記録するのでビルドの再現性の点で問題になったりもする。
PEP-552では元ファイルのハッシュをpycファイルに記録出来るようにする拡張を提案している。通常の利用では引き続き時刻を元にした判断が行われハッシュをpycに記録することは無いが、ハッシュを利用したpycはpy_compileやcompileallなどのモジュールで生成することができる。
ハッシュを記録したpycファイルには二種類有る。python実行時に更新確認をするものとしないものである。更新確認しないものは、外部のビルドシステムでpycの更新確認をする場合に有用である。
PEP-545 Pythonドキュメントの翻訳
PEP 545ではPythonドキュメントの翻訳プロセスに関して記述している。三つの翻訳が追加された。
- Japanese: https://docs.python.org/ja/
- French: https://docs.python.org/fr/
- Korean: https://docs.python.org/ko/
その他の言語の変更
- 関数で256以上の引数をとれるようになった
-
bytes.fromhex()とbytearray.fromhex()はスペースだけでなく、ASCIIの空白文字全てを無視するようになった。 -
str、bytes、bytearrayに新たにisascii()メソッドが追加され、文字列あるいはバイト列がASCII文字のみを含むか否かをテストできるようになった -
from ... import ...でImportErrorになる時にモジュール名とモジュールのパスを表示するようになった。
from os import unknown_func
$ python3.6 import_error.py
Traceback (most recent call last):
File "import_error.py", line 1, in <module>
from os import unknown_func
ImportError: cannot import name 'unknown_func'
$ python3.7 import_error.py
Traceback (most recent call last):
File "import_error.py", line 1, in <module>
from os import unknown_func
ImportError: cannot import name 'unknown_func' from 'os' (/Users/ksato/.pyenv/versions/3.7.0a2/lib/python3.7/os.py)
- サブモジュールを名前にバインドする絶対インポートを含む循環インポートが可能になった
-
object.__format__(x, '')はstr(x)と等価になった。 - スタックトレースの動的生成をより良くサポートするために、
types.TracebackTypeはPythonコードからインスタンス化できるようになり、tracebacksのtb_next属性に書き込みできるようになった。 -
-mオプションを使う時、sys.path[0]は空ディレクトリだったのが、実行ディレクトリのフルパスを返すようになった。 - 新たな
-XオプションあるいはPYTHONPROFILEIMPORTTIME環境変数により各モジュールインポートのタイミングを表示できる。
新規モジュール
contextvars
contextvarsという新たなモジュールと新たなC言語APIによりコンテキスト変数のサポートが導入された。コンテキスト変数はスレッドローカル変数と概念的には似ているが、非同期のコードでも正しく動作する。
dataclasses
クラスのデコレータdataclassを提供する新たなモジュールdataclassesが追加された。これを付けると、クラスの変数アノテーションを見て、__init__、__repr__、__eq__などのメソッドを自動追加する。
@dataclass
class Point:
x: float
y: float
z: float = 0.0
p = Point(1.5, 2.5)
print(p) # produces "Point(x=1.5, y=2.5, z=0.0)"
importlib.resources
このモジュールは幾つかの新たなAPIと、一つの新たな仮想クラスを提供する。これにより、パッケージ内のリソースにアクセスしたり開いたり読んだりすることができるようになる。リソースはほぼほぼパッケージ内のファイルだが、物理的なファイルシステム上の実際のファイルである必要はない。モジュールローダーはget_resource_reader()関数を提供し、それがimportlib.abc.ResourceReader のインスタンスを返しこの新たなAPIのサポートを行う。組み込みのパスローダーとzipファイルローダーは双方ともこれをサポートする。
改善されたモジュール
argparse
parse_intermixed_args()でオプションと位置引数を混合することができるようになった。
asyncio
asyncioモジュールは多くの機能追加とユーザビリティ及び性能の改善が行われた。特筆すべき主な変更点は以下の通り。
-
asyncio.run関数が追加され、同期コードから自動的にイベントループを作ったり消したりしながら、コルーティンを走らせることができるようになった。 - asyncioに
contextvarsモジュールのサポートが追加された。loop.call_soon()、loop.call_soon_threadsafe()、loop.call_later()、loop.call_at()、Future.add_done_callback()の各メッソドにcontextパラメータが追加され、Tasksクラスはそれらのコンテキストを自動的にトラックするようになった。詳細はPEP-567参照。 -
asyncio.get_event_loop().create_task()のショートカットとしてasyncio.create_task関数が追加された。 - 新たに追加された
loop.start_tls()を使うと、接続済のコネクションをTLSにアップグレードできる。 - 新たな
loop.sock_recv_into()関数はデータをソケットから読み、直接与えられたバッファに書き込む。これによりデータのコピーの回数を減らすことができる。 - 新たな
asyncio.current_task関数は、現在走っているTaskインスタンスを返し、asyncio.all_tasksは与えられたループにある全てのTaskのリストを返す。Task.current_task()とTask.all_tasks()メソッドは非推奨となる。 - 新たに
BufferedProtocolクラスが導入され、これにより受信バッファを手動制御するようなストリーミングプロトコルを実装できるようになった。 - 新たな
asyncio.get_running_loop関数は、現在実行中のループを返し、もし実行中のループが一つもない場合にはRuntimeError例外を発生させる。これは、asyncio.get_event_loopが実行中のループがない場合に新たなループを作って返すのとは対照的である。 -
StreamWriter.wait_closed()コルーチンメソッドは、そのストリームライターが閉じるまで待つ。StreamWriter.is_closing()メソッドはそのライターが閉じているかどうかを確認できる。 -
loop.sock_sendfile()コルーチンメソッドは、可能な場合にos.sendfileを使ってファイルを送る。 -
Task.get_loop()とFuture.get_loop()メソッドはそのTaskやFutureが生成されたループインスタンスを返す。Server.get_loop()は同様のことをasyncio.Serverオブジェクトに対して行う。 -
asyncio.Serverインスタンスがどのようにサービスを開始するかを制御できるようになった。以前はサーバーは生成された直後にサービスを開始していた。新たに導入されたstart_servingキーワード引数によりloop.create_server()、loop.create_unix_server()とServer.start_serving()、Server.serve_forever()でサーバーのインスタンス生成と実際のサービス開始を切り分けることができるようになった。Server.is_serving()メソッドはサーバが稼働中の時には真を返す。Serverクラスのオブジェクトは非同期コンテキストマネージャである。
srv = await loop.create_server(...)
async with srv:
# some code
# At this point, srv is closed and no longer accepts new connections.
-
loop.call_later()で返されるコールバックオブジェクトに新たにwhen()メソッドが追加され、絶対的なスケジュールされたコールバック時刻を返す。 -
loop.create_datagram_endpoint()メソッドにUnixソケットのサポートが追加された -
asyncio.open_connection、asyncio.start_server、loop.create_connection()、loop.create_server()、loop.create_accepted_socket()とそれらのUnixソケット版はssl_handshake_timeoutキーワード引数を受け付けるようになった。 -
Handle.cancelled()メソッドが追加され、コールバックがキャンセルされた時に真を返す。 - asyncioのソースコードが
async/awaitを使って書き換えられた。 -
ReadTransport.is_reading()メソッドが追加され、トランスポートの読み込み状態を確認できるようになった。加えて、ReadTransport.resume_reading()とReadTransport.pause_reading()が冪等(複数回操作を行っても結果が同じ)になった。 - ソケットパスを受け付けるLoopメソッドはパス風オブジェクトをサポートするようになった。
- Linux上の
asyncioのTCPソケットはデフォルトでTCP_NODELAYをつけて生成されるようになった。 - キャンセルされたタスクで起きた例外はログされなくなりました。
-
WindowsSelectorEventLoopPolicyクラスとWindowsProactorEventLoopPolicyクラスの追加。
幾つかのasyncioAPIは非推奨となった。
binascii
b2a_uu()が* backtick*キーワード引数を取れるようになった。これが真の時はゼロがスペースの代りに'`'で表現される。
calendar
HTMLCalendarクラスに新たな属性が追加され、生成されるHTMLカレンダーのCSSをカスタマイズするのが容易になった。
collections
collections.namedtuple()がデフォルト値をサポートするようになった。
compileall
compileall.compile_dir関数がinvalidation_mode 引数を取るようになり、ハッシュでのpycファイル更新確認ができるようになった。この更新確認モードはコマンドラインで--invalidation-modeをつけることでも指定できる。
concurrent.futures
ProcessPoolExecutorクラスとThreadPoolExecutorクラスはコンスラクタ引数としてinitializerとinitargsをサポートするようになった。
ProcessPoolExecutorクラスは、新たに追加されたmp_context引数でマルチプロセッシングコンテキストを取ることができる。
contextlib
ExitStackクラスよりもより簡単で高速に動作するno-opコンテキストマネージャとして、nullcontext関数が追加された
asynccontextmanager、AbstractAsyncContextManager、AsyncExitStackらが、非同期版の関数、クラスとして追加された。
cProfile
cProfileコマンドでスクリプトのパスを指定する代りに -mオプションでモジュール名を指定できるようになった。
crypt
Browfish暗号のハッシュ関数のサポートを追加。
mksalt()関数でハッシュの適応回数をパラメータで指定できるようになった。
datetime
fromisoformat()メソッドが追加され、isoformat()メソッドから出力された文字列からdatetimeオブジェクトを生成することができるようになった。
tzinfoクラスは分単位以下のオフセットをサポートするようになった。
dbm
dbm.dumbはread-onlyファイルを読めるようになり変更されていない時にはindexファイルを書かないようになった。
decimal
decimalモジュールはコンテキス変数を利用するようになり、十進数コンテキストを保持するようになった。
dis
dis()関数でネストしたコードオブジェクトの逆アセンブルができるようになった。最大ネスト数は新たに追加されたdepthパラメータでコントロールできる。
distutils
README.rstがREADMEとして利用可能になった。
enum
Enumクラスは_ignore_クラスプロパティを理解するようになり、列挙型のメンバにしたくないプロパティの名前を指定できるようになった。
Python 3.8ではEnum型でないオブジェクトでEnum型の存在確認(in演算)をするとTypeError例外を発生するようになる(例えば1 in Colorなど)。同様に、Flagクラスのメンバの存在確認でもTypeError例外を発生するようになる(例えば1 in Perm.RWなど)。今のところはこれらの操作ではFalseを返し非推奨の警告をだす。
functools
functools.singledispatchは型アノテーションを使った実装の登録をサポートするようになった。
gc
新たに追加されたgc.freezeにより、ガベージコレクタで追跡されている全てのオブジェクトをフリーズし、その後の回収対象から外すことができるようになった。これを呼ぶことでPOSIXのfork()をガベージコレクションの copy-on-writeに優しく、回収のスピードをあげることができる。gc.unfreezeはこの反対の操作をおこなう。また、gc.get_freeze_countでフリーズされているオブジェクトの数を知ることができる。
hmac
hmacモジュールは一回のみのダイジェスト計算に最適化されたdigest()関数を提供するようになった。これは通常のHMAC()よりも最大3倍速い。
http.client
HTTPConnectionとHTTPSConnectionでブロックサイズが変更可能になり、アップロードスループットを改善できる。
http.server
SimpleHTTPRequestHandlerが If-Modified-Sinceヘッダを解釈し、ターゲットのファイルがこのヘッダで指定された時刻から更新されていなければ304を返すようになった。
SimpleHTTPRequestHandlerのdirectoryパラメータと、http.serverモジュールのコマンドラインの--directoryオプションでサーブするディレクトリを指定できるようになった。
新たなThreadingHTTPServerクラスはThreadingMixinを使ってスレッドでリクエストを処理する。これは、http.serverを-mオプションで起動させた時の動作である。
idlelibとIDLE
自動補完の複数の修正。
モジュールブラウザはネストした関数やクラスを表示できるようになった。
設定画面が部分的に書き換えられ見た目と機能が向上した。
フォントのサンプルにラテン系以外の文字も追加され、特定のフォントを選んだ時の効果をよりよく見ることができるようになった。またサンプルに別の文字を含むように編集可能になった。
以前は拡張として実装されてたIDLEの機能が標準機能として再実装された。それらの設定は拡張タブから他の設定タブに移動された。
エディタのコードコンテキストオプションが改修された。
Windows上で新たなAPI呼び出しがされ、tkがDPIにスケールすることをOSに伝えている。これにより、Windows8.1+か10の上でテキストや線の描画がより鮮明になる可能性がある。
上記の変更は 3.6のメンテナンスリリースでもバックポートされている。
importlib
パッケージからのリソース読み込みに対応するために`importlib.abc.ResourceReader`仮想ベースクラスが導入された。
importlib.reload関数は、対象のモジュールがSpecを欠いていたらModuleNotFoundError例外をあげるようになった。
importlib.find_spec関数は、指定された親モジュールがパッケージじゃない(例えば__path__属性を欠いているなど)時に、AttributeErrorではなくModuleNotFoundError例外をあげるようになった。
importlib.source_hash関数は、渡されたソースコードのハッシュを計算し、ハッシュを利用したpycファイルはこの値を埋め込む。
io
TextIOWrapper.reconfigure()メソッドにより、テキストストリームを新たな設定で再構成できる。
ipaddress
IPv6NetworkおよびIPv4Networkクラスにsubnet_of()とsupernet_of()の二つのメソッドが追加され、ネットワークの包含関係を確認できる。
itertools
itertools.islice関数は、start, stop, slice引数に整数風オブジェクトを取れるようになった。
locale
format_string() 関数にmonetary引数が追加された。これが真だとLC_MONETARYで定義された桁区切り文字をつかってグループ化を行う。
locale.getpreferredencoding()関数は、Android か UTF-8モード(-X utf8オプション)の場合に常に'UTF-8'を返すようになった。
logging
Loggerクラスのインスタンスはピクル化できるようになった。
StreamHandler.setStream()メソッドが追加され、ハンドラを作成後にロガーストリームを変更することができるようになった。
logging.config.fileConfigに渡すコンフィグレーションファイルの中でハンドラ作成時のキーワード引数を指定できるようになった。
math
新たに導入されたremainder()関数が IEEE 754スタイルの剰余演算を提供する。
mimetypes
.bmpファイルのMIMEタイプを'image/x-ms-bmp'から'image/bmp'に変更した。
msilib
Database.Close()メソッドが新たに提供され、MSIデータベースを閉じることができる。
multiprocessing
新たなProcess.close()メソッドは、明示的にプロセスオブジェクトを閉じて、それに関連づけられた全てのリソースを解放する。そのプロセスがまだ稼働している時にはValueError例外をあげる。
新たなProcess.kill()メソッドは、Unix上でSIGKILLシグナルを用いてそのプロセスを停止させる。
Processクラスで作成されたデーモン化されていないスレッドがある場合、その完了を待ってプロセスは終了する。
os
os.fwalk()でバイト列のパスをサポート
os.scandir()でファイルディスクリプタを引数としてとれるようになった。
試してみよう。
import os
fd = os.open('.', os.O_DIRECTORY)
for f in os.scandir(fd):
print(f)
$ python3.6 scandir_fd.py
Traceback (most recent call last):
File "scandir_fd.py", line 3, in <module>
for f in os.scandir(fd):
TypeError: scandir: path should be string, bytes, os.PathLike or None, not int
$ python3.7 scandir_fd.py
<DirEntry 'scandir_fd.py'>
<DirEntry 'import_error.py'>
<DirEntry '.python-version'>
確かに、3.6ではエラーになるが3.7だと問題なく動く。
register_at_fork関数が導入され、プロセスがフォークするときに呼ばれるPythonコールバックを設定できるようになった。
os.preadv関数(os.readvとos.preadの機能を一体化)およびos.pwritev関数(os.writevとos.pwriteの機能を一体化)を追加した。
os.makedirsのmode引数は新たに作成される中間レベルディレクトリのファイルパーミッションビットに影響しなくなった。
os.dup2は新たに作成されたファイルディスクリプタを返すようになった。以前は常にNoneを返していた。
os.statで返される構造体は、Slarisおよびその派生OSでstat_result.st_fstype属性を返すようになった。
pathlib
Path.is_mount()メソッドがPOSIXシステムで追加され、指定したパスがマウントポイントかどうかを判定することができるようになった。
pdb
set_trace()にキーワード(のみ)引数の headerが追加された。これを指定するとデバッグが始まる前に指定された文字列をコンソールに表示する。
pdbのコマンドラインは、スクリプトの代りに -m module_nameというパラメータを付けられるようになった。
py_compile
py_compile.compile()とcompileallは SOURCE_DATE_EPOCH環境変数を見るようになった。これにより、.pycファイルを再現可能な形でビルドすることができるようになった。
pydoc
pydocサーバーは、コマンドライン引数の-nで指定された任意のホスト名にバインドできるようになった。
queue
新たにSimpleQueueクラスが提供され、バインドされていないFIFOキューを生成できるようになった。
re
re.ASCII、re.LOCALE、re.UNICODEがグループのスコープとして設定可能になった。
re.splitがr'\b'、'^$'、(?=-)というような空の文字列にマッチするパターンを指定可能になった。
re.LOCALEフラグ付きでコンパイルされた正規表現はコンパイル時のロカールに依存しなくなった。ロカールの設定はそのコンパイルされた正規表現が使われる際に適用される。
正規表現が将来的に意味が変わる文字セット(例えば、ネストしたセットやセット操作)を使っている場合、FutureWarning例外をあげるようになった。
コンパイルされた正規表現やマッチオブジェクトがcopy.copyやcopy.deepcopyでコピーできるようになった。
signal
signal.set_wakeup_fdにwarn_on_full_buffer引数が追加され、wakeupファイルディスクリプタがバッファオーバーフローした時に標準エラーに警告メッセージを出力するかどうかを指定できるようになった。
socket
socket.getblocking()メソッドが追加され、ソケットがブロッキングモードになっているか否かを確認できるようになった。
socket.close関数が追加され、渡されたソケットファイルディスクリプタを閉じることができるようになった。様々なプラットフォームのより良い互換性のため、今後はos.closeではなくこちらを使うべし。
socketモジュールにsocket.TCP_CONGESTION(Linux 2.6.13)、socket.TCP_USER_TIMEOUT (Linux 2.6.37)、socket.TCP_NOTSENT_LOWAT (Linux 3.12)という定数が追加された。
仮想マシンとそのホスト間の通信のためにsocket.AF_VSOCKソケットのサポートが追加された。
デフォルト動作として、ソケットはそのファイルディスクリプタからファミリー、タイプ、プロトコルを自動検知するようになった。
socketserver
socketserver.ThreadingMixIn.server_closeメソッドは非デーモン化されたスレッドの完了を待つようになった。socketserver.ForkingMixIn.server_closeメソッドは全ての子プロセスの完了を待つようになった。
新たなクラス属性としてsocketserver.ForkingMixIn.block_on_closeがsocketserver.ForkingMixInクラスとsocketserver.ThreadingMixInクラスに追加された。このクラス属性をFalseにすることで3.7より前の動作に戻すことができる。
sqlite3
利用しているSQLiteのライブラリがバージョン3.6.11以上の場合、sqlite3.ConnectionクラスにConnection.backupメソッドが追加される。
sqlite3.connectのdatabase引数はパス風オブジェクトを受け付けるようになった。
ssl
sslモジュールは、match_hostname()ではなくOpenSSLの組み込みAPIをホスト名やIPアドレスのチェックに使うようになった。値の確認はTLSハンドシェーク中に行われる。ホスト名が合わないなどの証明書検証のエラーは `SSLCertVerificationError` 例外があがり、TLS接続は適切なアラートメッセージを表示して失敗する。この新たな例外には付加情報が含まれている。また、ホスト名の検証は host_flagsによってカスタマイズできる。
sslモジュールはTLS拡張のSNI(Server Name Indication)でIPアドレスを送らないようにした(RFC-6066に準拠)。
match_hostname()はwww*.example.orgのように名前の中に*が含まれるワイルドカードをサポートしなくなった(*はホスト名の一番左に現れる時のみ有効)。
sslモジュールの暗号スイートの選択は、ハードコードされたホワイトリストではなく、ブラックリストを利用する方法がデフォルトとなった。そして、OpenSSLのセキュリティアップデートで利用不可となった暗号を利用可能にすることはできなくなった。デフォルトの暗号スイートの選択はコンパイル時に設定される。
国際化ドメイン名(IDNs)を含むサーバ証明書の検証のサポートを追加した。これによりssl.SSLSocket.server_hostname属性は、Uラベル形式(Unicodeでの表現、例えば "pythön.org") ではなくAラベル形式(Ascii Compatible Encodingでの表現、例えば "xn--pythn-mua.org") で期待されるホスト名を格納するようになった。
sslモジュールは予備的、実験的な位置付けでTLS 1.3とOpenSSL 1.1.1のサポートを追加した。
SSLSocketとSSLObjectは公開されたコンストラクターを持たなくなった。これらを直接インスタンス化することは元来ドキュメント化されておらずサポートもされていなかった。これらのインスタンスはSSLContextのwrap_socket()やwrap_bio()メソッドを使って生成すべきである。
OpenSSL 1.1のTLSプロトコルバージョンの上限・下限を設定するAPIはSSLContext.minimum_versionとSSLContext.maximum_versionで利用可能になった。サポートされるバージョンはHAS_TLSv1_1のような新たなフラグで指定する。
string
string.Templateで'{'と'}'に囲まれたプレースホルダの正規表現を囲まれていないものと独立に指定できるようになった。
subprocess
subprocess.run関数は、新たなキーワード引数capture_outputを取るようになり、これが真の時は標準出力と標準エラーをキャプチャするようになる。これは、stdoutとstderr引数にsubprocess.PIPEを渡すのと同等の効果がある。
subprocess.run関数とsubprocess.Popenクラスのコンストラクタは、universal_newlinesのエイリアスとしてtextキーワード引数を取るようになった。
Windows環境で close_fds のデフォルト値がFalseからTrueになった。これで全てのサポートプラットフォームでデフォルト値はTrueとなった。
subprocess.call、subprocess.runやPopenクラスのコンテキストマネージャ内で、より「上品に」KeyboardInterrupt例外を処理するようになった。つまり、例外処理を始める前に、子プロセスが終了するために少しの時間待つ。
sys
sys.breakpointhookフック関数が追加され、組み込み関数のbreakpointから呼ばれることになった。
Android上で、sys.getandroidapilevelはビルド時のAndroidのAPIバージョンを返す。
コルーチンのオリジン追跡深度は新たに追加されたsys.set_coroutine_origin_tracking_depth関数で設定でき、それをsys.get_coroutine_origin_tracking_depth関数で取得できる。asyncioモジュールは、非推奨となったsys.set_coroutine_wrapperの代わりにこれらの新しいAPIを使うようになった。
time
PEP-564 によりナノ秒の精度を持つ新たな時間関数が追加された。
- time.clock_gettime_ns()
- time.clock_settime_ns()
- time.monotonic_ns()
- time.perf_counter_ns()
- time.process_time_ns()
- time.time_ns()
そして、新たな時間ID定数として以下が追加された。
-
time.CLOCK_BOOTTIME(Linux):time.CLOCK_MONOTONICと同等だが、システムが停止している時間も含む。 -
time.CLOCK_PROF(FreeBSD, NetBSD and OpenBSD): 高精度のプロセス毎のタイマー -
time.CLOCK_UPTIME(FreeBSD, OpenBSD): 停止している時間を除くシステム稼働時間の絶対値
time.thread_time()とtime.thread_time_ns()関数が追加され、スレッドごとのCPU時間の測定ができるようになった。
新たに追加されたtime.pthread_getcpuclockid関数が、スレッド特有のCPU時間クロックのIDを返すようになった。
tkinter
tkinter.ttk.Spinbox が追加された。
tracemalloc
tracemalloc.Tracebackクラスは通常のトレースバックのように動作し、フレームは古い方から新しい方へとソートされる。Traceback.format()メソッドは負の値をlimitパラメータで取れるようになり、古い方からlimitの絶対値分だけにサイズを切り詰める。前の動作をさせたい場合は新たに追加されたmost_recent_firstを引数を使うと良い。
types
WrapperDescriptorTypeクラス、MethodWrapperTypeクラス、MethodDescriptorTypeクラス、ClassMethodDescriptorTypeクラスが追加された。
types.resolve_bases関数が追加され、PEP-560で示されているようにMRO(Method Resolution Orders)エントリーを動的に解決する。
unicodedata
unicodedataの内部データベースがUnicode 11を利用するようにアップグレードされた。
unittest
新たなコマンドライン・オプション-kが追加され、走らせるテストを部分文字列あるいはUnixのシェル風パターンで指定することができるようになった。例えば、python -m unittest -k fooはfoo_tests.SomeTest.test_somethingやbar_tests.SomeTest.test_fooを走らせるが、bar_tests.FooTest.test_somethingは対象外となる。
unittest.mock
sentinel属性がcopyやpickleされても同一性確認できるようになった。
試してみた。
from unittest.mock import sentinel
import copy
import pickle
a = sentinel.object_a
a2 = copy.copy(a)
print('a == a2: ', format(a==a2))
a3 = pickle.loads(pickle.dumps(a))
print('a == a3: ', format(a==a3))
$ python3.6 sentinel_test.py
a == a2: False
a == a3: False
$ python sentinel_test.py
a == a2: True
a == a3: True
また、新たな関数mock.sealが導入され、それが適用されたモックオブジェクトでは新たな属性の読み書きができなくなる。モックオブジェクトが他のモックを属性として持っていたらそれらにもこのSealは再帰的に適用される。
urllib.parse
urllib.parse.quote()が参照する仕様がRFC 2396 からRFC 3986に変更になり、'~'がデフォルトでクオートされない文字に追加された。
uu
encode()関数がbacktickキーワード引数をとれるようになった。これが真の時はゼロがスペースの代りに'`'で表現される。
uuid
新たに追加されたUUID.is_safe属性により、そのプラットフォームのUUID生成方法がマルチプロセス対応しているかどうかを知ることができるようになった。
uuid.getnodeはローカルアドレスではなくグローバルアドレスを優先的に用いる。これにより、uuid.uuid1で生成されるUUIDのグローバルな単一性をよりよく保証できる。仮にローカルアドレスしかない場合は最初に見つかったモノを返す。
warnings
警告フィルタの初期値が以下のように変更された
- コマンドラインオプションで有効にされる警告(
-bや-X devオプションを含む)は常にsys.warnoptions属性経由で渡される - コマンドラインオプションで有効にされる警告は次の優先度順位を持つ
-
-b/-bbのためのBytesWarningフィルタ -
-Wで指定されたフィルタ -
PYTHONWARNINGSで指定されたフィルタ - その他のCPython特有のフィルタ(新たな
-X devのために追加されたデフォルトフィルタなど) - 警告の仕組みで暗黙に定義されたフィルタ
-
- CPythonのデバッグビルドではデフォルトで全ての警告が表示される
単一ファイルスクリプトや対話プロンプトの時はデフォルトで非推奨警告が表示される。
xml.etree
find()メソッドのXPath述語で[. = "text"]という形の記述が可能になり、小ノードのテキストだけでなく自ノードのテキストとの比較も可能になった。また、XPath述語に見やすさのために空白を入れられるようになった。
xmlrpc.server
xmrpc.server.SimpleXMLRPCDispatcherとその継承クラスのregister_function()がデコレーターとして利用可能になった。
zipapp
zipapp.create_archive()関数がfilter引数をとれるようになった。これによってどのファイルをアーカイブに含めるかをユーザが指定できるようになる。またcompressed引数あるいは--compressコマンドライン・オプションでで圧縮したアーカイブを作成できるようになった。
zipfile
ZipFileクラスはcompresslevelパラメータを受け付け、圧縮レベルをコントロールできるようになった。
ZipFileで生成されたアーカイブに含まれるサブディレクトリはアルファベット順に格納されるようになった。