From ed00e968934c0403a3654f9010b433aa3803d433 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sat, 9 Nov 2024 17:58:48 +0700 Subject: [PATCH 1/6] Allow specifying arguments to Cython cell_magic --- src/sage/repl/ipython_extension.py | 79 ++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 5 deletions(-) diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index b6fc42bbb37..afb6d92dc77 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -342,7 +342,7 @@ def cython(self, line, cell): INPUT: - - ``line`` -- ignored + - ``line`` -- parsed as keyword arguments. See :func:`~sage.misc.cython.cython` for details. - ``cell`` -- string; the Cython source code to process @@ -350,19 +350,88 @@ def cython(self, line, cell): EXAMPLES:: + sage: # needs sage.misc.cython sage: from sage.repl.interpreter import get_test_shell sage: shell = get_test_shell() - sage: shell.run_cell( # needs sage.misc.cython + sage: shell.run_cell( ....: ''' - ....: %%cython + ....: %%cython -v1 --annotate --no-sage-namespace ....: def f(): ....: print('test') ....: ''') - sage: f() # needs sage.misc.cython + Compiling ....pyx because it changed. + [1/1] Cythonizing ....pyx + sage: f() test + + TESTS: + + See :mod:`sage.repl.interpreter` for explanation of the dummy line. + + Test unrecognized arguments:: + + sage: # needs sage.misc.cython + sage: print("dummy line"); shell.run_cell(''' + ....: %%cython --some-unrecognized-argument + ....: print(1) + ....: ''') + dummy line + ... + ArgumentError...Traceback (most recent call last) + ... + ArgumentError: unrecognized arguments: --some-unrecognized-argument + + Test ``--help`` is disabled:: + + sage: # needs sage.misc.cython + sage: print("dummy line"); shell.run_cell(''' + ....: %%cython --help + ....: print(1) + ....: ''') + dummy line + ... + ArgumentError...Traceback (most recent call last) + ... + ArgumentError: unrecognized arguments: --help + + Test invalid quotes:: + + sage: # needs sage.misc.cython + sage: print("dummy line"); shell.run_cell(''' + ....: %%cython --a=' + ....: print(1) + ....: ''') + dummy line + ... + ValueError...Traceback (most recent call last) + ... + ValueError: No closing quotation """ from sage.misc.cython import cython_compile - return cython_compile(cell) + import shlex + import argparse + + class ExitCatchingArgumentParser(argparse.ArgumentParser): + def error(self, message): + # exit_on_error=False does not work completely in some Python versions + # see https://stackoverflow.com/q/67890157 + raise argparse.ArgumentError(None, message) + + parser = ExitCatchingArgumentParser(prog="%%cython", add_help=False) + parser.add_argument("--verbose", "-v", type=int) + for (arg, arg_short) in [ + ("compile-message", "m"), + ("use-cache", "c"), + ("create-local-c-file", "l"), + ("annotate", "a"), + ("sage-namespace", "s"), + ("create-local-so-file", "o"), + ]: + action = parser.add_argument(f"--{arg}", f"-{arg_short}", action="store_true", default=None) + parser.add_argument(f"--no-{arg}", action="store_false", dest=action.dest, default=None) + + args = parser.parse_args(shlex.split(line)) + return cython_compile(cell, **{k: v for k, v in args.__dict__.items() if v is not None}) @cell_magic def fortran(self, line, cell): From 5ffe9d07d182f6becf8c4a84015e47222129b644 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Mon, 11 Nov 2024 07:36:33 +0700 Subject: [PATCH 2/6] More explicit documentation on allowed arguments to %%cython --- src/sage/repl/ipython_extension.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index afb6d92dc77..80108d17722 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -342,7 +342,18 @@ def cython(self, line, cell): INPUT: - - ``line`` -- parsed as keyword arguments. See :func:`~sage.misc.cython.cython` for details. + - ``line`` -- parsed as keyword arguments. The allowed arguments are: + + - ``--verbose N`` / ``-v N`` + - ``--compile-message`` / ``-m`` + - ``--use-cache`` / ``-c`` + - ``--create-local-c-file`` / ``-l`` + - ``--annotate`` / ``-a`` + - ``--sage-namespace`` / ``-s`` + - ``--create-local-so-file`` / ``-o`` + - ``--no-compile-message``, ``--no-use-cache``, etc. (there is no short form for the ``--no-*`` flags) + + See :func:`~sage.misc.cython.cython` for details. - ``cell`` -- string; the Cython source code to process From 42b952874ae0b2aa710d2d867cbc5805b4edf28c Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Mon, 11 Nov 2024 14:00:49 +0700 Subject: [PATCH 3/6] Change to UsageError for consistency, and use argparse.BooleanOptionalAction --- src/sage/repl/ipython_extension.py | 38 +++++++++++------------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index 80108d17722..a191992b650 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -382,28 +382,20 @@ def cython(self, line, cell): Test unrecognized arguments:: sage: # needs sage.misc.cython - sage: print("dummy line"); shell.run_cell(''' + sage: shell.run_cell(''' ....: %%cython --some-unrecognized-argument ....: print(1) ....: ''') - dummy line - ... - ArgumentError...Traceback (most recent call last) - ... - ArgumentError: unrecognized arguments: --some-unrecognized-argument + UsageError: unrecognized arguments: --some-unrecognized-argument Test ``--help`` is disabled:: sage: # needs sage.misc.cython - sage: print("dummy line"); shell.run_cell(''' + sage: shell.run_cell(''' ....: %%cython --help ....: print(1) ....: ''') - dummy line - ... - ArgumentError...Traceback (most recent call last) - ... - ArgumentError: unrecognized arguments: --help + UsageError: unrecognized arguments: --help Test invalid quotes:: @@ -426,21 +418,19 @@ class ExitCatchingArgumentParser(argparse.ArgumentParser): def error(self, message): # exit_on_error=False does not work completely in some Python versions # see https://stackoverflow.com/q/67890157 - raise argparse.ArgumentError(None, message) + # we raise UsageError to make the interface similar to what happens when e.g. + # IPython's ``%run`` gets unrecognized arguments + from IPython.core.error import UsageError + raise UsageError(message) parser = ExitCatchingArgumentParser(prog="%%cython", add_help=False) parser.add_argument("--verbose", "-v", type=int) - for (arg, arg_short) in [ - ("compile-message", "m"), - ("use-cache", "c"), - ("create-local-c-file", "l"), - ("annotate", "a"), - ("sage-namespace", "s"), - ("create-local-so-file", "o"), - ]: - action = parser.add_argument(f"--{arg}", f"-{arg_short}", action="store_true", default=None) - parser.add_argument(f"--no-{arg}", action="store_false", dest=action.dest, default=None) - + parser.add_argument("-m", "--compile-message", action=argparse.BooleanOptionalAction) + parser.add_argument("-c", "--use-cache", action=argparse.BooleanOptionalAction) + parser.add_argument("-l", "--create-local-c-file", action=argparse.BooleanOptionalAction) + parser.add_argument("-a", "--annotate", action=argparse.BooleanOptionalAction) + parser.add_argument("-s", "--sage-namespace", action=argparse.BooleanOptionalAction) + parser.add_argument("-o", "--create-local-so-file", action=argparse.BooleanOptionalAction) args = parser.parse_args(shlex.split(line)) return cython_compile(cell, **{k: v for k, v in args.__dict__.items() if v is not None}) From 0fa96d5c7a7e10bdd31b8916447f3f7faab6e817 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Tue, 12 Nov 2024 20:21:23 +0700 Subject: [PATCH 4/6] %%cython: Remove infrequent short option --- src/sage/repl/ipython_extension.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index a191992b650..8edb4609d50 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -348,8 +348,8 @@ def cython(self, line, cell): - ``--compile-message`` / ``-m`` - ``--use-cache`` / ``-c`` - ``--create-local-c-file`` / ``-l`` - - ``--annotate`` / ``-a`` - - ``--sage-namespace`` / ``-s`` + - ``--annotate`` + - ``--sage-namespace`` - ``--create-local-so-file`` / ``-o`` - ``--no-compile-message``, ``--no-use-cache``, etc. (there is no short form for the ``--no-*`` flags) @@ -425,12 +425,12 @@ def error(self, message): parser = ExitCatchingArgumentParser(prog="%%cython", add_help=False) parser.add_argument("--verbose", "-v", type=int) - parser.add_argument("-m", "--compile-message", action=argparse.BooleanOptionalAction) - parser.add_argument("-c", "--use-cache", action=argparse.BooleanOptionalAction) - parser.add_argument("-l", "--create-local-c-file", action=argparse.BooleanOptionalAction) - parser.add_argument("-a", "--annotate", action=argparse.BooleanOptionalAction) - parser.add_argument("-s", "--sage-namespace", action=argparse.BooleanOptionalAction) - parser.add_argument("-o", "--create-local-so-file", action=argparse.BooleanOptionalAction) + parser.add_argument("--compile-message", "-m", action=argparse.BooleanOptionalAction) + parser.add_argument("--use-cache", "-c", action=argparse.BooleanOptionalAction) + parser.add_argument("--create-local-c-file", "-l", action=argparse.BooleanOptionalAction) + parser.add_argument("--annotate", action=argparse.BooleanOptionalAction) + parser.add_argument("--sage-namespace", action=argparse.BooleanOptionalAction) + parser.add_argument("--create-local-so-file", "-o", action=argparse.BooleanOptionalAction) args = parser.parse_args(shlex.split(line)) return cython_compile(cell, **{k: v for k, v in args.__dict__.items() if v is not None}) From 531b1d7de662ee53a30a95786f203f5866bb6ce1 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Tue, 12 Nov 2024 22:11:13 +0700 Subject: [PATCH 5/6] Apply suggested changes --- src/sage/repl/ipython_extension.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index 8edb4609d50..a1eec499b8e 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -351,7 +351,7 @@ def cython(self, line, cell): - ``--annotate`` - ``--sage-namespace`` - ``--create-local-so-file`` / ``-o`` - - ``--no-compile-message``, ``--no-use-cache``, etc. (there is no short form for the ``--no-*`` flags) + - ``--no-compile-message``, ``--no-use-cache``, etc. See :func:`~sage.misc.cython.cython` for details. @@ -377,8 +377,6 @@ def cython(self, line, cell): TESTS: - See :mod:`sage.repl.interpreter` for explanation of the dummy line. - Test unrecognized arguments:: sage: # needs sage.misc.cython @@ -397,7 +395,7 @@ def cython(self, line, cell): ....: ''') UsageError: unrecognized arguments: --help - Test invalid quotes:: + Test invalid quotes (see :mod:`sage.repl.interpreter` for explanation of the dummy line):: sage: # needs sage.misc.cython sage: print("dummy line"); shell.run_cell(''' From 578478425a5a5e27f8d8c9c01b1e5720310e444f Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 14 Nov 2024 22:35:07 +0700 Subject: [PATCH 6/6] Remove more short options --- src/sage/repl/ipython_extension.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index a1eec499b8e..e47eba38179 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -345,12 +345,12 @@ def cython(self, line, cell): - ``line`` -- parsed as keyword arguments. The allowed arguments are: - ``--verbose N`` / ``-v N`` - - ``--compile-message`` / ``-m`` - - ``--use-cache`` / ``-c`` - - ``--create-local-c-file`` / ``-l`` + - ``--compile-message`` + - ``--use-cache`` + - ``--create-local-c-file`` - ``--annotate`` - ``--sage-namespace`` - - ``--create-local-so-file`` / ``-o`` + - ``--create-local-so-file`` - ``--no-compile-message``, ``--no-use-cache``, etc. See :func:`~sage.misc.cython.cython` for details. @@ -423,12 +423,12 @@ def error(self, message): parser = ExitCatchingArgumentParser(prog="%%cython", add_help=False) parser.add_argument("--verbose", "-v", type=int) - parser.add_argument("--compile-message", "-m", action=argparse.BooleanOptionalAction) - parser.add_argument("--use-cache", "-c", action=argparse.BooleanOptionalAction) - parser.add_argument("--create-local-c-file", "-l", action=argparse.BooleanOptionalAction) + parser.add_argument("--compile-message", action=argparse.BooleanOptionalAction) + parser.add_argument("--use-cache", action=argparse.BooleanOptionalAction) + parser.add_argument("--create-local-c-file", action=argparse.BooleanOptionalAction) parser.add_argument("--annotate", action=argparse.BooleanOptionalAction) parser.add_argument("--sage-namespace", action=argparse.BooleanOptionalAction) - parser.add_argument("--create-local-so-file", "-o", action=argparse.BooleanOptionalAction) + parser.add_argument("--create-local-so-file", action=argparse.BooleanOptionalAction) args = parser.parse_args(shlex.split(line)) return cython_compile(cell, **{k: v for k, v in args.__dict__.items() if v is not None})