python-win32com excel com model started generating errors - python

Over the last few days, I have been working on automating the generation of some pivot tables for a number of reports.
Boiled down to the minimum, the following code was working without issue:
import win32com.client
objExcelApp = win32com.client.gencache.EnsureDispatch('Excel.Application')
objExcelApp.Visible = 1
This would pop-up an instance of excel and I could continue working in Python. But suddenly, today my scripts are failing with the following:
>>>import win32com.client
>>> objExcelApp = win32com.client.gencache.EnsureDispatch('Excel.Application')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Program Files (x86)\Python37-32\lib\site-packages\win32com\client\gencache.py", line 534, in EnsureDispatch
mod = EnsureModule(tla[0], tla[1], tla[3], tla[4], bForDemand=bForDemand)
File "C:\Program Files (x86)\Python37-32\lib\site-packages\win32com\client\gencache.py", line 391, in EnsureModule
module = GetModuleForTypelib(typelibCLSID, lcid, major, minor)
File "C:\Program Files (x86)\Python37-32\lib\site-packages\win32com\client\gencache.py", line 266, in GetModuleForTypelib
AddModuleToCache(typelibCLSID, lcid, major, minor)
File "C:\Program Files (x86)\Python37-32\lib\site-packages\win32com\client\gencache.py", line 552, in AddModuleToCache
dict = mod.CLSIDToClassMap
AttributeError: module 'win32com.gen_py.00020813-0000-0000-C000-000000000046x0x1x9' has no attribute 'CLSIDToClassMap'
The code has not changed from yesterday to today. I have no idea what is happening!!!.
Another interesting kicker. if I do the same code in the same session again I get a different error:
>>> objExcelApp = win32com.client.gencache.EnsureDispatch('Excel.Application')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Program Files (x86)\Python37-32\lib\site-packages\win32com\client\gencache.py", line 534, in EnsureDispatch
mod = EnsureModule(tla[0], tla[1], tla[3], tla[4], bForDemand=bForDemand)
File "C:\Program Files (x86)\Python37-32\lib\site-packages\win32com\client\gencache.py", line 447, in EnsureModule
if module.MinorVersion != tlbAttributes[4] or genpy.makepy_version != module.makepy_version:
AttributeError: module 'win32com.gen_py.00020813-0000-0000-C000-000000000046x0x1x9' has no attribute 'MinorVersion'
>>>
So I jump over to a windows machine with a fresh windows install, install python37 and pip install pypiwin32. Run the very same lines and excel opens just like it did yesterday on my original machine.
I tried un-installing and re-installing with no luck. Any idea what is going on here?
NOTE:
Dynamic dispatch still works:
import win32com.client
objExcelApp = win32com.client.Dispatch("Excel.Application")
objExcelApp.Visible = 1
But I specifically need static dispatch as Pivot Tables won't work with a dynamically dispatched object (much later in my code):
objExcelPivotCache = objExcelWorkbook.PivotCaches().Create(SourceType=win32c.xlDatabase, SourceData=objExcelPivotSourceRange)

I had the same issue and I resolved it by following the instructions here: https://mail.python.org/pipermail/python-win32/2007-August/006147.html
Deleting the gen_py output directory and re-running makepy SUCCEEDS
and subsequently the test application runs OK again.
So the symptom is resolved, but any clues as to how this could have
happened. This is a VERY long running application (think 24x7 for
years) and I'm concerned that whatever caused this might occur again.
To find the output directory, run this in your python console / python session:
import win32com
print(win32com.__gen_path__)
Based on the exception message in your post, the directory you need to remove will be titled '00020813-0000-0000-C000-000000000046x0x1x9'. So delete this directory and re-run the code. And if you're nervous about deleting it (like I was) just cut the directory and paste it somewhere else.
💡Note that this directory is usually in your "TEMP" directory (copy-paste %TEMP%/gen_py in Windows File Explorer and you will arrive there directly).
I have no idea why this happens nor do I know how to prevent it from happening again, but the directions in the link I provided seemed to work for me.

A more straightforward solution was posted in a related question Issue in using win32com to access Excel file.
Basically, you just need to delete the folder C:\Users\<your username>\AppData\Local\Temp\gen_py and rerun your code.
💡TIP: You can also put in your Windows file explorer %TEMP%\gen_py to access it directly, and then delete its content.

Execute this command line in a powershell or cmd (NOT in Administrator mode => wouldn't work for me)
python -m win32com.client.makepy "Excel.Application"
It fixes all errors and you don't have to change your python code.
And keep using
win32com.client.gencache.EnsureDispatch("Excel.Application")
With gencache.EnsureDispatch you have access to the constants of the application loaded dynamically by makepy which must have the registered application (in our case Excel.Application).
If you have the same problem with Outlook, use "Outlook.Application" in above.
If still not working, reinstall pywin32 of your python distribution
<path to python root or venv>\pip.exe uninstall pywin32
<path to python root or venv>\pip.exe install pywin32

What has worked for me is:
excel = win32.gencache.EnsureDispatch('Excel.Application')
#change to =>
excel = win32.Dispatch('Excel.Application')

For me, it seems, the issue was that I have multiple processes that interact with Windows apps through win32com.
Since win32com creates the "gen_py" directory in win32api.GetTempPath() this can cause conflicts and the cache getting corrupted.
My solution is to set a custom location for "gen_py" for each process. A simple example:
from pathlib import Path
import win32com
gen_py_path = '/some/custom/location/gen_py'
Path(gen_py_path).mkdir(parents=True, exist_ok=True)
win32com.__gen_path__ = gen_py_path
# Any other imports/code that uses win32com
This way you don't have to delete the default "gen_py" folder and wonder what issues might arise. But if you still find you need to delete, you can just delete the custom folder and know you're deleting the cache just for that process.

To add to this discussion, for those receiving this error as part of an unsupervised automated process, you can fully automating the recovery process and allow any processes to continue unsupervised.
As answers by Ian and Qin mention, we need to delete the gen_py output directory and restart the process. As far as automation goes, there are two problems with this: the gen_py output directory is a temporary directory that can change, and currently running processes that rely on gen_py continue to fail even after it is regenerated.
To address these problems, we can dynamically look up the location, then we can completely nuke the whole process and restart it. I've tried deleting and re-importing win32com, but it seems a reference to the corrupted cache is still maintained, so the whole process needs to be restarted.
temp_data_dir = os.environ.get('LOCALAPPDATA'))
gen_py_dir = ''
for curr_path, dirs, files, in walk(temp_data_dir)
if 'gen_py' in dirs:
gen_py_dir = Path(curr_path).joinpath('gen_py')
shutil.rmtree(gen_py_dir)
execv(restart_args)
The restarted process should call win32com.client.gencache.EnsureDispatch('Excel.Application') again and a fresh copy of gen_py will now be utilized, then we can retry the failed Excel automation code.
The issue happens sporadically in a completely unreliable way that I can't replicate. My best guess is that the gen_py cache is sometimes corrupted somehow and just needs to be refreshed.

Related

How to get past the AttributeError in Gnu Radio version 3.8

Here is the error I am recieving:
Traceback (most recent call last):
File "/home/awilhelmy5/Downloads/qpsk-adaptive-master/gnuradio/qpsk_usrp.py", line 354, in <module>
main()
File "/home/awilhelmy5/Downloads/qpsk-adaptive-master/gnuradio/qpsk_usrp.py", line 332, in main
tb = top_block_cls()
File "/home/awilhelmy5/Downloads/qpsk-adaptive-master/gnuradio/qpsk_usrp.py", line 148, in __init__
self.mapper_preamble_sync_demapper_hard_0 = mapper.preamble_sync_dehard(0, per_bits, mapper.QPSK, [0,1,3,2], 0, 3, False)
AttributeError: module 'mapper' has no attribute 'preamble_sync_dehard'
The very last line of the error is the part that is bugging me. I have tried a multitude of things, such as installing swig version 4.0, tried doing the sudo ldconfig command, tried reversing the order of the commands in the .h file, I changed the yml file name to match the name it had in the xml file and I even started messing around with the target_link
_libraries command. Any help would be greatly appreciated!
Is it possible that your code has an error (e.g. accidental deletion of some characters)? I ask because I was not able to find the text "preamble_sync_dehard" anywhere on the web, but there is a class called gr::mapper::preamble_sync_demapper_hard. Perhaps some person or program did an unwise find-and-replace that intended to remove a prefix mapper_ but ended up removing a substring instead. You can check whether this is the problem: run Python and enter
import mapper
dir(mapper)
This will list all the names in the Python module, one of which (if this is the only problem) will be preamble_sync_demapper_hard, or some related spelling which you can then adjust your qpsk_usrp.py to use.
But if it is not there at all, then you may have a bigger problem. From what I have heard, OOT modules generally have to have their structure updated in order to work with GNU Radio 3.8, and the repository I found doesn't seem to have been touched since 2018 (before 3.8 was released in 2019).

Why isn't my code working in command line?

I am using Python3.6 and I need to run my code in command line. The code works when I run it in PyCharm but when I use command line I get this error:
File "path", line 43, in <module>
rb = ds.GetRasterBand(1)
AttributeError: 'NoneType' object has no attribute 'GetRasterBand'
It seems that I have a problem with these lines:
ds = gdal.Open('tif_file.tif', gdal.GA_ReadOnly)
rb = ds.GetRasterBand(1)
img_array = rb.ReadAsArray()
Does anyone know what I might have done wrong?
EDIT
Some magic just happened. I tried to run my code this morning and everything seems fine. I guess what my computer needed was a restart or something. Thanks to you all for help.
from the gdal documentation:
from osgeo import gdal
dataset = gdal.Open(filename, gdal.GA_ReadOnly)
if not dataset:
...
Note that if GDALOpen() returns NULL it means the open failed, and
that an error messages will already have been emitted via CPLError().
If you want to control how errors are reported to the user review the
CPLError() documentation. Generally speaking all of GDAL uses
CPLError() for error reporting. Also, note that pszFilename need not
actually be the name of a physical file (though it usually is). It's
interpretation is driver dependent, and it might be an URL, a filename
with additional parameters added at the end controlling the open or
almost anything. Please try not to limit GDAL file selection dialogs
to only selecting physical files.
looks like the file you are trying to open is not a valid gdal file or some other magic is going on in the file selection. you could try to direct the program to a known good file online to test it.

Including sound files in a pygame script using pyinstaller

I am new to programming, so I made myself the challenge to create Pong, and so I did. Now I want to share it with a couple of friends, so I decided to try using pyinstaller (have tried cx_Freeze).
In this Pong game I have 3 sound effects, located in the folder "sfx". So I've looked into including files using pyinstaller, so my .spec file says:
added_files = [
('E:\Game Development Stuff\Python 3\Games\Pong\sfx\hitOutline.ogg', 'sfx'),
('E:\Game Development Stuff\Python 3\Games\Pong\sfx\hitPaddle.ogg', 'sfx'),
('E:\Game Development Stuff\Python 3\Games\Pong\sfx/score.ogg', 'sfx')
]
a = Analysis(['pong.py'],
pathex=['E:\\Game Development Stuff\\Python 3\\Games\\Pong'],
binaries=None,
datas=added_files,
and in the Pong program itself, I use this code to get the path:
def resource_path(relative):
if hasattr(sys, "_MEIPASS"):
return os.path.join(sys._MEIPASS, relative)
return os.path.join(relative)
fileDir = os.path.dirname(os.path.realpath('__file__'))
hitPaddle = resource_path(os.path.join(fileDir, "sfx", "hitPaddle.ogg"))
hitOutline = resource_path(os.path.join(fileDir, "sfx", "hitOutline.ogg"))
score = resource_path(os.path.join(fileDir, "sfx", "score.ogg"))
hitPaddleSound=pygame.mixer.Sound(hitPaddle)
hitOutlineSound=pygame.mixer.Sound(hitOutline)
scoreSound=pygame.mixer.Sound(score)
So I make the exe file using pyinstaller (with the command pyinstaller pong.spec)
but when I open the pong.exe file the command window says:
Traceback "<string>", Unable to open file 'E:\\Game Development Stuff\\Python 3\\Games\\Pong\\dist\\pong\\sfx\\hitPaddle.ogg'
but in that exact same path is hitPaddle.ogg.
It seems to me that pygame isn't able to found it for some weird reason?
I believe the issue is in this line. You are not refrencing the files correctly. You wrote:
hitPaddle = resource_path(os.path.join(fileDir, "sfx", "hitPaddle.ogg"))
Instead you should of just:
hitpaddle = resource_path("sfx\hitPaddle.ogg")
This is because when you added the files in the spec file, you stated that they should be in "root\sfx" folder. When the .exe is run in onefile mode, all files are actually located in a temp folder called MEIXXXX, with XXXX being some integers. When you run the .exe, if you open this folder you should be able to see your files there.
Solved it for me after struggling with the same issue for hours. Conclusions:
The problem is not in not being able to find it, then it would say something with 'could not find'. It is really an issue with opening the file. Somehow, the .ogg format is giving issues. I changed all my .ogg files to .wav files and my game is running without problems now as executable.
I have no idea why though, because two weeks ago for a previous version I did manage to make a working .exe with the exact same .ogg files. And I don't see how the changes I made should have any effect on this. Anyway, it works now, and perhaps this can also solve this problem for others.

What happened to my computer? I always got a 'cookielib bug' even I changed my Python Version

I want to learn the skill to log in websites with Python, so I copy other's code then try to understand them.
I've write several web crawls which don't need to post data to the websites by myself.
But this time, when I try to learn crawls that need post data, Python doesn't work.
It's the wrong message from Windows Command Line:
C:\Python26\lib\cookielib.py:1579: UserWarning: cookielib bug!
Traceback (most recent call last):
File "C:\Python26\lib\cookielib.py", line 1577, in make_cookies
parse_ns_headers(ns_hdrs), request)
File "C:\Python26\lib\cookielib.py", line 1534, in _cookies_from_attrs_set
cookie = self._cookie_from_cookie_tuple(tup, request)
File "C:\Python26\lib\cookielib.py", line 1527, in _cookie_from_cookie_tuple
rest)
File "C:\Python26\lib\cookielib.py", line 764, in __init__
self._rest = copy.copy(rest)
AttributeError: 'module' object has no attribute 'copy'
_warn_unhandled_exception()
Actually, I have tried to use Python2.7.6 and Python2.6 and refresh 2.7.6 for times.
The code that I copied is from http://www.oschina.net/code/snippet_1253232_26503.
This code is right because lots of people run this code .
I provide an account:
Email='13018015260'(Also can be telephone number in this site),password='qwerty'
The code is not the problem, but the Python itself. Once I use cookielib in code, Python on my computer doesn't work!
Sorry for my poor English, I want to know the answer, because I even can't find similar problems in Google!
Make sure that you do not have your own copy.py or copy.pyc in python path.
You can check that using following command in python interactive shell.
python -c "import copy; print(copy.__file__)"
It should print path something like:
c:\python27\lib\copy.pyc
If the above command print something that does not reference the file in standard library path, renamed the file (copy.py), and make sure you delete copy.pyc file.

Error on Pytz - IndexError: list index out of range

I'm having this problem with ptyz:
>>> import pytz
>>> pytz.timezone('US/Mountain')
Traceback (most recent call last):
File "stdin", line 1, in module
File "/home/user/.local/lib/python2.6/site-packages/pytz-2013b-py2.6.egg/pytz/__init__.py", line 181, in timezone
_tzinfo_cache[zone] = build_tzinfo(zone, fp)
File "/home/user/.local/lib/python2.6/site-packages/pytz-2013b-py2.6.egg/pytz/tzfile.py", line 78, in build_tzinfo
while ttinfo[i][1]:
IndexError: list index out of range
I have two accounts in a server, and two different installations of pytz, though they are a copy of each other. In one of them, pytz works as a charm, but in the other one I have this error. It looks like an error inside ptyz, but it cannot be, because pytz works fine in the other account.
Has anyone handled this befor or have any idea of what may be causing this?
Update:
This error just happen when the script is called by a page, and that's the exact last message:
build_tzinfo(zone='US/Michigan', fp=<closed file '/home/user/.local/lib/python2...e-packages/pytz/zoneinfo/US/Michigan', mode 'rb'>)
and fp is a variable inside init.py that just receives it:
open(filename, 'rb')
It seems that the file is found, opened, but not really opened. I found at http://docs.python.org/2/tutorial/inputoutput.html that there are differences between linux and windows on the way they see binary files. My server runs Linux and, again, on the other account, with the same instalation, pytz works as a charm.
That's what happened:
After I updated my question, I noticed that the problem was with python opening a binary file. A friend told me to check the software I was using to send files to the server (Filezila), and there was three types of transfer: ASCII, Binary or Automatic. The software was set to Automatic. I send again the binary files in the binary transfer mode and it worked.

Categories