diff --git a/cloudpickle/cloudpickle.py b/cloudpickle/cloudpickle.py index cb2883f80..a1df816d1 100644 --- a/cloudpickle/cloudpickle.py +++ b/cloudpickle/cloudpickle.py @@ -331,7 +331,7 @@ def save_function_tuple(self, func): save(_fill_function) # skeleton function updater write(pickle.MARK) # beginning of tuple that _fill_function expects - self._save_subimports(code, set(f_globals.values()) | set(closure)) + self._save_subimports(code, list(f_globals.values()) + list(closure)) # create a skeleton function object and memoize it save(_make_skel_func) diff --git a/tests/cloudpickle_test.py b/tests/cloudpickle_test.py index 29deb8cdf..50de54cf3 100644 --- a/tests/cloudpickle_test.py +++ b/tests/cloudpickle_test.py @@ -138,9 +138,10 @@ def test_nested_lambdas(self): reason="subprocess has a bug in 3.4.0 to 3.4.2") def test_locally_defined_function_and_class(self): LOCAL_CONSTANT = 42 + LOCAL_LIST = [] # unhashable closure variable def some_function(x, y): - return (x + y) / LOCAL_CONSTANT + return (x + y) / LOCAL_CONSTANT + len(LOCAL_LIST) # pickle the function definition self.assertEqual(pickle_depickle(some_function)(41, 1), 1) @@ -390,8 +391,10 @@ def test_submodule_closure(self): # Same as test_submodule except the package is not a global def scope(): import xml.etree.ElementTree + l = [] # unhashable closure variable def example(): x = xml.etree.ElementTree.Comment # potential AttributeError + return len(l) return example example = scope()