Python プログラミング Anaconda3 再起動後、なぜか Spyder が起動できない!

 いつも見にきてくれてありがとうございます。石川さんです。スイカの季節ですね。いや、今ならオリンピックの話題が優先でしょうか。オリンピック、あんまり興味が持てないんだよねぇ。せっかく東京でやるのにね。

概要

 Anacondaに付属してくるSpyder IDEを使っていたのですが、パソコン再起動後、突然起動しなくなりました。原因はプロジェクトを利用するときに、日本語のファイル名を使ったことでした。Bugのようですが、対応方法について記載しておきました。

経緯

 最近、Pythonのスクリプトの編集、実行には、AnacondaをインストールするとついてくるSpyderを使っています。しかし、今日は、パソコンを再起動したあとに、Spyderを起動するとなぜか立ち上がらなくなってしまいました。えっ、どうした、Spyderよ。立ち上がって来いよ~。そんなに貧弱じゃないだろ?と、言いつつ、Anacondaプロンプトですらヒストリが読めなくて起動時にエラーを出力していたことを思い出しました。何か、入力しちゃいけない文字コードを入力してしまったのでしょうか。しかし、起動した後に、スプラッシュ画像が出て、そのままお亡くなりになるなんて、聞いてないよ~。少なくともエラーメッセージを出して欲しいよ。どうしようもないじゃない、Spyderさん。

まずはSpyderを開始できるようにします

 さて。気を取り直して、実行プログラムのありかを探して、まずはそこからでしょうか、と、思って実行プログラムを見ると、おや、今まで気にもならなかったプログラムがあるじゃないですか!そう、「Reset Spyder Settings (anaconda3)」です。こんなの、今まで、気にしたこともなかったなぁ。

Reset Spyder Settings(anaconda3)

 さて、実行したところ、何やら設定がリセットされたような気がしますので、再度実行してみます。心なしかスプラッシュ画像が小さくなったような気がします。何とか立ち上がりました。アイコンも心なしか小さくなったような気がしますねぇ。。。ま、それはいいか。

アイコンが小さくなったような気がする

原因を追究します

 直前に作業していたのは、、、と、記憶をたどると、そうそう、新しくプロジェクトを作成して、そこにドキュメントフォルダをつくって、Sphinxのドキュメントを構築しようとしていたんだった、と、いうことを思い出しました。ということで、その新しいプロジェクトを再度開いてみると、、、おお、エラーか?。。。エラーですね。「Issue reporter」なる画面が起動されました。ふむふむ「Spyder has encountered an internal problem!」ということですね。内部の問題に直面しました、ということなのですが、問題レポートを送ればいいのかな?

Issue reporter

 いや、送る前に、包括的なトラブルシューティングガイドで相談してください、と、書いてありますね。ほとんどの問題が解決されるらしいです。あとは、分かっているバグ、を検索してということだけど、検索しようにも何のメッセージも出てないしなぁ。。。そもそもこの「Issue report」は出てきたんだけど、エラーメッセージは何にも出力されていないのですよね。だからレポートを書くとしたら、「プロジェクトを開こうとしたら、内部的な問題に出会いました」くらいしか書きようがないですよね。とりあえず、「Close」でよいのかな?あ、「Close」ボタンの隣に「Show details」ボタンを発見しました!このボタンを押して詳細を見てみよう。と、ポチリとした結果、下部にエラーメッセージが出てまいりました。

Show detailsを押した結果

テキストは一部分だけが見える状態でしたので、以下に全文を張り付けておきます。これだけ情報があれば、なんとかなりそうですね。

Traceback (most recent call last):
  File "C:\Users\mitsu\anaconda3\lib\site-packages\spyder\plugins\projects\plugin.py", line 129, in <lambda>
    triggered=lambda v: self.open_project())
  File "C:\Users\mitsu\anaconda3\lib\site-packages\spyder\plugins\projects\plugin.py", line 402, in open_project
    project_type_class = self._load_project_type_class(path)
  File "C:\Users\mitsu\anaconda3\lib\site-packages\spyder\plugins\projects\plugin.py", line 813, in _load_project_type_class
    config.read(fpath)
  File "C:\Users\mitsu\anaconda3\lib\configparser.py", line 697, in read
    self._read(fp, filename)
  File "C:\Users\mitsu\anaconda3\lib\configparser.py", line 1017, in _read
    for lineno, line in enumerate(fp, start=1):
UnicodeDecodeError: 'cp932' codec can't decode byte 0x81 in position 269: illegal multibyte sequence

 想定の範囲内ですが、UnicodeDecodeErrorですね!記憶にないけど、プロジェクト作るときに、日本語を使っちゃったのかなぁ。configparser.pyでエラーが発生しているのと、起動時は問題なくてプロジェクトを開くときにエラーが発生したので、プロジェクトのフォルダを見に行ってみます。ありましたね「.spyproject」フォルダが怪しいです。ちょっと覗いてみます。

エラーになったプロジェクトのフォルダ

 なるほど、「config」フォルダがあって、その中に複数の「.ini」ファイルがあります。この中をひとつずつ見ていきましょう。

エラーになったconfigフォルダ

 見つけました。「workspace.ini」ファイルですね。ここにマルチバイト文字がありました。そうそう、Sphinxで使う「.rst」のファイル名を日本語にしたのを思い出しました。このファイル自体はUTF-8で保存されていたので、うまく開けないのはどうしてでしょうね。

[workspace]
restore_data_on_startup = True
save_data_on_exit = True
save_history = True
save_non_project_files = False
project_type = empty-project-type
recent_files = ['..\\..\\..\\Users\\mitsu\\.spyder-py3\\temp.py', 'doc\\source\\index.rst', 'doc\\source\\このドキュメントについて.rst', 'doc\\source\\conf.py']

[main]
version = 0.2.0
recent_files = []

さらに原因を追究します

 configparser.pyのソースファイルを覗いてみたところ、ファイルをencoding=Noneとしてオープンしていることがわかりました。encoding=Noneとした場合は、ロケールのデフォルトエンコーディングが使用されます。つまり、日本語のWindows10環境では「cp932」が使われる、ということになります。configparser.pyの中にはファイルへの書き込みのためのオープンが見当たらなかったので、どのような設定になっているのかはちょっと不明だったのですが、上述のとおりファイルの内容はUTF-8で書き込まれていたので、書き込み時はUTF-8でオープンされているのだと思います。

では、修正しましょう

 さて、どう修正するのがよいでしょうか。気持ちとしてはconfigparser.pyのencoding=”utf-8″としたいところですが、影響範囲がはかり知れないので、Spyderに限って考えたいと思います。そうすると、エラーメッセージで指摘されている、C:\Users\mitsu\anaconda3\lib\site-packages\spyder\plugins\projects\plugin.pyの813行目に、encoding=”utf-8″を追加するのがよいでしょうか。

        config.read(fpath)  # 修正前
        config.read(fpath,encoding="utf-8")  # 修正後

 さて、修正してみたまではよかったのですが、果たして反映されるのでしょうか。Spyderって、実行形式で配布されている訳じゃないのかな?と、迷っている間に実行できそうなので、ささっとSpyderを再起動してみます。おっ、できました。エラーは発生しませんでした。

エラーなく日本語ファイルが開けました

まとめ

 結論としては、UTF-8で保存したファイルをローカルロケールでオープンして読み込んだためにエラーが発生した、ということでしたね。なので、パソコン再起動が原因ではなくて、Spyderの再起動が原因、ということでした。Pythonはバージョン3から完全UTF-8対応したはずなのに、どうしてこんなことが起きるのかというと、デフォルトエンコーディング、大混乱しているようですね。「Fluent Python Pythonicな思考とコーディング手法」を参考に、Pythonのデフォルトエンコーディングに影響を与える設定を確認してみました。

Python 3.8.8 (default, Apr 13 2021, 15:08:03) [MSC v.1916 64 bit (AMD64)]
Type "copyright", "credits" or "license" for more information.

IPython 7.22.0 -- An enhanced Interactive Python.

In [1]: import sys, locale

In [2]: locale.getpreferredencoding()
Out[2]: 'cp932'

In [3]: my_file = open("dummy","w")

In [4]: type(my_file)
Out[4]: _io.TextIOWrapper

In [5]: my_file.encoding
Out[5]: 'cp932'

In [6]: sys.stdout.isatty()
Out[6]: False

In [7]: sys.stdout.encoding
Out[7]: 'UTF-8'

In [8]: sys.stdin.isatty()
Out[8]: False

In [9]: sys.stdin.encoding
Out[9]: 'cp932'

In [10]: sys.stderr.isatty()
Out[10]: False

In [11]: sys.stderr.encoding
Out[11]: 'UTF-8'

In [12]: sys.getdefaultencoding()
Out[12]: 'utf-8'

In [13]: sys.getfilesystemencoding()
Out[13]: 'utf-8'

In [14]: my_file.close()

 書籍はブラジル向けにローカライズされたWindows 7の結果が示されており、結果はなんと4種類のエンコーディングが出力されていました。それに比べると日本語のWindows10環境は「cp932」と「utf-8」の二つしかないので、まだマシな方かも知れませんね。(苦笑)