Hello community,
here is the log from the commit of package python-cloudpickle for
openSUSE:Factory checked in at 2018-07-17 09:41:40
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-cloudpickle (Old)
and /work/SRC/openSUSE:Factory/.python-cloudpickle.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-cloudpickle"
Tue Jul 17 09:41:40 2018 rev:2 rq:622917 version:0.5.3
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-cloudpickle/python-cloudpickle.changes
2018-04-01 17:26:34.407417595 +0200
+++
/work/SRC/openSUSE:Factory/.python-cloudpickle.new/python-cloudpickle.changes
2018-07-17 09:41:40.825448086 +0200
@@ -1,0 +2,9 @@
+Sat Jul 14 19:14:34 UTC 2018 - [email protected]
+
+- update to version 0.5.3:
+ * Fixed a crash in Python 2 when serializing non-hashable
+ instancemethods of built-in types (issue #144).
+ * itertools objects can also pickled (PR #156).
+ * logging.RootLogger can be also pickled (PR #160).
+
+-------------------------------------------------------------------
Old:
----
cloudpickle-0.5.2.tar.gz
New:
----
cloudpickle-0.5.3.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-cloudpickle.spec ++++++
--- /var/tmp/diff_new_pack.fVvMm2/_old 2018-07-17 09:41:41.433445854 +0200
+++ /var/tmp/diff_new_pack.fVvMm2/_new 2018-07-17 09:41:41.437445839 +0200
@@ -16,21 +16,21 @@
#
-%bcond_without tests
-
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
+%bcond_without tests
Name: python-cloudpickle
-Version: 0.5.2
+Version: 0.5.3
Release: 0
Summary: Extended pickling support for Python objects
License: BSD-3-Clause
Group: Development/Languages/Python
-Url: https://github.com/cloudpipe/cloudpickle
+URL: https://github.com/cloudpipe/cloudpickle
Source:
https://files.pythonhosted.org/packages/source/c/cloudpickle/cloudpickle-%{version}.tar.gz
BuildRequires: %{python_module devel}
BuildRequires: %{python_module setuptools}
BuildRequires: fdupes
BuildRequires: python-rpm-macros
+BuildArch: noarch
%if %{with tests}
BuildRequires: %{python_module curses}
BuildRequires: %{python_module mock}
@@ -40,8 +40,6 @@
BuildRequires: %{python_module scipy}
BuildRequires: %{python_module tornado}
%endif
-BuildRoot: %{_tmppath}/%{name}-%{version}-build
-BuildArch: noarch
%python_subpackages
%description
@@ -56,7 +54,6 @@
Among other things, cloudpickle supports pickling for lambda expressions,
functions and classes defined interactively in the __main__ module.
-
%prep
%setup -q -n cloudpickle-%{version}
@@ -75,7 +72,6 @@
%endif
%files %{python_files}
-%defattr(-,root,root,-)
%doc README.md
%license LICENSE
%{python_sitelib}/*
++++++ cloudpickle-0.5.2.tar.gz -> cloudpickle-0.5.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cloudpickle-0.5.2/PKG-INFO
new/cloudpickle-0.5.3/PKG-INFO
--- old/cloudpickle-0.5.2/PKG-INFO 2017-11-21 09:28:40.000000000 +0100
+++ new/cloudpickle-0.5.3/PKG-INFO 2018-05-14 18:24:48.000000000 +0200
@@ -1,12 +1,11 @@
Metadata-Version: 1.1
Name: cloudpickle
-Version: 0.5.2
+Version: 0.5.3
Summary: Extended pickling support for Python objects
Home-page: https://github.com/cloudpipe/cloudpickle
Author: Cloudpipe
Author-email: [email protected]
-License: LICENSE.txt
-Description-Content-Type: UNKNOWN
+License: BSD 3-Clause License
Description: # cloudpickle
[(value)
-#relevant opcodes
+# relevant opcodes
STORE_GLOBAL = opcode.opmap['STORE_GLOBAL']
DELETE_GLOBAL = opcode.opmap['DELETE_GLOBAL']
LOAD_GLOBAL = opcode.opmap['LOAD_GLOBAL']
@@ -173,7 +173,7 @@
def islambda(func):
- return getattr(func,'__name__') == '<lambda>'
+ return getattr(func, '__name__') == '<lambda>'
_BUILTIN_TYPE_NAMES = {}
@@ -270,24 +270,19 @@
if 'recursion' in e.args[0]:
msg = """Could not pickle object as excessively deep recursion
required."""
raise pickle.PicklingError(msg)
+ else:
+ raise
def save_memoryview(self, obj):
self.save(obj.tobytes())
+
dispatch[memoryview] = save_memoryview
if not PY3:
def save_buffer(self, obj):
self.save(str(obj))
- dispatch[buffer] = save_buffer
- def save_unsupported(self, obj):
- raise pickle.PicklingError("Cannot pickle objects of type %s" %
type(obj))
- dispatch[types.GeneratorType] = save_unsupported
-
- # itertools objects do not pickle!
- for v in itertools.__dict__.values():
- if type(v) is type:
- dispatch[v] = save_unsupported
+ dispatch[buffer] = save_buffer # noqa: F821 'buffer' was removed in
Python 3
def save_module(self, obj):
"""
@@ -309,6 +304,7 @@
self.save_reduce(dynamic_subimport, (obj.__name__, vars(obj)),
obj=obj)
else:
self.save_reduce(subimport, (obj.__name__,), obj=obj)
+
dispatch[types.ModuleType] = save_module
def save_codeobject(self, obj):
@@ -329,6 +325,7 @@
obj.co_firstlineno, obj.co_lnotab, obj.co_freevars,
obj.co_cellvars
)
self.save_reduce(types.CodeType, args, obj=obj)
+
dispatch[types.CodeType] = save_codeobject
def save_function(self, obj, name=None):
@@ -337,7 +334,13 @@
Determines what kind of function obj is (e.g. lambda, defined at
interactive prompt, etc) and handles the pickling appropriately.
"""
- if obj in _BUILTIN_TYPE_CONSTRUCTORS:
+ try:
+ should_special_case = obj in _BUILTIN_TYPE_CONSTRUCTORS
+ except TypeError:
+ # Methods of builtin types aren't hashable in python 2.
+ should_special_case = False
+
+ if should_special_case:
# We keep a special-cased cache of built-in type constructors at
# global scope, because these functions are structured very
# differently in different python versions and implementations (for
@@ -420,6 +423,7 @@
else:
write(pickle.GLOBAL + modname + '\n' + name + '\n')
self.memoize(obj)
+
dispatch[types.FunctionType] = save_function
def _save_subimports(self, code, top_level_dependencies):
@@ -432,14 +436,16 @@
if isinstance(x, types.ModuleType) and hasattr(x, '__package__')
and x.__package__:
# check if the package has any currently loaded sub-imports
prefix = x.__name__ + '.'
- for name, module in sys.modules.items():
+ # A concurrent thread could mutate sys.modules,
+ # make sure we iterate over a copy to avoid exceptions
+ for name in list(sys.modules):
# Older versions of pytest will add a "None" module to
sys.modules.
if name is not None and name.startswith(prefix):
# check whether the function can address the sub-module
tokens = set(name[len(prefix):].split('.'))
if not tokens - set(code.co_names):
# ensure unpickler executes this import
- self.save(module)
+ self.save(sys.modules[name])
# then discards the reference to it
self.write(pickle.POP)
@@ -572,8 +578,7 @@
# PyPy "builtin-code" object
out_names = set()
else:
- out_names = set(names[oparg]
- for op, oparg in _walk_global_ops(co))
+ out_names = {names[oparg] for _, oparg in _walk_global_ops(co)}
# see if nested function have any global refs
if co.co_consts:
@@ -623,6 +628,7 @@
if obj.__module__ == "__builtin__":
return self.save_global(obj)
return self.save_function(obj)
+
dispatch[types.BuiltinFunctionType] = save_builtin_function
def save_global(self, obj, name=None, pack=struct.pack):
@@ -661,7 +667,8 @@
self.save_reduce(types.MethodType, (obj.__func__,
obj.__self__), obj=obj)
else:
self.save_reduce(types.MethodType, (obj.__func__,
obj.__self__, obj.__self__.__class__),
- obj=obj)
+ obj=obj)
+
dispatch[types.MethodType] = save_instancemethod
def save_inst(self, obj):
@@ -715,11 +722,13 @@
def save_property(self, obj):
# properties not correctly saved in python
self.save_reduce(property, (obj.fget, obj.fset, obj.fdel,
obj.__doc__), obj=obj)
+
dispatch[property] = save_property
def save_classmethod(self, obj):
orig_func = obj.__func__
self.save_reduce(type(obj), (orig_func,), obj=obj)
+
dispatch[classmethod] = save_classmethod
dispatch[staticmethod] = save_classmethod
@@ -730,7 +739,7 @@
return item
items = obj(Dummy())
if not isinstance(items, tuple):
- items = (items, )
+ items = (items,)
return self.save_reduce(operator.itemgetter, items)
if type(operator.itemgetter) is type:
@@ -761,16 +770,16 @@
def save_file(self, obj):
"""Save a file"""
try:
- import StringIO as pystringIO #we can't use cStringIO as it lacks
the name attribute
+ import StringIO as pystringIO # we can't use cStringIO as it
lacks the name attribute
except ImportError:
import io as pystringIO
- if not hasattr(obj, 'name') or not hasattr(obj, 'mode'):
+ if not hasattr(obj, 'name') or not hasattr(obj, 'mode'):
raise pickle.PicklingError("Cannot pickle files that do not map to
an actual file")
if obj is sys.stdout:
- return self.save_reduce(getattr, (sys,'stdout'), obj=obj)
+ return self.save_reduce(getattr, (sys, 'stdout'), obj=obj)
if obj is sys.stderr:
- return self.save_reduce(getattr, (sys,'stderr'), obj=obj)
+ return self.save_reduce(getattr, (sys, 'stderr'), obj=obj)
if obj is sys.stdin:
raise pickle.PicklingError("Cannot pickle standard input")
if obj.closed:
@@ -805,10 +814,10 @@
def save_not_implemented(self, obj):
self.save_reduce(_gen_not_implemented, ())
- if PY3:
- dispatch[io.TextIOWrapper] = save_file
- else:
+ try: # Python 2
dispatch[file] = save_file
+ except NameError: # Python 3
+ dispatch[io.TextIOWrapper] = save_file
dispatch[type(Ellipsis)] = save_ellipsis
dispatch[type(NotImplemented)] = save_not_implemented
@@ -823,6 +832,11 @@
dispatch[logging.Logger] = save_logger
+ def save_root_logger(self, obj):
+ self.save_reduce(logging.getLogger, (), obj=obj)
+
+ dispatch[logging.RootLogger] = save_root_logger
+
"""Special functions for Add-on libraries"""
def inject_addons(self):
"""Plug in system. Register additional pickling functions if modules
already loaded"""
@@ -928,7 +942,7 @@
if type(modname) is str:
try:
mod = __import__(modname)
- except Exception as e:
+ except Exception:
sys.stderr.write('warning: could not import %s\n. '
'Your function may unexpectedly error due to
this import failing;'
'A version mismatch is likely. Specific
error was:\n' % modname)
@@ -937,7 +951,7 @@
setattr(main, mod.__name__, mod)
-#object generators:
+# object generators:
def _genpartial(func, args, kwds):
if not args:
args = ()
@@ -945,9 +959,11 @@
kwds = {}
return partial(func, *args, **kwds)
+
def _gen_ellipsis():
return Ellipsis
+
def _gen_not_implemented():
return NotImplemented
@@ -1064,7 +1080,7 @@
def _find_module(mod_name):
"""
Iterate over each part instead of calling imp.find_module directly.
- This function is able to find submodules (e.g. sickit.tree)
+ This function is able to find submodules (e.g. scikit.tree)
"""
path = None
for part in mod_name.split('.'):
@@ -1075,9 +1091,11 @@
file.close()
return path, description
+
"""Constructors for 3rd party libraries
Note: These can never be renamed due to client compatibility issues"""
+
def _getobject(modname, attribute):
mod = __import__(modname, fromlist=[attribute])
return mod.__dict__[attribute]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cloudpickle-0.5.2/cloudpickle.egg-info/PKG-INFO
new/cloudpickle-0.5.3/cloudpickle.egg-info/PKG-INFO
--- old/cloudpickle-0.5.2/cloudpickle.egg-info/PKG-INFO 2017-11-21
09:28:40.000000000 +0100
+++ new/cloudpickle-0.5.3/cloudpickle.egg-info/PKG-INFO 2018-05-14
18:24:48.000000000 +0200
@@ -1,12 +1,11 @@
Metadata-Version: 1.1
Name: cloudpickle
-Version: 0.5.2
+Version: 0.5.3
Summary: Extended pickling support for Python objects
Home-page: https://github.com/cloudpipe/cloudpickle
Author: Cloudpipe
Author-email: [email protected]
-License: LICENSE.txt
-Description-Content-Type: UNKNOWN
+License: BSD 3-Clause License
Description: # cloudpickle
[.read(),
classifiers=[
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/cloudpickle-0.5.2/tests/cloudpickle_test.py
new/cloudpickle-0.5.3/tests/cloudpickle_test.py
--- old/cloudpickle-0.5.2/tests/cloudpickle_test.py 2017-11-21
09:26:40.000000000 +0100
+++ new/cloudpickle-0.5.3/tests/cloudpickle_test.py 2018-05-13
06:52:50.000000000 +0200
@@ -47,6 +47,15 @@
from .testutils import assert_run_python_script
+class RaiserOnPickle(object):
+
+ def __init__(self, exc):
+ self.exc = exc
+
+ def __reduce__(self):
+ raise self.exc
+
+
def pickle_depickle(obj, protocol=cloudpickle.DEFAULT_PROTOCOL):
"""Helper function to test whether object pickled with cloudpickle can be
depickled with pickle
@@ -213,7 +222,7 @@
def test_unhashable_closure(self):
def f():
- s = set((1, 2)) # mutable set is unhashable
+ s = {1, 2} # mutable set is unhashable
def g():
return len(s)
@@ -338,15 +347,6 @@
else: # skip if scipy is not available
pass
- def test_save_unsupported(self):
- sio = StringIO()
- pickler = cloudpickle.CloudPickler(sio, 2)
-
- with pytest.raises(pickle.PicklingError) as excinfo:
- pickler.save_unsupported("test")
-
- assert "Cannot pickle objects of type" in str(excinfo.value)
-
def test_loads_namespace(self):
obj = 1, 2, 3, 4
returned_obj = cloudpickle.loads(cloudpickle.dumps(obj))
@@ -494,7 +494,7 @@
nvars = 65537 + 258
names = ['g%d' % i for i in range(1, nvars)]
r = random.Random(42)
- d = dict([(name, r.randrange(100)) for name in names])
+ d = {name: r.randrange(100) for name in names}
# def f(x):
# x = g1, g2, ...
# return zlib.crc32(bytes(bytearray(x)))
@@ -613,8 +613,8 @@
msg='cell contents not set correctly',
)
- def test_logger(self):
- logger = logging.getLogger('cloudpickle.dummy_test_logger')
+ def check_logger(self, name):
+ logger = logging.getLogger(name)
pickled = pickle_depickle(logger, protocol=self.protocol)
self.assertTrue(pickled is logger, (pickled, logger))
@@ -633,7 +633,13 @@
out, _ = proc.communicate()
self.assertEqual(proc.wait(), 0)
self.assertEqual(out.strip().decode(),
- 'INFO:cloudpickle.dummy_test_logger:hello')
+ 'INFO:{}:hello'.format(logger.name))
+
+ def test_logger(self):
+ # logging.RootLogger object
+ self.check_logger(None)
+ # logging.Logger object
+ self.check_logger('cloudpickle.dummy_test_logger')
def test_abc(self):
@@ -687,7 +693,7 @@
self.assertEqual(depickled3.x, 3)
self.assertEqual(len(weakset), 2)
- self.assertEqual(set(weakset), set([depickled1, depickled2]))
+ self.assertEqual(set(weakset), {depickled1, depickled2})
def test_faulty_module(self):
for module_name in ['_faulty_module', '_missing_module', None]:
@@ -862,6 +868,32 @@
b'\x14NtR.')
self.assertEquals(42, cloudpickle.loads(pickled)(42))
+ def test_pickle_reraise(self):
+ for exc_type in [Exception, ValueError, TypeError, RuntimeError]:
+ obj = RaiserOnPickle(exc_type("foo"))
+ with pytest.raises((exc_type, pickle.PicklingError)):
+ cloudpickle.dumps(obj)
+
+ def test_unhashable_function(self):
+ d = {'a': 1}
+ depickled_method = pickle_depickle(d.get)
+ self.assertEquals(depickled_method('a'), 1)
+ self.assertEquals(depickled_method('b'), None)
+
+ def test_itertools_count(self):
+ counter = itertools.count(1, step=2)
+
+ # advance the counter a bit
+ next(counter)
+ next(counter)
+
+ new_counter = pickle_depickle(counter, protocol=self.protocol)
+
+ self.assertTrue(counter is not new_counter)
+
+ for _ in range(10):
+ self.assertEqual(next(counter), next(new_counter))
+
class Protocol2CloudPickleTest(CloudPickleTest):