Skip to content

Commit 8c49d8f

Browse files
authored
Add test_errorinfo. (enthought#819)
* Add `test_errorinfo`. * Replace `_SetErrorInfo` with `SetErrorInfo`. This allows us to remove the magic number `0` from the arguments without changing the behavior. * Replace `from comtypes.hresult import *` with specific imports in `errorinfo.py`. * Fix expected `__name__` of frames in `Test_ReportException.test_with_stacklevel`.
1 parent d9d132d commit 8c49d8f

File tree

3 files changed

+98
-3
lines changed

3 files changed

+98
-3
lines changed

comtypes/errorinfo.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from typing import TYPE_CHECKING
55

66
from comtypes import BSTR, COMMETHOD, GUID, HRESULT, IUnknown
7-
from comtypes.hresult import *
7+
from comtypes.hresult import DISP_E_EXCEPTION, S_OK
88

99
if TYPE_CHECKING:
1010
from comtypes import hints # type: ignore
@@ -109,7 +109,7 @@ def ReportError(
109109
ei.SetSource(
110110
progid
111111
) # progid for the class or application that created the error
112-
_SetErrorInfo(0, ei)
112+
SetErrorInfo(ei)
113113
return hresult
114114

115115

comtypes/test/test_errorinfo.py

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import unittest as ut
2+
3+
from comtypes import errorinfo, shelllink
4+
from comtypes import hresult as hres
5+
6+
7+
class Test_GetErrorInfo(ut.TestCase):
8+
def test_error_has_been_set(self):
9+
self.assertIsNone(errorinfo.GetErrorInfo())
10+
errmsg = "sample unexpected error message for tests"
11+
errcode = hres.E_UNEXPECTED
12+
helpcontext = 123
13+
hr = errorinfo.ReportError(
14+
errmsg,
15+
shelllink.IShellLinkW._iid_,
16+
str(shelllink.ShellLink._reg_clsid_),
17+
helpfile="help.chm",
18+
helpcontext=helpcontext,
19+
hresult=errcode,
20+
)
21+
self.assertEqual(errcode, hr)
22+
pei = errorinfo.GetErrorInfo()
23+
self.assertIsNotNone(pei)
24+
self.assertEqual(shelllink.IShellLinkW._iid_, pei.GetGUID())
25+
self.assertEqual("lnkfile", pei.GetSource())
26+
self.assertEqual(errmsg, pei.GetDescription())
27+
self.assertEqual("help.chm", pei.GetHelpFile())
28+
self.assertEqual(helpcontext, pei.GetHelpContext())
29+
# Calling `GetErrorInfo` clears the error state for the thread.
30+
# Therefore, `None` is returned in the second call.
31+
self.assertIsNone(errorinfo.GetErrorInfo())
32+
33+
def test_without_optional_args(self):
34+
self.assertIsNone(errorinfo.GetErrorInfo())
35+
errmsg = "sample unexpected error message for tests"
36+
hr = errorinfo.ReportError(errmsg, shelllink.IShellLinkW._iid_)
37+
self.assertEqual(hres.DISP_E_EXCEPTION, hr)
38+
pei = errorinfo.GetErrorInfo()
39+
self.assertIsNotNone(pei)
40+
self.assertEqual(shelllink.IShellLinkW._iid_, pei.GetGUID())
41+
self.assertIsNone(pei.GetSource())
42+
self.assertEqual(errmsg, pei.GetDescription())
43+
self.assertIsNone(pei.GetHelpFile())
44+
self.assertEqual(0, pei.GetHelpContext())
45+
46+
def test_error_has_not_been_set(self):
47+
self.assertIsNone(errorinfo.GetErrorInfo())
48+
pei = errorinfo.GetErrorInfo()
49+
self.assertIsNone(pei)
50+
51+
52+
def raise_runtime_error():
53+
_raise_runtime_error()
54+
55+
56+
def _raise_runtime_error():
57+
raise RuntimeError("for testing")
58+
59+
60+
class Test_ReportException(ut.TestCase):
61+
def test_without_stacklevel(self):
62+
self.assertIsNone(errorinfo.GetErrorInfo())
63+
iid = shelllink.IShellLinkW._iid_
64+
try:
65+
raise_runtime_error()
66+
except RuntimeError:
67+
hr = errorinfo.ReportException(hres.E_UNEXPECTED, iid)
68+
self.assertEqual(hres.E_UNEXPECTED, hr)
69+
pei = errorinfo.GetErrorInfo()
70+
self.assertIsNotNone(pei)
71+
self.assertEqual(shelllink.IShellLinkW._iid_, pei.GetGUID())
72+
self.assertIsNone(pei.GetSource())
73+
self.assertEqual("<class 'RuntimeError'>: for testing", pei.GetDescription())
74+
self.assertIsNone(pei.GetHelpFile())
75+
self.assertEqual(0, pei.GetHelpContext())
76+
self.assertIsNone(errorinfo.GetErrorInfo())
77+
78+
def test_with_stacklevel(self):
79+
self.assertIsNone(errorinfo.GetErrorInfo())
80+
stem = "<class 'RuntimeError'>: for testing"
81+
iid = shelllink.IShellLinkW._iid_
82+
for slv, text in [
83+
# XXX: If the codebase changes, the line where functions or
84+
# methods are defined will change, meaning this test is brittle.
85+
(0, f"{stem} ({__name__}, line 93)"),
86+
(1, f"{stem} ({__name__}, line 53)"),
87+
(2, f"{stem} ({__name__}, line 57)"),
88+
]:
89+
with self.subTest(text=text):
90+
try:
91+
raise_runtime_error()
92+
except RuntimeError:
93+
errorinfo.ReportException(hres.E_UNEXPECTED, iid, stacklevel=slv)
94+
pei = errorinfo.GetErrorInfo()
95+
self.assertEqual(text, pei.GetDescription())
96+
self.assertIsNone(errorinfo.GetErrorInfo())

pyproject.toml

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ ignore = ["E402"]
1111
"comtypes/_npsupport.py" = ["F401"]
1212
"comtypes/_vtbl.py" = ["E722"]
1313
"comtypes/automation.py" = ["F401", "F403", "F405"]
14-
"comtypes/errorinfo.py" = ["F403", "F405"]
1514
"comtypes/git.py" = ["F401", "F403", "F405"]
1615
"comtypes/util.py" = ["F403", "F405"]
1716
"comtypes/viewobject.py" = ["F403", "F405"]

0 commit comments

Comments
 (0)