"tempfile" --- 一時ファイルやディレクトリの作成
***********************************************

**ソースコード:** Lib/tempfile.py

======================================================================

このモジュールは一時ファイルやディレクトリを作成します。 サポートされ
ている全てのプラットフォームで動作します。 "TemporaryFile"、
"NamedTemporaryFile"、"TemporaryDirectory"、 "SpooledTemporaryFile" は
自動的に後始末をし、*context managers コンテキストマネージャ* として使
うことの出来る高水準のインターフェイスです。 "mkstemp()" と
"mkdtemp()" は手動で後始末をしなければならない低水準の関数です。

ユーザが呼び出し可能な全ての関数とコンストラクタは追加の引数を受け取り
ます。 その引数によって一時ファイルやディレクトリの場所と名前を直接操
作することが出来ます。 このモジュールに使用されるファイル名はランダム
な文字を含みます。そのためファイルは共有された一時ディレクトリに安全に
作成されます。 後方互換性を保つために引数の順序は若干奇妙です。 分かり
やすさのためにキーワード引数を使用してください。

このモジュールではユーザが呼び出し可能な以下の項目を定義しています:

tempfile.TemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None)

   一時的な記憶領域として使うことの出来る *file-like object* を返しま
   す。 ファイルは "mkstemp()" と同じルールにより安全に作成されます。
   オブジェクトは閉じられる (オブジェクトのガベージコレクションによる
   暗黙的なものも含みます) とすぐに破壊されます。 Unix では、そのファ
   イルのディレクトリエントリは全く作成されないか、ファイル作成後すぐ
   に削除されます。 これは他のプラットフォームではサポートされません。
   よって、この関数で作成された一時ファイルがファイルシステムで可視な
   名前を持つかどうかをコードで当てにすべきではありません。

   返されたオブジェクトを *コンテキストマネージャ* として使うことがで
   きます （使用例 を参照してください）。 コンテキストの完了やファイル
   オブジェクトの破壊で、一時ファイルはファイルシステムから削除されま
   す。

   作成されたファイルを閉じることなく読み書きできるように、 *mode* 引
   数のデフォルトは "'w+b'" です。 保存されるデータに関わらず全てのプ
   ラットフォーム上で一貫して動作するようにバイナリモードが使用されま
   す。 *buffering*、*encoding*、*errors*、*newline* は、 "open()" に
   対する引数として解釈されます。

   *dir*、*prefix*、*suffix* 引数の意味とデフォルトは "mkstemp()" のも
   のと同じです。

   返されたオブジェクトは、POSIXプラットフォームでは本物のファイルオブ
   ジェクトです。 それ以外のプラットフォームでは、"file" 属性が下層の
   本物のファイルであるファイル様オブジェクトです。

   "os.O_TMPFILE" フラグは、利用可能で動作する場合に用いられます
   (Linux 固有で、Linux kernel 3.11 以降)。

   プラットフォームが Posix でも Cygwin でもない場合は、TemporaryFile
   は NamedTemporaryFile の別名です。

   引数 "fullpath" を指定して 監査イベント "tempfile.mkstemp" を送出し
   ます。

   バージョン 3.5 で変更: 利用可能であれば "os.O_TMPFILE" フラグが使用
   されます。

   バージョン 3.8 で変更: *errors* 引数が追加されました。

tempfile.NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True, *, errors=None, delete_on_close=True)

   以下の点を除き、"TemporaryFile()" と同じように動作します:

   * 返されるファイルには、ファイルシステム上で見える名前が必ずありま
     す。

   * 名前付きファイルを管理するために、"TemporaryFile()" の引数に
     *delete* と *delete_on_close* を追加しています。 これらは、名前付
     きファイルを自動で削除するかどうかと、その方法を指定します。

   戻り値は常に *ファイル類似オブジェクト* で、その "file" 属性が基と
   なる実際のファイルオブジェクトです。 通常のファイルと同じように
   "with" 文で使えます。 一時ファイルの名前は、返されたファイル類似オ
   ブジェクトの "name" 属性から取得できます。 Unix では
   "TemporaryFile()" と異なり、ファイルの作成直後にディレクトリエント
   リが削除されることはありません。

   *delete* が真 (デフォルト) で *delete_on_close* も真 (デフォルト)
   の場合、ファイルを閉じるとすぐに削除します。 *delete* が真で
   *delete_on_close* が偽の場合は、コンテキストマネージャーを終了する
   とき、または *ファイル類似オブジェクト* をファイナライズするときに
   削除します。 この場合、削除は常に保証されるわけではありません
   ("object.__del__()" を参照)。 *delete* が偽の場合、
   *delete_on_close* の値は無視します。

   したがって、一時ファイルを閉じた後で、その名前を使って再び開くには
   、閉じる際に削除しないようにする (*delete* 引数を偽にする) か、
   "with" 文で一時ファイルを作成する場合は *delete_on_close* 引数を偽
   にしてください。 後者ではコンテキストマネージャーの終了時に一時ファ
   イルの自動クリーンアップが行われるため、この方法を推奨します。

   一時ファイルを開いたまま、その名前を使って再び開く場合の動作は次の
   とおりです:

   * POSIX では常に再び開けます。

   * Windows では、次の条件のうち少なくとも 1 つを満たす必要があります
     :

     * *delete* が偽である

     * 追加のオープンが削除アクセスを共有する (例えば、"O_TEMPORARY"
       フラグを指定して "os.open()" を呼び出す)

     * *delete* が真で *delete_on_close* が偽である。 ただし、この場合
       は、削除アクセスを共有せずに追加で開いたファイル (例えば、組み
       込み関数 "open()" で開いたもの) を、コンテキストマネージャーを
       終了する前に閉じる必要があります。 そうしないと、終了時の
       "os.unlink()" 呼び出しが "PermissionError" で失敗します。

   Windows では、*delete_on_close* が偽で、ユーザーに削除アクセス権の
   ないディレクトリにファイルを作成した場合、 コンテキストマネージャー
   の終了時の "os.unlink()" 呼び出しが "PermissionError" で失敗します
   。 *delete_on_close* が真の場合は、ファイルを開く際に削除アクセスを
   要求し、それが許可されなければ直ちに失敗するため、この問題は起こり
   ません。

   POSIX では、SIGKILL で突然終了させられたプロセスは、作成した
   NamedTemporaryFile を自動的に削除できません。 これは POSIX に限った
   話です。

   引数 "fullpath" を指定して 監査イベント "tempfile.mkstemp" を送出し
   ます。

   バージョン 3.8 で変更: *errors* 引数が追加されました。

   バージョン 3.12 で変更: *delete_on_close* 引数が追加されました。

class tempfile.SpooledTemporaryFile(max_size=0, mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None)

   このクラスはファイルサイズが *max_size* を超えるかファイルの
   "fileno()" メソッドが呼ばれるまで、データがメモリにスプールされる点
   以外は "TemporaryFile()" と正確に同じことを行います。 上記条件を満
   たすと内容はディスクに書き込まれ、操作は "TemporaryFile()" と同様に
   進みます。

   rollover()

      この関数が返すファイルは、追加で1つのメソッド "rollover()" を持
      っています。このメソッドが呼ばれると、(サイズに関係なく)メモリか
      らディスクへのロールオーバーが実行されます。

   返されたオブジェクトはファイル様オブジェクトで、その "_file" 属性は
   (バイナリかテキスト *mode* が指定されたかどうかに依存して)
   "io.BytesIO" か "io.TextIOWrapper" オブジェクト、あるいは
   "rollover()" が呼ばれたかどうかに依存して本物のファイルオブジェクト
   になります。 このファイル様オブジェクトは、通常のファイルオブジェク
   トと同じように "with" 文中で使用することが出来ます。

   バージョン 3.3 で変更: truncate メソッドが *size* 引数を受け取るよ
   うになりました。

   バージョン 3.8 で変更: *errors* 引数が追加されました。

   バージョン 3.11 で変更: バイナリとテキストのどちらの *mode* を指定
   したかに応じて、抽象基底クラス "io.BufferedIOBase" または
   "io.TextIOBase" を完全に実装するようになりました。

class tempfile.TemporaryDirectory(suffix=None, prefix=None, dir=None, ignore_cleanup_errors=False, *, delete=True)

   このクラスは "mkdtemp()" と同じルールを使用して安全に一時ディレクト
   リを作成します。返されたオブジェクトは、*コンテキストマネージャ* と
   して使用することができます (使用例 を参照)。コンテキストの完了や一
   時ディレクトリオブジェクトを破壊すると、新規作成された一時ディレク
   トリとその中身はファイルシステムから削除されます。

   name

      ディレクトリ名は返されたオブジェクトの "name" 属性から取得できま
      す。返されたオブジェクトが *コンテキストマネージャ* として使用さ
      れた場合、 "name" は "with" 文内の "as" 節のターゲットがあればそ
      れに割り当てられます。

   cleanup()

      "cleanup()" メソッドを呼び出して、ディレクトリを明示的にクリーン
      アップできます。 *ignore_cleanup_errors* が真の場合、明示的また
      は暗黙のクリーンアップ中に処理されなかった例外 (Windows で開いた
      ファイルを削除する際の "PermissionError" など) を無視し、残りの
      項目も削除できる限り削除します。 そうでなければ、クリーンアップ
      が行われた文脈 ("cleanup()" の呼び出し、コンテキストマネージャー
      の終了、オブジェクトのガベージコレクション、インタープリタの終了
      ) でエラーを送出します。

   *delete* 引数を使うと、コンテキストの終了時にディレクトリツリーをク
   リーンアップしないようにできます。 コンテキストマネージャーが終了時
   の処理を無効にできるのは変わって見えるかもしれませんが、デバッグ中
   や、ほかのロジックに応じてクリーンアップを行うかどうかを決めたい場
   合に役立ちます。

   警告:

     クリーンアップ中にディレクトリツリーが変更された場合の安全性は保
     証されません。 ツリーの外部のファイルのアクセス権やファイルフラグ
     がリセットされることがあります。
     "shutil.rmtree.avoids_symlink_attacks" が偽のシステムでは、クリー
     ンアップ中にシンボリックリンクを操作すると、ツリーの外部のファイ
     ルが削除されることがあります。

   引数 "fullpath" を指定して 監査イベント "tempfile.mkdtemp" を送出し
   ます。

   Added in version 3.2.

   バージョン 3.10 で変更: *ignore_cleanup_errors* 引数が追加されまし
   た。

   バージョン 3.12 で変更: *delete* パラメータが追加されました。

tempfile.mkstemp(suffix=None, prefix=None, dir=None, text=False)

   可能な限り最も安全な手段で一時ファイルを生成します。 プラットフォー
   ムが "os.open()" の "os.O_EXCL" フラグを正しく実装している限り、フ
   ァイルの作成で競合が起こることはありません。 作成したユーザのユーザ
   ID からのみファイルを読み書き出来ます。 プラットフォームがファイル
   が実行可能かどうかを示す許可ビットを使用している場合、ファイルは誰
   からも実行不可です。

   このファイル記述子は 子プロセスに継承されません。

   "TemporaryFile()" と異なり、"mkstemp()" の利用者は、ファイル記述子
   を閉じる処理 (例えば "os.close()") と一時ファイルの削除 (例えば
   "os.remove()") を自分で行う必要があります。

   *suffix* が "None" でない場合、ファイル名はその接尾辞で終わります。
   そうでない場合、接尾辞はありません。 "mkstemp()" はファイル名と接尾
   辞の間にドットを追加しません。 必要であれば *suffix* の先頭につけて
   ください。

   *prefix* が "None" でない場合、ファイル名はその接頭辞で始まります。
   そうでない場合、デフォルトの接頭辞が使われます。 必要に応じ、デフォ
   ルトは "gettempprefix()" または "gettempprefixb()" の返り値です。

   *dir* が "None" でない場合、ファイルはそのディレクトリ下に作成され
   ます。 "None" の場合、デフォルトのディレクトリが使われます。デフォ
   ルトのディレクトリはプラットフォームに依存するリストから選ばれます
   が、アプリケーションのユーザは *TMPDIR*、*TEMP*、または *TMP* 環境
   変数を設定することでディレクトリの場所を管理することができます。そ
   のため、生成されるファイル名が、"os.popen()" で外部コマンドにクォー
   ティング無しで渡すことができるなどといった、扱いやすい性質を持つ保
   証はありません。

   *suffix*、*prefix*、*dir* のいずれかが "None" でない場合、それらは
   同じ型でなければなりません。 bytes の場合、返された名前は str でな
   はく bytes です。 他の挙動はデフォルトで返り値を bytes に強制的にし
   たい場合は "suffix=b''" を渡してください。

   *text* に真を指定した場合は、ファイルはテキストモードで開かれます。
   そうでない場合(デフォルト)は、ファイルはバイナリモードで開かれます
   。

   "mkstemp()" は開かれたファイルを扱うための OS レベルのハンドル
   ("os.open()" が返すものと同じ) とファイルの絶対パス名が順番に並んだ
   タプルを返します。

   引数 "fullpath" を指定して 監査イベント "tempfile.mkstemp" を送出し
   ます。

   バージョン 3.5 で変更: *suffix*、*prefix*、*dir* は bytes の返り値
   を得るために bytes で渡すことが出来ます。 それ以前は str のみ許され
   ていました。 適切なデフォルト値を使用するよう、*suffix* と *prefix*
   は "None" を受け入れ、デフォルトにするようになりました。

   バージョン 3.6 で変更: *dir* パラメタが *path-like object* を受け付
   けるようになりました。

tempfile.mkdtemp(suffix=None, prefix=None, dir=None)

   可能な限り安全な方法で一時ディレクトリを作成します。 ディレクトリの
   生成で競合は発生しません。 ディレクトリを作成したユーザ ID だけが、
   このディレクトリに対して内容を読み出したり、書き込んだり、検索した
   りすることができます。

   "mkdtemp()" のユーザは用済みになった時に一時ディレクトリとその中身
   を削除しなければなりません。

   *prefix*, *suffix*, *dir* 引数は "mkstemp()" 関数のものと同じです。

   "mkdtemp()" は新たに生成されたディレクトリの絶対パス名を返します。

   引数 "fullpath" を指定して 監査イベント "tempfile.mkdtemp" を送出し
   ます。

   バージョン 3.5 で変更: *suffix*、*prefix*、*dir* は bytes の返り値
   を得るために bytes で渡すことが出来ます。 それ以前は str のみ許され
   ていました。 適切なデフォルト値を使用するよう、*suffix* と *prefix*
   は "None" を受け入れ、デフォルトにするようになりました。

   バージョン 3.6 で変更: *dir* パラメタが *path-like object* を受け付
   けるようになりました。

   バージョン 3.12 で変更: *dir* が相対パスでも、"mkdtemp()" は常に絶
   対パスを返すようになりました。

tempfile.gettempdir()

   一時ファイルに用いられるディレクトリの名前を返します。 これはモジュ
   ール内の全ての関数の *dir* 引数のデフォルト値を定義します。

   Python は呼び出したユーザがファイルを作ることの出来るディレクトリを
   検索するのに標準的なリストを使用します。 そのリストは:

   1. 環境変数 "TMPDIR" で与えられているディレクトリ名。

   2. 環境変数 "TEMP" で与えられているディレクトリ名。

   3. 環境変数 "TMP" で与えられているディレクトリ名。

   4. プラットフォーム依存の場所:

      * Windows では "%USERPROFILE%\AppData\Local\Temp"、
        "%SYSTEMROOT%\Temp"、"C:\TEMP"、"C:\TMP"、"\TEMP"、"\TMP" の順
        。

      * その他の全てのプラットフォームでは、 "/tmp" 、 "/var/tmp" 、お
        よび "/usr/tmp" の順。

   5. 最後の手段として、現在の作業ディレクトリ。

   この検索の結果はキャッシュされます。以下の "tempdir" の記述を参照し
   てください。

   バージョン 3.10 で変更: 常に str を返すようになりました。 以前は
   "tempdir" が "None" でなければ、その型を問わず値を返していました。

tempfile.gettempdirb()

   "gettempdir()" と同じですが返り値は bytesです。

   Added in version 3.5.

tempfile.gettempprefix()

   一時ファイルを生成する際に使われるファイル名の接頭辞を返します。 こ
   れにはディレクトリ部は含まれません。

tempfile.gettempprefixb()

   "gettempprefix()" と同じですが返り値は bytes です。

   Added in version 3.5.

このモジュールは、"gettempdir()" が返す一時ファイル用ディレクトリの名
前をグローバル変数に格納します。 直接設定してディレクトリの選択処理を
上書きできますが、推奨しません。 このモジュールのすべての関数には、デ
ィレクトリを指定する *dir* 引数があります。 こちらを使う方法を推奨しま
す。 API 全体の動作を変えずに済むため、その変更を想定していないほかの
コードに影響を及ぼしません。

tempfile.tempdir

   この変数を "None" 以外に設定すると、このモジュールの関数の *dir* 引
   数のデフォルト値を、bytes または str という型も含めて指定します。 *
   パス類似オブジェクト* は指定できません。

   "tempdir" が (デフォルトの) "None" の場合、 "gettempprefix()" を除
   く上記のいずれかの関数を呼び出す際は常に "gettempdir()" で述べられ
   ているアルゴリズムによって初期化されます。

   注釈:

     "tempdir" を bytes の値に設定すると、厄介な副作用があることに注意
     してください。 str 型の "prefix"、"suffix"、"dir" 引数を明示的に
     指定しなかった場合、"mkstemp()" と "mkdtemp()" の戻り値のデフォル
     トの型が、全体として bytes に変わります。 この動作を期待したり、
     この動作に依存したりするコードは書かないでください。 この扱いづら
     い動作は、過去の実装との互換性のために維持されています。


使用例
======

"tempfile" モジュールの典型的な使い方をいくつか示します。

   >>> import tempfile

   # 一時ファイルを作成してデータを書き込む
   >>> fp = tempfile.TemporaryFile()
   >>> fp.write(b'Hello world!')
   # ファイルからデータを読み取る
   >>> fp.seek(0)
   >>> fp.read()
   b'Hello world!'
   # ファイルを閉じると削除される
   >>> fp.close()

   # コンテキストマネージャーを使って一時ファイルを作成する
   >>> with tempfile.TemporaryFile() as fp:
   ...     fp.write(b'Hello world!')
   ...     fp.seek(0)
   ...     fp.read()
   b'Hello world!'
   >>>
   # ファイルは閉じられ、削除されている

   # コンテキストマネージャーを使って一時ファイルを作成する
   # ファイルを閉じ、名前を使って再び開く
   >>> with tempfile.NamedTemporaryFile(delete_on_close=False) as fp:
   ...     fp.write(b'Hello world!')
   ...     fp.close()
   ... # ファイルは閉じられているが、削除されていない
   ... # 名前を使ってファイルを再び開く
   ...     with open(fp.name, mode='rb') as f:
   ...         f.read()
   b'Hello world!'
   >>>
   # ファイルは削除されている

   # コンテキストマネージャーを使って一時ディレクトリを作成する
   >>> with tempfile.TemporaryDirectory() as tmpdirname:
   ...     print('created temporary directory', tmpdirname)
   >>>
   # ディレクトリとその内容は削除されている


非推奨の関数と変数
==================

一時ファイルを作成する歴史的な手法は、まず "mktemp()" 関数でファイル名
を作り、その名前を使ってファイルを作成するというものでした。 残念なが
らこの方法は安全ではありません。 なぜなら、"mktemp()" の呼び出しと最初
のプロセスが続いてファイル作成を試みる間に、異なるプロセスがその名前で
ファイルを同時に作成するかもしれないからです。 解決策は二つのステップ
を同時に行い、ファイルをすぐに作成するというものです。 この方法は
"mkstemp()" や上述している他の関数で使用されています。

tempfile.mktemp(suffix='', prefix='tmp', dir=None)

   バージョン 2.3 で非推奨: 代わりに "mkstemp()" を使って下さい。

   呼び出し時には存在しなかった、ファイルの絶対パス名を返します。
   *prefix*、*suffix*、*dir* 引数は "mkstemp()" のものと似ていますが、
   bytes のファイル名、"suffix=None"、そして "prefix=None" がサポート
   されていない点で異なります。

   警告:

     この関数を使うとプログラムのセキュリティホールになる可能性があり
     ます。この関数がファイル名を返した後、あなたがそのファイル名を使
     って次に何かをしようとする段階に至る前に、誰か他の人間があなたを
     出し抜くことができてしまいます。 "mktemp()" の利用は、
     "NamedTemporaryFile()" に "delete=False" 引数を渡すことで、簡単に
     置き換えることができます:

        >>> f = NamedTemporaryFile(delete=False)
        >>> f.name
        '/tmp/tmptjujjt'
        >>> f.write(b"Hello World!\n")
        13
        >>> f.close()
        >>> os.unlink(f.name)
        >>> os.path.exists(f.name)
        False
