Python

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

【エラー】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に変える方法については以下にまとめたので、もし興味があれば見てみてほしい。

    コチラもオススメ

    KRSW

    駆け出し機械学習エンジニア。機械学習、DB、WEBと浅く広い感じ。 Junior machine learning engineer. Not a specialist but a generalist who knows DB, WEB too.

    役に立ったらシェアしてくれると励みになります。

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

    -Python
    -, , ,

    Translate »

    Copyright© ITips , 2020 All Rights Reserved.