leakTest.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import sys
  2. from win32com.axscript.server.error import Exception
  3. from win32com.axscript import axscript
  4. from win32com.axscript.server import axsite
  5. import pythoncom
  6. from win32com.server import util, connect
  7. import win32com.server.policy
  8. class MySite(axsite.AXSite):
  9. def OnScriptError(self, error):
  10. exc = error.GetExceptionInfo()
  11. context, line, char = error.GetSourcePosition()
  12. print(" >Exception:", exc[1])
  13. try:
  14. st = error.GetSourceLineText()
  15. except pythoncom.com_error:
  16. st = None
  17. if st is None: st = ""
  18. text = st + "\n" + (" " * (char-1)) + "^" + "\n" + exc[2]
  19. for line in text.splitlines():
  20. print(" >" + line)
  21. class MyCollection(util.Collection):
  22. def _NewEnum(self):
  23. print("Making new Enumerator")
  24. return util.Collection._NewEnum(self)
  25. class Test:
  26. _public_methods_ = [ 'echo' ]
  27. _public_attrs_ = ['collection', 'verbose']
  28. def __init__(self):
  29. self.verbose = 0
  30. self.collection = util.wrap( MyCollection( [1,'Two',3] ))
  31. self.last = ""
  32. # self._connect_server_ = TestConnectServer(self)
  33. def echo(self, *args):
  34. self.last = ''.join(map(str, args))
  35. if self.verbose:
  36. for arg in args:
  37. print(arg, end=' ')
  38. print()
  39. # self._connect_server_.Broadcast(last)
  40. #### Connections currently wont work, as there is no way for the engine to
  41. #### know what events we support. We need typeinfo support.
  42. IID_ITestEvents = pythoncom.MakeIID("{8EB72F90-0D44-11d1-9C4B-00AA00125A98}")
  43. class TestConnectServer(connect.ConnectableServer):
  44. _connect_interfaces_ = [IID_ITestEvents]
  45. # The single public method that the client can call on us
  46. # (ie, as a normal COM server, this exposes just this single method.
  47. def __init__(self, object):
  48. self.object = object
  49. def Broadcast(self,arg):
  50. # Simply broadcast a notification.
  51. self._BroadcastNotify(self.NotifyDoneIt, (arg,))
  52. def NotifyDoneIt(self, interface, arg):
  53. interface.Invoke(1000, 0, pythoncom.DISPATCH_METHOD, 1, arg)
  54. VBScript = """\
  55. prop = "Property Value"
  56. sub hello(arg1)
  57. test.echo arg1
  58. end sub
  59. sub testcollection
  60. test.verbose = 1
  61. for each item in test.collection
  62. test.echo "Collection item is", item
  63. next
  64. end sub
  65. """
  66. if sys.version_info < (3,):
  67. PyScript = """print "PyScript is being parsed..."\n"""
  68. else:
  69. PyScript = """print("PyScript is being parsed...")\n"""
  70. PyScript += """\
  71. prop = "Property Value"
  72. def hello(arg1):
  73. test.echo(arg1)
  74. pass
  75. def testcollection():
  76. test.verbose = 1
  77. # test.collection[1] = "New one"
  78. for item in test.collection:
  79. test.echo("Collection item is", item)
  80. pass
  81. """
  82. ErrScript = """\
  83. bad code for everyone!
  84. """
  85. def TestEngine(engineName, code, bShouldWork = 1):
  86. echoer = Test()
  87. model = {
  88. 'test' : util.wrap(echoer),
  89. }
  90. site = MySite(model)
  91. engine = site._AddEngine(engineName)
  92. engine.AddCode(code, axscript.SCRIPTTEXT_ISPERSISTENT)
  93. try:
  94. engine.Start()
  95. finally:
  96. if not bShouldWork:
  97. engine.Close()
  98. return
  99. doTestEngine(engine, echoer)
  100. # re-transition the engine back to the UNINITIALIZED state, a-la ASP.
  101. engine.eScript.SetScriptState(axscript.SCRIPTSTATE_UNINITIALIZED)
  102. engine.eScript.SetScriptSite(util.wrap(site))
  103. print("restarting")
  104. engine.Start()
  105. # all done!
  106. engine.Close()
  107. def doTestEngine(engine, echoer):
  108. # Now call into the scripts IDispatch
  109. from win32com.client.dynamic import Dispatch
  110. ob = Dispatch(engine.GetScriptDispatch())
  111. try:
  112. ob.hello("Goober")
  113. except pythoncom.com_error as exc:
  114. print("***** Calling 'hello' failed", exc)
  115. return
  116. if echoer.last != "Goober":
  117. print("***** Function call didnt set value correctly", repr(echoer.last))
  118. if str(ob.prop) != "Property Value":
  119. print("***** Property Value not correct - ", repr(ob.prop))
  120. ob.testcollection()
  121. # Now make sure my engines can evaluate stuff.
  122. result = engine.eParse.ParseScriptText("1+1", None, None, None, 0, 0, axscript.SCRIPTTEXT_ISEXPRESSION)
  123. if result != 2:
  124. print("Engine could not evaluate '1+1' - said the result was", result)
  125. def dotestall():
  126. for i in range(10):
  127. TestEngine("Python", PyScript)
  128. print(sys.gettotalrefcount())
  129. ## print "Testing Exceptions"
  130. ## try:
  131. ## TestEngine("Python", ErrScript, 0)
  132. ## except pythoncom.com_error:
  133. ## pass
  134. def testall():
  135. dotestall()
  136. pythoncom.CoUninitialize()
  137. print("AXScript Host worked correctly - %d/%d COM objects left alive." % (pythoncom._GetInterfaceCount(), pythoncom._GetGatewayCount()))
  138. if __name__ == '__main__':
  139. testall()