LoginSignup
0
0

More than 1 year has passed since last update.

Python で ModuleNotFoundError: No module named '_contextvars'. が出たときの対処法

Posted at

背景

Visual Studio 2019でboostを使ってC++上でPython3.7で作ったプログラムを動かそうとしたところ、コンパイル、ビルドはできたのですがPythonプログラムの実行の途中でエラーが出てしまいました。
ログを見てみると、

...
       import contextvars
  File "C:\Users\〇〇\AppData\Local\Programs\Python\Python37\Lib\contextvars.py", line 1, in <module>
       from _contextvars import Context, ContextVar, Token, copy_context
ModuleNotFoundError: No module named '_contextvars'

といったエラーが出ているようです。
このエラーに対する情報はネット上で散見されますが、対処法が示されているものは少なく、どの対処法を試しても解決できませんでした。しかし、ちょっとした力わざで解決することができたので情報共有と備忘録を兼ねて投稿します。

エラーの詳細

上記のログを見ればわかるように、_contextvarsをインポートしようとしたときに、_contextvarsが見つからないか何かでインポートできないようです。ここでログにあったパス(C:\Users\〇〇\AppData\Local\Programs\Python\Python37\Lib)に飛んでみましょう。
ここにはVS2019でインストールしたPythonが入っている(たぶん)のですが、確かに_contextvars.pyというファイルは見つかりません。代わりにcontextvars.py(_がない)があったのでその中身を見てみます。

contextvars.py
from _contextvars import Context, ContextVar, Token, copy_context


__all__ = ('Context', 'ContextVar', 'Token', 'copy_context')

ログでもわかるように、_contextvarsのインポートの前にcontextvarsのインポートを行っているのですが、contextvars.pyは「_contextvars.pyからContext, ContextVar, Token, copy_contextという関数をインポートするよ」と言っているだけのようです。つまり、「contextvars.pyを動かすには_contextvars.pyが必要。だけど_contextvars.pyが存在しないからエラーが出た。」ということのようです。

_contextvars.pyはいずこへ

これによると、Python3.7をインストールしたときにすべてのパッケージがインストールされず、aptでインストールしなおしたら正常に動作したよ!とのことです。
早速やってみました。ダメでした。
WSL上でubuntuにPython3.7をインストールしなおしましたが(手順:Masashi Murakami様)、ubuntu内のPythonの中身(user/lib/Python3.7)に_contextvars.pyは存在しませんでした。(_contextvars.pyがあったらwindowsのほうにコピペるれば行けると思ったのですが、、、)

次に

によると、virtualenvを再インストールすれば直った!とのことです。
早速やってみました。ダメでした。
VS2019上で

pip install virtualenv

したのですが結局_contextvars.pyは作られず、プロジェクトを実行しなおしてもやはりModuleNotFoundErrorがでます。

_contextvars.py発見!

もうあきらめてふて寝しようとしたとき、その前にほんとに_contextvars.pyはどこにも存在しないのかと駄目もとでエクスプローラで検索したところ、dummy_contextvars.pyというものをC:\Users\〇〇\AppData\Local\Programs\Python\Python37\Lib\site-packages\prompt_toolkit\eventloopで発見しました。
中身を見てみると、

dummy_contextvars.py
"""
Dummy contextvars implementation, to make prompt_toolkit work on Python 3.6.

As long as there is only one application running at a time, we don't need the
real contextvars. So, stuff like the telnet-server and so on requires 3.7.
"""
from typing import Any, Callable, Generic, Optional, TypeVar


def copy_context() -> "Context":
    return Context()


_T = TypeVar("_T")


class Context:
    def run(self, callable: Callable[..., _T], *args: Any, **kwargs: Any) -> _T:
        return callable(*args, **kwargs)

    def copy(self) -> "Context":
        return self


class Token(Generic[_T]):
    pass


class ContextVar(Generic[_T]):
    def __init__(self, name: str, *, default: Optional[_T] = None) -> None:
        self._name = name
        self._value = default

    @property
    def name(self) -> str:
        return self._name

    def get(self, default: Optional[_T] = None) -> _T:
        result = self._value or default
        if result is None:
            raise LookupError
        return result

    def set(self, value: _T) -> Token[_T]:
        self._value = value
        return Token()

    def reset(self, token: Token[_T]) -> None:
        pass

Python3.6でcontextvarsを使えるようにする(contextvarsは3.7で実装されたらしい)ためのもののようですが、おやおや~、 Context,、ContextVar, Token, copy_contextが定義されていますね。
これは使えるのではということで、C:\Users\〇〇\AppData\Local\Programs\Python\Python37\Libにコピペ、名前を_contextvars.pyに変更しました。

そしてプロジェクトを実行、、、
ModuleNotFoundErrorは出ず、無事実行できました!

まとめ

ModuleNotFoundError: No module named '_contextvars'が出たときは_contextvars.pyがないか探し、なければdummy_contextvars.pyを探してきてコピペして名前変更すればOK!

このエラーにどれだけの方々が直面するかわかりませんが、直面した際ネット上にはあまり情報がないのでこの記事が参考になれば幸いです。
最後にcontextvarsについて、公式ドキュメントのリンクを載せておきます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0