summaryrefslogtreecommitdiff
path: root/Lib/ctypes/test/test_strings.py
blob: 4b58e7ca4ff3ae6427a985f9d76c3ace51ef07a1 (plain)
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
import unittest
from ctypes import *
from ctypes.test import need_symbol
from test import test_support

class StringArrayTestCase(unittest.TestCase):
    def test(self):
        BUF = c_char * 4

        buf = BUF("a", "b", "c")
        self.assertEqual(buf.value, "abc")
        self.assertEqual(buf.raw, "abc\000")

        buf.value = "ABCD"
        self.assertEqual(buf.value, "ABCD")
        self.assertEqual(buf.raw, "ABCD")

        buf.value = "x"
        self.assertEqual(buf.value, "x")
        self.assertEqual(buf.raw, "x\000CD")

        buf[1] = "Z"
        self.assertEqual(buf.value, "xZCD")
        self.assertEqual(buf.raw, "xZCD")

        self.assertRaises(ValueError, setattr, buf, "value", "aaaaaaaa")
        self.assertRaises(TypeError, setattr, buf, "value", 42)

    def test_c_buffer_value(self, memoryview=memoryview):
        buf = c_buffer(32)

        buf.value = "Hello, World"
        self.assertEqual(buf.value, "Hello, World")

        self.assertRaises(TypeError, setattr, buf, "value", memoryview("Hello, World"))
        self.assertRaises(TypeError, setattr, buf, "value", memoryview("abc"))
        self.assertRaises(ValueError, setattr, buf, "raw", memoryview("x" * 100))

    def test_c_buffer_raw(self, memoryview=memoryview):
        buf = c_buffer(32)

        buf.raw = memoryview("Hello, World")
        self.assertEqual(buf.value, "Hello, World")
        self.assertRaises(TypeError, setattr, buf, "value", memoryview("abc"))
        self.assertRaises(ValueError, setattr, buf, "raw", memoryview("x" * 100))

    def test_c_buffer_deprecated(self):
        # Compatibility with 2.x
        with test_support.check_py3k_warnings():
            self.test_c_buffer_value(buffer)
            self.test_c_buffer_raw(buffer)

    def test_param_1(self):
        BUF = c_char * 4
        buf = BUF()
##        print c_char_p.from_param(buf)

    def test_param_2(self):
        BUF = c_char * 4
        buf = BUF()
##        print BUF.from_param(c_char_p("python"))
##        print BUF.from_param(BUF(*"pyth"))

@need_symbol('c_wchar')
class WStringArrayTestCase(unittest.TestCase):
    def test(self):
        BUF = c_wchar * 4

        buf = BUF(u"a", u"b", u"c")
        self.assertEqual(buf.value, u"abc")

        buf.value = u"ABCD"
        self.assertEqual(buf.value, u"ABCD")

        buf.value = u"x"
        self.assertEqual(buf.value, u"x")

        buf[1] = u"Z"
        self.assertEqual(buf.value, u"xZCD")

class StringTestCase(unittest.TestCase):
    @unittest.skip('test disabled')
    def test_basic_strings(self):
        cs = c_string("abcdef")

        # Cannot call len on a c_string any longer
        self.assertRaises(TypeError, len, cs)
        self.assertEqual(sizeof(cs), 7)

        # The value property is the string up to the first terminating NUL.
        self.assertEqual(cs.value, "abcdef")
        self.assertEqual(c_string("abc\000def").value, "abc")

        # The raw property is the total buffer contents:
        self.assertEqual(cs.raw, "abcdef\000")
        self.assertEqual(c_string("abc\000def").raw, "abc\000def\000")

        # We can change the value:
        cs.value = "ab"
        self.assertEqual(cs.value, "ab")
        self.assertEqual(cs.raw, "ab\000\000\000\000\000")

        cs.raw = "XY"
        self.assertEqual(cs.value, "XY")
        self.assertEqual(cs.raw, "XY\000\000\000\000\000")

        self.assertRaises(TypeError, c_string, u"123")

    @unittest.skip('test disabled')
    def test_sized_strings(self):

        # New in releases later than 0.4.0:
        self.assertRaises(TypeError, c_string, None)

        # New in releases later than 0.4.0:
        # c_string(number) returns an empty string of size number
        self.assertEqual(len(c_string(32).raw), 32)
        self.assertRaises(ValueError, c_string, -1)
        self.assertRaises(ValueError, c_string, 0)

        # These tests fail, because it is no longer initialized
##        self.assertEqual(c_string(2).value, "")
##        self.assertEqual(c_string(2).raw, "\000\000")
        self.assertEqual(c_string(2).raw[-1], "\000")
        self.assertEqual(len(c_string(2).raw), 2)

    @unittest.skip('test disabled')
    def test_initialized_strings(self):

        self.assertEqual(c_string("ab", 4).raw[:2], "ab")
        self.assertEqual(c_string("ab", 4).raw[:2:], "ab")
        self.assertEqual(c_string("ab", 4).raw[:2:-1], "ba")
        self.assertEqual(c_string("ab", 4).raw[:2:2], "a")
        self.assertEqual(c_string("ab", 4).raw[-1], "\000")
        self.assertEqual(c_string("ab", 2).raw, "a\000")

    @unittest.skip('test disabled')
    def test_toolong(self):
        cs = c_string("abcdef")
        # Much too long string:
        self.assertRaises(ValueError, setattr, cs, "value", "123456789012345")

        # One char too long values:
        self.assertRaises(ValueError, setattr, cs, "value", "1234567")

    @unittest.skip('test disabled')
    def test_perf(self):
        check_perf()

@need_symbol('c_wchar')
class WStringTestCase(unittest.TestCase):
    def test_wchar(self):
        c_wchar(u"x")
        repr(byref(c_wchar(u"x")))
        c_wchar("x")


    @unittest.skip('test disabled')
    def test_basic_wstrings(self):
        cs = c_wstring(u"abcdef")

        # XXX This behaviour is about to change:
        # len returns the size of the internal buffer in bytes.
        # This includes the terminating NUL character.
        self.assertEqual(sizeof(cs), 14)

        # The value property is the string up to the first terminating NUL.
        self.assertEqual(cs.value, u"abcdef")
        self.assertEqual(c_wstring(u"abc\000def").value, u"abc")

        self.assertEqual(c_wstring(u"abc\000def").value, u"abc")

        # The raw property is the total buffer contents:
        self.assertEqual(cs.raw, u"abcdef\000")
        self.assertEqual(c_wstring(u"abc\000def").raw, u"abc\000def\000")

        # We can change the value:
        cs.value = u"ab"
        self.assertEqual(cs.value, u"ab")
        self.assertEqual(cs.raw, u"ab\000\000\000\000\000")

        self.assertRaises(TypeError, c_wstring, "123")
        self.assertRaises(ValueError, c_wstring, 0)

    @unittest.skip('test disabled')
    def test_toolong(self):
        cs = c_wstring(u"abcdef")
        # Much too long string:
        self.assertRaises(ValueError, setattr, cs, "value", u"123456789012345")

        # One char too long values:
        self.assertRaises(ValueError, setattr, cs, "value", u"1234567")


def run_test(rep, msg, func, arg):
    items = range(rep)
    from time import clock
    start = clock()
    for i in items:
        func(arg); func(arg); func(arg); func(arg); func(arg)
    stop = clock()
    print "%20s: %.2f us" % (msg, ((stop-start)*1e6/5/rep))

def check_perf():
    # Construct 5 objects

    REP = 200000

    run_test(REP, "c_string(None)", c_string, None)
    run_test(REP, "c_string('abc')", c_string, 'abc')

# Python 2.3 -OO, win2k, P4 700 MHz:
#
#      c_string(None): 1.75 us
#     c_string('abc'): 2.74 us

# Python 2.2 -OO, win2k, P4 700 MHz:
#
#      c_string(None): 2.95 us
#     c_string('abc'): 3.67 us


if __name__ == '__main__':
##    check_perf()
    unittest.main()