実行できる Python 標準ライブラリ

[KLab Engineer Advent Calendar 2021](https://qiita.com/advent-calendar/2021/klab) の 6 日目

`python -m` オプション。 これはライブラリを直接実行するためのオプションです。これでもって標準ライブラリを実行したときこれらがどのように動作するのかを紹介します。便利なもの、どのような動きをするのか想像できないものなど、さまざまで確認していて楽しかったです。

Python 3.10 で確認しています。なお、これらの動作は公式ドキュメントに記載がないもの、単体テスト用途と思われるものが混じっています。それらについて将来のバージョンで同じ動作をし続けるかどうかの保証はありません。

## [this](https://www.python.org/dev/peps/pep-0020/)
[The Zen of Python](https://www.python.org/dev/peps/pep-0020/) を表示するイースターエッグです。インタラクティブシェルに `import this` と打ち込むことで読むことができる、と紹介されることが多いライブラリですが、 `python -m this` でも読むことが可能です。

## [asyncio](https://docs.python.org/ja/3/library/asyncio.html)
await 文が使用できるインタラクティブシェルを立ち上げます。 [IPython](https://ipython.org/) などの高度なシェルが入っていない環境でも asyncio を試したい、というときに使えます。

```
$ python -m asyncio
asyncio REPL 3.10.0 (tags/v3.10.0:b494f5935c, Oct  5 2021, 23:50:57) [GCC 9.3.0] on linux
Use "await" directly instead of "asyncio.run()".
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio
>>> await asyncio.sleep(7)
```

## [venv](https://docs.python.org/ja/3/library/venv.html)
Python 仮想環境を構築します。公式ドキュメント冒頭には -m オプションで使う使い方が書かれており `import venv` とコードに書く使い方をした人のほうがすくないのではないでしょうか。

```
$ python3 -m venv /path/to/new/virtual/environment
```

## [dis](https://docs.python.org/ja/3/library/dis.html)
Python コードを渡すと dis.dis を用いて Python コードをディスアセンブリしてその結果を出力します。

```
$ cat hello.py
print('Hello, World!')
$ python -m dis hello.py
  1           0 LOAD_NAME                0 (print)
              2 LOAD_CONST               0 ('Hello, World!')
              4 CALL_FUNCTION            1
              6 POP_TOP
              8 LOAD_CONST               1 (None)
             10 RETURN_VALUE
```


## [calendar](https://docs.python.org/ja/3/library/calendar.html)
カレンダー出力を行うライブラリです。これを実行すると cal コマンドが生成するような text もしくは XHTML 1.0 形式でカレンダーを作ることができます。

```
$ python -m calendar 2021 12
   December 2021
Mo Tu We Th Fr Sa Su
       1  2  3  4  5
 6  7  8  9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
```

## [webbrowser](https://docs.python.org/ja/3/library/webbrowser.html)
ブラウザを立ち上げて渡された URL を開きます。 webbrowser を直接実行する用法はドキュメントに記載があり、今後も使えるものと思われます。

```
$ python -m webbrowser
Usage: C:\Users\fgshu\AppData\Local\Programs\Python\Python310\lib\webbrowser.py [-n | -t] url
    -n: open new window
    -t: open new tab

$ python -m webbrowser -t "https://qiita.com/advent-calendar/2021/klab"    
```

## [http.server](https://docs.python.org/ja/3/library/http.server.html)
簡易 HTTP サーバーが立ち上がります。テスト目的でブラウザになにか表示したいときには使えるかもしれません。

```
$ python -m http.server --help
usage: server.py [-h] [--cgi] [--bind ADDRESS] [--directory DIRECTORY] [port]

positional arguments:
  port                  Specify alternate port [default: 8000]

options:
  -h, --help            show this help message and exit
  --cgi                 Run as CGI Server
  --bind ADDRESS, -b ADDRESS
                        Specify alternate bind address [default: all interfaces]
  --directory DIRECTORY, -d DIRECTORY
                        Specify alternative directory [default:current directory]
```

## [pickle](https://docs.python.org/ja/3/library/pickle.html)
pickle は Python オブジェクトをそのままシリアライズできるライブラリです。これを用いて作られた pickle 形式のファイルを渡して実行すると、その内容を出力してくれます。

```
$ python -c "import pickle; pickle.dump('spam', open('spam.pickle', 'wb'))"
$ python -m pickle spam.pickle
'spam'
```

出力には [pprint.pprint](https://docs.python.org/ja/3/library/pprint.html#pprint.pprint) が使われるので入り組んだコンテナオブジェクトでも読みやすく整形されます。

## [zipfile](https://docs.python.org/ja/3/library/zipfile.html)
zipfile は ZIP アーカイブを操作するためのライブラリです。これは zip, unzip コマンドのように動作します。 `python -m zipfile -e spam.zip` で　ZIP アーカイブの内容を展開することができます。これで unzip コマンドがなくても安心？

```
$ python -m zipfile --help
usage: zipfile.py [-h] (-l <zipfile> | -e <zipfile> <output_dir> | -c <name> [<file> ...] | -t <zipfile>)

A simple command-line interface for zipfile module.

options:
  -h, --help            show this help message and exit
  -l <zipfile>, --list <zipfile>
                        Show listing of a zipfile
  -e <zipfile> <output_dir>, --extract <zipfile> <output_dir>
                        Extract zipfile into target dir
  -c <name> [<file> ...], --create <name> [<file> ...]
                        Create zipfile from sources
  -t <zipfile>, --test <zipfile>
                        Test if a zipfile is valid
```

## [tarfile](https://docs.python.org/ja/3/library/tarfile.html)
tarfile は tar アーカイブを操作するためのライブラリです。これは tar コマンドのように動作します。 `python -m tarfile -c spam.tar spam.txt ham.txt eggs.txt` として tar アーカイブ spam.tar を作成することができます。 tar コマンドがなくても安心？ とおもいきや、圧縮形式各種に対応していない、 2021 年現在 Windows にすら `tar.exe` が存在するなとといったことから出番は少なそうです。

```
$ python -m tarfile --help
usage: tarfile.py [-h] [-v]
                  (-l <tarfile> | -e <tarfile> [<output_dir> ...] | -c <name> [<file> ...] | -t <tarfile>)        

A simple command-line interface for tarfile module.

options:
  -h, --help            show this help message and exit
  -v, --verbose         Verbose output
  -l <tarfile>, --list <tarfile>
                        Show listing of a tarfile
  -e <tarfile> [<output_dir> ...], --extract <tarfile> [<output_dir> ...]
                        Extract tarfile into target dir
  -c <name> [<file> ...], --create <name> [<file> ...]
                        Create tarfile from sources
  -t <tarfile>, --test <tarfile>
                        Test if a tarfile is valid
```

## [gzip](https://docs.python.org/ja/3/library/gzip.html)
gzip は gzip 形式のファイルを操作するライブラリです。これは gzip, gunzip コマンドのように動作します。なお、 [bz2](https://docs.python.org/ja/3/library/bz2.html) や [lzma](https://docs.python.org/ja/3/library/lzma.html) も同様に動きそうな気がしますがこれらは直接実行しても何も起こりません。

```
$ python -m gzip --help   
usage: gzip.py [-h] [--fast | --best | -d] [file ...]

A simple command line interface for the gzip module: act like gzip, but do not delete the input file.

positional arguments:
  file

options:
  -h, --help        show this help message and exit
  --fast            compress faster
  --best            compress better
  -d, --decompress  act like gunzip instead of gzip
```

## [base64](https://docs.python.org/ja/3/library/base64.html)
ファイルもしくは標準入力からうけとったデータを base64 形式でエンコードもしくはデコードすることができます。

```
$ python -m base64 -h
option -h not recognized
usage: C:\Users\fgshu\AppData\Local\Programs\Python\Python310\lib\base64.py [-d|-e|-u|-t] [file|-]
        -d, -u: decode
        -e: encode (default)
        -t: encode and decode string 'Aladdin:open sesame'

$ echo spam | python -m base64
C38hbQo=
```

[quopri](https://docs.python.org/ja/3/library/quopri.html) ライブラリ、 [uu](https://docs.python.org/ja/3/library/uu.html) ライブラリも同様の使い方が可能です。

## [zipapp](https://docs.python.org/ja/3/library/zipapp.html)
Python から直接実行できて zip 圧縮されている .pyz ファイルを作成します。

## [timeit](https://docs.python.org/ja/3/library/timeit.html)
Python ベンチマークである timeit は -m オプションで直接実行するのが使い方の一つです。公式ドキュメント冒頭にこの使い方が書かれています。

## [pdb](https://docs.python.org/ja/3/library/pdb.html)
Python デバッガです。 -m オプションで直接実行するのが使い方の一つです。

## [trace](https://docs.python.org/ja/3/library/trace.html)
Python 実行の様子を追跡する trace ライブラリは -m オプションで直接実行するのが使い方の一つです。

## [ast](https://docs.python.org/ja/3/library/ast.html)
Python コードの抽象構文木を確認できるライブラリ ast は Python 3.9 より -m での直接実行をサポートし始めました。

## [doctest](https://docs.python.org/ja/3/library/doctest.html)
可読かつ動かせるテストを作る doctest 。これを動かす方法の一つは -m で直接実行するというものです。

## [pydoc](https://docs.python.org/ja/3/library/index.html)
Python コードの docstring から説明文を生成します。インタラクティブシェルで help() を呼び出したときによむことができるテキストと同等のものが得られます。また、 -p ポート番号とすることで HTTP サーバーが立ち上がります。


# テストやデモンストレーションが行われるライブラリ

## [aifc](https://docs.python.org/ja/3/library/aifc.html)
AIFF オーディオファイルの情報を表示します。

## [cgi](https://docs.python.org/ja/3/library/cgi.html)
HTML 形式で環境変数などを出力します。

## [dbm](https://docs.python.org/ja/3/library/dbm.html)
[whichdb](https://docs.python.org/ja/3/library/dbm.html#dbm.whichdb) でファイルフォーマットを推測します。

## [ensurepip](https://docs.python.org/ja/3/library/ensurepip.html)
[pip] (https://pip.pypa.io/en/stable/) をインストールします。あえて実行しなくとも通常インストール済みのものです。

## [filecmp](https://docs.python.org/ja/3/library/filecmp.html)
[dircmp](https://docs.python.org/ja/3/library/filecmp.html#filecmp.dircmp) で二つのディレクトリを比較します。

## [fileinput](https://docs.python.org/ja/3/library/fileinput.html)
ファイルをひとつなぎにしつつ、どのファイル由来の行か、何行目かを出力します。

## [ftplib](https://docs.python.org/ja/3/library/ftplib.html)
簡易 FTP クライアントが立ち上がります。

## [getopt](https://docs.python.org/ja/3/library/getopt.html)
`print(getopt(sys.argv[1:], "a:b", ["alpha=", "beta"]))` が実行されます。

```
$ python -m getopt -a spam ham eggs
([('-a', 'spam')], ['ham', 'eggs'])
```

## [heapq](https://docs.python.org/ja/3/library/heapq.html)
doctest を自身に対して実行します。

## [imaplib](https://docs.python.org/ja/3/library/imaplib.html)
IMAP4 サーバを指定すると接続テストを行います。

## [imghdr](https://docs.python.org/ja/3/library/imghdr.html)
カレントディレクトリの画像ファイルの形式を推測します。

## [locale](https://docs.python.org/ja/3/library/locale.html)
getdefaultlocale, resetlocale, setlocale(LC_ALL, "") の動作確認を行います。

## [mailcap](https://docs.python.org/ja/3/library/mailcap.html)
[mailcap.getcaps()](https://docs.python.org/ja/3/library/mailcap.html#mailcap.getcaps) 他を実行します。

## [netrc](https://docs.python.org/ja/3/library/netrc.html)
[netrc()](https://docs.python.org/ja/3/library/netrc.html#netrc.netrc) を実行します。

## [nntplib](https://docs.python.org/ja/3/library/nntplib.html)
nntplib を用いてネットニュースを読むデモが実行されます。

```
> py -m nntplib -h
usage: nntplib.py [-h] [-g GROUP] [-s SERVER] [-p PORT] [-n NB_ARTICLES] [-S]

nntplib built-in demo - display the latest articles in a newsgroup

options:
  -h, --help            show this help message and exit
  -g GROUP, --group GROUP
                        group to fetch messages from (default: gmane.comp.python.general)
  -s SERVER, --server SERVER
                        NNTP server hostname (default: news.gmane.io)
  -p PORT, --port PORT  NNTP port number (default: 119 / 563)
  -n NB_ARTICLES, --nb-articles NB_ARTICLES
                        number of articles to fetch (default: 10)
  -S, --ssl             use NNTP over SSL
```
## [platform](https://docs.python.org/ja/3/library/platform.html)
[platform.platform](https://docs.python.org/ja/3/library/platform.html#platform.platform) を実行します。

```
> py -m platform --terse
Windows-10

$ python -m platform --terse
Linux-5.4.0.89-generic-x86_64-with-glibc2.29
```

## [pprint](https://docs.python.org/ja/3/library/pprint.html)
pformat 関数ほかのベンチマークを実行します。

## [poplib](https://docs.python.org/ja/3/library/poplib.html)
host, user, password の 3 引数をうけとり POP3 で受信します。

## [random](https://docs.python.org/ja/3/library/random.html)
random ほかのベンチマークを実行します。

## [shlex](https://docs.python.org/ja/3/library/shlex.html)
shlex, gettoken をファイルもしくは標準入力に対して実行することで字句解析器 shlex の動作の様子を確認することができます。

## [smtplib](https://docs.python.org/ja/3/library/smtplib.html)
localhost へメールの送信を試みます。

## [sndhdr](https://docs.python.org/ja/3/library/sndhdr.html)
カレントディレクトリの音声ファイルの形式を推測します。

## [telnetlib](https://docs.python.org/ja/3/library/telnetlib.html)
簡易 Telnet クライアントが立ち上がります。

## [test](https://docs.python.org/ja/3/library/test.html)
Python そのものに対する regression test が実行されます。

```
$ python -m test --help
usage: python -m test [options] [test_name1 [test_name2 ...]]
python path/to/Lib/test/regrtest.py [options] [test_name1 [test_name2 ...]]

Run Python regression tests.

(オプション多数のため省略。ぜひ、動かしてみてください。)
```

## [textwrap](https://docs.python.org/ja/3/library/textwrap.html)
`print(dedent("Hello there.\n  This is indented."))` が実行されます。

## [tkinter](https://docs.python.org/ja/3/library/tkinter.html)
Tcl/Tk のバージョンが書かれたウィンドウが開きます。

## [turtle](https://docs.python.org/ja/3/library/turtle.html)
タートルグラフィックスのデモが 2 つ実行されます。見てて楽しいです。