Python3.6の新機能

# はじめに
以前、[Python3.5の新機能](http://qiita.com/ksato9700/items/9a0aef07d90d00e67525)という記事を書いたが、3.6もα版が出て来たので、3.6の機能を先取りして確認してみようと思う。

開発ロードマップ([PEP-494](https://www.python.org/dev/peps/pep-0494/))によると

 - 3.6.0 alpha 1: 2016-05-17 (完了)
 - 3.6.0 alpha 2: 2016-06-13 (完了)
 - 3.6.0 alpha 3: 2016-07-11 (完了)
 - 3.6.0 alpha 4: 2016-08-15 (完了)
 - 3.6.0 beta 1: 2016-09-12 (完了・新機能追加はここまで)
 - 3.6.0 beta 2: 2016-10-03
 - 3.6.0 beta 3: 2016-10-31
 - 3.6.0 beta 4: 2016-11-21
 - 3.6.0 candidate 1: 2016-12-05
 - 3.6.0 candidate 2: 2016-12-12 (必要であれば)
 - 3.6.0 final: 2016-12-16

となっていて、先はまだまだ長い。最終版が出るのは12月16日。クリスマス前だ。新機能の追加も9月のベータが出るまで続くのでそれまではドンドン変わっていくと思うが、変更がある度にこの記事をアップデートしていこうと思う。その方が一気に見るよりも楽だし(^^;

という事で、今回参照したのは3.6.0b1で、[ここ](https://docs.python.org/3.6/whatsnew/3.6.html)のドラフト版リリースドキュメントを参考にした。

試す場合にはpyenvを使って

```
pyenv install 3.6.0b1
pyenv local 3.6.0b1
```
でどうぞ。

## 更新履歴
### 2016.07.16
 - 確認に使ったバージョンを 3.6.0a2から3.6.0a3に変更
 - (それ以外、気がついた変更なし...)

### 2016.10.01
 - 確認に使ったバージョンを 3.6.0b1に変更
 - Betaになりこれ以上の仕様変更は無いためタイトルから"(a3版)"を削除
 - 「新たな文法の導入」に global/nonlocalの変更、PEP515, PEP526, PEP525, PEP530 を追加
 - 「セキュリティの改善」を追加
 - 「Windowsでの改善」にPSP529, PEP528他を追加
 - 「新規ビルトイン機能」を追加
 - 「新機能」に追加多数
 - 「その他の言語の変更」に記述追加
 - 「改善されたモジュール」に記述追加
 - 「廃止候補」に「廃止予定のビルドオプション」を追加



# 変更内容
## リリースハイライト
### 新たな文法の導入
 - `global`と`nonlocal`はそのスコープで最初にその変数を使う前に置かないとダメになった(これまでは警告のみ)
 - [PEP-498](https://www.python.org/dev/peps/pep-0498/) 書式化文字列リテラル
 - [PEP-515](https://www.python.org/dev/peps/pep-0515/) 数値リテラルの中に`_`を入れられる様になった
 - [PEP-526](https://www.python.org/dev/peps/pep-0526/) 変数にアノテーションする記法の導入
 - [PEP-525](https://www.python.org/dev/peps/pep-0525/) 非同期ジェネレーターの導入
 - [PEP-530](https://www.python.org/dev/peps/pep-0530/) 非同期内包表記の導入

PEP-498、PEP-515、PEP-526は「新機能」のところで更に詳細に触れている。

### セキュリティの改善
 - Linux上で、os.urandom()はシステムのurandomエントロピープールが初期化されるまでブロックすることになった。詳細な論拠はPEP524(https://www.python.org/dev/peps/pep-0524/)参照。
 - `hashlib`と`ssl`モジュールがOpenSSL 1.1.0をサポート
 - `ssl`のデフォルト設定と機能セットがよりセキュアなものに
 - `hashlib`モジュールが新たなハッシュ関数(BLAKE2、SHA-3、SHAKE)と鍵導出関数`scrypt()`をサポート

### Windowsでの改善
 - PEP529(https://www.python.org/dev/peps/pep-0529/) WindowsのファイルシステムエンコーディングをUTF-8に変更
 - PEP528(https://www.python.org/dev/peps/pep-0528/) WindowsのコンソールエンコーディングをUTF-8に変更
 - これまで py.exeをコマンドラインで使う時には、バージョン指定が無いとPython2を優先させていたのだが、今後はPython3になる。
 - `python.exe`と`pythonw.exe`がロングパス対応になり、ファイルパスの260文字制限がなくなった
 - `._pth`ファイルにモジュールのサーチパスを書くことができるようになった
 - `PYTHONHOME`が環境変数で設定されない場合、`Python36.zip`の位置でそれを推測するようになった

### 新規ビルトイン機能
 - PEP-520(https://www.python.org/dev/peps/pep-0520/) クラスの属性の定義順序を保持する
 - PEP-468(https://www.python.org/dev/peps/pep-0468/) キーワード引数の順序を保持する

## 新機能
### [PEP-515](https://www.python.org/dev/peps/pep-0515/) 数値リテラルの中に`_`を入れられる様に
`1000000000000000`を`1_000_000_000_000_000`と書いたり出来るようになった。意味的な変更はまったくなく単純に読みやすさのためだけの`_`だ。

### [PEP-523](https://www.python.org/dev/peps/pep-0523/) フレーム評価APIの追加
 フレームオブジェクトの評価はこれまでカスタマイズできなかったが、それを出来るようにするためのCレベルのAPIを追加した。これによりJITやDebuggerの実装が楽になるらしい。

### [PEP-519](https://www.python.org/dev/peps/pep-0519/) ファイルシステムパスプロトコルの追加
 従来、ファイルシステムのパスは`str`型か`bytes`型で、Python標準のものも含めて、パスを扱うライブラリはその想定で作られていた。そのため、[pathlib](https://docs.python.org/3.6/library/pathlib.html#module-pathlib)のような、パスを表現するライブラリを既存のライブラリと組み合わせて使うのが困難だった。
 
これを解消するために`os.PathLike`というインターフェース(仮想基底クラス)を定義した。パスを表すオブジェクトは、これを継承し、パスの文字列表現を返す`__fspath__()`というメソッドを定義することで、他のライブラリがこれをパスだと認識して動作してくれることになった。
 
### [PEP-498](https://www.python.org/dev/peps/pep-0498/) 書式化文字列リテラル
文字列の前に`f`をつけると書式化文字列になる。str.formatの書式にも似ているが、`{`と`}`で囲まれた部分が変数として置換される。例えばこんな感じ。

```
>>> name = "モンティ・パイソン"
>>> f"私の名前は{name}です"
'私の名前はモンティ・パイソンです'
```

これが、str.formatを使うと

```
>>> "私の名前は{name}です".format(name=name)
```

あるいは

```
>>> "私の名前は{}です".format(name)
```

としなければならなかったので、少し記述が楽になりそう。

### [PEP-526](https://www.python.org/dev/peps/pep-0526/) 変数にアノテーションする記法の導入
Pythonは明示的な型指定のない動的型付けの言語だが、そのため静的解析などをやりにくいという問題があった。それを解消するために、PEP-484(https://www.python.org/dev/peps/pep-0484/)では関数の引数に型情報を付記するという方法が提案され、Python3.5で導入された。

これをさらに拡張し、変数(クラス変数、インスタンス変数を含む)にも型情報を付けられるようにしたというのが今回の変更。従来もコメントを使えば同じように出来たが、文法の変更で対応したというのが違いになる。例えばこんな感じ。

```
from typing import List, Dict
 
primes: List[int] = [] # 整数のリスト型の例で、それを空リストで初期化

captain: str  # 文字列型。初期化しない例

class Starship:
    stats: Dict[str, int] = {} # クラス変数の例。Keyとして文字列、値として整数を取る辞書型
```

なお、この型アノテーションで何か動作が変わるわけではなく、違った型の値を代入してもエラーにはならない。あくまでも、型情報の「ヒント」であり、この情報を元に静的解析をしたりという用途に向けたものになる。

### [PEP-529](https://www.python.org/dev/peps/pep-0529/) WindowsのファイルシステムエンコーディングをUTF-8に変更

従来はWindowsの上でBytesを使ってパスを受け渡しするとデータ欠損とかが出る場合があった。Python 3.6からはBytesを使っていたとしてもシステムのデフォルトエンコーディングでエンコードされて返ってくることになった。なお、デフォルトエンコーディングは今のところUTF-8だが、ベータ期間のフィードバックに寄って最終的に変わるかもしれないとのこと。

### [PEP-487](https://www.python.org/dev/peps/pep-0487/) クラス生成の簡単カスタマイズ

クラスが継承された場合に、`__init_subclass__(cls)`というクラスメソッドが呼ばれる事になった。この中でカスタマイズするコードを書くことが出来る。また、ディスクリプタオブジェクトの初期化時に`__set_name__`というメソッドを呼ぶことになった。

### [PEP-528](https://www.python.org/dev/peps/pep-0528/) WindowsのコンソールエンコーディングをUTF-8に変更

全てのUnicode文字を受け付けるようになり、正しくstrオブジェクトに読み込むことができるようになった。そして、`sys.stdin`、`sys.stdout`、`sys.stderr`のデフォルトエンコーディングはUTF-8となった。

### PYTHONMALLOC環境変数
PYTHONMALLOCという環境変数にある値を入れることによってPythonのメモリ割り当ての動作を変えるたりデバッグの為のフックを仕掛けることができる。

#### PYTHONMALLOC=debug
この設定にすると、以下のデバッグ機能が有効になる
 - 新たに割り当てられたメモリ領域は`0xCB`で埋められる
 - 開放された領域は`0xDB`で埋められる
 - メモリ割り当てAPIの不正な利用が検出される。例えば`PyMem_Malloc()`で取った領域を`PyObject_Free()`で開放したりした場合。
 - 割り当て領域の前に書き込んだり(バッファアンダーフロー)、後に書き込んだり(バッファオーバーフロー)した場合を検出。
 - メモリ割り当て関数が呼ばれた時にGIL(Global Interpreter Lock)が確保されているかどうかの確認。

#### PYTHONMALLOC=malloc
この設定にすると、Cライブラリの`malloc`を強制的に使うようになる。これによって、Valgrindなどの外部ツールが使えるようになる。

#### PYTHONMALLOC=malloc_debug
上記2つの組み合わせ

### DTraceとシステムタップのサポート
`--with-dtrace`付きでコンパイルすると以下のイベントを検知するマーカーが有効になる。

- 関数呼び出し、関数復帰
- ガベージコレクションの開始と終了
- 実行されているコードの行番号

この機能によってPythonをデバッグ用に再コンパイルすることなくデバッグやプロファイリングができる。

### [PEP-520](https://www.python.org/dev/peps/pep-0520/) クラス属性の定義順序保持

クラスの属性はソースコードに記述された順序で、クラスの`__dict__`属性に保持される。

### [PEP-468](https://www.python.org/dev/peps/pep-0468/) キーワード引数順序の保持

関数のキーワード引数はその順序を保持された形で`**kwargs`に渡される。

### [PEP-509](https://www.python.org/dev/peps/pep-0509/) 辞書型オブジェクトに内部バージョン導入

辞書型オブジェクトに変更が加わったときのみ更新されるバージョンを導入した。それにより、各種の最適化(性能向上)を行うことが可能になる。

## その他の言語の変更

− `dict()`はPyPyで由来のコンパクトな表現を使うようになり、メモリ使用量はPythono3.5と比べて20-25%少ない。そして、[PEP-468](https://www.python.org/dev/peps/pep-0468/)のキーワード引数の順序保持はこれを使って実装されている。一方、「順序が保存される」という性質は実装依存のもので、将来的に変わる可能性があるので、それを前提にした実装はするべきではない。

- トレースバックの長い繰り返しは省略して表記されるようになった

- `import`がモジュールを見つけられなかった場合は`ModuleNotFoundError`を返すようになった


## 新規のモジュール
(今のところなし)

## 改善されたモジュール
### asyncio
asyncioは「provisional(暫定的な)」と定義されているので、全ての変更は3.5.xにもバックポートされる。

3.5.0からの主な変更点は以下の通り。

 - `ensure_future()`関数とそれを使う関数は、すべての種類のawaitable オブジェクトを引数に指定できるようになった。
 - `run_coroutine_threadsafe()`関数が新たに導入されて、他のスレッドからイベントループにコルーチンを投入できるようになった。
 - `Transport.is_closing()`メソッドが追加され、トランスポートが閉じられている(あるいは閉じている途中)かが確認できるようになった。
 - `loop.create_server()` メソッドはホストのリストを引数に取れるようになった。
 - `loop.create_future()` メソッドが追加され、Futureオブジェクトを作成できるようになった。これによって、代替のイベントループ実装が可能になり、より速いasyncio.Futureを提供できるようになる。
 - `loop.get_exception_handler()`メソッドが追加され、現在の例外ハンドラーを取得できるようになった。
 - `timeout()`コンテキストマネージャによってタイムアウト処理のコードが簡単にかけるようになった。
 - `StreamReader.readuntil()`メソッドが追加され、セパレータバイトで句切られたストリームを読めるようになった。
 - `loop.getaddrinfo()`メソッドが改善され、アドレスが既に名前解決していれば、OS側の`getaddrinfo`を呼ばなくても良くなった。

asyncioはあまり使ったことが無かったが、この中で`run_coroutine_threadsafe()`を使ってみた。

```asyncio_test.py
import asyncio

@asyncio.coroutine
def wakeup(name, repeat):
    for i in range(repeat):
        yield from asyncio.sleep(1)
        print("{}/{}: 起きた！".format(name, i))
    return repeat

def target(name, repeat, loop):
    future = asyncio.run_coroutine_threadsafe(wakeup(name, repeat), loop)
    return future.result()

loop = asyncio.get_event_loop()

futures = [
    loop.run_in_executor(None, target, "A", 1, loop),
    loop.run_in_executor(None, target, "B", 2, loop),
    loop.run_in_executor(None, target, "C", 3, loop),
]

loop.run_until_complete(asyncio.wait(futures))
loop.close()

```

ちょっとややこしいが、`wakeup`というのが実行するコルーチン。1秒間寝た後に、`name`で与えられた名前を名乗って「起きた！」という行をPrintするだけ。それをもう一つの引数`repeat`の回数だけ繰り返す。そのコルーチンを実行するのが`target`という関数で、その中で`run_coroutine_threadsafe`を呼んでいる。それを別々のスレッドで実行するために、`run_in_executor`で実行している。

実行結果はこんなふうになるはず。

```
$ python asyncio_test.py
A/0: 起きた！
B/0: 起きた！
C/0: 起きた！
B/1: 起きた！
C/1: 起きた！
C/2: 起きた！
```

なお、上にも書いたようにこのasyncioの変更は3.5シリーズにもバックポートされ、実際もう3.5.1で実装されているようだ。実際、上の例も問題なく動く。

### contextlib
コンテキストマネージャの仮想ベースクラスとして`contextlib.AbstractContextManager`が追加され、`__enter__()`と`__exit__()`のデフォルト実装を提供するようになった。また、typingモジュールにも同様のクラスが追加された。

### venv
venvは新たに`--prompt`パラメータを受け取るようになった。これにより仮想環境時にコマンドラインプロンプトのprefixを変えられる。

### datetime
`datetime.strftime()`メソッドと`date.strftime()`メソッドがISO 8601の`%G`、`%u`、`%V`をサポートするようになった。%Gと%Vは週単位表記での年と週番号(01-53)を表し、%uは週の何番目かを表す(月曜日が1で日曜日が7)。

### distutils.command.sdist
default_format 属性は distutils.command.sdist.sdistから除去され、デフォルトの属性は['gztar']になった。想定外だが、この属性に依存したコードは全て修正されなければならない。

### email
policy引数の追加された新たなメールAPIが「provisional(暫定)」ではなくなり、ドキュメントもそれを中心に書き直された。従来のドキュメントはレガシーAPIとして残されている。

`email.mime`クラスや`DecodedGenerator`はpolicy引数を受け取るようになった。

policyオブジェクトに`message_factory`属性が追加され、パーサが新たなメッセージを生成する時にどのメッセージクラスを使うのか指定できるようになった。

### encodings
Windows環境上で、`CP_OEMCP`を使う`'oem'`が追加された。また、`CP_ACP`を使う`mbcs`に`ansi`というエイリアスが加えられた。

### faulthandler
Windows環境でWindows例外を発生させるハンドラーをインストールするようになった。

### hashlib
hashlibはOpenSSL 1.1.0をサポートした。推奨バージョンは1.0.2以上だが、 0.9.8zc、0.9.8zh、1.0.1t と LibreSSL 2.3、2.4でもテストされている。

BLAKE2ハッシュ関数のサポートが追加され、blake2b()、blake2s()が利用できるようになった。

SHA-3ハッシュ関数 sha3_224()、sha3_256()、sha3_384()、sha3_512() と SHAKEハッシュ関数 shake_128()、shake_256()が追加された。

パスワードベースの鍵導出関数 scrypt()がOpenSSL 1.1.0以上の場合に利用可能になった。

### http.client

HTTPConnection.request() と endheaders() がリクエストボディで chunked エンコーディングをサポートした。

### idlelibとIDLE
idlelibパッケージが今風にリファクタリングされIDLEの見た目や操作性・視認性が向上した。変更にはファイル名の変更も含まれ、3.5までのコードはそのままだと動かない。

### importlib
`importlib.util.LazyLoader`がラッパーローダーの上で`create_module()`を呼ぶようになったので`importlib.machinery.BuiltinImporter`と`importlib.machinery.ExtensionFileLoader`が`importlib.util.LazyLoader`と一緒に使えないという制約がなくなった。

`importlib.util.cache_from_source()`、`importlib.util.source_from_cache()`、`importlib.util.spec_from_file_location()`はパス風オブジェクトを受け取れるようになった。

### json
`json.load()`と`json.loads()`はバイナリを入力として受け取れるようになった。エンコードされたJSONはUTF-8、UTF-16、UTF-32のいずれかでエンコードされていなければならない。

### os
`close()`メソッドが提供され、`scandir()`のイタレーターを明示的に閉じれるようになった。そして、`scandir()`のイタレーターがコンテキストマネージャプロトコルをサポートするようになった。`scandir()`のイタレーターが使い切られていない、あるいは明示的に閉じられなかった場合には、`ResourceWarning`例外がデストラクタの中で発生する。これは、メモリリーク対策だと思うが、withステートメントと一緒に使えば自動で呼んでくれる。

Linuxの`getrandom()`システムコールは新たなos.getrandm()関数を介して利用可能になった。

### pickle
`__new__`をキーワード引数と共に呼ばなければならなかったオブジェクトの塩漬け(ピクル化)ができるようになった。これはpickle version 4以上であればこれまでもできていたが、今回の変更でversion 3以下でもできるようになったとのこと。

## re

正規表現にかかる修飾子が追加された。例えば`'(?i:p)ython'`は`'python'`と`'Python'`にはマッチするけど`'PYTHON'`にはマッチしない。同様に`'(?i)g(?-i:v)r'`は`'GvR'`や`'gvr'`にはマッチするけど`'GVR'`にはマッチしない。 

### readline
`set_auto_history()`が追加され、履歴への自動追加有無が制御できるようになった。

### rlcompleter
rlcompleterはreadlineのcompletion(補完機能)。ひとつ目の変更は、アンダースコア('_')で始まるモジュール変数・メソッド・属性を補完のリストから外したこと。と言っても分かりにくいので、例を。これまでは、Pythonを対話モードで立ち上げて、"int."と打ち込んだ後にTABキーを2回押すとこうなった

```
$ python
Python 3.5.2 (default, Jul  7 2016, 23:37:57)
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> int.<TAB><TAB>
int.__abs__(            int.__dir__(            int.__hash__(           int.__mul__(            int.__reduce__(         int.__rtruediv__(       int.__xor__(
int.__add__(            int.__divmod__(         int.__index__(          int.__name__            int.__reduce_ex__(      int.__rxor__(           int.bit_length(
int.__and__(            int.__doc__             int.__init__(           int.__ne__(             int.__repr__(           int.__setattr__(        int.conjugate(
int.__base__(           int.__eq__(             int.__instancecheck__(  int.__neg__(            int.__rfloordiv__(      int.__sizeof__(         int.denominator
int.__bases__           int.__flags__           int.__int__(            int.__new__(            int.__rlshift__(        int.__str__(            int.from_bytes(
int.__basicsize__       int.__float__(          int.__invert__(         int.__or__(             int.__rmod__(           int.__sub__(            int.imag
int.__bool__(           int.__floor__(          int.__itemsize__        int.__pos__(            int.__rmul__(           int.__subclasscheck__(  int.mro(
int.__call__(           int.__floordiv__(       int.__le__(             int.__pow__(            int.__ror__(            int.__subclasses__(     int.numerator
int.__ceil__(           int.__format__(         int.__lshift__(         int.__prepare__(        int.__round__(          int.__subclasshook__(   int.real
int.__class__(          int.__ge__(             int.__lt__(             int.__qualname__        int.__rpow__(           int.__text_signature__  int.to_bytes(
int.__delattr__(        int.__getattribute__(   int.__mod__(            int.__radd__(           int.__rrshift__(        int.__truediv__(
int.__dict__            int.__getnewargs__(     int.__module__          int.__rand__(           int.__rshift__(         int.__trunc__(
int.__dictoffset__      int.__gt__(             int.__mro__             int.__rdivmod__(        int.__rsub__(           int.__weakrefoffset__
>>> int.
```

これが、3.6からはこうなる。

```
ython 3.6.0a3 (default, Jul 16 2016, 00:35:58)
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> int.
int.bit_length(  int.conjugate(   int.denominator  int.from_bytes(  int.imag         int.mro(         int.numerator    int.real         int.to_bytes(
```

`_`から始まる名前が補完候補から外されている。それらを表示したければ、`_`を打ち込んでから`<TAB><TAB>`。

```
>>> int.__
int.__abs__(             int.__dict__             int.__getattribute__(    int.__lt__(              int.__prepare__(         int.__ror__(             int.__subclasscheck__(
int.__abstractmethods__  int.__dictoffset__       int.__getnewargs__(      int.__mod__(             int.__qualname__         int.__round__(           int.__subclasses__(
int.__add__(             int.__dir__(             int.__gt__(              int.__module__           int.__radd__(            int.__rpow__(            int.__subclasshook__(
int.__and__(             int.__divmod__(          int.__hash__(            int.__mro__              int.__rand__(            int.__rrshift__(         int.__text_signature__
int.__base__(            int.__doc__              int.__index__(           int.__mul__(             int.__rdivmod__(         int.__rshift__(          int.__truediv__(
int.__bases__            int.__eq__(              int.__init__(            int.__name__             int.__reduce__(          int.__rsub__(            int.__trunc__(
int.__basicsize__        int.__flags__            int.__instancecheck__(   int.__ne__(              int.__reduce_ex__(       int.__rtruediv__(        int.__weakrefoffset__
int.__bool__(            int.__float__(           int.__int__(             int.__neg__(             int.__repr__(            int.__rxor__(            int.__xor__(
int.__call__(            int.__floor__(           int.__invert__(          int.__new__(             int.__rfloordiv__(       int.__setattr__(
int.__ceil__(            int.__floordiv__(        int.__itemsize__         int.__or__(              int.__rlshift__(         int.__sizeof__(
int.__class__(           int.__format__(          int.__le__(              int.__pos__(             int.__rmod__(            int.__str__(
int.__delattr__(         int.__ge__(              int.__lshift__(          int.__pow__(             int.__rmul__(            int.__sub__(
>>> int.__
```

それから、幾つかのキーワードを補完した後にスペース(' ')かコロン(':')が付くようになった。例えば、`wi`と打ち込んで`<TAB>`を押すと`with `とスペース付きで補完されるし、`tr`と打ち込んだから`<TAB>`すると`try:`となる。地味に便利。

あと、これまで表示されなかった`@property`で作られた属性とかの補完ができるようになったともあるが、これはよく判らなかった。

### site
sys.pathにパスを追加する際に重複チェックしているが、それがうまく動かない場合の修正っぽい。

### sqlite3
`sqlite3.Cursor.lastrowid`は最後に変更した列の列IDを返すが、これまでINSERTを実行した時のみ有効だったが、REPLACEを実行した時にも取れるようになった。

### socket
`ioctl()`関数で`SIO_LOOPBACK_FAST_PATH`が使えるようになり、Windows環境(Win8以上)でTCP loopbackのパフォーマンスを向上させることができるようになった。

getsockopt()の定数`SO_DOMAIN`、`SO_PROTOCOL`、`SO_PEERSEC`、`and SO_PASSSEC`がサポートされた。

アドレスファミリー AF_ALGがサポートされ、LinuxカーネルのCrypto APIを利用できることになった。

### socketserver
socketserverモジュールに基づくサーバー(例えば`http.server`, `xmlrpc.server`や`wsgiref.simple_server`で定義されている)がコンテキストマネージャプロトコルをサポートするようになった。

`StreamRequestHandler`クラスの`wfile`属性が`io.BufferedIOBase`の`writable`インターフェイスを実装した。特に、`write()`はデータを全て送ることが保証されるようになった。

### ssl
sslはOpenSSL 1.1.0をサポートした。推奨バージョンは1.0.2以上だが、 0.9.8zc、0.9.8zh、1.0.1t と LibreSSL 2.3、2.4でもテストされている。

3DES はデフォルト暗号スイートから外された。また、ChaCha20 Poly1305 暗号スイートは正しい場所に置かれることになった。

SSLContextのデフォルトコンフィギュレーションはより良いオプションと暗号を使うようになった。

SSLセッションはクライアント側から相手側にSSLSessionを使ってコピーできるようになった。TLSセッションの再開が速度改善された。

全ての定数やフラグはIntEnumからIntFlagsへ変更された。

SSLContext作成時に引き渡すパラメータとして、Server-sideのみ、Client-sideのみのプロトコルが追加された。

サブジェクトの別名拡張領域にGeneralリソースIDを入れてもシステムエラーにならなくなった。

### subprocess
`subprocess.Popen`で作られた子プロセスが実行中にのPopenオブジェクトを消去しようとすると、`ResourceWarning`例外が起こるようになった。

### telnetlib
`Telnet`がコンテクストマネージャプロトコルを実装。

### tkinter
`tkinter.Variable`クラスに`trace_add()` `trace_remove()` `trace_info()`メソッドを追加し、Tclの古いAPIを使っていた実装を置き換えた。

### traceback
トレースバックの長い繰り返しは省略して表記されるようになった。例えば自己ループする関数を実行するとこのようになる。

```
>>> def f(): f()
...
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in f
  File "<stdin>", line 1, in f
  File "<stdin>", line 1, in f
  [Previous line repeated 995 more times]
RecursionError: maximum recursion depth exceeded
```


### typing
`contextlib.AbstractContextManager`の為の`typing.ContextManager`クラスが追加された(前述のとおり)。

### unicodedata
内部のデータベースが Unicode 9.0.0にアップグレードされた。

### unittest.mock
`Mock`クラスに`Mock.assert_called()`と`Mock.assert_called_once()`が追加され、mockオブジェクトが呼ばれたかどうかを確認できるようなった。

### urllib.request
HTTPリクエストがファイルか繰り返し可能なボディ(ただしバイトオブジェクトを除く)を持ちながら、Content-lengthヘッダが指定されなかった場合、これまではエラーになっていたが、Chunked転送エンコーディングを行って送出するようになった。

### urllib.robotparser
`RobotFileParser`が`Crawl-delay`拡張と`Request-rate`拡張をサポートするようになった。これらはrobots.txtでクローリング間隔の調整に使うものだ。
 - Crawl-delay: クローリングを始める前に待たなければならない時間(秒)
 - Request-rate: 一定時間内に要求できるページ数

### warnings
`warnings.warn_explicit()`関数に`source`パラメータが追加され、`ResourceWarning`を発生させたオブジェクトがわかるようになった。`source`属性は`warnings.WarningMessage`にも追加されている。

そして、ResourceWarningがあがる時にはtracemallocが使われ、消去対象のオブジェクトのメモリのトレースバックが取れるようになった。こんな例が挙げてある。

```example.py
import warnings

def func():
    return open(__file__)

f = func()
f = None
```

`func`関数の中でファイルをオープンし、その直後にそのファイルオブジェクトへの参照をNULLで上書きすることで切ってしまっている。これを実行するとこのようになる。

```
$ python -Wd -X tracemalloc=5 example.py
example.py:7: ResourceWarning: unclosed file <_io.TextIOWrapper name='example.py' mode='r' encoding='UTF-8'>
  f = None
Object allocated at (most recent call first):
  File "example.py", lineno 4
    return open(__file__)
  File "example.py", lineno 6
    f = func()
```

### winreg
Windows環境のレジストリを操作するwinregモジュールで64ビット整数のREG_QWORD型がサポートされた。

### winsound
Beep、MessageBeep、PlaySoundでキーワード引数を渡せるようになった。

### xmlrpc.client
Apache XML-RPC実装で新たに導入された数値型と`None`の非整列化(unmarshalling)をサポート

### zipfile
`ZipInfo.from_file()`というクラスメソッドが追加され、ZipInfoオブジェクトをファイル名を指定して作れるようになり、`ZipInfo.is_dir()`メソッドでそれがディレクトリであるかどうかを確認できるようになった。そして、`ZipFile.open()`はZIPファイルからデータを取り出すだけでなく、書き込みを行うためにも使えるようになった。

### zlib
`compress()`関数が`level`をキーワード引数として指定できるようになった。

### fileinput
`hook_encoded()`でファイルオープン時に使うエンコーディングだけでなく、エラーハンドラーも指定できるようになった。詳細は`open()`の`errors`パラメータを参照のこと。

## 最適化

- ASCIIデコーダは、エラーハンドラーが`surrogateescape` `ignore` `replace`の時に最大60倍速くなった。
- ASCIIとLatin1エンコーダは、エラーハンドラーが`surrogateescape`の時に最大3倍速くなった。
- UTF-8エンコーダは、エラーハンドラーが`ignore` `replace` `surrogateescape` `surrogatepass`の時に最大75倍速くなった。
- UTF-8デコーダは、エラーハンドラーが`ignore` `replace` `surrogateescape`の時に最大15倍速くなった。 
- bytes % args が最大2倍速くなった。
- bytearray % args が2.5倍から5倍速くなった。
- `bytes.fromhex()`と`bytearray.fromhex()`が2倍から3.5倍速くなった。
- `bytes.replace(b'', b'.')`と`bytearray.replace(b'', b'.')`が最大80%速くなった。
- PyMem_Malloc()ドメインのメモリ割り当てにCライブラリのmallocに代わってpymallocを使うようになった。pymallocは512バイト以下の短命のオブジェクト向けに最適化されていて、それよりも大きなブロックの確保にはmallocを使う。
- `pickle.load()`と`pickle.loads()`は大量の小さなオブジェクトをロードする際に最大10%速くなった。
- キーワード引数は位置引数を引き渡すよりもオーバーヘッドがあるが、Argument Clinic (CPythonのCコードの為のプリプロセッサ)を使った機能により、そのオーバーヘッドは大幅に削減された。
- globモジュール中のglob()とiglob()が最適化され、3から6倍速くなった。
- os.scandir()を使ったpathlibのglobbingを最適化し、1.5から4倍速くなった

## ビルドとC APIの変更
- PythonをビルドするのにC99をサポートしたツールチェーンが必要になった。
- CpythonをAndroid NDKでクロスコンパイルし、Android API レベル21以上で正常に動かすことができるようになった。Androidはまだ正式にサポートしているプラットフォームではないが、Androidエミュレータ上での標準テストスイートの実行結果は良好(16の失敗のみ)である。
- コンフィギュレーションフラグに`--with-optimization`が追加された。これを指定するとLTO(Link Time Optimization:リンク時最適化)とPGO(Profile-Guided Optimization:プロファイルに基づく最適化)ビルドサポートが有効になる。
- `Py_FinalizeEx()` APIが導入され、インタープリターの終了処理が成功したかどうか(終了処理中にエラーがあったかどうか)が判るようになった。
- `PyArg_ParseTupleAndKeywords()`が位置専用引数のサポートを行うようになった。
- `PyTrackback_Print`は長い繰り返しを省略して表示するようになった。

## 廃止候補

### 廃止予定のビルドオプション
`--with-system-ffi`オプションはOSX以外のプラットフォームではデフォルトで有効になった。`--without-system-ffi`で無効にすることはできるが、このフラグの使用はPython 3.7以降できなくなる。OSXはこの変更の影響を受けない。

### 新たなキーワード

`async`と`await`を変数名、クラス名、関数名、モジュール名として使うことは非推奨となった。[PEP-492](https://www.python.org/dev/peps/pep-0492)によってPython3.5で導入された`async`と`await`はPython 3.7で正式なキーワードになる予定。

### 廃止予定のPythonモジュール、関数、メソッド
- importlib.machinery.SourceFileLoader.load_module() importlib.machinery.SourcelessFileLoader.load_module()は廃止予定となった。
- tkinter.tixモジュールは廃止予定となった。代りにtkinter.ttkを使うべし。

### 廃止予定のC APIの関数および型
- (今のところなし)

### 廃止予定の機能
- `pyvenv`スクリプトは廃止予定。代りに`python3 -m venv`の仕様が推奨される
- 相対インポートを行うときに`__spec__`あるいは`__package__`が定義されていないとImportWarning例外を起きるようになった。
- `dbm.dumb`モジュールは常にアップデート可の状態でオープンされ、存在しなければ作成されていた。他のdbmの実装と合わせるためにこの動作は廃止予定とされ、Python 3.8で利用不可となる。
- 幾つかのモジュールでパスとして使われていたバイト風オブジェクトの利用は廃止予定となった。
- disutilsの`extra_path`は廃止予定となった。
- バックスラッシュと文字の組み合わせで正しいエスケープシーケンスになっていない場合にはDeprecationWarningを起こすことになった。将来的には文法エラーになるが暫くはこのまま。
- インラインフラグ`(?letters)`は正規表現の先頭でのみ使えることとなった。
- SSL関連の`certfile`、`keyfile`、`check_hostname`のような引数は、ftplib、http.client、imaplib、poplib、smtplibなどで使われているがそれは廃止予定となった。代りに`context`を使うことが期待される。
- sslモジュール内の幾つかのプロトコルや関数が廃止予定となった。将来のOpenSSLでなくなるものや、他の代替手段が提供されたものなど。

### 廃止予定のPythonの動作
- ジェネレータ内でStopIterationをあげるとDeprecationWarningがあがる様になった。3.7からはこれがRuntimeErrorとなる。

## 削除済み
### APIと機能の削除
- `inspect.getmoduleinfo()`は削除された。あるパスのモジュール名を知るには`inspect.getmodulename()`を使う。 
- `traceback.Ignore`クラスと`traceback.usage` `traceback.modname` `traceback.fullmodname` `traceback.find_lines_from_code` `traceback.find_lines` `traceback.find_strings` `traceback.find_executable_lines`メソッドはtracebackモジュールから消去された。これらは3.2から廃止候補でプライベートメソッドで同様の機能は提供されている。
- `tk_menuBar()` `tk_bindForTraversal()`ダミーメソッドはtkinterウィジェットクラスから消去された。
- `zipfile.ZipFile`クラスの`open()`メソッドは、'U'モードのサポートを廃止。代替として`io.TextIOWrapper`を圧縮ファイルの読み込みに使うべし。

## Python 3.6へのポーティングに際して
ここでは、あなたのコードをPython3.6へポーティングする際に気をつけるべきことを列挙する。

### Pythonコマンドの動作
- `COUNT_ALLOCS` `SHOW_ALLOC_COUNT` `SHOW_TRACK_COUNT`マクロを定義してビルドしたPythonの出力はデフォルトでオフになった。これをオンにするには　`-X showalloccount`を引数に追加してPythonを起動すると良い。また出力先はstdoutからstderrになった。

### Python APIの変更
- (ちょっと細かいので割愛)

### C APIの変更
- `PyMem_Malloc()`メモリ割り当てはシステムのmalocではなく、pymallocを使うようになったので、GILを取らずに`PyMem_Malloc()`を呼ぶアプリはクラッシュするようになる。`PYTHONMALLOC`環境変数を`debug`にすればメモリ割り当てが確認できる。
- `Py_Exit()`(とメインのインタープリター)は終了時のメモリ解放に失敗すると120を返すようになった。

# 最後に
ざっと変更点を見るつもりだったが、見ているうちに色々と興味深い点が出てきて、思ったよりも時間がかかってしまった。今現在、b1でこれ以上の変更は定義上はないので、タイトルから"(α3版)"を消した。3.6のfinalが12月中旬の予定なのでもしかするとまた変更が入るかもしれないが、適宜アップデートしていこう。