Learn more  » Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

agriconnect / libpython3.8-testsuite   deb

Repository URL to install this package:

/ usr / lib / python3.8 / test / test_bytes.py

"""Unit tests for the bytes and bytearray types.

XXX This is a mess.  Common tests should be unified with string_tests.py (and
the latter should be modernized).
"""

import array
import os
import re
import sys
import copy
import functools
import pickle
import tempfile
import unittest

import test.support
import test.string_tests
import test.list_tests
from test.support import bigaddrspacetest, MAX_Py_ssize_t


if sys.flags.bytes_warning:
    def check_bytes_warnings(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            with test.support.check_warnings(('', BytesWarning)):
                return func(*args, **kw)
        return wrapper
else:
    # no-op
    def check_bytes_warnings(func):
        return func


class Indexable:
    def __init__(self, value=0):
        self.value = value
    def __index__(self):
        return self.value


class BaseBytesTest:

    def test_basics(self):
        b = self.type2test()
        self.assertEqual(type(b), self.type2test)
        self.assertEqual(b.__class__, self.type2test)

    def test_copy(self):
        a = self.type2test(b"abcd")
        for copy_method in (copy.copy, copy.deepcopy):
            b = copy_method(a)
            self.assertEqual(a, b)
            self.assertEqual(type(a), type(b))

    def test_empty_sequence(self):
        b = self.type2test()
        self.assertEqual(len(b), 0)
        self.assertRaises(IndexError, lambda: b[0])
        self.assertRaises(IndexError, lambda: b[1])
        self.assertRaises(IndexError, lambda: b[sys.maxsize])
        self.assertRaises(IndexError, lambda: b[sys.maxsize+1])
        self.assertRaises(IndexError, lambda: b[10**100])
        self.assertRaises(IndexError, lambda: b[-1])
        self.assertRaises(IndexError, lambda: b[-2])
        self.assertRaises(IndexError, lambda: b[-sys.maxsize])
        self.assertRaises(IndexError, lambda: b[-sys.maxsize-1])
        self.assertRaises(IndexError, lambda: b[-sys.maxsize-2])
        self.assertRaises(IndexError, lambda: b[-10**100])

    def test_from_iterable(self):
        b = self.type2test(range(256))
        self.assertEqual(len(b), 256)
        self.assertEqual(list(b), list(range(256)))

        # Non-sequence iterable.
        b = self.type2test({42})
        self.assertEqual(b, b"*")
        b = self.type2test({43, 45})
        self.assertIn(tuple(b), {(43, 45), (45, 43)})

        # Iterator that has a __length_hint__.
        b = self.type2test(iter(range(256)))
        self.assertEqual(len(b), 256)
        self.assertEqual(list(b), list(range(256)))

        # Iterator that doesn't have a __length_hint__.
        b = self.type2test(i for i in range(256) if i % 2)
        self.assertEqual(len(b), 128)
        self.assertEqual(list(b), list(range(256))[1::2])

        # Sequence without __iter__.
        class S:
            def __getitem__(self, i):
                return (1, 2, 3)[i]
        b = self.type2test(S())
        self.assertEqual(b, b"\x01\x02\x03")

    def test_from_tuple(self):
        # There is a special case for tuples.
        b = self.type2test(tuple(range(256)))
        self.assertEqual(len(b), 256)
        self.assertEqual(list(b), list(range(256)))
        b = self.type2test((1, 2, 3))
        self.assertEqual(b, b"\x01\x02\x03")

    def test_from_list(self):
        # There is a special case for lists.
        b = self.type2test(list(range(256)))
        self.assertEqual(len(b), 256)
        self.assertEqual(list(b), list(range(256)))
        b = self.type2test([1, 2, 3])
        self.assertEqual(b, b"\x01\x02\x03")

    def test_from_mutating_list(self):
        # Issue #34973: Crash in bytes constructor with mutating list.
        class X:
            def __index__(self):
                a.clear()
                return 42
        a = [X(), X()]
        self.assertEqual(bytes(a), b'*')

        class Y:
            def __index__(self):
                if len(a) < 1000:
                    a.append(self)
                return 42
        a = [Y()]
        self.assertEqual(bytes(a), b'*' * 1000)  # should not crash

    def test_from_index(self):
        b = self.type2test([Indexable(), Indexable(1), Indexable(254),
                            Indexable(255)])
        self.assertEqual(list(b), [0, 1, 254, 255])
        self.assertRaises(ValueError, self.type2test, [Indexable(-1)])
        self.assertRaises(ValueError, self.type2test, [Indexable(256)])

    def test_from_buffer(self):
        a = self.type2test(array.array('B', [1, 2, 3]))
        self.assertEqual(a, b"\x01\x02\x03")
        a = self.type2test(b"\x01\x02\x03")
        self.assertEqual(a, b"\x01\x02\x03")

        # Issues #29159 and #34974.
        # Fallback when __index__ raises a TypeError
        class B(bytes):
            def __index__(self):
                raise TypeError

        self.assertEqual(self.type2test(B(b"foobar")), b"foobar")

    def test_from_ssize(self):
        self.assertEqual(self.type2test(0), b'')
        self.assertEqual(self.type2test(1), b'\x00')
        self.assertEqual(self.type2test(5), b'\x00\x00\x00\x00\x00')
        self.assertRaises(ValueError, self.type2test, -1)

        self.assertEqual(self.type2test('0', 'ascii'), b'0')
        self.assertEqual(self.type2test(b'0'), b'0')
        self.assertRaises(OverflowError, self.type2test, sys.maxsize + 1)

    def test_constructor_type_errors(self):
        self.assertRaises(TypeError, self.type2test, 0.0)
        class C:
            pass
        self.assertRaises(TypeError, self.type2test, ["0"])
        self.assertRaises(TypeError, self.type2test, [0.0])
        self.assertRaises(TypeError, self.type2test, [None])
        self.assertRaises(TypeError, self.type2test, [C()])
        self.assertRaises(TypeError, self.type2test, encoding='ascii')
        self.assertRaises(TypeError, self.type2test, errors='ignore')
        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])
        self.assertRaises(ValueError, self.type2test, [-sys.maxsize])
        self.assertRaises(ValueError, self.type2test, [-sys.maxsize-1])
        self.assertRaises(ValueError, self.type2test, [-sys.maxsize-2])
        self.assertRaises(ValueError, self.type2test, [-10**100])
        self.assertRaises(ValueError, self.type2test, [256])
        self.assertRaises(ValueError, self.type2test, [257])
        self.assertRaises(ValueError, self.type2test, [sys.maxsize])
        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_constructor_exceptions(self):
        # Issue #34974: bytes and bytearray constructors replace unexpected
        # exceptions.
        class BadInt:
            def __index__(self):
                1/0
        self.assertRaises(ZeroDivisionError, self.type2test, BadInt())
        self.assertRaises(ZeroDivisionError, self.type2test, [BadInt()])

        class BadIterable:
            def __iter__(self):
                1/0
        self.assertRaises(ZeroDivisionError, self.type2test, BadIterable())

    def test_compare(self):
        b1 = self.type2test([1, 2, 3])
        b2 = self.type2test([1, 2, 3])
        b3 = self.type2test([1, 3])

        self.assertEqual(b1, b2)
        self.assertTrue(b2 != b3)
        self.assertTrue(b1 <= b2)
        self.assertTrue(b1 <= b3)
        self.assertTrue(b1 <  b3)
        self.assertTrue(b1 >= b2)
        self.assertTrue(b3 >= b2)
        self.assertTrue(b3 >  b2)

        self.assertFalse(b1 != b2)
        self.assertFalse(b2 == b3)
        self.assertFalse(b1 >  b2)
        self.assertFalse(b1 >  b3)
        self.assertFalse(b1 >= b3)
        self.assertFalse(b1 <  b2)
        self.assertFalse(b3 <  b2)
        self.assertFalse(b3 <= b2)

    @check_bytes_warnings
    def test_compare_to_str(self):
        # Byte comparisons with unicode should always fail!
        # Test this for all expected byte orders and Unicode character
        # sizes.
        self.assertEqual(self.type2test(b"\0a\0b\0c") == "abc", False)
        self.assertEqual(self.type2test(b"\0\0\0a\0\0\0b\0\0\0c") == "abc",
                            False)
        self.assertEqual(self.type2test(b"a\0b\0c\0") == "abc", False)
        self.assertEqual(self.type2test(b"a\0\0\0b\0\0\0c\0\0\0") == "abc",
                            False)
        self.assertEqual(self.type2test() == str(), False)
        self.assertEqual(self.type2test() != str(), True)

    def test_reversed(self):
        input = list(map(ord, "Hello"))
        b = self.type2test(input)
        output = list(reversed(b))
        input.reverse()
        self.assertEqual(output, input)

    def test_getslice(self):
        def by(s):
            return self.type2test(map(ord, s))
        b = by("Hello, world")

        self.assertEqual(b[:5], by("Hello"))
        self.assertEqual(b[1:5], by("ello"))
        self.assertEqual(b[5:7], by(", "))
        self.assertEqual(b[7:], by("world"))
        self.assertEqual(b[7:12], by("world"))
        self.assertEqual(b[7:100], by("world"))

        self.assertEqual(b[:-7], by("Hello"))
        self.assertEqual(b[-11:-7], by("ello"))
        self.assertEqual(b[-7:-5], by(", "))
        self.assertEqual(b[-5:], by("world"))
        self.assertEqual(b[-5:12], by("world"))
        self.assertEqual(b[-5:100], by("world"))
        self.assertEqual(b[-100:5], by("Hello"))

    def test_extended_getslice(self):
        # Test extended slicing by comparing with list slicing.
        L = list(range(255))
        b = self.type2test(L)
        indices = (0, None, 1, 3, 19, 100, sys.maxsize, -1, -2, -31, -100)
        for start in indices:
            for stop in indices:
                # Skip step 0 (invalid)
                for step in indices[1:]:
                    self.assertEqual(b[start:stop:step], self.type2test(L[start:stop:step]))

    def test_encoding(self):
        sample = "Hello world\n\u1234\u5678\u9abc"
        for enc in ("utf-8", "utf-16"):
            b = self.type2test(sample, enc)
            self.assertEqual(b, self.type2test(sample.encode(enc)))
        self.assertRaises(UnicodeEncodeError, self.type2test, sample, "latin-1")
        b = self.type2test(sample, "latin-1", "ignore")
        self.assertEqual(b, self.type2test(sample[:-3], "utf-8"))

    def test_decode(self):
        sample = "Hello world\n\u1234\u5678\u9abc"
        for enc in ("utf-8", "utf-16"):
            b = self.type2test(sample, enc)
            self.assertEqual(b.decode(enc), sample)
        sample = "Hello world\n\x80\x81\xfe\xff"
        b = self.type2test(sample, "latin-1")
        self.assertRaises(UnicodeDecodeError, b.decode, "utf-8")
        self.assertEqual(b.decode("utf-8", "ignore"), "Hello world\n")
        self.assertEqual(b.decode(errors="ignore", encoding="utf-8"),
                         "Hello world\n")
        # Default encoding is utf-8
        self.assertEqual(self.type2test(b'\xe2\x98\x83').decode(), '\u2603')

    def test_from_int(self):
        b = self.type2test(0)
        self.assertEqual(b, self.type2test())
        b = self.type2test(10)
        self.assertEqual(b, self.type2test([0]*10))
        b = self.type2test(10000)
        self.assertEqual(b, self.type2test([0]*10000))

    def test_concat(self):
        b1 = self.type2test(b"abc")
        b2 = self.type2test(b"def")
        self.assertEqual(b1 + b2, b"abcdef")
        self.assertEqual(b1 + bytes(b"def"), b"abcdef")
        self.assertEqual(bytes(b"def") + b1, b"defabc")
        self.assertRaises(TypeError, lambda: b1 + "def")
        self.assertRaises(TypeError, lambda: "abc" + b2)

    def test_repeat(self):
        for b in b"abc", self.type2test(b"abc"):
            self.assertEqual(b * 3, b"abcabcabc")
            self.assertEqual(b * 0, b"")
            self.assertEqual(b * -1, b"")
            self.assertRaises(TypeError, lambda: b * 3.14)
            self.assertRaises(TypeError, lambda: 3.14 * b)
            # XXX Shouldn't bytes and bytearray agree on what to raise?
            with self.assertRaises((OverflowError, MemoryError)):
                c = b * sys.maxsize
            with self.assertRaises((OverflowError, MemoryError)):
Loading ...