Skip to content

Commit 7ede68b

Browse files
authored
Add --post-mortem option and PRE_EVALUATION_HOOK & (#83)
sync with mathics-core main
1 parent 9b4ad85 commit 7ede68b

File tree

3 files changed

+124
-96
lines changed

3 files changed

+124
-96
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
strategy:
1313
matrix:
1414
os: [macOS]
15-
python-version: ['3.8', '3.9', '3.10']
15+
python-version: ['3.9', '3.10', 3.11]
1616
steps:
1717
- uses: actions/checkout@v4
1818
- name: Set up Python ${{ matrix.python-version }}

.pre-commit-config.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ repos:
1616
- id: black
1717
language_version: python3
1818
exclude: 'mathicsscript/version.py'
19-
- repo: https://github.com/pycqa/flake8
20-
rev: 3.9.2
21-
hooks:
22-
- id: flake8
23-
stages: [commit]
19+
# - repo: https://github.com/pycqa/flake8
20+
# rev: 3.9.2
21+
# hooks:
22+
# - id: flake8
23+
# stages: [commit]

mathicsscript/__main__.py

Lines changed: 118 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,26 @@
99
from typing import Any
1010

1111
import click
12+
import mathics.core as mathics_core
1213
from mathics import license_string, settings, version_info
1314
from mathics.core.attributes import attribute_string_to_number
1415
from mathics.core.definitions import autoload_files
1516
from mathics.core.evaluation import Evaluation, Output
1617
from mathics.core.expression import from_python
1718
from mathics.core.parser import MathicsFileLineFeeder
1819
from mathics.core.symbols import Symbol, SymbolFalse, SymbolTrue
20+
from mathics.core.systemsymbols import SymbolTeXForm
1921
from mathics_scanner import replace_wl_with_plain_text
2022
from pygments import highlight
2123

2224
from mathicsscript.asymptote import asymptote_version
2325
from mathicsscript.settings import definitions
2426
from mathicsscript.termshell import ShellEscapeException, mma_lexer
2527
from mathicsscript.termshell_gnu import TerminalShellGNUReadline
26-
from mathicsscript.termshell_prompt import TerminalShellPromptToolKit
28+
from mathicsscript.termshell_prompt import (
29+
TerminalShellCommon,
30+
TerminalShellPromptToolKit,
31+
)
2732
from mathicsscript.version import __version__
2833

2934
try:
@@ -47,7 +52,6 @@
4752
**version_info
4853
)
4954

50-
5155
if "cython" in version_info:
5256
version_string += f"cython {version_info['cython']}, "
5357

@@ -135,6 +139,100 @@ def out(self, out):
135139
return self.shell.out_callback(out)
136140

137141

142+
def interactive_eval_loop(
143+
shell: TerminalShellCommon, unicode, prompt, strict_wl_output: bool
144+
):
145+
def identity(x: Any) -> Any:
146+
return x
147+
148+
def fmt_fun(query: Any) -> Any:
149+
return highlight(str(query), mma_lexer, shell.terminal_formatter)
150+
151+
while True:
152+
try:
153+
if have_readline and shell.using_readline:
154+
import readline as GNU_readline
155+
156+
last_pos = GNU_readline.get_current_history_length()
157+
158+
full_form = definitions.get_ownvalue(
159+
"Settings`$ShowFullFormInput"
160+
).replace.to_python()
161+
style = definitions.get_ownvalue("Settings`$PygmentsStyle")
162+
fmt = identity
163+
if style:
164+
style = style.replace.get_string_value()
165+
if shell.terminal_formatter:
166+
fmt = fmt_fun
167+
168+
evaluation = Evaluation(shell.definitions, output=TerminalOutput(shell))
169+
query, source_code = evaluation.parse_feeder_returning_code(shell)
170+
if mathics_core.PRE_EVALUATION_HOOK is not None:
171+
mathics_core.PRE_EVALUATION_HOOK(query, evaluation)
172+
173+
if (
174+
have_readline
175+
and shell.using_readline
176+
and hasattr(GNU_readline, "remove_history_item")
177+
):
178+
current_pos = GNU_readline.get_current_history_length()
179+
for pos in range(last_pos, current_pos - 1):
180+
GNU_readline.remove_history_item(pos)
181+
wl_input = source_code.rstrip()
182+
if unicode:
183+
wl_input = replace_wl_with_plain_text(wl_input)
184+
GNU_readline.add_history(wl_input)
185+
186+
if query is None:
187+
continue
188+
189+
if hasattr(query, "head") and query.head == SymbolTeXForm:
190+
output_style = "//TeXForm"
191+
else:
192+
output_style = ""
193+
194+
if full_form:
195+
print(fmt(query))
196+
result = evaluation.evaluate(
197+
query, timeout=settings.TIMEOUT, format="unformatted"
198+
)
199+
if result is not None:
200+
shell.print_result(
201+
result, prompt, output_style, strict_wl_output=strict_wl_output
202+
)
203+
204+
except ShellEscapeException as e:
205+
source_code = e.line
206+
if len(source_code) and source_code[1] == "!":
207+
try:
208+
print(open(source_code[2:], "r").read())
209+
except Exception:
210+
print(str(sys.exc_info()[1]))
211+
else:
212+
subprocess.run(source_code[1:], shell=True)
213+
214+
# Should we test exit code for adding to history?
215+
GNU_readline.add_history(source_code.rstrip())
216+
# FIXME add this... when in Mathics core updated
217+
# shell.definitions.increment_line(1)
218+
219+
except (KeyboardInterrupt):
220+
print("\nKeyboardInterrupt")
221+
except EOFError:
222+
if prompt:
223+
print("\n\nGoodbye!\n")
224+
break
225+
except SystemExit:
226+
print("\n\nGoodbye!\n")
227+
# raise to pass the error code on, e.g. Quit[1]
228+
raise
229+
finally:
230+
# Reset the input line that would be shown in a parse error.
231+
# This is not to be confused with the number of complete
232+
# inputs that have been seen, i.e. In[]
233+
shell.reset_lineno()
234+
235+
138236
@click.command()
139237
@click.version_option(version=__version__)
140238
@click.option(
@@ -184,6 +282,11 @@ def out(self, out):
184282
show_default=True,
185283
help="Accept Unicode operators in input and show unicode in output.",
186284
)
285+
@click.option(
286+
"--post-mortem/--no-unicode",
287+
show_default=True,
288+
help="go to post-mortem debug on a terminating system exception (needs trepan3k)",
289+
)
187290
@click.option(
188291
"--prompt/--no-prompt",
189292
default=True,
@@ -242,6 +345,7 @@ def main(
242345
readline,
243346
completion,
244347
unicode,
348+
post_mortem,
245349
prompt,
246350
pyextensions,
247351
execute,
@@ -275,6 +379,17 @@ def main(
275379
"Settings`$PygmentsShowTokens", from_python(True if pygments_tokens else False)
276380
)
277381

382+
if post_mortem:
383+
try:
384+
from trepan.post_mortem import post_mortem_excepthook
385+
except ImportError:
386+
print(
387+
"trepan3k is needed for post-mortem debugging --post-mortem option ignored."
388+
)
389+
print("And you may want also trepan3k-mathics3-plugin as well.")
390+
else:
391+
sys.excepthook = post_mortem_excepthook
392+
278393
readline = "none" if (execute or file and not persist) else readline.lower()
279394
if readline == "prompt":
280395
shell = TerminalShellPromptToolKit(
@@ -373,96 +488,9 @@ def main(
373488
definitions.set_attribute(
374489
"Settings`MathicsScriptVersion", attribute_string_to_number["System`Locked"]
375490
)
376-
TeXForm = Symbol("System`TeXForm")
377-
378-
def identity(x: Any) -> Any:
379-
return x
380-
381-
def fmt_fun(query: Any) -> Any:
382-
return highlight(str(query), mma_lexer, shell.terminal_formatter)
383491

384492
definitions.set_line_no(0)
385-
while True:
386-
try:
387-
if have_readline and shell.using_readline:
388-
import readline as GNU_readline
389-
390-
last_pos = GNU_readline.get_current_history_length()
391-
392-
full_form = definitions.get_ownvalue(
393-
"Settings`$ShowFullFormInput"
394-
).replace.to_python()
395-
style = definitions.get_ownvalue("Settings`$PygmentsStyle")
396-
fmt = identity
397-
if style:
398-
style = style.replace.get_string_value()
399-
if shell.terminal_formatter:
400-
fmt = fmt_fun
401-
402-
evaluation = Evaluation(shell.definitions, output=TerminalOutput(shell))
403-
query, source_code = evaluation.parse_feeder_returning_code(shell)
404-
405-
if (
406-
have_readline
407-
and shell.using_readline
408-
and hasattr(GNU_readline, "remove_history_item")
409-
):
410-
current_pos = GNU_readline.get_current_history_length()
411-
for pos in range(last_pos, current_pos - 1):
412-
GNU_readline.remove_history_item(pos)
413-
wl_input = source_code.rstrip()
414-
if unicode:
415-
wl_input = replace_wl_with_plain_text(wl_input)
416-
GNU_readline.add_history(wl_input)
417-
418-
if query is None:
419-
continue
420-
421-
if hasattr(query, "head") and query.head == TeXForm:
422-
output_style = "//TeXForm"
423-
else:
424-
output_style = ""
425-
426-
if full_form:
427-
print(fmt(query))
428-
result = evaluation.evaluate(
429-
query, timeout=settings.TIMEOUT, format="unformatted"
430-
)
431-
if result is not None:
432-
shell.print_result(
433-
result, prompt, output_style, strict_wl_output=strict_wl_output
434-
)
435-
436-
except ShellEscapeException as e:
437-
source_code = e.line
438-
if len(source_code) and source_code[1] == "!":
439-
try:
440-
print(open(source_code[2:], "r").read())
441-
except Exception:
442-
print(str(sys.exc_info()[1]))
443-
else:
444-
subprocess.run(source_code[1:], shell=True)
445-
446-
# Should we test exit code for adding to history?
447-
GNU_readline.add_history(source_code.rstrip())
448-
# FIXME add this... when in Mathics core updated
449-
# shell.definitions.increment_line(1)
450-
451-
except (KeyboardInterrupt):
452-
print("\nKeyboardInterrupt")
453-
except EOFError:
454-
if prompt:
455-
print("\n\nGoodbye!\n")
456-
break
457-
except SystemExit:
458-
print("\n\nGoodbye!\n")
459-
# raise to pass the error code on, e.g. Quit[1]
460-
raise
461-
finally:
462-
# Reset the input line that would be shown in a parse error.
463-
# This is not to be confused with the number of complete
464-
# inputs that have been seen, i.e. In[]
465-
shell.reset_lineno()
493+
interactive_eval_loop(shell, unicode, prompt, strict_wl_output)
466494
return exit_rc
467495

468496

0 commit comments

Comments
 (0)