|
9 | 9 | import io |
10 | 10 | import _pyio as pyio |
11 | 11 | import pickle |
| 12 | +import sys |
12 | 13 |
|
13 | 14 | class MemorySeekTestMixin: |
14 | 15 |
|
@@ -711,12 +712,57 @@ def test_setstate(self): |
711 | 712 |
|
712 | 713 | @support.cpython_only |
713 | 714 | def test_sizeof(self): |
714 | | - basesize = support.calcobjsize('P2nN2Pn') |
| 715 | + basesize = support.calcobjsize('P2nN2PnP') |
715 | 716 | check = self.check_sizeof |
716 | 717 | self.assertEqual(object.__sizeof__(io.BytesIO()), basesize) |
717 | 718 | check(io.BytesIO(), basesize ) |
718 | | - check(io.BytesIO(b'a'), basesize + 1 + 1 ) |
719 | | - check(io.BytesIO(b'a' * 1000), basesize + 1000 + 1 ) |
| 719 | + check(io.BytesIO(b'a'), basesize + 1 ) |
| 720 | + check(io.BytesIO(b'a' * 1000), basesize + 1000) |
| 721 | + |
| 722 | + # Various tests of copy-on-write behaviour for BytesIO. |
| 723 | + |
| 724 | + def _test_cow_mutation(self, mutation): |
| 725 | + # Common code for all BytesIO copy-on-write mutation tests. |
| 726 | + imm = b' ' * 1024 |
| 727 | + old_rc = sys.getrefcount(imm) |
| 728 | + memio = self.ioclass(imm) |
| 729 | + self.assertEqual(sys.getrefcount(imm), old_rc + 1) |
| 730 | + mutation(memio) |
| 731 | + self.assertEqual(sys.getrefcount(imm), old_rc) |
| 732 | + |
| 733 | + @support.cpython_only |
| 734 | + def test_cow_truncate(self): |
| 735 | + # Ensure truncate causes a copy. |
| 736 | + def mutation(memio): |
| 737 | + memio.truncate(1) |
| 738 | + self._test_cow_mutation(mutation) |
| 739 | + |
| 740 | + @support.cpython_only |
| 741 | + def test_cow_write(self): |
| 742 | + # Ensure write that would not cause a resize still results in a copy. |
| 743 | + def mutation(memio): |
| 744 | + memio.seek(0) |
| 745 | + memio.write(b'foo') |
| 746 | + self._test_cow_mutation(mutation) |
| 747 | + |
| 748 | + @support.cpython_only |
| 749 | + def test_cow_setstate(self): |
| 750 | + # __setstate__ should cause buffer to be released. |
| 751 | + memio = self.ioclass(b'foooooo') |
| 752 | + state = memio.__getstate__() |
| 753 | + def mutation(memio): |
| 754 | + memio.__setstate__(state) |
| 755 | + self._test_cow_mutation(mutation) |
| 756 | + |
| 757 | + @support.cpython_only |
| 758 | + def test_cow_mutable(self): |
| 759 | + # BytesIO should accept only Bytes for copy-on-write sharing, since |
| 760 | + # arbitrary buffer-exporting objects like bytearray() aren't guaranteed |
| 761 | + # to be immutable. |
| 762 | + ba = bytearray(1024) |
| 763 | + old_rc = sys.getrefcount(ba) |
| 764 | + memio = self.ioclass(ba) |
| 765 | + self.assertEqual(sys.getrefcount(ba), old_rc) |
720 | 766 |
|
721 | 767 | class CStringIOTest(PyStringIOTest): |
722 | 768 | ioclass = io.StringIO |
|
0 commit comments