123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- import sys
- import unittest
- import pywintypes
- import win32api
- from pywin32_testutil import int2long
- # A class that will never die vie refcounting, but will die via GC.
- class Cycle:
- def __init__(self, handle):
- self.cycle = self
- self.handle = handle
- class PyHandleTestCase(unittest.TestCase):
- def testCleanup1(self):
- # We used to clobber all outstanding exceptions.
- def f1(invalidate):
- import win32event
- h = win32event.CreateEvent(None, 0, 0, None)
- if invalidate:
- win32api.CloseHandle(int(h))
- 1/0
- # If we invalidated, then the object destruction code will attempt
- # to close an invalid handle. We don't wan't an exception in
- # this case
- def f2(invalidate):
- """ This function should throw an IOError. """
- try:
- f1(invalidate)
- except ZeroDivisionError as exc:
- raise IOError("raise 2")
- self.assertRaises(IOError, f2, False)
- # Now do it again, but so the auto object destruction
- # actually fails.
- self.assertRaises(IOError, f2, True)
- def testCleanup2(self):
- # Cause an exception during object destruction.
- # The worst this does is cause an ".XXX undetected error (why=3)"
- # So avoiding that is the goal
- import win32event
- h = win32event.CreateEvent(None, 0, 0, None)
- # Close the handle underneath the object.
- win32api.CloseHandle(int(h))
- # Object destructor runs with the implicit close failing
- h = None
- def testCleanup3(self):
- # And again with a class - no __del__
- import win32event
- class Test:
- def __init__(self):
- self.h = win32event.CreateEvent(None, 0, 0, None)
- win32api.CloseHandle(int(self.h))
- t=Test()
- t = None
- def testCleanupGood(self):
- # And check that normal error semantics *do* work.
- import win32event
- h = win32event.CreateEvent(None, 0, 0, None)
- win32api.CloseHandle(int(h))
- self.assertRaises(win32api.error, h.Close)
- # A following Close is documented as working
- h.Close()
- def testInvalid(self):
- h=pywintypes.HANDLE(-2)
- try:
- h.Close()
- # Ideally, we'd:
- # self.assertRaises(win32api.error, h.Close)
- # and everywhere markh has tried, that would pass - but not on
- # github automation, where the .Close apparently works fine.
- # (same for -1. Using 0 appears to work fine everywhere)
- # There still seems value in testing it though, so we just accept
- # either working or failing.
- except win32api.error:
- pass
- def testOtherHandle(self):
- h=pywintypes.HANDLE(1)
- h2=pywintypes.HANDLE(h)
- self.failUnlessEqual(h, h2)
- # but the above doesn't really test everything - we want a way to
- # pass the handle directly into PyWinLong_AsVoidPtr. One way to
- # to that is to abuse win32api.GetProcAddress() - the 2nd param
- # is passed to PyWinLong_AsVoidPtr() if its not a string.
- # passing a handle value of '1' should work - there is something
- # at that ordinal
- win32api.GetProcAddress(sys.dllhandle, h)
- def testHandleInDict(self):
- h=pywintypes.HANDLE(1)
- d = dict(foo=h)
- self.failUnlessEqual(d['foo'], h)
- def testHandleInDictThenInt(self):
- h=pywintypes.HANDLE(1)
- d = dict(foo=h)
- self.failUnlessEqual(d['foo'], 1)
- def testHandleCompareNone(self):
- h=pywintypes.HANDLE(1)
- self.failIfEqual(h, None)
- self.failIfEqual(None, h)
- # ensure we use both __eq__ and __ne__ ops
- self.failIf(h==None)
- self.failUnless(h!=None)
- def testHandleCompareInt(self):
- h=pywintypes.HANDLE(1)
- self.failIfEqual(h, 0)
- self.failUnlessEqual(h, 1)
- # ensure we use both __eq__ and __ne__ ops
- self.failUnless(h==1)
- self.failUnless(1==h)
- self.failIf(h!=1)
- self.failIf(1!=h)
- self.failIf(h==0)
- self.failIf(0==h)
- self.failUnless(h!=0)
- self.failUnless(0!=h)
- def testHandleNonZero(self):
- h=pywintypes.HANDLE(0)
- self.failIf(h)
- h=pywintypes.HANDLE(1)
- self.failUnless(h)
- def testLong(self):
- # sys.maxint+1 should always be a 'valid' handle, treated as an
- # unsigned int, even though it is a long. Although pywin32 should not
- # directly create such longs, using struct.unpack() with a P format
- # may well return them. eg:
- # >>> struct.unpack("P", struct.pack("P", -1))
- # (4294967295L,)
- try:
- big = sys.maxsize
- except AttributeError:
- big = sys.maxint
- pywintypes.HANDLE(big+1)
- def testGC(self):
- # This used to provoke:
- # Fatal Python error: unexpected exception during garbage collection
- def make():
- h=pywintypes.HANDLE(-2)
- c = Cycle(h)
- import gc
- make()
- gc.collect()
- def testTypes(self):
- self.assertRaises(TypeError, pywintypes.HANDLE, "foo")
- self.assertRaises(TypeError, pywintypes.HANDLE, ())
- # should be able to get a long!
- pywintypes.HANDLE(int2long(0))
- if __name__ == '__main__':
- unittest.main()
|