Staging
v0.5.1
https://github.com/python/cpython
Raw File
Tip revision: 9ad18bbb529e13fd1125ec1e38047de651d935a7 authored by Neal Norwitz on 04 April 2006, 19:29:29 UTC
we need os.path too for the normal run on windows
Tip revision: 9ad18bb
test_prototypes.py
from ctypes import *
import unittest

# IMPORTANT INFO:
#
# Consider this call:
#    func.restype = c_char_p
#    func(c_char_p("123"))
# It returns
#    "123"
#
# WHY IS THIS SO?
#
# argument tuple (c_char_p("123"), ) is destroyed after the function
# func is called, but NOT before the result is actually built.
#
# If the arglist would be destroyed BEFORE the result has been built,
# the c_char_p("123") object would already have a zero refcount,
# and the pointer passed to (and returned by) the function would
# probably point to deallocated space.
#
# In this case, there would have to be an additional reference to the argument...

import _ctypes_test
testdll = cdll.load(_ctypes_test.__file__)

def c_wbuffer(init):
    n = len(init) + 1
    return (c_wchar * n)(*init)

class CharPointersTestCase(unittest.TestCase):

    def setUp(self):
        func = testdll._testfunc_p_p
        func.restype = c_long
        func.argtypes = None

    def test_int_pointer_arg(self):
        func = testdll._testfunc_p_p
        func.restype = c_long
        self.failUnlessEqual(0, func(0))

        ci = c_int(0)

        func.argtypes = POINTER(c_int),
        self.failUnlessEqual(addressof(ci), func(byref(ci)))

        func.argtypes = c_char_p,
        self.assertRaises(ArgumentError, func, byref(ci))

        func.argtypes = POINTER(c_short),
        self.assertRaises(ArgumentError, func, byref(ci))

        func.argtypes = POINTER(c_double),
        self.assertRaises(ArgumentError, func, byref(ci))

    def test_POINTER_c_char_arg(self):
        func = testdll._testfunc_p_p
        func.restype = c_char_p
        func.argtypes = POINTER(c_char),

        self.failUnlessEqual(None, func(None))
        self.failUnlessEqual("123", func("123"))
        self.failUnlessEqual(None, func(c_char_p(None)))
        self.failUnlessEqual("123", func(c_char_p("123")))

        self.failUnlessEqual("123", func(c_buffer("123")))
        ca = c_char("a")
        self.failUnlessEqual("a", func(pointer(ca))[0])
        self.failUnlessEqual("a", func(byref(ca))[0])

    def test_c_char_p_arg(self):
        func = testdll._testfunc_p_p
        func.restype = c_char_p
        func.argtypes = c_char_p,

        self.failUnlessEqual(None, func(None))
        self.failUnlessEqual("123", func("123"))
        self.failUnlessEqual(None, func(c_char_p(None)))
        self.failUnlessEqual("123", func(c_char_p("123")))

        self.failUnlessEqual("123", func(c_buffer("123")))
        ca = c_char("a")
        self.failUnlessEqual("a", func(pointer(ca))[0])
        self.failUnlessEqual("a", func(byref(ca))[0])

    def test_c_void_p_arg(self):
        func = testdll._testfunc_p_p
        func.restype = c_char_p
        func.argtypes = c_void_p,

        self.failUnlessEqual(None, func(None))
        self.failUnlessEqual("123", func("123"))
        self.failUnlessEqual("123", func(c_char_p("123")))
        self.failUnlessEqual(None, func(c_char_p(None)))

        self.failUnlessEqual("123", func(c_buffer("123")))
        ca = c_char("a")
        self.failUnlessEqual("a", func(pointer(ca))[0])
        self.failUnlessEqual("a", func(byref(ca))[0])

        func(byref(c_int()))
        func(pointer(c_int()))
        func((c_int * 3)())

        try:
            func.restype = c_wchar_p
        except NameError:
            pass
        else:
            self.failUnlessEqual(None, func(c_wchar_p(None)))
            self.failUnlessEqual(u"123", func(c_wchar_p(u"123")))

##    def test_instance(self):
##        func = testdll._testfunc_p_p

##        class X:
##            _as_parameter_ = 0

##        self.failUnlessEqual(0, func(X()))

try:
    c_wchar
except NameError:
    pass
else:
    class WCharPointersTestCase(unittest.TestCase):

        def setUp(self):
            func = testdll._testfunc_p_p
            func.restype = c_int
            func.argtypes = None


        def test_POINTER_c_wchar_arg(self):
            func = testdll._testfunc_p_p
            func.restype = c_wchar_p
            func.argtypes = POINTER(c_wchar),

            self.failUnlessEqual(None, func(None))
            self.failUnlessEqual(u"123", func(u"123"))
            self.failUnlessEqual(None, func(c_wchar_p(None)))
            self.failUnlessEqual(u"123", func(c_wchar_p(u"123")))

            self.failUnlessEqual(u"123", func(c_wbuffer(u"123")))
            ca = c_wchar("a")
            self.failUnlessEqual(u"a", func(pointer(ca))[0])
            self.failUnlessEqual(u"a", func(byref(ca))[0])

        def test_c_wchar_p_arg(self):
            func = testdll._testfunc_p_p
            func.restype = c_wchar_p
            func.argtypes = c_wchar_p,

            c_wchar_p.from_param(u"123")

            self.failUnlessEqual(None, func(None))
            self.failUnlessEqual("123", func(u"123"))
            self.failUnlessEqual(None, func(c_wchar_p(None)))
            self.failUnlessEqual("123", func(c_wchar_p("123")))

            # XXX Currently, these raise TypeErrors, although they shouldn't:
            self.failUnlessEqual("123", func(c_wbuffer("123")))
            ca = c_wchar("a")
            self.failUnlessEqual("a", func(pointer(ca))[0])
            self.failUnlessEqual("a", func(byref(ca))[0])

class ArrayTest(unittest.TestCase):
    def test(self):
        func = testdll._testfunc_ai8
        func.restype = POINTER(c_int)
        func.argtypes = c_int * 8,

        func((c_int * 8)(1, 2, 3, 4, 5, 6, 7, 8))

        # This did crash before:

        def func(): pass
        CFUNCTYPE(None, c_int * 3)(func)

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

if __name__ == '__main__':
    unittest.main()
back to top