File: test_runpack.py

package info (click to toggle)
pypy 7.0.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 107,216 kB
  • sloc: python: 1,201,787; ansic: 62,419; asm: 5,169; cpp: 3,017; sh: 2,534; makefile: 545; xml: 243; lisp: 45; awk: 4
file content (120 lines) | stat: -rw-r--r-- 4,156 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import pytest
from rpython.rtyper.test.tool import BaseRtypingTest
from rpython.rlib.rstruct.runpack import runpack
from rpython.rlib.rstruct import standardfmttable
from rpython.rlib.rstruct.error import StructError
from rpython.rlib.rarithmetic import LONG_BIT
import struct

class TestRStruct(BaseRtypingTest):
    def test_unpack(self):
        import sys
        pad = '\x00' * (LONG_BIT//8-1)    # 3 or 7 null bytes
        def fn():
            return runpack('sll', 'a'+pad+'\x03'+pad+'\x04'+pad)[1]
        result = 3 if sys.byteorder == 'little' else 3 << (LONG_BIT-8)
        assert fn() == result
        assert self.interpret(fn, []) == result

    def test_unpack_2(self):
        data = struct.pack('iiii', 0, 1, 2, 4)
        def fn():
            a, b, c, d = runpack('iiii', data)
            return a * 1000 + b * 100 + c * 10 + d
        assert fn() == 124
        assert self.interpret(fn, []) == 124

    def test_unpack_error(self):
        data = '123' # 'i' expects 4 bytes, not 3
        def fn():
            try:
                runpack('i', data)
            except StructError:
                return True
            else:
                return False
        assert fn()
        assert self.interpret(fn, [])

    def test_unpack_single(self):
        data = struct.pack('i', 123)
        def fn():
            return runpack('i', data)
        assert fn() == 123
        assert self.interpret(fn, []) == 123

    def test_unpack_big_endian(self):
        def fn():
            return runpack(">i", "\x01\x02\x03\x04")
        assert fn() == 0x01020304
        assert self.interpret(fn, []) == 0x01020304

    def test_unpack_double_big_endian(self):
        def fn():
            return runpack(">d", "testtest")
        assert fn() == struct.unpack(">d", "testtest")[0]
        assert self.interpret(fn, []) == struct.unpack(">d", "testtest")[0]

    def test_native_floats(self):
        """
        Check the 'd' and 'f' format characters on native packing.
        """
        d_data = struct.pack("df", 12.34, 12.34)
        def fn():
            d, f = runpack("@df", d_data)
            return d, f
        #
        # direct test
        d, f = fn()
        assert d == 12.34     # no precision lost
        assert f != 12.34     # precision lost
        assert abs(f - 12.34) < 1E-6
        #
        # translated test
        res = self.interpret(fn, [])
        d = res.item0
        f = res.item1  # convert from r_singlefloat
        assert d == 12.34     # no precision lost
        assert f != 12.34     # precision lost
        assert abs(f - 12.34) < 1E-6

    def test_unpack_halffloat(self):
        assert runpack(">e", b"\x7b\xef") == 64992.0
        assert runpack("<e", b"\xef\x7b") == 64992.0

    def test_unpack_standard_little(self):
        def unpack(fmt, data):
            def fn():
                return runpack(fmt, data)
            return self.interpret(fn, [])
        #
        assert unpack("<i", 'DCBA') == 0x41424344
        assert unpack("<i", '\xfd\xff\xff\xff') == -3
        assert unpack("<i", '\x00\x00\x00\x80') == -2147483648
        assert unpack("<I", 'DCB\x81') == 0x81424344
        assert unpack("<q", 'HGFEDCBA') == 0x4142434445464748
        assert unpack("<q", 'HHIJKLM\xbe') == -0x41B2B3B4B5B6B7B8
        assert unpack("<Q", 'HGFEDCB\x81') == 0x8142434445464748

    def test_unpack_standard_big(self):
        def unpack(fmt, data):
            def fn():
                return runpack(fmt, data)
            return self.interpret(fn, [])
        #
        assert unpack(">i", 'ABCD') == 0x41424344
        assert unpack(">i", '\xff\xff\xff\xfd') == -3
        assert unpack(">i", '\x80\x00\x00\x00') == -2147483648
        assert unpack(">I", '\x81BCD') == 0x81424344
        assert unpack(">q", 'ABCDEFGH') == 0x4142434445464748
        assert unpack(">q", '\xbeMLKJIHH') == -0x41B2B3B4B5B6B7B8
        assert unpack(">Q", '\x81BCDEFGH') == 0x8142434445464748


class TestNoFastPath(TestRStruct):

    def setup_method(self, meth):
        standardfmttable.USE_FASTPATH = False

    def teardown_method(self, meth):
        standardfmttable.USE_FASTPATH = True