ImportError: cannot import name wraps

ImportError: cannot import name wraps

我在 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

安装了 mock==1.0.1 并且出于某种原因它起作用了。 (耸肩)

编辑:对我来说真正的解决办法是 更新 setuptools 到最新,它允许我将 mock 和 6 升级到最新。我使用的是 setuptools 3.3。在我的例子中,我还必须手动删除所述模块,因为它们由 '/usr/local/lib/python2.7/dist-packages/'

中的 OS 所有

检查所有版本

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

我对 six==1.9.0 进行了 pip 安装,它采用了新版本。似乎 mock==1.3.0 没有正确定义它需要获得包装支持的 6 版本。

因此 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) 有一个自称是 1.9.0 的发行版 6 包,由于某种原因没有包装 3) 使用中的设置工具没有与 pbr 正确集成并且缺少 deps 4) 您的 pip/setuptools 组合没有正确询问车轮元数据。

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

我最初对 "OS-owned" 和 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*

我在我的 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*

在 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

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

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

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

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

允许我在终端中 运行 测试(没有 removing/renaming 任何库等)。

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

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

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

虽然您没有使用像 virtualenv 这样的虚拟环境,但它确实是一个很好的用例。通过沙箱化您的 Python 安装和项目的所有依赖项,您可以避免完全破解 global/default python 安装,这是很多 complexity/difficulty 的来源从。

这是我在收到 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

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

我发现了一个有趣的东西! 在我的项目根路径中有一个名为 "functools.py" 的文件,当我 运行 我的项目时, pycharm 将引发 ImportError。 所以我重命名我的文件解决了这个问题~~