(self)
| 5529 | |
| 5530 | @support.thread_unsafe |
| 5531 | def test_pickle_slots(self): |
| 5532 | # Tests pickling of classes with __slots__. |
| 5533 | |
| 5534 | # Pickling of classes with __slots__ but without __getstate__ should |
| 5535 | # fail (if using protocol 0 or 1) |
| 5536 | global C |
| 5537 | class C: |
| 5538 | __slots__ = ['a'] |
| 5539 | with self.assertRaises(TypeError): |
| 5540 | pickle.dumps(C(), 0) |
| 5541 | |
| 5542 | global D |
| 5543 | class D(C): |
| 5544 | pass |
| 5545 | with self.assertRaises(TypeError): |
| 5546 | pickle.dumps(D(), 0) |
| 5547 | |
| 5548 | class C: |
| 5549 | "A class with __getstate__ and __setstate__ implemented." |
| 5550 | __slots__ = ['a'] |
| 5551 | def __getstate__(self): |
| 5552 | state = getattr(self, '__dict__', {}).copy() |
| 5553 | for cls in type(self).__mro__: |
| 5554 | for slot in cls.__dict__.get('__slots__', ()): |
| 5555 | try: |
| 5556 | state[slot] = getattr(self, slot) |
| 5557 | except AttributeError: |
| 5558 | pass |
| 5559 | return state |
| 5560 | def __setstate__(self, state): |
| 5561 | for k, v in state.items(): |
| 5562 | setattr(self, k, v) |
| 5563 | def __repr__(self): |
| 5564 | return "%s()<%r>" % (type(self).__name__, self.__getstate__()) |
| 5565 | |
| 5566 | class D(C): |
| 5567 | "A subclass of a class with slots." |
| 5568 | pass |
| 5569 | |
| 5570 | global E |
| 5571 | class E(C): |
| 5572 | "A subclass with an extra slot." |
| 5573 | __slots__ = ['b'] |
| 5574 | |
| 5575 | # Now it should work |
| 5576 | for pickle_copier in self._generate_pickle_copiers(): |
| 5577 | with self.subTest(pickle_copier=pickle_copier): |
| 5578 | x = C() |
| 5579 | y = pickle_copier.copy(x) |
| 5580 | self._assert_is_copy(x, y) |
| 5581 | |
| 5582 | x.a = 42 |
| 5583 | y = pickle_copier.copy(x) |
| 5584 | self._assert_is_copy(x, y) |
| 5585 | |
| 5586 | x = D() |
| 5587 | x.a = 42 |
| 5588 | x.b = 100 |
nothing calls this directly
no test coverage detected