Skip to content

better handing of Ctrl-C (and IDEs stop buttons) #237

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion doc/source/changes/version_0_34.rst.inc
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,9 @@ Miscellaneous improvements
Fixes
^^^^^

* fixed something (closes :editor_issue:`1`).
* fixed `run_editor_on_exception` so that the larray editor is not opened when trying to stop a program (via Ctrl-C or
the IDE stop button). Closes :editor_issue:`231`.

* fixed the larray editor window not closing when trying to stop a program (via `Ctrl-C` or the IDE stop button) with
such a window open (closes :editor_issue:`231`). With PyCharm for example, to actually close the program, the user
had to press the IDE stop button a second time (which killed the program instead of stopping it cleanly).
26 changes: 15 additions & 11 deletions larray_editor/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,7 @@ def edit(obj=None, title='', minvalue=None, maxvalue=None, readonly=False, depth
qt_app, parent = get_app_and_window("Viewer")

caller_frame = sys._getframe(depth + 1)
if display_caller_info:
caller_info = getframeinfo(caller_frame)
else:
caller_info = None

caller_info = getframeinfo(caller_frame) if display_caller_info else None
if obj is None:
global_vars = caller_frame.f_globals
local_vars = caller_frame.f_locals
Expand Down Expand Up @@ -306,6 +302,12 @@ def get_name(i, obj, depth=0):
def _qt_except_hook(type, value, tback):
# only print the exception and do *not* exit the program
traceback.print_exception(type, value, tback)
# only catch simple Exception (avoid catching KeyboardInterrupt, ...)
if not isinstance(value, Exception):
# in a Qt app, the except hook is only called when the window gets the focus again,
# so e.g. if we try to stop an app from PyCharm, it stays alive until we switch
# back to the app window.
sys.exit(1)


def install_except_hook():
Expand Down Expand Up @@ -372,10 +374,12 @@ def excepthook(type, value, tback):
tb_limit = user_tb_length if usercode_traceback else None
traceback.print_exception(type, value, main_tb, limit=tb_limit)

stack = extract_tb(main_tb, limit=tb_limit)
stack_pos = user_tb_length - 1 if user_tb_length is not None and usercode_frame else None
print("\nlaunching larray editor to debug...", file=sys.stderr)
_debug(stack, stack_pos=stack_pos)
# open the editor if this is a simple Exception (i.e. not KeyboardInterrupt, ...)
if isinstance(value, Exception):
stack = extract_tb(main_tb, limit=tb_limit)
stack_pos = user_tb_length - 1 if user_tb_length is not None and usercode_frame else None
print("\nlaunching larray editor to debug...", file=sys.stderr)
_debug(stack, stack_pos=stack_pos)

return excepthook

Expand All @@ -389,10 +393,10 @@ def run_editor_on_exception(root_path=None, usercode_traceback=True, usercode_fr
root_path : str, optional
Defaults to None (the directory of the main script).
usercode_traceback : bool, optional
Whether or not to show only the part of the traceback (error log) which corresponds to the user code.
Whether to show only the part of the traceback (error log) which corresponds to the user code.
Otherwise, it will show the complete traceback, including code inside libraries. Defaults to True.
usercode_frame : bool, optional
Whether or not to start the debug window in the frame corresponding to the user code.
Whether to start the debug window in the frame corresponding to the user code.
This argument is ignored (it is always True) if usercode_traceback is True. Defaults to True.

Notes
Expand Down