Skip to content

Commit 5af2dac

Browse files
Fix leakage of exc_info from eval to exec call.
`exec()` was always executed in the `except SyntaxError` block of the try around `eval()`, and because of this ``sys.exc_info()`` would not see the right exception if called as a statement. See: prompt-toolkit#435 Thanks to Peter Holloway for the proposed fix.
1 parent 7ea2e5b commit 5af2dac

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

ptpython/repl.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,7 @@ def eval(self, line: str) -> object:
199199
try:
200200
code = self._compile_with_flags(line, "eval")
201201
except SyntaxError:
202-
# If not a valid `eval` expression, run using `exec` instead.
203-
code = self._compile_with_flags(line, "exec")
204-
exec(code, self.get_globals(), self.get_locals())
202+
pass
205203
else:
206204
# No syntax errors for eval. Do eval.
207205
result = eval(code, self.get_globals(), self.get_locals())
@@ -212,6 +210,13 @@ def eval(self, line: str) -> object:
212210
self._store_eval_result(result)
213211
return result
214212

213+
# If not a valid `eval` expression, run using `exec` instead.
214+
# Note that we shouldn't run this in the `except SyntaxError` block
215+
# above, then `sys.exc_info()` would not report the right error.
216+
# See issue: https://github.com/prompt-toolkit/ptpython/issues/435
217+
code = self._compile_with_flags(line, "exec")
218+
exec(code, self.get_globals(), self.get_locals())
219+
215220
return None
216221

217222
async def eval_async(self, line: str) -> object:
@@ -231,9 +236,7 @@ async def eval_async(self, line: str) -> object:
231236
try:
232237
code = self._compile_with_flags(line, "eval")
233238
except SyntaxError:
234-
# If not a valid `eval` expression, run using `exec` instead.
235-
code = self._compile_with_flags(line, "exec")
236-
exec(code, self.get_globals(), self.get_locals())
239+
pass
237240
else:
238241
# No syntax errors for eval. Do eval.
239242
result = eval(code, self.get_globals(), self.get_locals())
@@ -244,6 +247,10 @@ async def eval_async(self, line: str) -> object:
244247
self._store_eval_result(result)
245248
return result
246249

250+
# If not a valid `eval` expression, run using `exec` instead.
251+
code = self._compile_with_flags(line, "exec")
252+
exec(code, self.get_globals(), self.get_locals())
253+
247254
return None
248255

249256
def _store_eval_result(self, result: object) -> None:

0 commit comments

Comments
 (0)