【问题标题】:ImportError: cannot import name wrapsImportError:无法导入名称换行
【发布时间】:2015-10-03 18:13:44
【问题描述】:

我在 Ubuntu 14.04.2 LTS 上使用 python 2.7.6。我正在使用模拟来模拟一些单元测试,并注意到当我导入模拟时它无法导入包装。

不确定是否应该使用不同版本的 mock 或 6 来使其导入工作?找不到任何相关答案,而且我没有使用虚拟环境。

mock 模块说它与 python 2.7.x 兼容:https://pypi.python.org/pypi/mock

模拟==1.1.3 六==1.9.0

Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from mock import Mock
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/mock/__init__.py", line 2, in <module>
    import mock.mock as _mock
  File "/usr/local/lib/python2.7/dist-packages/mock/mock.py", line 68, in <module>
    from six import wraps
ImportError: cannot import name wraps

也尝试了 sudo 没有运气。

$ sudo python -c 'from six import wraps'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: cannot import name wraps

【问题讨论】:

    标签: python mocking python-unittest


    【解决方案1】:

    安装了 mock==1.0.1 并且由于某种原因可以正常工作。 (耸肩)

    edit:对我来说真正的解决办法是更新 setuptools 到最新,它允许我将 mock 和 6 升级到最新。我在 setuptools 3.3 上。在我的情况下,我还必须手动删除所述模块,因为它们归操作系统所有,位于 '/usr/local/lib/python2.7/dist-packages/'

    检查所有版本

    pip freeze | grep -e six -e mock
    easy_install --version
    

    更新所有内容

    wget https://bootstrap.pypa.io/ez_setup.py -O - | sudo python
    pip install mock --upgrade
    pip install six --upgrade
    

    感谢@lifeless

    【讨论】:

    • 那是因为 mock 1.0.1 不依赖于六个。
    • hmm 现在我的 Mac 上遇到了同样的问题,即使是最新版本,所以我不确定这意味着什么。 setuptools==18.0.1,模拟==1.3.0,六==1.9.0
    • 谢谢,pip install mock==1.0.1 帮助。
    • 我已经回到这个问题很多次了。如果我能不止一次投票,我会的。谢谢你的回答。
    • “手动删除所述模块”部分是否会影响其他人?它困扰着我。有了我们可以使用的 python 生态系统,我觉得我们不应该采取这种策略。
    【解决方案2】:

    我安装了 6==1.9.0 的 pip 并使用了新版本。似乎 mock==1.3.0 没有正确定义获得包装支持所需的 6 版本。

    【讨论】:

    • 我们指定 1.7 - github.com/testing-cabal/mock/blob/master/requirements.txt#L6 - 它确实定义了换行。我们详细研究的所有报告实际上已经加载了六个不正确的预先存在的安装。如果您能提供一些详细信息,很乐意帮助您更多地调试您的案例。
    • @lifeless 我很确定问题是你有一个 >= 要求,所以如果在要求链中有人已经有一个旧版本的 6,= 1.7 ,它不能正常工作,但是如果我在我的要求中明确单独对其进行版本化,它设置为1.9.0,当然满足mock。
    • 如果你 pip 安装一个依赖于 Y>=N 的项目 X,并且 Y = 不是问题。但是,如果您使用的是需求文件并且已经指定了 Y,那么 X 所具有的依赖关系将被忽略.... 给我一份所发生情况的记录,以便我们重现它并查看正在发生的事情。
    【解决方案3】:

    所以 mock 1.1.1 及以上版本定义了六个 1.7 或以上版本的要求:

    https://github.com/testing-cabal/mock/blob/master/requirements.txt#L6

    这会被 pbr 反映到 setuptools 元数据中,它有一个版本化的 setup_requires 依赖项:

    https://github.com/testing-cabal/mock/blob/master/setup.py#L17

    所以有两种可能性: 1)六个1.7还不够新 2) 有一个发行版 6 包声称是 1.9.0,由于某种原因没有包装 3) 使用的 setuptools 没有与 pbr 正确集成,并且缺少 deps 4) 您的 pip/setuptools 组合未正确查询轮元数据。

    我们确实对 setuptools 17.1 有严格的要求,而且最近 setup.py 才明确报告了这一点。如果您能弄清楚是哪种情况并更新https://github.com/testing-cabal/mock/issues/298,我会很高兴,这样我们就可以修复导致 setup.py /wheels 无声失败的任何交互。

    【讨论】:

    • 谢谢。我确实看到这个特定的盒子有 setuptools 3.3。尝试升级希望这是问题所在。
    【解决方案4】:

    我最初遇到了旧的“操作系统拥有”版本和 pip/setuptools 的问题。在我手动安装 pip 之后,像这样:

    wget https://bootstrap.pypa.io/get-pip.py
    sudo python get-pip.py
    sudo ln -s /usr/local/bin/pip /usr/bin/pip
    

    然后安装最新版本的pipmocksix,我还是遇到了你上面描述的问题。原来我在以下位置安装了两次:

    /usr/lib/python2.7/dist-packages/

    /usr/local/lib/python2.7/dist-packages/

    在我从 /usr/lib/ 中删除六个之后,它工作正常: rm /usr/lib/python2.7/dist-packages/*six*

    【讨论】:

      【解决方案5】:

      我在我的 mac 上遇到了同样的问题,我意识到我的 python 的 sys.path 包含这两个

      /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/
      

      /Library/Python/2.7/site-packages/
      

      前者比后者早。

      您可以通过在 python 控制台中运行以下命令来测试您是否正在发生这种情况。

      import six
      six.__version__
      

      我的 python 正在从前一个目录(没有包装器)加载过时的 Six.py,即使 pip 在第二个目录中安装了更新的版本 6。 (好像mac的框架默认自带6个版本。)

      我能够通过将 Six.py 和 Six.pyc 移出第一个目录(需要 sudo 访问权限)来修复它,以便 python 可以在第二个目录中找到更新版本的 6。我相信您也可以更改 sys.path 中路径的顺序。

      要查找需要删除的六个旧版本,请从终端控制台运行此命令

      find /System/Library/Frameworks/Python.framework/Versions -name six.py*
      

      【讨论】:

      • 这应该是公认的答案!这个比OP写的接受的答案更合理和合乎逻辑。这个答案有效。
      • 你可以在python控制台中six.__file__后面的six.__file__看到包six的位置。
      • 它对我有用!我在使用openssl时解决了类似的问题。
      【解决方案6】:

      在 Mac OSX 上,之前安装的 6 版本阻止了我的升级版本的使用。正如之前在我的解释器中运行以下建议的那样,我验证了这一点:

      import six
      six.__version__
      

      为了解决这个问题,我移动了文件:

      mv/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/six.py 
      /tmp/old_six.py
      

      这已在本网站的另一个答案中说明,但我想提供更简化的响应。

      【讨论】:

      • 虽然您的答案提供了解决方案,但在这种情况下,您可以做的最好的事情是让其他答案脱颖而出,并在评论中提供任何其他评论。
      • 我无法发表评论,因为我的代表太低了。我什至无法投票并影响回应。但是,一旦我的代表达到足够高的水平,我就会承诺这样做。谢谢。
      【解决方案7】:

      另一种解决方案是将 PYTHONPATH 环境变量设置为指向已安装的包。

      在我的 bash 配置中设置我的环境变量,以便:

      PYTHONPATH=/Library/Python/2.7/site-packages
      

      允许我在终端中运行测试(无需删除/重命名任何库等)。

      但是,在使用 PyCharm 时,无法正确导入此环境变量并没有多大帮助。尽管 PyCharm 显示为包含父变量(在它显示的导入中列出了该变量),但此导入似乎无法正常工作。

      在 PyCharm 运行配置中手动将环境变量设置为上述即可解决此问题。

      我不确定 PyCharm 在从系统环境变量或其他一些技巧导入 PYTHONPATH 变量后是否会覆盖它,但这确实为我解决了错误。

      【讨论】:

        【解决方案8】:

        虽然您没有使用像virtualenv 这样的虚拟环境,但它肯定是一个很好的用例。通过沙箱化您的 Python 安装和项目的所有依赖项,您可以避免完全破解全局/默认 Python 安装,这是很多复杂性/困难的来源。

        这是我在收到 wraps 错误时使用的 - requirements.txt 包含 mock==2.0.0six==1.10.0

        cd <my_project>
        virtualenv venv
        source venv/bin/activate
        sudo pip install -r requirements.txt
        

        在我看来,这不仅更易于使用,而且为可能想要运行您的代码的人记录文档也更简单。

        【讨论】:

          【解决方案9】:

          我发现了一件有趣的事情! 我的项目根路径中有一个名为“functools.py”的文件,当我运行我的项目时,pycharm 会引发 ImportError。 所以我重命名我的文件来解决这个问题~~

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-03-31
            • 2014-10-10
            • 2014-09-20
            • 2014-08-28
            • 2014-06-10
            • 2016-05-16
            • 2019-05-25
            相关资源
            最近更新 更多