diff options
author | Pierre Glaser <pierreglaser@msn.com> | 2019-05-08 23:08:25 +0200 |
---|---|---|
committer | Antoine Pitrou <antoine@python.org> | 2019-05-08 23:08:25 +0200 |
commit | 289f1f80ee87a4baf4567a86b3425fb3bf73291d (patch) | |
tree | b8145681f26ca875572165d143c6f2e5bd1e8906 /Lib/pickle.py | |
parent | 9a4135e939bc223f592045a38e0f927ba170da32 (diff) | |
download | cpython-git-289f1f80ee87a4baf4567a86b3425fb3bf73291d.tar.gz |
bpo-35900: Enable custom reduction callback registration in _pickle (GH-12499)
Enable custom reduction callback registration for functions and classes in
_pickle.c, using the new Pickler's attribute ``reducer_override``.
Diffstat (limited to 'Lib/pickle.py')
-rw-r--r-- | Lib/pickle.py | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/Lib/pickle.py b/Lib/pickle.py index 47f0d280ef..595beda476 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -497,34 +497,42 @@ class _Pickler: self.write(self.get(x[0])) return - # Check the type dispatch table - t = type(obj) - f = self.dispatch.get(t) - if f is not None: - f(self, obj) # Call unbound method with explicit self - return - - # Check private dispatch table if any, or else copyreg.dispatch_table - reduce = getattr(self, 'dispatch_table', dispatch_table).get(t) + rv = NotImplemented + reduce = getattr(self, "reducer_override", None) if reduce is not None: rv = reduce(obj) - else: - # Check for a class with a custom metaclass; treat as regular class - if issubclass(t, type): - self.save_global(obj) + + if rv is NotImplemented: + # Check the type dispatch table + t = type(obj) + f = self.dispatch.get(t) + if f is not None: + f(self, obj) # Call unbound method with explicit self return - # Check for a __reduce_ex__ method, fall back to __reduce__ - reduce = getattr(obj, "__reduce_ex__", None) + # Check private dispatch table if any, or else + # copyreg.dispatch_table + reduce = getattr(self, 'dispatch_table', dispatch_table).get(t) if reduce is not None: - rv = reduce(self.proto) + rv = reduce(obj) else: - reduce = getattr(obj, "__reduce__", None) + # Check for a class with a custom metaclass; treat as regular + # class + if issubclass(t, type): + self.save_global(obj) + return + + # Check for a __reduce_ex__ method, fall back to __reduce__ + reduce = getattr(obj, "__reduce_ex__", None) if reduce is not None: - rv = reduce() + rv = reduce(self.proto) else: - raise PicklingError("Can't pickle %r object: %r" % - (t.__name__, obj)) + reduce = getattr(obj, "__reduce__", None) + if reduce is not None: + rv = reduce() + else: + raise PicklingError("Can't pickle %r object: %r" % + (t.__name__, obj)) # Check for string returned by reduce(), meaning "save as global" if isinstance(rv, str): |