From 5036e13cdc9b8fa1dba5805209a41902ef453224 Mon Sep 17 00:00:00 2001 From: Avasam Date: Tue, 11 Mar 2025 11:58:52 -0400 Subject: [PATCH 1/6] Fix DispatchWithEvents and WithEvents throw on 2nd call --- CHANGES.txt | 3 ++- com/win32com/client/__init__.py | 3 +-- com/win32com/test/testPyComTest.py | 7 +++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index f0c965f157..bff7382e90 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -13,7 +13,8 @@ https://mhammond.github.io/pywin32_installers.html . Coming in build 310, as yet unreleased -------------------------------------- -* Drop support for Vista, set Windows 7 as the minimal Windows version. (#, @Avasam) +* Fixed a regression where `win32com.client.DispatchWithEvents` and win32com.client.WithEvents` would throw a `TypeError` on the second call (#2489, @Avasam) +* Drop support for Vista, set Windows 7 as the minimal Windows version. (#2487, @Avasam) * Restores many IIDs in `win32com(ext).shell.shell`. See #2486 for details. Build 309, released 2025/03/09 diff --git a/com/win32com/client/__init__.py b/com/win32com/client/__init__.py index d1e84e09c0..27a0f1ec42 100644 --- a/com/win32com/client/__init__.py +++ b/com/win32com/client/__init__.py @@ -269,7 +269,7 @@ def __get_disp_and_event_classes(dispatch): disp = Dispatch(dispatch) if disp.__class__.__dict__.get("CLSID"): - return disp.__class__ + disp_class = disp.__class__ # Eeek - no makepy support - try and build it. error_msg = "This COM object can not automate the makepy process - please run makepy manually for this object" @@ -333,7 +333,6 @@ class object that derives from three classes: >>> ie = DispatchWithEvents("InternetExplorer.Application", IEEvents) >>> ie.Visible = 1 Visible changed: 1 - >>> """ disp, disp_class, events_class = __get_disp_and_event_classes(clsid) result_class = type( diff --git a/com/win32com/test/testPyComTest.py b/com/win32com/test/testPyComTest.py index f8b0c73733..903106889b 100644 --- a/com/win32com/test/testPyComTest.py +++ b/com/win32com/test/testPyComTest.py @@ -628,6 +628,13 @@ def TestGenerated(): # and a plain "WithEvents". handler = win32com.client.WithEvents(o, RandomEventHandler) TestEvents(o, handler) + + # Ensure that if it has already been dispatched, the base classes are the same. + o2_again = win32com.client.DispatchWithEvents(o, RandomEventHandler) + assert o2._obj_.__class__.__bases__ == o2_again._obj_.__class__.__bases__ + handler_again = win32com.client.WithEvents(o, RandomEventHandler) + assert handler.__class__.__bases__ == handler_again.__class__.__bases__ + progress("Finished generated .py test.") From ed0d2ad17d7781c3bf2845114a26343b658b9670 Mon Sep 17 00:00:00 2001 From: Avasam Date: Tue, 11 Mar 2025 14:15:23 -0400 Subject: [PATCH 2/6] Redundant test, the test just isn't running. --- CHANGES.txt | 2 +- com/win32com/test/testPyComTest.py | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index bff7382e90..18a16c6c28 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -13,7 +13,7 @@ https://mhammond.github.io/pywin32_installers.html . Coming in build 310, as yet unreleased -------------------------------------- -* Fixed a regression where `win32com.client.DispatchWithEvents` and win32com.client.WithEvents` would throw a `TypeError` on the second call (#2489, @Avasam) +* Fixed a regression where `win32com.client.DispatchWithEvents` and win32com.client.WithEvents` would throw a `TypeError` on the second call (#2491, @Avasam) * Drop support for Vista, set Windows 7 as the minimal Windows version. (#2487, @Avasam) * Restores many IIDs in `win32com(ext).shell.shell`. See #2486 for details. diff --git a/com/win32com/test/testPyComTest.py b/com/win32com/test/testPyComTest.py index 903106889b..f8b0c73733 100644 --- a/com/win32com/test/testPyComTest.py +++ b/com/win32com/test/testPyComTest.py @@ -628,13 +628,6 @@ def TestGenerated(): # and a plain "WithEvents". handler = win32com.client.WithEvents(o, RandomEventHandler) TestEvents(o, handler) - - # Ensure that if it has already been dispatched, the base classes are the same. - o2_again = win32com.client.DispatchWithEvents(o, RandomEventHandler) - assert o2._obj_.__class__.__bases__ == o2_again._obj_.__class__.__bases__ - handler_again = win32com.client.WithEvents(o, RandomEventHandler) - assert handler.__class__.__bases__ == handler_again.__class__.__bases__ - progress("Finished generated .py test.") From d2fb7de18277a5100d8d7cca68b65a4d550b3b99 Mon Sep 17 00:00:00 2001 From: Avasam Date: Tue, 11 Mar 2025 17:28:22 -0400 Subject: [PATCH 3/6] Cleaner if-else --- com/win32com/client/__init__.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/com/win32com/client/__init__.py b/com/win32com/client/__init__.py index 27a0f1ec42..b9f830d4c4 100644 --- a/com/win32com/client/__init__.py +++ b/com/win32com/client/__init__.py @@ -270,22 +270,22 @@ def __get_disp_and_event_classes(dispatch): if disp.__class__.__dict__.get("CLSID"): disp_class = disp.__class__ + else: + # Eeek - no makepy support - try and build it. + try: + ti = disp._oleobj_.GetTypeInfo() + disp_clsid = ti.GetTypeAttr()[0] + tlb, index = ti.GetContainingTypeLib() + tla = tlb.GetLibAttr() + gencache.EnsureModule(tla[0], tla[1], tla[3], tla[4], bValidateFile=0) + # Get the class from the module. + disp_class = gencache.GetClassForProgID(str(disp_clsid)) + except pythoncom.com_error as error: + disp_class = None + + if disp_class is None: + raise TypeError("This COM object can not automate the makepy process - please run makepy manually for this object") - # Eeek - no makepy support - try and build it. - error_msg = "This COM object can not automate the makepy process - please run makepy manually for this object" - try: - ti = disp._oleobj_.GetTypeInfo() - disp_clsid = ti.GetTypeAttr()[0] - tlb, index = ti.GetContainingTypeLib() - tla = tlb.GetLibAttr() - gencache.EnsureModule(tla[0], tla[1], tla[3], tla[4], bValidateFile=0) - # Get the class from the module. - disp_class = gencache.GetClassForProgID(str(disp_clsid)) - except pythoncom.com_error as error: - raise TypeError(error_msg) from error - - if disp_class is None: - raise TypeError(error_msg) # Get the clsid clsid = disp_class.CLSID # Create a new class that derives from 2 classes: From 90afcce3541cef4d1617c064816642282bc55327 Mon Sep 17 00:00:00 2001 From: Avasam Date: Tue, 11 Mar 2025 17:29:02 -0400 Subject: [PATCH 4/6] cleaner changelog entry --- CHANGES.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 18a16c6c28..ad85e5d420 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -14,8 +14,8 @@ https://mhammond.github.io/pywin32_installers.html . Coming in build 310, as yet unreleased -------------------------------------- * Fixed a regression where `win32com.client.DispatchWithEvents` and win32com.client.WithEvents` would throw a `TypeError` on the second call (#2491, @Avasam) -* Drop support for Vista, set Windows 7 as the minimal Windows version. (#2487, @Avasam) - * Restores many IIDs in `win32com(ext).shell.shell`. See #2486 for details. +* Dropped support for Vista, set Windows 7 as the minimal Windows version. (#2487, @Avasam) +* Restored many IIDs in `win32com(ext).shell.shell`. See #2486 for details. (#2487, @Avasam) Build 309, released 2025/03/09 ------------------------------ From c4eef13dbc97cd040c190d902674a169b3be62fd Mon Sep 17 00:00:00 2001 From: Avasam Date: Tue, 11 Mar 2025 17:32:47 -0400 Subject: [PATCH 5/6] Keep teh from error: more detailled exception --- com/win32com/client/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/com/win32com/client/__init__.py b/com/win32com/client/__init__.py index b9f830d4c4..ba9ec5a910 100644 --- a/com/win32com/client/__init__.py +++ b/com/win32com/client/__init__.py @@ -272,6 +272,7 @@ def __get_disp_and_event_classes(dispatch): disp_class = disp.__class__ else: # Eeek - no makepy support - try and build it. + error_msg = "This COM object can not automate the makepy process - please run makepy manually for this object" try: ti = disp._oleobj_.GetTypeInfo() disp_clsid = ti.GetTypeAttr()[0] @@ -281,10 +282,11 @@ def __get_disp_and_event_classes(dispatch): # Get the class from the module. disp_class = gencache.GetClassForProgID(str(disp_clsid)) except pythoncom.com_error as error: - disp_class = None + raise TypeError(error_msg) from error + if disp_class is None: - raise TypeError("This COM object can not automate the makepy process - please run makepy manually for this object") + raise TypeError(error_msg) # Get the clsid clsid = disp_class.CLSID From abf3382cf22b77024bfb65e83c5e9304ee20fcf9 Mon Sep 17 00:00:00 2001 From: Avasam Date: Tue, 11 Mar 2025 17:33:55 -0400 Subject: [PATCH 6/6] typo: remove extra space --- com/win32com/client/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/com/win32com/client/__init__.py b/com/win32com/client/__init__.py index ba9ec5a910..ae879590b5 100644 --- a/com/win32com/client/__init__.py +++ b/com/win32com/client/__init__.py @@ -284,7 +284,6 @@ def __get_disp_and_event_classes(dispatch): except pythoncom.com_error as error: raise TypeError(error_msg) from error - if disp_class is None: raise TypeError(error_msg)