ImportError: cannot import name wraps

24,199

Solution 1

Installed mock==1.0.1 and that worked for some reason. (shrugs)

edit: The real fix for me was to updated setuptools to the latest and it allowed me to upgrade mock and six to the latest. I was on setuptools 3.3. In my case I also had to remove said modules by hand because they were owned by OS in '/usr/local/lib/python2.7/dist-packages/'

check versions of everything

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

Update everything

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

Thanks @lifeless

Solution 2

I encountered the same issue on my mac, which I was able to fix by realizing that my python's sys.path contained both

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

and

/Library/Python/2.7/site-packages/

with the former earlier than the latter.

You can test if this is happening to you by running the following in the python console.

import six
six.__version__

my python was loading an outdated six.py from the former directory (which didn't have wrapper), even though pip had installed a newer version six in the second directory. (It seems mac's framework comes with a version of six by default.)

I was able to fix it by moving six.py and six.pyc out of the first directory (requires sudo access), so that python would find the newer version of six in the second directory. I'm sure you could also change the ordering of the paths in sys.path.

To find the older version of six that need to be deleted run this from the terminal console

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

Solution 3

so mock 1.1.1 and above defines a versioned requirement on six 1.7 or above:

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

This gets reflected into setuptools metadata by pbr, which there is a versioned setup_requires dependency on:

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

So there are a couple of possibilities: 1) six 1.7 is not new enough 2) there's a distro six package claiming to be 1.9.0 that doesn't have wraps for some reason 3) the setuptools in use didn't integrate properly with pbr and deps are missing 4) the wheel metadata isn't being interrogated properly by your pip/setuptools combination.

We do have a hard requirement for setuptools 17.1, and that was only explicitly reported by setup.py more recently. I'd love it if you can figure which of these is the case and update https://github.com/testing-cabal/mock/issues/298 so that we can fix whatever interaction is leading to this silent failure of setup.py / wheels.

Solution 4

On Mac OSX, the previously installed version of six was blocking my upgraded version from being used. I verified this, as previously suggested by running the following in my interpreter:

import six
six.__version__

To fix this I moved the file:

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

This is stated already in another answer on this site, but I wanted to provide a more streamlined response.

Solution 5

I originally had an issue with old "OS-owned" versions of and pip/setuptools. After I installed pip manually, like so:

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

And then installing the latest version of pip, mock and six, I still had the problem you've described above. Turns out that I had six installed twice in:

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

and in

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

After I removed the six from /usr/lib/ it worked fine: rm /usr/lib/python2.7/dist-packages/*six*

Share:
24,199

Related videos on Youtube

Michael
Author by

Michael

Software Developer in Web Security & Backend Developer.

Updated on September 13, 2020

Comments

  • Michael
    Michael over 3 years

    I'm using python 2.7.6 on Ubuntu 14.04.2 LTS. I'm using mock to mock some unittests and noticing when I import mock it fails importing wraps.

    Not sure if there's a different version of mock or six I should be using for it's import to work? Couldn't find any relevant answers and I'm not using virtual environments.

    mock module says it's compatible with python 2.7.x: https://pypi.python.org/pypi/mock

    mock==1.1.3 six==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
    

    also tried with sudo with no luck.

    $ sudo python -c 'from six import wraps'
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
    ImportError: cannot import name wraps
    
  • Michael
    Michael almost 9 years
    Thanks. I do see that this particular box has setuptools 3.3. Trying to upgrade that hoping that's the problem.
  • lifeless
    lifeless almost 9 years
    Thats because mock 1.0.1 didn't depend on six.
  • lifeless
    lifeless almost 9 years
    ok, so I think this means we have to look at the minimum version handling logic again. I'll open a ticket
  • Michael
    Michael almost 9 years
    hmm now I have the same problem on my Mac even with the last versions so I'm not sure what that means. setuptools==18.0.1 , mock==1.3.0, six==1.9.0
  • Bunyk
    Bunyk over 8 years
    Thanks, pip install mock==1.0.1 helps.
  • lifeless
    lifeless over 8 years
    We specify 1.7 - github.com/testing-cabal/mock/blob/master/requirements.txt#L‌​6 - which does define wraps. All the reports that we've dug into in detail have actually had incorrect pre-existing installs of six being loaded. Happy to help you debug your case more if you can provide some details.
  • Jordan
    Jordan over 8 years
    @lifeless I'm pretty sure the issue is that you have a >= requirement, so if somehow in the requirements chain somebody already has an old version of six, < 1.9.0 but >= 1.7, it won't work properly, but if I explicitly version it separately in my requirements, it is set to 1.9.0, which mock is of course satisfied by.
  • lifeless
    lifeless over 8 years
    If you pip install a project X which depends on Y>=N, and Y < N is already installed, pip will install the current release of Y. e.g. >= is not the problem. However, if you are using a requirements file and already specify Y then the dependency that X has is ignored.... get me a transcript of what happens, so we can reproduce it and we can see what is happening.
  • TayTay
    TayTay over 8 years
    While your answer provides the solution, in cases like this the best thing you can do to make the other answer standout is to upvote and provide any other remarks in a comment.
  • Control Complex
    Control Complex over 8 years
    I cannot comment because my rep is too low. I cannot even upvote and affect the response. However, once my rep gets high enough I promise to do so. Thank you.
  • emptyflash
    emptyflash over 8 years
    I've come back to this so many times. If I could vote it up more than once I would. Thank you for this answer.
  • AnnieFromTaiwan
    AnnieFromTaiwan about 8 years
    This should be the accepted answer! This one is more reasonable and logical than the accepted answer written by OP. And this answer works.
  • AnnieFromTaiwan
    AnnieFromTaiwan about 8 years
    You can see the location of package six using six.__file__ after import six in python console.
  • killthrush
    killthrush over 7 years
    Does the 'remove said modules by hand' part bug anyone else? It bugs me. With the python ecosystem we have at our disposal, I feel like we shouldn't have to resort to such tactics.
  • Kxrr
    Kxrr over 7 years
    It works for me! And I solved similar problem when using openssl.