Skip to content

Commit

Permalink
Take some first steps to resolving TYPEDESC and FUNCDESC confusion
Browse files Browse the repository at this point in the history
* Instead of passing around tuples, we now pass PyFUNCDESC and PyVARDESC
  objects everywhere instead of converting to a tuple at the first
  opportunity.

* Use `desc.memid` instead of `desc[0]`, because element zero is
  `memid` in both types.
  • Loading branch information
mhammond committed Mar 30, 2021
1 parent 8ea6d30 commit 1a938d3
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 24 deletions.
20 changes: 10 additions & 10 deletions com/win32com/client/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ def _propMapGetCheck_(self,key,item):
del self.propMapGet[key]

def _AddFunc_(self,typeinfo,fdesc,bForUser):
assert(fdesc.desckind == pythoncom.DESCKIND_FUNCDESC)
id = fdesc.memid
funcflags = fdesc.wFuncFlags
try:
Expand Down Expand Up @@ -221,25 +222,26 @@ def _AddFunc_(self,typeinfo,fdesc,bForUser):
if not map is None:
# if map.has_key(name):
# sys.stderr.write("Warning - overwriting existing method/attribute %s\n" % name)
map[name] = MapEntry(tuple(fdesc), names, doc, resultCLSID, resultDoc, hidden)
map[name] = MapEntry(fdesc, names, doc, resultCLSID, resultDoc, hidden)
# any methods that can't be reached via DISPATCH we return None
# for, so dynamic dispatch doesnt see it.
if fdesc.funckind != pythoncom.FUNC_DISPATCH:
return None
return (name,map)
return None

def _AddVar_(self,typeinfo,fdesc,bForUser):
def _AddVar_(self, typeinfo, vardesc, bForUser):
### need pythoncom.VARFLAG_FRESTRICTED ...
### then check it
assert(vardesc.desckind == pythoncom.DESCKIND_VARDESC)

if fdesc.varkind == pythoncom.VAR_DISPATCH:
id = fdesc.memid
if vardesc.varkind == pythoncom.VAR_DISPATCH:
id = vardesc.memid
names = typeinfo.GetNames(id)
# Translate any Alias or Enums in result.
typerepr, flags, defval = fdesc.elemdescVar
typerepr, flags, defval = vardesc.elemdescVar
typerepr, resultCLSID, resultDoc = _ResolveType(typerepr, typeinfo)
fdesc.elemdescVar = typerepr, flags, defval
vardesc.elemdescVar = typerepr, flags, defval
doc = None
try:
if bForUser: doc = typeinfo.GetDocumentation(id)
Expand All @@ -249,10 +251,8 @@ def _AddVar_(self,typeinfo,fdesc,bForUser):
# handle the enumerator specially
map = self.propMap
# Check if the element is hidden.
hidden = 0
if hasattr(fdesc,"wVarFlags"):
hidden = (fdesc.wVarFlags & 0x40) != 0 # VARFLAG_FHIDDEN
map[names[0]] = MapEntry(tuple(fdesc), names, doc, resultCLSID, resultDoc, hidden)
hidden = (vardesc.wVarFlags & 0x40) != 0 # VARFLAG_FHIDDEN
map[names[0]] = MapEntry(vardesc, names, doc, resultCLSID, resultDoc, hidden)
return (names[0],map)
else:
return None
Expand Down
4 changes: 2 additions & 2 deletions com/win32com/client/dynamic.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,9 +448,9 @@ def _LazyAddAttr_(self,attr):
# bug 1587023
if x==0 and attr[:3] in ('Set', 'Get'):
x,t = typecomp.Bind(attr[3:], i)
if x==1: #it's a FUNCDESC
if x==pythoncom.DESCKIND_FUNCDESC: #it's a FUNCDESC
r = olerepr._AddFunc_(typeinfo,t,0)
elif x==2: #it's a VARDESC
elif x==pythoncom.DESCKIND_VARDESC: #it's a VARDESC
r = olerepr._AddVar_(typeinfo,t,0)
else: #not found or TYPEDESC/IMPLICITAPP
r=None
Expand Down
27 changes: 15 additions & 12 deletions com/win32com/client/genpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def WriteSinkEventMap(obj, stream):
print('\t_dispid_to_func_ = {', file=stream)
for name, entry in list(obj.propMapGet.items()) + list(obj.propMapPut.items()) + list(obj.mapFuncs.items()):
fdesc = entry.desc
print('\t\t%9d : "%s",' % (entry.desc[0], MakeEventMethodName(entry.names[0])), file=stream)
print('\t\t%9d : "%s",' % (fdesc.memid, MakeEventMethodName(entry.names[0])), file=stream)
print('\t\t}', file=stream)


Expand Down Expand Up @@ -245,7 +245,7 @@ def WriteVTableMap(self, generator):
item_num = item_num + 1
if item_num % 5 == 0:
print("\n\t\t\t", end=' ', file=stream)
print("), %d, (%r, %r, [" % (dispid, desc[0], desc[1]), end=' ', file=stream)
print("), %d, (%r, %r, [" % (dispid, desc.memid, desc[1]), end=' ', file=stream)
for arg in arg_desc:
item_num = item_num + 1
if item_num % 5 == 0:
Expand All @@ -257,7 +257,10 @@ def WriteVTableMap(self, generator):
arg3_repr = repr(arg[3])
print(repr((arg[0], arg[1], defval, arg3_repr)), ",", end=' ', file=stream)
print("],", end=' ', file=stream)
for d in desc[3:]:
# XXX - upgrade below to using attributes once we are confident whether we
# are dealing with a TYPEDESC or FUNCDESC - it's almost certainly the
# latter, but...
for d in tuple(desc)[3:]:
print(repr(d), ",", end=' ', file=stream)
print(")),", file=stream)
print("]", file=stream)
Expand Down Expand Up @@ -373,7 +376,7 @@ def WriteClassBody(self, generator):
# skip [restricted] methods, unless it is the
# enumerator (which, being part of the "system",
# we know about and can use)
dispid = entry.desc[0]
dispid = entry.desc.memid
if entry.desc[9] & pythoncom.FUNCFLAG_FRESTRICTED and \
dispid != pythoncom.DISPID_NEWENUM:
continue
Expand Down Expand Up @@ -409,19 +412,19 @@ def WriteClassBody(self, generator):
details = entry.desc
resultDesc = details[2]
argDesc = ()
mapEntry = MakeMapLineEntry(details[0], pythoncom.DISPATCH_PROPERTYGET, resultDesc, argDesc, key, entry.GetResultCLSIDStr())
mapEntry = MakeMapLineEntry(details.memid, pythoncom.DISPATCH_PROPERTYGET, resultDesc, argDesc, key, entry.GetResultCLSIDStr())

if entry.desc[0]==pythoncom.DISPID_VALUE:
if details.memid==pythoncom.DISPID_VALUE:
lkey = "value"
elif entry.desc[0]==pythoncom.DISPID_NEWENUM:
elif details.memid==pythoncom.DISPID_NEWENUM:
lkey = "_newenum"
else:
lkey = key.lower()
if lkey in specialItems and specialItems[lkey] is None: # remember if a special one.
specialItems[lkey] = (entry, pythoncom.DISPATCH_PROPERTYGET, mapEntry)
# All special methods, except _newenum, are written
# "normally". This is a mess!
if entry.desc[0]==pythoncom.DISPID_NEWENUM:
if details.memid==pythoncom.DISPID_NEWENUM:
continue

print('\t\t"%s": %s,' % (build.MakePublicAttributeName(key), mapEntry), file=stream)
Expand All @@ -436,17 +439,17 @@ def WriteClassBody(self, generator):
argDesc = details[2]
resultDesc = details[8]
mapEntry = MakeMapLineEntry(details[0], pythoncom.DISPATCH_PROPERTYGET, resultDesc, argDesc, key, entry.GetResultCLSIDStr())
if entry.desc[0]==pythoncom.DISPID_VALUE:
if details.memid==pythoncom.DISPID_VALUE:
lkey = "value"
elif entry.desc[0]==pythoncom.DISPID_NEWENUM:
elif details.memid==pythoncom.DISPID_NEWENUM:
lkey = "_newenum"
else:
lkey = key.lower()
if lkey in specialItems and specialItems[lkey] is None: # remember if a special one.
specialItems[lkey]=(entry, pythoncom.DISPATCH_PROPERTYGET, mapEntry)
# All special methods, except _newenum, are written
# "normally". This is a mess!
if entry.desc[0]==pythoncom.DISPID_NEWENUM:
if details.memid==pythoncom.DISPID_NEWENUM:
continue
print('\t\t"%s": %s,' % (build.MakePublicAttributeName(key), mapEntry), file=stream)

Expand Down Expand Up @@ -526,7 +529,7 @@ def WriteClassBody(self, generator):
print('\t#Note that many Office objects do not use zero-based indexing.', file=stream)
print('\tdef __getitem__(self, key):', file=stream)
print('\t\treturn self._get_good_object_(self._oleobj_.Invoke(*(%d, LCID, %d, 1, key)), "Item", %s)' \
% (entry.desc[0], invoketype, resultCLSID), file=stream)
% (entry.desc.memid, invoketype, resultCLSID), file=stream)

if specialItems["count"]:
entry, invoketype, propArgs = specialItems["count"]
Expand Down

0 comments on commit 1a938d3

Please sign in to comment.