mhammond / pywin32

Python for Windows (pywin32) Extensions
5.06k stars 799 forks source link

AttributeError #1930

Closed TomYaboYogaWorkout closed 2 years ago

TomYaboYogaWorkout commented 2 years ago

I use the pywin32 library since one week to parse visio files to extract shapes and their content. I ran my scripts several times but since yesterday when I execute them I have this error :

File "C:\Program Files\Python39\lib\site-packages\win32com\client\__init__.py", line 580, in __getattr__ raise AttributeError( AttributeError: '<win32com.gen_py.Microsoft Visio 16.0 Type Library.IVDocument instance at 0x1943434388768>' object has no attribute 'pages'

Here is the part of my script which generate the error :

import glob
import os
import win32com.client as w32

path = r"C\Users\..." 
all_files = glob.glob(path + "/*.vsd")
visio = w32.Dispatch("visio.Application")

for filename in all_files:

    print(filename)
    vdoc = visio.Documents.Open(filename) 
    page = vdoc.pages(1) <-- the problematic line
    shps = page.Shapes 

I make a list of visio files and after I open them in the for loop I read the first page (they have all one page). The first visio open as well but after I have the error. I tried to uninstall et reinstall pywin32, I worked in another repertory, change my import name... I tried on an another pc and pywin32 works as well. I really don't understand why python rise this error now, above all I don't touch this line . Have you some ideas to resolve this problem ?

I use pywin 304 and python 3.9.13

mhammond commented 2 years ago

Instead of visio = w32.Dispatch("visio.Application"), try visio = w32.EnsureDispatch("visio.Application") - that will ensure makepy support exists for the object.

TomYaboYogaWorkout commented 2 years ago

I have an new error : AttributeError: module 'win32com.client' has no attribute 'EnsureDispatch'

mhammond commented 2 years ago

oops - from win32com.client.gencache import EnsureDispatch

TomYaboYogaWorkout commented 2 years ago

Sorry but I am back on the first error : File "C:\Program Files\Python39\lib\site-packages\win32com\client\__init__.py", line 580, in __getattr__ raise AttributeError( AttributeError: '<win32com.gen_py.Microsoft Visio 16.0 Type Library.IVDocument instance at 0x1959880910256>' object has no attribute 'pages'

mhammond commented 2 years ago

That will have generated a file in win32com.gen_py.__path__ - you should see how it references page - possibly via a method called GetPages or similar. Alternatively, use the slower win32com.client.dynamic.DumbDispatch(), which will ignore that type info.

TomYaboYogaWorkout commented 2 years ago

I didn't find win32com.gen_py.__path__ but I found genpy.py in client and I don't find any pages or GetPages references . So I understand that show me this error but I don't understand why this error is risen just now. I tried the DumbDispatch() methode too but I still have the same AttributeError.

kxrob commented 2 years ago

I didn't find win32com.gen_py.__path__ but I found genpy.py in client and I don't find any pages or GetPages references

print or interactively ask win32com.gen_py.__path__ and/or specifically vdoc.__module__; sys.modules[_] : Its shows the folder / file where the generated types are pre-compiled.
Its probably case sensitive vdoc.Pages. You may also erase / rename the generated files (incl. dicts.dat) to get back to the dynamic types - when no speed issue.

You may have used the dynamic types first, and later the generated via EnsureDispatch() / makepy or so.

For some classes the COM type info required for generated types is incomplete (but probably not for Visio) and currently the generated types don't fall back to the dynamic attribute search. I have a patch, which I put as PR #1931, that does this ...

TomYaboYogaWorkout commented 2 years ago

So, I solved the problem I just capitalized all .Pages/.Type/.Text/.Shapes/.Names. And my script run again. I don't understand what happened because it works before without any capital letters... I am a begginer in Python. Sorry for the inconvenience and thank you for your help.

kxrob commented 2 years ago

I don't understand what happened because it works before without any capital letters

As indicated, first you used the (default) dynamic on-the-fly COM interface via .Dispatch() only - which is effectively case insensitive like VB: It asks the case insensitive COM on the fly (when not already cached) extra for each property name to find the property ID.

Later somehow (by EnsureDispatch() / CastTo() / Record() / makepy utility or so) you caused generation of a (faster) "pre-compiled" python interface module file for the "Microsoft Visio 16.0 Type Library" - which you can inspect / print() as sys.modules[vdoc.__module__] - it's a .py file with a long cryptic file name. The generated classes in that module are Python kind of case sensitive.