Skip to content

Commit

Permalink
Allow view-annotate to display in Sage notebook
Browse files Browse the repository at this point in the history
  • Loading branch information
user202729 committed Dec 10, 2024
1 parent fc339c2 commit 97577fe
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 4 deletions.
21 changes: 19 additions & 2 deletions src/sage/misc/cython.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def _standard_libs_libdirs_incdirs_aliases():

def cython(filename, verbose=0, compile_message=False,
use_cache=False, create_local_c_file=False, annotate=True, view_annotate=False,
sage_namespace=True, create_local_so_file=False):
view_annotate_callback=webbrowser.open, sage_namespace=True, create_local_so_file=False):
r"""
Compile a Cython file. This converts a Cython file to a C (or C++ file),
and then compiles that. The .c file and the .so file are
Expand Down Expand Up @@ -114,6 +114,11 @@ def cython(filename, verbose=0, compile_message=False,
- ``view_annotate`` -- boolean (default: ``False``); if ``True``, open the
annotated html file in a web browser using :func:`webbrowser.open`
- ``view_annotate_callback`` -- function (default: ``webbrowser.open``); a function
that takes a string being the path to the html file. This can be overridden to
change what to do with the annotated html file. Have no effect unless
``view_annotate`` is ``True``
- ``sage_namespace`` -- boolean (default: ``True``); if ``True``, import
``sage.all``
Expand Down Expand Up @@ -258,6 +263,18 @@ def cython(filename, verbose=0, compile_message=False,
Traceback (most recent call last):
...
ValueError: Cannot view annotated file without creating it
::
sage: collected_paths = []
sage: cython('''
....: def f(int n):
....: return n*n
....: ''', view_annotate=True, view_annotate_callback=collected_paths.append)
sage: collected_paths
['...']
sage: len(collected_paths)
1
"""
if not filename.endswith('pyx'):
print("Warning: file (={}) should have extension .pyx".format(filename), file=sys.stderr)
Expand Down Expand Up @@ -416,7 +433,7 @@ def cython(filename, verbose=0, compile_message=False,
if view_annotate:
if not annotate:
raise ValueError("Cannot view annotated file without creating it")
webbrowser.open(os.path.join(target_dir, name + ".html"))
view_annotate_callback(os.path.join(target_dir, name + ".html"))

# This emulates running "setup.py build" with the correct options
#
Expand Down
48 changes: 46 additions & 2 deletions src/sage/repl/ipython_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,23 @@
"""

from IPython.core.magic import Magics, magics_class, line_magic, cell_magic
from IPython.core.display import HTML
from IPython import get_ipython

from sage.repl.load import load_wrap
from sage.env import SAGE_IMPORTALL, SAGE_STARTUP_FILE
from sage.misc.lazy_import import LazyImport
from sage.misc.misc import run_once


def _running_in_notebook():
try:
from ipykernel.zmqshell import ZMQInteractiveShell
except ImportError:
return False
return isinstance(get_ipython(), ZMQInteractiveShell)


@magics_class
class SageMagics(Magics):

Expand Down Expand Up @@ -356,6 +366,16 @@ def cython(self, line, cell):
See :func:`~sage.misc.cython.cython` for details.
For ``--view-annotate``, the following additional choices are allowed:
- ``--view-annotate=none`` (default)
- ``--view-annotate=auto`` (same as ``--view-annotate``); select one of the
choices below automatically
- ``--view-annotate=webbrowser``; open the annotation in a web browser
(preferred if the Sage command line is used)
- ``--view-annotate=displayhtml``; display the annotation inline in the notebook
(preferred if the Sage notebook is used)
- ``cell`` -- string; the Cython source code to process
OUTPUT: none; the Cython code is compiled and loaded
Expand Down Expand Up @@ -396,6 +416,15 @@ def cython(self, line, cell):
....: ''')
UsageError: unrecognized arguments: --help
Test ``--view-annotate`` invalid arguments::
sage: # needs sage.misc.cython
sage: shell.run_cell('''
....: %%cython --view-annotate=xx
....: print(1)
....: ''')
UsageError: argument --view-annotate: invalid choice: 'xx' (choose from 'none', 'auto', 'webbrowser', 'displayhtml')
Test invalid quotes (see :mod:`sage.repl.interpreter` for explanation of the dummy line)::
sage: # needs sage.misc.cython
Expand Down Expand Up @@ -428,11 +457,26 @@ def error(self, message):
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("--view-annotate", action=argparse.BooleanOptionalAction)
parser.add_argument("--view-annotate", choices=["none", "auto", "webbrowser", "displayhtml"],
nargs="?", const="auto", default="none")
parser.add_argument("--sage-namespace", 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})
view_annotate = args.view_annotate
del args.view_annotate
if view_annotate == "auto":
if _running_in_notebook():
view_annotate = "displayhtml"
else:
view_annotate = "webbrowser"
args_dict = {k: v for k, v in args.__dict__.items() if v is not None}
if view_annotate != "none":
args_dict["view_annotate"] = True
if view_annotate == "displayhtml":
path_to_annotate_html_container = []
cython_compile(cell, **args_dict, view_annotate_callback=path_to_annotate_html_container.append)
return HTML(filename=path_to_annotate_html_container[0])
return cython_compile(cell, **args_dict)

@cell_magic
def fortran(self, line, cell):
Expand Down

0 comments on commit 97577fe

Please sign in to comment.