def __setattr__(self, attr, value): if self.__dict__.has_key( attr ): # Fast-track - if already in our dict, just make the assignment. # XXX - should maybe check method map - if someone assigns to a method, # it could mean something special (not sure what, tho!) self.__dict__[attr] = value return # Allow property assignment. debug_attr_print("SetAttr called for %s.%s=%s on DispatchContainer" % (self._username_, attr, ` value `)) if self._olerepr_: # Check the "general" property map. if self._olerepr_.propMap.has_key(attr): self._oleobj_.Invoke(self._olerepr_.propMap[attr].dispid, 0, pythoncom.DISPATCH_PROPERTYPUT, 0, value) return # Check the specific "put" map. if self._olerepr_.propMapPut.has_key(attr): self._oleobj_.Invoke(self._olerepr_.propMapPut[attr].dispid, 0, pythoncom.DISPATCH_PROPERTYPUT, 0, value) return # Try the OLE Object if self._oleobj_: if self.__LazyMap__(attr): # Check the "general" property map. if self._olerepr_.propMap.has_key(attr): self._oleobj_.Invoke(self._olerepr_.propMap[attr].dispid, 0, pythoncom.DISPATCH_PROPERTYPUT, 0, value) return # Check the specific "put" map. if self._olerepr_.propMapPut.has_key(attr): self._oleobj_.Invoke( self._olerepr_.propMapPut[attr].dispid, 0, pythoncom.DISPATCH_PROPERTYPUT, 0, value) return try: entry = build.MapEntry(self.__AttrToID__(attr), (attr, )) except pythoncom.com_error: # No attribute of that name entry = None if entry is not None: try: self._oleobj_.Invoke(entry.dispid, 0, pythoncom.DISPATCH_PROPERTYPUT, 0, value) self._olerepr_.propMap[attr] = entry debug_attr_print( "__setattr__ property %s (id=0x%x) in Dispatch container %s" % (attr, entry.dispid, self._username_)) return except pythoncom.com_error: pass raise AttributeError, "Property '%s.%s' can not be set." % ( self._username_, attr)
def __init__(self, typeinfo, attr, doc=None, bForUser=1): build.OleItem.__init__(self, doc) self.clsid = attr[0] self.mapVars = {} typeFlags = attr[11] self.hidden = typeFlags & pythoncom.TYPEFLAG_FHIDDEN or \ typeFlags & pythoncom.TYPEFLAG_FRESTRICTED for j in range(attr[7]): vdesc = typeinfo.GetVarDesc(j) name = typeinfo.GetNames(vdesc[0])[0] self.mapVars[name] = build.MapEntry(vdesc)
def _FlagAsMethod(self, *methodNames): """Flag these attribute names as being methods. Some objects do not correctly differentiate methods and properties, leading to problems when calling these methods. Specifically, trying to say: ob.SomeFunc() may yield an exception "None object is not callable" In this case, an attempt to fetch the *property*has worked and returned None, rather than indicating it is really a method. Calling: ob._FlagAsMethod("SomeFunc") should then allow this to work. """ for name in methodNames: details = build.MapEntry(self.__AttrToID__(name), (name, )) self._olerepr_.mapFuncs[name] = details
def __getattr__(self, attr): if attr == '__iter__': # We can't handle this as a normal method, as if the attribute # exists, then it must return an iterable object. try: invkind = pythoncom.DISPATCH_METHOD | pythoncom.DISPATCH_PROPERTYGET enum = self._oleobj_.InvokeTypes(pythoncom.DISPID_NEWENUM, LCID, invkind, (13, 10), ()) except pythoncom.com_error: raise AttributeError( "This object can not function as an iterator") # We must return a callable object. class Factory: def __init__(self, ob): self.ob = ob def __call__(self): import win32com.client.util return win32com.client.util.Iterator(self.ob) return Factory(enum) if attr.startswith('_') and attr.endswith('_'): # Fast-track. raise AttributeError(attr) # If a known method, create new instance and return. try: return MakeMethod(self._builtMethods_[attr], self, self.__class__) except KeyError: pass # XXX - Note that we current are case sensitive in the method. #debug_attr_print("GetAttr called for %s on DispatchContainer %s" % (attr,self._username_)) # First check if it is in the method map. Note that an actual method # must not yet exist, (otherwise we would not be here). This # means we create the actual method object - which also means # this code will never be asked for that method name again. if attr in self._olerepr_.mapFuncs: return self._make_method_(attr) # Delegate to property maps/cached items retEntry = None if self._olerepr_ and self._oleobj_: # first check general property map, then specific "put" map. retEntry = self._olerepr_.propMap.get(attr) if retEntry is None: retEntry = self._olerepr_.propMapGet.get(attr) # Not found so far - See what COM says. if retEntry is None: try: if self.__LazyMap__(attr): if attr in self._olerepr_.mapFuncs: return self._make_method_(attr) retEntry = self._olerepr_.propMap.get(attr) if retEntry is None: retEntry = self._olerepr_.propMapGet.get(attr) if retEntry is None: retEntry = build.MapEntry(self.__AttrToID__(attr), (attr, )) except pythoncom.ole_error: pass # No prop by that name - retEntry remains None. if not retEntry is None: # see if in my cache try: ret = self._mapCachedItems_[retEntry.dispid] debug_attr_print("Cached items has attribute!", ret) return ret except (KeyError, AttributeError): debug_attr_print("Attribute %s not in cache" % attr) # If we are still here, and have a retEntry, get the OLE item if not retEntry is None: invoke_type = _GetDescInvokeType(retEntry, pythoncom.INVOKE_PROPERTYGET) debug_attr_print("Getting property Id 0x%x from OLE object" % retEntry.dispid) try: ret = self._oleobj_.Invoke(retEntry.dispid, 0, invoke_type, 1) except pythoncom.com_error, details: if details.hresult in ERRORS_BAD_CONTEXT: # May be a method. self._olerepr_.mapFuncs[attr] = retEntry return self._make_method_(attr) raise debug_attr_print("OLE returned ", ret) return self._get_good_object_(ret)
def __getattr__(self, attr): if attr[0] == '_' and attr[-1] == '_': # Fast-track. raise AttributeError, attr # If a known method, create new instance and return. try: return new.instancemethod(self._builtMethods_[attr], self, self.__class__) except KeyError: pass # XXX - Note that we current are case sensitive in the method. #debug_attr_print("GetAttr called for %s on DispatchContainer %s" % (attr,self._username_)) # First check if it is in the method map. Note that an actual method # must not yet exist, (otherwise we would not be here). This # means we create the actual method object - which also means # this code will never be asked for that method name again. if self._olerepr_.mapFuncs.has_key(attr): return self._make_method_(attr) # Delegate to property maps/cached items retEntry = None if self._olerepr_ and self._oleobj_: # first check general property map, then specific "put" map. if self._olerepr_.propMap.has_key(attr): retEntry = self._olerepr_.propMap[attr] if retEntry is None and self._olerepr_.propMapGet.has_key(attr): retEntry = self._olerepr_.propMapGet[attr] # Not found so far - See what COM says. if retEntry is None: try: if self.__LazyMap__(attr): if self._olerepr_.mapFuncs.has_key(attr): return self._make_method_(attr) if self._olerepr_.propMap.has_key(attr): retEntry = self._olerepr_.propMap[attr] if retEntry is None and self._olerepr_.propMapGet.has_key( attr): retEntry = self._olerepr_.propMapGet[attr] if retEntry is None: retEntry = build.MapEntry(self.__AttrToID__(attr), (attr, )) except pythoncom.ole_error: pass # No prop by that name - retEntry remains None. if not retEntry is None: # see if in my cache try: ret = self._mapCachedItems_[retEntry.dispid] debug_attr_print("Cached items has attribute!", ret) return ret except (KeyError, AttributeError): debug_attr_print("Attribute %s not in cache" % attr) # If we are still here, and have a retEntry, get the OLE item if not retEntry is None: debug_attr_print("Getting property Id 0x%x from OLE object" % retEntry.dispid) try: ret = self._oleobj_.Invoke(retEntry.dispid, 0, pythoncom.DISPATCH_PROPERTYGET, 1) except pythoncom.com_error, details: if details[0] in ERRORS_BAD_CONTEXT: # May be a method. self._olerepr_.mapFuncs[attr] = retEntry return self._make_method_(attr) raise pythoncom.com_error, details self._olerepr_.propMap[attr] = retEntry debug_attr_print("OLE returned ", ret) return self._get_good_object_(ret)