handles.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import sys
  2. import unittest
  3. import pywintypes
  4. import win32api
  5. from pywin32_testutil import int2long
  6. # A class that will never die vie refcounting, but will die via GC.
  7. class Cycle:
  8. def __init__(self, handle):
  9. self.cycle = self
  10. self.handle = handle
  11. class PyHandleTestCase(unittest.TestCase):
  12. def testCleanup1(self):
  13. # We used to clobber all outstanding exceptions.
  14. def f1(invalidate):
  15. import win32event
  16. h = win32event.CreateEvent(None, 0, 0, None)
  17. if invalidate:
  18. win32api.CloseHandle(int(h))
  19. 1/0
  20. # If we invalidated, then the object destruction code will attempt
  21. # to close an invalid handle. We don't wan't an exception in
  22. # this case
  23. def f2(invalidate):
  24. """ This function should throw an IOError. """
  25. try:
  26. f1(invalidate)
  27. except ZeroDivisionError, exc:
  28. raise IOError("raise 2")
  29. self.assertRaises(IOError, f2, False)
  30. # Now do it again, but so the auto object destruction
  31. # actually fails.
  32. self.assertRaises(IOError, f2, True)
  33. def testCleanup2(self):
  34. # Cause an exception during object destruction.
  35. # The worst this does is cause an ".XXX undetected error (why=3)"
  36. # So avoiding that is the goal
  37. import win32event
  38. h = win32event.CreateEvent(None, 0, 0, None)
  39. # Close the handle underneath the object.
  40. win32api.CloseHandle(int(h))
  41. # Object destructor runs with the implicit close failing
  42. h = None
  43. def testCleanup3(self):
  44. # And again with a class - no __del__
  45. import win32event
  46. class Test:
  47. def __init__(self):
  48. self.h = win32event.CreateEvent(None, 0, 0, None)
  49. win32api.CloseHandle(int(self.h))
  50. t=Test()
  51. t = None
  52. def testCleanupGood(self):
  53. # And check that normal error semantics *do* work.
  54. import win32event
  55. h = win32event.CreateEvent(None, 0, 0, None)
  56. win32api.CloseHandle(int(h))
  57. self.assertRaises(win32api.error, h.Close)
  58. # A following Close is documented as working
  59. h.Close()
  60. def testInvalid(self):
  61. h=pywintypes.HANDLE(-2)
  62. self.assertRaises(win32api.error, h.Close)
  63. def testOtherHandle(self):
  64. h=pywintypes.HANDLE(1)
  65. h2=pywintypes.HANDLE(h)
  66. self.failUnlessEqual(h, h2)
  67. # but the above doesn't really test everything - we want a way to
  68. # pass the handle directly into PyWinLong_AsVoidPtr. One way to
  69. # to that is to abuse win32api.GetProcAddress() - the 2nd param
  70. # is passed to PyWinLong_AsVoidPtr() if its not a string.
  71. # passing a handle value of '1' should work - there is something
  72. # at that ordinal
  73. win32api.GetProcAddress(sys.dllhandle, h)
  74. def testHandleInDict(self):
  75. h=pywintypes.HANDLE(1)
  76. d = dict(foo=h)
  77. self.failUnlessEqual(d['foo'], h)
  78. def testHandleInDictThenInt(self):
  79. h=pywintypes.HANDLE(1)
  80. d = dict(foo=h)
  81. self.failUnlessEqual(d['foo'], 1)
  82. def testHandleCompareNone(self):
  83. h=pywintypes.HANDLE(1)
  84. self.failIfEqual(h, None)
  85. self.failIfEqual(None, h)
  86. # ensure we use both __eq__ and __ne__ ops
  87. self.failIf(h==None)
  88. self.failUnless(h!=None)
  89. def testHandleCompareInt(self):
  90. h=pywintypes.HANDLE(1)
  91. self.failIfEqual(h, 0)
  92. self.failUnlessEqual(h, 1)
  93. # ensure we use both __eq__ and __ne__ ops
  94. self.failUnless(h==1)
  95. self.failUnless(1==h)
  96. self.failIf(h!=1)
  97. self.failIf(1!=h)
  98. self.failIf(h==0)
  99. self.failIf(0==h)
  100. self.failUnless(h!=0)
  101. self.failUnless(0!=h)
  102. def testHandleNonZero(self):
  103. h=pywintypes.HANDLE(0)
  104. self.failIf(h)
  105. h=pywintypes.HANDLE(1)
  106. self.failUnless(h)
  107. def testLong(self):
  108. # sys.maxint+1 should always be a 'valid' handle, treated as an
  109. # unsigned int, even though it is a long. Although pywin32 should not
  110. # directly create such longs, using struct.unpack() with a P format
  111. # may well return them. eg:
  112. # >>> struct.unpack("P", struct.pack("P", -1))
  113. # (4294967295L,)
  114. try:
  115. big = sys.maxsize
  116. except AttributeError:
  117. big = sys.maxint
  118. pywintypes.HANDLE(big+1)
  119. def testGC(self):
  120. # This used to provoke:
  121. # Fatal Python error: unexpected exception during garbage collection
  122. def make():
  123. h=pywintypes.HANDLE(-2)
  124. c = Cycle(h)
  125. import gc
  126. make()
  127. gc.collect()
  128. def testTypes(self):
  129. self.assertRaises(TypeError, pywintypes.HANDLE, "foo")
  130. self.assertRaises(TypeError, pywintypes.HANDLE, ())
  131. # should be able to get a long!
  132. pywintypes.HANDLE(int2long(0))
  133. if __name__ == '__main__':
  134. unittest.main()