Skip to content

Commit 03fddb4

Browse files
committed
Prevent duplicate offending-line-output for console syntax errors
1 parent 7b21740 commit 03fddb4

File tree

1 file changed

+53
-24
lines changed

1 file changed

+53
-24
lines changed

preditor/gui/console.py

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -48,27 +48,7 @@ class ConsolePrEdit(QTextEdit):
4848
def __init__(self, parent):
4949
super(ConsolePrEdit, self).__init__(parent)
5050

51-
# For Traceback workbox lines, use this regex pattern, so we can extract
52-
# workboxName and lineNum. Note that Syntax errors present slightly
53-
# differently than other Exceptions.
54-
# SyntaxErrors:
55-
# - Do NOT include the text ", in" followed by a module
56-
# - DO include the offending line of code
57-
# Other Exceptions
58-
# - DO include the text ", in" followed by a module
59-
# - Do NOT include the offending line of code if from stdIn (ie
60-
# a workbox)
61-
# So we will use the presence of the text ", in" to tell use whether to
62-
# fake the offending code line or not.
63-
pattern = r'File "<Workbox(?:Selection)?>:(?P<workboxName>.*)", '
64-
pattern += r'line (?P<lineNum>\d{1,6})'
65-
pattern += r'(?P<inStr>, in)?'
66-
self.workbox_pattern = re.compile(pattern)
67-
68-
# Define a pattern to capture info from tracebacks. The newline/$ section
69-
# handle SyntaxError output that does not include the `, in ...` portion.
70-
pattern = r'File "(?P<filename>.*)", line (?P<lineNum>\d{1,10})(, in|\r\n|\n|$)'
71-
self.traceback_pattern = re.compile(pattern)
51+
self.defineRegexPatterns()
7252

7353
self._consolePrompt = '>>> '
7454
# Note: Changing _outputPrompt may require updating resource\lang\python.xml
@@ -147,6 +127,47 @@ def __init__(self, parent):
147127
# it on.
148128
self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
149129

130+
def defineRegexPatterns(self):
131+
"""Define various regex patterns to use to determine if the msg to write
132+
is part of a traceback, and also to determine if it is from a workbox, or
133+
from the console.
134+
135+
We construct various parts of the patterns, and combine them into the
136+
final patterns. The workbox pattern and console pattern share the line
137+
and in_str parts.
138+
"""
139+
140+
# For Traceback workbox lines, use this regex pattern, so we can extract
141+
# workboxName and lineNum. Note that Syntax errors present slightly
142+
# differently than other Exceptions.
143+
# SyntaxErrors:
144+
# - Do NOT include the text ", in" followed by a module
145+
# - DO include the offending line of code
146+
# Other Exceptions
147+
# - DO include the text ", in" followed by a module
148+
# - Do NOT include the offending line of code if from stdIn (ie
149+
# a workbox)
150+
# So we will use the presence of the text ", in" to tell use whether to
151+
# fake the offending code line or not.
152+
153+
# Define pattern pieces
154+
console_pattern = r'File "<ConsolePrEdit>", '
155+
workbox_pattern = r'File "<Workbox(?:Selection)?>:(?P<workboxName>.*)", '
156+
line_pattern = r'line (?P<lineNum>\d{1,6})'
157+
in_str_pattern = r'(?P<inStr>, in)?'
158+
159+
# Put the pattern pieces to together to make patterns
160+
workbox_pattern = workbox_pattern + line_pattern + in_str_pattern
161+
self.workbox_pattern = re.compile(workbox_pattern)
162+
163+
console_pattern = console_pattern + line_pattern + in_str_pattern
164+
self.console_pattern = re.compile(console_pattern)
165+
166+
# Define a pattern to capture info from tracebacks. The newline/$ section
167+
# handle SyntaxError output that does not include the `, in ...` portion.
168+
pattern = r'File "(?P<filename>.*)", line (?P<lineNum>\d{1,10})(, in|\r\n|\n|$)'
169+
self.traceback_pattern = re.compile(pattern)
170+
150171
def setCodeHighlighter(self, highlight):
151172
"""Set the code highlighter for the console
152173
@@ -1012,9 +1033,17 @@ def write(self, msg, error=False):
10121033
msg = "{}{}{}".format(msg, indent, workboxLine)
10131034

10141035
elif isConsolePrEdit:
1015-
consoleLine = self.consoleLine
1016-
indent = self.getIndentForCodeTracebackLine(msg)
1017-
msg = "{}{}{}\n".format(msg, indent, consoleLine)
1036+
# Syntax error tracebacks are different than other Exception.
1037+
# They don't include ", in ..." and are issued differently than
1038+
# other Exceptions, in that they will issue the final piece of
1039+
# offending code, whereas other Exceptions do not, for some
1040+
# reason. They do not need, and shouldn't, be handled here.
1041+
match = self.console_pattern.search(msg)
1042+
inStr = match.groupdict().get("inStr", "")
1043+
if inStr:
1044+
consoleLine = self.consoleLine
1045+
indent = self.getIndentForCodeTracebackLine(msg)
1046+
msg = "{}{}{}\n".format(msg, indent, consoleLine)
10181047

10191048
# To make it easier to see relevant lines of a traceback, optionally insert
10201049
# a newline separating internal PrEditor code from the code run by user.

0 commit comments

Comments
 (0)