diff options
Diffstat (limited to 'Lib/test/test_bytes.py')
| -rw-r--r-- | Lib/test/test_bytes.py | 137 | 
1 files changed, 116 insertions, 21 deletions
| diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 3c09141..0a73fcb 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -13,9 +13,11 @@ import functools  import pickle  import tempfile  import unittest +  import test.support  import test.string_tests  import test.buffer_tests +from test.support import bigaddrspacetest, MAX_Py_ssize_t  if sys.flags.bytes_warning: @@ -98,6 +100,14 @@ class BaseBytesTest:          self.assertRaises(TypeError, self.type2test, [0.0])          self.assertRaises(TypeError, self.type2test, [None])          self.assertRaises(TypeError, self.type2test, [C()]) +        self.assertRaises(TypeError, self.type2test, 0, 'ascii') +        self.assertRaises(TypeError, self.type2test, b'', 'ascii') +        self.assertRaises(TypeError, self.type2test, 0, errors='ignore') +        self.assertRaises(TypeError, self.type2test, b'', errors='ignore') +        self.assertRaises(TypeError, self.type2test, '') +        self.assertRaises(TypeError, self.type2test, '', errors='ignore') +        self.assertRaises(TypeError, self.type2test, '', b'ascii') +        self.assertRaises(TypeError, self.type2test, '', 'ascii', b'ignore')      def test_constructor_value_errors(self):          self.assertRaises(ValueError, self.type2test, [-1]) @@ -111,6 +121,17 @@ class BaseBytesTest:          self.assertRaises(ValueError, self.type2test, [sys.maxsize+1])          self.assertRaises(ValueError, self.type2test, [10**100]) +    @bigaddrspacetest +    def test_constructor_overflow(self): +        size = MAX_Py_ssize_t +        self.assertRaises((OverflowError, MemoryError), self.type2test, size) +        try: +            # Should either pass or raise an error (e.g. on debug builds with +            # additional malloc() overhead), but shouldn't crash. +            bytearray(size - 4) +        except (OverflowError, MemoryError): +            pass +      def test_compare(self):          b1 = self.type2test([1, 2, 3])          b2 = self.type2test([1, 2, 3]) @@ -288,8 +309,23 @@ class BaseBytesTest:              self.assertEqual(self.type2test(b"").join(lst), b"abc")              self.assertEqual(self.type2test(b"").join(tuple(lst)), b"abc")              self.assertEqual(self.type2test(b"").join(iter(lst)), b"abc") -        self.assertEqual(self.type2test(b".").join([b"ab", b"cd"]), b"ab.cd") -        # XXX more... +        dot_join = self.type2test(b".:").join +        self.assertEqual(dot_join([b"ab", b"cd"]), b"ab.:cd") +        self.assertEqual(dot_join([memoryview(b"ab"), b"cd"]), b"ab.:cd") +        self.assertEqual(dot_join([b"ab", memoryview(b"cd")]), b"ab.:cd") +        self.assertEqual(dot_join([bytearray(b"ab"), b"cd"]), b"ab.:cd") +        self.assertEqual(dot_join([b"ab", bytearray(b"cd")]), b"ab.:cd") +        # Stress it with many items +        seq = [b"abc"] * 1000 +        expected = b"abc" + b".:abc" * 999 +        self.assertEqual(dot_join(seq), expected) +        self.assertRaises(TypeError, self.type2test(b" ").join, None) +        # Error handling and cleanup when some item in the middle of the +        # sequence has the wrong type. +        with self.assertRaises(TypeError): +            dot_join([bytearray(b"ab"), "cd", b"ef"]) +        with self.assertRaises(TypeError): +            dot_join([memoryview(b"ab"), "cd", b"ef"])      def test_count(self):          b = self.type2test(b'mississippi') @@ -519,22 +555,23 @@ class BaseBytesTest:                  self.assertEqual(b, q)      def test_iterator_pickling(self): -        for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0": -            it = itorg = iter(self.type2test(b)) -            data = list(self.type2test(b)) -            d = pickle.dumps(it) -            it = pickle.loads(d) -            self.assertEqual(type(itorg), type(it)) -            self.assertEqual(list(it), data) - -            it = pickle.loads(d) -            try: -                next(it) -            except StopIteration: -                continue -            d = pickle.dumps(it) -            it = pickle.loads(d) -            self.assertEqual(list(it), data[1:]) +        for proto in range(pickle.HIGHEST_PROTOCOL + 1): +            for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0": +                it = itorg = iter(self.type2test(b)) +                data = list(self.type2test(b)) +                d = pickle.dumps(it, proto) +                it = pickle.loads(d) +                self.assertEqual(type(itorg), type(it)) +                self.assertEqual(list(it), data) + +                it = pickle.loads(d) +                try: +                    next(it) +                except StopIteration: +                    continue +                d = pickle.dumps(it, proto) +                it = pickle.loads(d) +                self.assertEqual(list(it), data[1:])      def test_strip(self):          b = self.type2test(b'mississippi') @@ -686,7 +723,7 @@ class BytesTest(BaseBytesTest, unittest.TestCase):      type2test = bytes      def test_buffer_is_readonly(self): -        fd = os.dup(sys.stdin.fileno()) +        fd = os.open(__file__, os.O_RDONLY)          with open(fd, "rb", buffering=0) as f:              self.assertRaises(TypeError, f.readinto, b"") @@ -707,6 +744,14 @@ class BytesTest(BaseBytesTest, unittest.TestCase):              def __index__(self):                  return 42          self.assertEqual(bytes(A()), b'a') +        # Issue #24731 +        class A: +            def __bytes__(self): +                return OtherBytesSubclass(b'abc') +        self.assertEqual(bytes(A()), b'abc') +        self.assertIs(type(bytes(A())), OtherBytesSubclass) +        self.assertEqual(BytesSubclass(A()), b'abc') +        self.assertIs(type(BytesSubclass(A())), BytesSubclass)      # Test PyBytes_FromFormat()      def test_from_format(self): @@ -765,7 +810,7 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase):          finally:              try:                  os.remove(tfn) -            except os.error: +            except OSError:                  pass      def test_reverse(self): @@ -901,6 +946,31 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase):              with self.assertRaises(ValueError):                  b[3:4] = elem +    def test_setslice_extend(self): +        # Exercise the resizing logic (see issue #19087) +        b = bytearray(range(100)) +        self.assertEqual(list(b), list(range(100))) +        del b[:10] +        self.assertEqual(list(b), list(range(10, 100))) +        b.extend(range(100, 110)) +        self.assertEqual(list(b), list(range(10, 110))) + +    def test_fifo_overrun(self): +        # Test for issue #23985, a buffer overrun when implementing a FIFO +        # Build Python in pydebug mode for best results. +        b = bytearray(10) +        b.pop()        # Defeat expanding buffer off-by-one quirk +        del b[:1]      # Advance start pointer without reallocating +        b += bytes(2)  # Append exactly the number of deleted bytes +        del b          # Free memory buffer, allowing pydebug verification + +    def test_del_expand(self): +        # Reducing the size should not expand the buffer (issue #23985) +        b = bytearray(10) +        size = sys.getsizeof(b) +        del b[:1] +        self.assertLessEqual(sys.getsizeof(b), size) +      def test_extended_set_del_slice(self):          indices = (0, None, 1, 3, 19, 300, 1<<333, -1, -2, -31, -300)          for start in indices: @@ -968,10 +1038,27 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase):          for i in range(100):              b += b"x"              alloc = b.__alloc__() -            self.assertTrue(alloc >= len(b)) +            self.assertGreater(alloc, len(b))  # including trailing null byte              if alloc not in seq:                  seq.append(alloc) +    def test_init_alloc(self): +        b = bytearray() +        def g(): +            for i in range(1, 100): +                yield i +                a = list(b) +                self.assertEqual(a, list(range(1, len(a)+1))) +                self.assertEqual(len(b), len(a)) +                self.assertLessEqual(len(b), i) +                alloc = b.__alloc__() +                self.assertGreater(alloc, len(b))  # including trailing null byte +        b.__init__(g()) +        self.assertEqual(list(b), list(range(1, 100))) +        self.assertEqual(len(b), 99) +        alloc = b.__alloc__() +        self.assertGreater(alloc, len(b)) +      def test_extend(self):          orig = b'hello'          a = bytearray(orig) @@ -1280,6 +1367,11 @@ class BytearrayPEP3137Test(unittest.TestCase,              self.assertEqual(val, newval)              self.assertTrue(val is not newval,                              expr+' returned val on a mutable object') +        sep = self.marshal(b'') +        newval = sep.join([val]) +        self.assertEqual(val, newval) +        self.assertIsNot(val, newval) +  class FixedStringTest(test.string_tests.BaseTest): @@ -1381,6 +1473,9 @@ class ByteArraySubclass(bytearray):  class BytesSubclass(bytes):      pass +class OtherBytesSubclass(bytes): +    pass +  class ByteArraySubclassTest(SubclassTest, unittest.TestCase):      type2test = bytearray      subclass2test = ByteArraySubclass | 
