(self)
| 5766 | |
| 5767 | @support.thread_unsafe |
| 5768 | def test_pickle_slots(self): |
| 5769 | # Tests pickling of classes with __slots__. |
| 5770 | |
| 5771 | # Pickling of classes with __slots__ but without __getstate__ should |
| 5772 | # fail (if using protocol 0 or 1) |
| 5773 | global C |
| 5774 | class C: |
| 5775 | __slots__ = ['a'] |
| 5776 | with self.assertRaises(TypeError): |
| 5777 | pickle.dumps(C(), 0) |
| 5778 | |
| 5779 | global D |
| 5780 | class D(C): |
| 5781 | pass |
| 5782 | with self.assertRaises(TypeError): |
| 5783 | pickle.dumps(D(), 0) |
| 5784 | |
| 5785 | class C: |
| 5786 | "A class with __getstate__ and __setstate__ implemented." |
| 5787 | __slots__ = ['a'] |
| 5788 | def __getstate__(self): |
| 5789 | state = getattr(self, '__dict__', {}).copy() |
| 5790 | for cls in type(self).__mro__: |
| 5791 | for slot in cls.__dict__.get('__slots__', ()): |
| 5792 | try: |
| 5793 | state[slot] = getattr(self, slot) |
| 5794 | except AttributeError: |
| 5795 | pass |
| 5796 | return state |
| 5797 | def __setstate__(self, state): |
| 5798 | for k, v in state.items(): |
| 5799 | setattr(self, k, v) |
| 5800 | def __repr__(self): |
| 5801 | return "%s()<%r>" % (type(self).__name__, self.__getstate__()) |
| 5802 | |
| 5803 | class D(C): |
| 5804 | "A subclass of a class with slots." |
| 5805 | pass |
| 5806 | |
| 5807 | global E |
| 5808 | class E(C): |
| 5809 | "A subclass with an extra slot." |
| 5810 | __slots__ = ['b'] |
| 5811 | |
| 5812 | # Now it should work |
| 5813 | for pickle_copier in self._generate_pickle_copiers(): |
| 5814 | with self.subTest(pickle_copier=pickle_copier): |
| 5815 | x = C() |
| 5816 | y = pickle_copier.copy(x) |
| 5817 | self._assert_is_copy(x, y) |
| 5818 | |
| 5819 | x.a = 42 |
| 5820 | y = pickle_copier.copy(x) |
| 5821 | self._assert_is_copy(x, y) |
| 5822 | |
| 5823 | x = D() |
| 5824 | x.a = 42 |
| 5825 | x.b = 100 |
nothing calls this directly
no test coverage detected