summaryrefslogtreecommitdiff
path: root/Lib/pickle.py
diff options
context:
space:
mode:
authorPierre Glaser <pierreglaser@msn.com>2019-05-08 23:08:25 +0200
committerAntoine Pitrou <antoine@python.org>2019-05-08 23:08:25 +0200
commit289f1f80ee87a4baf4567a86b3425fb3bf73291d (patch)
treeb8145681f26ca875572165d143c6f2e5bd1e8906 /Lib/pickle.py
parent9a4135e939bc223f592045a38e0f927ba170da32 (diff)
downloadcpython-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.py48
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):