V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
zxCoder
V2EX  ›  问与答

ImportError: cannot import name 'ContextVar' from 'werkzeug.local'

  •  
  •   zxCoder · 2021-06-07 19:44:32 +08:00 · 3067 次点击
    这是一个创建于 1300 天前的主题,其中的信息可能已经有所发展或是发生改变。

    flask 2.0.1

    一个小时前 flask 还正常,后来装了几个其他包,再启动就报错了

    ImportError: cannot import name 'ContextVar' from 'werkzeug.local'

    定位在

    from werkzeug.local import ContextVar
    

    可是 werkzeug/local.py 这个文件里确实没有 ContextVar

    是哪里出了问题呢? pip 重装了也不行

    killva4624
        1
    killva4624  
       2021-06-07 19:49:55 +08:00
    看看你的 import 的包路径有没有被修改过吧,可能是包升级过了:
    import werkzeug
    killva4624
        2
    killva4624  
       2021-06-07 19:50:08 +08:00
    @killva4624 print(werkzeug.__file__)
    zxCoder
        3
    zxCoder  
    OP
       2021-06-07 19:51:57 +08:00
    @killva4624 唉 迷惑 werkzeug 从 2.0.1 降到 2.0.0 就好了。。。。
    killva4624
        4
    killva4624  
       2021-06-07 20:03:18 +08:00   ❤️ 1
    感觉是 contextvars 这个包的问题
    local.py:

    ```python
    try:
    from contextvars import ContextVar

    if "gevent" in sys.modules or "eventlet" in sys.modules:
    # Both use greenlet, so first check it has patched
    # ContextVars, Greenlet <0.4.17 does not.
    import greenlet

    greenlet_patched = getattr(greenlet, "GREENLET_USE_CONTEXT_VARS", False)

    if not greenlet_patched:
    # If Gevent is used, check it has patched ContextVars,
    # <20.5 does not.
    try:
    from gevent.monkey import is_object_patched
    except ImportError:
    # Gevent isn't used, but Greenlet is and hasn't patched
    raise _CannotUseContextVar()
    else:
    if is_object_patched("threading", "local") and not is_object_patched(
    "contextvars", "ContextVar"
    ):
    raise _CannotUseContextVar()


    except (ImportError, _CannotUseContextVar):

    class ContextVar: # type: ignore
    """A fake ContextVar based on the previous greenlet/threading
    ident function. Used on Python 3.6, eventlet, and old versions
    of gevent.
    """

    def __init__(self, _name: str) -> None:
    self.storage: t.Dict[int, t.Dict[str, t.Any]] = {}

    def get(self, default: t.Dict[str, t.Any]) -> t.Dict[str, t.Any]:
    return self.storage.get(_get_ident(), default)

    def set(self, value: t.Dict[str, t.Any]) -> None:
    self.storage[_get_ident()] = value
    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   910 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 22:17 · PVG 06:17 · LAX 14:17 · JFK 17:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.