mirror of
https://github.com/python/cpython.git
synced 2025-12-09 02:35:14 +00:00
Move the NEWOBJ-generating code to a separate function, and invoke it
after checking for __reduce__.
This commit is contained in:
parent
533dbcf250
commit
54fb192508
1 changed files with 28 additions and 24 deletions
|
|
@ -283,30 +283,6 @@ class Pickler:
|
||||||
self.save_global(obj)
|
self.save_global(obj)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Check for instance of subclass of common built-in types
|
|
||||||
# XXX This block is experimental code that will go away!
|
|
||||||
if self.proto >= 2:
|
|
||||||
if isinstance(obj, _builtin_type):
|
|
||||||
assert t not in _builtin_type # Proper subclass
|
|
||||||
args = ()
|
|
||||||
getnewargs = getattr(obj, "__getnewargs__", None)
|
|
||||||
if getnewargs:
|
|
||||||
args = getnewargs() # This better not reference obj
|
|
||||||
self.save_global(t)
|
|
||||||
self.save(args)
|
|
||||||
self.write(NEWOBJ)
|
|
||||||
self.memoize(obj)
|
|
||||||
getstate = getattr(obj, "__getstate__", None)
|
|
||||||
if getstate:
|
|
||||||
state = getstate()
|
|
||||||
else:
|
|
||||||
state = getattr(obj, "__dict__", None)
|
|
||||||
# XXX What about __slots__?
|
|
||||||
if state is not None:
|
|
||||||
self.save(state)
|
|
||||||
self.write(BUILD)
|
|
||||||
return
|
|
||||||
|
|
||||||
# Check copy_reg.dispatch_table
|
# Check copy_reg.dispatch_table
|
||||||
reduce = dispatch_table.get(t)
|
reduce = dispatch_table.get(t)
|
||||||
if reduce:
|
if reduce:
|
||||||
|
|
@ -315,6 +291,11 @@ class Pickler:
|
||||||
# Check for __reduce__ method
|
# Check for __reduce__ method
|
||||||
reduce = getattr(obj, "__reduce__", None)
|
reduce = getattr(obj, "__reduce__", None)
|
||||||
if not reduce:
|
if not reduce:
|
||||||
|
# Check for instance of subclass of common built-in types
|
||||||
|
if self.proto >= 2 and isinstance(obj, _builtin_type):
|
||||||
|
assert t not in _builtin_type # Proper subclass
|
||||||
|
self.save_newobj(obj)
|
||||||
|
return
|
||||||
raise PicklingError("Can't pickle %r object: %r" %
|
raise PicklingError("Can't pickle %r object: %r" %
|
||||||
(t.__name__, obj))
|
(t.__name__, obj))
|
||||||
rv = reduce()
|
rv = reduce()
|
||||||
|
|
@ -384,6 +365,29 @@ class Pickler:
|
||||||
save(state)
|
save(state)
|
||||||
write(BUILD)
|
write(BUILD)
|
||||||
|
|
||||||
|
def save_newobj(self, obj):
|
||||||
|
# Save a new-style class instance, using protocol 2.
|
||||||
|
# XXX Much of this is still experimental.
|
||||||
|
t = type(obj)
|
||||||
|
args = ()
|
||||||
|
getnewargs = getattr(obj, "__getnewargs__", None)
|
||||||
|
if getnewargs:
|
||||||
|
args = getnewargs() # This better not reference obj
|
||||||
|
self.save_global(t)
|
||||||
|
self.save(args)
|
||||||
|
self.write(NEWOBJ)
|
||||||
|
self.memoize(obj)
|
||||||
|
getstate = getattr(obj, "__getstate__", None)
|
||||||
|
if getstate:
|
||||||
|
state = getstate()
|
||||||
|
else:
|
||||||
|
state = getattr(obj, "__dict__", None)
|
||||||
|
# XXX What about __slots__?
|
||||||
|
if state is not None:
|
||||||
|
self.save(state)
|
||||||
|
self.write(BUILD)
|
||||||
|
return
|
||||||
|
|
||||||
# Methods below this point are dispatched through the dispatch table
|
# Methods below this point are dispatched through the dispatch table
|
||||||
|
|
||||||
dispatch = {}
|
dispatch = {}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue