Skip to content

Commit 16e6f32

Browse files
Avasamclin1234
authored andcommitted
Annotate axscript.client.error module and remove redundant code (mhammond#2236)
1 parent f0383a4 commit 16e6f32

File tree

3 files changed

+72
-47
lines changed

3 files changed

+72
-47
lines changed

CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Coming in build 307, as yet unreleased
1515
--------------------------------------
1616

1717
### pywin32
18+
* Marked `exc_type` and `exc_traceback` in `win32comext.axscript.client.error.AXScriptException.__init__` as deprecated.
19+
They are now unused and all information is taken from the `exc_value` parameter.
1820
* Fixed non-overriden `pywin.scintilla.formatter.Formatter.ColorizeString` raising `TypeError` instead of `RuntimeError` due to too many parameters (#2216, @Avasam)
1921
* Fixed broken since Python 3 tokenization in `win32comext.axdebug.codecontainer.pySourceCodeContainer.GetSyntaxColorAttributes` (#2216, @Avasam)
2022
* Fixed a `TypeError` due to incorrect kwargs in `win32comext.axscript.client.pydumper.Register` (#2216, @Avasam)

com/win32comext/axscript/client/error.py

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,36 @@
44
as well as the IActiveScriptError interface code.
55
"""
66

7+
from __future__ import annotations
8+
79
import re
810
import traceback
11+
import warnings
12+
from types import TracebackType
913

1014
import pythoncom
1115
import win32com.server.util
1216
import winerror
1317
from win32com.axscript import axscript
1418
from win32com.server.exception import COMException
19+
from win32comext.axscript.client.debug import DebugManager
20+
from win32comext.axscript.client.framework import AXScriptCodeBlock, COMScript
21+
from win32comext.axscript.server.axsite import AXSite
1522

1623
debugging = 0
1724

1825

19-
def FormatForAX(text):
26+
def FormatForAX(text: str):
2027
"""Format a string suitable for an AX Host"""
2128
# Replace all " with ', so it works OK in HTML (ie, ASP)
2229
return ExpandTabs(AddCR(text))
2330

2431

25-
def ExpandTabs(text):
32+
def ExpandTabs(text: str):
2633
return re.sub(r"\t", " ", text)
2734

2835

29-
def AddCR(text):
36+
def AddCR(text: str):
3037
return re.sub(r"\n", "\r\n", text)
3138

3239

@@ -45,7 +52,7 @@ def _query_interface_(self, iid):
4552
print("IActiveScriptError QI - unknown IID", iid)
4653
return 0
4754

48-
def _SetExceptionInfo(self, exc):
55+
def _SetExceptionInfo(self, exc: AXScriptException):
4956
self.exception = exc
5057

5158
def GetSourceLineText(self):
@@ -72,14 +79,27 @@ class AXScriptException(COMException):
7279
object.
7380
"""
7481

75-
def __init__(self, site, codeBlock, exc_type, exc_value, exc_traceback):
82+
def __init__(
83+
self,
84+
site: COMScript,
85+
codeBlock: AXScriptCodeBlock | None,
86+
exc_type: None = None,
87+
exc_value: BaseException | None = None,
88+
exc_traceback: None = None,
89+
):
7690
# set properties base class shares via base ctor...
7791
super().__init__(
7892
description="Unknown Exception",
7993
scode=winerror.DISP_E_EXCEPTION,
8094
source="Python ActiveX Scripting Engine",
8195
)
8296

97+
if exc_type is not None or exc_traceback is not None:
98+
warnings.warn(
99+
"`exc_type` and `exc_traceback` were redundant and are now unused.",
100+
category=DeprecationWarning,
101+
)
102+
83103
# And my other values...
84104
if codeBlock is None:
85105
self.sourceContext = 0
@@ -89,18 +109,18 @@ def __init__(self, site, codeBlock, exc_type, exc_value, exc_traceback):
89109
self.startLineNo = codeBlock.startLineNumber
90110
self.linetext = ""
91111

92-
self.__BuildFromException(site, exc_type, exc_value, exc_traceback)
112+
self.__BuildFromException(site, exc_value)
93113

94-
def __BuildFromException(self, site, type, value, tb):
114+
def __BuildFromException(self, site: COMScript, value: BaseException | None):
95115
if debugging:
96116
import linecache
97117

98118
linecache.clearcache()
99119
try:
100-
if issubclass(type, SyntaxError):
120+
if isinstance(value, SyntaxError):
101121
self._BuildFromSyntaxError(value)
102122
else:
103-
self._BuildFromOther(site, type, value, tb)
123+
self._BuildFromOther(site, value)
104124
except: # Error extracting traceback info!!!
105125
traceback.print_exc()
106126
# re-raise.
@@ -111,13 +131,16 @@ def _BuildFromSyntaxError(self, exc: SyntaxError):
111131
msg = exc.msg or "Unknown Error"
112132
offset = exc.offset or 0
113133
line = exc.text or ""
134+
lineno = exc.lineno or 0
114135

115136
self.description = FormatForAX(msg)
116-
self.lineno = exc.lineno
137+
self.lineno = lineno
117138
self.colno = offset - 1
118139
self.linetext = ExpandTabs(line.rstrip())
119140

120-
def _BuildFromOther(self, site, exc_type, value, tb):
141+
def _BuildFromOther(self, site: COMScript, value: BaseException | None):
142+
tb = value.__traceback__ if value else None
143+
exc_type = type(value) if value else None
121144
self.colno = -1
122145
self.lineno = 0
123146
if debugging: # Full traceback if debugging.
@@ -132,7 +155,6 @@ def _BuildFromOther(self, site, exc_type, value, tb):
132155
"r_reload",
133156
"r_open",
134157
] # hide from these functions down in the traceback.
135-
depth = None
136158
tb_top = tb
137159
while tb_top:
138160
filename, lineno, name, line = self.ExtractTracebackInfo(tb_top, site)
@@ -141,8 +163,7 @@ def _BuildFromOther(self, site, exc_type, value, tb):
141163
tb_top = tb_top.tb_next
142164
format_items = []
143165
if tb_top: # found one.
144-
depth = 0
145-
tb_look = tb_top
166+
tb_look: TracebackType | None = tb_top
146167
# Look down for our bottom
147168
while tb_look:
148169
filename, lineno, name, line = self.ExtractTracebackInfo(tb_look, site)
@@ -155,15 +176,14 @@ def _BuildFromOther(self, site, exc_type, value, tb):
155176
self.lineno = lineno
156177
self.linetext = line
157178
format_items.append((filename, lineno, name, line))
158-
depth = depth + 1
159179
tb_look = tb_look.tb_next
160180
else:
161-
depth = None
162181
tb_top = tb
163182

164183
bits = ["Traceback (most recent call last):\n"]
165-
bits.extend(traceback.format_list(format_items))
166-
if exc_type == pythoncom.com_error:
184+
# Fixed in https://github.com/python/typeshed/pull/11675 , to be included in next mypy release
185+
bits.extend(traceback.format_list(format_items)) # type: ignore[arg-type]
186+
if isinstance(value, pythoncom.com_error):
167187
desc = f"{value.strerror} (0x{value.hresult:x})"
168188
if (
169189
value.hresult == winerror.DISP_E_EXCEPTION
@@ -176,23 +196,17 @@ def _BuildFromOther(self, site, exc_type, value, tb):
176196
bits.extend(traceback.format_exception_only(exc_type, value))
177197

178198
self.description = ExpandTabs("".join(bits))
179-
# Clear tracebacks etc.
180-
tb = tb_top = tb_look = None
181199

182-
def ExtractTracebackInfo(self, tb, site):
200+
def ExtractTracebackInfo(self, tb: TracebackType, site: COMScript):
183201
import linecache
184202

185-
f = tb.tb_frame
186203
lineno = tb.tb_lineno
187-
co = f.f_code
204+
co = tb.tb_frame.f_code
188205
filename = co.co_filename
189206
name = co.co_name
190-
line = linecache.getline(filename, lineno)
207+
line: str | None = linecache.getline(filename, lineno)
191208
if not line:
192-
try:
193-
codeBlock = site.scriptCodeBlocks[filename]
194-
except KeyError:
195-
codeBlock = None
209+
codeBlock = site.scriptCodeBlocks.get(filename)
196210
if codeBlock:
197211
# Note: 'line' will now be unicode.
198212
line = codeBlock.GetLineNo(lineno)
@@ -206,15 +220,19 @@ def __repr__(self):
206220
return "AXScriptException Object with description:" + self.description
207221

208222

209-
def ProcessAXScriptException(scriptingSite, debugManager, exceptionInstance):
223+
def ProcessAXScriptException(
224+
scriptingSite: AXSite,
225+
debugManager: DebugManager,
226+
exceptionInstance: AXScriptException,
227+
):
210228
"""General function to handle any exception in AX code
211229
212230
This function creates an instance of our IActiveScriptError interface, and
213231
gives it to the host, along with out exception class. The host will
214232
likely call back on the IActiveScriptError interface to get the source text
215233
and other information not normally in COM exceptions.
216234
"""
217-
# traceback.print_exc()
235+
# traceback.print_exc()
218236
instance = IActiveScriptError()
219237
instance._SetExceptionInfo(exceptionInstance)
220238
gateway = win32com.server.util.wrap(instance, axscript.IID_IActiveScriptError)

com/win32comext/axscript/client/framework.py

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import re
1313
import sys
14+
from typing import NoReturn
1415

1516
import pythoncom # Need simple connection point support
1617
import win32api
@@ -112,7 +113,7 @@ def trace(*args):
112113
print()
113114

114115

115-
def RaiseAssert(scode, desc):
116+
def RaiseAssert(scode, desc) -> NoReturn:
116117
"""A debugging function that raises an exception considered an "Assertion"."""
117118
print("**************** ASSERTION FAILED *******************")
118119
print(desc)
@@ -122,7 +123,14 @@ def RaiseAssert(scode, desc):
122123
class AXScriptCodeBlock:
123124
"""An object which represents a chunk of code in an AX Script"""
124125

125-
def __init__(self, name, codeText, sourceContextCookie, startLineNumber, flags):
126+
def __init__(
127+
self,
128+
name: str,
129+
codeText: str,
130+
sourceContextCookie: int,
131+
startLineNumber: int,
132+
flags,
133+
):
126134
self.name = name
127135
self.codeText = codeText
128136
self.codeObject = None
@@ -139,7 +147,7 @@ def GetFileName(self):
139147
def GetDisplayName(self):
140148
return self.name
141149

142-
def GetLineNo(self, no):
150+
def GetLineNo(self, no: int):
143151
pos = -1
144152
for i in range(no - 1):
145153
pos = self.codeText.find("\n", pos + 1)
@@ -628,7 +636,7 @@ def __init__(self):
628636
self.safetyOptions = 0
629637
self.lcid = 0
630638
self.subItems = {}
631-
self.scriptCodeBlocks = {}
639+
self.scriptCodeBlocks: dict[str, AXScriptCodeBlock] = {}
632640

633641
def _query_interface_(self, iid):
634642
if self.debugManager:
@@ -1086,7 +1094,7 @@ def _ApplyInScriptedSection(self, fn, args):
10861094
else:
10871095
return fn(*args)
10881096

1089-
def ApplyInScriptedSection(self, codeBlock, fn, args):
1097+
def ApplyInScriptedSection(self, codeBlock: AXScriptCodeBlock | None, fn, args):
10901098
self.BeginScriptedSection()
10911099
try:
10921100
try:
@@ -1105,7 +1113,9 @@ def _CompileInScriptedSection(self, code, name, type):
11051113
self.debugManager.OnEnterScript()
11061114
return compile(code, name, type)
11071115

1108-
def CompileInScriptedSection(self, codeBlock, type, realCode=None):
1116+
def CompileInScriptedSection(
1117+
self, codeBlock: AXScriptCodeBlock, type, realCode=None
1118+
):
11091119
if codeBlock.codeObject is not None: # already compiled
11101120
return 1
11111121
if realCode is None:
@@ -1137,7 +1147,7 @@ def _ExecInScriptedSection(self, codeObject, globals, locals=None):
11371147
else:
11381148
exec(codeObject, globals, locals)
11391149

1140-
def ExecInScriptedSection(self, codeBlock, globals, locals=None):
1150+
def ExecInScriptedSection(self, codeBlock: AXScriptCodeBlock, globals, locals=None):
11411151
if locals is None:
11421152
locals = globals
11431153
assert (
@@ -1185,31 +1195,26 @@ def EvalInScriptedSection(self, codeBlock, globals, locals=None):
11851195
except:
11861196
self.HandleException(codeBlock)
11871197

1188-
def HandleException(self, codeBlock):
1189-
# NOTE - Never returns - raises a ComException
1190-
exc_type, exc_value, exc_traceback = sys.exc_info()
1198+
def HandleException(self, codeBlock: AXScriptCodeBlock | None) -> NoReturn:
1199+
"""Never returns - raises a ComException"""
1200+
exc_type, exc_value, *_ = sys.exc_info()
11911201
# If a SERVER exception, re-raise it. If a client side COM error, it is
11921202
# likely to have originated from the script code itself, and therefore
11931203
# needs to be reported like any other exception.
11941204
if IsCOMServerException(exc_type):
11951205
# Ensure the traceback doesnt cause a cycle.
1196-
exc_traceback = None
11971206
raise
11981207
# It could be an error by another script.
11991208
if (
1200-
issubclass(pythoncom.com_error, exc_type)
1209+
isinstance(exc_value, pythoncom.com_error)
12011210
and exc_value.hresult == axscript.SCRIPT_E_REPORTED
12021211
):
12031212
# Ensure the traceback doesnt cause a cycle.
1204-
exc_traceback = None
12051213
raise COMException(scode=exc_value.hresult)
12061214

1207-
exception = error.AXScriptException(
1208-
self, codeBlock, exc_type, exc_value, exc_traceback
1209-
)
1215+
exception = error.AXScriptException(self, codeBlock, exc_value=exc_value)
12101216

12111217
# Ensure the traceback doesnt cause a cycle.
1212-
exc_traceback = None
12131218
result_exception = error.ProcessAXScriptException(
12141219
self.scriptSite, self.debugManager, exception
12151220
)

0 commit comments

Comments
 (0)