diff options
Diffstat (limited to 'Lib/test/test_bytes.py')
| -rw-r--r-- | Lib/test/test_bytes.py | 148 | 
1 files changed, 134 insertions, 14 deletions
| diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index cc312b1..05dc26a 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -300,6 +300,20 @@ class BaseBytesTest:          self.assertRaises(ValueError, self.type2test.fromhex, '\x00')          self.assertRaises(ValueError, self.type2test.fromhex, '12   \x00   34') +        for data, pos in ( +            # invalid first hexadecimal character +            ('12 x4 56', 3), +            # invalid second hexadecimal character +            ('12 3x 56', 4), +            # two invalid hexadecimal characters +            ('12 xy 56', 3), +            # test non-ASCII string +            ('12 3\xff 56', 4), +        ): +            with self.assertRaises(ValueError) as cm: +                self.type2test.fromhex(data) +            self.assertIn('at position %s' % pos, str(cm.exception)) +      def test_hex(self):          self.assertRaises(TypeError, self.type2test.hex)          self.assertRaises(TypeError, self.type2test.hex, 1) @@ -722,26 +736,107 @@ class BytesTest(BaseBytesTest, unittest.TestCase):      # Test PyBytes_FromFormat()      def test_from_format(self): -        test.support.import_module('ctypes') -        from ctypes import pythonapi, py_object, c_int, c_char_p +        ctypes = test.support.import_module('ctypes') +        _testcapi = test.support.import_module('_testcapi') +        from ctypes import pythonapi, py_object +        from ctypes import ( +            c_int, c_uint, +            c_long, c_ulong, +            c_size_t, c_ssize_t, +            c_char_p) +          PyBytes_FromFormat = pythonapi.PyBytes_FromFormat          PyBytes_FromFormat.restype = py_object +        # basic tests          self.assertEqual(PyBytes_FromFormat(b'format'),                           b'format') - +        self.assertEqual(PyBytes_FromFormat(b'Hello %s !', b'world'), +                         b'Hello world !') + +        # test formatters +        self.assertEqual(PyBytes_FromFormat(b'c=%c', c_int(0)), +                         b'c=\0') +        self.assertEqual(PyBytes_FromFormat(b'c=%c', c_int(ord('@'))), +                         b'c=@') +        self.assertEqual(PyBytes_FromFormat(b'c=%c', c_int(255)), +                         b'c=\xff') +        self.assertEqual(PyBytes_FromFormat(b'd=%d ld=%ld zd=%zd', +                                            c_int(1), c_long(2), +                                            c_size_t(3)), +                         b'd=1 ld=2 zd=3') +        self.assertEqual(PyBytes_FromFormat(b'd=%d ld=%ld zd=%zd', +                                            c_int(-1), c_long(-2), +                                            c_size_t(-3)), +                         b'd=-1 ld=-2 zd=-3') +        self.assertEqual(PyBytes_FromFormat(b'u=%u lu=%lu zu=%zu', +                                            c_uint(123), c_ulong(456), +                                            c_size_t(789)), +                         b'u=123 lu=456 zu=789') +        self.assertEqual(PyBytes_FromFormat(b'i=%i', c_int(123)), +                         b'i=123') +        self.assertEqual(PyBytes_FromFormat(b'i=%i', c_int(-123)), +                         b'i=-123') +        self.assertEqual(PyBytes_FromFormat(b'x=%x', c_int(0xabc)), +                         b'x=abc') + +        sizeof_ptr = ctypes.sizeof(c_char_p) + +        if os.name == 'nt': +            # Windows (MSCRT) +            ptr_format = '0x%0{}X'.format(2 * sizeof_ptr) +            def ptr_formatter(ptr): +                return (ptr_format % ptr) +        else: +            # UNIX (glibc) +            def ptr_formatter(ptr): +                return '%#x' % ptr + +        ptr = 0xabcdef +        self.assertEqual(PyBytes_FromFormat(b'ptr=%p', c_char_p(ptr)), +                         ('ptr=' + ptr_formatter(ptr)).encode('ascii')) +        self.assertEqual(PyBytes_FromFormat(b's=%s', c_char_p(b'cstr')), +                         b's=cstr') + +        # test minimum and maximum integer values +        size_max = c_size_t(-1).value +        for formatstr, ctypes_type, value, py_formatter in ( +            (b'%d', c_int, _testcapi.INT_MIN, str), +            (b'%d', c_int, _testcapi.INT_MAX, str), +            (b'%ld', c_long, _testcapi.LONG_MIN, str), +            (b'%ld', c_long, _testcapi.LONG_MAX, str), +            (b'%lu', c_ulong, _testcapi.ULONG_MAX, str), +            (b'%zd', c_ssize_t, _testcapi.PY_SSIZE_T_MIN, str), +            (b'%zd', c_ssize_t, _testcapi.PY_SSIZE_T_MAX, str), +            (b'%zu', c_size_t, size_max, str), +            (b'%p', c_char_p, size_max, ptr_formatter), +        ): +            self.assertEqual(PyBytes_FromFormat(formatstr, ctypes_type(value)), +                             py_formatter(value).encode('ascii')), + +        # width and precision (width is currently ignored) +        self.assertEqual(PyBytes_FromFormat(b'%5s', b'a'), +                         b'a') +        self.assertEqual(PyBytes_FromFormat(b'%.3s', b'abcdef'), +                         b'abc') + +        # '%%' formatter +        self.assertEqual(PyBytes_FromFormat(b'%%'), +                         b'%') +        self.assertEqual(PyBytes_FromFormat(b'[%%]'), +                         b'[%]') +        self.assertEqual(PyBytes_FromFormat(b'%%%c', c_int(ord('_'))), +                         b'%_') +        self.assertEqual(PyBytes_FromFormat(b'%%s'), +                         b'%s') + +        # Invalid formats and partial formatting          self.assertEqual(PyBytes_FromFormat(b'%'), b'%') -        self.assertEqual(PyBytes_FromFormat(b'%%'), b'%') -        self.assertEqual(PyBytes_FromFormat(b'%%s'), b'%s') -        self.assertEqual(PyBytes_FromFormat(b'[%%]'), b'[%]') -        self.assertEqual(PyBytes_FromFormat(b'%%%c', c_int(ord('_'))), b'%_') +        self.assertEqual(PyBytes_FromFormat(b'x=%i y=%', c_int(2), c_int(3)), +                         b'x=2 y=%') -        self.assertEqual(PyBytes_FromFormat(b'c:%c', c_int(255)), -                         b'c:\xff') -        self.assertEqual(PyBytes_FromFormat(b's:%s', c_char_p(b'cstr')), -                         b's:cstr') - -        # Issue #19969 +        # Issue #19969: %c must raise OverflowError for values +        # not in the range [0; 255]          self.assertRaises(OverflowError,                            PyBytes_FromFormat, b'%c', c_int(-1))          self.assertRaises(OverflowError, @@ -1504,7 +1599,32 @@ class SubclassTest:              self.assertEqual(type(a), type(b))              self.assertEqual(type(a.y), type(b.y)) -    test_fromhex = BaseBytesTest.test_fromhex +    def test_fromhex(self): +        b = self.type2test.fromhex('1a2B30') +        self.assertEqual(b, b'\x1a\x2b\x30') +        self.assertIs(type(b), self.type2test) + +        class B1(self.basetype): +            def __new__(cls, value): +                me = self.basetype.__new__(cls, value) +                me.foo = 'bar' +                return me + +        b = B1.fromhex('1a2B30') +        self.assertEqual(b, b'\x1a\x2b\x30') +        self.assertIs(type(b), B1) +        self.assertEqual(b.foo, 'bar') + +        class B2(self.basetype): +            def __init__(me, *args, **kwargs): +                if self.basetype is not bytes: +                    self.basetype.__init__(me, *args, **kwargs) +                me.foo = 'bar' + +        b = B2.fromhex('1a2B30') +        self.assertEqual(b, b'\x1a\x2b\x30') +        self.assertIs(type(b), B2) +        self.assertEqual(b.foo, 'bar')  class ByteArraySubclass(bytearray): | 
