summaryrefslogtreecommitdiff
path: root/lib/python2.7/ctypes/test/test_python_api.py
blob: 698170f901da3cff3256a4d7033684cc1144c6c2 (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
from ctypes import *
import unittest, sys
from ctypes.test import is_resource_enabled

################################################################
# This section should be moved into ctypes\__init__.py, when it's ready.

from _ctypes import PyObj_FromPtr

################################################################

from sys import getrefcount as grc
if sys.version_info > (2, 4):
    c_py_ssize_t = c_size_t
else:
    c_py_ssize_t = c_int

class PythonAPITestCase(unittest.TestCase):

    def test_PyString_FromStringAndSize(self):
        PyString_FromStringAndSize = pythonapi.PyString_FromStringAndSize

        PyString_FromStringAndSize.restype = py_object
        PyString_FromStringAndSize.argtypes = c_char_p, c_py_ssize_t

        self.assertEqual(PyString_FromStringAndSize("abcdefghi", 3), "abc")

    def test_PyString_FromString(self):
        pythonapi.PyString_FromString.restype = py_object
        pythonapi.PyString_FromString.argtypes = (c_char_p,)

        s = "abc"
        refcnt = grc(s)
        pyob = pythonapi.PyString_FromString(s)
        self.assertEqual(grc(s), refcnt)
        self.assertEqual(s, pyob)
        del pyob
        self.assertEqual(grc(s), refcnt)

    if is_resource_enabled("refcount"):
        # This test is unreliable, because it is possible that code in
        # unittest changes the refcount of the '42' integer.  So, it
        # is disabled by default.
        def test_PyInt_Long(self):
            ref42 = grc(42)
            pythonapi.PyInt_FromLong.restype = py_object
            self.assertEqual(pythonapi.PyInt_FromLong(42), 42)

            self.assertEqual(grc(42), ref42)

            pythonapi.PyInt_AsLong.argtypes = (py_object,)
            pythonapi.PyInt_AsLong.restype = c_long

            res = pythonapi.PyInt_AsLong(42)
            self.assertEqual(grc(res), ref42 + 1)
            del res
            self.assertEqual(grc(42), ref42)

    def test_PyObj_FromPtr(self):
        s = "abc def ghi jkl"
        ref = grc(s)
        # id(python-object) is the address
        pyobj = PyObj_FromPtr(id(s))
        self.assertTrue(s is pyobj)

        self.assertEqual(grc(s), ref + 1)
        del pyobj
        self.assertEqual(grc(s), ref)

    def test_PyOS_snprintf(self):
        PyOS_snprintf = pythonapi.PyOS_snprintf
        PyOS_snprintf.argtypes = POINTER(c_char), c_size_t, c_char_p

        buf = c_buffer(256)
        PyOS_snprintf(buf, sizeof(buf), "Hello from %s", "ctypes")
        self.assertEqual(buf.value, "Hello from ctypes")

        PyOS_snprintf(buf, sizeof(buf), "Hello from %s", "ctypes", 1, 2, 3)
        self.assertEqual(buf.value, "Hello from ctypes")

        # not enough arguments
        self.assertRaises(TypeError, PyOS_snprintf, buf)

    def test_pyobject_repr(self):
        self.assertEqual(repr(py_object()), "py_object(<NULL>)")
        self.assertEqual(repr(py_object(42)), "py_object(42)")
        self.assertEqual(repr(py_object(object)), "py_object(%r)" % object)

if __name__ == "__main__":
    unittest.main()