Seaborn: Problem with pickle and old version of library six in the repository.

Created on 7 Jul 2016  路  3Comments  路  Source: mwaskom/seaborn

If you import seaborn and try to serialize, as example, Ellipsis object, then sometimes you will see an error ImportError: No module named 'winreg':

import seaborn
import pickle

pickle.dumps(Ellipsis)

It reproduces not all the time, but usually for second or third try.

OS X El Capitan 10.11.5
Python 3.5.1
seaborn 0.7.0

As I understand, the reason is that seaborn uses outdated version of six library. When I tried to change six library from repository to an actual version the problem was solved.

Most helpful comment

The problem is that seaborn imports this internally packaged module six. When six is imported, it creates MovedModule objects which will be stored in sys.modules.

When Pickle tries to store object by using function save_global it goes through all objects inside sys.modules and try to get attribute by name of saved object.

When seaborn.external.six.MovedModule.__getattr__ is called, it will try to load this module and will fail if this module is not in the system.

So yes, this is a problem with seaborn.external.six and as you can see, in my example there is no other used libraries except seaborn and pickle.

The new version of six package doesn't have this problem inside.

All 3 comments

I don't think this should be causing your issue because the seaborn six is internally packaged and other libraries shouldn't be able to import it (unless they do from seaborn.ext import six for some reason). Though six does do some magic so maybe...

The problem is that seaborn imports this internally packaged module six. When six is imported, it creates MovedModule objects which will be stored in sys.modules.

When Pickle tries to store object by using function save_global it goes through all objects inside sys.modules and try to get attribute by name of saved object.

When seaborn.external.six.MovedModule.__getattr__ is called, it will try to load this module and will fail if this module is not in the system.

So yes, this is a problem with seaborn.external.six and as you can see, in my example there is no other used libraries except seaborn and pickle.

The new version of six package doesn't have this problem inside.

This problem even crashes the unittest package under Python3 when using the unittest.TestCase.assertWarnsRegex method. This method uses the sys.modules attribute that is corrupted by seaborn.ext.six. You can reproduce this error (under Python3) via

import seaborn
import unittest

class Test(unittest.TestCase):
    def test_something(self):
        with self.assertWarnsRegex(RuntimeWarning, "crashes anyway"):
            pass

t = Test('test_something')
t.test_something()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in test_something
  File "/usr/local/lib/python3.5/unittest/case.py", line 225, in __enter__
    for v in sys.modules.values():
RuntimeError: dictionary changed size during iteration
Was this page helpful?
0 / 5 - 0 ratings