text: """
  Here is probably the place to write the docs, since the test-cases
  show how the type behave.
  
  Later...
  """
  
  from ctypes import *
  import sys, unittest
  
  try:
      WINFUNCTYPE
  except NameError:
      # fake to enable this test on Linux
      WINFUNCTYPE = CFUNCTYPE
  
  import _ctypes_test
  dll = CDLL(_ctypes_test.__file__)
  if sys.platform == "win32":
      windll = WinDLL(_ctypes_test.__file__)
  
  class POINT(Structure):
      _fields_ = [("x", c_int), ("y", c_int)]
  class RECT(Structure):
      _fields_ = [("left", c_int), ("top", c_int),
                  ("right", c_int), ("bottom", c_int)]
  class FunctionTestCase(unittest.TestCase):
  
      def test_mro(self):
          # in Python 2.3, this raises TypeError: MRO conflict among bases classes,
          # in Python 2.2 it works.
          #
          # But in early versions of _ctypes.c, the result of tp_new
          # wasn't checked, and it even crashed Python.
          # Found by Greg Chapman.
  
          try:
              class X(object, Array):
                  _length_ = 5
                  _type_ = "i"
          except TypeError:
              pass
  
  
          from _ctypes import _Pointer
          try:
              class X(object, _Pointer):
                  pass
          except TypeError:
              pass
  
          from _ctypes import _SimpleCData
          try:
              class X(object, _SimpleCData):
                  _type_ = "i"
          except TypeError:
              pass
  
          try:
              class X(object, Structure):
                  _fields_ = []
          except TypeError:
              pass
  
  
      def test_wchar_parm(self):
          try:
              c_wchar
          except NameError:
              return
          f = dll._testfunc_i_bhilfd
          f.argtypes = [c_byte, c_wchar, c_int, c_long, c_float, c_double]
          result = f(1, u"x", 3, 4, 5.0, 6.0)
          self.assertEqual(result, 139)
          self.assertEqual(type(result), int)
  
      def test_wchar_result(self):
          try:
              c_wchar
          except NameError:
              return
          f = dll._testfunc_i_bhilfd
          f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double]
          f.restype = c_wchar
          result = f(0, 0, 0, 0, 0, 0)
          self.assertEqual(result, u'\x00')
  
      def test_voidresult(self):
          f = dll._testfunc_v
          f.restype = None
          f.argtypes = [c_int, c_int, POINTER(c_int)]
          result = c_int()
          self.assertEqual(None, f(1, 2, byref(result)))
          self.assertEqual(result.value, 3)
  
      def test_intresult(self):
          f = dll._testfunc_i_bhilfd
          f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double]
          f.restype = c_int
          result = f(1, 2, 3, 4, 5.0, 6.0)
          self.assertEqual(result, 21)
          self.assertEqual(type(result), int)
  
          result = f(-1, -2, -3, -4, -5.0, -6.0)
          self.assertEqual(result, -21)
          self.assertEqual(type(result), int)
  
          # If we declare the function to return a short,
          # is the high part split off?
          f.restype = c_short
          result = f(1, 2, 3, 4, 5.0, 6.0)
          self.assertEqual(result, 21)
          self.assertEqual(type(result), int)
  
          result = f(1, 2, 3, 0x10004, 5.0, 6.0)
          self.assertEqual(result, 21)
          self.assertEqual(type(result), int)
  
          # You cannot assign character format codes as restype any longer
          self.assertRaises(TypeError, setattr, f, "restype", "i")
  
      def test_floatresult(self):
          f = dll._testfunc_f_bhilfd
          f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double]
          f.restype = c_float
          result = f(1, 2, 3, 4, 5.0, 6.0)
          self.assertEqual(result, 21)
          self.assertEqual(type(result), float)
  
          result = f(-1, -2, -3, -4, -5.0, -6.0)
          self.assertEqual(result, -21)
          self.assertEqual(type(result), float)
  
      def test_doubleresult(self):
          f = dll._testfunc_d_bhilfd
          f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double]
          f.restype = c_double
          result = f(1, 2, 3, 4, 5.0, 6.0)
          self.assertEqual(result, 21)
          self.assertEqual(type(result), float)
  
          result = f(-1, -2, -3, -4, -5.0, -6.0)
          self.assertEqual(result, -21)
          self.assertEqual(type(result), float)
  
      def test_longdoubleresult(self):
          f = dll._testfunc_D_bhilfD
          f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_longdouble]
          f.restype = c_longdouble
          result = f(1, 2, 3, 4, 5.0, 6.0)
          self.assertEqual(result, 21)
          self.assertEqual(type(result), float)
  
          result = f(-1, -2, -3, -4, -5.0, -6.0)
          self.assertEqual(result, -21)
          self.assertEqual(type(result), float)
  
      def test_longlongresult(self):
          try:
              c_longlong
          except NameError:
              return
          f = dll._testfunc_q_bhilfd
          f.restype = c_longlong
          f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double]
          result = f(1, 2, 3, 4, 5.0, 6.0)
          self.assertEqual(result, 21)
  
          f = dll._testfunc_q_bhilfdq
          f.restype = c_longlong
          f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double, c_longlong]
          result = f(1, 2, 3, 4, 5.0, 6.0, 21)
          self.assertEqual(result, 42)
  
      def test_stringresult(self):
          f = dll._testfunc_p_p
          f.argtypes = None
          f.restype = c_char_p
          result = f("123")
          self.assertEqual(result, "123")
  
          result = f(None)
          self.assertEqual(result, None)
  
      def test_pointers(self):
          f = dll._testfunc_p_p
          f.restype = POINTER(c_int)
          f.argtypes = [POINTER(c_int)]
  
          # This only works if the value c_int(42) passed to the
          # function is still alive while the pointer (the result) is
          # used.
  
          v = c_int(42)
  
          self.assertEqual(pointer(v).contents.value, 42)
          result = f(pointer(v))
          self.assertEqual(type(result), POINTER(c_int))
          self.assertEqual(result.contents.value, 42)
  
          # This on works...
          result = f(pointer(v))
          self.assertEqual(result.contents.value, v.value)
  
          p = pointer(c_int(99))
          result = f(p)
          self.assertEqual(result.contents.value, 99)
  
          arg = byref(v)
          result = f(arg)
          self.assertNotEqual(result.contents, v.value)
  
          self.assertRaises(ArgumentError, f, byref(c_short(22)))
  
          # It is dangerous, however, because you don't control the lifetime
          # of the pointer:
          result = f(byref(c_int(99)))
          self.assertNotEqual(result.contents, 99)
  
      def test_errors(self):
          f = dll._testfunc_p_p
          f.restype = c_int
  
          class X(Structure):
              _fields_ = [("y", c_int)]
  
          self.assertRaises(TypeError, f, X()) #cannot convert parameter
  
      ################################################################
      def test_shorts(self):
          f = dll._testfunc_callback_i_if
  
          args = []
          expected = [262144, 131072, 65536, 32768, 16384, 8192, 4096, 2048,
                      1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1]
  
          def callback(v):
              args.append(v)
              return v
  
          CallBack = CFUNCTYPE(c_int, c_int)
  
          cb = CallBack(callback)
          f(2**18, cb)
          self.assertEqual(args, expected)
  
      ################################################################
  
  
      def test_callbacks(self):
          f = dll._testfunc_callback_i_if
          f.restype = c_int
          f.argtypes = None
  
          MyCallback = CFUNCTYPE(c_int, c_int)
  
          def callback(value):
              #print "called back with", value
              return value
  
          cb = MyCallback(callback)
          result = f(-10, cb)
          self.assertEqual(result, -18)
  
          # test with prototype
          f.argtypes = [c_int, MyCallback]
          cb = MyCallback(callback)
          result = f(-10, cb)
          self.assertEqual(result, -18)
  
          AnotherCallback = WINFUNCTYPE(c_int, c_int, c_int, c_int, c_int)
  
          # check that the prototype works: we call f with wrong
          # argument types
          cb = AnotherCallback(callback)
          self.assertRaises(ArgumentError, f, -10, cb)
  
  
      def test_callbacks_2(self):
          # Can also use simple datatypes as argument type specifiers
          # for the callback function.
          # In this case the call receives an instance of that type
          f = dll._testfunc_callback_i_if
          f.restype = c_int
  
          MyCallback = CFUNCTYPE(c_int, c_int)
  
          f.argtypes = [c_int, MyCallback]
  
          def callback(value):
              #print "called back with", value
              self.assertEqual(type(value), int)
              return value
  
          cb = MyCallback(callback)
          result = f(-10, cb)
          self.assertEqual(result, -18)
  
      def test_longlong_callbacks(self):
  
          f = dll._testfunc_callback_q_qf
          f.restype = c_longlong
  
          MyCallback = CFUNCTYPE(c_longlong, c_longlong)
  
          f.argtypes = [c_longlong, MyCallback]
  
          def callback(value):
              self.assertIsInstance(value, (int, long))
              return value & 0x7FFFFFFF
  
          cb = MyCallback(callback)
  
          self.assertEqual(13577625587, f(1000000000000, cb))
  
      def test_errors(self):
          self.assertRaises(AttributeError, getattr, dll, "_xxx_yyy")
          self.assertRaises(ValueError, c_int.in_dll, dll, "_xxx_yyy")
  
      def test_byval(self):
  
          # without prototype
          ptin = POINT(1, 2)
          ptout = POINT()
          # EXPORT int _testfunc_byval(point in, point *pout)
          result = dll._testfunc_byval(ptin, byref(ptout))
          got = result, ptout.x, ptout.y
          expected = 3, 1, 2
          self.assertEqual(got, expected)
  
          # with prototype
          ptin = POINT(101, 102)
          ptout = POINT()
          dll._testfunc_byval.argtypes = (POINT, POINTER(POINT))
          dll._testfunc_byval.restype = c_int
          result = dll._testfunc_byval(ptin, byref(ptout))
          got = result, ptout.x, ptout.y
          expected = 203, 101, 102
          self.assertEqual(got, expected)
  
      def test_struct_return_2H(self):
          class S2H(Structure):
              _fields_ = [("x", c_short),
                          ("y", c_short)]
          dll.ret_2h_func.restype = S2H
          dll.ret_2h_func.argtypes = [S2H]
          inp = S2H(99, 88)
          s2h = dll.ret_2h_func(inp)
          self.assertEqual((s2h.x, s2h.y), (99*2, 88*3))
  
      if sys.platform == "win32":
          def test_struct_return_2H_stdcall(self):
              class S2H(Structure):
                  _fields_ = [("x", c_short),
                              ("y", c_short)]
  
              windll.s_ret_2h_func.restype = S2H
              windll.s_ret_2h_func.argtypes = [S2H]
              s2h = windll.s_ret_2h_func(S2H(99, 88))
              self.assertEqual((s2h.x, s2h.y), (99*2, 88*3))
  
      def test_struct_return_8H(self):
          class S8I(Structure):
              _fields_ = [("a", c_int),
                          ("b", c_int),
                          ("c", c_int),
                          ("d", c_int),
                          ("e", c_int),
                          ("f", c_int),
                          ("g", c_int),
                          ("h", c_int)]
          dll.ret_8i_func.restype = S8I
          dll.ret_8i_func.argtypes = [S8I]
          inp = S8I(9, 8, 7, 6, 5, 4, 3, 2)
          s8i = dll.ret_8i_func(inp)
          self.assertEqual((s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h),
                               (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9))
  
      if sys.platform == "win32":
          def test_struct_return_8H_stdcall(self):
              class S8I(Structure):
                  _fields_ = [("a", c_int),
                              ("b", c_int),
                              ("c", c_int),
                              ("d", c_int),
                              ("e", c_int),
                              ("f", c_int),
                              ("g", c_int),
                              ("h", c_int)]
              windll.s_ret_8i_func.restype = S8I
              windll.s_ret_8i_func.argtypes = [S8I]
              inp = S8I(9, 8, 7, 6, 5, 4, 3, 2)
              s8i = windll.s_ret_8i_func(inp)
              self.assertEqual((s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h),
                                   (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9))
  
      def test_sf1651235(self):
          # see http://www.python.org/sf/1651235
  
          proto = CFUNCTYPE(c_int, RECT, POINT)
          def callback(*args):
              return 0
  
          callback = proto(callback)
          self.assertRaises(ArgumentError, lambda: callback((1, 2, 3, 4), POINT()))
  
  if __name__ == '__main__':
      unittest.main()
  