1 from ctypes import * 2 import unittest, sys 3 from ctypes.test import is_resource_enabled 4 5 ################################################################ 6 # This section should be moved into ctypes\__init__.py, when it's ready. 7 8 from _ctypes import PyObj_FromPtr 9 10 ################################################################ 11 12 from sys import getrefcount as grc 13 if sys.version_info > (2, 4): 14 c_py_ssize_t = c_size_t 15 else: 16 c_py_ssize_t = c_int 17 18 class PythonAPITestCase(unittest.TestCase): 19 20 def test_PyString_FromStringAndSize(self): 21 PyString_FromStringAndSize = pythonapi.PyString_FromStringAndSize 22 23 PyString_FromStringAndSize.restype = py_object 24 PyString_FromStringAndSize.argtypes = c_char_p, c_py_ssize_t 25 26 self.assertEqual(PyString_FromStringAndSize("abcdefghi", 3), "abc") 27 28 def test_PyString_FromString(self): 29 pythonapi.PyString_FromString.restype = py_object 30 pythonapi.PyString_FromString.argtypes = (c_char_p,) 31 32 s = "abc" 33 refcnt = grc(s) 34 pyob = pythonapi.PyString_FromString(s) 35 self.assertEqual(grc(s), refcnt) 36 self.assertEqual(s, pyob) 37 del pyob 38 self.assertEqual(grc(s), refcnt) 39 40 if is_resource_enabled("refcount"): 41 # This test is unreliable, because it is possible that code in 42 # unittest changes the refcount of the '42' integer. So, it 43 # is disabled by default. 44 def test_PyInt_Long(self): 45 ref42 = grc(42) 46 pythonapi.PyInt_FromLong.restype = py_object 47 self.assertEqual(pythonapi.PyInt_FromLong(42), 42) 48 49 self.assertEqual(grc(42), ref42) 50 51 pythonapi.PyInt_AsLong.argtypes = (py_object,) 52 pythonapi.PyInt_AsLong.restype = c_long 53 54 res = pythonapi.PyInt_AsLong(42) 55 self.assertEqual(grc(res), ref42 + 1) 56 del res 57 self.assertEqual(grc(42), ref42) 58 59 def test_PyObj_FromPtr(self): 60 s = "abc def ghi jkl" 61 ref = grc(s) 62 # id(python-object) is the address 63 pyobj = PyObj_FromPtr(id(s)) 64 self.assertTrue(s is pyobj) 65 66 self.assertEqual(grc(s), ref + 1) 67 del pyobj 68 self.assertEqual(grc(s), ref) 69 70 def test_PyOS_snprintf(self): 71 PyOS_snprintf = pythonapi.PyOS_snprintf 72 PyOS_snprintf.argtypes = POINTER(c_char), c_size_t, c_char_p 73 74 buf = c_buffer(256) 75 PyOS_snprintf(buf, sizeof(buf), "Hello from %s", "ctypes") 76 self.assertEqual(buf.value, "Hello from ctypes") 77 78 PyOS_snprintf(buf, sizeof(buf), "Hello from %s", "ctypes", 1, 2, 3) 79 self.assertEqual(buf.value, "Hello from ctypes") 80 81 # not enough arguments 82 self.assertRaises(TypeError, PyOS_snprintf, buf) 83 84 def test_pyobject_repr(self): 85 self.assertEqual(repr(py_object()), "py_object(<NULL>)") 86 self.assertEqual(repr(py_object(42)), "py_object(42)") 87 self.assertEqual(repr(py_object(object)), "py_object(%r)" % object) 88 89 if __name__ == "__main__": 90 unittest.main() 91