(self, func, args, state=None, listitems=None,
dictitems=None, state_setter=None, *, obj=None)
| 619 | "persistent IDs in protocol 0 must be ASCII strings") |
| 620 | |
| 621 | def save_reduce(self, func, args, state=None, listitems=None, |
| 622 | dictitems=None, state_setter=None, *, obj=None): |
| 623 | # This API is called by some subclasses |
| 624 | |
| 625 | if not isinstance(args, tuple): |
| 626 | raise PicklingError("args from save_reduce() must be a tuple") |
| 627 | if not callable(func): |
| 628 | raise PicklingError("func from save_reduce() must be callable") |
| 629 | |
| 630 | save = self.save |
| 631 | write = self.write |
| 632 | |
| 633 | func_name = getattr(func, "__name__", "") |
| 634 | if self.proto >= 2 and func_name == "__newobj_ex__": |
| 635 | cls, args, kwargs = args |
| 636 | if not hasattr(cls, "__new__"): |
| 637 | raise PicklingError("args[0] from {} args has no __new__" |
| 638 | .format(func_name)) |
| 639 | if obj is not None and cls is not obj.__class__: |
| 640 | raise PicklingError("args[0] from {} args has the wrong class" |
| 641 | .format(func_name)) |
| 642 | if self.proto >= 4: |
| 643 | save(cls) |
| 644 | save(args) |
| 645 | save(kwargs) |
| 646 | write(NEWOBJ_EX) |
| 647 | else: |
| 648 | func = partial(cls.__new__, cls, *args, **kwargs) |
| 649 | save(func) |
| 650 | save(()) |
| 651 | write(REDUCE) |
| 652 | elif self.proto >= 2 and func_name == "__newobj__": |
| 653 | # A __reduce__ implementation can direct protocol 2 or newer to |
| 654 | # use the more efficient NEWOBJ opcode, while still |
| 655 | # allowing protocol 0 and 1 to work normally. For this to |
| 656 | # work, the function returned by __reduce__ should be |
| 657 | # called __newobj__, and its first argument should be a |
| 658 | # class. The implementation for __newobj__ |
| 659 | # should be as follows, although pickle has no way to |
| 660 | # verify this: |
| 661 | # |
| 662 | # def __newobj__(cls, *args): |
| 663 | # return cls.__new__(cls, *args) |
| 664 | # |
| 665 | # Protocols 0 and 1 will pickle a reference to __newobj__, |
| 666 | # while protocol 2 (and above) will pickle a reference to |
| 667 | # cls, the remaining args tuple, and the NEWOBJ code, |
| 668 | # which calls cls.__new__(cls, *args) at unpickling time |
| 669 | # (see load_newobj below). If __reduce__ returns a |
| 670 | # three-tuple, the state from the third tuple item will be |
| 671 | # pickled regardless of the protocol, calling __setstate__ |
| 672 | # at unpickling time (see load_build below). |
| 673 | # |
| 674 | # Note that no standard __newobj__ implementation exists; |
| 675 | # you have to provide your own. This is to enforce |
| 676 | # compatibility with Python 2.2 (pickles written using |
| 677 | # protocol 0 or 1 in Python 2.3 should be unpicklable by |
| 678 | # Python 2.2). |
no test coverage detected