zxCoder
V2EX  ›  问与答

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

  •  
  •   zxCoder · Jun 7, 2021 · 3489 views
    This topic created in 1863 days ago, the information mentioned may be changed or developed.

    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  
       Jun 7, 2021
    看看你的 import 的包路径有没有被修改过吧,可能是包升级过了:
    import werkzeug
    killva4624
        2
    killva4624  
       Jun 7, 2021
    @killva4624 print(werkzeug.__file__)
    zxCoder
        3
    zxCoder  
    OP
       Jun 7, 2021
    @killva4624 唉 迷惑 werkzeug 从 2.0.1 降到 2.0.0 就好了。。。。
    killva4624
        4
    killva4624  
       Jun 7, 2021   ❤️ 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
    ```
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   4691 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 10:03 · PVG 18:03 · LAX 03:03 · JFK 06:03
    ♥ Do have faith in what you're doing.