What is the reason why deleting the gen py solves the no attribute 'CLSIDToPackageMap'? In several places there were solutions (which all involved deleting a folder in temp/gen_py, but the only explanation I found was the answer here which explains this is because of a switch from late to early binding. My questions are then:
(1) Why does this switch occur?
(2) Why does deleting the folder in gen_py solve this problem?
See also:
python 3.x - Why am I suddenly getting a no attribute 'CLSIDToPackageMap' error with win32com.client? - Stack Overflow
Fix for module win32com.gen_py has no attribute 'CLSIDToPackageMap' (github.com)
python-win32com excel com model started generating errors - Stack Overflow
I can (mostly) answer this.
There are two methods for launching a COM object: win32com.client.Dispatch for late binding and win32com.gencache.EnsureDispatch for early binding.
(You needn't actually understand early vs late to understand why your issue happens.)
When you use late binding, Python doesn't care about upper/lower case of COM attributes. When you use early binding, you have to get the case right. So "CLSIDToPackageMap" is probably named with different case somewhere in the code.
OK. So how could this "go wrong" if it ever worked? Let's assume you used code that did late binding. It worked because it didn't need the case to match. Then, at some point, you used early binding on the same object. (Maybe you ran someone else's code that used early binding).
Once you use early binding, you can never go back! Even if you write late binding code for an object, if that object later gets early bound, your late-binding code will use early binding.
The code for early binding gets generated when someone uses early binding, if it doesn't exist. It gets generated into gen_py, so deleting the folder from gen_py will let your late-binding code actually do late binding once again.