Python

【エラー】gsutil TypeError: cannot pickle '_io.TextIOWrapper' object

2020-09-23

【エラー】gsutil TypeError: cannot pickle '_io.TextIOWrapper' object

コマンドラインからGoogle Cloud Storage (GCS) を操作することができる gsutil パッケージ。

GCSからファイルをコピーする際に gsutil cp コマンドを使うのだが、複数ファイルの場合直列に処理すると遅い。
そこで並列に処理するために gsutil -m cp を実行したら以下のエラーが発生した。

gsutil TypeError: cannot pickle '_io.TextIOWrapper' object

一体何が間違っているのだろうか。

今回はこの gsutil TypeError: cannot pickle '_io.TextIOWrapper' object のエラー原因と対処法について解説する。

この記事を書いている人


システムエンジニア、AIエンジニアと、IT業界で10年以上働いている中堅。PythonとSQLが得意。最近GCP環境を習得中。

記事を読むメリット

  • gsutil TypeError: cannot pickle '_io.TextIOWrapper' object の原因と解決方法がわかる

  • エラー内容

    現象としては gsutil cp で順番に1つずつコピーはできるが、並列に処理する gsutil -m cp ではエラーになる。


    エラー内容を知るために今一度エラーメッセージを見てみる。

    gsutil TypeError: cannot pickle '_io.TextIOWrapper' object
    

    まず TypeError なので変数の型が合っていない

    そして cannot pickle 以下のメッセージは _io.TextIOWrapper 形式のオブジェクトをpicle、つまり変数のままファイル出力できないと言っている。

    なんで -m つけたときだけエラーになるのか
    型のエラーなら -m つけてない直列処理でも起こりそうなものですけど


    エラー原因

    gsutil TypeError: cannot pickle '_io.TextIOWrapper' object の根本原因、それはPythonのバージョン

    実はこのエラーPython3.8からMacOS上での動作が一部変わった事に起因している。

    Tracking this down, this error comes from a change in Python 3.8 in the multiprocessing library:

    Changed in version 3.8: On macOS, the spawn start method is now the default. The fork start method should be considered unsafe as it can lead to crashes of the subprocess. See bpo-33725.

    Spawn is being run for those using MacOs and Python 3.8+ by default since nothing is explicitly set either through get_context or set_start_method.

    これはわかんないわ
    ↑の英語の情報も、エラーメッセージでググってたどり着いたので、エラー情報をネット上で共有するのって大事だと思いますわ。



    エラーの解決方法

    gsutil TypeError: cannot pickle '_io.TextIOWrapper' object の原因はPythonのバージョン
    であれば解決方法はPythonのバージョンを変更する

    具体的にはPython3.8ではなくPython3.7系を使えばこのエラーは出ない


    そしてPython3.7のインストール方法だが、Linux環境にPythonをインストールする方法と変わらない

    pyenvをインストールして、pyenvを使ってPython3.7をインストールし、最後にPython3.7をデフォルトにするだけだ。

    注意点があるとすればMacOSの現在のデフォルトシェルはbashではなくzshである点
    pyenvインストール後の環境変数の設定をzsh用にするか、もしくはデフォルトの起動シェルをbashに変更するかする必要がある。

    完全に一緒ではないんだね
    うん。
    自分でやるときも「Linuxと同じだなぁ」と思いながら作業してたけど、pyenvインストール後に zsh:command not found が出て、「あれ?pyenv動かないぞ?」ってなりましたもん。
    まぁターミナルの起動シェルをzshからbashにして事なきを得ましたけど



    【エラー】gsutil TypeError: cannot pickle '_io.TextIOWrapper' object まとめ

    gsutil TypeError: cannot pickle '_io.TextIOWrapper' object の原因は Python3.8からMacOSでの挙動が少し変わったから

    解決方法はPython3.8の代わりに3.7を使う

    原因がわかれば簡単だったね
    いやぁ、ググって見つかるエラーで良かったですわ



    ちなみにMacのターミナルの起動シェルをzshからbashに変える方法については以下にまとめたので、もし興味があれば見てみてほしい。

    ITipsと同じようなブログを作る方法

    ブログに興味がありますか?

    もしブログに興味がある場合は↓このページ↓を参考にすれば、ITipsと同じ構成でブログを作ることができます

    サーバー、ドメイン、ASPと【ブログに必要なものは全て】このページに書きました。
    同じ構成でブログ作るのはいいけど、記事はマネしないでネ (TДT;)

    ランキング参加中

    にほんブログ村 IT技術ブログへ

    他にもブログやSNSで紹介してくれると励みになります。

    はてブのコメントで酷評されると泣きます(´;ω;`)

    -Python
    -, , , ,

    © 2024 ITips