Uploaded Test files
This commit is contained in:
parent
f584ad9d97
commit
2e81cb7d99
16627 changed files with 2065359 additions and 102444 deletions
84
venv/Lib/site-packages/win32com/test/GenTestScripts.py
Normal file
84
venv/Lib/site-packages/win32com/test/GenTestScripts.py
Normal file
|
@ -0,0 +1,84 @@
|
|||
#
|
||||
# Generate scripts needed for serious testing!
|
||||
#
|
||||
import win32com, win32com.client.makepy
|
||||
import win32com.test
|
||||
import pythoncom
|
||||
import sys, os
|
||||
|
||||
genList = [
|
||||
("msword8", "{00020905-0000-0000-C000-000000000046}",1033,8,0),
|
||||
]
|
||||
|
||||
genDir = "Generated4Test"
|
||||
def GetGenPath():
|
||||
import win32api
|
||||
return os.path.join(win32api.GetFullPathName(win32com.test.__path__[0]), genDir)
|
||||
|
||||
def GenerateFromRegistered(fname, *loadArgs):
|
||||
# tlb = apply(pythoncom.LoadRegTypeLib, loadArgs)
|
||||
genPath = GetGenPath()
|
||||
try:
|
||||
os.stat(genPath)
|
||||
except os.error:
|
||||
os.mkdir(genPath)
|
||||
# Ensure an __init__ exists.
|
||||
open(os.path.join(genPath, "__init__.py"), "w").close()
|
||||
print(fname, ": generating -", end=' ')
|
||||
f = open(os.path.join(genPath, fname + ".py"), "w")
|
||||
win32com.client.makepy.GenerateFromTypeLibSpec(loadArgs, f, bQuiet = 1, bGUIProgress = 1)
|
||||
f.close()
|
||||
print("compiling -", end=' ')
|
||||
fullModName = "win32com.test.%s.%s" % (genDir, fname)
|
||||
exec("import " + fullModName)
|
||||
# Inject the generated module as a top level module.
|
||||
sys.modules[fname] = sys.modules[fullModName]
|
||||
print("done")
|
||||
|
||||
|
||||
def GenerateAll():
|
||||
for args in genList:
|
||||
try:
|
||||
GenerateFromRegistered(*args)
|
||||
except KeyboardInterrupt:
|
||||
print("** Interrupted ***")
|
||||
break
|
||||
except pythoncom.com_error:
|
||||
print("** Could not generate test code for ", args[0])
|
||||
|
||||
def CleanAll():
|
||||
print("Cleaning generated test scripts...")
|
||||
try: # Clear exceptions!
|
||||
1/0
|
||||
except:
|
||||
pass
|
||||
genPath = GetGenPath()
|
||||
for args in genList:
|
||||
try:
|
||||
name = args[0]+".py"
|
||||
os.unlink(os.path.join(genPath, name))
|
||||
except os.error as details:
|
||||
if type(details)==type(()) and details[0]!=2:
|
||||
print("Could not deleted generated", name, details)
|
||||
try:
|
||||
name = args[0]+".pyc"
|
||||
os.unlink(os.path.join(genPath, name))
|
||||
except os.error as details:
|
||||
if type(details)==type(()) and details[0]!=2:
|
||||
print("Could not deleted generated", name, details)
|
||||
try:
|
||||
os.unlink(os.path.join(genPath, "__init__.py"))
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
os.unlink(os.path.join(genPath, "__init__.pyc"))
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
os.rmdir(genPath)
|
||||
except os.error as details:
|
||||
print("Could not delete test directory -", details)
|
||||
|
||||
if __name__=='__main__':
|
||||
GenerateAll()
|
||||
CleanAll()
|
64
venv/Lib/site-packages/win32com/test/Testpys.sct
Normal file
64
venv/Lib/site-packages/win32com/test/Testpys.sct
Normal file
|
@ -0,0 +1,64 @@
|
|||
<scriptlet>
|
||||
|
||||
<Registration
|
||||
Description="TestPys"
|
||||
ProgID="TestPys.Scriptlet"
|
||||
Version="1"
|
||||
ClassID="{2eeb6080-cd58-11d1-b81e-00a0240b2fef}">
|
||||
|
||||
<SCRIPT LANGUAGE="VBScript">
|
||||
Function Register()
|
||||
Msgbox "Scriptlet 'Test' registered."
|
||||
End Function
|
||||
|
||||
Function Unregister()
|
||||
Msgbox "Scriptlet 'Test' unregistered."
|
||||
End Function
|
||||
</SCRIPT>
|
||||
</Registration>
|
||||
|
||||
<implements id=Automation type=Automation>
|
||||
<property name=PyProp1>
|
||||
<get/>
|
||||
<put/>
|
||||
</property>
|
||||
<property name=PyProp2>
|
||||
<get/>
|
||||
<put/>
|
||||
</property>
|
||||
<method name=PyMethod1>
|
||||
</method>
|
||||
|
||||
<method name=PyMethod2>
|
||||
</method>
|
||||
</implements>
|
||||
|
||||
<script language=python>
|
||||
|
||||
PyProp1 = "PyScript Property1";
|
||||
PyProp2 = "PyScript Property2";
|
||||
|
||||
def get_PyProp1():
|
||||
return PyProp1
|
||||
|
||||
def put_PyProp1(newValue):
|
||||
global PyProp1
|
||||
PyProp1 = newValue
|
||||
|
||||
def get_PyProp2():
|
||||
return PyProp2
|
||||
|
||||
def put_PyProp2(newValue):
|
||||
global PyProp2
|
||||
PyProp2 = newValue
|
||||
|
||||
def PyMethod1():
|
||||
return "PyMethod1 called"
|
||||
|
||||
def PyMethod2():
|
||||
return "PyMethod2 called"
|
||||
|
||||
</script>
|
||||
|
||||
</scriptlet>
|
||||
|
1
venv/Lib/site-packages/win32com/test/__init__.py
Normal file
1
venv/Lib/site-packages/win32com/test/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
# Empty file to designate a Python package
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
61
venv/Lib/site-packages/win32com/test/daodump.py
Normal file
61
venv/Lib/site-packages/win32com/test/daodump.py
Normal file
|
@ -0,0 +1,61 @@
|
|||
# import dao3032
|
||||
# No longer imported here - callers responsibility to load
|
||||
#
|
||||
import win32com.client
|
||||
|
||||
def DumpDB(db, bDeep = 1):
|
||||
# MUST be a DB object.
|
||||
DumpTables(db,bDeep)
|
||||
DumpRelations(db,bDeep)
|
||||
DumpAllContainers(db,bDeep)
|
||||
|
||||
def DumpTables(db, bDeep = 1):
|
||||
for tab in db.TableDefs:
|
||||
tab = db.TableDefs(tab.Name) # Redundant lookup for testing purposes.
|
||||
print("Table %s - Fields: %d, Attributes:%d" % (tab.Name, len(tab.Fields), tab.Attributes))
|
||||
if bDeep: DumpFields(tab.Fields)
|
||||
|
||||
def DumpFields(fields):
|
||||
for field in fields:
|
||||
print(" %s, size=%d, reqd=%d, type=%d, defVal=%s" % (field.Name, field.Size, field.Required, field.Type, str(field.DefaultValue)))
|
||||
|
||||
def DumpRelations(db, bDeep = 1):
|
||||
for relation in db.Relations:
|
||||
print("Relation %s - %s->%s" % (relation.Name, relation.Table, relation.ForeignTable))
|
||||
|
||||
#### This dont work. TLB says it is a Fields collection, but apparently not!
|
||||
#### if bDeep: DumpFields(relation.Fields)
|
||||
|
||||
def DumpAllContainers(db, bDeep = 1):
|
||||
for cont in db.Containers:
|
||||
print("Container %s - %d documents" % (cont.Name, len(cont.Documents)))
|
||||
if bDeep: DumpContainerDocuments(cont)
|
||||
|
||||
def DumpContainerDocuments(container):
|
||||
for doc in container.Documents:
|
||||
import time
|
||||
timeStr = time.ctime(int(doc.LastUpdated))
|
||||
print(" %s - updated %s (" % (doc.Name, timeStr), end=' ')
|
||||
print(doc.LastUpdated,")") # test the _print_ method?
|
||||
|
||||
def TestEngine(engine):
|
||||
import sys
|
||||
if len(sys.argv)>1:
|
||||
dbName = sys.argv[1]
|
||||
else:
|
||||
dbName = "e:\\temp\\TestPython.mdb"
|
||||
db = engine.OpenDatabase(dbName)
|
||||
DumpDB(db)
|
||||
|
||||
def test():
|
||||
for progid in ("DAO.DBEngine.36", "DAO.DBEngine.35", "DAO.DBEngine.30"):
|
||||
try:
|
||||
ob = win32com.client.gencache.EnsureDispatch(progid)
|
||||
except pythoncom.com_error:
|
||||
print(progid, "does not seem to be installed")
|
||||
else:
|
||||
TestEngine(ob)
|
||||
break
|
||||
|
||||
if __name__=='__main__':
|
||||
test()
|
151
venv/Lib/site-packages/win32com/test/errorSemantics.py
Normal file
151
venv/Lib/site-packages/win32com/test/errorSemantics.py
Normal file
|
@ -0,0 +1,151 @@
|
|||
# errorSemantics.py
|
||||
|
||||
# Test the Python error handling semantics. Specifically:
|
||||
#
|
||||
# * When a Python COM object is called via IDispatch, the nominated
|
||||
# scode is placed in the exception tuple, and the HRESULT is
|
||||
# DISP_E_EXCEPTION
|
||||
# * When the same interface is called via IWhatever, the
|
||||
# nominated scode is returned directly (with the scode also
|
||||
# reflected in the exception tuple)
|
||||
# * In all cases, the description etc end up in the exception tuple
|
||||
# * "Normal" Python exceptions resolve to an E_FAIL "internal error"
|
||||
|
||||
import pythoncom
|
||||
from win32com.server.exception import COMException
|
||||
from win32com.server.util import wrap
|
||||
from win32com.client import Dispatch
|
||||
import winerror
|
||||
from win32com.test.util import CaptureWriter
|
||||
|
||||
class error(Exception):
|
||||
def __init__(self, msg, com_exception=None):
|
||||
Exception.__init__(self, msg, str(com_exception))
|
||||
|
||||
# Our COM server.
|
||||
class TestServer:
|
||||
_public_methods_ = [ 'Clone', 'Commit', 'LockRegion', 'Read']
|
||||
_com_interfaces_ = [ pythoncom.IID_IStream ]
|
||||
|
||||
def Clone(self):
|
||||
raise COMException("Not today", scode=winerror.E_UNEXPECTED)
|
||||
|
||||
def Commit(self, flags):
|
||||
raise Exception("foo")
|
||||
|
||||
def test():
|
||||
# Call via a native interface.
|
||||
com_server = wrap(TestServer(), pythoncom.IID_IStream)
|
||||
try:
|
||||
com_server.Clone()
|
||||
raise error("Expecting this call to fail!")
|
||||
except pythoncom.com_error as com_exc:
|
||||
if com_exc.hresult != winerror.E_UNEXPECTED:
|
||||
raise error("Calling the object natively did not yield the correct scode", com_exc)
|
||||
exc = com_exc.excepinfo
|
||||
if not exc or exc[-1] != winerror.E_UNEXPECTED:
|
||||
raise error("The scode element of the exception tuple did not yield the correct scode", com_exc)
|
||||
if exc[2] != "Not today":
|
||||
raise error("The description in the exception tuple did not yield the correct string", com_exc)
|
||||
cap = CaptureWriter()
|
||||
try:
|
||||
cap.capture()
|
||||
try:
|
||||
com_server.Commit(0)
|
||||
finally:
|
||||
cap.release()
|
||||
raise error("Expecting this call to fail!")
|
||||
except pythoncom.com_error as com_exc:
|
||||
if com_exc.hresult != winerror.E_FAIL:
|
||||
raise error("The hresult was not E_FAIL for an internal error", com_exc)
|
||||
if com_exc.excepinfo[1] != "Python COM Server Internal Error":
|
||||
raise error("The description in the exception tuple did not yield the correct string", com_exc)
|
||||
# Check we saw a traceback in stderr
|
||||
if cap.get_captured().find("Traceback")<0:
|
||||
raise error("Could not find a traceback in stderr: %r" % (cap.get_captured(),))
|
||||
|
||||
# Now do it all again, but using IDispatch
|
||||
com_server = Dispatch(wrap(TestServer()))
|
||||
try:
|
||||
com_server.Clone()
|
||||
raise error("Expecting this call to fail!")
|
||||
except pythoncom.com_error as com_exc:
|
||||
if com_exc.hresult != winerror.DISP_E_EXCEPTION:
|
||||
raise error("Calling the object via IDispatch did not yield the correct scode", com_exc)
|
||||
exc = com_exc.excepinfo
|
||||
if not exc or exc[-1] != winerror.E_UNEXPECTED:
|
||||
raise error("The scode element of the exception tuple did not yield the correct scode", com_exc)
|
||||
if exc[2] != "Not today":
|
||||
raise error("The description in the exception tuple did not yield the correct string", com_exc)
|
||||
|
||||
cap.clear()
|
||||
try:
|
||||
cap.capture()
|
||||
try:
|
||||
com_server.Commit(0)
|
||||
finally:
|
||||
cap.release()
|
||||
raise error("Expecting this call to fail!")
|
||||
except pythoncom.com_error as com_exc:
|
||||
if com_exc.hresult != winerror.DISP_E_EXCEPTION:
|
||||
raise error("Calling the object via IDispatch did not yield the correct scode", com_exc)
|
||||
exc = com_exc.excepinfo
|
||||
if not exc or exc[-1] != winerror.E_FAIL:
|
||||
raise error("The scode element of the exception tuple did not yield the correct scode", com_exc)
|
||||
if exc[1] != "Python COM Server Internal Error":
|
||||
raise error("The description in the exception tuple did not yield the correct string", com_exc)
|
||||
# Check we saw a traceback in stderr
|
||||
if cap.get_captured().find("Traceback")<0:
|
||||
raise error("Could not find a traceback in stderr: %r" % (cap.get_captured(),))
|
||||
|
||||
try:
|
||||
import logging
|
||||
except ImportError:
|
||||
logging = None
|
||||
if logging is not None:
|
||||
import win32com
|
||||
class TestLogHandler(logging.Handler):
|
||||
def __init__(self):
|
||||
self.num_emits = 0
|
||||
logging.Handler.__init__(self)
|
||||
def emit(self, record):
|
||||
self.num_emits += 1
|
||||
return
|
||||
print("--- record start")
|
||||
print(self.format(record))
|
||||
print("--- record end")
|
||||
|
||||
def testLogger():
|
||||
assert not hasattr(win32com, "logger")
|
||||
handler = TestLogHandler()
|
||||
formatter = logging.Formatter('%(message)s')
|
||||
handler.setFormatter(formatter)
|
||||
log = logging.getLogger("win32com_test")
|
||||
log.addHandler(handler)
|
||||
win32com.logger = log
|
||||
# Now throw some exceptions!
|
||||
# Native interfaces
|
||||
com_server = wrap(TestServer(), pythoncom.IID_IStream)
|
||||
try:
|
||||
com_server.Commit(0)
|
||||
raise RuntimeError("should have failed")
|
||||
except pythoncom.error:
|
||||
pass
|
||||
assert handler.num_emits == 1, handler.num_emits
|
||||
handler.num_emits = 0 # reset
|
||||
|
||||
com_server = Dispatch(wrap(TestServer()))
|
||||
try:
|
||||
com_server.Commit(0)
|
||||
raise RuntimeError("should have failed")
|
||||
except pythoncom.error:
|
||||
pass
|
||||
assert handler.num_emits == 1, handler.num_emits
|
||||
|
||||
if __name__=='__main__':
|
||||
test()
|
||||
if logging is not None:
|
||||
testLogger()
|
||||
from .util import CheckClean
|
||||
CheckClean()
|
||||
print("error semantic tests worked")
|
66
venv/Lib/site-packages/win32com/test/pippo.idl
Normal file
66
venv/Lib/site-packages/win32com/test/pippo.idl
Normal file
|
@ -0,0 +1,66 @@
|
|||
// TestServer.idl : IDL source for TestServer.dll
|
||||
//
|
||||
|
||||
// This file will be processed by the MIDL tool to
|
||||
// produce the type library (TestServer.tlb) and marshalling code.
|
||||
|
||||
import "oaidl.idl";
|
||||
import "ocidl.idl";
|
||||
[
|
||||
object,
|
||||
uuid(50086EE8-F535-464B-806E-365ADBB727CF),
|
||||
dual,
|
||||
helpstring("ITestServerApp Interface"),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface ITestServerApp : IDispatch
|
||||
{
|
||||
[id(1), helpstring("method Test1")] HRESULT Test1([out, retval] ITestServerApp **pVal);
|
||||
[id(2), helpstring("method Test2")] HRESULT Test2([out, retval] VARIANT *pVar);
|
||||
[propget, id(3), helpstring("property MyProp1")] HRESULT MyProp1([out, retval] long *pVal);
|
||||
};
|
||||
[
|
||||
object,
|
||||
uuid(618DB2A3-D5BD-4850-B66A-828727EB37E5),
|
||||
dual,
|
||||
helpstring("IPippo Interface"),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface IPippo : IDispatch
|
||||
{
|
||||
[id(1), helpstring("method Method1")] HRESULT Method1([out, retval] IPippo **val);
|
||||
[propget, id(2), helpstring("property MyProp1")] HRESULT MyProp1([out, retval] long *pVal);
|
||||
[id(3), helpstring("method Method2")] HRESULT Method2([in] long in1, [in, out] long *inout1,
|
||||
[out, retval] long *val);
|
||||
[id(4), helpstring("method Method3")] HRESULT Method3([in] VARIANT in1,
|
||||
[out, retval] VARIANT *val);
|
||||
};
|
||||
|
||||
[
|
||||
uuid(7783054E-9A20-4584-8C62-6ED2A08F6AC6),
|
||||
version(1.0),
|
||||
helpstring("TestServer 1.0 Type Library")
|
||||
]
|
||||
library TESTSERVERLib
|
||||
{
|
||||
importlib("stdole32.tlb");
|
||||
importlib("stdole2.tlb");
|
||||
importlib("msado15.dll");
|
||||
|
||||
[
|
||||
uuid(49E44E89-5A72-4456-B1D5-68268A19E798),
|
||||
helpstring("TestServerApp Class")
|
||||
]
|
||||
coclass TestServerApp
|
||||
{
|
||||
[default] interface ITestServerApp;
|
||||
};
|
||||
[
|
||||
uuid(1F0F75D6-BD63-41B9-9F88-2D9D2E1AA5C3),
|
||||
helpstring("Pippo Class")
|
||||
]
|
||||
coclass Pippo
|
||||
{
|
||||
[default] interface IPippo;
|
||||
};
|
||||
};
|
85
venv/Lib/site-packages/win32com/test/pippo_server.py
Normal file
85
venv/Lib/site-packages/win32com/test/pippo_server.py
Normal file
|
@ -0,0 +1,85 @@
|
|||
# A little test server, complete with typelib, we can use for testing.
|
||||
# Originally submitted with bug:
|
||||
# [ 753154 ] memory leak wrapping object having _typelib_guid_ attribute
|
||||
# but modified by mhammond for use as part of the test suite.
|
||||
import sys, os
|
||||
import pythoncom
|
||||
import win32com
|
||||
import winerror
|
||||
from win32com.server.util import wrap
|
||||
|
||||
class CPippo:
|
||||
#
|
||||
# COM declarations
|
||||
#
|
||||
_reg_clsid_ = "{1F0F75D6-BD63-41B9-9F88-2D9D2E1AA5C3}"
|
||||
_reg_desc_ = "Pippo Python test object"
|
||||
_reg_progid_ = "Python.Test.Pippo"
|
||||
#_reg_clsctx_ = pythoncom.CLSCTX_LOCAL_SERVER
|
||||
###
|
||||
### Link to typelib
|
||||
_typelib_guid_ = '{7783054E-9A20-4584-8C62-6ED2A08F6AC6}'
|
||||
_typelib_version_ = 1, 0
|
||||
_com_interfaces_ = ['IPippo']
|
||||
|
||||
def __init__(self):
|
||||
self.MyProp1 = 10
|
||||
|
||||
def Method1(self):
|
||||
return wrap(CPippo())
|
||||
|
||||
def Method2(self, in1, inout1):
|
||||
return in1, inout1 * 2
|
||||
|
||||
def Method3(self, in1):
|
||||
# in1 will be a tuple, not a list.
|
||||
# Yet, we are not allowed to return a tuple, but need to convert it to a list first. (Bug?)
|
||||
return list(in1)
|
||||
|
||||
def BuildTypelib():
|
||||
from distutils.dep_util import newer
|
||||
this_dir = os.path.dirname(__file__)
|
||||
idl = os.path.abspath(os.path.join(this_dir, "pippo.idl"))
|
||||
tlb=os.path.splitext(idl)[0] + '.tlb'
|
||||
if newer(idl, tlb):
|
||||
print(("Compiling %s" % (idl,)))
|
||||
rc = os.system ('midl "%s"' % (idl,))
|
||||
if rc:
|
||||
raise RuntimeError("Compiling MIDL failed!")
|
||||
# Can't work out how to prevent MIDL from generating the stubs.
|
||||
# just nuke them
|
||||
for fname in "dlldata.c pippo_i.c pippo_p.c pippo.h".split():
|
||||
os.remove(os.path.join(this_dir, fname))
|
||||
|
||||
print(("Registering %s" % (tlb,)))
|
||||
tli=pythoncom.LoadTypeLib(tlb)
|
||||
pythoncom.RegisterTypeLib(tli,tlb)
|
||||
|
||||
def UnregisterTypelib():
|
||||
k = CPippo
|
||||
try:
|
||||
pythoncom.UnRegisterTypeLib(k._typelib_guid_,
|
||||
k._typelib_version_[0],
|
||||
k._typelib_version_[1],
|
||||
0,
|
||||
pythoncom.SYS_WIN32)
|
||||
print("Unregistered typelib")
|
||||
except pythoncom.error as details:
|
||||
if details[0]==winerror.TYPE_E_REGISTRYACCESS:
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
|
||||
def main(argv=None):
|
||||
if argv is None: argv = sys.argv[1:]
|
||||
if '--unregister' in argv:
|
||||
# Unregister the type-libraries.
|
||||
UnregisterTypelib()
|
||||
else:
|
||||
# Build and register the type-libraries.
|
||||
BuildTypelib()
|
||||
import win32com.server.register
|
||||
win32com.server.register.UseCommandLine(CPippo)
|
||||
|
||||
if __name__=='__main__':
|
||||
main(sys.argv)
|
90
venv/Lib/site-packages/win32com/test/policySemantics.py
Normal file
90
venv/Lib/site-packages/win32com/test/policySemantics.py
Normal file
|
@ -0,0 +1,90 @@
|
|||
import win32com.server.util
|
||||
import win32com.client
|
||||
import pythoncom
|
||||
import winerror
|
||||
import win32com.test.util
|
||||
|
||||
import unittest
|
||||
|
||||
class Error(Exception):
|
||||
pass
|
||||
|
||||
# An object representing a list of numbers
|
||||
class PythonSemanticClass:
|
||||
_public_methods_ = ["In"] # DISPIDs are allocated.
|
||||
_dispid_to_func_ = { 10: 'Add', 11:'Remove'} # DISPIDs specified by the object.
|
||||
def __init__(self):
|
||||
self.list = []
|
||||
def _NewEnum(self):
|
||||
return win32com.server.util.NewEnum(self.list)
|
||||
def _value_(self):
|
||||
# should return an array.
|
||||
return self.list
|
||||
def _Evaluate(self):
|
||||
# return the sum
|
||||
return sum(self.list)
|
||||
def In(self, value):
|
||||
return value in self.list
|
||||
def Add(self, value):
|
||||
self.list.append(value)
|
||||
def Remove(self, value):
|
||||
self.list.remove(value)
|
||||
|
||||
def DispExTest(ob):
|
||||
if not __debug__: print("WARNING: Tests dressed up as assertions are being skipped!")
|
||||
assert ob.GetDispID("Add", 0)==10, "Policy did not honour the dispid"
|
||||
# Not impl
|
||||
# assert ob.GetMemberName(10, 0)=="add", "Policy did not give me the correct function for the dispid"
|
||||
assert ob.GetDispID("Remove", 0)==11, "Policy did not honour the dispid"
|
||||
assert ob.GetDispID("In", 0)==1000, "Allocated dispid unexpected value"
|
||||
assert ob.GetDispID("_NewEnum", 0)==pythoncom.DISPID_NEWENUM, "_NewEnum() got unexpected DISPID"
|
||||
dispids = []
|
||||
dispid = -1
|
||||
while 1:
|
||||
try:
|
||||
dispid = ob.GetNextDispID(0, dispid)
|
||||
dispids.append(dispid)
|
||||
except pythoncom.com_error as xxx_todo_changeme:
|
||||
(hr, desc, exc, arg) = xxx_todo_changeme.args
|
||||
assert hr==winerror.S_FALSE, "Bad result at end of enum"
|
||||
break
|
||||
dispids.sort()
|
||||
if dispids != [pythoncom.DISPID_EVALUATE, pythoncom.DISPID_NEWENUM, 10, 11, 1000]:
|
||||
raise Error("Got back the wrong dispids: %s" % dispids)
|
||||
|
||||
def SemanticTest(ob):
|
||||
# First just check our object "generally" as expected.
|
||||
ob.Add(1)
|
||||
ob.Add(2)
|
||||
ob.Add(3)
|
||||
# invoke _value_
|
||||
if ob() != (1,2,3):
|
||||
raise Error("Bad result - got %s" % (repr(ob())))
|
||||
|
||||
dispob = ob._oleobj_
|
||||
|
||||
rc = dispob.Invoke(pythoncom.DISPID_EVALUATE, 0, pythoncom.DISPATCH_METHOD|pythoncom.DISPATCH_PROPERTYGET, 1)
|
||||
if rc != 6:
|
||||
raise Error("Evaluate returned %d" % rc)
|
||||
|
||||
|
||||
class Tester(win32com.test.util.TestCase):
|
||||
def setUp(self):
|
||||
debug=0
|
||||
import win32com.server.dispatcher
|
||||
if debug:
|
||||
dispatcher=win32com.server.dispatcher.DefaultDebugDispatcher
|
||||
else:
|
||||
dispatcher=None
|
||||
disp = win32com.server.util.wrap(PythonSemanticClass(), useDispatcher=dispatcher)
|
||||
self.ob = win32com.client.Dispatch(disp)
|
||||
def tearDown(self):
|
||||
self.ob = None
|
||||
def testSemantics(self):
|
||||
SemanticTest(self.ob)
|
||||
def testIDispatchEx(self):
|
||||
dispexob = self.ob._oleobj_.QueryInterface(pythoncom.IID_IDispatchEx)
|
||||
DispExTest(dispexob)
|
||||
|
||||
if __name__=='__main__':
|
||||
unittest.main()
|
18
venv/Lib/site-packages/win32com/test/readme.txt
Normal file
18
venv/Lib/site-packages/win32com/test/readme.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
COM Test Suite Readme
|
||||
---------------------
|
||||
|
||||
Running the test suite:
|
||||
-----------------------
|
||||
* Open a command prompt
|
||||
* Change to the "win32com\test" directory.
|
||||
* run "testall.py". This will perform level 1 testing.
|
||||
You may specify 1, 2, or 3 on the command line ("testutil 3")
|
||||
to execute more tests.
|
||||
|
||||
In general, this should just run the best it can, utilizing what is available
|
||||
on the machine. It is likely some tests will refuse to run due to objects not
|
||||
being locally available - this is normal.
|
||||
|
||||
The win32com source tree has source code to a C++ and VB component used purely
|
||||
for testing. You may like to build and register these, particularly if you
|
||||
are doing anything related to argument/result handling.
|
74
venv/Lib/site-packages/win32com/test/testADOEvents.py
Normal file
74
venv/Lib/site-packages/win32com/test/testADOEvents.py
Normal file
|
@ -0,0 +1,74 @@
|
|||
from win32com.client import Dispatch, DispatchWithEvents, constants
|
||||
import pythoncom
|
||||
import os
|
||||
import time
|
||||
|
||||
finished = 0 # Flag for the wait loop from (3) to test
|
||||
|
||||
class ADOEvents: # event handler class
|
||||
def OnWillConnect(self, str, user, pw, opt, sts, cn):
|
||||
# Must have this event, as if it is not handled, ADO assumes the
|
||||
# operation is cancelled, and raises an error (Operation cancelled
|
||||
# by the user)
|
||||
pass
|
||||
def OnConnectComplete(self, error, status, connection):
|
||||
# Assume no errors, until we have the basic stuff
|
||||
# working. Now, "connection" should be an open
|
||||
# connection to my data source
|
||||
# Do the "something" from (2). For now, just
|
||||
# print the connection data source
|
||||
print("connection is", connection)
|
||||
print("Connected to", connection.Properties("Data Source"))
|
||||
# OK, our work is done. Let the main loop know
|
||||
global finished
|
||||
finished = 1
|
||||
def OnCommitTransComplete(self, pError, adStatus, pConnection):
|
||||
pass
|
||||
def OnInfoMessage(self, pError, adStatus, pConnection):
|
||||
pass
|
||||
def OnDisconnect(self, adStatus, pConnection):
|
||||
pass
|
||||
def OnBeginTransComplete(self, TransactionLevel, pError, adStatus, pConnection):
|
||||
pass
|
||||
def OnRollbackTransComplete(self, pError, adStatus, pConnection):
|
||||
pass
|
||||
def OnExecuteComplete(self, RecordsAffected, pError, adStatus, pCommand, pRecordset, pConnection):
|
||||
pass
|
||||
def OnWillExecute(self, Source, CursorType, LockType, Options, adStatus, pCommand, pRecordset, pConnection):
|
||||
pass
|
||||
|
||||
def TestConnection(dbname):
|
||||
# Create the ADO connection object, and link the event
|
||||
# handlers into it
|
||||
c = DispatchWithEvents("ADODB.Connection", ADOEvents)
|
||||
|
||||
# Initiate the asynchronous open
|
||||
dsn = "Driver={Microsoft Access Driver (*.mdb)};Dbq=%s" % dbname
|
||||
user = "system"
|
||||
pw = "manager"
|
||||
c.Open(dsn, user, pw, constants.adAsyncConnect)
|
||||
|
||||
# Sit in a loop, until our event handler (above) sets the
|
||||
# "finished" flag or we time out.
|
||||
end_time = time.clock() + 10
|
||||
while time.clock() < end_time:
|
||||
# Pump messages so that COM gets a look in
|
||||
pythoncom.PumpWaitingMessages()
|
||||
if not finished:
|
||||
print("XXX - Failed to connect!")
|
||||
|
||||
def Test():
|
||||
from . import testAccess
|
||||
try:
|
||||
testAccess.GenerateSupport()
|
||||
except pythoncom.com_error:
|
||||
print("*** Can not import the MSAccess type libraries - tests skipped")
|
||||
return
|
||||
dbname = testAccess.CreateTestAccessDatabase()
|
||||
try:
|
||||
TestConnection(dbname)
|
||||
finally:
|
||||
os.unlink(dbname)
|
||||
|
||||
if __name__=='__main__':
|
||||
Test()
|
34
venv/Lib/site-packages/win32com/test/testAXScript.py
Normal file
34
venv/Lib/site-packages/win32com/test/testAXScript.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Test AXScripting the best we can in an automated fashion...
|
||||
import win32api, os, sys
|
||||
|
||||
import win32com.axscript
|
||||
import win32com.axscript.client
|
||||
|
||||
import unittest
|
||||
import win32com.test.util
|
||||
|
||||
verbose = "-v" in sys.argv
|
||||
|
||||
class AXScript(win32com.test.util.TestCase):
|
||||
def setUp(self):
|
||||
file = win32api.GetFullPathName(os.path.join(win32com.axscript.client.__path__[0], "pyscript.py"))
|
||||
from win32com.test.util import RegisterPythonServer
|
||||
self.verbose = verbose
|
||||
RegisterPythonServer(file, 'python', verbose=self.verbose)
|
||||
|
||||
def testHost(self):
|
||||
file = win32api.GetFullPathName(os.path.join(win32com.axscript.__path__[0], "test\\testHost.py"))
|
||||
cmd = '%s "%s"' % (win32api.GetModuleFileName(0), file)
|
||||
if verbose:
|
||||
print("Testing Python Scripting host")
|
||||
win32com.test.util.ExecuteShellCommand(cmd, self)
|
||||
|
||||
def testCScript(self):
|
||||
file = win32api.GetFullPathName(os.path.join(win32com.axscript.__path__[0], "Demos\\Client\\wsh\\test.pys"))
|
||||
cmd = 'cscript.exe "%s"' % (file)
|
||||
if verbose:
|
||||
print("Testing Windows Scripting host with Python script")
|
||||
win32com.test.util.ExecuteShellCommand(cmd, self)
|
||||
|
||||
if __name__=='__main__':
|
||||
win32com.test.util.testmain()
|
169
venv/Lib/site-packages/win32com/test/testAccess.py
Normal file
169
venv/Lib/site-packages/win32com/test/testAccess.py
Normal file
|
@ -0,0 +1,169 @@
|
|||
#
|
||||
# This assumes that you have MSAccess and DAO installed.
|
||||
# You need to run makepy.py over "msaccess.tlb" and
|
||||
# "dao3032.dll", and ensure the generated files are on the
|
||||
# path.
|
||||
|
||||
# You can run this with no args, and a test database will be generated.
|
||||
# You can optionally pass a dbname on the command line, in which case it will be dumped.
|
||||
|
||||
import pythoncom
|
||||
from win32com.client import gencache, constants, Dispatch
|
||||
import win32api
|
||||
import os, sys
|
||||
|
||||
def CreateTestAccessDatabase(dbname = None):
|
||||
# Creates a test access database - returns the filename.
|
||||
if dbname is None:
|
||||
dbname = os.path.join( win32api.GetTempPath(), "COMTestSuiteTempDatabase.mdb" )
|
||||
|
||||
access = Dispatch("Access.Application")
|
||||
dbEngine = access.DBEngine
|
||||
workspace = dbEngine.Workspaces(0)
|
||||
|
||||
try:
|
||||
os.unlink(dbname)
|
||||
except os.error:
|
||||
print("WARNING - Unable to delete old test database - expect a COM exception RSN!")
|
||||
|
||||
newdb = workspace.CreateDatabase( dbname, constants.dbLangGeneral, constants.dbEncrypt )
|
||||
|
||||
# Create one test table.
|
||||
table = newdb.CreateTableDef("Test Table 1")
|
||||
table.Fields.Append( table.CreateField("First Name", constants.dbText ) )
|
||||
table.Fields.Append( table.CreateField("Last Name", constants.dbText ) )
|
||||
|
||||
index = table.CreateIndex("UniqueIndex")
|
||||
index.Fields.Append( index.CreateField("First Name") )
|
||||
index.Fields.Append( index.CreateField("Last Name") )
|
||||
index.Unique = -1
|
||||
table.Indexes.Append(index)
|
||||
|
||||
newdb.TableDefs.Append( table )
|
||||
|
||||
# Create a second test table.
|
||||
table = newdb.CreateTableDef("Test Table 2")
|
||||
table.Fields.Append( table.CreateField("First Name", constants.dbText ) )
|
||||
table.Fields.Append( table.CreateField("Last Name", constants.dbText ) )
|
||||
|
||||
newdb.TableDefs.Append( table )
|
||||
|
||||
# Create a relationship between them
|
||||
relation = newdb.CreateRelation("TestRelationship")
|
||||
relation.Table = "Test Table 1"
|
||||
relation.ForeignTable = "Test Table 2"
|
||||
|
||||
field = relation.CreateField("First Name")
|
||||
field.ForeignName = "First Name"
|
||||
relation.Fields.Append( field )
|
||||
|
||||
field = relation.CreateField("Last Name")
|
||||
field.ForeignName = "Last Name"
|
||||
relation.Fields.Append( field )
|
||||
|
||||
relation.Attributes = constants.dbRelationDeleteCascade + constants.dbRelationUpdateCascade
|
||||
|
||||
newdb.Relations.Append(relation)
|
||||
|
||||
# Finally we can add some data to the table.
|
||||
tab1 = newdb.OpenRecordset("Test Table 1")
|
||||
tab1.AddNew()
|
||||
tab1.Fields("First Name").Value = "Mark"
|
||||
tab1.Fields("Last Name").Value = "Hammond"
|
||||
tab1.Update()
|
||||
|
||||
tab1.MoveFirst()
|
||||
# We do a simple bookmark test which tests our optimized VT_SAFEARRAY|VT_UI1 support.
|
||||
# The bookmark will be a buffer object - remember it for later.
|
||||
bk = tab1.Bookmark
|
||||
|
||||
# Add a second record.
|
||||
tab1.AddNew()
|
||||
tab1.Fields("First Name").Value = "Second"
|
||||
tab1.Fields("Last Name").Value = "Person"
|
||||
tab1.Update()
|
||||
|
||||
# Reset the bookmark to the one we saved.
|
||||
# But first check the test is actually doing something!
|
||||
tab1.MoveLast()
|
||||
if tab1.Fields("First Name").Value != "Second":
|
||||
raise RuntimeError("Unexpected record is last - makes bookmark test pointless!")
|
||||
|
||||
tab1.Bookmark = bk
|
||||
if tab1.Bookmark != bk:
|
||||
raise RuntimeError("The bookmark data is not the same")
|
||||
|
||||
if tab1.Fields("First Name").Value != "Mark":
|
||||
raise RuntimeError("The bookmark did not reset the record pointer correctly")
|
||||
|
||||
return dbname
|
||||
|
||||
|
||||
def DoDumpAccessInfo(dbname):
|
||||
from . import daodump
|
||||
a = forms = None
|
||||
try:
|
||||
sys.stderr.write("Creating Access Application...\n")
|
||||
a=Dispatch("Access.Application")
|
||||
print("Opening database %s" % dbname)
|
||||
a.OpenCurrentDatabase(dbname)
|
||||
db = a.CurrentDb()
|
||||
daodump.DumpDB(db,1)
|
||||
forms = a.Forms
|
||||
print("There are %d forms open." % (len(forms)))
|
||||
# Uncommenting these lines means Access remains open.
|
||||
# for form in forms:
|
||||
# print " %s" % form.Name
|
||||
reports = a.Reports
|
||||
print("There are %d reports open" % (len(reports)))
|
||||
finally:
|
||||
if not a is None:
|
||||
sys.stderr.write("Closing database\n")
|
||||
try:
|
||||
a.CloseCurrentDatabase()
|
||||
except pythoncom.com_error:
|
||||
pass
|
||||
|
||||
# Generate all the support we can.
|
||||
def GenerateSupport():
|
||||
# dao
|
||||
gencache.EnsureModule("{00025E01-0000-0000-C000-000000000046}", 0, 4, 0)
|
||||
# Access
|
||||
# gencache.EnsureModule("{4AFFC9A0-5F99-101B-AF4E-00AA003F0F07}", 0, 8, 0)
|
||||
gencache.EnsureDispatch("Access.Application")
|
||||
|
||||
def DumpAccessInfo(dbname):
|
||||
amod = gencache.GetModuleForProgID("Access.Application")
|
||||
dmod = gencache.GetModuleForProgID("DAO.DBEngine.35")
|
||||
if amod is None and dmod is None:
|
||||
DoDumpAccessInfo(dbname)
|
||||
# Now generate all the support we can.
|
||||
GenerateSupport()
|
||||
else:
|
||||
sys.stderr.write("testAccess not doing dynamic test, as generated code already exists\n")
|
||||
# Now a generated version.
|
||||
DoDumpAccessInfo(dbname)
|
||||
|
||||
def test(dbname = None):
|
||||
if dbname is None:
|
||||
# We need makepy support to create a database (just for the constants!)
|
||||
try:
|
||||
GenerateSupport()
|
||||
except pythoncom.com_error:
|
||||
print("*** Can not import the MSAccess type libraries - tests skipped")
|
||||
return
|
||||
dbname = CreateTestAccessDatabase()
|
||||
print("A test database at '%s' was created" % dbname)
|
||||
|
||||
DumpAccessInfo(dbname)
|
||||
|
||||
if __name__=='__main__':
|
||||
import sys
|
||||
from .util import CheckClean
|
||||
dbname = None
|
||||
if len(sys.argv)>1:
|
||||
dbname = sys.argv[1]
|
||||
|
||||
test(dbname)
|
||||
|
||||
CheckClean()
|
124
venv/Lib/site-packages/win32com/test/testArrays.py
Normal file
124
venv/Lib/site-packages/win32com/test/testArrays.py
Normal file
|
@ -0,0 +1,124 @@
|
|||
# Originally contributed by Stefan Schukat as part of this arbitrary-sized
|
||||
# arrays patch.
|
||||
from win32com.client import gencache
|
||||
from win32com.test import util
|
||||
import unittest
|
||||
|
||||
ZeroD = 0
|
||||
OneDEmpty = []
|
||||
OneD = [1,2,3]
|
||||
TwoD = [
|
||||
[1,2,3],
|
||||
[1,2,3],
|
||||
[1,2,3]
|
||||
]
|
||||
|
||||
TwoD1 = [
|
||||
[
|
||||
[1,2,3,5],
|
||||
[1,2,3],
|
||||
[1,2,3]
|
||||
],
|
||||
[
|
||||
[1,2,3],
|
||||
[1,2,3],
|
||||
[1,2,3]
|
||||
]
|
||||
]
|
||||
|
||||
OneD1 = [
|
||||
[
|
||||
[1,2,3],
|
||||
[1,2,3],
|
||||
[1,2,3]
|
||||
],
|
||||
[
|
||||
[1,2,3],
|
||||
[1,2,3]
|
||||
]
|
||||
]
|
||||
|
||||
OneD2 = [
|
||||
[1,2,3],
|
||||
[1,2,3,4,5],
|
||||
[
|
||||
[1,2,3,4,5],
|
||||
[1,2,3,4,5],
|
||||
[1,2,3,4,5]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
ThreeD = [
|
||||
[
|
||||
[1,2,3],
|
||||
[1,2,3],
|
||||
[1,2,3]
|
||||
],
|
||||
[
|
||||
[1,2,3],
|
||||
[1,2,3],
|
||||
[1,2,3]
|
||||
]
|
||||
]
|
||||
|
||||
FourD = [
|
||||
[
|
||||
[[1,2,3],[1,2,3],[1,2,3]],
|
||||
[[1,2,3],[1,2,3],[1,2,3]],
|
||||
[[1,2,3],[1,2,3],[1,2,3]]
|
||||
],
|
||||
[
|
||||
[[1,2,3],[1,2,3],[1,2,3]],
|
||||
[[1,2,3],[1,2,3],[1,2,3]],
|
||||
[[1,2,3],[1,2,3],[1,2,3]]
|
||||
]
|
||||
]
|
||||
|
||||
LargeD = [
|
||||
[ [list(range(10))] * 10],
|
||||
] * 512
|
||||
|
||||
def _normalize_array(a):
|
||||
if type(a) != type(()):
|
||||
return a
|
||||
ret = []
|
||||
for i in a:
|
||||
ret.append(_normalize_array(i))
|
||||
return ret
|
||||
|
||||
class ArrayTest(util.TestCase):
|
||||
def setUp(self):
|
||||
self.arr = gencache.EnsureDispatch("PyCOMTest.ArrayTest")
|
||||
def tearDown(self):
|
||||
self.arr = None
|
||||
def _doTest(self, array):
|
||||
self.arr.Array = array
|
||||
self.failUnlessEqual(_normalize_array(self.arr.Array), array)
|
||||
def testZeroD(self):
|
||||
self._doTest(ZeroD)
|
||||
def testOneDEmpty(self):
|
||||
self._doTest(OneDEmpty)
|
||||
def testOneD(self):
|
||||
self._doTest(OneD)
|
||||
def testTwoD(self):
|
||||
self._doTest(TwoD)
|
||||
def testThreeD(self):
|
||||
self._doTest(ThreeD)
|
||||
def testFourD(self):
|
||||
self._doTest(FourD)
|
||||
def testTwoD1(self):
|
||||
self._doTest(TwoD1)
|
||||
def testOneD1(self):
|
||||
self._doTest(OneD1)
|
||||
def testOneD2(self):
|
||||
self._doTest(OneD2)
|
||||
def testLargeD(self):
|
||||
self._doTest(LargeD)
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
util.testmain()
|
||||
except SystemExit as rc:
|
||||
if not rc:
|
||||
raise
|
160
venv/Lib/site-packages/win32com/test/testClipboard.py
Normal file
160
venv/Lib/site-packages/win32com/test/testClipboard.py
Normal file
|
@ -0,0 +1,160 @@
|
|||
# testClipboard.py
|
||||
import unittest
|
||||
import pythoncom
|
||||
import win32con
|
||||
import winerror
|
||||
import win32clipboard
|
||||
|
||||
from pywin32_testutil import str2bytes
|
||||
|
||||
from win32com.server.util import NewEnum, wrap
|
||||
from win32com.server.exception import COMException
|
||||
|
||||
IDataObject_Methods = """GetData GetDataHere QueryGetData
|
||||
GetCanonicalFormatEtc SetData EnumFormatEtc
|
||||
DAdvise DUnadvise EnumDAdvise""".split()
|
||||
|
||||
# A COM object implementing IDataObject used for basic testing.
|
||||
num_do_objects = 0
|
||||
|
||||
def WrapCOMObject(ob, iid=None):
|
||||
return wrap(ob, iid=iid, useDispatcher = 0)
|
||||
|
||||
class TestDataObject:
|
||||
_com_interfaces_ = [pythoncom.IID_IDataObject]
|
||||
_public_methods_ = IDataObject_Methods
|
||||
def __init__(self, strval):
|
||||
global num_do_objects
|
||||
num_do_objects += 1
|
||||
self.strval = strval
|
||||
self.supported_fe = []
|
||||
for cf in (win32con.CF_TEXT, win32con.CF_UNICODETEXT):
|
||||
fe = cf, None, pythoncom.DVASPECT_CONTENT, -1, pythoncom.TYMED_HGLOBAL
|
||||
self.supported_fe.append(fe)
|
||||
|
||||
def __del__(self):
|
||||
global num_do_objects
|
||||
num_do_objects -= 1
|
||||
|
||||
def _query_interface_(self, iid):
|
||||
if iid==pythoncom.IID_IEnumFORMATETC:
|
||||
return NewEnum(self.supported_fe, iid=iid)
|
||||
|
||||
def GetData(self, fe):
|
||||
ret_stg = None
|
||||
cf, target, aspect, index, tymed = fe
|
||||
if aspect & pythoncom.DVASPECT_CONTENT and \
|
||||
tymed==pythoncom.TYMED_HGLOBAL:
|
||||
if cf == win32con.CF_TEXT:
|
||||
ret_stg = pythoncom.STGMEDIUM()
|
||||
# ensure always 'bytes' by encoding string.
|
||||
ret_stg.set(pythoncom.TYMED_HGLOBAL, str2bytes(self.strval))
|
||||
elif cf == win32con.CF_UNICODETEXT:
|
||||
ret_stg = pythoncom.STGMEDIUM()
|
||||
ret_stg.set(pythoncom.TYMED_HGLOBAL, str(self.strval))
|
||||
|
||||
if ret_stg is None:
|
||||
raise COMException(hresult=winerror.E_NOTIMPL)
|
||||
return ret_stg
|
||||
|
||||
def GetDataHere(self, fe):
|
||||
raise COMException(hresult=winerror.E_NOTIMPL)
|
||||
|
||||
def QueryGetData(self, fe):
|
||||
cf, target, aspect, index, tymed = fe
|
||||
if aspect & pythoncom.DVASPECT_CONTENT == 0:
|
||||
raise COMException(hresult=winerror.DV_E_DVASPECT)
|
||||
if tymed!=pythoncom.TYMED_HGLOBAL:
|
||||
raise COMException(hresult=winerror.DV_E_TYMED)
|
||||
return None # should check better
|
||||
|
||||
def GetCanonicalFormatEtc(self, fe):
|
||||
RaiseCOMException(winerror.DATA_S_SAMEFORMATETC)
|
||||
# return fe
|
||||
|
||||
def SetData(self, fe, medium):
|
||||
raise COMException(hresult=winerror.E_NOTIMPL)
|
||||
|
||||
def EnumFormatEtc(self, direction):
|
||||
if direction != pythoncom.DATADIR_GET:
|
||||
raise COMException(hresult=winerror.E_NOTIMPL)
|
||||
return NewEnum(self.supported_fe, iid=pythoncom.IID_IEnumFORMATETC)
|
||||
|
||||
def DAdvise(self, fe, flags, sink):
|
||||
raise COMException(hresult=winerror.E_NOTIMPL)
|
||||
|
||||
def DUnadvise(self, connection):
|
||||
raise COMException(hresult=winerror.E_NOTIMPL)
|
||||
|
||||
def EnumDAdvise(self):
|
||||
raise COMException(hresult=winerror.E_NOTIMPL)
|
||||
|
||||
class ClipboardTester(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pythoncom.OleInitialize()
|
||||
def tearDown(self):
|
||||
try:
|
||||
pythoncom.OleFlushClipboard()
|
||||
except pythoncom.com_error:
|
||||
# We never set anything!
|
||||
pass
|
||||
def testIsCurrentClipboard(self):
|
||||
do = TestDataObject("Hello from Python")
|
||||
do = WrapCOMObject(do, iid=pythoncom.IID_IDataObject)
|
||||
pythoncom.OleSetClipboard(do)
|
||||
self.failUnless(pythoncom.OleIsCurrentClipboard(do))
|
||||
|
||||
def testComToWin32(self):
|
||||
# Set the data via our DataObject
|
||||
do = TestDataObject("Hello from Python")
|
||||
do = WrapCOMObject(do, iid=pythoncom.IID_IDataObject)
|
||||
pythoncom.OleSetClipboard(do)
|
||||
# Then get it back via the standard win32 clipboard functions.
|
||||
win32clipboard.OpenClipboard()
|
||||
got = win32clipboard.GetClipboardData(win32con.CF_TEXT)
|
||||
# CF_TEXT gives bytes on py3k - use str2bytes() to ensure that's true.
|
||||
expected = str2bytes("Hello from Python")
|
||||
self.assertEqual(got, expected)
|
||||
# Now check unicode
|
||||
got = win32clipboard.GetClipboardData(win32con.CF_UNICODETEXT)
|
||||
self.assertEqual(got, "Hello from Python")
|
||||
win32clipboard.CloseClipboard()
|
||||
|
||||
def testWin32ToCom(self):
|
||||
# Set the data via the std win32 clipboard functions.
|
||||
val = str2bytes("Hello again!") # ensure always bytes, even in py3k
|
||||
win32clipboard.OpenClipboard()
|
||||
win32clipboard.SetClipboardData(win32con.CF_TEXT, val)
|
||||
win32clipboard.CloseClipboard()
|
||||
# and get it via an IDataObject provided by COM
|
||||
do = pythoncom.OleGetClipboard()
|
||||
cf = win32con.CF_TEXT, None, pythoncom.DVASPECT_CONTENT, -1, pythoncom.TYMED_HGLOBAL
|
||||
stg = do.GetData(cf)
|
||||
got = stg.data
|
||||
# The data we get back has the \0, as our STGMEDIUM has no way of
|
||||
# knowing if it meant to be a string, or a binary buffer, so
|
||||
# it must return it too.
|
||||
self.failUnlessEqual(got, str2bytes("Hello again!\0"))
|
||||
|
||||
def testDataObjectFlush(self):
|
||||
do = TestDataObject("Hello from Python")
|
||||
do = WrapCOMObject(do, iid=pythoncom.IID_IDataObject)
|
||||
pythoncom.OleSetClipboard(do)
|
||||
self.assertEqual(num_do_objects, 1)
|
||||
|
||||
do = None # clear my ref!
|
||||
pythoncom.OleFlushClipboard()
|
||||
self.assertEqual(num_do_objects, 0)
|
||||
|
||||
def testDataObjectReset(self):
|
||||
do = TestDataObject("Hello from Python")
|
||||
do = WrapCOMObject(do)
|
||||
pythoncom.OleSetClipboard(do)
|
||||
do = None # clear my ref!
|
||||
self.assertEqual(num_do_objects, 1)
|
||||
pythoncom.OleSetClipboard(None)
|
||||
self.assertEqual(num_do_objects, 0)
|
||||
|
||||
if __name__=='__main__':
|
||||
from win32com.test import util
|
||||
util.testmain()
|
147
venv/Lib/site-packages/win32com/test/testCollections.py
Normal file
147
venv/Lib/site-packages/win32com/test/testCollections.py
Normal file
|
@ -0,0 +1,147 @@
|
|||
# testCollections.py
|
||||
#
|
||||
# This code tests both the client and server side of collections
|
||||
# and enumerators.
|
||||
#
|
||||
# Also has the side effect of testing some of the PythonCOM error semantics.
|
||||
import sys
|
||||
import win32com.server.util
|
||||
import win32com.test.util
|
||||
import win32com.client
|
||||
import traceback
|
||||
import pythoncom
|
||||
import pywintypes
|
||||
import winerror
|
||||
L=pywintypes.Unicode
|
||||
|
||||
import unittest
|
||||
|
||||
error = "collection test error"
|
||||
|
||||
def MakeEmptyEnum():
|
||||
# create the Python enumerator object as a real COM object
|
||||
o = win32com.server.util.wrap( win32com.server.util.Collection() )
|
||||
return win32com.client.Dispatch(o)
|
||||
|
||||
def MakeTestEnum():
|
||||
# create a sub-collection, just to make sure it works :-)
|
||||
sub = win32com.server.util.wrap( win32com.server.util.Collection( ['Sub1', 2, 'Sub3']) )
|
||||
# create the Python enumerator object as a real COM object
|
||||
o = win32com.server.util.wrap( win32com.server.util.Collection( [1,'Two',3, sub]))
|
||||
return win32com.client.Dispatch(o)
|
||||
|
||||
def TestEnumAgainst(o,check):
|
||||
for i in range(len(check)):
|
||||
if o(i) != check[i]:
|
||||
raise error("Using default method gave the incorrect value - %s/%s" % (repr(o(i)), repr(check[i])))
|
||||
|
||||
for i in range(len(check)):
|
||||
if o.Item(i) != check[i]:
|
||||
raise error("Using Item method gave the incorrect value - %s/%s" % (repr(o(i)), repr(check[i])))
|
||||
|
||||
# First try looping.
|
||||
cmp = []
|
||||
for s in o:
|
||||
cmp.append(s)
|
||||
|
||||
if cmp[:len(check)] != check:
|
||||
raise error("Result after looping isnt correct - %s/%s" % (repr(cmp[:len(check)]), repr(check)))
|
||||
|
||||
for i in range(len(check)):
|
||||
if o[i] != check[i]:
|
||||
raise error("Using indexing gave the incorrect value")
|
||||
|
||||
|
||||
def TestEnum(quiet=None):
|
||||
if quiet is None:
|
||||
quiet = not "-v" in sys.argv
|
||||
if not quiet: print("Simple enum test")
|
||||
o = MakeTestEnum()
|
||||
check = [1,'Two',3]
|
||||
TestEnumAgainst(o, check)
|
||||
|
||||
if not quiet: print("sub-collection test")
|
||||
sub = o[3]
|
||||
TestEnumAgainst(sub ,['Sub1', 2, 'Sub3'])
|
||||
|
||||
# Remove the sublist for this test!
|
||||
o.Remove(o.Count()-1)
|
||||
|
||||
if not quiet: print("Remove item test")
|
||||
del check[1]
|
||||
o.Remove(1)
|
||||
TestEnumAgainst(o, check)
|
||||
|
||||
if not quiet: print("Add item test")
|
||||
o.Add('New Item')
|
||||
check.append('New Item')
|
||||
TestEnumAgainst(o, check)
|
||||
|
||||
if not quiet: print("Insert item test")
|
||||
o.Insert(2, -1)
|
||||
check.insert(2, -1)
|
||||
TestEnumAgainst(o, check)
|
||||
|
||||
### This does not work!
|
||||
# if not quiet: print "Indexed replace item test"
|
||||
# o[2] = 'Replaced Item'
|
||||
# check[2] = 'Replaced Item'
|
||||
# TestEnumAgainst(o, check)
|
||||
|
||||
try:
|
||||
o()
|
||||
raise error("default method with no args worked when it shouldnt have!")
|
||||
except pythoncom.com_error as xxx_todo_changeme:
|
||||
(hr, desc, exc, argErr) = xxx_todo_changeme.args
|
||||
if hr != winerror.DISP_E_BADPARAMCOUNT:
|
||||
raise error("Expected DISP_E_BADPARAMCOUNT - got %d (%s)" % (hr, desc))
|
||||
|
||||
try:
|
||||
o.Insert("foo", 2)
|
||||
raise error("Insert worked when it shouldnt have!")
|
||||
except pythoncom.com_error as xxx_todo_changeme1:
|
||||
(hr, desc, exc, argErr) = xxx_todo_changeme1.args
|
||||
if hr != winerror.DISP_E_TYPEMISMATCH:
|
||||
raise error("Expected DISP_E_TYPEMISMATCH - got %d (%s)" % (hr, desc))
|
||||
|
||||
# Remove the sublist for this test!
|
||||
try:
|
||||
o.Remove(o.Count())
|
||||
raise error("Remove worked when it shouldnt have!")
|
||||
except pythoncom.com_error as xxx_todo_changeme2:
|
||||
(hr, desc, exc, argErr) = xxx_todo_changeme2.args
|
||||
if hr != winerror.DISP_E_BADINDEX:
|
||||
raise error("Expected DISP_E_BADINDEX - got %d (%s)" % (hr, desc))
|
||||
|
||||
# Test an empty collection
|
||||
if not quiet: print("Empty collection test")
|
||||
o = MakeEmptyEnum()
|
||||
for item in o:
|
||||
raise error("Empty list performed an iteration")
|
||||
|
||||
try:
|
||||
ob = o[1]
|
||||
raise error("Empty list could be indexed")
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
try:
|
||||
ob = o[0]
|
||||
raise error("Empty list could be indexed")
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
try:
|
||||
ob = o(0)
|
||||
raise error("Empty list could be indexed")
|
||||
except pythoncom.com_error as xxx_todo_changeme3:
|
||||
(hr, fn, desc, arg) = xxx_todo_changeme3.args
|
||||
if hr != winerror.DISP_E_BADINDEX:
|
||||
raise error("Expected DISP_E_BADINDEX - got %d (%s)" % (hr, desc))
|
||||
|
||||
class TestCase(win32com.test.util.TestCase):
|
||||
def testEnum(self):
|
||||
TestEnum()
|
||||
|
||||
if __name__=='__main__':
|
||||
unittest.main()
|
40
venv/Lib/site-packages/win32com/test/testDCOM.py
Normal file
40
venv/Lib/site-packages/win32com/test/testDCOM.py
Normal file
|
@ -0,0 +1,40 @@
|
|||
# testDCOM
|
||||
usage="""\
|
||||
testDCOM.py - Simple DCOM test
|
||||
Usage: testDCOM.py serverName
|
||||
|
||||
Attempts to start the Python.Interpreter object on the named machine,
|
||||
and checks that the object is indeed running remotely.
|
||||
|
||||
Requires the named server be configured to run DCOM (using dcomcnfg.exe),
|
||||
and the Python.Interpreter object installed and registered on that machine.
|
||||
|
||||
The Python.Interpreter object must be installed on the local machine,
|
||||
but no special DCOM configuration should be necessary.
|
||||
"""
|
||||
# NOTE: If you configured the object locally using dcomcnfg, you could
|
||||
# simple use Dispatch rather than DispatchEx.
|
||||
import pythoncom, win32com.client, win32api, string, sys
|
||||
|
||||
def test(serverName):
|
||||
if string.lower(serverName)==string.lower(win32api.GetComputerName()):
|
||||
print("You must specify a remote server name, not the local machine!")
|
||||
return
|
||||
|
||||
# Hack to overcome a DCOM limitation. As the Python.Interpreter object
|
||||
# is probably installed locally as an InProc object, DCOM seems to ignore
|
||||
# all settings, and use the local object.
|
||||
clsctx = pythoncom.CLSCTX_SERVER & ~pythoncom.CLSCTX_INPROC_SERVER
|
||||
ob = win32com.client.DispatchEx("Python.Interpreter", serverName, clsctx=clsctx)
|
||||
ob.Exec("import win32api")
|
||||
actualName = ob.Eval("win32api.GetComputerName()")
|
||||
if string.lower(serverName) != string.lower(actualName):
|
||||
print("Error: The object created on server '%s' reported its name as '%s'" % (serverName, actualName))
|
||||
else:
|
||||
print("Object created and tested OK on server '%s'" % serverName)
|
||||
|
||||
if __name__=='__main__':
|
||||
if len(sys.argv) == 2:
|
||||
test(sys.argv[1])
|
||||
else:
|
||||
print(usage)
|
42
venv/Lib/site-packages/win32com/test/testDates.py
Normal file
42
venv/Lib/site-packages/win32com/test/testDates.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
from __future__ import print_function
|
||||
|
||||
from datetime import datetime
|
||||
import unittest
|
||||
|
||||
import pywintypes
|
||||
import win32com.client
|
||||
import win32com.test.util
|
||||
import win32com.server.util
|
||||
from win32timezone import TimeZoneInfo
|
||||
|
||||
# A COM object so we can pass dates to and from the COM boundary.
|
||||
class Tester:
|
||||
_public_methods_ = [ 'TestDate' ]
|
||||
def TestDate(self, d):
|
||||
assert isinstance(d, datetime)
|
||||
return d
|
||||
|
||||
|
||||
def test_ob():
|
||||
return win32com.client.Dispatch(win32com.server.util.wrap(Tester()))
|
||||
|
||||
class TestCase(win32com.test.util.TestCase):
|
||||
def check(self, d, expected = None):
|
||||
if not issubclass(pywintypes.TimeType, datetime):
|
||||
self.skipTest("this is testing pywintypes and datetime")
|
||||
got = test_ob().TestDate(d)
|
||||
self.assertEqual(got, expected or d)
|
||||
|
||||
def testUTC(self):
|
||||
self.check(datetime(year=2000, month=12, day=25, microsecond=500000, tzinfo=TimeZoneInfo.utc()))
|
||||
|
||||
def testLocal(self):
|
||||
self.check(datetime(year=2000, month=12, day=25, microsecond=500000, tzinfo=TimeZoneInfo.local()))
|
||||
|
||||
def testMSTruncated(self):
|
||||
# milliseconds are kept but microseconds are lost after rounding.
|
||||
self.check(datetime(year=2000, month=12, day=25, microsecond=500500, tzinfo=TimeZoneInfo.utc()),
|
||||
datetime(year=2000, month=12, day=25, microsecond=500000, tzinfo=TimeZoneInfo.utc()))
|
||||
|
||||
if __name__=='__main__':
|
||||
unittest.main()
|
94
venv/Lib/site-packages/win32com/test/testDictionary.py
Normal file
94
venv/Lib/site-packages/win32com/test/testDictionary.py
Normal file
|
@ -0,0 +1,94 @@
|
|||
# testDictionary.py
|
||||
#
|
||||
import sys
|
||||
import datetime
|
||||
import time
|
||||
import win32com.server.util
|
||||
import win32com.test.util
|
||||
import win32com.client
|
||||
import traceback
|
||||
import pythoncom
|
||||
import pywintypes
|
||||
import winerror
|
||||
import win32timezone
|
||||
|
||||
import unittest
|
||||
|
||||
def MakeTestDictionary():
|
||||
return win32com.client.Dispatch("Python.Dictionary")
|
||||
|
||||
def TestDictAgainst(dict,check):
|
||||
for key, value in list(check.items()):
|
||||
if dict(key) != value:
|
||||
raise Exception("Indexing for '%s' gave the incorrect value - %s/%s" % (repr(key), repr(dict[key]), repr(check[key])))
|
||||
|
||||
# Ensure we have the correct version registered.
|
||||
def Register(quiet):
|
||||
import win32com.servers.dictionary
|
||||
from win32com.test.util import RegisterPythonServer
|
||||
RegisterPythonServer(win32com.servers.dictionary.__file__, 'Python.Dictionary')
|
||||
|
||||
def TestDict(quiet=None):
|
||||
if quiet is None:
|
||||
quiet = not "-v" in sys.argv
|
||||
Register(quiet)
|
||||
|
||||
if not quiet: print("Simple enum test")
|
||||
dict = MakeTestDictionary()
|
||||
checkDict = {}
|
||||
TestDictAgainst(dict, checkDict)
|
||||
|
||||
dict["NewKey"] = "NewValue"
|
||||
checkDict["NewKey"] = "NewValue"
|
||||
TestDictAgainst(dict, checkDict)
|
||||
|
||||
dict["NewKey"] = None
|
||||
del checkDict["NewKey"]
|
||||
TestDictAgainst(dict, checkDict)
|
||||
|
||||
if issubclass(pywintypes.TimeType, datetime.datetime):
|
||||
now = win32timezone.now()
|
||||
# We want to keep the milliseconds but discard microseconds as they
|
||||
# don't survive the conversion.
|
||||
now = now.replace(microsecond = round(now.microsecond / 1000) * 1000)
|
||||
else:
|
||||
now = pythoncom.MakeTime(time.gmtime(time.time()))
|
||||
dict["Now"] = now
|
||||
checkDict["Now"] = now
|
||||
TestDictAgainst(dict, checkDict)
|
||||
|
||||
if not quiet:
|
||||
print("Failure tests")
|
||||
try:
|
||||
dict()
|
||||
raise Exception("default method with no args worked when it shouldnt have!")
|
||||
except pythoncom.com_error as xxx_todo_changeme:
|
||||
(hr, desc, exc, argErr) = xxx_todo_changeme.args
|
||||
if hr != winerror.DISP_E_BADPARAMCOUNT:
|
||||
raise Exception("Expected DISP_E_BADPARAMCOUNT - got %d (%s)" % (hr, desc))
|
||||
|
||||
try:
|
||||
dict("hi", "there")
|
||||
raise Exception("multiple args worked when it shouldnt have!")
|
||||
except pythoncom.com_error as xxx_todo_changeme1:
|
||||
(hr, desc, exc, argErr) = xxx_todo_changeme1.args
|
||||
if hr != winerror.DISP_E_BADPARAMCOUNT:
|
||||
raise Exception("Expected DISP_E_BADPARAMCOUNT - got %d (%s)" % (hr, desc))
|
||||
|
||||
try:
|
||||
dict(0)
|
||||
raise Exception("int key worked when it shouldnt have!")
|
||||
except pythoncom.com_error as xxx_todo_changeme2:
|
||||
(hr, desc, exc, argErr) = xxx_todo_changeme2.args
|
||||
if hr != winerror.DISP_E_TYPEMISMATCH:
|
||||
raise Exception("Expected DISP_E_TYPEMISMATCH - got %d (%s)" % (hr, desc))
|
||||
|
||||
if not quiet:
|
||||
print("Python.Dictionary tests complete.")
|
||||
|
||||
class TestCase(win32com.test.util.TestCase):
|
||||
def testDict(self):
|
||||
TestDict()
|
||||
|
||||
if __name__=='__main__':
|
||||
unittest.main()
|
26
venv/Lib/site-packages/win32com/test/testDictionary.vbs
Normal file
26
venv/Lib/site-packages/win32com/test/testDictionary.vbs
Normal file
|
@ -0,0 +1,26 @@
|
|||
' Test Pyhon.Dictionary using VBScript - this uses
|
||||
' IDispatchEx, so is an interesting test.
|
||||
|
||||
set ob = CreateObject("Python.Dictionary")
|
||||
ob("hello") = "there"
|
||||
' Our keys are case insensitive.
|
||||
ob.Item("hi") = ob("HELLO")
|
||||
|
||||
dim ok
|
||||
ok = true
|
||||
|
||||
if ob("hello") <> "there" then
|
||||
WScript.Echo "**** The dictionary value was wrong!!"
|
||||
ok = false
|
||||
end if
|
||||
|
||||
if ob("hi") <> "there" then
|
||||
WScript.Echo "**** The other dictionary value was wrong!!"
|
||||
ok = false
|
||||
end if
|
||||
|
||||
if ok then
|
||||
WScript.Echo "VBScript has successfully tested Python.Dictionary"
|
||||
end if
|
||||
|
||||
|
75
venv/Lib/site-packages/win32com/test/testDynamic.py
Normal file
75
venv/Lib/site-packages/win32com/test/testDynamic.py
Normal file
|
@ -0,0 +1,75 @@
|
|||
# Test dynamic policy, and running object table.
|
||||
|
||||
import pythoncom
|
||||
import winerror
|
||||
|
||||
from win32com.server.exception import Exception
|
||||
|
||||
error = "testDynamic error"
|
||||
|
||||
iid = pythoncom.MakeIID("{b48969a0-784b-11d0-ae71-d23f56000000}")
|
||||
|
||||
class VeryPermissive:
|
||||
def _dynamic_(self, name, lcid, wFlags, args):
|
||||
if wFlags & pythoncom.DISPATCH_METHOD:
|
||||
return getattr(self,name)(*args)
|
||||
|
||||
if wFlags & pythoncom.DISPATCH_PROPERTYGET:
|
||||
try:
|
||||
# to avoid problems with byref param handling, tuple results are converted to lists.
|
||||
ret = self.__dict__[name]
|
||||
if type(ret)==type(()):
|
||||
ret = list(ret)
|
||||
return ret
|
||||
except KeyError: # Probably a method request.
|
||||
raise Exception(scode=winerror.DISP_E_MEMBERNOTFOUND)
|
||||
|
||||
if wFlags & (pythoncom.DISPATCH_PROPERTYPUT | pythoncom.DISPATCH_PROPERTYPUTREF):
|
||||
setattr(self, name, args[0])
|
||||
return
|
||||
|
||||
raise Exception(scode=winerror.E_INVALIDARG, desc="invalid wFlags")
|
||||
|
||||
def write(self, *args):
|
||||
if len(args)==0:
|
||||
raise Exception(scode=winerror.DISP_E_BADPARAMCOUNT) # Probably call as PROPGET.
|
||||
|
||||
for arg in args[:-1]:
|
||||
print(str(arg), end=' ')
|
||||
print(str(args[-1]))
|
||||
|
||||
def Test():
|
||||
import win32com.server.util, win32com.server.policy
|
||||
# import win32dbg;win32dbg.brk()
|
||||
ob = win32com.server.util.wrap(VeryPermissive(),usePolicy=win32com.server.policy.DynamicPolicy)
|
||||
try:
|
||||
handle = pythoncom.RegisterActiveObject(ob, iid, 0)
|
||||
except pythoncom.com_error as details:
|
||||
print("Warning - could not register the object in the ROT:", details)
|
||||
handle = None
|
||||
try:
|
||||
import win32com.client.dynamic
|
||||
client = win32com.client.dynamic.Dispatch(iid)
|
||||
client.ANewAttr = "Hello"
|
||||
if client.ANewAttr != "Hello":
|
||||
raise error("Could not set dynamic property")
|
||||
|
||||
v = ["Hello","From","Python",1.4]
|
||||
client.TestSequence = v
|
||||
if v != list(client.TestSequence):
|
||||
raise error("Dynamic sequences not working! %r/%r" % (repr(v), repr(client.testSequence)))
|
||||
|
||||
client.write("This","output","has","come","via","COM")
|
||||
# Check our new "_FlagAsMethod" works (kinda!)
|
||||
client._FlagAsMethod("NotReallyAMethod")
|
||||
if not callable(client.NotReallyAMethod):
|
||||
raise error("Method I flagged as callable isn't!")
|
||||
|
||||
|
||||
client = None
|
||||
finally:
|
||||
if handle is not None:
|
||||
pythoncom.RevokeActiveObject(handle)
|
||||
|
||||
if __name__=='__main__':
|
||||
Test()
|
112
venv/Lib/site-packages/win32com/test/testExchange.py
Normal file
112
venv/Lib/site-packages/win32com/test/testExchange.py
Normal file
|
@ -0,0 +1,112 @@
|
|||
# TestExchange = Exchange Server Dump
|
||||
# Note that this code uses "CDO", which is unlikely to get the best choice.
|
||||
# You should use the Outlook object model, or
|
||||
# the win32com.mapi examples for a low-level interface.
|
||||
|
||||
from win32com.client import gencache, constants
|
||||
import pythoncom
|
||||
import os
|
||||
|
||||
ammodule = None # was the generated module!
|
||||
|
||||
def GetDefaultProfileName():
|
||||
import win32api, win32con
|
||||
try:
|
||||
key = win32api.RegOpenKey(win32con.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows Messaging Subsystem\\Profiles")
|
||||
try:
|
||||
return win32api.RegQueryValueEx(key, "DefaultProfile")[0]
|
||||
finally:
|
||||
key.Close()
|
||||
except win32api.error:
|
||||
return None
|
||||
|
||||
#
|
||||
# Recursive dump of folders.
|
||||
#
|
||||
def DumpFolder(folder, indent = 0):
|
||||
print(" " * indent, folder.Name)
|
||||
folders = folder.Folders
|
||||
folder = folders.GetFirst()
|
||||
while folder:
|
||||
DumpFolder(folder, indent+1)
|
||||
folder = folders.GetNext()
|
||||
|
||||
def DumpFolders(session):
|
||||
try:
|
||||
infostores = session.InfoStores
|
||||
except AttributeError:
|
||||
# later outlook?
|
||||
store = session.DefaultStore
|
||||
folder = store.GetRootFolder()
|
||||
DumpFolder(folder)
|
||||
return
|
||||
|
||||
print(infostores)
|
||||
print("There are %d infostores" % infostores.Count)
|
||||
for i in range(infostores.Count):
|
||||
infostore = infostores[i+1]
|
||||
print("Infostore = ", infostore.Name)
|
||||
try:
|
||||
folder = infostore.RootFolder
|
||||
except pythoncom.com_error as details:
|
||||
hr, msg, exc, arg = details
|
||||
# -2147221219 == MAPI_E_FAILONEPROVIDER - a single provider temporarily not available.
|
||||
if exc and exc[-1]==-2147221219:
|
||||
print("This info store is currently not available")
|
||||
continue
|
||||
DumpFolder(folder)
|
||||
|
||||
# Build a dictionary of property tags, so I can reverse look-up
|
||||
#
|
||||
PropTagsById={}
|
||||
if ammodule:
|
||||
for name, val in ammodule.constants.__dict__.items():
|
||||
PropTagsById[val] = name
|
||||
|
||||
|
||||
def TestAddress(session):
|
||||
# entry = session.GetAddressEntry("Skip")
|
||||
# print entry
|
||||
pass
|
||||
|
||||
|
||||
def TestUser(session):
|
||||
ae = session.CurrentUser
|
||||
fields = getattr(ae, "Fields", [])
|
||||
print("User has %d fields" % len(fields))
|
||||
for f in range(len(fields)):
|
||||
field = fields[f+1]
|
||||
try:
|
||||
id = PropTagsById[field.ID]
|
||||
except KeyError:
|
||||
id = field.ID
|
||||
print("%s/%s=%s" % (field.Name, id, field.Value))
|
||||
|
||||
def test():
|
||||
import win32com.client
|
||||
oldcwd = os.getcwd()
|
||||
try:
|
||||
session = gencache.EnsureDispatch("MAPI.Session")
|
||||
try:
|
||||
session.Logon(GetDefaultProfileName())
|
||||
except pythoncom.com_error as details:
|
||||
print("Could not log on to MAPI:", details)
|
||||
return
|
||||
except pythoncom.error:
|
||||
# no mapi.session - let's try outlook
|
||||
app = gencache.EnsureDispatch("Outlook.Application")
|
||||
session = app.Session
|
||||
|
||||
try:
|
||||
TestUser(session)
|
||||
TestAddress(session)
|
||||
DumpFolders(session)
|
||||
finally:
|
||||
session.Logoff()
|
||||
# It appears Exchange will change the cwd on us :(
|
||||
os.chdir(oldcwd)
|
||||
|
||||
if __name__=='__main__':
|
||||
from .util import CheckClean
|
||||
test()
|
||||
CheckClean()
|
106
venv/Lib/site-packages/win32com/test/testExplorer.py
Normal file
106
venv/Lib/site-packages/win32com/test/testExplorer.py
Normal file
|
@ -0,0 +1,106 @@
|
|||
# testExplorer -
|
||||
|
||||
import sys
|
||||
import os
|
||||
import win32com.client.dynamic
|
||||
from win32com.client import Dispatch
|
||||
import win32api
|
||||
import win32gui
|
||||
import win32con
|
||||
import winerror
|
||||
import glob
|
||||
import pythoncom
|
||||
import time
|
||||
from win32com.test.util import CheckClean
|
||||
|
||||
bVisibleEventFired = 0
|
||||
|
||||
class ExplorerEvents:
|
||||
def OnVisible(self, visible):
|
||||
global bVisibleEventFired
|
||||
bVisibleEventFired = 1
|
||||
|
||||
def TestExplorerEvents():
|
||||
global bVisibleEventFired
|
||||
iexplore = win32com.client.DispatchWithEvents("InternetExplorer.Application", ExplorerEvents)
|
||||
iexplore.Visible = 1
|
||||
if not bVisibleEventFired:
|
||||
raise RuntimeError("The IE event did not appear to fire!")
|
||||
iexplore.Quit()
|
||||
iexplore = None
|
||||
|
||||
bVisibleEventFired = 0
|
||||
ie = win32com.client.Dispatch("InternetExplorer.Application")
|
||||
ie_events = win32com.client.DispatchWithEvents(ie, ExplorerEvents)
|
||||
ie.Visible = 1
|
||||
if not bVisibleEventFired:
|
||||
raise RuntimeError("The IE event did not appear to fire!")
|
||||
ie.Quit()
|
||||
ie = None
|
||||
print("IE Event tests worked.")
|
||||
|
||||
def TestObjectFromWindow():
|
||||
# Check we can use ObjectFromLresult to get the COM object from the
|
||||
# HWND - see KB Q249232
|
||||
# Locating the HWND is different than the KB says...
|
||||
hwnd = win32gui.FindWindow('IEFrame', None)
|
||||
for child_class in ['TabWindowClass', 'Shell DocObject View',
|
||||
'Internet Explorer_Server']:
|
||||
hwnd = win32gui.FindWindowEx(hwnd, 0, child_class, None)
|
||||
# ack - not working for markh on vista with IE8 (or maybe it is the
|
||||
# lack of the 'accessibility' components mentioned in Q249232)
|
||||
# either way - not working!
|
||||
return
|
||||
# But here is the point - once you have an 'Internet Explorer_Server',
|
||||
# you can send a message and use ObjectFromLresult to get it back.
|
||||
msg = win32gui.RegisterWindowMessage("WM_HTML_GETOBJECT")
|
||||
rc, result = win32gui.SendMessageTimeout(hwnd, msg, 0, 0, win32con.SMTO_ABORTIFHUNG, 1000)
|
||||
ob = pythoncom.ObjectFromLresult(result, pythoncom.IID_IDispatch, 0)
|
||||
doc = Dispatch(ob)
|
||||
# just to prove it works, set the background color of the document.
|
||||
for color in "red green blue orange white".split():
|
||||
doc.bgColor = color
|
||||
time.sleep(0.2)
|
||||
|
||||
def TestExplorer(iexplore):
|
||||
if not iexplore.Visible: iexplore.Visible = -1
|
||||
iexplore.Navigate(win32api.GetFullPathName('..\\readme.htm'))
|
||||
win32api.Sleep(1000)
|
||||
TestObjectFromWindow()
|
||||
win32api.Sleep(3000)
|
||||
try:
|
||||
iexplore.Quit()
|
||||
except (AttributeError, pythoncom.com_error):
|
||||
# User got sick of waiting :)
|
||||
pass
|
||||
|
||||
def TestAll():
|
||||
try:
|
||||
try:
|
||||
iexplore = win32com.client.dynamic.Dispatch("InternetExplorer.Application")
|
||||
TestExplorer(iexplore)
|
||||
|
||||
win32api.Sleep(1000)
|
||||
iexplore = None
|
||||
|
||||
# Test IE events.
|
||||
TestExplorerEvents()
|
||||
# Give IE a chance to shutdown, else it can get upset on fast machines.
|
||||
time.sleep(2)
|
||||
|
||||
# Note that the TextExplorerEvents will force makepy - hence
|
||||
# this gencache is really no longer needed.
|
||||
|
||||
from win32com.client import gencache
|
||||
gencache.EnsureModule("{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}", 0, 1, 1)
|
||||
iexplore = win32com.client.Dispatch("InternetExplorer.Application")
|
||||
TestExplorer(iexplore)
|
||||
except pythoncom.com_error as exc:
|
||||
if exc.hresult!=winerror.RPC_E_DISCONNECTED: # user closed the app!
|
||||
raise
|
||||
finally:
|
||||
iexplore = None
|
||||
|
||||
if __name__=='__main__':
|
||||
TestAll()
|
||||
CheckClean()
|
119
venv/Lib/site-packages/win32com/test/testGIT.py
Normal file
119
venv/Lib/site-packages/win32com/test/testGIT.py
Normal file
|
@ -0,0 +1,119 @@
|
|||
"""Testing pasing object between multiple COM threads
|
||||
|
||||
Uses standard COM marshalling to pass objects between threads. Even
|
||||
though Python generally seems to work when you just pass COM objects
|
||||
between threads, it shouldnt.
|
||||
|
||||
This shows the "correct" way to do it.
|
||||
|
||||
It shows that although we create new threads to use the Python.Interpreter,
|
||||
COM marshalls back all calls to that object to the main Python thread,
|
||||
which must be running a message loop (as this sample does).
|
||||
|
||||
When this test is run in "free threaded" mode (at this stage, you must
|
||||
manually mark the COM objects as "ThreadingModel=Free", or run from a
|
||||
service which has marked itself as free-threaded), then no marshalling
|
||||
is done, and the Python.Interpreter object start doing the "expected" thing
|
||||
- ie, it reports being on the same thread as its caller!
|
||||
|
||||
Python.exe needs a good way to mark itself as FreeThreaded - at the moment
|
||||
this is a pain in the but!
|
||||
|
||||
"""
|
||||
|
||||
import _thread, traceback
|
||||
import win32com.client
|
||||
import win32event, win32api
|
||||
import pythoncom
|
||||
|
||||
def TestInterp(interp):
|
||||
if interp.Eval("1+1") != 2:
|
||||
raise ValueError("The interpreter returned the wrong result.")
|
||||
try:
|
||||
interp.Eval(1+1)
|
||||
raise ValueError("The interpreter did not raise an exception")
|
||||
except pythoncom.com_error as details:
|
||||
import winerror
|
||||
if details[0]!=winerror.DISP_E_TYPEMISMATCH:
|
||||
raise ValueError("The interpreter exception was not winerror.DISP_E_TYPEMISMATCH.")
|
||||
|
||||
|
||||
def TestInterpInThread(stopEvent, cookie):
|
||||
try:
|
||||
DoTestInterpInThread(cookie)
|
||||
finally:
|
||||
win32event.SetEvent(stopEvent)
|
||||
|
||||
def CreateGIT():
|
||||
return pythoncom.CoCreateInstance(pythoncom.CLSID_StdGlobalInterfaceTable,
|
||||
None,
|
||||
pythoncom.CLSCTX_INPROC,
|
||||
pythoncom.IID_IGlobalInterfaceTable)
|
||||
|
||||
def DoTestInterpInThread(cookie):
|
||||
try:
|
||||
pythoncom.CoInitialize()
|
||||
myThread = win32api.GetCurrentThreadId()
|
||||
GIT = CreateGIT()
|
||||
|
||||
interp = GIT.GetInterfaceFromGlobal(cookie, pythoncom.IID_IDispatch)
|
||||
interp = win32com.client.Dispatch(interp)
|
||||
|
||||
TestInterp(interp)
|
||||
interp.Exec("import win32api")
|
||||
print("The test thread id is %d, Python.Interpreter's thread ID is %d" % (myThread, interp.Eval("win32api.GetCurrentThreadId()")))
|
||||
interp = None
|
||||
pythoncom.CoUninitialize()
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
def BeginThreadsSimpleMarshal(numThreads, cookie):
|
||||
"""Creates multiple threads using simple (but slower) marshalling.
|
||||
|
||||
Single interpreter object, but a new stream is created per thread.
|
||||
|
||||
Returns the handles the threads will set when complete.
|
||||
"""
|
||||
ret = []
|
||||
for i in range(numThreads):
|
||||
hEvent = win32event.CreateEvent(None, 0, 0, None)
|
||||
_thread.start_new(TestInterpInThread, (hEvent, cookie))
|
||||
ret.append(hEvent)
|
||||
return ret
|
||||
|
||||
|
||||
def test(fn):
|
||||
print("The main thread is %d" % (win32api.GetCurrentThreadId()))
|
||||
GIT = CreateGIT()
|
||||
interp = win32com.client.Dispatch("Python.Interpreter")
|
||||
cookie = GIT.RegisterInterfaceInGlobal(interp._oleobj_, pythoncom.IID_IDispatch)
|
||||
|
||||
events = fn(4, cookie)
|
||||
numFinished = 0
|
||||
while 1:
|
||||
try:
|
||||
rc = win32event.MsgWaitForMultipleObjects(events, 0, 2000, win32event.QS_ALLINPUT)
|
||||
if rc >= win32event.WAIT_OBJECT_0 and rc < win32event.WAIT_OBJECT_0+len(events):
|
||||
numFinished = numFinished + 1
|
||||
if numFinished >= len(events):
|
||||
break
|
||||
elif rc==win32event.WAIT_OBJECT_0 + len(events): # a message
|
||||
# This is critical - whole apartment model demo will hang.
|
||||
pythoncom.PumpWaitingMessages()
|
||||
else: # Timeout
|
||||
print("Waiting for thread to stop with interfaces=%d, gateways=%d" % (pythoncom._GetInterfaceCount(), pythoncom._GetGatewayCount()))
|
||||
except KeyboardInterrupt:
|
||||
break
|
||||
GIT.RevokeInterfaceFromGlobal(cookie)
|
||||
del interp
|
||||
del GIT
|
||||
|
||||
if __name__=='__main__':
|
||||
test(BeginThreadsSimpleMarshal)
|
||||
win32api.Sleep(500)
|
||||
# Doing CoUninit here stop Pythoncom.dll hanging when DLLMain shuts-down the process
|
||||
pythoncom.CoUninitialize()
|
||||
if pythoncom._GetInterfaceCount()!=0 or pythoncom._GetGatewayCount()!=0:
|
||||
print("Done with interfaces=%d, gateways=%d" % (pythoncom._GetInterfaceCount(), pythoncom._GetGatewayCount()))
|
||||
else:
|
||||
print("Done.")
|
133
venv/Lib/site-packages/win32com/test/testGatewayAddresses.py
Normal file
133
venv/Lib/site-packages/win32com/test/testGatewayAddresses.py
Normal file
|
@ -0,0 +1,133 @@
|
|||
# The purpose of this test is to ensure that the gateways objects
|
||||
# do the right thing WRT COM rules about object identity etc.
|
||||
|
||||
# Also includes a basic test that we support inheritance correctly in
|
||||
# gateway interfaces.
|
||||
|
||||
# For our test, we create an object of type IID_IPersistStorage
|
||||
# This interface derives from IPersist.
|
||||
# Therefore, QI's for IID_IDispatch, IID_IUnknown, IID_IPersist and
|
||||
# IID_IPersistStorage should all return the same gateway object.
|
||||
#
|
||||
# In addition, the interface should only need to declare itself as
|
||||
# using the IPersistStorage interface, and as the gateway derives
|
||||
# from IPersist, it should automatically be available without declaration.
|
||||
#
|
||||
# We also create an object of type IID_I??, and perform a QI for it.
|
||||
# We then jump through a number of hoops, ensuring that the objects
|
||||
# returned by the QIs follow all the rules.
|
||||
#
|
||||
# Here is Gregs summary of the rules:
|
||||
# 1) the set of supported interfaces is static and unchanging
|
||||
# 2) symmetric: if you QI an interface for that interface, it succeeds
|
||||
# 3) reflexive: if you QI against A for B, the new pointer must succeed
|
||||
# for a QI for A
|
||||
# 4) transitive: if you QI for B, then QI that for C, then QI'ing A for C
|
||||
# must succeed
|
||||
#
|
||||
#
|
||||
# Note that 1) Requires cooperation of the Python programmer. The rule to keep is:
|
||||
# "whenever you return an _object_ from _query_interface_(), you must return the
|
||||
# same object each time for a given IID. Note that you must return the same
|
||||
# _wrapped_ object
|
||||
# you
|
||||
# The rest are tested here.
|
||||
|
||||
|
||||
from win32com.server.util import wrap
|
||||
import pythoncom
|
||||
from .util import CheckClean
|
||||
|
||||
numErrors = 0
|
||||
|
||||
# Check that the 2 objects both have identical COM pointers.
|
||||
def CheckSameCOMObject(ob1, ob2):
|
||||
addr1 = repr(ob1).split()[6][:-1]
|
||||
addr2 = repr(ob2).split()[6][:-1]
|
||||
return addr1==addr2
|
||||
|
||||
# Check that the objects conform to COM identity rules.
|
||||
def CheckObjectIdentity(ob1, ob2):
|
||||
u1 = ob1.QueryInterface(pythoncom.IID_IUnknown)
|
||||
u2 = ob2.QueryInterface(pythoncom.IID_IUnknown)
|
||||
return CheckSameCOMObject(u1, u2)
|
||||
|
||||
def FailObjectIdentity(ob1, ob2, when):
|
||||
if not CheckObjectIdentity(ob1, ob2):
|
||||
global numErrors
|
||||
numErrors = numErrors + 1
|
||||
print(when, "are not identical (%s, %s)" % (repr(ob1), repr(ob2)))
|
||||
|
||||
|
||||
class Dummy:
|
||||
_public_methods_ = [] # We never attempt to make a call on this object.
|
||||
_com_interfaces_ = [pythoncom.IID_IPersistStorage]
|
||||
|
||||
class Dummy2:
|
||||
_public_methods_ = [] # We never attempt to make a call on this object.
|
||||
_com_interfaces_ = [pythoncom.IID_IPersistStorage, pythoncom.IID_IExternalConnection]
|
||||
|
||||
class DeletgatedDummy:
|
||||
_public_methods_ = []
|
||||
|
||||
class Dummy3:
|
||||
_public_methods_ = [] # We never attempt to make a call on this object.
|
||||
_com_interfaces_ = [pythoncom.IID_IPersistStorage]
|
||||
def _query_interface_(self, iid):
|
||||
if iid==pythoncom.IID_IExternalConnection:
|
||||
# This will NEVER work - can only wrap the object once!
|
||||
return wrap(DelegatedDummy())
|
||||
|
||||
def TestGatewayInheritance():
|
||||
# By default, wrap() creates and discards a temporary object.
|
||||
# This is not necessary, but just the current implementation of wrap.
|
||||
# As the object is correctly discarded, it doesnt affect this test.
|
||||
o = wrap(Dummy(), pythoncom.IID_IPersistStorage)
|
||||
o2 = o.QueryInterface(pythoncom.IID_IUnknown)
|
||||
FailObjectIdentity(o, o2, "IID_IPersistStorage->IID_IUnknown")
|
||||
|
||||
o3 = o2.QueryInterface(pythoncom.IID_IDispatch)
|
||||
|
||||
FailObjectIdentity(o2, o3, "IID_IUnknown->IID_IDispatch")
|
||||
FailObjectIdentity(o, o3, "IID_IPersistStorage->IID_IDispatch")
|
||||
|
||||
o4 = o3.QueryInterface(pythoncom.IID_IPersistStorage)
|
||||
FailObjectIdentity(o, o4, "IID_IPersistStorage->IID_IPersistStorage(2)")
|
||||
FailObjectIdentity(o2, o4, "IID_IUnknown->IID_IPersistStorage(2)")
|
||||
FailObjectIdentity(o3, o4, "IID_IDispatch->IID_IPersistStorage(2)")
|
||||
|
||||
|
||||
o5 = o4.QueryInterface(pythoncom.IID_IPersist)
|
||||
FailObjectIdentity(o, o5, "IID_IPersistStorage->IID_IPersist")
|
||||
FailObjectIdentity(o2, o5, "IID_IUnknown->IID_IPersist")
|
||||
FailObjectIdentity(o3, o5, "IID_IDispatch->IID_IPersist")
|
||||
FailObjectIdentity(o4, o5, "IID_IPersistStorage(2)->IID_IPersist")
|
||||
|
||||
def TestMultiInterface():
|
||||
o = wrap(Dummy2(), pythoncom.IID_IPersistStorage)
|
||||
o2 = o.QueryInterface(pythoncom.IID_IExternalConnection)
|
||||
|
||||
FailObjectIdentity(o, o2, "IID_IPersistStorage->IID_IExternalConnection")
|
||||
|
||||
# Make the same QI again, to make sure it is stable.
|
||||
o22 = o.QueryInterface(pythoncom.IID_IExternalConnection)
|
||||
FailObjectIdentity(o, o22, "IID_IPersistStorage->IID_IExternalConnection")
|
||||
FailObjectIdentity(o2, o22, "IID_IPersistStorage->IID_IExternalConnection (stability)")
|
||||
|
||||
o3 = o2.QueryInterface(pythoncom.IID_IPersistStorage)
|
||||
FailObjectIdentity(o2, o3, "IID_IExternalConnection->IID_IPersistStorage")
|
||||
FailObjectIdentity(o, o3, "IID_IPersistStorage->IID_IExternalConnection->IID_IPersistStorage")
|
||||
|
||||
|
||||
def test():
|
||||
TestGatewayInheritance()
|
||||
TestMultiInterface()
|
||||
if numErrors==0:
|
||||
print("Worked ok")
|
||||
else:
|
||||
print("There were", numErrors, "errors.")
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
test()
|
||||
CheckClean()
|
12
venv/Lib/site-packages/win32com/test/testInterp.vbs
Normal file
12
venv/Lib/site-packages/win32com/test/testInterp.vbs
Normal file
|
@ -0,0 +1,12 @@
|
|||
set o = CreateObject("Python.Interpreter")
|
||||
if o.Eval("1+1") <> 2 Then
|
||||
WScript.Echo "Eval('1+1') failed"
|
||||
bFailed = True
|
||||
end if
|
||||
|
||||
if bFailed then
|
||||
WScript.Echo "*********** VBScript tests failed *********"
|
||||
else
|
||||
WScript.Echo "VBScript test worked OK"
|
||||
end if
|
||||
|
132
venv/Lib/site-packages/win32com/test/testIterators.py
Normal file
132
venv/Lib/site-packages/win32com/test/testIterators.py
Normal file
|
@ -0,0 +1,132 @@
|
|||
from __future__ import generators
|
||||
|
||||
# Some raw iter tests. Some "high-level" iterator tests can be found in
|
||||
# testvb.py and testOutlook.py
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from win32com.client.gencache import EnsureDispatch
|
||||
from win32com.client import Dispatch
|
||||
import win32com.server.util
|
||||
import win32com.test.util
|
||||
import pythoncom
|
||||
|
||||
def yield_iter(iter):
|
||||
while 1:
|
||||
yield next(iter)
|
||||
|
||||
class _BaseTestCase(win32com.test.util.TestCase):
|
||||
def test_enumvariant_vb(self):
|
||||
ob, iter = self.iter_factory()
|
||||
got=[]
|
||||
for v in iter:
|
||||
got.append(v)
|
||||
self.assertEquals(got, self.expected_data)
|
||||
def test_yield(self):
|
||||
ob, i = self.iter_factory()
|
||||
got=[]
|
||||
for v in yield_iter(iter(i)):
|
||||
got.append(v)
|
||||
self.assertEquals(got, self.expected_data)
|
||||
|
||||
def _do_test_nonenum(self, object):
|
||||
try:
|
||||
for i in object:
|
||||
pass
|
||||
self.fail("Could iterate over a non-iterable object")
|
||||
except TypeError:
|
||||
pass # this is expected.
|
||||
self.assertRaises(TypeError, iter, object)
|
||||
self.assertRaises(AttributeError, getattr, object, "next")
|
||||
|
||||
def test_nonenum_wrapper(self):
|
||||
# Check our raw PyIDispatch
|
||||
ob = self.object._oleobj_
|
||||
try:
|
||||
for i in ob:
|
||||
pass
|
||||
self.fail("Could iterate over a non-iterable object")
|
||||
except TypeError:
|
||||
pass # this is expected.
|
||||
self.assertRaises(TypeError, iter, ob)
|
||||
self.assertRaises(AttributeError, getattr, ob, "next")
|
||||
|
||||
# And our Dispatch wrapper
|
||||
ob = self.object
|
||||
try:
|
||||
for i in ob:
|
||||
pass
|
||||
self.fail("Could iterate over a non-iterable object")
|
||||
except TypeError:
|
||||
pass # this is expected.
|
||||
# Note that as our object may be dynamic, we *do* have a __getitem__
|
||||
# method, meaning we *can* call iter() on the object. In this case
|
||||
# actual iteration is what fails.
|
||||
# So either the 'iter(); will raise a type error, or an attempt to
|
||||
# fetch it
|
||||
try:
|
||||
next(iter(ob))
|
||||
self.fail("Expected a TypeError fetching this iterator")
|
||||
except TypeError:
|
||||
pass
|
||||
# And it should never have a 'next' method
|
||||
self.assertRaises(AttributeError, getattr, ob, "next")
|
||||
|
||||
class VBTestCase(_BaseTestCase):
|
||||
def setUp(self):
|
||||
def factory():
|
||||
# Our VB test harness exposes a property with IEnumVariant.
|
||||
ob = self.object.EnumerableCollectionProperty
|
||||
for i in self.expected_data:
|
||||
ob.Add(i)
|
||||
# Get the raw IEnumVARIANT.
|
||||
invkind = pythoncom.DISPATCH_METHOD | pythoncom.DISPATCH_PROPERTYGET
|
||||
iter = ob._oleobj_.InvokeTypes(pythoncom.DISPID_NEWENUM,0,invkind,(13, 10),())
|
||||
return ob, iter.QueryInterface(pythoncom.IID_IEnumVARIANT)
|
||||
# We *need* generated dispatch semantics, so dynamic __getitem__ etc
|
||||
# don't get in the way of our tests.
|
||||
self.object = EnsureDispatch("PyCOMVBTest.Tester")
|
||||
self.expected_data = [1, "Two", "3"]
|
||||
self.iter_factory = factory
|
||||
|
||||
def tearDown(self):
|
||||
self.object = None
|
||||
|
||||
# Test our client semantics, but using a wrapped Python list object.
|
||||
# This has the effect of re-using our client specific tests, but in this
|
||||
# case is exercising the server side.
|
||||
class SomeObject:
|
||||
_public_methods_ = ["GetCollection"]
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
def GetCollection(self):
|
||||
return win32com.server.util.NewCollection(self.data)
|
||||
|
||||
class WrappedPythonCOMServerTestCase(_BaseTestCase):
|
||||
def setUp(self):
|
||||
def factory():
|
||||
ob = self.object.GetCollection()
|
||||
flags = pythoncom.DISPATCH_METHOD | pythoncom.DISPATCH_PROPERTYGET
|
||||
enum = ob._oleobj_.Invoke(pythoncom.DISPID_NEWENUM, 0, flags, 1)
|
||||
return ob, enum.QueryInterface(pythoncom.IID_IEnumVARIANT)
|
||||
|
||||
self.expected_data = [1,'Two',3]
|
||||
sv = win32com.server.util.wrap(SomeObject(self.expected_data))
|
||||
self.object = Dispatch(sv)
|
||||
self.iter_factory = factory
|
||||
|
||||
def tearDown(self):
|
||||
self.object = None
|
||||
|
||||
def suite():
|
||||
# We dont want our base class run
|
||||
suite = unittest.TestSuite()
|
||||
for item in globals().values():
|
||||
if type(item)==type(unittest.TestCase) and \
|
||||
issubclass(item, unittest.TestCase) and \
|
||||
item != _BaseTestCase:
|
||||
suite.addTest(unittest.makeSuite(item))
|
||||
return suite
|
||||
|
||||
if __name__=='__main__':
|
||||
unittest.main(argv=sys.argv + ['suite'])
|
163
venv/Lib/site-packages/win32com/test/testMSOffice.py
Normal file
163
venv/Lib/site-packages/win32com/test/testMSOffice.py
Normal file
|
@ -0,0 +1,163 @@
|
|||
# Test MSOffice
|
||||
#
|
||||
# Main purpose of test is to ensure that Dynamic COM objects
|
||||
# work as expected.
|
||||
|
||||
# Assumes Word and Excel installed on your machine.
|
||||
|
||||
import win32com, sys, string, win32api, traceback
|
||||
import win32com.client.dynamic
|
||||
from win32com.test.util import CheckClean
|
||||
import pythoncom
|
||||
from win32com.client import gencache
|
||||
from pywintypes import Unicode
|
||||
|
||||
error = "MSOffice test error"
|
||||
|
||||
# Test a few of the MSOffice components.
|
||||
def TestWord():
|
||||
# Try and load the object exposed by Word 8
|
||||
# Office 97 - _totally_ different object model!
|
||||
try:
|
||||
# NOTE - using "client.Dispatch" would return an msword8.py instance!
|
||||
print("Starting Word 8 for dynamic test")
|
||||
word = win32com.client.dynamic.Dispatch("Word.Application")
|
||||
TestWord8(word)
|
||||
|
||||
word = None
|
||||
# Now we will test Dispatch without the new "lazy" capabilities
|
||||
print("Starting Word 8 for non-lazy dynamic test")
|
||||
dispatch = win32com.client.dynamic._GetGoodDispatch("Word.Application")
|
||||
typeinfo = dispatch.GetTypeInfo()
|
||||
attr = typeinfo.GetTypeAttr()
|
||||
olerepr = win32com.client.build.DispatchItem(typeinfo, attr, None, 0)
|
||||
word = win32com.client.dynamic.CDispatch(dispatch, olerepr)
|
||||
dispatch = typeinfo = attr = olerepr = None
|
||||
TestWord8(word)
|
||||
|
||||
except pythoncom.com_error:
|
||||
print("Starting Word 7 for dynamic test")
|
||||
word = win32com.client.Dispatch("Word.Basic")
|
||||
TestWord7(word)
|
||||
|
||||
print("Starting MSWord for generated test")
|
||||
from win32com.client import gencache
|
||||
word = gencache.EnsureDispatch("Word.Application.8")
|
||||
TestWord8(word)
|
||||
|
||||
def TestWord7(word):
|
||||
word.FileNew()
|
||||
# If not shown, show the app.
|
||||
if not word.AppShow(): word._proc_("AppShow")
|
||||
|
||||
for i in range(12):
|
||||
word.FormatFont(Color=i+1, Points=i+12)
|
||||
word.Insert("Hello from Python %d\n" % i)
|
||||
|
||||
word.FileClose(2)
|
||||
|
||||
def TestWord8(word):
|
||||
word.Visible = 1
|
||||
doc = word.Documents.Add()
|
||||
wrange = doc.Range()
|
||||
for i in range(10):
|
||||
wrange.InsertAfter("Hello from Python %d\n" % i)
|
||||
paras = doc.Paragraphs
|
||||
for i in range(len(paras)):
|
||||
p = paras[i]()
|
||||
p.Font.ColorIndex = i+1
|
||||
p.Font.Size = 12 + (4 * i)
|
||||
# XXX - note that
|
||||
# for para in paras:
|
||||
# para().Font...
|
||||
# doesnt seem to work - no error, just doesnt work
|
||||
# Should check if it works for VB!
|
||||
doc.Close(SaveChanges = 0)
|
||||
word.Quit()
|
||||
win32api.Sleep(1000) # Wait for word to close, else we
|
||||
# may get OA error.
|
||||
|
||||
def TestWord8OldStyle():
|
||||
try:
|
||||
import win32com.test.Generated4Test.msword8
|
||||
except ImportError:
|
||||
print("Can not do old style test")
|
||||
|
||||
|
||||
def TextExcel(xl):
|
||||
xl.Visible = 0
|
||||
if xl.Visible: raise error("Visible property is true.")
|
||||
xl.Visible = 1
|
||||
if not xl.Visible: raise error("Visible property not true.")
|
||||
|
||||
if int(xl.Version[0])>=8:
|
||||
xl.Workbooks.Add()
|
||||
else:
|
||||
xl.Workbooks().Add()
|
||||
|
||||
|
||||
xl.Range("A1:C1").Value = (1,2,3)
|
||||
xl.Range("A2:C2").Value = ('x','y','z')
|
||||
xl.Range("A3:C3").Value = ('3','2','1')
|
||||
|
||||
for i in range(20):
|
||||
xl.Cells(i+1,i+1).Value = "Hi %d" % i
|
||||
|
||||
if xl.Range("A1").Value != "Hi 0":
|
||||
raise error("Single cell range failed")
|
||||
|
||||
if xl.Range("A1:B1").Value != ((Unicode("Hi 0"),2),):
|
||||
raise error("flat-horizontal cell range failed")
|
||||
|
||||
if xl.Range("A1:A2").Value != ((Unicode("Hi 0"),),(Unicode("x"),)):
|
||||
raise error("flat-vertical cell range failed")
|
||||
|
||||
if xl.Range("A1:C3").Value != ((Unicode("Hi 0"),2,3),(Unicode("x"),Unicode("Hi 1"),Unicode("z")),(3,2,Unicode("Hi 2"))):
|
||||
raise error("square cell range failed")
|
||||
|
||||
xl.Range("A1:C3").Value =((3,2,1),("x","y","z"),(1,2,3))
|
||||
|
||||
if xl.Range("A1:C3").Value != ((3,2,1),(Unicode("x"),Unicode("y"),Unicode("z")),(1,2,3)):
|
||||
raise error("Range was not what I set it to!")
|
||||
|
||||
# test dates out with Excel
|
||||
xl.Cells(5,1).Value = "Excel time"
|
||||
xl.Cells(5,2).Formula = "=Now()"
|
||||
|
||||
import time
|
||||
xl.Cells(6,1).Value = "Python time"
|
||||
xl.Cells(6,2).Value = pythoncom.MakeTime(time.time())
|
||||
xl.Cells(6,2).NumberFormat = "d/mm/yy h:mm"
|
||||
xl.Columns("A:B").EntireColumn.AutoFit()
|
||||
|
||||
xl.Workbooks(1).Close(0)
|
||||
xl.Quit()
|
||||
|
||||
def TestAll():
|
||||
TestWord()
|
||||
|
||||
print("Starting Excel for Dynamic test...")
|
||||
xl = win32com.client.dynamic.Dispatch("Excel.Application")
|
||||
TextExcel(xl)
|
||||
|
||||
try:
|
||||
print("Starting Excel 8 for generated excel8.py test...")
|
||||
mod = gencache.EnsureModule("{00020813-0000-0000-C000-000000000046}", 0, 1, 2, bForDemand=1)
|
||||
xl = win32com.client.Dispatch("Excel.Application")
|
||||
TextExcel(xl)
|
||||
except ImportError:
|
||||
print("Could not import the generated Excel 97 wrapper")
|
||||
|
||||
try:
|
||||
import xl5en32
|
||||
mod = gencache.EnsureModule("{00020813-0000-0000-C000-000000000046}", 9, 1, 0)
|
||||
xl = win32com.client.Dispatch("Excel.Application.5")
|
||||
print("Starting Excel 95 for makepy test...")
|
||||
TextExcel(xl)
|
||||
except ImportError:
|
||||
print("Could not import the generated Excel 95 wrapper")
|
||||
|
||||
if __name__=='__main__':
|
||||
TestAll()
|
||||
CheckClean()
|
||||
pythoncom.CoUninitialize()
|
115
venv/Lib/site-packages/win32com/test/testMSOfficeEvents.py
Normal file
115
venv/Lib/site-packages/win32com/test/testMSOfficeEvents.py
Normal file
|
@ -0,0 +1,115 @@
|
|||
# OfficeEvents - test/demonstrate events with Word and Excel.
|
||||
from win32com.client import DispatchWithEvents, Dispatch
|
||||
import msvcrt, pythoncom
|
||||
import time, sys
|
||||
import types
|
||||
|
||||
import threading
|
||||
stopEvent = threading.Event()
|
||||
|
||||
def TestExcel():
|
||||
class ExcelEvents:
|
||||
def OnNewWorkbook(self, wb):
|
||||
if type(wb) != types.InstanceType:
|
||||
raise RuntimeError("The transformer doesnt appear to have translated this for us!")
|
||||
self.seen_events["OnNewWorkbook"] = None
|
||||
def OnWindowActivate(self, wb, wn):
|
||||
if type(wb) != types.InstanceType or type(wn) != types.InstanceType:
|
||||
raise RuntimeError("The transformer doesnt appear to have translated this for us!")
|
||||
self.seen_events["OnWindowActivate"] = None
|
||||
def OnWindowDeactivate(self, wb, wn):
|
||||
self.seen_events["OnWindowDeactivate"] = None
|
||||
def OnSheetDeactivate(self, sh):
|
||||
self.seen_events["OnSheetDeactivate"] = None
|
||||
def OnSheetBeforeDoubleClick(self, Sh, Target, Cancel):
|
||||
if Target.Column % 2 == 0:
|
||||
print("You can double-click there...")
|
||||
else:
|
||||
print("You can not double-click there...")
|
||||
# This function is a void, so the result ends up in
|
||||
# the only ByRef - Cancel.
|
||||
return 1
|
||||
|
||||
class WorkbookEvents:
|
||||
def OnActivate(self):
|
||||
print("workbook OnActivate")
|
||||
def OnBeforeRightClick(self, Target, Cancel):
|
||||
print("It's a Worksheet Event")
|
||||
|
||||
e = DispatchWithEvents("Excel.Application", ExcelEvents)
|
||||
e.seen_events = {}
|
||||
e.Visible=1
|
||||
book = e.Workbooks.Add()
|
||||
book = DispatchWithEvents(book, WorkbookEvents)
|
||||
print("Have book", book)
|
||||
# sheet = e.Worksheets(1)
|
||||
# sheet = DispatchWithEvents(sheet, WorksheetEvents)
|
||||
|
||||
print("Double-click in a few of the Excel cells...")
|
||||
print("Press any key when finished with Excel, or wait 10 seconds...")
|
||||
if not _WaitForFinish(e, 10):
|
||||
e.Quit()
|
||||
if not _CheckSeenEvents(e, ["OnNewWorkbook", "OnWindowActivate"]):
|
||||
sys.exit(1)
|
||||
|
||||
def TestWord():
|
||||
class WordEvents:
|
||||
def OnDocumentChange(self):
|
||||
self.seen_events["OnDocumentChange"] = None
|
||||
def OnWindowActivate(self, doc, wn):
|
||||
self.seen_events["OnWindowActivate"] = None
|
||||
def OnQuit(self):
|
||||
self.seen_events["OnQuit"] = None
|
||||
stopEvent.set()
|
||||
|
||||
w = DispatchWithEvents("Word.Application", WordEvents)
|
||||
w.seen_events = {}
|
||||
w.Visible = 1
|
||||
w.Documents.Add()
|
||||
print("Press any key when finished with Word, or wait 10 seconds...")
|
||||
if not _WaitForFinish(w, 10):
|
||||
w.Quit()
|
||||
if not _CheckSeenEvents(w, ["OnDocumentChange", "OnWindowActivate"]):
|
||||
sys.exit(1)
|
||||
|
||||
def _WaitForFinish(ob, timeout):
|
||||
end = time.time() + timeout
|
||||
while 1:
|
||||
if msvcrt.kbhit():
|
||||
msvcrt.getch()
|
||||
break
|
||||
pythoncom.PumpWaitingMessages()
|
||||
stopEvent.wait(.2)
|
||||
if stopEvent.isSet():
|
||||
stopEvent.clear()
|
||||
break
|
||||
try:
|
||||
if not ob.Visible:
|
||||
# Gone invisible - we need to pretend we timed
|
||||
# out, so the app is quit.
|
||||
return 0
|
||||
except pythoncom.com_error:
|
||||
# Excel is busy (eg, editing the cell) - ignore
|
||||
pass
|
||||
if time.time() > end:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def _CheckSeenEvents(o, events):
|
||||
rc = 1
|
||||
for e in events:
|
||||
if e not in o.seen_events:
|
||||
print("ERROR: Expected event did not trigger", e)
|
||||
rc = 0
|
||||
return rc
|
||||
|
||||
def test():
|
||||
import sys
|
||||
if "noword" not in sys.argv[1:]:
|
||||
TestWord()
|
||||
if "noexcel" not in sys.argv[1:]:
|
||||
TestExcel()
|
||||
print("Word and Excel event tests passed.")
|
||||
|
||||
if __name__=='__main__':
|
||||
test()
|
140
venv/Lib/site-packages/win32com/test/testMarshal.py
Normal file
140
venv/Lib/site-packages/win32com/test/testMarshal.py
Normal file
|
@ -0,0 +1,140 @@
|
|||
"""Testing pasing object between multiple COM threads
|
||||
|
||||
Uses standard COM marshalling to pass objects between threads. Even
|
||||
though Python generally seems to work when you just pass COM objects
|
||||
between threads, it shouldnt.
|
||||
|
||||
This shows the "correct" way to do it.
|
||||
|
||||
It shows that although we create new threads to use the Python.Interpreter,
|
||||
COM marshalls back all calls to that object to the main Python thread,
|
||||
which must be running a message loop (as this sample does).
|
||||
|
||||
When this test is run in "free threaded" mode (at this stage, you must
|
||||
manually mark the COM objects as "ThreadingModel=Free", or run from a
|
||||
service which has marked itself as free-threaded), then no marshalling
|
||||
is done, and the Python.Interpreter object start doing the "expected" thing
|
||||
- ie, it reports being on the same thread as its caller!
|
||||
|
||||
Python.exe needs a good way to mark itself as FreeThreaded - at the moment
|
||||
this is a pain in the but!
|
||||
|
||||
"""
|
||||
|
||||
import threading, traceback
|
||||
import win32com.client
|
||||
import win32event, win32api
|
||||
import pythoncom
|
||||
import unittest
|
||||
|
||||
from .testServers import InterpCase
|
||||
|
||||
freeThreaded = 1
|
||||
|
||||
class ThreadInterpCase(InterpCase):
|
||||
def _testInterpInThread(self, stopEvent, interp):
|
||||
try:
|
||||
self._doTestInThread(interp)
|
||||
finally:
|
||||
win32event.SetEvent(stopEvent)
|
||||
|
||||
def _doTestInThread(self, interp):
|
||||
pythoncom.CoInitialize()
|
||||
myThread = win32api.GetCurrentThreadId()
|
||||
|
||||
if freeThreaded:
|
||||
interp = pythoncom.CoGetInterfaceAndReleaseStream(interp, pythoncom.IID_IDispatch)
|
||||
interp = win32com.client.Dispatch(interp)
|
||||
|
||||
interp.Exec("import win32api")
|
||||
#print "The test thread id is %d, Python.Interpreter's thread ID is %d" % (myThread, interp.Eval("win32api.GetCurrentThreadId()"))
|
||||
pythoncom.CoUninitialize()
|
||||
|
||||
def BeginThreadsSimpleMarshal(self, numThreads):
|
||||
"""Creates multiple threads using simple (but slower) marshalling.
|
||||
|
||||
Single interpreter object, but a new stream is created per thread.
|
||||
|
||||
Returns the handles the threads will set when complete.
|
||||
"""
|
||||
interp = win32com.client.Dispatch("Python.Interpreter")
|
||||
events = []
|
||||
threads = []
|
||||
for i in range(numThreads):
|
||||
hEvent = win32event.CreateEvent(None, 0, 0, None)
|
||||
events.append(hEvent)
|
||||
interpStream = pythoncom.CoMarshalInterThreadInterfaceInStream(pythoncom.IID_IDispatch, interp._oleobj_)
|
||||
t = threading.Thread(target=self._testInterpInThread, args=(hEvent, interpStream))
|
||||
t.setDaemon(1) # so errors dont cause shutdown hang
|
||||
t.start()
|
||||
threads.append(t)
|
||||
interp = None
|
||||
return threads, events
|
||||
|
||||
#
|
||||
# NOTE - this doesnt quite work - Im not even sure it should, but Greg reckons
|
||||
# you should be able to avoid the marshal per thread!
|
||||
# I think that refers to CoMarshalInterface though...
|
||||
def BeginThreadsFastMarshal(self, numThreads):
|
||||
"""Creates multiple threads using fast (but complex) marshalling.
|
||||
|
||||
The marshal stream is created once, and each thread uses the same stream
|
||||
|
||||
Returns the handles the threads will set when complete.
|
||||
"""
|
||||
interp = win32com.client.Dispatch("Python.Interpreter")
|
||||
if freeThreaded:
|
||||
interp = pythoncom.CoMarshalInterThreadInterfaceInStream(pythoncom.IID_IDispatch, interp._oleobj_)
|
||||
events = []
|
||||
threads = []
|
||||
for i in range(numThreads):
|
||||
hEvent = win32event.CreateEvent(None, 0, 0, None)
|
||||
t = threading.Thread(target=self._testInterpInThread, args=(hEvent, interp))
|
||||
t.setDaemon(1) # so errors dont cause shutdown hang
|
||||
t.start()
|
||||
events.append(hEvent)
|
||||
threads.append(t)
|
||||
return threads, events
|
||||
|
||||
def _DoTestMarshal(self, fn, bCoWait = 0):
|
||||
#print "The main thread is %d" % (win32api.GetCurrentThreadId())
|
||||
threads, events = fn(2)
|
||||
numFinished = 0
|
||||
while 1:
|
||||
try:
|
||||
if bCoWait:
|
||||
rc = pythoncom.CoWaitForMultipleHandles(0, 2000, events)
|
||||
else:
|
||||
# Specifying "bWaitAll" here will wait for messages *and* all events
|
||||
# (which is pretty useless)
|
||||
rc = win32event.MsgWaitForMultipleObjects(events, 0, 2000, win32event.QS_ALLINPUT)
|
||||
if rc >= win32event.WAIT_OBJECT_0 and rc < win32event.WAIT_OBJECT_0+len(events):
|
||||
numFinished = numFinished + 1
|
||||
if numFinished >= len(events):
|
||||
break
|
||||
elif rc==win32event.WAIT_OBJECT_0 + len(events): # a message
|
||||
# This is critical - whole apartment model demo will hang.
|
||||
pythoncom.PumpWaitingMessages()
|
||||
else: # Timeout
|
||||
print("Waiting for thread to stop with interfaces=%d, gateways=%d" % (pythoncom._GetInterfaceCount(), pythoncom._GetGatewayCount()))
|
||||
except KeyboardInterrupt:
|
||||
break
|
||||
for t in threads:
|
||||
t.join(2)
|
||||
self.failIf(t.isAlive(), "thread failed to stop!?")
|
||||
threads = None # threads hold references to args
|
||||
# Seems to be a leak here I can't locate :(
|
||||
#self.failUnlessEqual(pythoncom._GetInterfaceCount(), 0)
|
||||
#self.failUnlessEqual(pythoncom._GetGatewayCount(), 0)
|
||||
|
||||
def testSimpleMarshal(self):
|
||||
self._DoTestMarshal(self.BeginThreadsSimpleMarshal)
|
||||
|
||||
def testSimpleMarshalCoWait(self):
|
||||
self._DoTestMarshal(self.BeginThreadsSimpleMarshal, 1)
|
||||
|
||||
# def testFastMarshal(self):
|
||||
# self._DoTestMarshal(self.BeginThreadsFastMarshal)
|
||||
|
||||
if __name__=='__main__':
|
||||
unittest.main('testMarshal')
|
25
venv/Lib/site-packages/win32com/test/testNetscape.py
Normal file
25
venv/Lib/site-packages/win32com/test/testNetscape.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
## AHH - I cant make this work!!!
|
||||
|
||||
# But this is the general idea.
|
||||
|
||||
import netscape
|
||||
import sys
|
||||
|
||||
error = "Netscape Test Error"
|
||||
|
||||
if __name__=='__main__':
|
||||
n=netscape.CNetworkCX()
|
||||
rc = n.Open("http://d|/temp/apyext.html", 0, None, 0, None)
|
||||
if not rc: raise error("Open method of Netscape failed")
|
||||
while 1:
|
||||
num, str = n.Read(None, 0)
|
||||
print("Got ", num, str)
|
||||
if num==0:
|
||||
break # used to be continue - no idea!!
|
||||
if num==-1:
|
||||
break
|
||||
# sys.stdout.write(str)
|
||||
n.Close()
|
||||
print("Done!")
|
||||
del n
|
||||
sys.last_type = sys.last_value = sys.last_traceback = None
|
212
venv/Lib/site-packages/win32com/test/testPersist.py
Normal file
212
venv/Lib/site-packages/win32com/test/testPersist.py
Normal file
|
@ -0,0 +1,212 @@
|
|||
import pythoncom
|
||||
import win32com.server.util
|
||||
import time
|
||||
|
||||
import win32com, sys, string, win32api, traceback
|
||||
import win32com.client.dynamic
|
||||
import win32com.client
|
||||
import pythoncom
|
||||
from win32com.axcontrol import axcontrol
|
||||
from pywintypes import Unicode
|
||||
from win32com import storagecon
|
||||
from win32com.test.util import CheckClean
|
||||
|
||||
import pywintypes
|
||||
import win32ui
|
||||
import win32api, os
|
||||
|
||||
from pywin32_testutil import str2bytes
|
||||
|
||||
S_OK = 0
|
||||
|
||||
import datetime
|
||||
if issubclass(pywintypes.TimeType, datetime.datetime):
|
||||
import win32timezone
|
||||
now = win32timezone.now()
|
||||
else:
|
||||
now = pywintypes.Time(time.time())
|
||||
|
||||
class LockBytes:
|
||||
_public_methods_ = [ 'ReadAt', 'WriteAt', 'Flush', 'SetSize', 'LockRegion', 'UnlockRegion', 'Stat' ]
|
||||
_com_interfaces_ = [ pythoncom.IID_ILockBytes ]
|
||||
|
||||
def __init__(self, data = ""):
|
||||
self.data = str2bytes(data)
|
||||
self.ctime = now
|
||||
self.mtime = now
|
||||
self.atime = now
|
||||
|
||||
def ReadAt(self, offset, cb):
|
||||
print("ReadAt")
|
||||
result = self.data[offset:offset + cb]
|
||||
return result
|
||||
|
||||
def WriteAt(self, offset, data):
|
||||
print("WriteAt " +str(offset))
|
||||
print("len " + str(len(data)))
|
||||
print("data:")
|
||||
#print data
|
||||
if len(self.data) >= offset:
|
||||
newdata = self.data[0:offset] + data
|
||||
print(len(newdata))
|
||||
if len(self.data) >= offset + len(data):
|
||||
newdata = newdata + self.data[offset + len(data):]
|
||||
print(len(newdata))
|
||||
self.data = newdata
|
||||
return len(data)
|
||||
|
||||
def Flush(self, whatsthis=0):
|
||||
print("Flush" + str(whatsthis))
|
||||
fname = os.path.join(win32api.GetTempPath(), "persist.doc")
|
||||
open(fname, "wb").write(self.data)
|
||||
return S_OK
|
||||
|
||||
def SetSize(self, size):
|
||||
print("Set Size" + str(size))
|
||||
if size > len(self.data):
|
||||
self.data = self.data + str2bytes("\000" * (size - len(self.data)))
|
||||
else:
|
||||
self.data = self.data[0:size]
|
||||
return S_OK
|
||||
|
||||
def LockRegion(self, offset, size, locktype):
|
||||
print("LockRegion")
|
||||
pass
|
||||
|
||||
def UnlockRegion(self, offset, size, locktype):
|
||||
print("UnlockRegion")
|
||||
pass
|
||||
|
||||
def Stat(self, statflag):
|
||||
print("returning Stat " + str(statflag))
|
||||
return (
|
||||
"PyMemBytes",
|
||||
storagecon.STGTY_LOCKBYTES,
|
||||
len(self.data),
|
||||
self.mtime,
|
||||
self.ctime,
|
||||
self.atime,
|
||||
storagecon.STGM_DIRECT|storagecon.STGM_READWRITE|storagecon.STGM_CREATE ,
|
||||
storagecon.STGM_SHARE_EXCLUSIVE,
|
||||
"{00020905-0000-0000-C000-000000000046}",
|
||||
0, # statebits ?
|
||||
0
|
||||
)
|
||||
|
||||
|
||||
class OleClientSite:
|
||||
_public_methods_ = [ 'SaveObject', 'GetMoniker', 'GetContainer', 'ShowObject', 'OnShowWindow', 'RequestNewObjectLayout' ]
|
||||
_com_interfaces_ = [ axcontrol.IID_IOleClientSite ]
|
||||
|
||||
def __init__(self, data = ""):
|
||||
self.IPersistStorage = None
|
||||
self.IStorage = None
|
||||
|
||||
def SetIPersistStorage(self, IPersistStorage):
|
||||
self.IPersistStorage = IPersistStorage
|
||||
|
||||
def SetIStorage(self, IStorage):
|
||||
self.IStorage = IStorage
|
||||
|
||||
def SaveObject(self):
|
||||
print("SaveObject")
|
||||
if self.IPersistStorage != None and self.IStorage != None:
|
||||
self.IPersistStorage.Save(self.IStorage,1)
|
||||
self.IStorage.Commit(0)
|
||||
return S_OK
|
||||
|
||||
def GetMoniker(self, dwAssign, dwWhichMoniker):
|
||||
print("GetMoniker " + str(dwAssign) + " " + str(dwWhichMoniker))
|
||||
|
||||
def GetContainer(self):
|
||||
print("GetContainer")
|
||||
|
||||
def ShowObject(self):
|
||||
print("ShowObject")
|
||||
|
||||
def OnShowWindow(self, fShow):
|
||||
print("ShowObject" + str(fShow))
|
||||
|
||||
def RequestNewObjectLayout(self):
|
||||
print("RequestNewObjectLayout")
|
||||
|
||||
|
||||
def test():
|
||||
# create a LockBytes object and
|
||||
#wrap it as a COM object
|
||||
# import win32com.server.dispatcher
|
||||
lbcom = win32com.server.util.wrap(LockBytes(), pythoncom.IID_ILockBytes) #, useDispatcher=win32com.server.dispatcher.DispatcherWin32trace)
|
||||
|
||||
# create a structured storage on the ILockBytes object
|
||||
stcom = pythoncom.StgCreateDocfileOnILockBytes(lbcom, storagecon.STGM_DIRECT| storagecon.STGM_CREATE | storagecon.STGM_READWRITE | storagecon.STGM_SHARE_EXCLUSIVE, 0)
|
||||
|
||||
# create our ClientSite
|
||||
ocs = OleClientSite()
|
||||
# wrap it as a COM object
|
||||
ocscom = win32com.server.util.wrap(ocs, axcontrol.IID_IOleClientSite)
|
||||
|
||||
# create a Word OLE Document, connect it to our site and our storage
|
||||
oocom=axcontrol.OleCreate("{00020906-0000-0000-C000-000000000046}",
|
||||
axcontrol.IID_IOleObject,
|
||||
0,
|
||||
(0,),
|
||||
ocscom,
|
||||
stcom,
|
||||
)
|
||||
|
||||
mf=win32ui.GetMainFrame()
|
||||
hwnd=mf.GetSafeHwnd()
|
||||
|
||||
# Set the host and document name
|
||||
# for unknown reason document name becomes hostname, and document name
|
||||
# is not set, debugged it, but don't know where the problem is?
|
||||
oocom.SetHostNames("OTPython", "This is Cool")
|
||||
|
||||
# activate the OLE document
|
||||
oocom.DoVerb( -1, ocscom, 0, hwnd, mf.GetWindowRect())
|
||||
|
||||
# set the hostnames again
|
||||
oocom.SetHostNames("OTPython2", "ThisisCool2")
|
||||
|
||||
# get IDispatch of Word
|
||||
doc=win32com.client.Dispatch(oocom.QueryInterface(pythoncom.IID_IDispatch))
|
||||
|
||||
# get IPersistStorage of Word
|
||||
dpcom=oocom.QueryInterface(pythoncom.IID_IPersistStorage)
|
||||
|
||||
# let our ClientSite know the interfaces
|
||||
ocs.SetIPersistStorage(dpcom)
|
||||
ocs.SetIStorage(stcom)
|
||||
|
||||
# use IDispatch to do the Office Word test
|
||||
# pasted from TestOffice.py
|
||||
|
||||
wrange = doc.Range()
|
||||
for i in range(10):
|
||||
wrange.InsertAfter("Hello from Python %d\n" % i)
|
||||
paras = doc.Paragraphs
|
||||
for i in range(len(paras)):
|
||||
paras[i]().Font.ColorIndex = i+1
|
||||
paras[i]().Font.Size = 12 + (4 * i)
|
||||
# XXX - note that
|
||||
# for para in paras:
|
||||
# para().Font...
|
||||
# doesnt seem to work - no error, just doesnt work
|
||||
# Should check if it works for VB!
|
||||
|
||||
|
||||
dpcom.Save(stcom, 0)
|
||||
dpcom.HandsOffStorage()
|
||||
# oocom.Close(axcontrol.OLECLOSE_NOSAVE) # or OLECLOSE_SAVEIFDIRTY, but it fails???
|
||||
|
||||
#Save the ILockBytes data to "persist2.doc"
|
||||
lbcom.Flush()
|
||||
|
||||
#exiting Winword will automatically update the ILockBytes data
|
||||
#and flush it to "%TEMP%\persist.doc"
|
||||
doc.Application.Quit()
|
||||
|
||||
if __name__=='__main__':
|
||||
test()
|
||||
pythoncom.CoUninitialize()
|
||||
CheckClean()
|
78
venv/Lib/site-packages/win32com/test/testPippo.py
Normal file
78
venv/Lib/site-packages/win32com/test/testPippo.py
Normal file
|
@ -0,0 +1,78 @@
|
|||
import sys
|
||||
import unittest
|
||||
import pythoncom
|
||||
from win32com.client import Dispatch
|
||||
from win32com.client.gencache import EnsureDispatch
|
||||
|
||||
class PippoTester(unittest.TestCase):
|
||||
def setUp(self):
|
||||
from win32com.test.util import RegisterPythonServer
|
||||
from win32com.test import pippo_server
|
||||
RegisterPythonServer(pippo_server.__file__, "Python.Test.Pippo")
|
||||
# create it.
|
||||
self.object = Dispatch("Python.Test.Pippo")
|
||||
|
||||
def testLeaks(self):
|
||||
try:
|
||||
gtrc = sys.gettotalrefcount
|
||||
except AttributeError:
|
||||
print("Please run this with python_d for leak tests")
|
||||
gtrc = lambda: 0
|
||||
# note creating self.object() should have consumed our "one time" leaks
|
||||
self.object.Method1()
|
||||
start = gtrc()
|
||||
for i in range(1000):
|
||||
object = Dispatch("Python.Test.Pippo")
|
||||
object.Method1()
|
||||
object = None
|
||||
end = gtrc()
|
||||
if end-start > 5:
|
||||
self.fail("We lost %d references!" % (end-start,))
|
||||
|
||||
def testResults(self):
|
||||
rc, out1 = self.object.Method2(123, 111)
|
||||
self.assertEqual(rc, 123)
|
||||
self.assertEqual(out1, 222)
|
||||
|
||||
def testPythonArrays(self):
|
||||
self._testArray([-3, -2, -1, 0, 1, 2, 3])
|
||||
self._testArray([-3.14, -2, -.1, 0., 1.1, 2.5, 3])
|
||||
|
||||
def testNumpyArrays(self):
|
||||
try:
|
||||
import numpy
|
||||
except:
|
||||
print("Numpy test not possible because numpy module failed to import")
|
||||
return
|
||||
self._testArray(numpy.array([-3, -2, -1, 0, 1, 2, 3]))
|
||||
self._testArray(numpy.array([-3.14, -2, -.1, 0., 1.1, 2.5, 3]))
|
||||
|
||||
def testByteArrays(self):
|
||||
if 'bytes' in dir(__builtins__):
|
||||
# Use eval to avoid compilation error in Python 2.
|
||||
self._testArray(eval("b'abcdef'"))
|
||||
self._testArray(eval("bytearray(b'abcdef')"))
|
||||
|
||||
def _testArray(self, inArray):
|
||||
outArray = self.object.Method3(inArray)
|
||||
self.assertEqual(list(outArray), list(inArray))
|
||||
|
||||
def testLeaksGencache(self):
|
||||
try:
|
||||
gtrc = sys.gettotalrefcount
|
||||
except AttributeError:
|
||||
print("Please run this with python_d for leak tests")
|
||||
gtrc = lambda: 0
|
||||
# note creating self.object() should have consumed our "one time" leaks
|
||||
object = EnsureDispatch("Python.Test.Pippo")
|
||||
start = gtrc()
|
||||
for i in range(1000):
|
||||
object = EnsureDispatch("Python.Test.Pippo")
|
||||
object.Method1()
|
||||
object = None
|
||||
end = gtrc()
|
||||
if end-start > 10:
|
||||
self.fail("We lost %d references!" % (end-start,))
|
||||
|
||||
if __name__=='__main__':
|
||||
unittest.main()
|
730
venv/Lib/site-packages/win32com/test/testPyComTest.py
Normal file
730
venv/Lib/site-packages/win32com/test/testPyComTest.py
Normal file
|
@ -0,0 +1,730 @@
|
|||
# NOTE - Still seems to be a leak here somewhere
|
||||
# gateway count doesnt hit zero. Hence the print statements!
|
||||
|
||||
import sys; sys.coinit_flags=0 # Must be free-threaded!
|
||||
import win32api, pythoncom, time
|
||||
import pywintypes
|
||||
import os
|
||||
import winerror
|
||||
import win32com
|
||||
import win32com.client.connect
|
||||
from win32com.test.util import CheckClean
|
||||
from win32com.client import constants, DispatchBaseClass, CastTo, VARIANT
|
||||
from win32com.test.util import RegisterPythonServer
|
||||
from pywin32_testutil import str2memory
|
||||
import datetime
|
||||
import decimal
|
||||
import win32timezone
|
||||
|
||||
importMsg = "**** PyCOMTest is not installed ***\n PyCOMTest is a Python test specific COM client and server.\n It is likely this server is not installed on this machine\n To install the server, you must get the win32com sources\n and build it using MS Visual C++"
|
||||
|
||||
error = Exception
|
||||
|
||||
# This test uses a Python implemented COM server - ensure correctly registered.
|
||||
RegisterPythonServer(os.path.join(os.path.dirname(__file__), '..', "servers", "test_pycomtest.py"),
|
||||
"Python.Test.PyCOMTest")
|
||||
|
||||
from win32com.client import gencache
|
||||
try:
|
||||
gencache.EnsureModule('{6BCDCB60-5605-11D0-AE5F-CADD4C000000}', 0, 1, 1)
|
||||
except pythoncom.com_error:
|
||||
print("The PyCOMTest module can not be located or generated.")
|
||||
print(importMsg)
|
||||
raise RuntimeError(importMsg)
|
||||
|
||||
# We had a bg where RegisterInterfaces would fail if gencache had
|
||||
# already been run - exercise that here
|
||||
from win32com import universal
|
||||
universal.RegisterInterfaces('{6BCDCB60-5605-11D0-AE5F-CADD4C000000}', 0, 1, 1)
|
||||
|
||||
verbose = 0
|
||||
|
||||
# convert a normal int to a long int - used to avoid, eg, '1L' for py3k
|
||||
# friendliness
|
||||
def ensure_long(int_val):
|
||||
if sys.version_info > (3,):
|
||||
# py3k - no such thing as a 'long'
|
||||
return int_val
|
||||
# on py2x, we just use an expression that results in a long
|
||||
return 0x100000000-0x100000000+int_val
|
||||
|
||||
def check_get_set(func, arg):
|
||||
got = func(arg)
|
||||
if got != arg:
|
||||
raise error("%s failed - expected %r, got %r" % (func, arg, got))
|
||||
|
||||
def check_get_set_raises(exc, func, arg):
|
||||
try:
|
||||
got = func(arg)
|
||||
except exc as e:
|
||||
pass # what we expect!
|
||||
else:
|
||||
raise error("%s with arg %r didn't raise %s - returned %r" % (func, arg, exc, got))
|
||||
|
||||
def progress(*args):
|
||||
if verbose:
|
||||
for arg in args:
|
||||
print(arg, end=' ')
|
||||
print()
|
||||
|
||||
def TestApplyResult(fn, args, result):
|
||||
try:
|
||||
fnName = str(fn).split()[1]
|
||||
except:
|
||||
fnName = str(fn)
|
||||
progress("Testing ", fnName)
|
||||
pref = "function " + fnName
|
||||
rc = fn(*args)
|
||||
if rc != result:
|
||||
raise error("%s failed - result not %r but %r" % (pref, result, rc))
|
||||
|
||||
def TestConstant(constName, pyConst):
|
||||
try:
|
||||
comConst = getattr(constants, constName)
|
||||
except:
|
||||
raise error("Constant %s missing" % (constName,))
|
||||
if comConst != pyConst:
|
||||
raise error("Constant value wrong for %s - got %s, wanted %s" % (constName, comConst, pyConst))
|
||||
|
||||
# Simple handler class. This demo only fires one event.
|
||||
class RandomEventHandler:
|
||||
def _Init(self):
|
||||
self.fireds = {}
|
||||
def OnFire(self, no):
|
||||
try:
|
||||
self.fireds[no] = self.fireds[no] + 1
|
||||
except KeyError:
|
||||
self.fireds[no] = 0
|
||||
def OnFireWithNamedParams(self, no, a_bool, out1, out2):
|
||||
# This test exists mainly to help with an old bug, where named
|
||||
# params would come in reverse.
|
||||
Missing = pythoncom.Missing
|
||||
if no is not Missing:
|
||||
# We know our impl called 'OnFire' with the same ID
|
||||
assert no in self.fireds
|
||||
assert no+1==out1, "expecting 'out1' param to be ID+1"
|
||||
assert no+2==out2, "expecting 'out2' param to be ID+2"
|
||||
# The middle must be a boolean.
|
||||
assert a_bool is Missing or type(a_bool)==bool, "middle param not a bool"
|
||||
return out1+2, out2+2
|
||||
|
||||
def _DumpFireds(self):
|
||||
if not self.fireds:
|
||||
print("ERROR: Nothing was received!")
|
||||
for firedId, no in self.fireds.items():
|
||||
progress("ID %d fired %d times" % (firedId, no))
|
||||
|
||||
# A simple handler class that derives from object (ie, a "new style class") -
|
||||
# only relevant for Python 2.x (ie, the 2 classes should be identical in 3.x)
|
||||
class NewStyleRandomEventHandler(object):
|
||||
def _Init(self):
|
||||
self.fireds = {}
|
||||
def OnFire(self, no):
|
||||
try:
|
||||
self.fireds[no] = self.fireds[no] + 1
|
||||
except KeyError:
|
||||
self.fireds[no] = 0
|
||||
def OnFireWithNamedParams(self, no, a_bool, out1, out2):
|
||||
# This test exists mainly to help with an old bug, where named
|
||||
# params would come in reverse.
|
||||
Missing = pythoncom.Missing
|
||||
if no is not Missing:
|
||||
# We know our impl called 'OnFire' with the same ID
|
||||
assert no in self.fireds
|
||||
assert no+1==out1, "expecting 'out1' param to be ID+1"
|
||||
assert no+2==out2, "expecting 'out2' param to be ID+2"
|
||||
# The middle must be a boolean.
|
||||
assert a_bool is Missing or type(a_bool)==bool, "middle param not a bool"
|
||||
return out1+2, out2+2
|
||||
|
||||
def _DumpFireds(self):
|
||||
if not self.fireds:
|
||||
print("ERROR: Nothing was received!")
|
||||
for firedId, no in self.fireds.items():
|
||||
progress("ID %d fired %d times" % (firedId, no))
|
||||
|
||||
|
||||
# Test everything which can be tested using both the "dynamic" and "generated"
|
||||
# COM objects (or when there are very subtle differences)
|
||||
def TestCommon(o, is_generated):
|
||||
progress("Getting counter")
|
||||
counter = o.GetSimpleCounter()
|
||||
TestCounter(counter, is_generated)
|
||||
|
||||
progress("Checking default args")
|
||||
rc = o.TestOptionals()
|
||||
if rc[:-1] != ("def", 0, 1) or abs(rc[-1]-3.14)>.01:
|
||||
print(rc)
|
||||
raise error("Did not get the optional values correctly")
|
||||
rc = o.TestOptionals("Hi", 2, 3, 1.1)
|
||||
if rc[:-1] != ("Hi", 2, 3) or abs(rc[-1]-1.1)>.01:
|
||||
print(rc)
|
||||
raise error("Did not get the specified optional values correctly")
|
||||
rc = o.TestOptionals2(0)
|
||||
if rc != (0, "", 1):
|
||||
print(rc)
|
||||
raise error("Did not get the optional2 values correctly")
|
||||
rc = o.TestOptionals2(1.1, "Hi", 2)
|
||||
if rc[1:] != ("Hi", 2) or abs(rc[0]-1.1)>.01:
|
||||
print(rc)
|
||||
raise error("Did not get the specified optional2 values correctly")
|
||||
|
||||
progress("Checking getting/passing IUnknown")
|
||||
check_get_set(o.GetSetUnknown, o)
|
||||
progress("Checking getting/passing IDispatch")
|
||||
if not isinstance(o.GetSetDispatch(o), o.__class__):
|
||||
raise error("GetSetDispatch failed: %r" % (o.GetSetDispatch(o),))
|
||||
progress("Checking getting/passing IDispatch of known type")
|
||||
if o.GetSetInterface(o).__class__ != o.__class__:
|
||||
raise error("GetSetDispatch failed")
|
||||
|
||||
progress("Checking misc args")
|
||||
check_get_set(o.GetSetVariant, 4)
|
||||
check_get_set(o.GetSetVariant, "foo")
|
||||
check_get_set(o.GetSetVariant, o)
|
||||
|
||||
# signed/unsigned.
|
||||
check_get_set(o.GetSetInt, 0)
|
||||
check_get_set(o.GetSetInt, -1)
|
||||
check_get_set(o.GetSetInt, 1)
|
||||
|
||||
check_get_set(o.GetSetUnsignedInt, 0)
|
||||
check_get_set(o.GetSetUnsignedInt, 1)
|
||||
check_get_set(o.GetSetUnsignedInt, 0x80000000)
|
||||
if o.GetSetUnsignedInt(-1) != 0xFFFFFFFF:
|
||||
# -1 is a special case - we accept a negative int (silently converting to
|
||||
# unsigned) but when getting it back we convert it to a long.
|
||||
raise error("unsigned -1 failed")
|
||||
|
||||
check_get_set(o.GetSetLong, 0)
|
||||
check_get_set(o.GetSetLong, -1)
|
||||
check_get_set(o.GetSetLong, 1)
|
||||
|
||||
check_get_set(o.GetSetUnsignedLong, 0)
|
||||
check_get_set(o.GetSetUnsignedLong, 1)
|
||||
check_get_set(o.GetSetUnsignedLong, 0x80000000)
|
||||
# -1 is a special case - see above.
|
||||
if o.GetSetUnsignedLong(-1) != 0xFFFFFFFF:
|
||||
raise error("unsigned -1 failed")
|
||||
|
||||
# We want to explicitly test > 32 bits. py3k has no 'maxint' and
|
||||
# 'maxsize+1' is no good on 64bit platforms as its 65 bits!
|
||||
big = 2147483647 # sys.maxint on py2k
|
||||
for l in big, big+1, 1 << 65:
|
||||
check_get_set(o.GetSetVariant, l)
|
||||
|
||||
progress("Checking structs")
|
||||
r = o.GetStruct()
|
||||
assert r.int_value == 99 and str(r.str_value)=="Hello from C++"
|
||||
assert o.DoubleString("foo") == "foofoo"
|
||||
|
||||
progress("Checking var args")
|
||||
o.SetVarArgs("Hi", "There", "From", "Python", 1)
|
||||
if o.GetLastVarArgs() != ("Hi", "There", "From", "Python", 1):
|
||||
raise error("VarArgs failed -" + str(o.GetLastVarArgs()))
|
||||
|
||||
progress("Checking arrays")
|
||||
l=[]
|
||||
TestApplyResult(o.SetVariantSafeArray, (l,), len(l))
|
||||
l=[1,2,3,4]
|
||||
TestApplyResult(o.SetVariantSafeArray, (l,), len(l))
|
||||
TestApplyResult(o.CheckVariantSafeArray, ((1,2,3,4,),), 1)
|
||||
|
||||
# and binary
|
||||
TestApplyResult(o.SetBinSafeArray, (str2memory('foo\0bar'),), 7)
|
||||
|
||||
progress("Checking properties")
|
||||
o.LongProp = 3
|
||||
if o.LongProp != 3 or o.IntProp != 3:
|
||||
raise error("Property value wrong - got %d/%d" % (o.LongProp,o.IntProp))
|
||||
o.LongProp = o.IntProp = -3
|
||||
if o.LongProp != -3 or o.IntProp != -3:
|
||||
raise error("Property value wrong - got %d/%d" % (o.LongProp,o.IntProp))
|
||||
# This number fits in an unsigned long. Attempting to set it to a normal
|
||||
# long will involve overflow, which is to be expected. But we do
|
||||
# expect it to work in a property explicitly a VT_UI4.
|
||||
check = 3 *10 **9
|
||||
o.ULongProp = check
|
||||
if o.ULongProp != check:
|
||||
raise error("Property value wrong - got %d (expected %d)" % (o.ULongProp, check))
|
||||
|
||||
TestApplyResult(o.Test, ("Unused", 99), 1) # A bool function
|
||||
TestApplyResult(o.Test, ("Unused", -1), 1) # A bool function
|
||||
TestApplyResult(o.Test, ("Unused", 1==1), 1) # A bool function
|
||||
TestApplyResult(o.Test, ("Unused", 0), 0)
|
||||
TestApplyResult(o.Test, ("Unused", 1==0), 0)
|
||||
|
||||
assert o.DoubleString("foo") == "foofoo"
|
||||
|
||||
TestConstant("ULongTest1", ensure_long(0xFFFFFFFF))
|
||||
TestConstant("ULongTest2", ensure_long(0x7FFFFFFF))
|
||||
TestConstant("LongTest1", ensure_long(-0x7FFFFFFF))
|
||||
TestConstant("LongTest2", ensure_long(0x7FFFFFFF))
|
||||
TestConstant("UCharTest", 255)
|
||||
TestConstant("CharTest", -1)
|
||||
# 'Hello Loraine', but the 'r' is the "Registered" sign (\xae)
|
||||
TestConstant("StringTest", "Hello Lo\xaeaine")
|
||||
|
||||
progress("Checking dates and times")
|
||||
if issubclass(pywintypes.TimeType, datetime.datetime):
|
||||
# For now *all* times passed must be tz-aware.
|
||||
now = win32timezone.now()
|
||||
# but conversion to and from a VARIANT loses sub-second...
|
||||
now = now.replace(microsecond=0)
|
||||
later = now + datetime.timedelta(seconds=1)
|
||||
TestApplyResult(o.EarliestDate, (now, later), now)
|
||||
else:
|
||||
# old PyTime object
|
||||
now = pythoncom.MakeTime(time.gmtime(time.time()))
|
||||
later = pythoncom.MakeTime(time.gmtime(time.time()+1))
|
||||
TestApplyResult(o.EarliestDate, (now, later), now)
|
||||
# But it can still *accept* tz-naive datetime objects...
|
||||
now = datetime.datetime.now()
|
||||
expect = pythoncom.MakeTime(now)
|
||||
TestApplyResult(o.EarliestDate, (now, now), expect)
|
||||
|
||||
progress("Checking currency")
|
||||
# currency.
|
||||
pythoncom.__future_currency__ = 1
|
||||
if o.CurrencyProp != 0:
|
||||
raise error("Expecting 0, got %r" % (o.CurrencyProp,))
|
||||
for val in ("1234.5678", "1234.56", "1234"):
|
||||
o.CurrencyProp = decimal.Decimal(val)
|
||||
if o.CurrencyProp != decimal.Decimal(val):
|
||||
raise error("%s got %r" % (val, o.CurrencyProp))
|
||||
v1 = decimal.Decimal("1234.5678")
|
||||
TestApplyResult(o.DoubleCurrency, (v1,), v1*2)
|
||||
|
||||
v2 = decimal.Decimal("9012.3456")
|
||||
TestApplyResult(o.AddCurrencies, (v1, v2), v1+v2)
|
||||
|
||||
TestTrickyTypesWithVariants(o, is_generated)
|
||||
progress("Checking win32com.client.VARIANT")
|
||||
TestPyVariant(o, is_generated)
|
||||
|
||||
|
||||
def TestTrickyTypesWithVariants(o, is_generated):
|
||||
# Test tricky stuff with type handling and generally only works with
|
||||
# "generated" support but can be worked around using VARIANT.
|
||||
if is_generated:
|
||||
got = o.TestByRefVariant(2)
|
||||
else:
|
||||
v = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_VARIANT, 2)
|
||||
o.TestByRefVariant(v)
|
||||
got = v.value
|
||||
if got != 4:
|
||||
raise error("TestByRefVariant failed")
|
||||
|
||||
if is_generated:
|
||||
got = o.TestByRefString("Foo")
|
||||
else:
|
||||
v = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_BSTR, "Foo")
|
||||
o.TestByRefString(v)
|
||||
got = v.value
|
||||
if got != "FooFoo":
|
||||
raise error("TestByRefString failed")
|
||||
|
||||
# check we can pass ints as a VT_UI1
|
||||
vals=[1,2,3,4]
|
||||
if is_generated:
|
||||
arg = vals
|
||||
else:
|
||||
arg = VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_UI1, vals)
|
||||
TestApplyResult(o.SetBinSafeArray, (arg,), len(vals))
|
||||
|
||||
# safearrays of doubles and floats
|
||||
vals = [0, 1.1, 2.2, 3.3]
|
||||
if is_generated:
|
||||
arg = vals
|
||||
else:
|
||||
arg = VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, vals)
|
||||
TestApplyResult(o.SetDoubleSafeArray, (arg,), len(vals))
|
||||
|
||||
if is_generated:
|
||||
arg = vals
|
||||
else:
|
||||
arg = VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R4, vals)
|
||||
TestApplyResult(o.SetFloatSafeArray, (arg,), len(vals))
|
||||
|
||||
vals=[1.1, 2.2, 3.3, 4.4]
|
||||
expected = (1.1*2, 2.2*2, 3.3*2, 4.4*2)
|
||||
if is_generated:
|
||||
TestApplyResult(o.ChangeDoubleSafeArray, (vals,), expected)
|
||||
else:
|
||||
arg = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_ARRAY | pythoncom.VT_R8, vals)
|
||||
o.ChangeDoubleSafeArray(arg)
|
||||
if arg.value != expected:
|
||||
raise error("ChangeDoubleSafeArray got the wrong value")
|
||||
|
||||
if is_generated:
|
||||
got = o.DoubleInOutString("foo")
|
||||
else:
|
||||
v = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_BSTR, "foo")
|
||||
o.DoubleInOutString(v)
|
||||
got = v.value
|
||||
assert got == "foofoo", got
|
||||
|
||||
val = decimal.Decimal("1234.5678")
|
||||
if is_generated:
|
||||
got = o.DoubleCurrencyByVal(val)
|
||||
else:
|
||||
v = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_CY, val)
|
||||
o.DoubleCurrencyByVal(v)
|
||||
got = v.value
|
||||
assert got == val * 2
|
||||
|
||||
def TestDynamic():
|
||||
progress("Testing Dynamic")
|
||||
import win32com.client.dynamic
|
||||
o = win32com.client.dynamic.DumbDispatch("PyCOMTest.PyCOMTest")
|
||||
TestCommon(o, False)
|
||||
|
||||
counter = win32com.client.dynamic.DumbDispatch("PyCOMTest.SimpleCounter")
|
||||
TestCounter(counter, False)
|
||||
|
||||
# Dynamic doesn't know this should be an int, so we get a COM
|
||||
# TypeMismatch error.
|
||||
try:
|
||||
check_get_set_raises(ValueError, o.GetSetInt, "foo")
|
||||
raise error("no exception raised")
|
||||
except pythoncom.com_error as exc:
|
||||
if exc.hresult != winerror.DISP_E_TYPEMISMATCH:
|
||||
raise
|
||||
|
||||
# damn - props with params don't work for dynamic objects :(
|
||||
# o.SetParamProp(0, 1)
|
||||
# if o.ParamProp(0) != 1:
|
||||
# raise RuntimeError, o.paramProp(0)
|
||||
|
||||
|
||||
def TestGenerated():
|
||||
# Create an instance of the server.
|
||||
from win32com.client.gencache import EnsureDispatch
|
||||
o = EnsureDispatch("PyCOMTest.PyCOMTest")
|
||||
TestCommon(o, True)
|
||||
|
||||
counter = EnsureDispatch("PyCOMTest.SimpleCounter")
|
||||
TestCounter(counter, True)
|
||||
|
||||
# XXX - this is failing in dynamic tests, but should work fine.
|
||||
i1, i2 = o.GetMultipleInterfaces()
|
||||
if not isinstance(i1, DispatchBaseClass) or not isinstance(i2, DispatchBaseClass):
|
||||
# Yay - is now an instance returned!
|
||||
raise error("GetMultipleInterfaces did not return instances - got '%s', '%s'" % (i1, i2))
|
||||
del i1
|
||||
del i2
|
||||
|
||||
# Generated knows to only pass a 32bit int, so should fail.
|
||||
check_get_set_raises(OverflowError, o.GetSetInt, 0x80000000)
|
||||
check_get_set_raises(OverflowError, o.GetSetLong, 0x80000000)
|
||||
|
||||
# Generated knows this should be an int, so raises ValueError
|
||||
check_get_set_raises(ValueError, o.GetSetInt, "foo")
|
||||
check_get_set_raises(ValueError, o.GetSetLong, "foo")
|
||||
|
||||
# Pass some non-sequence objects to our array decoder, and watch it fail.
|
||||
try:
|
||||
o.SetVariantSafeArray("foo")
|
||||
raise error("Expected a type error")
|
||||
except TypeError:
|
||||
pass
|
||||
try:
|
||||
o.SetVariantSafeArray(666)
|
||||
raise error("Expected a type error")
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
o.GetSimpleSafeArray(None)
|
||||
TestApplyResult(o.GetSimpleSafeArray, (None,), tuple(range(10)))
|
||||
resultCheck = tuple(range(5)), tuple(range(10)), tuple(range(20))
|
||||
TestApplyResult(o.GetSafeArrays, (None, None, None), resultCheck)
|
||||
|
||||
l=[]
|
||||
TestApplyResult(o.SetIntSafeArray, (l,), len(l))
|
||||
l=[1,2,3,4]
|
||||
TestApplyResult(o.SetIntSafeArray, (l,), len(l))
|
||||
ll=[1,2,3,0x100000000]
|
||||
TestApplyResult(o.SetLongLongSafeArray, (ll,), len(ll))
|
||||
TestApplyResult(o.SetULongLongSafeArray, (ll,), len(ll))
|
||||
|
||||
# Tell the server to do what it does!
|
||||
TestApplyResult(o.Test2, (constants.Attr2,), constants.Attr2)
|
||||
TestApplyResult(o.Test3, (constants.Attr2,), constants.Attr2)
|
||||
TestApplyResult(o.Test4, (constants.Attr2,), constants.Attr2)
|
||||
TestApplyResult(o.Test5, (constants.Attr2,), constants.Attr2)
|
||||
|
||||
TestApplyResult(o.Test6, (constants.WideAttr1,), constants.WideAttr1)
|
||||
TestApplyResult(o.Test6, (constants.WideAttr2,), constants.WideAttr2)
|
||||
TestApplyResult(o.Test6, (constants.WideAttr3,), constants.WideAttr3)
|
||||
TestApplyResult(o.Test6, (constants.WideAttr4,), constants.WideAttr4)
|
||||
TestApplyResult(o.Test6, (constants.WideAttr5,), constants.WideAttr5)
|
||||
|
||||
o.SetParamProp(0, 1)
|
||||
if o.ParamProp(0) != 1:
|
||||
raise RuntimeError(o.paramProp(0))
|
||||
|
||||
# Make sure CastTo works - even though it is only casting it to itself!
|
||||
o2 = CastTo(o, "IPyCOMTest")
|
||||
if o != o2:
|
||||
raise error("CastTo should have returned the same object")
|
||||
|
||||
# Do the connection point thing...
|
||||
# Create a connection object.
|
||||
progress("Testing connection points")
|
||||
o2 = win32com.client.DispatchWithEvents(o, RandomEventHandler)
|
||||
TestEvents(o2, o2)
|
||||
o2 = win32com.client.DispatchWithEvents(o, NewStyleRandomEventHandler)
|
||||
TestEvents(o2, o2)
|
||||
# and a plain "WithEvents".
|
||||
handler = win32com.client.WithEvents(o, RandomEventHandler)
|
||||
TestEvents(o, handler)
|
||||
handler = win32com.client.WithEvents(o, NewStyleRandomEventHandler)
|
||||
TestEvents(o, handler)
|
||||
progress("Finished generated .py test.")
|
||||
|
||||
|
||||
def TestEvents(o, handler):
|
||||
sessions = []
|
||||
handler._Init()
|
||||
try:
|
||||
for i in range(3):
|
||||
session = o.Start()
|
||||
sessions.append(session)
|
||||
time.sleep(.5)
|
||||
finally:
|
||||
# Stop the servers
|
||||
for session in sessions:
|
||||
o.Stop(session)
|
||||
handler._DumpFireds()
|
||||
handler.close()
|
||||
|
||||
|
||||
def _TestPyVariant(o, is_generated, val, checker = None):
|
||||
if is_generated:
|
||||
vt, got = o.GetVariantAndType(val)
|
||||
else:
|
||||
# Gotta supply all 3 args with the last 2 being explicit variants to
|
||||
# get the byref behaviour.
|
||||
var_vt = VARIANT(pythoncom.VT_UI2 | pythoncom.VT_BYREF, 0)
|
||||
var_result = VARIANT(pythoncom.VT_VARIANT | pythoncom.VT_BYREF, 0)
|
||||
o.GetVariantAndType(val, var_vt, var_result)
|
||||
vt = var_vt.value
|
||||
got = var_result.value
|
||||
if checker is not None:
|
||||
checker(got)
|
||||
return
|
||||
# default checking.
|
||||
assert vt == val.varianttype, (vt, val.varianttype)
|
||||
# Handle our safe-array test - if the passed value is a list of variants,
|
||||
# compare against the actual values.
|
||||
if type(val.value) in (tuple, list):
|
||||
check = [v.value if isinstance(v, VARIANT) else v for v in val.value]
|
||||
# pythoncom always returns arrays as tuples.
|
||||
got = list(got)
|
||||
else:
|
||||
check = val.value
|
||||
assert type(check) == type(got), (type(check), type(got))
|
||||
assert check == got, (check, got)
|
||||
|
||||
def _TestPyVariantFails(o, is_generated, val, exc):
|
||||
try:
|
||||
_TestPyVariant(o, is_generated, val)
|
||||
raise error("Setting %r didn't raise %s" % (val, exc))
|
||||
except exc:
|
||||
pass
|
||||
|
||||
def TestPyVariant(o, is_generated):
|
||||
_TestPyVariant(o, is_generated, VARIANT(pythoncom.VT_UI1, 1))
|
||||
_TestPyVariant(o, is_generated, VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_UI4, [1,2,3]))
|
||||
_TestPyVariant(o, is_generated, VARIANT(pythoncom.VT_BSTR, "hello"))
|
||||
_TestPyVariant(o, is_generated, VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_BSTR, ["hello", "there"]))
|
||||
def check_dispatch(got):
|
||||
assert isinstance(got._oleobj_, pythoncom.TypeIIDs[pythoncom.IID_IDispatch])
|
||||
_TestPyVariant(o, is_generated, VARIANT(pythoncom.VT_DISPATCH, o), check_dispatch)
|
||||
_TestPyVariant(o, is_generated, VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_DISPATCH, [o]))
|
||||
# an array of variants each with a specific type.
|
||||
v = VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_VARIANT,
|
||||
[VARIANT(pythoncom.VT_UI4, 1),
|
||||
VARIANT(pythoncom.VT_UI4, 2),
|
||||
VARIANT(pythoncom.VT_UI4, 3)
|
||||
]
|
||||
)
|
||||
_TestPyVariant(o, is_generated, v)
|
||||
|
||||
# and failures
|
||||
_TestPyVariantFails(o, is_generated, VARIANT(pythoncom.VT_UI1, "foo"), ValueError)
|
||||
|
||||
|
||||
def TestCounter(counter, bIsGenerated):
|
||||
# Test random access into container
|
||||
progress("Testing counter", repr(counter))
|
||||
import random
|
||||
for i in range(50):
|
||||
num = int(random.random() * len(counter))
|
||||
try:
|
||||
# XXX - this appears broken by commit 08a14d4deb374eaa06378509cf44078ad467b9dc -
|
||||
# We shouldn't need to do generated differently than dynamic.
|
||||
if bIsGenerated:
|
||||
ret = counter.Item(num+1)
|
||||
else:
|
||||
ret = counter[num]
|
||||
if ret != num+1:
|
||||
raise error("Random access into element %d failed - return was %s" % (num,repr(ret)))
|
||||
except IndexError:
|
||||
raise error("** IndexError accessing collection element %d" % num)
|
||||
|
||||
num = 0
|
||||
if bIsGenerated:
|
||||
counter.SetTestProperty(1)
|
||||
counter.TestProperty = 1 # Note this has a second, default arg.
|
||||
counter.SetTestProperty(1,2)
|
||||
if counter.TestPropertyWithDef != 0:
|
||||
raise error("Unexpected property set value!")
|
||||
if counter.TestPropertyNoDef(1) != 1:
|
||||
raise error("Unexpected property set value!")
|
||||
else:
|
||||
pass
|
||||
# counter.TestProperty = 1
|
||||
|
||||
counter.LBound=1
|
||||
counter.UBound=10
|
||||
if counter.LBound != 1 or counter.UBound!=10:
|
||||
print("** Error - counter did not keep its properties")
|
||||
|
||||
if bIsGenerated:
|
||||
bounds = counter.GetBounds()
|
||||
if bounds[0]!=1 or bounds[1]!=10:
|
||||
raise error("** Error - counter did not give the same properties back")
|
||||
counter.SetBounds(bounds[0], bounds[1])
|
||||
|
||||
for item in counter:
|
||||
num = num + 1
|
||||
if num != len(counter):
|
||||
raise error("*** Length of counter and loop iterations dont match ***")
|
||||
if num != 10:
|
||||
raise error("*** Unexpected number of loop iterations ***")
|
||||
|
||||
counter = iter(counter)._iter_.Clone() # Test Clone() and enum directly
|
||||
counter.Reset()
|
||||
num = 0
|
||||
for item in counter:
|
||||
num = num + 1
|
||||
if num != 10:
|
||||
raise error("*** Unexpected number of loop iterations - got %d ***" % num)
|
||||
progress("Finished testing counter")
|
||||
|
||||
def TestLocalVTable(ob):
|
||||
# Python doesn't fully implement this interface.
|
||||
if ob.DoubleString("foo") != "foofoo":
|
||||
raise error("couldn't foofoo")
|
||||
|
||||
###############################
|
||||
##
|
||||
## Some vtable tests of the interface
|
||||
##
|
||||
def TestVTable(clsctx=pythoncom.CLSCTX_ALL):
|
||||
# Any vtable interfaces marked as dual *should* be able to be
|
||||
# correctly implemented as IDispatch.
|
||||
ob = win32com.client.Dispatch("Python.Test.PyCOMTest")
|
||||
TestLocalVTable(ob)
|
||||
# Now test it via vtable - use some C++ code to help here as Python can't do it directly yet.
|
||||
tester = win32com.client.Dispatch("PyCOMTest.PyCOMTest")
|
||||
testee = pythoncom.CoCreateInstance("Python.Test.PyCOMTest", None, clsctx, pythoncom.IID_IUnknown)
|
||||
# check we fail gracefully with None passed.
|
||||
try:
|
||||
tester.TestMyInterface(None)
|
||||
except pythoncom.com_error as details:
|
||||
pass
|
||||
# and a real object.
|
||||
tester.TestMyInterface(testee)
|
||||
|
||||
def TestVTable2():
|
||||
# We once crashed creating our object with the native interface as
|
||||
# the first IID specified. We must do it _after_ the tests, so that
|
||||
# Python has already had the gateway registered from last run.
|
||||
ob = win32com.client.Dispatch("Python.Test.PyCOMTest")
|
||||
iid = pythoncom.InterfaceNames["IPyCOMTest"]
|
||||
clsid = "Python.Test.PyCOMTest"
|
||||
clsctx = pythoncom.CLSCTX_SERVER
|
||||
try:
|
||||
testee = pythoncom.CoCreateInstance(clsid, None, clsctx, iid)
|
||||
except TypeError:
|
||||
# Python can't actually _use_ this interface yet, so this is
|
||||
# "expected". Any COM error is not.
|
||||
pass
|
||||
|
||||
def TestVTableMI():
|
||||
clsctx = pythoncom.CLSCTX_SERVER
|
||||
ob = pythoncom.CoCreateInstance("Python.Test.PyCOMTestMI", None, clsctx, pythoncom.IID_IUnknown)
|
||||
# This inherits from IStream.
|
||||
ob.QueryInterface(pythoncom.IID_IStream)
|
||||
# This implements IStorage, specifying the IID as a string
|
||||
ob.QueryInterface(pythoncom.IID_IStorage)
|
||||
# IDispatch should always work
|
||||
ob.QueryInterface(pythoncom.IID_IDispatch)
|
||||
|
||||
iid = pythoncom.InterfaceNames["IPyCOMTest"]
|
||||
try:
|
||||
ob.QueryInterface(iid)
|
||||
except TypeError:
|
||||
# Python can't actually _use_ this interface yet, so this is
|
||||
# "expected". Any COM error is not.
|
||||
pass
|
||||
|
||||
def TestQueryInterface(long_lived_server = 0, iterations=5):
|
||||
tester = win32com.client.Dispatch("PyCOMTest.PyCOMTest")
|
||||
if long_lived_server:
|
||||
# Create a local server
|
||||
t0 = win32com.client.Dispatch("Python.Test.PyCOMTest", clsctx=pythoncom.CLSCTX_LOCAL_SERVER)
|
||||
# Request custom interfaces a number of times
|
||||
prompt = [
|
||||
"Testing QueryInterface without long-lived local-server #%d of %d...",
|
||||
"Testing QueryInterface with long-lived local-server #%d of %d..."
|
||||
]
|
||||
|
||||
for i in range(iterations):
|
||||
progress(prompt[long_lived_server!=0] % (i+1, iterations))
|
||||
tester.TestQueryInterface()
|
||||
|
||||
class Tester(win32com.test.util.TestCase):
|
||||
def testVTableInProc(self):
|
||||
# We used to crash running this the second time - do it a few times
|
||||
for i in range(3):
|
||||
progress("Testing VTables in-process #%d..." % (i+1))
|
||||
TestVTable(pythoncom.CLSCTX_INPROC_SERVER)
|
||||
def testVTableLocalServer(self):
|
||||
for i in range(3):
|
||||
progress("Testing VTables out-of-process #%d..." % (i+1))
|
||||
TestVTable(pythoncom.CLSCTX_LOCAL_SERVER)
|
||||
def testVTable2(self):
|
||||
for i in range(3):
|
||||
TestVTable2()
|
||||
def testVTableMI(self):
|
||||
for i in range(3):
|
||||
TestVTableMI()
|
||||
def testMultiQueryInterface(self):
|
||||
TestQueryInterface(0,6)
|
||||
# When we use the custom interface in the presence of a long-lived
|
||||
# local server, i.e. a local server that is already running when
|
||||
# we request an instance of our COM object, and remains afterwards,
|
||||
# then after repeated requests to create an instance of our object
|
||||
# the custom interface disappears -- i.e. QueryInterface fails with
|
||||
# E_NOINTERFACE. Set the upper range of the following test to 2 to
|
||||
# pass this test, i.e. TestQueryInterface(1,2)
|
||||
TestQueryInterface(1,6)
|
||||
def testDynamic(self):
|
||||
TestDynamic()
|
||||
def testGenerated(self):
|
||||
TestGenerated()
|
||||
|
||||
if __name__=='__main__':
|
||||
# XXX - todo - Complete hack to crank threading support.
|
||||
# Should NOT be necessary
|
||||
def NullThreadFunc():
|
||||
pass
|
||||
import _thread
|
||||
_thread.start_new( NullThreadFunc, () )
|
||||
|
||||
if "-v" in sys.argv: verbose = 1
|
||||
|
||||
win32com.test.util.testmain()
|
33
venv/Lib/site-packages/win32com/test/testPyScriptlet.js
Normal file
33
venv/Lib/site-packages/win32com/test/testPyScriptlet.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
function print(msg)
|
||||
{
|
||||
WScript.Echo(msg) ;
|
||||
}
|
||||
|
||||
function check(condition, msg)
|
||||
{
|
||||
if (!condition) {
|
||||
print("***** testPyScriptlet.js failed *****");
|
||||
print(msg);
|
||||
}
|
||||
}
|
||||
|
||||
var thisScriptEngine = ScriptEngine() ;
|
||||
|
||||
var majorVersion = ScriptEngineMajorVersion() ;
|
||||
var minorVersion = ScriptEngineMinorVersion() ;
|
||||
var buildVersion = ScriptEngineBuildVersion() ;
|
||||
|
||||
WScript.Echo(thisScriptEngine + " Version " + majorVersion + "." + minorVersion + " Build " + buildVersion) ;
|
||||
|
||||
var scriptlet = new ActiveXObject("TestPys.Scriptlet") ;
|
||||
|
||||
check(scriptlet.PyProp1=="PyScript Property1", "PyProp1 wasn't correct initial value");
|
||||
scriptlet.PyProp1 = "New Value";
|
||||
check(scriptlet.PyProp1=="New Value", "PyProp1 wasn't correct new value");
|
||||
|
||||
check(scriptlet.PyProp2=="PyScript Property2", "PyProp2 wasn't correct initial value");
|
||||
scriptlet.PyProp2 = "Another New Value";
|
||||
check(scriptlet.PyProp2=="Another New Value", "PyProp2 wasn't correct new value");
|
||||
|
||||
check(scriptlet.PyMethod1()=="PyMethod1 called", "Method1 wrong value");
|
||||
check(scriptlet.PyMethod2()=="PyMethod2 called", "Method2 wrong value");
|
26
venv/Lib/site-packages/win32com/test/testROT.py
Normal file
26
venv/Lib/site-packages/win32com/test/testROT.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
import pythoncom
|
||||
import unittest
|
||||
import win32com.test.util
|
||||
import winerror
|
||||
|
||||
class TestROT(win32com.test.util.TestCase):
|
||||
def testit(self):
|
||||
ctx = pythoncom.CreateBindCtx()
|
||||
rot = pythoncom.GetRunningObjectTable()
|
||||
num = 0
|
||||
for mk in rot:
|
||||
name = mk.GetDisplayName(ctx, None)
|
||||
num += 1
|
||||
# Monikers themselves can iterate their contents (sometimes :)
|
||||
try:
|
||||
for sub in mk:
|
||||
num += 1
|
||||
except pythoncom.com_error as exc:
|
||||
if exc.hresult != winerror.E_NOTIMPL:
|
||||
raise
|
||||
|
||||
#if num < 2:
|
||||
# print "Only", num, "objects in the ROT - this is unusual"
|
||||
|
||||
if __name__=='__main__':
|
||||
unittest.main()
|
39
venv/Lib/site-packages/win32com/test/testServers.py
Normal file
39
venv/Lib/site-packages/win32com/test/testServers.py
Normal file
|
@ -0,0 +1,39 @@
|
|||
import pythoncom, win32com.client.dynamic, sys
|
||||
import winerror
|
||||
import win32com.test.util
|
||||
import unittest
|
||||
|
||||
def TestConnections():
|
||||
import win32com.demos.connect
|
||||
win32com.demos.connect.test()
|
||||
|
||||
class InterpCase(win32com.test.util.TestCase):
|
||||
def setUp(self):
|
||||
# Ensure the correct version registered.
|
||||
from win32com.test.util import RegisterPythonServer
|
||||
from win32com.servers import interp
|
||||
RegisterPythonServer(interp.__file__, "Python.Interpreter")
|
||||
|
||||
def _testInterp(self, interp):
|
||||
self.assertEquals(interp.Eval("1+1"), 2)
|
||||
win32com.test.util.assertRaisesCOM_HRESULT(self, winerror.DISP_E_TYPEMISMATCH,
|
||||
interp.Eval, 2)
|
||||
|
||||
def testInproc(self):
|
||||
interp = win32com.client.dynamic.Dispatch("Python.Interpreter", clsctx = pythoncom.CLSCTX_INPROC)
|
||||
self._testInterp(interp)
|
||||
|
||||
def testLocalServer(self):
|
||||
interp = win32com.client.dynamic.Dispatch("Python.Interpreter", clsctx = pythoncom.CLSCTX_LOCAL_SERVER)
|
||||
self._testInterp(interp)
|
||||
|
||||
def testAny(self):
|
||||
interp = win32com.client.dynamic.Dispatch("Python.Interpreter")
|
||||
self._testInterp(interp)
|
||||
|
||||
class ConnectionsTestCase(win32com.test.util.TestCase):
|
||||
def testConnections(self):
|
||||
TestConnections()
|
||||
|
||||
if __name__=='__main__':
|
||||
unittest.main('testServers')
|
260
venv/Lib/site-packages/win32com/test/testShell.py
Normal file
260
venv/Lib/site-packages/win32com/test/testShell.py
Normal file
|
@ -0,0 +1,260 @@
|
|||
import sys, os
|
||||
import struct
|
||||
import unittest
|
||||
import copy
|
||||
import datetime
|
||||
import win32timezone
|
||||
|
||||
try:
|
||||
sys_maxsize = sys.maxsize # 2.6 and later - maxsize != maxint on 64bits
|
||||
except AttributeError:
|
||||
sys_maxsize = sys.maxint
|
||||
|
||||
import win32con
|
||||
import pythoncom
|
||||
import pywintypes
|
||||
from win32com.shell import shell
|
||||
from win32com.shell.shellcon import *
|
||||
from win32com.storagecon import *
|
||||
|
||||
import win32com.test.util
|
||||
from pywin32_testutil import str2bytes
|
||||
|
||||
class ShellTester(win32com.test.util.TestCase):
|
||||
def testShellLink(self):
|
||||
desktop = str(shell.SHGetSpecialFolderPath(0, CSIDL_DESKTOP))
|
||||
num = 0
|
||||
shellLink = pythoncom.CoCreateInstance(shell.CLSID_ShellLink, None, pythoncom.CLSCTX_INPROC_SERVER, shell.IID_IShellLink)
|
||||
persistFile = shellLink.QueryInterface(pythoncom.IID_IPersistFile)
|
||||
names = [os.path.join(desktop, n) for n in os.listdir(desktop)]
|
||||
programs = str(shell.SHGetSpecialFolderPath(0, CSIDL_PROGRAMS))
|
||||
names.extend([os.path.join(programs, n) for n in os.listdir(programs)])
|
||||
for name in names:
|
||||
try:
|
||||
persistFile.Load(name,STGM_READ)
|
||||
except pythoncom.com_error:
|
||||
continue
|
||||
# Resolve is slow - avoid it for our tests.
|
||||
#shellLink.Resolve(0, shell.SLR_ANY_MATCH | shell.SLR_NO_UI)
|
||||
fname, findData = shellLink.GetPath(0)
|
||||
unc = shellLink.GetPath(shell.SLGP_UNCPRIORITY)[0]
|
||||
num += 1
|
||||
if num == 0:
|
||||
# This isn't a fatal error, but is unlikely.
|
||||
print("Could not find any links on your desktop or programs dir, which is unusual")
|
||||
|
||||
def testShellFolder(self):
|
||||
sf = shell.SHGetDesktopFolder()
|
||||
names_1 = []
|
||||
for i in sf: # Magically calls EnumObjects
|
||||
name = sf.GetDisplayNameOf(i, SHGDN_NORMAL)
|
||||
names_1.append(name)
|
||||
|
||||
# And get the enumerator manually
|
||||
enum = sf.EnumObjects(0, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN)
|
||||
names_2 = []
|
||||
for i in enum:
|
||||
name = sf.GetDisplayNameOf(i, SHGDN_NORMAL)
|
||||
names_2.append(name)
|
||||
names_1.sort()
|
||||
names_2.sort()
|
||||
self.assertEqual(names_1, names_2)
|
||||
|
||||
class PIDLTester(win32com.test.util.TestCase):
|
||||
def _rtPIDL(self, pidl):
|
||||
pidl_str = shell.PIDLAsString(pidl)
|
||||
pidl_rt = shell.StringAsPIDL(pidl_str)
|
||||
self.assertEqual(pidl_rt, pidl)
|
||||
pidl_str_rt = shell.PIDLAsString(pidl_rt)
|
||||
self.assertEqual(pidl_str_rt, pidl_str)
|
||||
|
||||
def _rtCIDA(self, parent, kids):
|
||||
cida = parent, kids
|
||||
cida_str = shell.CIDAAsString(cida)
|
||||
cida_rt = shell.StringAsCIDA(cida_str)
|
||||
self.assertEqual(cida, cida_rt)
|
||||
cida_str_rt = shell.CIDAAsString(cida_rt)
|
||||
self.assertEqual(cida_str_rt, cida_str)
|
||||
|
||||
def testPIDL(self):
|
||||
# A PIDL of "\1" is: cb pidl cb
|
||||
expect = str2bytes("\03\00" "\1" "\0\0")
|
||||
self.assertEqual(shell.PIDLAsString([str2bytes("\1")]), expect)
|
||||
self._rtPIDL([str2bytes("\0")])
|
||||
self._rtPIDL([str2bytes("\1"), str2bytes("\2"), str2bytes("\3")])
|
||||
self._rtPIDL([str2bytes("\0") * 2048] * 2048)
|
||||
# PIDL must be a list
|
||||
self.assertRaises(TypeError, shell.PIDLAsString, "foo")
|
||||
|
||||
def testCIDA(self):
|
||||
self._rtCIDA([str2bytes("\0")], [ [str2bytes("\0")] ])
|
||||
self._rtCIDA([str2bytes("\1")], [ [str2bytes("\2")] ])
|
||||
self._rtCIDA([str2bytes("\0")], [ [str2bytes("\0")], [str2bytes("\1")], [str2bytes("\2")] ])
|
||||
|
||||
def testBadShortPIDL(self):
|
||||
# A too-short child element: cb pidl cb
|
||||
pidl = str2bytes("\01\00" "\1")
|
||||
self.assertRaises(ValueError, shell.StringAsPIDL, pidl)
|
||||
|
||||
# ack - tried to test too long PIDLs, but a len of 0xFFFF may not
|
||||
# always fail.
|
||||
|
||||
class FILEGROUPDESCRIPTORTester(win32com.test.util.TestCase):
|
||||
def _getTestTimes(self):
|
||||
if issubclass(pywintypes.TimeType, datetime.datetime):
|
||||
ctime = win32timezone.now()
|
||||
atime = ctime + datetime.timedelta(seconds=1)
|
||||
wtime = atime + datetime.timedelta(seconds=1)
|
||||
else:
|
||||
ctime = pywintypes.Time(11)
|
||||
atime = pywintypes.Time(12)
|
||||
wtime = pywintypes.Time(13)
|
||||
return ctime, atime, wtime
|
||||
|
||||
def _testRT(self, fd):
|
||||
fgd_string = shell.FILEGROUPDESCRIPTORAsString([fd])
|
||||
fd2 = shell.StringAsFILEGROUPDESCRIPTOR(fgd_string)[0]
|
||||
|
||||
fd = fd.copy()
|
||||
fd2 = fd2.copy()
|
||||
|
||||
# The returned objects *always* have dwFlags and cFileName.
|
||||
if 'dwFlags' not in fd:
|
||||
del fd2['dwFlags']
|
||||
if 'cFileName' not in fd:
|
||||
self.assertEqual(fd2['cFileName'], '')
|
||||
del fd2['cFileName']
|
||||
|
||||
self.assertEqual(fd, fd2)
|
||||
|
||||
def _testSimple(self, make_unicode):
|
||||
fgd = shell.FILEGROUPDESCRIPTORAsString([], make_unicode)
|
||||
header = struct.pack("i", 0)
|
||||
self.assertEqual(header, fgd[:len(header)])
|
||||
self._testRT(dict())
|
||||
d = dict()
|
||||
fgd = shell.FILEGROUPDESCRIPTORAsString([d], make_unicode)
|
||||
header = struct.pack("i", 1)
|
||||
self.assertEqual(header, fgd[:len(header)])
|
||||
self._testRT(d)
|
||||
|
||||
def testSimpleBytes(self):
|
||||
self._testSimple(False)
|
||||
|
||||
def testSimpleUnicode(self):
|
||||
self._testSimple(True)
|
||||
|
||||
def testComplex(self):
|
||||
clsid = pythoncom.MakeIID("{CD637886-DB8B-4b04-98B5-25731E1495BE}")
|
||||
ctime, atime, wtime = self._getTestTimes()
|
||||
d = dict(cFileName="foo.txt",
|
||||
clsid=clsid,
|
||||
sizel=(1,2),
|
||||
pointl=(3,4),
|
||||
dwFileAttributes = win32con.FILE_ATTRIBUTE_NORMAL,
|
||||
ftCreationTime=ctime,
|
||||
ftLastAccessTime=atime,
|
||||
ftLastWriteTime=wtime,
|
||||
nFileSize=sys_maxsize + 1)
|
||||
self._testRT(d)
|
||||
|
||||
def testUnicode(self):
|
||||
# exercise a bug fixed in build 210 - multiple unicode objects failed.
|
||||
ctime, atime, wtime = self._getTestTimes()
|
||||
d = [dict(cFileName="foo.txt",
|
||||
sizel=(1,2),
|
||||
pointl=(3,4),
|
||||
dwFileAttributes = win32con.FILE_ATTRIBUTE_NORMAL,
|
||||
ftCreationTime=ctime,
|
||||
ftLastAccessTime=atime,
|
||||
ftLastWriteTime=wtime,
|
||||
nFileSize=sys_maxsize + 1),
|
||||
dict(cFileName="foo2.txt",
|
||||
sizel=(1,2),
|
||||
pointl=(3,4),
|
||||
dwFileAttributes = win32con.FILE_ATTRIBUTE_NORMAL,
|
||||
ftCreationTime=ctime,
|
||||
ftLastAccessTime=atime,
|
||||
ftLastWriteTime=wtime,
|
||||
nFileSize=sys_maxsize + 1),
|
||||
dict(cFileName="foo\xa9.txt",
|
||||
sizel=(1,2),
|
||||
pointl=(3,4),
|
||||
dwFileAttributes = win32con.FILE_ATTRIBUTE_NORMAL,
|
||||
ftCreationTime=ctime,
|
||||
ftLastAccessTime=atime,
|
||||
ftLastWriteTime=wtime,
|
||||
nFileSize=sys_maxsize + 1),
|
||||
]
|
||||
s = shell.FILEGROUPDESCRIPTORAsString(d, 1)
|
||||
d2 = shell.StringAsFILEGROUPDESCRIPTOR(s)
|
||||
# clobber 'dwFlags' - they are not expected to be identical
|
||||
for t in d2:
|
||||
del t['dwFlags']
|
||||
self.assertEqual(d, d2)
|
||||
|
||||
class FileOperationTester(win32com.test.util.TestCase):
|
||||
def setUp(self):
|
||||
import tempfile
|
||||
self.src_name = os.path.join(tempfile.gettempdir(), "pywin32_testshell")
|
||||
self.dest_name = os.path.join(tempfile.gettempdir(), "pywin32_testshell_dest")
|
||||
self.test_data = str2bytes("Hello from\0Python")
|
||||
f=open(self.src_name, "wb")
|
||||
f.write(self.test_data)
|
||||
f.close()
|
||||
try:
|
||||
os.unlink(self.dest_name)
|
||||
except os.error:
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
for fname in (self.src_name, self.dest_name):
|
||||
if os.path.isfile(fname):
|
||||
os.unlink(fname)
|
||||
|
||||
def testCopy(self):
|
||||
s = (0, # hwnd,
|
||||
FO_COPY, #operation
|
||||
self.src_name,
|
||||
self.dest_name)
|
||||
|
||||
rc, aborted = shell.SHFileOperation(s)
|
||||
self.failUnless(not aborted)
|
||||
self.failUnlessEqual(0, rc)
|
||||
self.failUnless(os.path.isfile(self.src_name))
|
||||
self.failUnless(os.path.isfile(self.dest_name))
|
||||
|
||||
def testRename(self):
|
||||
s = (0, # hwnd,
|
||||
FO_RENAME, #operation
|
||||
self.src_name,
|
||||
self.dest_name)
|
||||
rc, aborted = shell.SHFileOperation(s)
|
||||
self.failUnless(not aborted)
|
||||
self.failUnlessEqual(0, rc)
|
||||
self.failUnless(os.path.isfile(self.dest_name))
|
||||
self.failUnless(not os.path.isfile(self.src_name))
|
||||
|
||||
def testMove(self):
|
||||
s = (0, # hwnd,
|
||||
FO_MOVE, #operation
|
||||
self.src_name,
|
||||
self.dest_name)
|
||||
rc, aborted = shell.SHFileOperation(s)
|
||||
self.failUnless(not aborted)
|
||||
self.failUnlessEqual(0, rc)
|
||||
self.failUnless(os.path.isfile(self.dest_name))
|
||||
self.failUnless(not os.path.isfile(self.src_name))
|
||||
|
||||
def testDelete(self):
|
||||
s = (0, # hwnd,
|
||||
FO_DELETE, #operation
|
||||
self.src_name, None,
|
||||
FOF_NOCONFIRMATION)
|
||||
rc, aborted = shell.SHFileOperation(s)
|
||||
self.failUnless(not aborted)
|
||||
self.failUnlessEqual(0, rc)
|
||||
self.failUnless(not os.path.isfile(self.src_name))
|
||||
|
||||
if __name__=='__main__':
|
||||
win32com.test.util.testmain()
|
62
venv/Lib/site-packages/win32com/test/testStorage.py
Normal file
62
venv/Lib/site-packages/win32com/test/testStorage.py
Normal file
|
@ -0,0 +1,62 @@
|
|||
from win32com import storagecon
|
||||
import pythoncom, os, win32api
|
||||
import win32com.test.util
|
||||
|
||||
import unittest
|
||||
|
||||
class TestEnum(win32com.test.util.TestCase):
|
||||
def testit(self):
|
||||
fname, tmp = win32api.GetTempFileName(win32api.GetTempPath(),'stg')
|
||||
m=storagecon.STGM_READWRITE | storagecon.STGM_SHARE_EXCLUSIVE
|
||||
## file, mode, format, attrs (always 0), IID (IStorage or IPropertySetStorage, storage options(only used with STGFMT_DOCFILE)
|
||||
pss=pythoncom.StgOpenStorageEx(fname, m, storagecon.STGFMT_FILE, 0 , pythoncom.IID_IPropertySetStorage)
|
||||
### {"Version":2,"reserved":0,"SectorSize":512,"TemplateFile":u'somefilename'})
|
||||
|
||||
## FMTID_SummaryInformation FMTID_DocSummaryInformation FMTID_UserDefinedProperties
|
||||
psuser=pss.Create(pythoncom.FMTID_UserDefinedProperties,
|
||||
pythoncom.IID_IPropertySetStorage,
|
||||
storagecon.PROPSETFLAG_DEFAULT,
|
||||
storagecon.STGM_READWRITE|storagecon.STGM_CREATE|storagecon.STGM_SHARE_EXCLUSIVE) ## its very picky about flag combinations!
|
||||
psuser.WriteMultiple((3,4),('hey','bubba'))
|
||||
psuser.WritePropertyNames((3,4),('property3','property4'))
|
||||
expected_summaries = []
|
||||
expected_summaries.append( ('property3', 3, pythoncom.VT_BSTR))
|
||||
expected_summaries.append( ('property4', 4, pythoncom.VT_BSTR))
|
||||
psuser=None
|
||||
|
||||
pssum=pss.Create(pythoncom.FMTID_SummaryInformation,
|
||||
pythoncom.IID_IPropertySetStorage,
|
||||
storagecon.PROPSETFLAG_DEFAULT,
|
||||
storagecon.STGM_READWRITE|storagecon.STGM_CREATE|storagecon.STGM_SHARE_EXCLUSIVE)
|
||||
pssum.WriteMultiple((storagecon.PIDSI_AUTHOR,storagecon.PIDSI_COMMENTS),('me', 'comment'))
|
||||
|
||||
pssum=None
|
||||
pss=None ## doesn't seem to be a close or release method, and you can't even reopen it from the same process until previous object is gone
|
||||
|
||||
pssread=pythoncom.StgOpenStorageEx(fname, storagecon.STGM_READ|storagecon.STGM_SHARE_EXCLUSIVE, storagecon.STGFMT_FILE, 0 , pythoncom.IID_IPropertySetStorage)
|
||||
found_summaries = []
|
||||
for psstat in pssread:
|
||||
ps=pssread.Open(psstat[0],storagecon.STGM_READ|storagecon.STGM_SHARE_EXCLUSIVE)
|
||||
for p in ps:
|
||||
p_val = ps.ReadMultiple((p[1],))[0]
|
||||
if (p[1]==storagecon.PIDSI_AUTHOR and p_val=='me') or \
|
||||
(p[1]==storagecon.PIDSI_COMMENTS and p_val=='comment'):
|
||||
pass
|
||||
else:
|
||||
self.fail("Uxexpected property %s/%s" % (p, p_val))
|
||||
ps=None
|
||||
## FMTID_UserDefinedProperties can't exist without FMTID_DocSummaryInformation, and isn't returned independently from Enum
|
||||
## also can't be open at same time
|
||||
if psstat[0]==pythoncom.FMTID_DocSummaryInformation:
|
||||
ps=pssread.Open(pythoncom.FMTID_UserDefinedProperties,storagecon.STGM_READ|storagecon.STGM_SHARE_EXCLUSIVE)
|
||||
for p in ps:
|
||||
found_summaries.append(p)
|
||||
ps=None
|
||||
psread=None
|
||||
expected_summaries.sort()
|
||||
found_summaries.sort()
|
||||
self.assertEqual(expected_summaries, found_summaries)
|
||||
|
||||
if __name__=='__main__':
|
||||
unittest.main()
|
||||
|
131
venv/Lib/site-packages/win32com/test/testStreams.py
Normal file
131
venv/Lib/site-packages/win32com/test/testStreams.py
Normal file
|
@ -0,0 +1,131 @@
|
|||
import pythoncom
|
||||
import win32com.server.util
|
||||
import win32com.test.util
|
||||
|
||||
import unittest
|
||||
from pywin32_testutil import str2bytes
|
||||
|
||||
class Persists:
|
||||
_public_methods_ = [ 'GetClassID', 'IsDirty', 'Load', 'Save',
|
||||
'GetSizeMax', 'InitNew' ]
|
||||
_com_interfaces_ = [ pythoncom.IID_IPersistStreamInit ]
|
||||
def __init__(self):
|
||||
self.data = str2bytes("abcdefg")
|
||||
self.dirty = 1
|
||||
def GetClassID(self):
|
||||
return pythoncom.IID_NULL
|
||||
def IsDirty(self):
|
||||
return self.dirty
|
||||
def Load(self, stream):
|
||||
self.data = stream.Read(26)
|
||||
def Save(self, stream, clearDirty):
|
||||
stream.Write(self.data)
|
||||
if clearDirty:
|
||||
self.dirty = 0
|
||||
def GetSizeMax(self):
|
||||
return 1024
|
||||
|
||||
def InitNew(self):
|
||||
pass
|
||||
|
||||
|
||||
class Stream:
|
||||
_public_methods_ = [ 'Read', 'Write', 'Seek' ]
|
||||
_com_interfaces_ = [ pythoncom.IID_IStream ]
|
||||
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
self.index = 0
|
||||
|
||||
def Read(self, amount):
|
||||
result = self.data[self.index : self.index + amount]
|
||||
self.index = self.index + amount
|
||||
return result
|
||||
|
||||
def Write(self, data):
|
||||
self.data = data
|
||||
self.index = 0
|
||||
return len(data)
|
||||
|
||||
def Seek(self, dist, origin):
|
||||
if origin==pythoncom.STREAM_SEEK_SET:
|
||||
self.index = dist
|
||||
elif origin==pythoncom.STREAM_SEEK_CUR:
|
||||
self.index = self.index + dist
|
||||
elif origin==pythoncom.STREAM_SEEK_END:
|
||||
self.index = len(self.data)+dist
|
||||
else:
|
||||
raise ValueError('Unknown Seek type: ' +str(origin))
|
||||
if self.index < 0:
|
||||
self.index = 0
|
||||
else:
|
||||
self.index = min(self.index, len(self.data))
|
||||
return self.index
|
||||
|
||||
class BadStream(Stream):
|
||||
""" PyGStream::Read could formerly overflow buffer if the python implementation
|
||||
returned more data than requested.
|
||||
"""
|
||||
def Read(self, amount):
|
||||
return str2bytes('x')*(amount+1)
|
||||
|
||||
class StreamTest(win32com.test.util.TestCase):
|
||||
def _readWrite(self, data, write_stream, read_stream = None):
|
||||
if read_stream is None: read_stream = write_stream
|
||||
write_stream.Write(data)
|
||||
read_stream.Seek(0, pythoncom.STREAM_SEEK_SET)
|
||||
got = read_stream.Read(len(data))
|
||||
self.assertEqual(data, got)
|
||||
read_stream.Seek(1, pythoncom.STREAM_SEEK_SET)
|
||||
got = read_stream.Read(len(data)-2)
|
||||
self.assertEqual(data[1:-1], got)
|
||||
|
||||
def testit(self):
|
||||
mydata = str2bytes('abcdefghijklmnopqrstuvwxyz')
|
||||
|
||||
# First test the objects just as Python objects...
|
||||
s = Stream(mydata)
|
||||
p = Persists()
|
||||
|
||||
p.Load(s)
|
||||
p.Save(s, 0)
|
||||
self.assertEqual(s.data, mydata)
|
||||
|
||||
# Wrap the Python objects as COM objects, and make the calls as if
|
||||
# they were non-Python COM objects.
|
||||
s2 = win32com.server.util.wrap(s, pythoncom.IID_IStream)
|
||||
p2 = win32com.server.util.wrap(p, pythoncom.IID_IPersistStreamInit)
|
||||
|
||||
self._readWrite(mydata, s, s)
|
||||
self._readWrite(mydata, s, s2)
|
||||
self._readWrite(mydata, s2, s)
|
||||
self._readWrite(mydata, s2, s2)
|
||||
|
||||
self._readWrite(str2bytes("string with\0a NULL"), s2, s2)
|
||||
# reset the stream
|
||||
s.Write(mydata)
|
||||
p2.Load(s2)
|
||||
p2.Save(s2, 0)
|
||||
self.assertEqual(s.data, mydata)
|
||||
|
||||
def testseek(self):
|
||||
s = Stream(str2bytes('yo'))
|
||||
s = win32com.server.util.wrap(s, pythoncom.IID_IStream)
|
||||
# we used to die in py3k passing a value > 32bits
|
||||
s.Seek(0x100000000, pythoncom.STREAM_SEEK_SET)
|
||||
|
||||
def testerrors(self):
|
||||
# setup a test logger to capture tracebacks etc.
|
||||
records, old_log = win32com.test.util.setup_test_logger()
|
||||
## check for buffer overflow in Read method
|
||||
badstream = BadStream('Check for buffer overflow')
|
||||
badstream2 = win32com.server.util.wrap(badstream, pythoncom.IID_IStream)
|
||||
self.assertRaises(pythoncom.com_error, badstream2.Read, 10)
|
||||
win32com.test.util.restore_test_logger(old_log)
|
||||
# expecting 2 pythoncom errors to have been raised by the gateways.
|
||||
self.assertEqual(len(records), 2)
|
||||
self.failUnless(records[0].msg.startswith('pythoncom error'))
|
||||
self.failUnless(records[1].msg.startswith('pythoncom error'))
|
||||
|
||||
if __name__=='__main__':
|
||||
unittest.main()
|
17
venv/Lib/site-packages/win32com/test/testWMI.py
Normal file
17
venv/Lib/site-packages/win32com/test/testWMI.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
from win32com.client import GetObject
|
||||
import win32com.test.util
|
||||
|
||||
import unittest
|
||||
|
||||
class Simple(win32com.test.util.TestCase):
|
||||
def testit(self):
|
||||
cses = GetObject("WinMgMts:").InstancesOf("Win32_Process")
|
||||
vals = []
|
||||
for cs in cses:
|
||||
val = cs.Properties_("Caption").Value
|
||||
vals.append(val)
|
||||
self.failIf(len(vals)<5, "We only found %d processes!" % len(vals))
|
||||
|
||||
if __name__=='__main__':
|
||||
unittest.main()
|
||||
|
263
venv/Lib/site-packages/win32com/test/testall.py
Normal file
263
venv/Lib/site-packages/win32com/test/testall.py
Normal file
|
@ -0,0 +1,263 @@
|
|||
import sys, os, string, re
|
||||
import pythoncom
|
||||
import win32com.client
|
||||
from win32com.test.util import CheckClean, TestCase, \
|
||||
CapturingFunctionTestCase, ShellTestCase, \
|
||||
TestLoader, TestRunner, RegisterPythonServer
|
||||
import traceback
|
||||
import getopt
|
||||
|
||||
import unittest
|
||||
|
||||
verbosity = 1 # default unittest verbosity.
|
||||
|
||||
try:
|
||||
this_file = __file__
|
||||
except NameError:
|
||||
this_file = sys.argv[0]
|
||||
|
||||
def GenerateAndRunOldStyle():
|
||||
from . import GenTestScripts
|
||||
GenTestScripts.GenerateAll()
|
||||
try:
|
||||
pass #
|
||||
finally:
|
||||
GenTestScripts.CleanAll()
|
||||
|
||||
def CleanGenerated():
|
||||
import win32com, shutil
|
||||
if os.path.isdir(win32com.__gen_path__):
|
||||
if verbosity > 1:
|
||||
print("Deleting files from %s" % (win32com.__gen_path__))
|
||||
shutil.rmtree(win32com.__gen_path__)
|
||||
import win32com.client.gencache
|
||||
win32com.client.gencache.__init__() # Reset
|
||||
|
||||
def RemoveRefCountOutput(data):
|
||||
while 1:
|
||||
last_line_pos = data.rfind("\n")
|
||||
if not re.match("\[\d+ refs\]", data[last_line_pos+1:]):
|
||||
break
|
||||
if last_line_pos < 0:
|
||||
# All the output
|
||||
return ''
|
||||
data = data[:last_line_pos]
|
||||
|
||||
return data
|
||||
|
||||
def ExecuteSilentlyIfOK(cmd, testcase):
|
||||
f = os.popen(cmd)
|
||||
data = f.read().strip()
|
||||
rc = f.close()
|
||||
if rc:
|
||||
print(data)
|
||||
testcase.fail("Executing '%s' failed (%d)" % (cmd, rc))
|
||||
# for "_d" builds, strip the '[xxx refs]' line
|
||||
return RemoveRefCountOutput(data)
|
||||
|
||||
class PyCOMTest(TestCase):
|
||||
no_leak_tests = True # done by the test itself
|
||||
def testit(self):
|
||||
# Check that the item is registered, so we get the correct
|
||||
# 'skipped' behaviour (and recorded as such) rather than either
|
||||
# error or silence due to non-registration.
|
||||
RegisterPythonServer(os.path.join(os.path.dirname(__file__), '..', "servers", "test_pycomtest.py"),
|
||||
"Python.Test.PyCOMTest")
|
||||
|
||||
# Execute testPyComTest in its own process so it can play
|
||||
# with the Python thread state
|
||||
fname = os.path.join(os.path.dirname(this_file), "testPyComTest.py")
|
||||
cmd = '%s "%s" -q 2>&1' % (sys.executable, fname)
|
||||
data = ExecuteSilentlyIfOK(cmd, self)
|
||||
|
||||
class PippoTest(TestCase):
|
||||
def testit(self):
|
||||
# Check we are registered before spawning the process.
|
||||
from win32com.test import pippo_server
|
||||
RegisterPythonServer(pippo_server.__file__, "Python.Test.Pippo")
|
||||
|
||||
python = sys.executable
|
||||
fname = os.path.join(os.path.dirname(this_file), "testPippo.py")
|
||||
cmd = '%s "%s" 2>&1' % (python, fname)
|
||||
ExecuteSilentlyIfOK(cmd, self)
|
||||
|
||||
# This is a list of "win32com.test.???" module names, optionally with a
|
||||
# function in that module if the module isn't unitest based...
|
||||
unittest_modules = [
|
||||
# Level 1 tests.
|
||||
"""testIterators testvbscript_regexp testStorage
|
||||
testStreams testWMI policySemantics testShell testROT
|
||||
testAXScript testxslt testDictionary testCollections
|
||||
testServers errorSemantics.test testvb testArrays
|
||||
testClipboard testMarshal
|
||||
""".split(),
|
||||
# Level 2 tests.
|
||||
"""testMSOffice.TestAll testMSOfficeEvents.test testAccess.test
|
||||
testExplorer.TestAll testExchange.test
|
||||
""".split(),
|
||||
# Level 3 tests.
|
||||
"""testmakepy.TestAll
|
||||
""".split()
|
||||
]
|
||||
|
||||
# A list of other unittest modules we use - these are fully qualified module
|
||||
# names and the module is assumed to be unittest based.
|
||||
unittest_other_modules = [
|
||||
# Level 1 tests.
|
||||
"""win32com.directsound.test.ds_test
|
||||
""".split(),
|
||||
# Level 2 tests.
|
||||
[],
|
||||
# Level 3 tests.
|
||||
[]
|
||||
]
|
||||
|
||||
|
||||
output_checked_programs = [
|
||||
# Level 1 tests.
|
||||
[
|
||||
("cscript.exe /nologo //E:vbscript testInterp.vbs", "VBScript test worked OK"),
|
||||
("cscript.exe /nologo //E:vbscript testDictionary.vbs",
|
||||
"VBScript has successfully tested Python.Dictionary"),
|
||||
],
|
||||
# Level 2 tests.
|
||||
[
|
||||
],
|
||||
# Level 3 tests
|
||||
[
|
||||
],
|
||||
]
|
||||
|
||||
custom_test_cases = [
|
||||
# Level 1 tests.
|
||||
[
|
||||
PyCOMTest,
|
||||
PippoTest,
|
||||
],
|
||||
# Level 2 tests.
|
||||
[
|
||||
],
|
||||
# Level 3 tests
|
||||
[
|
||||
],
|
||||
]
|
||||
|
||||
def get_test_mod_and_func(test_name, import_failures):
|
||||
if test_name.find(".")>0:
|
||||
mod_name, func_name = test_name.split(".")
|
||||
else:
|
||||
mod_name = test_name
|
||||
func_name = None
|
||||
fq_mod_name = "win32com.test." + mod_name
|
||||
try:
|
||||
__import__(fq_mod_name)
|
||||
mod = sys.modules[fq_mod_name]
|
||||
except:
|
||||
import_failures.append((mod_name, sys.exc_info()[:2]))
|
||||
return None, None
|
||||
if func_name is None:
|
||||
func = None
|
||||
else:
|
||||
func = getattr(mod, func_name)
|
||||
return mod, func
|
||||
|
||||
# Return a test suite all loaded with the tests we want to run
|
||||
def make_test_suite(test_level = 1):
|
||||
suite = unittest.TestSuite()
|
||||
import_failures = []
|
||||
loader = TestLoader()
|
||||
for i in range(testLevel):
|
||||
for mod_name in unittest_modules[i]:
|
||||
mod, func = get_test_mod_and_func(mod_name, import_failures)
|
||||
if mod is None:
|
||||
continue
|
||||
if func is not None:
|
||||
test = CapturingFunctionTestCase(func, description=mod_name)
|
||||
else:
|
||||
if hasattr(mod, "suite"):
|
||||
test = mod.suite()
|
||||
else:
|
||||
test = loader.loadTestsFromModule(mod)
|
||||
assert test.countTestCases() > 0, "No tests loaded from %r" % mod
|
||||
suite.addTest(test)
|
||||
for cmd, output in output_checked_programs[i]:
|
||||
suite.addTest(ShellTestCase(cmd, output))
|
||||
|
||||
for test_class in custom_test_cases[i]:
|
||||
suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(test_class))
|
||||
# other "normal" unittest modules.
|
||||
for i in range(testLevel):
|
||||
for mod_name in unittest_other_modules[i]:
|
||||
try:
|
||||
__import__(mod_name)
|
||||
except:
|
||||
import_failures.append((mod_name, sys.exc_info()[:2]))
|
||||
continue
|
||||
|
||||
mod = sys.modules[mod_name]
|
||||
if hasattr(mod, "suite"):
|
||||
test = mod.suite()
|
||||
else:
|
||||
test = loader.loadTestsFromModule(mod)
|
||||
assert test.countTestCases() > 0, "No tests loaded from %r" % mod
|
||||
suite.addTest(test)
|
||||
|
||||
return suite, import_failures
|
||||
|
||||
def usage(why):
|
||||
print(why)
|
||||
print()
|
||||
print("win32com test suite")
|
||||
print("usage: testall [-v] test_level")
|
||||
print(" where test_level is an integer 1-3. Level 1 tests are quick,")
|
||||
print(" level 2 tests invoke Word, IE etc, level 3 take ages!")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__=='__main__':
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "v")
|
||||
except getopt.error as why:
|
||||
usage(why)
|
||||
for opt, val in opts:
|
||||
if opt=='-v':
|
||||
verbosity += 1
|
||||
testLevel = 1 # default to quick test
|
||||
test_names = []
|
||||
for arg in args:
|
||||
try:
|
||||
testLevel = int(arg)
|
||||
if testLevel < 0 or testLevel > 3:
|
||||
raise ValueError("Only levels 1-3 are supported")
|
||||
except ValueError:
|
||||
test_names.append(arg)
|
||||
if test_names:
|
||||
usage("Test names are not supported yet")
|
||||
CleanGenerated()
|
||||
|
||||
suite, import_failures = make_test_suite(testLevel)
|
||||
if verbosity:
|
||||
if hasattr(sys, "gettotalrefcount"):
|
||||
print("This is a debug build - memory leak tests will also be run.")
|
||||
print("These tests may take *many* minutes to run - be patient!")
|
||||
print("(running from python.exe will avoid these leak tests)")
|
||||
print("Executing level %d tests - %d test cases will be run" \
|
||||
% (testLevel, suite.countTestCases()))
|
||||
if verbosity==1 and suite.countTestCases() < 70:
|
||||
# A little row of markers so the dots show how close to finished
|
||||
print('|' * suite.countTestCases())
|
||||
testRunner = TestRunner(verbosity=verbosity)
|
||||
testResult = testRunner.run(suite)
|
||||
if import_failures:
|
||||
testResult.stream.writeln("*** The following test modules could not be imported ***")
|
||||
for mod_name, (exc_type, exc_val) in import_failures:
|
||||
desc = '\n'.join(traceback.format_exception_only(exc_type, exc_val))
|
||||
testResult.stream.write("%s: %s" % (mod_name, desc))
|
||||
testResult.stream.writeln("*** %d test(s) could not be run ***" % len(import_failures))
|
||||
|
||||
# re-print unit-test error here so it is noticed
|
||||
if not testResult.wasSuccessful():
|
||||
print("*" * 20, "- unittest tests FAILED")
|
||||
|
||||
CheckClean()
|
||||
pythoncom.CoUninitialize()
|
||||
CleanGenerated()
|
53
venv/Lib/site-packages/win32com/test/testmakepy.py
Normal file
53
venv/Lib/site-packages/win32com/test/testmakepy.py
Normal file
|
@ -0,0 +1,53 @@
|
|||
# Test makepy - try and run it over every OCX in the windows system directory.
|
||||
|
||||
import sys
|
||||
import win32api
|
||||
import traceback
|
||||
import glob
|
||||
import os
|
||||
import traceback
|
||||
|
||||
import win32com.test.util
|
||||
from win32com.client import makepy, selecttlb, gencache
|
||||
import pythoncom
|
||||
import winerror
|
||||
|
||||
def TestBuildAll(verbose = 1):
|
||||
num = 0
|
||||
tlbInfos = selecttlb.EnumTlbs()
|
||||
for info in tlbInfos:
|
||||
if verbose:
|
||||
print("%s (%s)" % (info.desc, info.dll))
|
||||
try:
|
||||
makepy.GenerateFromTypeLibSpec(info)
|
||||
# sys.stderr.write("Attr typeflags for coclass referenced object %s=%d (%d), typekind=%d\n" % (name, refAttr.wTypeFlags, refAttr.wTypeFlags & pythoncom.TYPEFLAG_FDUAL,refAttr.typekind))
|
||||
num += 1
|
||||
except pythoncom.com_error as details:
|
||||
# Ignore these 2 errors, as the are very common and can obscure
|
||||
# useful warnings.
|
||||
if details.hresult not in [winerror.TYPE_E_CANTLOADLIBRARY,
|
||||
winerror.TYPE_E_LIBNOTREGISTERED]:
|
||||
print("** COM error on", info.desc)
|
||||
print(details)
|
||||
except KeyboardInterrupt:
|
||||
print("Interrupted!")
|
||||
raise KeyboardInterrupt
|
||||
except:
|
||||
print("Failed:", info.desc)
|
||||
traceback.print_exc()
|
||||
if makepy.bForDemandDefault:
|
||||
# This only builds enums etc by default - build each
|
||||
# interface manually
|
||||
tinfo = (info.clsid, info.lcid, info.major, info.minor)
|
||||
mod = gencache.EnsureModule(info.clsid, info.lcid, info.major, info.minor)
|
||||
for name in mod.NamesToIIDMap.keys():
|
||||
makepy.GenerateChildFromTypeLibSpec(name, tinfo)
|
||||
return num
|
||||
|
||||
def TestAll(verbose = 0):
|
||||
num = TestBuildAll(verbose)
|
||||
print("Generated and imported", num, "modules")
|
||||
win32com.test.util.CheckClean()
|
||||
|
||||
if __name__=='__main__':
|
||||
TestAll("-q" not in sys.argv)
|
510
venv/Lib/site-packages/win32com/test/testvb.py
Normal file
510
venv/Lib/site-packages/win32com/test/testvb.py
Normal file
|
@ -0,0 +1,510 @@
|
|||
# Test code for a VB Program.
|
||||
#
|
||||
# This requires the PythonCOM VB Test Harness.
|
||||
#
|
||||
|
||||
import sys
|
||||
import winerror
|
||||
import pythoncom, win32com.client, win32com.client.dynamic, win32com.client.gencache
|
||||
from win32com.server.util import NewCollection, wrap
|
||||
from win32com.test import util
|
||||
from pywin32_testutil import str2memory
|
||||
|
||||
import traceback
|
||||
|
||||
# for debugging
|
||||
useDispatcher = None
|
||||
## import win32com.server.dispatcher
|
||||
## useDispatcher = win32com.server.dispatcher.DefaultDebugDispatcher
|
||||
|
||||
error = RuntimeError
|
||||
|
||||
# Set up a COM object that VB will do some callbacks on. This is used
|
||||
# to test byref params for gateway IDispatch.
|
||||
class TestObject:
|
||||
_public_methods_ = ["CallbackVoidOneByRef","CallbackResultOneByRef", "CallbackVoidTwoByRef",
|
||||
"CallbackString","CallbackResultOneByRefButReturnNone",
|
||||
"CallbackVoidOneByRefButReturnNone",
|
||||
"CallbackArrayResult", "CallbackArrayResultOneArrayByRef",
|
||||
"CallbackArrayResultWrongSize"
|
||||
]
|
||||
def CallbackVoidOneByRef(self, intVal):
|
||||
return intVal + 1
|
||||
def CallbackResultOneByRef(self, intVal):
|
||||
return intVal, intVal + 1
|
||||
def CallbackVoidTwoByRef(self, int1, int2):
|
||||
return int1+int2, int1-int2
|
||||
def CallbackString(self, strVal):
|
||||
return 0, strVal + " has visited Python"
|
||||
def CallbackArrayResult(self, arrayVal):
|
||||
ret = []
|
||||
for i in arrayVal:
|
||||
ret.append(i+1)
|
||||
# returning as a list forces it be processed as a single result
|
||||
# (rather than a tuple, where it may be interpreted as
|
||||
# multiple results for byref unpacking)
|
||||
return ret
|
||||
def CallbackArrayResultWrongSize(self, arrayVal):
|
||||
return list(arrayVal[:-1])
|
||||
def CallbackArrayResultOneArrayByRef(self, arrayVal):
|
||||
ret = []
|
||||
for i in arrayVal:
|
||||
ret.append(i+1)
|
||||
# See above for list processing.
|
||||
return list(arrayVal), ret
|
||||
|
||||
def CallbackResultOneByRefButReturnNone(self, intVal):
|
||||
return
|
||||
def CallbackVoidOneByRefButReturnNone(self, intVal):
|
||||
return
|
||||
|
||||
def TestVB( vbtest, bUseGenerated ):
|
||||
vbtest.LongProperty = -1
|
||||
if vbtest.LongProperty != -1:
|
||||
raise error("Could not set the long property correctly.")
|
||||
vbtest.IntProperty = 10
|
||||
if vbtest.IntProperty != 10:
|
||||
raise error("Could not set the integer property correctly.")
|
||||
vbtest.VariantProperty = 10
|
||||
if vbtest.VariantProperty != 10:
|
||||
raise error("Could not set the variant integer property correctly.")
|
||||
vbtest.VariantProperty = str2memory('raw\0data')
|
||||
if vbtest.VariantProperty != str2memory('raw\0data'):
|
||||
raise error("Could not set the variant buffer property correctly.")
|
||||
vbtest.StringProperty = "Hello from Python"
|
||||
if vbtest.StringProperty != "Hello from Python":
|
||||
raise error("Could not set the string property correctly.")
|
||||
vbtest.VariantProperty = "Hello from Python"
|
||||
if vbtest.VariantProperty != "Hello from Python":
|
||||
raise error("Could not set the variant string property correctly.")
|
||||
vbtest.VariantProperty = (1.0, 2.0, 3.0)
|
||||
if vbtest.VariantProperty != (1.0, 2.0, 3.0):
|
||||
raise error("Could not set the variant property to an array of floats correctly - '%s'." % (vbtest.VariantProperty,))
|
||||
|
||||
TestArrays(vbtest, bUseGenerated)
|
||||
TestStructs(vbtest)
|
||||
TestCollections(vbtest)
|
||||
|
||||
assert vbtest.TakeByValObject(vbtest)==vbtest
|
||||
|
||||
# Python doesnt support PUTREF properties without a typeref
|
||||
# (although we could)
|
||||
if bUseGenerated:
|
||||
ob = vbtest.TakeByRefObject(vbtest)
|
||||
assert ob[0]==vbtest and ob[1]==vbtest
|
||||
|
||||
# A property that only has PUTREF defined.
|
||||
vbtest.VariantPutref = vbtest
|
||||
if vbtest.VariantPutref._oleobj_!= vbtest._oleobj_:
|
||||
raise error("Could not set the VariantPutref property correctly.")
|
||||
# Cant test further types for this VariantPutref, as only
|
||||
# COM objects can be stored ByRef.
|
||||
|
||||
# A "set" type property - only works for generated.
|
||||
# VB recognizes a collection via a few "private" interfaces that we
|
||||
# could later build support in for.
|
||||
# vbtest.CollectionProperty = NewCollection((1,2,"3", "Four"))
|
||||
# if vbtest.CollectionProperty != (1,2,"3", "Four"):
|
||||
# raise error("Could not set the Collection property correctly - got back " + str(vbtest.CollectionProperty))
|
||||
|
||||
# These are sub's that have a single byref param
|
||||
# Result should be just the byref.
|
||||
if vbtest.IncrementIntegerParam(1) != 2:
|
||||
raise error("Could not pass an integer byref")
|
||||
|
||||
# Sigh - we cant have *both* "ommited byref" and optional args
|
||||
# We really have to opt that args nominated as optional work as optional
|
||||
# rather than simply all byrefs working as optional.
|
||||
# if vbtest.IncrementIntegerParam() != 1:
|
||||
# raise error("Could not pass an omitted integer byref")
|
||||
|
||||
if vbtest.IncrementVariantParam(1) != 2:
|
||||
raise error("Could not pass an int VARIANT byref:"+str(vbtest.IncrementVariantParam(1)))
|
||||
|
||||
if vbtest.IncrementVariantParam(1.5) != 2.5:
|
||||
raise error("Could not pass a float VARIANT byref")
|
||||
|
||||
# Can't test IncrementVariantParam with the param omitted as it
|
||||
# it not declared in the VB code as "Optional"
|
||||
callback_ob = wrap(TestObject(), useDispatcher = useDispatcher)
|
||||
vbtest.DoSomeCallbacks(callback_ob)
|
||||
|
||||
ret = vbtest.PassIntByVal(1)
|
||||
if ret != 2:
|
||||
raise error("Could not increment the integer - "+str(ret))
|
||||
|
||||
TestVBInterface(vbtest)
|
||||
# Python doesnt support byrefs without some sort of generated support.
|
||||
if bUseGenerated:
|
||||
# This is a VB function that takes a single byref
|
||||
# Hence 2 return values - function and byref.
|
||||
ret = vbtest.PassIntByRef(1)
|
||||
if ret != (1,2):
|
||||
raise error("Could not increment the integer - "+str(ret))
|
||||
# Check you can leave a byref arg blank.
|
||||
# see above
|
||||
# ret = vbtest.PassIntByRef()
|
||||
# if ret != (0,1):
|
||||
# raise error("Could not increment the integer with default arg- "+str(ret))
|
||||
|
||||
def _DoTestCollection(vbtest, col_name, expected):
|
||||
# It sucks that some objects allow "Count()", but others "Count"
|
||||
def _getcount(ob):
|
||||
r = getattr(ob, "Count")
|
||||
if type(r)!=type(0):
|
||||
return r()
|
||||
return r
|
||||
c = getattr(vbtest, col_name)
|
||||
check = []
|
||||
for item in c:
|
||||
check.append(item)
|
||||
if check != list(expected):
|
||||
raise error("Collection %s didn't have %r (had %r)" % (col_name, expected, check))
|
||||
# Just looping over the collection again works (ie, is restartable)
|
||||
check = []
|
||||
for item in c:
|
||||
check.append(item)
|
||||
if check != list(expected):
|
||||
raise error("Collection 2nd time around %s didn't have %r (had %r)" % (col_name, expected, check))
|
||||
# Check we can get it via iter()
|
||||
i = iter(getattr(vbtest, col_name))
|
||||
check = []
|
||||
for item in i:
|
||||
check.append(item)
|
||||
if check != list(expected):
|
||||
raise error("Collection iterator %s didn't have %r 2nd time around (had %r)" % (col_name, expected, check))
|
||||
# but an iterator is not restartable
|
||||
check = []
|
||||
for item in i:
|
||||
check.append(item)
|
||||
if check != []:
|
||||
raise error("2nd time around Collection iterator %s wasn't empty (had %r)" % (col_name, check))
|
||||
|
||||
# Check len()==Count()
|
||||
c = getattr(vbtest, col_name)
|
||||
if len(c) != _getcount(c):
|
||||
raise error("Collection %s __len__(%r) wasn't==Count(%r)" % (col_name, len(c), _getcount(c)))
|
||||
# Check we can do it with zero based indexing.
|
||||
c = getattr(vbtest, col_name)
|
||||
check = []
|
||||
for i in range(_getcount(c)):
|
||||
check.append(c[i])
|
||||
if check != list(expected):
|
||||
raise error("Collection %s didn't have %r (had %r)" % (col_name, expected, check))
|
||||
|
||||
# Check we can do it with our old "Skip/Next" methods.
|
||||
c = getattr(vbtest, col_name)._NewEnum()
|
||||
check = []
|
||||
while 1:
|
||||
n = c.Next()
|
||||
if not n:
|
||||
break
|
||||
check.append(n[0])
|
||||
if check != list(expected):
|
||||
raise error("Collection %s didn't have %r (had %r)" % (col_name, expected, check))
|
||||
|
||||
def TestCollections(vbtest):
|
||||
_DoTestCollection(vbtest, "CollectionProperty", [1,"Two", "3"])
|
||||
# zero based indexing works for simple VB collections.
|
||||
if vbtest.CollectionProperty[0] != 1:
|
||||
raise error("The CollectionProperty[0] element was not the default value")
|
||||
|
||||
_DoTestCollection(vbtest, "EnumerableCollectionProperty", [])
|
||||
vbtest.EnumerableCollectionProperty.Add(1)
|
||||
vbtest.EnumerableCollectionProperty.Add("Two")
|
||||
vbtest.EnumerableCollectionProperty.Add("3")
|
||||
_DoTestCollection(vbtest, "EnumerableCollectionProperty", [1,"Two", "3"])
|
||||
|
||||
def _DoTestArray(vbtest, data, expected_exception = None):
|
||||
try:
|
||||
vbtest.ArrayProperty = data
|
||||
if expected_exception is not None:
|
||||
raise error("Expected '%s'" % expected_exception)
|
||||
except expected_exception:
|
||||
return
|
||||
got = vbtest.ArrayProperty
|
||||
if got != data:
|
||||
raise error(
|
||||
"Could not set the array data correctly - got %r, expected %r"
|
||||
% (got, data))
|
||||
|
||||
def TestArrays(vbtest, bUseGenerated):
|
||||
# Try and use a safe array (note that the VB code has this declared as a VARIANT
|
||||
# and I cant work out how to force it to use native arrays!
|
||||
# (NOTE Python will convert incoming arrays to tuples, so we pass a tuple, even tho
|
||||
# a list works fine - just makes it easier for us to compare the result!
|
||||
# Empty array
|
||||
_DoTestArray(vbtest, ())
|
||||
# Empty child array
|
||||
_DoTestArray(vbtest, ((), ()))
|
||||
# ints
|
||||
_DoTestArray(vbtest, tuple(range(1,100)))
|
||||
# Floats
|
||||
_DoTestArray(vbtest, (1.0, 2.0, 3.0))
|
||||
# Strings.
|
||||
_DoTestArray(vbtest, tuple("Hello from Python".split()))
|
||||
# Date and Time?
|
||||
# COM objects.
|
||||
_DoTestArray(vbtest, (vbtest, vbtest))
|
||||
# Mixed
|
||||
_DoTestArray(vbtest, (1, 2.0, "3"))
|
||||
# Array alements containing other arrays
|
||||
_DoTestArray(vbtest, (1,(vbtest, vbtest),("3","4")))
|
||||
# Multi-dimensional
|
||||
_DoTestArray(vbtest, (( (1,2,3), (4,5,6) )))
|
||||
_DoTestArray(vbtest, (( (vbtest,vbtest,vbtest), (vbtest,vbtest,vbtest) )))
|
||||
# Another dimension!
|
||||
arrayData = ( ((1,2),(3,4),(5,6)), ((7,8),(9,10),(11,12)) )
|
||||
arrayData = ( ((vbtest,vbtest),(vbtest,vbtest),(vbtest,vbtest)),
|
||||
((vbtest,vbtest),(vbtest,vbtest),(vbtest,vbtest)) )
|
||||
_DoTestArray(vbtest, arrayData)
|
||||
|
||||
# Check that when a '__getitem__ that fails' object is the first item
|
||||
# in the structure, we don't mistake it for a sequence.
|
||||
_DoTestArray(vbtest, (vbtest, 2.0, "3"))
|
||||
_DoTestArray(vbtest, (1, 2.0, vbtest))
|
||||
|
||||
# Pass arbitrarily sized arrays - these used to fail, but thanks to
|
||||
# Stefan Schukat, they now work!
|
||||
expected_exception = None
|
||||
arrayData = ( ((1,2,1),(3,4),(5,6)), ((7,8),(9,10),(11,12)) )
|
||||
_DoTestArray(vbtest, arrayData, expected_exception)
|
||||
arrayData = ( ((vbtest,vbtest),), ((vbtest,),))
|
||||
_DoTestArray(vbtest, arrayData, expected_exception)
|
||||
# Pass bad data - last item wrong size
|
||||
arrayData = ( ((1,2),(3,4),(5,6,8)), ((7,8),(9,10),(11,12)) )
|
||||
_DoTestArray(vbtest, arrayData, expected_exception)
|
||||
|
||||
# byref safearray results with incorrect size.
|
||||
callback_ob = wrap(TestObject(), useDispatcher = useDispatcher)
|
||||
print("** Expecting a 'ValueError' exception to be printed next:")
|
||||
try:
|
||||
vbtest.DoCallbackSafeArraySizeFail(callback_ob)
|
||||
except pythoncom.com_error as exc:
|
||||
assert exc.excepinfo[1] == "Python COM Server Internal Error", "Didnt get the correct exception - '%s'" % (exc,)
|
||||
|
||||
if bUseGenerated:
|
||||
# This one is a bit strange! The array param is "ByRef", as VB insists.
|
||||
# The function itself also _returns_ the arram param.
|
||||
# Therefore, Python sees _2_ result values - one for the result,
|
||||
# and one for the byref.
|
||||
testData = "Mark was here".split()
|
||||
resultData, byRefParam = vbtest.PassSAFEARRAY(testData)
|
||||
if testData != list(resultData):
|
||||
raise error("The safe array data was not what we expected - got " + str(resultData))
|
||||
if testData != list(byRefParam):
|
||||
raise error("The safe array data was not what we expected - got " + str(byRefParam))
|
||||
testData = [1.0, 2.0, 3.0]
|
||||
resultData, byRefParam = vbtest.PassSAFEARRAYVariant(testData)
|
||||
assert testData == list(byRefParam)
|
||||
assert testData == list(resultData)
|
||||
testData = ["hi", "from", "Python"]
|
||||
resultData, byRefParam = vbtest.PassSAFEARRAYVariant(testData)
|
||||
assert testData == list(byRefParam), "Expected '%s', got '%s'" % (testData, list(byRefParam))
|
||||
assert testData == list(resultData), "Expected '%s', got '%s'" % (testData, list(resultData))
|
||||
# This time, instead of an explicit str() for 1.5, we just
|
||||
# pass Unicode, so the result should compare equal
|
||||
testData = [1, 2.0, "3"]
|
||||
resultData, byRefParam = vbtest.PassSAFEARRAYVariant(testData)
|
||||
assert testData == list(byRefParam)
|
||||
assert testData == list(resultData)
|
||||
print("Array tests passed")
|
||||
|
||||
def TestStructs(vbtest):
|
||||
try:
|
||||
vbtest.IntProperty = "One"
|
||||
raise error("Should have failed by now")
|
||||
except pythoncom.com_error as exc:
|
||||
if exc.hresult != winerror.DISP_E_TYPEMISMATCH:
|
||||
raise error("Expected DISP_E_TYPEMISMATCH")
|
||||
|
||||
s = vbtest.StructProperty
|
||||
if s.int_val != 99 or str(s.str_val) != "hello":
|
||||
raise error("The struct value was not correct")
|
||||
s.str_val = "Hi from Python"
|
||||
s.int_val = 11
|
||||
if s.int_val != 11 or str(s.str_val) != "Hi from Python":
|
||||
raise error("The struct value didnt persist!")
|
||||
|
||||
if s.sub_val.int_val != 66 or str(s.sub_val.str_val) != "sub hello":
|
||||
raise error("The sub-struct value was not correct")
|
||||
sub = s.sub_val
|
||||
sub.int_val = 22
|
||||
if sub.int_val != 22:
|
||||
print(sub.int_val)
|
||||
raise error("The sub-struct value didnt persist!")
|
||||
|
||||
if s.sub_val.int_val != 22:
|
||||
print(s.sub_val.int_val)
|
||||
raise error("The sub-struct value (re-fetched) didnt persist!")
|
||||
|
||||
if s.sub_val.array_val[0].int_val != 0 or str(s.sub_val.array_val[0].str_val) != "zero":
|
||||
print(s.sub_val.array_val[0].int_val)
|
||||
raise error("The array element wasnt correct")
|
||||
s.sub_val.array_val[0].int_val = 99
|
||||
s.sub_val.array_val[1].int_val = 66
|
||||
if s.sub_val.array_val[0].int_val != 99 or \
|
||||
s.sub_val.array_val[1].int_val != 66:
|
||||
print(s.sub_val.array_val[0].int_val)
|
||||
raise error("The array element didnt persist.")
|
||||
# Now pass the struct back to VB
|
||||
vbtest.StructProperty = s
|
||||
# And get it back again
|
||||
s = vbtest.StructProperty
|
||||
if s.int_val != 11 or str(s.str_val) != "Hi from Python":
|
||||
raise error("After sending to VB, the struct value didnt persist!")
|
||||
if s.sub_val.array_val[0].int_val != 99:
|
||||
raise error("After sending to VB, the struct array value didnt persist!")
|
||||
|
||||
# Now do some object equality tests.
|
||||
assert s==s
|
||||
assert s!=None
|
||||
if sys.version_info > (3,0):
|
||||
try:
|
||||
s < None
|
||||
raise error("Expected type error")
|
||||
except TypeError:
|
||||
pass
|
||||
try:
|
||||
None < s
|
||||
raise error("Expected type error")
|
||||
except TypeError:
|
||||
pass
|
||||
assert s != s.sub_val
|
||||
import copy
|
||||
s2 = copy.copy(s)
|
||||
assert s is not s2
|
||||
assert s == s2
|
||||
s2.int_val = 123
|
||||
assert s != s2
|
||||
# Make sure everything works with functions
|
||||
s2 = vbtest.GetStructFunc()
|
||||
assert s==s2
|
||||
vbtest.SetStructSub(s2)
|
||||
|
||||
# Create a new structure, and set its elements.
|
||||
s = win32com.client.Record("VBStruct", vbtest)
|
||||
assert s.int_val == 0, "new struct inst initialized correctly!"
|
||||
s.int_val = -1
|
||||
vbtest.SetStructSub(s)
|
||||
assert vbtest.GetStructFunc().int_val == -1, "new struct didnt make the round trip!"
|
||||
# Finally, test stand-alone structure arrays.
|
||||
s_array = vbtest.StructArrayProperty
|
||||
assert s_array is None, "Expected None from the uninitialized VB array"
|
||||
vbtest.MakeStructArrayProperty(3)
|
||||
s_array = vbtest.StructArrayProperty
|
||||
assert len(s_array)==3
|
||||
for i in range(len(s_array)):
|
||||
assert s_array[i].int_val == i
|
||||
assert s_array[i].sub_val.int_val == i
|
||||
assert s_array[i].sub_val.array_val[0].int_val == i
|
||||
assert s_array[i].sub_val.array_val[1].int_val == i+1
|
||||
assert s_array[i].sub_val.array_val[2].int_val == i+2
|
||||
|
||||
# Some error type checks.
|
||||
try:
|
||||
s.bad_attribute
|
||||
raise RuntimeError("Could get a bad attribute")
|
||||
except AttributeError:
|
||||
pass
|
||||
m = s.__members__
|
||||
assert m[0]=="int_val" and m[1]=="str_val" and m[2]=="ob_val" and m[3]=="sub_val", m
|
||||
|
||||
# Test attribute errors.
|
||||
try:
|
||||
s.foo
|
||||
raise RuntimeError("Expected attribute error")
|
||||
except AttributeError as exc:
|
||||
assert "foo" in str(exc), exc
|
||||
|
||||
# test repr - it uses repr() of the sub-objects, so check it matches.
|
||||
expected = "com_struct(int_val=%r, str_val=%r, ob_val=%r, sub_val=%r)" % (s.int_val, s.str_val, s.ob_val, s.sub_val)
|
||||
if repr(s) != expected:
|
||||
print("Expected repr:", expected)
|
||||
print("Actual repr :", repr(s))
|
||||
raise RuntimeError("repr() of record object failed")
|
||||
|
||||
print("Struct/Record tests passed")
|
||||
|
||||
def TestVBInterface(ob):
|
||||
t = ob.GetInterfaceTester(2)
|
||||
if t.getn() != 2:
|
||||
raise error("Initial value wrong")
|
||||
t.setn(3)
|
||||
if t.getn() != 3:
|
||||
raise error("New value wrong")
|
||||
|
||||
def TestObjectSemantics(ob):
|
||||
# a convenient place to test some of our equality semantics
|
||||
assert ob==ob._oleobj_
|
||||
assert not ob!=ob._oleobj_
|
||||
# same test again, but lhs and rhs reversed.
|
||||
assert ob._oleobj_==ob
|
||||
assert not ob._oleobj_!=ob
|
||||
# same tests but against different pointers. COM identity rules should
|
||||
# still ensure all works
|
||||
assert ob._oleobj_==ob._oleobj_.QueryInterface(pythoncom.IID_IUnknown)
|
||||
assert not ob._oleobj_!=ob._oleobj_.QueryInterface(pythoncom.IID_IUnknown)
|
||||
|
||||
assert ob._oleobj_!=None
|
||||
assert None!=ob._oleobj_
|
||||
assert ob!=None
|
||||
assert None!=ob
|
||||
if sys.version_info > (3,0):
|
||||
try:
|
||||
ob < None
|
||||
raise error("Expected type error")
|
||||
except TypeError:
|
||||
pass
|
||||
try:
|
||||
None < ob
|
||||
raise error("Expected type error")
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
assert ob._oleobj_.QueryInterface(pythoncom.IID_IUnknown)==ob._oleobj_
|
||||
assert not ob._oleobj_.QueryInterface(pythoncom.IID_IUnknown)!=ob._oleobj_
|
||||
|
||||
assert ob._oleobj_==ob._oleobj_.QueryInterface(pythoncom.IID_IDispatch)
|
||||
assert not ob._oleobj_!=ob._oleobj_.QueryInterface(pythoncom.IID_IDispatch)
|
||||
|
||||
assert ob._oleobj_.QueryInterface(pythoncom.IID_IDispatch)==ob._oleobj_
|
||||
assert not ob._oleobj_.QueryInterface(pythoncom.IID_IDispatch)!=ob._oleobj_
|
||||
|
||||
print("Object semantic tests passed")
|
||||
|
||||
def DoTestAll():
|
||||
o = win32com.client.Dispatch("PyCOMVBTest.Tester")
|
||||
TestObjectSemantics(o)
|
||||
TestVB(o,1)
|
||||
|
||||
o = win32com.client.dynamic.DumbDispatch("PyCOMVBTest.Tester")
|
||||
TestObjectSemantics(o)
|
||||
TestVB(o,0)
|
||||
|
||||
def TestAll():
|
||||
# Import the type library for the test module. Let the 'invalid clsid'
|
||||
# exception filter up, where the test runner will treat it as 'skipped'
|
||||
win32com.client.gencache.EnsureDispatch("PyCOMVBTest.Tester")
|
||||
|
||||
if not __debug__:
|
||||
raise RuntimeError("This must be run in debug mode - we use assert!")
|
||||
try:
|
||||
DoTestAll()
|
||||
print("All tests appear to have worked!")
|
||||
except:
|
||||
# ?????
|
||||
print("TestAll() failed!!")
|
||||
traceback.print_exc()
|
||||
raise
|
||||
|
||||
# Make this test run under our test suite to leak tests etc work
|
||||
def suite():
|
||||
import unittest
|
||||
test = util.CapturingFunctionTestCase(TestAll, description="VB tests")
|
||||
suite = unittest.TestSuite()
|
||||
suite.addTest(test)
|
||||
return suite
|
||||
|
||||
if __name__=='__main__':
|
||||
util.testmain()
|
37
venv/Lib/site-packages/win32com/test/testvbscript_regexp.py
Normal file
37
venv/Lib/site-packages/win32com/test/testvbscript_regexp.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
import unittest
|
||||
from win32com.client.gencache import EnsureDispatch
|
||||
from win32com.client.dynamic import DumbDispatch
|
||||
import win32com.test.util
|
||||
|
||||
class RegexTest(win32com.test.util.TestCase):
|
||||
def _CheckMatches(self, match, expected):
|
||||
found = []
|
||||
for imatch in match:
|
||||
found.append(imatch.FirstIndex)
|
||||
self.assertEquals(list(found), list(expected))
|
||||
|
||||
def _TestVBScriptRegex(self, re):
|
||||
StringToSearch = "Python python pYthon Python"
|
||||
re.Pattern = "Python"
|
||||
re.Global = True
|
||||
|
||||
re.IgnoreCase = True
|
||||
match = re.Execute(StringToSearch)
|
||||
expected = 0, 7, 14, 21
|
||||
self._CheckMatches(match, expected)
|
||||
|
||||
re.IgnoreCase = False
|
||||
match = re.Execute(StringToSearch)
|
||||
expected = 0, 21
|
||||
self._CheckMatches(match, expected)
|
||||
|
||||
def testDynamic(self):
|
||||
re = DumbDispatch("VBScript.Regexp")
|
||||
self._TestVBScriptRegex(re)
|
||||
|
||||
def testGenerated(self):
|
||||
re = EnsureDispatch("VBScript.Regexp")
|
||||
self._TestVBScriptRegex(re)
|
||||
|
||||
if __name__=='__main__':
|
||||
unittest.main()
|
12
venv/Lib/site-packages/win32com/test/testxslt.js
Normal file
12
venv/Lib/site-packages/win32com/test/testxslt.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
//Args: input-file style-file output-file
|
||||
var xml = WScript.CreateObject("Microsoft.XMLDOM"); //input
|
||||
xml.validateOnParse=false;
|
||||
xml.load(WScript.Arguments(0));
|
||||
var xsl = WScript.CreateObject("Microsoft.XMLDOM"); //style
|
||||
xsl.validateOnParse=false;
|
||||
xsl.load(WScript.Arguments(1));
|
||||
var out = WScript.CreateObject("Scripting.FileSystemObject"); //output
|
||||
var replace = true; var unicode = false; //output file properties
|
||||
var hdl = out.CreateTextFile( WScript.Arguments(2), replace, unicode )
|
||||
hdl.write( xml.transformNode( xsl.documentElement ));
|
||||
//eof
|
29
venv/Lib/site-packages/win32com/test/testxslt.py
Normal file
29
venv/Lib/site-packages/win32com/test/testxslt.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
import os
|
||||
import tempfile
|
||||
import unittest
|
||||
import win32com.test.util
|
||||
|
||||
expected_output = "The jscript test worked.\nThe Python test worked"
|
||||
|
||||
class XSLT(win32com.test.util.TestCase):
|
||||
def testAll(self):
|
||||
output_name = tempfile.mktemp("-pycom-test")
|
||||
cmd = "cscript //nologo testxslt.js doesnt_matter.xml testxslt.xsl " + output_name
|
||||
win32com.test.util.ExecuteShellCommand(cmd, self)
|
||||
try:
|
||||
f=open(output_name)
|
||||
try:
|
||||
got = f.read()
|
||||
if got != expected_output:
|
||||
print("ERROR: XSLT expected output of %r" % (expected_output,))
|
||||
print("but got %r" % (got,))
|
||||
finally:
|
||||
f.close()
|
||||
finally:
|
||||
try:
|
||||
os.unlink(output_name)
|
||||
except os.error:
|
||||
pass
|
||||
|
||||
if __name__=='__main__':
|
||||
unittest.main()
|
55
venv/Lib/site-packages/win32com/test/testxslt.xsl
Normal file
55
venv/Lib/site-packages/win32com/test/testxslt.xsl
Normal file
|
@ -0,0 +1,55 @@
|
|||
<!-- include in the xsl:stylesheet element:
|
||||
(a) the version attribute as usual
|
||||
(b) the XSLT namespace declaration as usual
|
||||
(c) the MSXSL namespace declaration
|
||||
(d) a namespace declaration to identify your functions
|
||||
(e) the 'extension-element-prefixes' attribute to give the
|
||||
namespace prefixes that indicate extension elements
|
||||
(i.e. 'msxsl')
|
||||
(f) the 'exclude-result-prefixes' attribute to indicate the
|
||||
namespaces that aren't supposed to be part of the result
|
||||
tree (i.e. 'foo') -->
|
||||
<xsl:stylesheet version="1.0"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
|
||||
xmlns:foo="http://www.pythoncom-test.com/foo"
|
||||
xmlns:bar="http://www.pythoncom-test.com/bar"
|
||||
extension-element-prefixes="msxsl"
|
||||
exclude-result-prefixes="foo bar">
|
||||
|
||||
<!-- do whatever output you want - you can use full XSLT functionality
|
||||
-->
|
||||
<xsl:output method="html" />
|
||||
|
||||
<!-- define the Javascript functions that you want to include within
|
||||
a msxsl:script element.
|
||||
- language indicates the scripting language
|
||||
- implements-prefix gives the namespace prefix that you declared
|
||||
for your function (i.e. foo) -->
|
||||
<msxsl:script language="javascript"
|
||||
implements-prefix="foo">
|
||||
function worked() {
|
||||
return "The jscript test worked";
|
||||
}
|
||||
</msxsl:script>
|
||||
|
||||
<!-- ditto for Python, using the 'bar' namespace
|
||||
-->
|
||||
<msxsl:script language="python"
|
||||
implements-prefix="bar">
|
||||
def worked():
|
||||
return "The Python test worked"
|
||||
</msxsl:script>
|
||||
|
||||
<xsl:template match="/">
|
||||
<!-- The output template. Keep whitespace down as our test matches text exactly -->
|
||||
<!-- call your functions using the prefix that you've used (i.e.
|
||||
foo) anywhere you can normally use an XPath function, but
|
||||
make sure it's returning the right kind of object -->
|
||||
<xsl:value-of select="foo:worked()" />.
|
||||
<xsl:value-of select="bar:worked()" />
|
||||
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
||||
|
225
venv/Lib/site-packages/win32com/test/util.py
Normal file
225
venv/Lib/site-packages/win32com/test/util.py
Normal file
|
@ -0,0 +1,225 @@
|
|||
import sys, os
|
||||
import win32api
|
||||
import tempfile
|
||||
import unittest
|
||||
import gc
|
||||
import pywintypes
|
||||
import pythoncom
|
||||
import winerror
|
||||
from pythoncom import _GetInterfaceCount, _GetGatewayCount
|
||||
import win32com
|
||||
import logging
|
||||
import winreg
|
||||
import io as StringIO
|
||||
|
||||
import pywin32_testutil
|
||||
from pywin32_testutil import TestLoader, TestResult, TestRunner, LeakTestCase
|
||||
|
||||
def CheckClean():
|
||||
# Ensure no lingering exceptions - Python should have zero outstanding
|
||||
# COM objects
|
||||
try:
|
||||
sys.exc_clear()
|
||||
except AttributeError:
|
||||
pass # py3k
|
||||
c = _GetInterfaceCount()
|
||||
if c:
|
||||
print("Warning - %d com interface objects still alive" % c)
|
||||
c = _GetGatewayCount()
|
||||
if c:
|
||||
print("Warning - %d com gateway objects still alive" % c)
|
||||
|
||||
def RegisterPythonServer(filename, progids=None, verbose=0):
|
||||
if progids:
|
||||
if isinstance(progids, str):
|
||||
progids = [progids]
|
||||
# we know the CLSIDs we need, but we might not be an admin user
|
||||
# and otherwise unable to register them. So as long as the progids
|
||||
# exist and the DLL points at our version, assume it already is.
|
||||
why_not = None
|
||||
for progid in progids:
|
||||
clsid = pywintypes.IID(progid)
|
||||
try:
|
||||
HKCR = winreg.HKEY_CLASSES_ROOT
|
||||
hk = winreg.OpenKey(HKCR, "CLSID\\%s" % clsid)
|
||||
dll = winreg.QueryValue(hk, "InprocServer32")
|
||||
except WindowsError:
|
||||
# no CLSID or InProcServer32 - not registered
|
||||
break
|
||||
ok_files = [os.path.basename(pythoncom.__file__),
|
||||
'pythoncomloader%d%d.dll' % (sys.version_info[0], sys.version_info[1])]
|
||||
if os.path.basename(dll) not in ok_files:
|
||||
why_not = "%r is registered against a different Python version (%s)" % (progid, dll)
|
||||
break
|
||||
else:
|
||||
#print "Skipping registration of '%s' - already registered" % filename
|
||||
return
|
||||
# needs registration - see if its likely!
|
||||
try:
|
||||
from win32com.shell.shell import IsUserAnAdmin
|
||||
except ImportError:
|
||||
print("Can't import win32com.shell - no idea if you are an admin or not?")
|
||||
is_admin = False
|
||||
else:
|
||||
try:
|
||||
is_admin = IsUserAnAdmin()
|
||||
except pythoncom.com_error:
|
||||
# old, less-secure OS - assume *is* admin.
|
||||
is_admin = True
|
||||
if not is_admin:
|
||||
msg = "%r isn't registered, but I'm not an administrator who can register it." % progids[0]
|
||||
if why_not:
|
||||
msg += "\n(registration check failed as %s)" % why_not
|
||||
# throw a normal "class not registered" exception - we don't report
|
||||
# them the same way as "real" errors.
|
||||
raise pythoncom.com_error(winerror.CO_E_CLASSSTRING, msg, None, -1)
|
||||
# so theoretically we are able to register it.
|
||||
cmd = '%s "%s" --unattended > nul 2>&1' % (win32api.GetModuleFileName(0), filename)
|
||||
if verbose:
|
||||
print("Registering engine", filename)
|
||||
# print cmd
|
||||
rc = os.system(cmd)
|
||||
if rc:
|
||||
print("Registration command was:")
|
||||
print(cmd)
|
||||
raise RuntimeError("Registration of engine '%s' failed" % filename)
|
||||
|
||||
def ExecuteShellCommand(cmd, testcase,
|
||||
expected_output = None, # Set to '' to check for nothing
|
||||
tracebacks_ok = 0, # OK if the output contains a t/b?
|
||||
):
|
||||
output_name = tempfile.mktemp('win32com_test')
|
||||
cmd = cmd + ' > "%s" 2>&1' % output_name
|
||||
rc = os.system(cmd)
|
||||
output = open(output_name, "r").read().strip()
|
||||
os.remove(output_name)
|
||||
class Failed(Exception): pass
|
||||
try:
|
||||
if rc:
|
||||
raise Failed("exit code was " + str(rc))
|
||||
if expected_output is not None and output != expected_output:
|
||||
raise Failed("Expected output %r (got %r)" % (expected_output, output))
|
||||
if not tracebacks_ok and \
|
||||
output.find("Traceback (most recent call last)")>=0:
|
||||
raise Failed("traceback in program output")
|
||||
return output
|
||||
except Failed as why:
|
||||
print("Failed to exec command '%r'" % cmd)
|
||||
print("Failed as", why)
|
||||
print("** start of program output **")
|
||||
print(output)
|
||||
print("** end of program output **")
|
||||
testcase.fail("Executing '%s' failed as %s" % (cmd, why))
|
||||
|
||||
def assertRaisesCOM_HRESULT(testcase, hresult, func, *args, **kw):
|
||||
try:
|
||||
func(*args, **kw)
|
||||
except pythoncom.com_error as details:
|
||||
if details.hresult==hresult:
|
||||
return
|
||||
testcase.fail("Excepected COM exception with HRESULT 0x%x" % hresult)
|
||||
|
||||
class CaptureWriter:
|
||||
def __init__(self):
|
||||
self.old_err = self.old_out = None
|
||||
self.clear()
|
||||
def capture(self):
|
||||
self.clear()
|
||||
self.old_out = sys.stdout
|
||||
self.old_err = sys.stderr
|
||||
sys.stdout = sys.stderr = self
|
||||
def release(self):
|
||||
if self.old_out:
|
||||
sys.stdout = self.old_out
|
||||
self.old_out = None
|
||||
if self.old_err:
|
||||
sys.stderr = self.old_err
|
||||
self.old_err = None
|
||||
def clear(self):
|
||||
self.captured = []
|
||||
def write(self, msg):
|
||||
self.captured.append(msg)
|
||||
def get_captured(self):
|
||||
return "".join(self.captured)
|
||||
def get_num_lines_captured(self):
|
||||
return len("".join(self.captured).split("\n"))
|
||||
|
||||
|
||||
# Utilities to set the win32com logger to something what just captures
|
||||
# records written and doesn't print them.
|
||||
class LogHandler(logging.Handler):
|
||||
def __init__(self):
|
||||
self.emitted = []
|
||||
logging.Handler.__init__(self)
|
||||
def emit(self, record):
|
||||
self.emitted.append(record)
|
||||
|
||||
_win32com_logger = None
|
||||
def setup_test_logger():
|
||||
old_log = getattr(win32com, "logger", None)
|
||||
global _win32com_logger
|
||||
if _win32com_logger is None:
|
||||
_win32com_logger = logging.Logger('test')
|
||||
handler = LogHandler()
|
||||
_win32com_logger.addHandler(handler)
|
||||
|
||||
win32com.logger = _win32com_logger
|
||||
handler = _win32com_logger.handlers[0]
|
||||
handler.emitted = []
|
||||
return handler.emitted, old_log
|
||||
|
||||
def restore_test_logger(prev_logger):
|
||||
assert prev_logger is None, "who needs this?"
|
||||
if prev_logger is None:
|
||||
del win32com.logger
|
||||
else:
|
||||
win32com.logger = prev_logger
|
||||
|
||||
# We used to override some of this (and may later!)
|
||||
TestCase = unittest.TestCase
|
||||
|
||||
def CapturingFunctionTestCase(*args, **kw):
|
||||
real_test = _CapturingFunctionTestCase(*args, **kw)
|
||||
return LeakTestCase(real_test)
|
||||
|
||||
class _CapturingFunctionTestCase(unittest.FunctionTestCase):#, TestCaseMixin):
|
||||
def __call__(self, result=None):
|
||||
if result is None: result = self.defaultTestResult()
|
||||
writer = CaptureWriter()
|
||||
#self._preTest()
|
||||
writer.capture()
|
||||
try:
|
||||
unittest.FunctionTestCase.__call__(self, result)
|
||||
if getattr(self, "do_leak_tests", 0) and hasattr(sys, "gettotalrefcount"):
|
||||
self.run_leak_tests(result)
|
||||
finally:
|
||||
writer.release()
|
||||
#self._postTest(result)
|
||||
output = writer.get_captured()
|
||||
self.checkOutput(output, result)
|
||||
if result.showAll:
|
||||
print(output)
|
||||
def checkOutput(self, output, result):
|
||||
if output.find("Traceback")>=0:
|
||||
msg = "Test output contained a traceback\n---\n%s\n---" % output
|
||||
result.errors.append((self, msg))
|
||||
|
||||
class ShellTestCase(unittest.TestCase):
|
||||
def __init__(self, cmd, expected_output):
|
||||
self.__cmd = cmd
|
||||
self.__eo = expected_output
|
||||
unittest.TestCase.__init__(self)
|
||||
def runTest(self):
|
||||
ExecuteShellCommand(self.__cmd, self, self.__eo)
|
||||
def __str__(self):
|
||||
max = 30
|
||||
if len(self.__cmd)>max:
|
||||
cmd_repr = self.__cmd[:max] + "..."
|
||||
else:
|
||||
cmd_repr = self.__cmd
|
||||
return "exec: " + cmd_repr
|
||||
|
||||
|
||||
def testmain(*args, **kw):
|
||||
pywin32_testutil.testmain(*args, **kw)
|
||||
CheckClean()
|
Loading…
Add table
Add a link
Reference in a new issue