passagemath-repl 10.5.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_repl-10.5.1.data/scripts/sage-cachegrind +25 -0
- passagemath_repl-10.5.1.data/scripts/sage-callgrind +16 -0
- passagemath_repl-10.5.1.data/scripts/sage-cleaner +230 -0
- passagemath_repl-10.5.1.data/scripts/sage-coverage +327 -0
- passagemath_repl-10.5.1.data/scripts/sage-eval +14 -0
- passagemath_repl-10.5.1.data/scripts/sage-fixdoctests +710 -0
- passagemath_repl-10.5.1.data/scripts/sage-inline-fortran +12 -0
- passagemath_repl-10.5.1.data/scripts/sage-ipynb2rst +50 -0
- passagemath_repl-10.5.1.data/scripts/sage-ipython +16 -0
- passagemath_repl-10.5.1.data/scripts/sage-massif +25 -0
- passagemath_repl-10.5.1.data/scripts/sage-notebook +267 -0
- passagemath_repl-10.5.1.data/scripts/sage-omega +25 -0
- passagemath_repl-10.5.1.data/scripts/sage-preparse +302 -0
- passagemath_repl-10.5.1.data/scripts/sage-run +27 -0
- passagemath_repl-10.5.1.data/scripts/sage-run-cython +10 -0
- passagemath_repl-10.5.1.data/scripts/sage-runtests +9 -0
- passagemath_repl-10.5.1.data/scripts/sage-startuptime.py +163 -0
- passagemath_repl-10.5.1.data/scripts/sage-valgrind +34 -0
- passagemath_repl-10.5.1.dist-info/METADATA +77 -0
- passagemath_repl-10.5.1.dist-info/RECORD +162 -0
- passagemath_repl-10.5.1.dist-info/WHEEL +5 -0
- passagemath_repl-10.5.1.dist-info/top_level.txt +1 -0
- sage/all__sagemath_repl.py +119 -0
- sage/doctest/__init__.py +4 -0
- sage/doctest/__main__.py +236 -0
- sage/doctest/all.py +4 -0
- sage/doctest/check_tolerance.py +261 -0
- sage/doctest/control.py +1727 -0
- sage/doctest/external.py +534 -0
- sage/doctest/fixtures.py +383 -0
- sage/doctest/forker.py +2665 -0
- sage/doctest/marked_output.py +102 -0
- sage/doctest/parsing.py +1708 -0
- sage/doctest/parsing_test.py +79 -0
- sage/doctest/reporting.py +733 -0
- sage/doctest/rif_tol.py +124 -0
- sage/doctest/sources.py +1657 -0
- sage/doctest/test.py +584 -0
- sage/doctest/tests/1second.rst +4 -0
- sage/doctest/tests/99seconds.rst +4 -0
- sage/doctest/tests/abort.rst +5 -0
- sage/doctest/tests/atexit.rst +7 -0
- sage/doctest/tests/fail_and_die.rst +6 -0
- sage/doctest/tests/initial.rst +15 -0
- sage/doctest/tests/interrupt.rst +7 -0
- sage/doctest/tests/interrupt_diehard.rst +14 -0
- sage/doctest/tests/keyboardinterrupt.rst +11 -0
- sage/doctest/tests/longtime.rst +5 -0
- sage/doctest/tests/nodoctest +5 -0
- sage/doctest/tests/random_seed.rst +4 -0
- sage/doctest/tests/show_skipped.rst +18 -0
- sage/doctest/tests/sig_on.rst +9 -0
- sage/doctest/tests/simple_failure.rst +8 -0
- sage/doctest/tests/sleep_and_raise.rst +106 -0
- sage/doctest/tests/tolerance.rst +31 -0
- sage/doctest/util.py +750 -0
- sage/interfaces/cleaner.py +48 -0
- sage/interfaces/quit.py +163 -0
- sage/misc/all__sagemath_repl.py +51 -0
- sage/misc/banner.py +235 -0
- sage/misc/benchmark.py +221 -0
- sage/misc/classgraph.py +134 -0
- sage/misc/copying.py +22 -0
- sage/misc/cython.py +694 -0
- sage/misc/dev_tools.py +745 -0
- sage/misc/edit_module.py +304 -0
- sage/misc/explain_pickle.py +3079 -0
- sage/misc/gperftools.py +361 -0
- sage/misc/inline_fortran.py +212 -0
- sage/misc/messaging.py +86 -0
- sage/misc/pager.py +21 -0
- sage/misc/profiler.py +179 -0
- sage/misc/python.py +70 -0
- sage/misc/remote_file.py +53 -0
- sage/misc/sage_eval.py +249 -0
- sage/misc/sage_input.py +3621 -0
- sage/misc/sagedoc.py +1742 -0
- sage/misc/sh.py +38 -0
- sage/misc/trace.py +90 -0
- sage/repl/__init__.py +16 -0
- sage/repl/all.py +15 -0
- sage/repl/attach.py +625 -0
- sage/repl/configuration.py +186 -0
- sage/repl/display/__init__.py +1 -0
- sage/repl/display/fancy_repr.py +354 -0
- sage/repl/display/formatter.py +318 -0
- sage/repl/display/jsmol_iframe.py +290 -0
- sage/repl/display/pretty_print.py +153 -0
- sage/repl/display/util.py +163 -0
- sage/repl/image.py +302 -0
- sage/repl/inputhook.py +91 -0
- sage/repl/interface_magic.py +298 -0
- sage/repl/interpreter.py +854 -0
- sage/repl/ipython_extension.py +593 -0
- sage/repl/ipython_kernel/__init__.py +1 -0
- sage/repl/ipython_kernel/__main__.py +4 -0
- sage/repl/ipython_kernel/all_jupyter.py +10 -0
- sage/repl/ipython_kernel/install.py +301 -0
- sage/repl/ipython_kernel/interact.py +278 -0
- sage/repl/ipython_kernel/kernel.py +217 -0
- sage/repl/ipython_kernel/widgets.py +466 -0
- sage/repl/ipython_kernel/widgets_sagenb.py +587 -0
- sage/repl/ipython_tests.py +163 -0
- sage/repl/load.py +326 -0
- sage/repl/preparse.py +2218 -0
- sage/repl/prompts.py +90 -0
- sage/repl/rich_output/__init__.py +4 -0
- sage/repl/rich_output/backend_base.py +648 -0
- sage/repl/rich_output/backend_doctest.py +316 -0
- sage/repl/rich_output/backend_emacs.py +151 -0
- sage/repl/rich_output/backend_ipython.py +596 -0
- sage/repl/rich_output/buffer.py +311 -0
- sage/repl/rich_output/display_manager.py +829 -0
- sage/repl/rich_output/example.avi +0 -0
- sage/repl/rich_output/example.canvas3d +1 -0
- sage/repl/rich_output/example.dvi +0 -0
- sage/repl/rich_output/example.flv +0 -0
- sage/repl/rich_output/example.gif +0 -0
- sage/repl/rich_output/example.jpg +0 -0
- sage/repl/rich_output/example.mkv +0 -0
- sage/repl/rich_output/example.mov +0 -0
- sage/repl/rich_output/example.mp4 +0 -0
- sage/repl/rich_output/example.ogv +0 -0
- sage/repl/rich_output/example.pdf +0 -0
- sage/repl/rich_output/example.png +0 -0
- sage/repl/rich_output/example.svg +54 -0
- sage/repl/rich_output/example.webm +0 -0
- sage/repl/rich_output/example.wmv +0 -0
- sage/repl/rich_output/example_jmol.spt.zip +0 -0
- sage/repl/rich_output/example_wavefront_scene.mtl +7 -0
- sage/repl/rich_output/example_wavefront_scene.obj +17 -0
- sage/repl/rich_output/output_basic.py +391 -0
- sage/repl/rich_output/output_browser.py +103 -0
- sage/repl/rich_output/output_catalog.py +54 -0
- sage/repl/rich_output/output_graphics.py +320 -0
- sage/repl/rich_output/output_graphics3d.py +345 -0
- sage/repl/rich_output/output_video.py +231 -0
- sage/repl/rich_output/preferences.py +432 -0
- sage/repl/rich_output/pretty_print.py +339 -0
- sage/repl/rich_output/test_backend.py +201 -0
- sage/repl/user_globals.py +214 -0
- sage/tests/all.py +0 -0
- sage/tests/all__sagemath_repl.py +3 -0
- sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py +630 -0
- sage/tests/arxiv_0812_2725.py +351 -0
- sage/tests/benchmark.py +1925 -0
- sage/tests/book_schilling_zabrocki_kschur_primer.py +795 -0
- sage/tests/book_stein_ent.py +651 -0
- sage/tests/book_stein_modform.py +558 -0
- sage/tests/cmdline.py +796 -0
- sage/tests/combinatorial_hopf_algebras.py +52 -0
- sage/tests/finite_poset.py +623 -0
- sage/tests/functools_partial_src.py +27 -0
- sage/tests/gosper-sum.py +218 -0
- sage/tests/lazy_imports.py +28 -0
- sage/tests/modular_group_cohomology.py +80 -0
- sage/tests/numpy.py +21 -0
- sage/tests/parigp.py +76 -0
- sage/tests/startup.py +27 -0
- sage/tests/symbolic-series.py +76 -0
- sage/tests/sympy.py +16 -0
- sage/tests/test_deprecation.py +31 -0
@@ -0,0 +1,50 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
if [ -z $SAGE_EXTCODE ]; then
|
4
|
+
SAGE_EXTCODE=`${0/-ipynb2rst} -c "from sage.env import SAGE_EXTCODE; print(SAGE_EXTCODE)"`
|
5
|
+
fi
|
6
|
+
|
7
|
+
fail () {
|
8
|
+
echo "ERROR: ${1}" 1>&2
|
9
|
+
exit 1
|
10
|
+
}
|
11
|
+
|
12
|
+
help () {
|
13
|
+
cat << EOF
|
14
|
+
Usage:
|
15
|
+
|
16
|
+
sage -ipynb2rst <source> [<destination>]
|
17
|
+
|
18
|
+
Generates reStructuredText source (.rst) from IPython worksheet (.ipynb).
|
19
|
+
|
20
|
+
If the destination is not specified, the reStructuredText source is written in
|
21
|
+
the standard output.
|
22
|
+
|
23
|
+
Examples:
|
24
|
+
|
25
|
+
sage -ipynb2rst file.ipynb file.rst
|
26
|
+
|
27
|
+
sage -ipynb2rst file.ipynb
|
28
|
+
|
29
|
+
Options:
|
30
|
+
-h, --help show this help message and exit
|
31
|
+
EOF
|
32
|
+
}
|
33
|
+
|
34
|
+
if [ "${1}" = '-h' ] || [ "${1}" = '--help' ] ; then help ; exit 0 ; fi
|
35
|
+
|
36
|
+
case "${#}" in
|
37
|
+
(1)
|
38
|
+
jupyter nbconvert --to rst --RSTExporter.template_path=[\'$SAGE_EXTCODE/nbconvert/\'] --RSTExporter.template_file='rst_sage.tpl' --NbConvertApp.output_files_dir='.' --output-dir='.' "${1}" || ( echo -e '\n' ; help )
|
39
|
+
$SAGE_EXTCODE/nbconvert/postprocess.py "${1/.ipynb/.rst}"
|
40
|
+
;;
|
41
|
+
(2)
|
42
|
+
jupyter nbconvert --output="${2}" --to rst --RSTExporter.template_path=[\'$SAGE_EXTCODE/nbconvert/\'] --RSTExporter.template_file='rst_sage.tpl' --NbConvertApp.output_files_dir='.' "${1}" || ( echo -e '\n' ; help )
|
43
|
+
$SAGE_EXTCODE/nbconvert/postprocess.py "${2}"
|
44
|
+
;;
|
45
|
+
(*)
|
46
|
+
help ;;
|
47
|
+
esac
|
48
|
+
|
49
|
+
exit 0
|
50
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!python
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
"""
|
4
|
+
Sage IPython startup script.
|
5
|
+
"""
|
6
|
+
|
7
|
+
# Display startup banner. Do this before anything else to give the user
|
8
|
+
# early feedback that Sage is starting.
|
9
|
+
from sage.misc.banner import banner
|
10
|
+
banner()
|
11
|
+
|
12
|
+
from sage.repl.interpreter import SageTerminalApp
|
13
|
+
|
14
|
+
app = SageTerminalApp.instance()
|
15
|
+
app.initialize()
|
16
|
+
app.start()
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
# We reuse the gdb pythonstartup script.
|
4
|
+
PYTHONSTARTUP=`dirname $0`/sage-ipython
|
5
|
+
export PYTHONSTARTUP
|
6
|
+
echo $PYTHONSTARTUP
|
7
|
+
if [ ! -d "$DOT_SAGE/valgrind" ]; then
|
8
|
+
mkdir "$DOT_SAGE/valgrind"
|
9
|
+
fi
|
10
|
+
|
11
|
+
LOG="$DOT_SAGE"/valgrind/sage-massif.%p
|
12
|
+
echo "Log file is $LOG"
|
13
|
+
|
14
|
+
MASSIF_FLAGS="--log-file=$LOG --depth=6 "; export MASSIF_FLAGS
|
15
|
+
if [ "$SAGE_MASSIF_FLAGS" ]; then
|
16
|
+
echo "Overwriting massif flags with:"
|
17
|
+
echo $SAGE_MASSIF_FLAGS
|
18
|
+
MASSIF_FLAGS=$SAGE_MASSIF_FLAGS; export MASSIF_FLAGS
|
19
|
+
else
|
20
|
+
echo "Using default flags:"
|
21
|
+
echo $MASSIF_FLAGS
|
22
|
+
fi
|
23
|
+
|
24
|
+
valgrind --tool=massif $MASSIF_FLAGS sage-python -i
|
25
|
+
|
@@ -0,0 +1,267 @@
|
|
1
|
+
#!python
|
2
|
+
# -*- coding: utf-8; mode: python -*-
|
3
|
+
|
4
|
+
import os
|
5
|
+
import sys
|
6
|
+
import ast
|
7
|
+
import argparse
|
8
|
+
import logging
|
9
|
+
import textwrap
|
10
|
+
from contextlib import contextmanager
|
11
|
+
|
12
|
+
logging.basicConfig()
|
13
|
+
logger = logging.getLogger()
|
14
|
+
|
15
|
+
from sage.misc.banner import banner
|
16
|
+
|
17
|
+
|
18
|
+
_system_jupyter_url = "https://doc.sagemath.org/html/en/installation/launching.html#setting-up-sagemath-as-a-jupyter-kernel-in-an-existing-jupyter-notebook-or-jupyterlab-installation"
|
19
|
+
|
20
|
+
|
21
|
+
class NotebookJupyter():
|
22
|
+
|
23
|
+
def print_banner(self):
|
24
|
+
print('Please wait while the Sage Jupyter Notebook server starts...')
|
25
|
+
|
26
|
+
@classmethod
|
27
|
+
def print_help(cls):
|
28
|
+
cls(['help'])
|
29
|
+
|
30
|
+
def __init__(self, argv):
|
31
|
+
self.print_banner()
|
32
|
+
try:
|
33
|
+
try:
|
34
|
+
# notebook 6
|
35
|
+
from notebook.notebookapp import main
|
36
|
+
except ImportError:
|
37
|
+
# notebook 7
|
38
|
+
from notebook.app import main
|
39
|
+
except ImportError:
|
40
|
+
import traceback
|
41
|
+
traceback.print_exc()
|
42
|
+
print("The Jupyter notebook is not installed (at least not in this Sage installation).")
|
43
|
+
print("You can install it by running")
|
44
|
+
print(" sage -i notebook")
|
45
|
+
print("Alternatively, you can follow the instructions at")
|
46
|
+
print(" " + _system_jupyter_url)
|
47
|
+
print("to use Sage with an existing Jupyter notebook installation.")
|
48
|
+
raise SystemExit(1)
|
49
|
+
main(argv)
|
50
|
+
|
51
|
+
|
52
|
+
class NotebookJupyterlab():
|
53
|
+
def print_banner(self):
|
54
|
+
print('Please wait while the Jupyterlab server starts...')
|
55
|
+
|
56
|
+
@classmethod
|
57
|
+
def print_help(cls):
|
58
|
+
cls(['help'])
|
59
|
+
|
60
|
+
def __init__(self, argv):
|
61
|
+
try:
|
62
|
+
from jupyterlab.labapp import main
|
63
|
+
except ImportError:
|
64
|
+
import traceback
|
65
|
+
traceback.print_exc()
|
66
|
+
print("Jupyterlab is not installed (at least not in this Sage installation).")
|
67
|
+
print("You can install it by running")
|
68
|
+
print(" sage -i jupyterlab")
|
69
|
+
print("Alternatively, you can follow the instructions at")
|
70
|
+
print(" " + _system_jupyter_url)
|
71
|
+
print("to use Sage with an existing Jupyterlab installation.")
|
72
|
+
raise SystemExit(1)
|
73
|
+
self.print_banner()
|
74
|
+
main(argv)
|
75
|
+
|
76
|
+
|
77
|
+
class SageNBExport(NotebookJupyter):
|
78
|
+
|
79
|
+
def print_banner(self):
|
80
|
+
print('Please wait while the SageNB export server starts...')
|
81
|
+
|
82
|
+
@classmethod
|
83
|
+
def print_help(cls):
|
84
|
+
cls(['--help'])
|
85
|
+
|
86
|
+
def __init__(self, argv):
|
87
|
+
if argv:
|
88
|
+
SAGENB_EXPORT = 'sagenb-export'
|
89
|
+
os.execvp(SAGENB_EXPORT, [SAGENB_EXPORT] + argv)
|
90
|
+
argv += [
|
91
|
+
"--NotebookApp.nbserver_extensions={'sagenb_export.nbextension':True}",
|
92
|
+
"--NotebookApp.default_url='/sagenb'",
|
93
|
+
]
|
94
|
+
super(SageNBExport, self).__init__(argv)
|
95
|
+
|
96
|
+
|
97
|
+
description = \
|
98
|
+
"""
|
99
|
+
The Sage notebook launcher is used to start the notebook, and allows
|
100
|
+
you to choose between different implementations. Any further command
|
101
|
+
line options are passed to the respective notebook.
|
102
|
+
"""
|
103
|
+
|
104
|
+
help_help = \
|
105
|
+
"""
|
106
|
+
show this help message and exit. Can be combined with
|
107
|
+
"--notebook=[...]" to see notebook-specific options
|
108
|
+
"""
|
109
|
+
|
110
|
+
epilog = \
|
111
|
+
"""
|
112
|
+
EXAMPLES:
|
113
|
+
|
114
|
+
* Run default notebook on port 1234.
|
115
|
+
|
116
|
+
sage -n default --port=1234
|
117
|
+
sage -n --port=1234 # equivalent
|
118
|
+
|
119
|
+
* Run Jupyter notebook in custom directory:
|
120
|
+
|
121
|
+
sage --notebook=jupyter --notebook-dir=/home/foo/bar
|
122
|
+
|
123
|
+
* List available legacy Sage notebooks:
|
124
|
+
|
125
|
+
sage --notebook=export --list
|
126
|
+
|
127
|
+
* Export a legacy Sage notebook as a Jupyter notebook:
|
128
|
+
|
129
|
+
sage --notebook=export --ipynb=Output.ipynb admin:10
|
130
|
+
"""
|
131
|
+
|
132
|
+
notebook_launcher = {
|
133
|
+
'default': NotebookJupyter, # change this to change the default
|
134
|
+
'ipython': NotebookJupyter,
|
135
|
+
'jupyter': NotebookJupyter,
|
136
|
+
'jupyterlab': NotebookJupyterlab,
|
137
|
+
'export': SageNBExport,
|
138
|
+
}
|
139
|
+
|
140
|
+
notebook_names = ', '.join(notebook_launcher.keys())
|
141
|
+
|
142
|
+
|
143
|
+
def make_parser():
|
144
|
+
"""
|
145
|
+
The main parser handling the selection of the notebook.
|
146
|
+
|
147
|
+
Any arguments that are not parsed here are supposed to be handled
|
148
|
+
by the notebook implementation.
|
149
|
+
"""
|
150
|
+
parser = argparse.ArgumentParser(
|
151
|
+
description=description, epilog=epilog,
|
152
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
153
|
+
add_help=False)
|
154
|
+
parser.add_argument('-h', '--help',
|
155
|
+
dest='option_help', action='store_true',
|
156
|
+
default=False,
|
157
|
+
help=help_help)
|
158
|
+
parser.add_argument('--log', dest='log', default=None,
|
159
|
+
help='one of [DEBUG, INFO, ERROR, WARNING, CRITICAL]')
|
160
|
+
default = None
|
161
|
+
for name, launcher in notebook_launcher.items():
|
162
|
+
if launcher == notebook_launcher['default'] and name != 'default':
|
163
|
+
default = name
|
164
|
+
if default is None:
|
165
|
+
raise RuntimeError('default launcher is defined but not known under a specific name')
|
166
|
+
parser.add_argument('--notebook', # long style
|
167
|
+
'-n', # short style
|
168
|
+
'-notebook', # wtf style, we can't decide (legacy support)
|
169
|
+
dest='notebook', type=str, nargs='?', const='default',
|
170
|
+
help='The notebook to run [one of: {0}]. Default is {1}'.format(
|
171
|
+
notebook_names, default))
|
172
|
+
return parser
|
173
|
+
|
174
|
+
|
175
|
+
def trac_23428_browser_workaround():
|
176
|
+
"""
|
177
|
+
Running 'sage -n" with the Jupyter notebook on Darwin fails to
|
178
|
+
open a browser automatically. See :trac:`23428`.
|
179
|
+
"""
|
180
|
+
if sys.platform != 'darwin':
|
181
|
+
return
|
182
|
+
if not os.environ.get('BROWSER', False):
|
183
|
+
os.environ['BROWSER'] = 'open'
|
184
|
+
|
185
|
+
|
186
|
+
@contextmanager
|
187
|
+
def sage_doc_server():
|
188
|
+
from functools import partial
|
189
|
+
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
|
190
|
+
from threading import Thread
|
191
|
+
from sage.env import SAGE_DOC, SAGE_DOC_LOCAL_PORT as port
|
192
|
+
|
193
|
+
server = ThreadingHTTPServer(('127.0.0.1', int(port)),
|
194
|
+
partial(SimpleHTTPRequestHandler, directory=SAGE_DOC))
|
195
|
+
|
196
|
+
if port == '0':
|
197
|
+
port = str(server.server_address[1])
|
198
|
+
os.environ['SAGE_DOC_LOCAL_PORT'] = port
|
199
|
+
|
200
|
+
server_thread = Thread(target=server.serve_forever, name="sage_doc_server")
|
201
|
+
server_thread.start()
|
202
|
+
print(f'Sage doc server started running at http://127.0.0.1:{port}')
|
203
|
+
|
204
|
+
try:
|
205
|
+
yield
|
206
|
+
finally:
|
207
|
+
server.shutdown()
|
208
|
+
server_thread.join()
|
209
|
+
print(f'Sage doc server stopped runnning at http://127.0.0.1:{port}')
|
210
|
+
|
211
|
+
|
212
|
+
if __name__ == '__main__':
|
213
|
+
parser = make_parser()
|
214
|
+
args, unknown = parser.parse_known_args(sys.argv[1:])
|
215
|
+
if unknown and unknown[0] == '--':
|
216
|
+
unknown = unknown[1:]
|
217
|
+
trac_23428_browser_workaround()
|
218
|
+
if args.log is not None:
|
219
|
+
import logging
|
220
|
+
level = getattr(logging, args.log.upper())
|
221
|
+
logger.setLevel(level=level)
|
222
|
+
logger.info('Main parser got arguments %s', args)
|
223
|
+
logger.info('Passing on to notebook implementation: %s', unknown)
|
224
|
+
|
225
|
+
if args.notebook == "sagenb":
|
226
|
+
logger.critical('cannot use the legacy notebook SageNB with Python 3')
|
227
|
+
print('The legacy notebook does not work under Python 3; '
|
228
|
+
'use the Jupyter notebook.')
|
229
|
+
print('See https://wiki.sagemath.org/Python3-Switch')
|
230
|
+
print('Use \"sage --notebook=export\" to export SageNB notebooks '
|
231
|
+
'to Jupyter')
|
232
|
+
sys.exit(1)
|
233
|
+
|
234
|
+
from sage.repl.ipython_kernel.install import SageKernelSpec
|
235
|
+
SageKernelSpec.check()
|
236
|
+
|
237
|
+
try:
|
238
|
+
launcher = notebook_launcher[args.notebook]
|
239
|
+
except KeyError:
|
240
|
+
logger.critical('unknown notebook: %s', args.notebook)
|
241
|
+
print('Error, notebook must be one of {0} but got {1}'.
|
242
|
+
format(notebook_names, args.notebook))
|
243
|
+
sys.exit(1)
|
244
|
+
|
245
|
+
if args.option_help:
|
246
|
+
if args.notebook == 'default':
|
247
|
+
parser.print_help()
|
248
|
+
else:
|
249
|
+
launcher.print_help()
|
250
|
+
sys.exit(0)
|
251
|
+
|
252
|
+
banner()
|
253
|
+
|
254
|
+
# Start a Sage doc server if the Sage documentation is available locally.
|
255
|
+
# See the corresponding code in src/sage/repl/ipython_kernel/kernel.py.
|
256
|
+
|
257
|
+
from sage.env import SAGE_DOC_SERVER_URL
|
258
|
+
from sage.features.sagemath import sagemath_doc_html
|
259
|
+
|
260
|
+
if SAGE_DOC_SERVER_URL:
|
261
|
+
print(f'Sage doc server is running at {SAGE_DOC_SERVER_URL}')
|
262
|
+
launcher(unknown)
|
263
|
+
elif sagemath_doc_html().is_present():
|
264
|
+
with sage_doc_server():
|
265
|
+
launcher(unknown)
|
266
|
+
else:
|
267
|
+
launcher(unknown)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
# We reuse the gdb pythonstartup script.
|
4
|
+
PYTHONSTARTUP=`dirname $0`/sage-ipython
|
5
|
+
export PYTHONSTARTUP
|
6
|
+
echo $PYTHONSTARTUP
|
7
|
+
if [ ! -d "$DOT_SAGE/valgrind" ]; then
|
8
|
+
mkdir "$DOT_SAGE/valgrind"
|
9
|
+
fi
|
10
|
+
|
11
|
+
LOG="$DOT_SAGE"/valgrind/sage-omega.%p
|
12
|
+
echo "Log file is $LOG"
|
13
|
+
|
14
|
+
OMEGA_FLAGS="--log-file=$LOG "; export OMEGA_FLAGS
|
15
|
+
if [ "$SAGE_OMEGA_FLAGS" ]; then
|
16
|
+
echo "Overwriting omega flags with:"
|
17
|
+
echo $SAGE_OMEGA_FLAGS
|
18
|
+
OMEGA_FLAGS=$SAGE_OMEGA_FLAGS; export OMEGA_FLAGS
|
19
|
+
else
|
20
|
+
echo "Using default flags:"
|
21
|
+
echo $OMEGA_FLAGS
|
22
|
+
fi
|
23
|
+
|
24
|
+
valgrind --tool=exp-omega $OMEGA_FLAGS sage-python -i
|
25
|
+
|
@@ -0,0 +1,302 @@
|
|
1
|
+
#!python
|
2
|
+
"""
|
3
|
+
Preparse .sage files and save the result to .sage.py files.
|
4
|
+
|
5
|
+
AUTHOR:
|
6
|
+
-- William Stein (2005): first version
|
7
|
+
-- William Stein (2008): fix trac #2391 and document the code.
|
8
|
+
-- Dan Drake (2009): fix trac #5052
|
9
|
+
-- Dan Drake (2010-12-08): fix trac #10440
|
10
|
+
-- Johan S. R. Nielsen (2015-11-06): fix trac #17019
|
11
|
+
"""
|
12
|
+
|
13
|
+
import os
|
14
|
+
import sys
|
15
|
+
import re
|
16
|
+
|
17
|
+
from sage.repl.preparse import preparse_file
|
18
|
+
from sage.misc.temporary_file import atomic_write
|
19
|
+
|
20
|
+
# The spkg/bin/sage script passes the files to be preparsed as
|
21
|
+
# arguments (but remove sys.argv[0]).
|
22
|
+
files = sys.argv[1:]
|
23
|
+
|
24
|
+
# There must be at least 1 file or we display an error/usage message
|
25
|
+
# and exit
|
26
|
+
if not files:
|
27
|
+
print("""Usage: {} <file1.sage> <file2.sage>...
|
28
|
+
Creates files file1.sage.py, file2.sage.py ... that are the Sage
|
29
|
+
preparsed versions of file1.sage, file2.sage ...
|
30
|
+
If a non-autogenerated .sage.py file with the same name exists, you will
|
31
|
+
receive an error and the file will not be overwritten.""".format(sys.argv[0]))
|
32
|
+
sys.exit(1)
|
33
|
+
|
34
|
+
# The module-scope variable contains a list of all files we
|
35
|
+
# have seen while preparsing a given file. The point of this
|
36
|
+
# is that we want to avoid preparsing a file we have already
|
37
|
+
# seen, since then infinite loops would result from mutual
|
38
|
+
# recursive includes.
|
39
|
+
files_so_far = []
|
40
|
+
|
41
|
+
# This message is inserted in autogenerated files so that the reader
|
42
|
+
# will know, and so we know it is safe to overwrite them.
|
43
|
+
AUTOGEN_MSG = "# This file was *autogenerated* from the file "
|
44
|
+
|
45
|
+
# We use this regexp to parse lines with load or attach statements.
|
46
|
+
# Here's what it looks for:
|
47
|
+
#
|
48
|
+
# A (possibly empty) sequence of whitespace at the beginning of the
|
49
|
+
# line, saved as a group named 'lws';
|
50
|
+
#
|
51
|
+
# followed by
|
52
|
+
#
|
53
|
+
# the word "load" or "attach";
|
54
|
+
#
|
55
|
+
# followed by
|
56
|
+
#
|
57
|
+
# a nonempty sequence of whitespace;
|
58
|
+
#
|
59
|
+
# followed by
|
60
|
+
#
|
61
|
+
# whatever else is on the line, saved as a group named 'files'.
|
62
|
+
#
|
63
|
+
# We want to save the leading white space so that we can maintain
|
64
|
+
# correct indentation in the preparsed file.
|
65
|
+
load_or_attach = re.compile(r"^(?P<lws>\s*)(load|attach)\s+(?P<files>.*)$")
|
66
|
+
|
67
|
+
def do_preparse(f, files_before=[]):
|
68
|
+
"""
|
69
|
+
Preparse the file f and write the result out to a filename
|
70
|
+
with extension .sage.py.
|
71
|
+
|
72
|
+
INPUT:
|
73
|
+
|
74
|
+
- ``f`` -- string: the name of a file
|
75
|
+
- ``files_before`` -- list of strings of previous filenames loaded (to avoid circular loops)
|
76
|
+
|
77
|
+
OUTPUT: none (writes a file with extension .sage.py to disk)
|
78
|
+
"""
|
79
|
+
if f in files_so_far:
|
80
|
+
return
|
81
|
+
files_so_far.append(f)
|
82
|
+
if not os.path.exists(f):
|
83
|
+
print("{}: File '{}' is missing".format(sys.argv[0], f))
|
84
|
+
return
|
85
|
+
if f.endswith('.py'):
|
86
|
+
return
|
87
|
+
if not f.endswith('.sage'):
|
88
|
+
print("{}: Unknown file type {}".format(sys.argv[0], f))
|
89
|
+
sys.exit(1)
|
90
|
+
|
91
|
+
fname = f + ".py"
|
92
|
+
if os.path.exists(fname):
|
93
|
+
with open(fname) as fin:
|
94
|
+
if AUTOGEN_MSG not in fin.read():
|
95
|
+
print("Refusing to overwrite existing non-autogenerated file {!r}."
|
96
|
+
.format(os.path.abspath(fname)))
|
97
|
+
print("Please delete or move this file manually.")
|
98
|
+
sys.exit(1)
|
99
|
+
|
100
|
+
# TODO:
|
101
|
+
# I am commenting this "intelligence" out, since, e.g., if I change
|
102
|
+
# the preparser between versions this can cause problems. This
|
103
|
+
# is an optimization that definitely isn't needed at present, since
|
104
|
+
# preparsing is so fast.
|
105
|
+
# Idea: I could introduce version numbers, though....
|
106
|
+
#if os.path.exists(fname) and os.path.getmtime(fname) >= os.path.getmtime(f):
|
107
|
+
# return
|
108
|
+
|
109
|
+
# Finally open the file
|
110
|
+
with open(f) as fin:
|
111
|
+
F = fin.read()
|
112
|
+
|
113
|
+
# Check to see if a coding is specified in the .sage file. If it is,
|
114
|
+
# then we want to copy it over to the new file and not include it in
|
115
|
+
# the preprocessing. If both the first and second line have an
|
116
|
+
# encoding declaration, the second line's encoding will get used.
|
117
|
+
|
118
|
+
lines = F.splitlines()
|
119
|
+
coding = ''
|
120
|
+
for num, line in enumerate(lines[:2]):
|
121
|
+
if re.search(r"coding[:=]\s*([-\w.]+)", line):
|
122
|
+
coding = line + '\n'
|
123
|
+
F = '\n'.join(lines[:num] + lines[(num+1):])
|
124
|
+
|
125
|
+
# It is ** critical ** that all the preparser-stuff we put into
|
126
|
+
# the file are put after the module docstring, since
|
127
|
+
# otherwise the docstring will not be understood by Python.
|
128
|
+
i = find_position_right_after_module_docstring(F)
|
129
|
+
header, body = F[:i] , F[i:]
|
130
|
+
# Preparse the body
|
131
|
+
body = preparse_file(body)
|
132
|
+
|
133
|
+
# Check for "from __future__ import ..." statements. Those
|
134
|
+
# statements need to come at the top of the file (after the
|
135
|
+
# module-level docstring is okay), so we separate them from the
|
136
|
+
# body.
|
137
|
+
#
|
138
|
+
# Note: this will convert invalid Python to valid, because it will
|
139
|
+
# move all "from __future__ import ..." to the top of the file,
|
140
|
+
# even if they were not at the top originally.
|
141
|
+
future_imports, body = find_future_imports(body)
|
142
|
+
|
143
|
+
# Check for load/attach commands.
|
144
|
+
body = do_load_and_attach(body, f, files_before)
|
145
|
+
|
146
|
+
# The Sage library include line along with a autogen message
|
147
|
+
sage_incl = '%s%s\nfrom sage.all_cmdline import * # import sage library\n'%(AUTOGEN_MSG, f)
|
148
|
+
|
149
|
+
# Finally, write out the result. We use atomic_write to avoid
|
150
|
+
# race conditions (for example, the file will never be half written).
|
151
|
+
with atomic_write(fname) as f:
|
152
|
+
f.write(coding)
|
153
|
+
f.write(header)
|
154
|
+
f.write('\n')
|
155
|
+
f.write(future_imports)
|
156
|
+
f.write('\n')
|
157
|
+
f.write(sage_incl)
|
158
|
+
f.write('\n')
|
159
|
+
f.write(body)
|
160
|
+
f.write('\n')
|
161
|
+
|
162
|
+
def find_position_right_after_module_docstring(G):
|
163
|
+
"""
|
164
|
+
Return first position right after the module docstring of G, if it
|
165
|
+
has one. Otherwise return 0.
|
166
|
+
|
167
|
+
INPUT:
|
168
|
+
G -- a string
|
169
|
+
OUTPUT:
|
170
|
+
an integer -- the index into G so that G[i] is right after
|
171
|
+
the module docstring of G, if G has one.
|
172
|
+
"""
|
173
|
+
# The basic idea below is that we look at each line first ignoring
|
174
|
+
# all empty lines and commented out lines. Then we check to see
|
175
|
+
# if the next line is a docstring. If so, we find where that
|
176
|
+
# docstring ends.
|
177
|
+
v = G.splitlines()
|
178
|
+
i = 0
|
179
|
+
while i < len(v):
|
180
|
+
s = v[i].strip()
|
181
|
+
if s and s[0] != '#':
|
182
|
+
break
|
183
|
+
i += 1
|
184
|
+
if i >= len(v):
|
185
|
+
# No module docstring --- entire file is commented out
|
186
|
+
return 0
|
187
|
+
|
188
|
+
# Now v[i] contains the first line of the first statement in the file.
|
189
|
+
# Is it a docstring?
|
190
|
+
n = v[i].lstrip()
|
191
|
+
if not (n[0] in ['"',"'"] or n[0:2] in ['r"',"r'"]):
|
192
|
+
# not a docstring
|
193
|
+
return 0
|
194
|
+
|
195
|
+
# First line is the module docstring. Where does it end?
|
196
|
+
def pos_after_line(k):
|
197
|
+
return sum(len(v[j])+1 for j in range(k+1))
|
198
|
+
|
199
|
+
n = n.lstrip('r') # strip leading r if there is one
|
200
|
+
if n[:3] in ["'''", '"""']:
|
201
|
+
quotes = n[:3]
|
202
|
+
# possibly multiline
|
203
|
+
if quotes in n[3:]:
|
204
|
+
return pos_after_line(i)
|
205
|
+
j = i+1
|
206
|
+
while j < len(v) and quotes not in v[j]:
|
207
|
+
j += 1
|
208
|
+
return pos_after_line(j)
|
209
|
+
else:
|
210
|
+
# it must be a single line; so add up the lengths of all lines
|
211
|
+
# including this one and return that
|
212
|
+
return pos_after_line(i)
|
213
|
+
|
214
|
+
|
215
|
+
def find_future_imports(G):
|
216
|
+
"""
|
217
|
+
Parse a file G as a string, looking for "from __future__ import ...".
|
218
|
+
|
219
|
+
Return a tuple: (the import statements, the file G with those
|
220
|
+
statements removed)
|
221
|
+
|
222
|
+
INPUT:
|
223
|
+
G -- a string; the contents of a file
|
224
|
+
|
225
|
+
This can only handle "from __future__ import ..." statements which
|
226
|
+
are completely on a single line: nothing of the form ::
|
227
|
+
|
228
|
+
from __future__ import \
|
229
|
+
print_function
|
230
|
+
|
231
|
+
or ::
|
232
|
+
|
233
|
+
from __future__ import (print_function,
|
234
|
+
division)
|
235
|
+
|
236
|
+
This function will raise an error if it detects lines of these forms.
|
237
|
+
"""
|
238
|
+
import_statements = []
|
239
|
+
# "from __future__ import ..." should not be indented.
|
240
|
+
m = re.search("^(from __future__ import .*)$", G, re.MULTILINE)
|
241
|
+
while m:
|
242
|
+
statement = m.group(0)
|
243
|
+
# If the import statement ends in a line continuation marker
|
244
|
+
# or if it contains a left parenthesis but not a right one,
|
245
|
+
# then the statement is not complete, so raise an error. (This
|
246
|
+
# is not a perfect check and some bad cases may slip through,
|
247
|
+
# like two left parentheses and only one right parenthesis,
|
248
|
+
# but they should be rare.)
|
249
|
+
if (statement[-1] == '\\' or
|
250
|
+
(statement.find('(') > -1 and statement.find(')') == -1)):
|
251
|
+
raise NotImplementedError('the Sage preparser can only preparse "from __future__ import ..." statements which are on a single line')
|
252
|
+
import_statements.append(statement)
|
253
|
+
G = G[:m.start()] + G[m.end():]
|
254
|
+
m = re.search("^(from __future__ import .*)$", G, re.MULTILINE)
|
255
|
+
return ('\n'.join(import_statements), G)
|
256
|
+
|
257
|
+
|
258
|
+
def do_load_and_attach(G, file, files_before):
|
259
|
+
"""
|
260
|
+
Parse a file G and replace load and attach statements with the
|
261
|
+
corresponding execfile() statements.
|
262
|
+
|
263
|
+
INPUT:
|
264
|
+
G -- a string; a file loaded in from disk
|
265
|
+
file -- the name of the file that contains the non-preparsed
|
266
|
+
version of G.
|
267
|
+
files_before -- list of files seen so far (don't recurse into
|
268
|
+
infinite loop)
|
269
|
+
|
270
|
+
OUTPUT:
|
271
|
+
string -- result of parsing load/attach statements in G, i.e.
|
272
|
+
modified version of G with execfiles.
|
273
|
+
"""
|
274
|
+
s = ''
|
275
|
+
for t in G.split('\n'):
|
276
|
+
z = load_or_attach.match(t)
|
277
|
+
if z:
|
278
|
+
files = z.group('files').split()
|
279
|
+
lws = z.group('lws')
|
280
|
+
for w in files:
|
281
|
+
name = w.replace(',', '').replace('"', '').replace("'", "")
|
282
|
+
if name in files_before:
|
283
|
+
print("WARNING: not loading {} (in {}) again since would cause circular loop"
|
284
|
+
.format(name, file))
|
285
|
+
continue
|
286
|
+
if name.endswith('.sage'):
|
287
|
+
do_preparse(name, files_before + [file])
|
288
|
+
s += lws + "exec(compile(open({0}.py).read(), {0}.py, \
|
289
|
+
'exec'))\n".format(name)
|
290
|
+
elif name.endswith('.py'):
|
291
|
+
s += lws + "exec(compile(open({0}).read(), {0}, \
|
292
|
+
'exec'))\n".format(name)
|
293
|
+
else:
|
294
|
+
s += t + '\n'
|
295
|
+
return s
|
296
|
+
|
297
|
+
|
298
|
+
# Here we do the actual work. We iterate over ever
|
299
|
+
# file in the input args and create the corresponding
|
300
|
+
# output file.
|
301
|
+
for f in files:
|
302
|
+
do_preparse(f)
|