PyXR

c:\python24\lib\site-packages\win32 \ com \ test \ errorSemantics.py



0001 # errorSemantics.py
0002 
0003 # Test the Python error handling semantics.  Specifically:
0004 #
0005 # * When a Python COM object is called via IDispatch, the nominated
0006 #   scode is placed in the exception tuple, and the HRESULT is
0007 #   DISP_E_EXCEPTION
0008 # * When the same interface is called via IWhatever, the
0009 #   nominated  scode is returned directly (with the scode also
0010 #   reflected in the exception tuple)
0011 # * In all cases, the description etc end up in the exception tuple
0012 # * "Normal" Python exceptions resolve to an E_FAIL "internal error"
0013 
0014 import pythoncom
0015 from win32com.server.exception import COMException
0016 from win32com.server.util import wrap
0017 from win32com.client import Dispatch
0018 import winerror
0019 from win32com.test.util import CaptureWriter
0020 
0021 class error(Exception):
0022     def __init__(self, msg, com_exception=None):
0023         Exception.__init__(self, msg, str(com_exception))
0024 
0025 # Our COM server.
0026 class TestServer:
0027     _public_methods_ = [ 'Clone', 'Commit', 'LockRegion', 'Read']
0028     _com_interfaces_ = [ pythoncom.IID_IStream ]
0029 
0030     def Clone(self):
0031         raise COMException("Not today", scode=winerror.E_UNEXPECTED)
0032 
0033     def Commit(self, flags):
0034         raise "foo"
0035 
0036 def test():
0037     # Call via a native interface.
0038     com_server = wrap(TestServer(), pythoncom.IID_IStream)
0039     try:
0040         com_server.Clone()
0041     except pythoncom.com_error, com_exc:
0042         hr, desc, exc, argErr = com_exc
0043         if hr != winerror.E_UNEXPECTED:
0044             raise error("Calling the object natively did not yield the correct scode", com_exc)
0045         if not exc or exc[-1] != winerror.E_UNEXPECTED:
0046             raise error("The scode element of the exception tuple did not yield the correct scode", com_exc)
0047         if exc[2] != "Not today":
0048             raise error("The description in the exception tuple did not yield the correct string", com_exc)
0049     cap = CaptureWriter()
0050     try:
0051         cap.capture()
0052         try:
0053             com_server.Commit(0)
0054         finally:
0055             cap.release()
0056     except pythoncom.com_error, com_exc:
0057         hr, desc, exc, argErr = com_exc
0058         if hr != winerror.E_FAIL:
0059             raise error("The hresult was not E_FAIL for an internal error", com_exc)
0060         if exc[1] != "Python COM Server Internal Error":
0061             raise error("The description in the exception tuple did not yield the correct string", com_exc)
0062     # Check we saw a traceback in stderr
0063     if cap.get_captured().find("Traceback")<0:
0064         raise error("Could not find a traceback in stderr: %r" % (cap.get_captured(),))
0065 
0066     # Now do it all again, but using IDispatch
0067     com_server = Dispatch(wrap(TestServer()))
0068     try:
0069         com_server.Clone()
0070     except pythoncom.com_error, com_exc:
0071         hr, desc, exc, argErr = com_exc
0072         if hr != winerror.DISP_E_EXCEPTION:
0073             raise error("Calling the object via IDispatch did not yield the correct scode", com_exc)
0074         if not exc or exc[-1] != winerror.E_UNEXPECTED:
0075             raise error("The scode element of the exception tuple did not yield the correct scode", com_exc)
0076         if exc[2] != "Not today":
0077             raise error("The description in the exception tuple did not yield the correct string", com_exc)
0078 
0079     cap.clear()
0080     try:
0081         cap.capture()
0082         try:
0083             com_server.Commit(0)
0084         finally:
0085             cap.release()
0086     except pythoncom.com_error, com_exc:
0087         hr, desc, exc, argErr = com_exc
0088         if hr != winerror.DISP_E_EXCEPTION:
0089             raise error("Calling the object via IDispatch did not yield the correct scode", com_exc)
0090         if not exc or exc[-1] != winerror.E_FAIL:
0091             raise error("The scode element of the exception tuple did not yield the correct scode", com_exc)
0092         if exc[1] != "Python COM Server Internal Error":
0093             raise error("The description in the exception tuple did not yield the correct string", com_exc)
0094     # Check we saw a traceback in stderr
0095     if cap.get_captured().find("Traceback")<0:
0096         raise error("Could not find a traceback in stderr: %r" % (cap.get_captured(),))
0097 
0098 try:
0099     import logging
0100 except ImportError:
0101     logging = None
0102 if logging is not None:
0103     import win32com
0104     class TestLogHandler(logging.Handler):
0105         def __init__(self):
0106             self.num_emits = 0
0107             logging.Handler.__init__(self)
0108         def emit(self, record):
0109             self.num_emits += 1
0110             return
0111             print "--- record start"
0112             print self.format(record)
0113             print "--- record end"
0114     
0115     def testLogger():
0116         assert not hasattr(win32com, "logger")
0117         handler = TestLogHandler()
0118         formatter = logging.Formatter('%(message)s')
0119         handler.setFormatter(formatter)
0120         log = logging.getLogger("win32com_test")
0121         log.addHandler(handler)
0122         win32com.logger = log
0123         # Now throw some exceptions!
0124         # Native interfaces
0125         com_server = wrap(TestServer(), pythoncom.IID_IStream)
0126         try:
0127             com_server.Commit(0)
0128             raise RuntimeError, "should have failed"
0129         except pythoncom.error:
0130             pass
0131         assert handler.num_emits == 1, handler.num_emits
0132         handler.num_emits = 0 # reset
0133 
0134         com_server = Dispatch(wrap(TestServer()))
0135         try:
0136             com_server.Commit(0)
0137             raise RuntimeError, "should have failed"
0138         except pythoncom.error:
0139             pass
0140         assert handler.num_emits == 1, handler.num_emits
0141     
0142 if __name__=='__main__':
0143     test()
0144     if logging is not None:
0145         testLogger()
0146     from util import CheckClean
0147     CheckClean()
0148     print "error semantic tests worked"
0149 

Generated by PyXR 0.9.4
SourceForge.net Logo