Python

Python3.7の新機能

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 モジュールの仮想ベースクラス」を非推奨に追加
  • contextlib distutils hmac importlib locale py_compile ssl sys tkinter warningsモジュールの改善点を追記
  • 動作変更の欄に PEP-479が発動した件を追記
  • 削除されたサポートプラットフォームにFreeBSD 9を追加

2018.03.02

3.7.0b2を元に以下を修正。

  • PEP-567 「コンテキスト変数」を追加
  • types.TracebackTypeの変更を「その他の言語の変更」に追加
  • 「abcモジュールの関数とメソッドをCで再実装」、「datetime.datedatetime.datetimeのコンストラクタを変更」を「最適化」に追加
  • sslモジュールの改善点を追記
  • deprecated を「非推奨」と訳すようにしました。

2018.07.12

3.7.0を元に以下を修正。

  • リリースハイライトを追加
  • PEP-560 「typingモジュールとジェネリック型のコアサポート」を追記
  • asynciocollectionscompilealldatetimedbmdecimalenumfunctoolsgcidlelib/IDLEioipaddressitertoolsloggingmimetypesmsilibmultiprocessingpydocqueuesignalsocketsocketserversqlite3tracemalloctypesuuidzipfileモジュールの改善点を追記
  • 長くなりすぎたので「ビルドとC APIの変更」、「最適化」、「その他のCPython実装の変更」、「非推奨」、「削除済み」、「Python 3.7へのポーティング」、「ドキュメンテーション」を削除
  • 最新版に合わせて項目の順序を変更

変更内容

リリースハイライト

新たな文法を導入した変更

  • PEP-563 アノテーションの評価を遅らせる

過去互換性のない文法変更

  • asyncawaitは予約語になりました。

新たなライブラリモジュール

  • PEP-567 コンテキスト変数
  • PEP-557 データクラス
  • importlib.resources

新たな組み込み機能

  • PEP-553 組み込みブレークポイント

Pythonデータモデルの改善

  • PEP-562 モジュール属性へのアクセスをカスタマイズ
  • PEP-560 typingモジュールとジェネリック型のコアサポート
  • 辞書型オブジェクトが挿入順を保持する事が正式にPython言語の仕様として宣言された

標準ライブラリの特筆すべき改善

  • asyncioモジュールは新機能の追加やユーザビリティ及び性能の改善が行われた
  • timeモジュールはナノ秒解像度の関数のサポートが追加された

CPython実装の改善

  • 文字エンコードのデフォルトとしてASCIIを使わないようになった
    • PEP 538 Cロケールの抑制
    • PEP 540 強制的なUTF-8実行時モード
  • PEP 552 確定的なpycファイル
  • 新たな開発実行時モード
  • PEP 552 非推奨警告の取り扱い改善

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-8C.utf8UTF-8のどれかに変更して実行を行うというもの。これにより、ロケールを解釈するC拡張モジュール(readlineなど)はASCIIの代りにUTF-8をデフォルトエンコーディングとして動作する。この動作は新たに導入されるPYTHONCOERCECLOCALEという環境変数によって制御が可能(0にすると以前のバージョンの動作に戻る)。また、これに伴い、stdinstdoutのデフォルトエラーハンドラーは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_compilecompileallなどのモジュールで生成することができる。

ハッシュを記録したpycファイルには二種類有る。python実行時に更新確認をするものとしないものである。更新確認しないものは、外部のビルドシステムでpycの更新確認をする場合に有用である。

PEP-545 Pythonドキュメントの翻訳

PEP 545ではPythonドキュメントの翻訳プロセスに関して記述している。三つの翻訳が追加された。

その他の言語の変更

  • 関数で256以上の引数をとれるようになった
  • bytes.fromhex()bytearray.fromhex() はスペースだけでなく、ASICIIの空白文字全てを無視するようになった。
  • strbytesbytearrayに新たにisascii()メソッドが追加され、文字列あるいはバイト列がASCII文字のみを含むか否かをテストできるようになった
  • from ... import ...ImportErrorになる時にモジュール名とモジュールのパスを表示するようになった。
import_error.py
from os import unknown_func
Python3.6
$ 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
$ 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_connectionasyncio.start_serverloop.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クラスはコンスラクタ引数としてinitializerinitargsをサポートするようになった。

ProcessPoolExecutorクラスは、新たに追加されたmp_context引数でマルチプロセッシングコンテキストを取ることができる。

contextlib

ExitStackクラスよりもより簡単で高速に動作するno-opコンテキストマネージャとして、nullcontext関数が追加された

asynccontextmanagerAbstractAsyncContextManagerAsyncExitStackらが、非同期版の関数、クラスとして追加された。

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

HTTPConnectionHTTPSConnectionでブロックサイズが変更可能になり、アップロードスループットを改善できる。

http.server

SimpleHTTPRequestHandlerが If-Modified-Sinceヘッダを解釈し、ターゲットのファイルがこのヘッダで指定された時刻から更新されていなければ304を返すようになった。

SimpleHTTPRequestHandlerdirectoryパラメータと、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()でファイルディスクリプタを引数としてとれるようになった。

試してみよう。

scandir_fd.py
import os
fd = os.open('.', os.O_DIRECTORY)
for f in os.scandir(fd):
  print(f)
Python3.6
$ 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
$ 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.readvos.preadの機能を一体化)およびos.pwritev関数(os.writevos.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.ASCIIre.LOCALEre.UNICODEがグループのスコープとして設定可能になった。

re.splitr'\b''^$'(?=-)というような空の文字列にマッチするパターンを指定可能になった。

re.LOCALEフラグ付きでコンパイルされた正規表現はコンパイル時のロカールに依存しなくなった。ロカールの設定はそのコンパイルされた正規表現が使われる際に適用される。

正規表現が将来的に意味が変わる文字セット(例えば、ネストしたセットやセット操作)を使っている場合、FutureWarning例外をあげるようになった。

コンパイルされた正規表現やマッチオブジェクトがcopy.copycopy.deepcopyでコピーできるようになった。

signal

signal.set_wakeup_fdwarn_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_closesocketserver.ForkingMixInクラスとsocketserver.ThreadingMixInクラスに追加された。このクラス属性をFalseにすることで3.7より前の動作に戻すことができる。

sqlite3

利用しているSQLiteのライブラリがバージョン3.6.11以上の場合、sqlite3.ConnectionクラスにConnection.backupメソッドが追加される。

sqlite3.connectdatabase引数はパス風オブジェクトを受け付けるようになった。

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_versionSSLContext.maximum_versionで利用可能になった。サポートされるバージョンはHAS_TLSv1_1のような新たなフラグで指定する。

string

string.Templateで'{'と'}'に囲まれたプレースホルダの正規表現を囲まれていないものと独立に指定できるようになった。

subprocess

subprocess.run関数は、新たなキーワード引数capture_outputを取るようになり、これが真の時は標準出力と標準エラーをキャプチャするようになる。これは、stdoutstderr引数にsubprocess.PIPEを渡すのと同等の効果がある。

subprocess.run関数とsubprocess.Popenクラスのコンストラクタは、universal_newlinesのエイリアスとしてtextキーワード引数を取るようになった。

Windows環境で close_fds のデフォルト値がFalseからTrueになった。これで全てのサポートプラットフォームでデフォルト値はTrueとなった。

subprocess.callsubprocess.runPopenクラスのコンテキストマネージャ内で、より「上品に」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 foofoo_tests.SomeTest.test_somethingbar_tests.SomeTest.test_fooを走らせるが、bar_tests.FooTest.test_somethingは対象外となる。

unittest.mock

sentinel属性がcopyやpickleされても同一性確認できるようになった。

試してみた。

sentinel_test.py
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
$ python3.6 sentinel_test.py
a == a2:  False
a == a3:  False
Python3.7
$ 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で生成されたアーカイブに含まれるサブディレクトリはアルファベット順に格納されるようになった。