PyXR

c:\python24\lib\site-packages\win32 \ com \ client \ dynamic.py



0001 """Support for dynamic COM client support.
0002 
0003 Introduction
0004  Dynamic COM client support is the ability to use a COM server without
0005  prior knowledge of the server.  This can be used to talk to almost all
0006  COM servers, including much of MS Office.
0007  
0008  In general, you should not use this module directly - see below.
0009  
0010 Example
0011  >>> import win32com.client
0012  >>> xl = win32com.client.Dispatch("Excel.Application")
0013  # The line above invokes the functionality of this class.
0014  # xl is now an object we can use to talk to Excel.
0015  >>> xl.Visible = 1 # The Excel window becomes visible.
0016 
0017 """
0018 import traceback
0019 import string
0020 import new
0021 
0022 import pythoncom
0023 import winerror
0024 import build
0025 
0026 from types import StringType, IntType, TupleType, ListType
0027 from pywintypes import UnicodeType, IIDType
0028 
0029 import win32com.client # Needed as code we eval() references it.
0030 from win32com.client import NeedUnicodeConversions
0031 
0032 debugging=0                        # General debugging
0033 debugging_attr=0        # Debugging dynamic attribute lookups.
0034 
0035 LCID = 0x0
0036 
0037 # These errors generally mean the property or method exists,
0038 # but can't be used in this context - eg, property instead of a method, etc.
0039 # Used to determine if we have a real error or not.
0040 ERRORS_BAD_CONTEXT = [
0041         winerror.DISP_E_MEMBERNOTFOUND,
0042         winerror.DISP_E_BADPARAMCOUNT,
0043         winerror.DISP_E_PARAMNOTOPTIONAL,
0044         winerror.DISP_E_TYPEMISMATCH,
0045     winerror.E_INVALIDARG,
0046 ]
0047 
0048 ALL_INVOKE_TYPES = [
0049         pythoncom.INVOKE_PROPERTYGET,
0050         pythoncom.INVOKE_PROPERTYPUT,
0051         pythoncom.INVOKE_PROPERTYPUTREF,
0052         pythoncom.INVOKE_FUNC
0053 ]
0054 
0055 def debug_print(*args):
0056         if debugging:
0057                 for arg in args:
0058                         print arg,
0059                 print
0060 
0061 def debug_attr_print(*args):
0062         if debugging_attr:
0063                 for arg in args:
0064                         print arg,
0065                 print
0066 
0067 # get the dispatch type in use.
0068 dispatchType = pythoncom.TypeIIDs[pythoncom.IID_IDispatch]
0069 iunkType = pythoncom.TypeIIDs[pythoncom.IID_IUnknown]
0070 _StringOrUnicodeType=[StringType, UnicodeType]
0071 _GoodDispatchType=[StringType,IIDType,UnicodeType]
0072 _defaultDispatchItem=build.DispatchItem
0073 
0074 def _GetGoodDispatch(IDispatch, clsctx = pythoncom.CLSCTX_SERVER):
0075         if type(IDispatch) in _GoodDispatchType:
0076                 try:
0077                         IDispatch = pythoncom.connect(IDispatch)
0078                 except pythoncom.ole_error:
0079                         IDispatch = pythoncom.CoCreateInstance(IDispatch, None, clsctx, pythoncom.IID_IDispatch)
0080         else:
0081                 # may already be a wrapped class.
0082                 IDispatch = getattr(IDispatch, "_oleobj_", IDispatch)
0083         return IDispatch
0084 
0085 def _GetGoodDispatchAndUserName(IDispatch,userName,clsctx):
0086         if userName is None:
0087                 if type(IDispatch) in _StringOrUnicodeType:
0088                         userName = IDispatch
0089                 else:
0090                         userName = "<unknown>"
0091         return (_GetGoodDispatch(IDispatch, clsctx), userName)
0092 
0093 def _GetDescInvokeType(entry, default_invoke_type):
0094         if not entry or not entry.desc: return default_invoke_type
0095         return entry.desc[4]
0096 
0097 def Dispatch(IDispatch, userName = None, createClass = None, typeinfo = None, UnicodeToString=NeedUnicodeConversions, clsctx = pythoncom.CLSCTX_SERVER):
0098         IDispatch, userName = _GetGoodDispatchAndUserName(IDispatch,userName,clsctx)
0099         if createClass is None:
0100                 createClass = CDispatch
0101         lazydata = None
0102         try:
0103                 if typeinfo is None:
0104                         typeinfo = IDispatch.GetTypeInfo()
0105                 try:
0106                         #try for a typecomp
0107                         typecomp = typeinfo.GetTypeComp()
0108                         lazydata = typeinfo, typecomp
0109                 except pythoncom.com_error:
0110                         pass
0111         except pythoncom.com_error:
0112                 typeinfo = None
0113         olerepr = MakeOleRepr(IDispatch, typeinfo, lazydata)
0114         return createClass(IDispatch, olerepr, userName,UnicodeToString, lazydata)
0115 
0116 def MakeOleRepr(IDispatch, typeinfo, typecomp):
0117         olerepr = None
0118         if typeinfo is not None:
0119                 try:
0120                         attr = typeinfo.GetTypeAttr()
0121                         # If the type info is a special DUAL interface, magically turn it into
0122                         # a DISPATCH typeinfo.
0123                         if attr[5] == pythoncom.TKIND_INTERFACE and attr[11] & pythoncom.TYPEFLAG_FDUAL:
0124                                 # Get corresponding Disp interface;
0125                                 # -1 is a special value which does this for us.
0126                                 href = typeinfo.GetRefTypeOfImplType(-1);
0127                                 typeinfo = typeinfo.GetRefTypeInfo(href)
0128                                 attr = typeinfo.GetTypeAttr()
0129                         if typecomp is None:
0130                                 olerepr = build.DispatchItem(typeinfo, attr, None, 0)
0131                         else:
0132                                 olerepr = build.LazyDispatchItem(attr, None)
0133                 except pythoncom.ole_error:
0134                         pass
0135         if olerepr is None: olerepr = build.DispatchItem()
0136         return olerepr
0137 
0138 def DumbDispatch(IDispatch, userName = None, createClass = None,UnicodeToString=NeedUnicodeConversions, clsctx=pythoncom.CLSCTX_SERVER):
0139         "Dispatch with no type info"
0140         IDispatch, userName = _GetGoodDispatchAndUserName(IDispatch,userName,clsctx)
0141         if createClass is None:
0142                 createClass = CDispatch
0143         return createClass(IDispatch, build.DispatchItem(), userName,UnicodeToString)
0144 
0145 class CDispatch:
0146         def __init__(self, IDispatch, olerepr, userName =  None, UnicodeToString=NeedUnicodeConversions, lazydata = None):
0147                 if userName is None: userName = "<unknown>"
0148                 self.__dict__['_oleobj_'] = IDispatch
0149                 self.__dict__['_username_'] = userName
0150                 self.__dict__['_olerepr_'] = olerepr
0151                 self.__dict__['_mapCachedItems_'] = {}
0152                 self.__dict__['_builtMethods_'] = {}
0153                 self.__dict__['_enum_'] = None
0154                 self.__dict__['_unicode_to_string_'] = UnicodeToString
0155                 self.__dict__['_lazydata_'] = lazydata
0156 
0157         def __call__(self, *args):
0158                 "Provide 'default dispatch' COM functionality - allow instance to be called"
0159                 if self._olerepr_.defaultDispatchName:
0160                         invkind, dispid = self._find_dispatch_type_(self._olerepr_.defaultDispatchName)
0161                 else:
0162                         invkind, dispid = pythoncom.DISPATCH_METHOD | pythoncom.DISPATCH_PROPERTYGET, pythoncom.DISPID_VALUE
0163                 if invkind is not None:
0164                         allArgs = (dispid,LCID,invkind,1) + args
0165                         return self._get_good_object_(self._oleobj_.Invoke(*allArgs),self._olerepr_.defaultDispatchName,None)
0166                 raise TypeError, "This dispatch object does not define a default method"
0167 
0168         def __nonzero__(self):
0169                 return 1 # ie "if object:" should always be "true" - without this, __len__ is tried.
0170                 # _Possibly_ want to defer to __len__ if available, but Im not sure this is
0171                 # desirable???
0172 
0173         def __repr__(self):
0174                 return "<COMObject %s>" % (self._username_)
0175 
0176         def __str__(self):
0177                 # __str__ is used when the user does "print object", so we gracefully
0178                 # fall back to the __repr__ if the object has no default method.
0179                 try:
0180                         return str(self.__call__())
0181                 except pythoncom.com_error, details:
0182                         if details[0] not in ERRORS_BAD_CONTEXT:
0183                                 raise
0184                         return self.__repr__()
0185 
0186         # Delegate comparison to the oleobjs, as they know how to do identity.
0187         def __cmp__(self, other):
0188                 other = getattr(other, "_oleobj_", other)
0189                 return cmp(self._oleobj_, other)
0190 
0191         def __int__(self):
0192                 return int(self.__call__())
0193 
0194         def __len__(self):
0195                 invkind, dispid = self._find_dispatch_type_("Count")
0196                 if invkind:
0197                         return self._oleobj_.Invoke(dispid, LCID, invkind, 1)
0198                 raise TypeError, "This dispatch object does not define a Count method"
0199 
0200         def _NewEnum(self):
0201                 try:
0202                         invkind = pythoncom.DISPATCH_METHOD | pythoncom.DISPATCH_PROPERTYGET
0203                         enum = self._oleobj_.InvokeTypes(pythoncom.DISPID_NEWENUM,LCID,invkind,(13, 10),())
0204                 except pythoncom.com_error:
0205                         return None # no enumerator for this object.
0206                 import util
0207                 return util.WrapEnum(enum, None)
0208 
0209         def __getitem__(self, index): # syver modified
0210                 # Improved __getitem__ courtesy Syver Enstad
0211                 # Must check _NewEnum before Item, to ensure b/w compat.
0212                 if isinstance(index, IntType):
0213                         if self.__dict__['_enum_'] is None:
0214                                 self.__dict__['_enum_'] = self._NewEnum()
0215                         if self.__dict__['_enum_'] is not None:
0216                                 return self._get_good_object_(self._enum_.__getitem__(index))
0217                 # See if we have an "Item" method/property we can use (goes hand in hand with Count() above!)
0218                 invkind, dispid = self._find_dispatch_type_("Item")
0219                 if invkind is not None:
0220                         return self._get_good_object_(self._oleobj_.Invoke(dispid, LCID, invkind, 1, index))
0221                 raise TypeError, "This object does not support enumeration"
0222 
0223         def __setitem__(self, index, *args):
0224                 # XXX - todo - We should support calling Item() here too!
0225 #         print "__setitem__ with", index, args
0226                 if self._olerepr_.defaultDispatchName:
0227                         invkind, dispid = self._find_dispatch_type_(self._olerepr_.defaultDispatchName)
0228                 else:
0229                         invkind, dispid = pythoncom.DISPATCH_PROPERTYPUT | pythoncom.DISPATCH_PROPERTYPUTREF, pythoncom.DISPID_VALUE
0230                 if invkind is not None:
0231                         allArgs = (dispid,LCID,invkind,0,index) + args
0232                         return self._get_good_object_(self._oleobj_.Invoke(*allArgs),self._olerepr_.defaultDispatchName,None)
0233                 raise TypeError, "This dispatch object does not define a default method"
0234 
0235         def _find_dispatch_type_(self, methodName):
0236                 if self._olerepr_.mapFuncs.has_key(methodName):
0237                         item = self._olerepr_.mapFuncs[methodName]
0238                         return item.desc[4], item.dispid
0239 
0240                 if self._olerepr_.propMapGet.has_key(methodName):
0241                         item = self._olerepr_.propMapGet[methodName]
0242                         return item.desc[4], item.dispid
0243 
0244                 try:
0245                         dispid = self._oleobj_.GetIDsOfNames(0,methodName)
0246                 except:        ### what error?
0247                         return None, None
0248                 return pythoncom.DISPATCH_METHOD | pythoncom.DISPATCH_PROPERTYGET, dispid
0249 
0250         def _ApplyTypes_(self, dispid, wFlags, retType, argTypes, user, resultCLSID, *args):
0251                 result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args)
0252                 return self._get_good_object_(result, user, resultCLSID)
0253 
0254         def _wrap_dispatch_(self, ob, userName = None, returnCLSID = None, UnicodeToString = NeedUnicodeConversions):
0255                 # Given a dispatch object, wrap it in a class
0256                 return Dispatch(ob, userName, UnicodeToString=UnicodeToString)
0257 
0258         def _get_good_single_object_(self,ob,userName = None, ReturnCLSID=None):
0259                 if iunkType==type(ob):
0260                         try:
0261                                 ob = ob.QueryInterface(pythoncom.IID_IDispatch)
0262                                 # If this works, we then enter the "is dispatch" test below.
0263                         except pythoncom.com_error:
0264                                 # It is an IUnknown, but not an IDispatch, so just let it through.
0265                                 pass
0266                 if dispatchType==type(ob):
0267                         # make a new instance of (probably this) class.
0268                         return self._wrap_dispatch_(ob, userName, ReturnCLSID)
0269                 elif self._unicode_to_string_ and UnicodeType==type(ob):  
0270                         return str(ob)
0271                 else:
0272                         return ob
0273                 
0274         def _get_good_object_(self,ob,userName = None, ReturnCLSID=None):
0275                 """Given an object (usually the retval from a method), make it a good object to return.
0276                    Basically checks if it is a COM object, and wraps it up.
0277                    Also handles the fact that a retval may be a tuple of retvals"""
0278                 if ob is None: # Quick exit!
0279                         return None
0280                 elif type(ob)==TupleType:
0281                         return tuple(map(lambda o, s=self, oun=userName, rc=ReturnCLSID: s._get_good_single_object_(o, oun, rc),  ob))
0282                 else:
0283                         return self._get_good_single_object_(ob)
0284 
0285         def _make_method_(self, name):
0286                 "Make a method object - Assumes in olerepr funcmap"
0287                 methodName = build.MakePublicAttributeName(name) # translate keywords etc.
0288                 methodCodeList = self._olerepr_.MakeFuncMethod(self._olerepr_.mapFuncs[name], methodName,0)
0289                 methodCode = string.join(methodCodeList,"\n")
0290                 try:
0291 #                 print "Method code for %s is:\n" % self._username_, methodCode
0292 #                 self._print_details_()
0293                         codeObject = compile(methodCode, "<COMObject %s>" % self._username_,"exec")
0294                         # Exec the code object
0295                         tempNameSpace = {}
0296                         # "Dispatch" in the exec'd code is win32com.client.Dispatch, not ours.
0297                         globNameSpace = globals().copy()
0298                         globNameSpace["Dispatch"] = win32com.client.Dispatch
0299                         exec codeObject in globNameSpace, tempNameSpace # self.__dict__, self.__dict__
0300                         name = methodName
0301                         # Save the function in map.
0302                         fn = self._builtMethods_[name] = tempNameSpace[name]
0303                         newMeth = new.instancemethod(fn, self, self.__class__)
0304                         return newMeth
0305                 except:
0306                         debug_print("Error building OLE definition for code ", methodCode)
0307                         traceback.print_exc()
0308                 return None
0309                 
0310         def _Release_(self):
0311                 """Cleanup object - like a close - to force cleanup when you dont 
0312                    want to rely on Python's reference counting."""
0313                 for childCont in self._mapCachedItems_.values():
0314                         childCont._Release_()
0315                 self._mapCachedItems_ = {}
0316                 if self._oleobj_:
0317                         self._oleobj_.Release()
0318                         self.__dict__['_oleobj_'] = None
0319                 if self._olerepr_:
0320                         self.__dict__['_olerepr_'] = None
0321                 self._enum_ = None
0322 
0323         def _proc_(self, name, *args):
0324                 """Call the named method as a procedure, rather than function.
0325                    Mainly used by Word.Basic, which whinges about such things."""
0326                 try:
0327                         item = self._olerepr_.mapFuncs[name]
0328                         dispId = item.dispid
0329                         return self._get_good_object_(self._oleobj_.Invoke(*(dispId, LCID, item.desc[4], 0) + (args) ))
0330                 except KeyError:
0331                         raise AttributeError, name
0332                 
0333         def _print_details_(self):
0334                 "Debug routine - dumps what it knows about an object."
0335                 print "AxDispatch container",self._username_
0336                 try:
0337                         print "Methods:"
0338                         for method in self._olerepr_.mapFuncs.keys():
0339                                 print "\t", method
0340                         print "Props:"
0341                         for prop, entry in self._olerepr_.propMap.items():
0342                                 print "\t%s = 0x%x - %s" % (prop, entry.dispid, `entry`)
0343                         print "Get Props:"
0344                         for prop, entry in self._olerepr_.propMapGet.items():
0345                                 print "\t%s = 0x%x - %s" % (prop, entry.dispid, `entry`)
0346                         print "Put Props:"
0347                         for prop, entry in self._olerepr_.propMapPut.items():
0348                                 print "\t%s = 0x%x - %s" % (prop, entry.dispid, `entry`)
0349                 except:
0350                         traceback.print_exc()
0351 
0352         def __LazyMap__(self, attr):
0353                 try:
0354                         if self._LazyAddAttr_(attr):
0355                                 debug_attr_print("%s.__LazyMap__(%s) added something" % (self._username_,attr))
0356                                 return 1
0357                 except AttributeError:
0358                         return 0
0359 
0360         # Using the typecomp, lazily create a new attribute definition.
0361         def _LazyAddAttr_(self,attr):
0362                 if self._lazydata_ is None: return 0
0363                 res = 0
0364                 typeinfo, typecomp = self._lazydata_
0365                 olerepr = self._olerepr_
0366                 # We need to explicitly check each invoke type individually - simply
0367                 # specifying '0' will bind to "any member", which may not be the one
0368                 # we are actually after (ie, we may be after prop_get, but returned
0369                 # the info for the prop_put.)
0370                 for i in ALL_INVOKE_TYPES:
0371                         try:
0372                                 x,t = typecomp.Bind(attr,i)
0373                                 if x==1:        #it's a FUNCDESC
0374                                         r = olerepr._AddFunc_(typeinfo,t,0)
0375                                 elif x==2:        #it's a VARDESC
0376                                         r = olerepr._AddVar_(typeinfo,t,0)
0377                                 else:                #not found or TYPEDESC/IMPLICITAPP
0378                                         r=None
0379                                 if not r is None:
0380                                         key, map = r[0],r[1]
0381                                         item = map[key]
0382                                         if map==olerepr.propMapPut:
0383                                                 olerepr._propMapPutCheck_(key,item)
0384                                         elif map==olerepr.propMapGet:
0385                                                 olerepr._propMapGetCheck_(key,item)
0386                                         res = 1
0387                         except:
0388                                 pass
0389                 return res
0390 
0391         def _FlagAsMethod(self, *methodNames):
0392                 """Flag these attribute names as being methods.
0393                 Some objects do not correctly differentiate methods and
0394                 properties, leading to problems when calling these methods.
0395 
0396                 Specifically, trying to say: ob.SomeFunc()
0397                 may yield an exception "None object is not callable"
0398                 In this case, an attempt to fetch the *property*has worked
0399                 and returned None, rather than indicating it is really a method.
0400                 Calling: ob._FlagAsMethod("SomeFunc")
0401                 should then allow this to work.
0402                 """
0403                 for name in methodNames:
0404                         details = build.MapEntry(self.__AttrToID__(name), (name,))
0405                         self._olerepr_.mapFuncs[name] = details
0406 
0407         def __AttrToID__(self,attr):
0408                         debug_attr_print("Calling GetIDsOfNames for property %s in Dispatch container %s" % (attr, self._username_))
0409                         return self._oleobj_.GetIDsOfNames(0,attr)
0410 
0411         def __getattr__(self, attr):
0412                 if attr=='__iter__':
0413                         # We can't handle this as a normal method, as if the attribute
0414                         # exists, then it must return an iterable object.
0415                         try:
0416                                 invkind = pythoncom.DISPATCH_METHOD | pythoncom.DISPATCH_PROPERTYGET
0417                                 enum = self._oleobj_.InvokeTypes(pythoncom.DISPID_NEWENUM,LCID,invkind,(13, 10),())
0418                         except pythoncom.com_error:
0419                                 raise AttributeError, "This object can not function as an iterator"
0420                         # We must return a callable object.
0421                         class Factory:
0422                                 def __init__(self, ob):
0423                                         self.ob = ob
0424                                 def __call__(self):
0425                                         import win32com.client.util
0426                                         return win32com.client.util.Iterator(self.ob)
0427                         return Factory(enum)
0428                         
0429                 if attr[0]=='_' and attr[-1]=='_': # Fast-track.
0430                         raise AttributeError, attr
0431                 # If a known method, create new instance and return.
0432                 try:
0433                         return new.instancemethod(self._builtMethods_[attr], self, self.__class__)
0434                 except KeyError:
0435                         pass
0436                 # XXX - Note that we current are case sensitive in the method.
0437                 #debug_attr_print("GetAttr called for %s on DispatchContainer %s" % (attr,self._username_))
0438                 # First check if it is in the method map.  Note that an actual method
0439                 # must not yet exist, (otherwise we would not be here).  This
0440                 # means we create the actual method object - which also means
0441                 # this code will never be asked for that method name again.
0442                 if self._olerepr_.mapFuncs.has_key(attr):
0443                         return self._make_method_(attr)
0444 
0445                 # Delegate to property maps/cached items
0446                 retEntry = None
0447                 if self._olerepr_ and self._oleobj_:
0448                         # first check general property map, then specific "put" map.
0449                         retEntry = self._olerepr_.propMap.get(attr)
0450                         if retEntry is None:
0451                                 retEntry = self._olerepr_.propMapGet.get(attr)
0452                         # Not found so far - See what COM says.
0453                         if retEntry is None:
0454                                 try:
0455                                         if self.__LazyMap__(attr):
0456                                                 if self._olerepr_.mapFuncs.has_key(attr): return self._make_method_(attr)
0457                                                 retEntry = self._olerepr_.propMap.get(attr)
0458                                                 if retEntry is None:
0459                                                         retEntry = self._olerepr_.propMapGet.get(attr)
0460                                         if retEntry is None:
0461                                                 retEntry = build.MapEntry(self.__AttrToID__(attr), (attr,))
0462                                 except pythoncom.ole_error:
0463                                         pass # No prop by that name - retEntry remains None.
0464 
0465                 if not retEntry is None: # see if in my cache
0466                         try:
0467                                 ret = self._mapCachedItems_[retEntry.dispid]
0468                                 debug_attr_print ("Cached items has attribute!", ret)
0469                                 return ret
0470                         except (KeyError, AttributeError):
0471                                 debug_attr_print("Attribute %s not in cache" % attr)
0472 
0473                 # If we are still here, and have a retEntry, get the OLE item
0474                 if not retEntry is None:
0475                         invoke_type = _GetDescInvokeType(retEntry, pythoncom.INVOKE_PROPERTYGET)
0476                         debug_attr_print("Getting property Id 0x%x from OLE object" % retEntry.dispid)
0477                         try:
0478                                 ret = self._oleobj_.Invoke(retEntry.dispid,0,invoke_type,1)
0479                         except pythoncom.com_error, details:
0480                                 if details[0] in ERRORS_BAD_CONTEXT:
0481                                         # May be a method.
0482                                         self._olerepr_.mapFuncs[attr] = retEntry
0483                                         return self._make_method_(attr)
0484                                 raise pythoncom.com_error, details
0485                         debug_attr_print("OLE returned ", ret)
0486                         return self._get_good_object_(ret)
0487 
0488                 # no where else to look.
0489                 raise AttributeError, "%s.%s" % (self._username_, attr)
0490 
0491         def __setattr__(self, attr, value):
0492                 if self.__dict__.has_key(attr): # Fast-track - if already in our dict, just make the assignment.
0493                         # XXX - should maybe check method map - if someone assigns to a method,
0494                         # it could mean something special (not sure what, tho!)
0495                         self.__dict__[attr] = value
0496                         return
0497                 # Allow property assignment.
0498                 debug_attr_print("SetAttr called for %s.%s=%s on DispatchContainer" % (self._username_, attr, `value`))
0499 
0500                 if self._olerepr_:
0501                         # Check the "general" property map.
0502                         if self._olerepr_.propMap.has_key(attr):
0503                                 entry = self._olerepr_.propMap[attr]
0504                                 invoke_type = _GetDescInvokeType(entry, pythoncom.INVOKE_PROPERTYPUT)
0505                                 self._oleobj_.Invoke(entry.dispid, 0, invoke_type, 0, value)
0506                                 return
0507                         # Check the specific "put" map.
0508                         if self._olerepr_.propMapPut.has_key(attr):
0509                                 entry = self._olerepr_.propMapPut[attr]
0510                                 invoke_type = _GetDescInvokeType(entry, pythoncom.INVOKE_PROPERTYPUT)
0511                                 self._oleobj_.Invoke(entry.dispid, 0, invoke_type, 0, value)
0512                                 return
0513 
0514                 # Try the OLE Object
0515                 if self._oleobj_:
0516                         if self.__LazyMap__(attr):
0517                                 # Check the "general" property map.
0518                                 if self._olerepr_.propMap.has_key(attr):
0519                                         entry = self._olerepr_.propMap[attr]
0520                                         invoke_type = _GetDescInvokeType(entry, pythoncom.INVOKE_PROPERTYPUT)
0521                                         self._oleobj_.Invoke(entry.dispid, 0, invoke_type, 0, value)
0522                                         return
0523                                 # Check the specific "put" map.
0524                                 if self._olerepr_.propMapPut.has_key(attr):
0525                                         entry = self._olerepr_.propMapPut[attr]
0526                                         invoke_type = _GetDescInvokeType(entry, pythoncom.INVOKE_PROPERTYPUT)
0527                                         self._oleobj_.Invoke(entry.dispid, 0, invoke_type, 0, value)
0528                                         return
0529                         try:
0530                                 entry = build.MapEntry(self.__AttrToID__(attr),(attr,))
0531                         except pythoncom.com_error:
0532                                 # No attribute of that name
0533                                 entry = None
0534                         if entry is not None:
0535                                 try:
0536                                         invoke_type = _GetDescInvokeType(entry, pythoncom.INVOKE_PROPERTYPUT)
0537                                         self._oleobj_.Invoke(entry.dispid, 0, invoke_type, 0, value)
0538                                         self._olerepr_.propMap[attr] = entry
0539                                         debug_attr_print("__setattr__ property %s (id=0x%x) in Dispatch container %s" % (attr, entry.dispid, self._username_))
0540                                         return
0541                                 except pythoncom.com_error:
0542                                         pass
0543                 raise AttributeError, "Property '%s.%s' can not be set." % (self._username_, attr)
0544 

Generated by PyXR 0.9.4
SourceForge.net Logo