0001 """Python.Dictionary COM Server. 0002 0003 This module implements a simple COM server that acts much like a Python 0004 dictionary or as a standard string-keyed VB Collection. The keys of 0005 the dictionary are strings and are case-insensitive. 0006 0007 It uses a highly customized policy to fine-tune the behavior exposed to 0008 the COM client. 0009 0010 The object exposes the following properties: 0011 0012 int Count (readonly) 0013 VARIANT Item(BSTR key) (propget for Item) 0014 Item(BSTR key, VARIANT value) (propput for Item) 0015 0016 Note that 'Item' is the default property, so the following forms of 0017 VB code are acceptable: 0018 0019 set ob = CreateObject("Python.Dictionary") 0020 ob("hello") = "there" 0021 ob.Item("hi") = ob("HELLO") 0022 0023 All keys are defined, returning VT_NULL (None) if a value has not been 0024 stored. To delete a key, simply assign VT_NULL to the key. 0025 0026 The object responds to the _NewEnum method by returning an enumerator over 0027 the dictionary's keys. This allows for the following type of VB code: 0028 0029 for each name in ob 0030 debug.print name, ob(name) 0031 next 0032 """ 0033 0034 import string 0035 import pythoncom 0036 from win32com.server import util, policy 0037 from win32com.server.exception import COMException 0038 import winerror 0039 import types 0040 import pywintypes 0041 0042 from pythoncom import DISPATCH_METHOD, DISPATCH_PROPERTYGET 0043 from winerror import S_OK 0044 0045 UnicodeType = pywintypes.UnicodeType 0046 StringType = types.StringType 0047 0048 0049 class DictionaryPolicy(policy.BasicWrapPolicy): 0050 ### BasicWrapPolicy looks for this 0051 _com_interfaces_ = [ ] 0052 0053 ### BasicWrapPolicy looks for this 0054 _name_to_dispid_ = { 0055 'item' : pythoncom.DISPID_VALUE, 0056 '_newenum' : pythoncom.DISPID_NEWENUM, 0057 'count' : 1, 0058 } 0059 0060 ### Auto-Registration process looks for these... 0061 _reg_desc_ = 'Python Dictionary' 0062 _reg_clsid_ = '{39b61048-c755-11d0-86fa-00c04fc2e03e}' 0063 _reg_progid_ = 'Python.Dictionary' 0064 _reg_verprogid_ = 'Python.Dictionary.1' 0065 _reg_policy_spec_ = 'win32com.servers.dictionary.DictionaryPolicy' 0066 0067 def _CreateInstance_(self, clsid, reqIID): 0068 self._wrap_({ }) 0069 return pythoncom.WrapObject(self, reqIID) 0070 0071 def _wrap_(self, ob): 0072 self._obj_ = ob # ob should be a dictionary 0073 0074 def _invokeex_(self, dispid, lcid, wFlags, args, kwargs, serviceProvider): 0075 if dispid == 0: # item 0076 l = len(args) 0077 if l < 1: 0078 raise COMException(desc="not enough parameters", scode=winerror.DISP_E_BADPARAMCOUNT) 0079 0080 key = args[0] 0081 if type(key) == UnicodeType: 0082 pass 0083 elif type(key) == StringType: 0084 key = pywintypes.Unicode(key) 0085 else: 0086 ### the nArgErr thing should be 0-based, not reversed... sigh 0087 raise COMException(desc="Key must be a string", scode=winerror.DISP_E_TYPEMISMATCH) 0088 0089 key = key.lower() 0090 0091 if wFlags & (DISPATCH_METHOD | DISPATCH_PROPERTYGET): 0092 if l > 1: 0093 raise COMException(scode=winerror.DISP_E_BADPARAMCOUNT) 0094 try: 0095 return self._obj_[key] 0096 except KeyError: 0097 return None # unknown keys return None (VT_NULL) 0098 0099 if l <> 2: 0100 raise COMException(scode=winerror.DISP_E_BADPARAMCOUNT) 0101 if args[1] is None: 0102 # delete a key when None is assigned to it 0103 try: 0104 del self._obj_[key] 0105 except KeyError: 0106 pass 0107 else: 0108 self._obj_[key] = args[1] 0109 return S_OK 0110 0111 if dispid == 1: # count 0112 if not wFlags & DISPATCH_PROPERTYGET: 0113 raise COMException(scode=winerror.DISP_E_MEMBERNOTFOUND) # not found 0114 if len(args) != 0: 0115 raise COMException(scode=winerror.DISP_E_BADPARAMCOUNT) 0116 return len(self._obj_) 0117 0118 if dispid == pythoncom.DISPID_NEWENUM: 0119 return util.NewEnum(self._obj_.keys()) 0120 0121 raise COMException(scode=winerror.DISP_E_MEMBERNOTFOUND) 0122 0123 def _getidsofnames_(self, names, lcid): 0124 ### this is a copy of MappedWrapPolicy._getidsofnames_ ... 0125 0126 # Note: these names will always be StringType 0127 name = string.lower(names[0]) 0128 try: 0129 return (self._name_to_dispid_[name],) 0130 except KeyError: 0131 raise COMException(scode=winerror.DISP_E_MEMBERNOTFOUND, 0132 desc="Member not found") 0133 0134 0135 def Register(): 0136 from win32com.server.register import UseCommandLine 0137 return UseCommandLine(DictionaryPolicy) 0138 0139 if __name__ == '__main__': 0140 Register() 0141
Generated by PyXR 0.9.4