passagemath-repl 10.4.62__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.4.62.data/scripts/sage-cachegrind +25 -0
- passagemath_repl-10.4.62.data/scripts/sage-callgrind +16 -0
- passagemath_repl-10.4.62.data/scripts/sage-cleaner +230 -0
- passagemath_repl-10.4.62.data/scripts/sage-coverage +327 -0
- passagemath_repl-10.4.62.data/scripts/sage-eval +14 -0
- passagemath_repl-10.4.62.data/scripts/sage-fixdoctests +708 -0
- passagemath_repl-10.4.62.data/scripts/sage-inline-fortran +12 -0
- passagemath_repl-10.4.62.data/scripts/sage-ipynb2rst +50 -0
- passagemath_repl-10.4.62.data/scripts/sage-ipython +16 -0
- passagemath_repl-10.4.62.data/scripts/sage-massif +25 -0
- passagemath_repl-10.4.62.data/scripts/sage-notebook +267 -0
- passagemath_repl-10.4.62.data/scripts/sage-omega +25 -0
- passagemath_repl-10.4.62.data/scripts/sage-preparse +302 -0
- passagemath_repl-10.4.62.data/scripts/sage-run +27 -0
- passagemath_repl-10.4.62.data/scripts/sage-run-cython +10 -0
- passagemath_repl-10.4.62.data/scripts/sage-runtests +9 -0
- passagemath_repl-10.4.62.data/scripts/sage-startuptime.py +163 -0
- passagemath_repl-10.4.62.data/scripts/sage-valgrind +34 -0
- passagemath_repl-10.4.62.dist-info/METADATA +77 -0
- passagemath_repl-10.4.62.dist-info/RECORD +162 -0
- passagemath_repl-10.4.62.dist-info/WHEEL +5 -0
- passagemath_repl-10.4.62.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 +131 -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 +246 -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/__init__.py +1 -0
- sage/tests/all.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 +1923 -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 +790 -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,48 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-repl
|
2
|
+
"""
|
3
|
+
Interface to the Sage cleaner
|
4
|
+
|
5
|
+
Triva Note: For the name "sage-cleaner", think of the
|
6
|
+
"The Cleaner" from Pulp Fiction:
|
7
|
+
http://www.frankjankowski.de/quiz/illus/keitel.jpg
|
8
|
+
"""
|
9
|
+
# ****************************************************************************
|
10
|
+
# Copyright (C) 2007 William Stein <wstein@gmail.com>
|
11
|
+
#
|
12
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
13
|
+
# as published by the Free Software Foundation; either version 2 of
|
14
|
+
# the License, or (at your option) any later version.
|
15
|
+
# https://www.gnu.org/licenses/
|
16
|
+
# ****************************************************************************
|
17
|
+
import os
|
18
|
+
import atexit
|
19
|
+
import tempfile
|
20
|
+
|
21
|
+
_spd = tempfile.TemporaryDirectory()
|
22
|
+
SAGE_SPAWNED_PROCESS_FILE = os.path.join(_spd.name, "spawned_processes")
|
23
|
+
atexit.register(lambda: _spd.cleanup())
|
24
|
+
|
25
|
+
|
26
|
+
def start_cleaner():
|
27
|
+
"""
|
28
|
+
Start ``sage-cleaner`` in a new process group.
|
29
|
+
"""
|
30
|
+
if not os.fork():
|
31
|
+
os.setpgid(os.getpid(), os.getpid())
|
32
|
+
|
33
|
+
# Redirect stdin, stdout, stderr to /dev/null
|
34
|
+
with open(os.devnull, "r+") as f:
|
35
|
+
os.dup2(f.fileno(), 0)
|
36
|
+
os.dup2(f.fileno(), 1)
|
37
|
+
os.dup2(f.fileno(), 2)
|
38
|
+
|
39
|
+
# Close all other file descriptors
|
40
|
+
try:
|
41
|
+
maxopenfiles = os.sysconf("SC_OPEN_MAX")
|
42
|
+
if maxopenfiles <= 0:
|
43
|
+
raise ValueError
|
44
|
+
except ValueError:
|
45
|
+
maxopenfiles = 1024
|
46
|
+
os.closerange(3, maxopenfiles)
|
47
|
+
|
48
|
+
os.execlp("sage-cleaner", "sage-cleaner")
|
sage/interfaces/quit.py
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-repl
|
2
|
+
"""
|
3
|
+
Quitting interfaces
|
4
|
+
"""
|
5
|
+
|
6
|
+
################################################################################
|
7
|
+
# Copyright (C) 2010 William Stein <wstein@gmail.com>
|
8
|
+
#
|
9
|
+
# Distributed under the terms of (any version of) the GNU
|
10
|
+
# General Public License (GPL). The full text of the GPL is available at:
|
11
|
+
#
|
12
|
+
# https://www.gnu.org/licenses/
|
13
|
+
################################################################################
|
14
|
+
|
15
|
+
import os
|
16
|
+
|
17
|
+
from sage.misc.cachefunc import cached_function
|
18
|
+
|
19
|
+
|
20
|
+
@cached_function
|
21
|
+
def sage_spawned_process_file():
|
22
|
+
"""
|
23
|
+
EXAMPLES::
|
24
|
+
|
25
|
+
sage: from sage.interfaces.quit import sage_spawned_process_file
|
26
|
+
sage: len(sage_spawned_process_file()) > 1
|
27
|
+
True
|
28
|
+
"""
|
29
|
+
# This is the old value of SAGE_TMP. Until sage-cleaner is
|
30
|
+
# completely removed, we need to leave these spawned_processes
|
31
|
+
# files where sage-cleaner will look for them.
|
32
|
+
from sage.env import DOT_SAGE, HOSTNAME
|
33
|
+
d = os.path.join(DOT_SAGE, "temp", HOSTNAME, str(os.getpid()))
|
34
|
+
os.makedirs(d, exist_ok=True)
|
35
|
+
return os.path.join(d, "spawned_processes")
|
36
|
+
|
37
|
+
|
38
|
+
def register_spawned_process(pid, cmd=''):
|
39
|
+
"""
|
40
|
+
Write a line to the ``spawned_processes`` file with the given
|
41
|
+
``pid`` and ``cmd``.
|
42
|
+
"""
|
43
|
+
if cmd != '':
|
44
|
+
cmd = cmd.strip().split()[0]
|
45
|
+
# This is safe, since only this process writes to this file.
|
46
|
+
try:
|
47
|
+
with open(sage_spawned_process_file(), 'a') as o:
|
48
|
+
o.write('%s %s\n' % (pid, cmd))
|
49
|
+
except OSError:
|
50
|
+
pass
|
51
|
+
else:
|
52
|
+
# If sage is being used as a python library, we need to launch
|
53
|
+
# the cleaner ourselves upon being told that there will be
|
54
|
+
# something to clean.
|
55
|
+
from sage.interfaces.cleaner import start_cleaner
|
56
|
+
start_cleaner()
|
57
|
+
|
58
|
+
|
59
|
+
expect_objects = []
|
60
|
+
|
61
|
+
|
62
|
+
def expect_quitall(verbose=False):
|
63
|
+
"""
|
64
|
+
EXAMPLES::
|
65
|
+
|
66
|
+
sage: sage.interfaces.quit.expect_quitall()
|
67
|
+
sage: gp.eval('a=10') # needs sage.libs.pari
|
68
|
+
'10'
|
69
|
+
sage: gp('a') # needs sage.libs.pari
|
70
|
+
10
|
71
|
+
sage: sage.interfaces.quit.expect_quitall()
|
72
|
+
sage: gp('a') # needs sage.libs.pari
|
73
|
+
a
|
74
|
+
sage: sage.interfaces.quit.expect_quitall(verbose=True) # needs sage.libs.pari
|
75
|
+
Exiting PARI/GP interpreter with PID ... running .../gp --fast --emacs --quiet --stacksize 10000000
|
76
|
+
"""
|
77
|
+
for P in expect_objects:
|
78
|
+
R = P()
|
79
|
+
if R is not None:
|
80
|
+
try:
|
81
|
+
R.quit(verbose=verbose)
|
82
|
+
except RuntimeError:
|
83
|
+
pass
|
84
|
+
kill_spawned_jobs()
|
85
|
+
|
86
|
+
|
87
|
+
def kill_spawned_jobs(verbose=False):
|
88
|
+
"""
|
89
|
+
INPUT:
|
90
|
+
|
91
|
+
- ``verbose`` -- boolean (default: ``False``); if ``True``, display a
|
92
|
+
message each time a process is sent a kill signal
|
93
|
+
|
94
|
+
EXAMPLES::
|
95
|
+
|
96
|
+
sage: gp.eval('a=10') # needs sage.libs.pari
|
97
|
+
'10'
|
98
|
+
sage: sage.interfaces.quit.kill_spawned_jobs(verbose=False)
|
99
|
+
sage: sage.interfaces.quit.expect_quitall()
|
100
|
+
sage: gp.eval('a=10') # needs sage.libs.pari
|
101
|
+
'10'
|
102
|
+
sage: sage.interfaces.quit.kill_spawned_jobs(verbose=True) # needs sage.libs.pari
|
103
|
+
Killing spawned job ...
|
104
|
+
|
105
|
+
After doing the above, we do the following to avoid confusion in other doctests::
|
106
|
+
|
107
|
+
sage: sage.interfaces.quit.expect_quitall()
|
108
|
+
"""
|
109
|
+
fname = sage_spawned_process_file()
|
110
|
+
if not os.path.exists(fname):
|
111
|
+
return
|
112
|
+
|
113
|
+
with open(fname) as f:
|
114
|
+
for L in f:
|
115
|
+
i = L.find(' ')
|
116
|
+
pid = L[:i].strip()
|
117
|
+
try:
|
118
|
+
if verbose:
|
119
|
+
print("Killing spawned job %s" % pid)
|
120
|
+
os.killpg(int(pid), 9)
|
121
|
+
except OSError:
|
122
|
+
pass
|
123
|
+
|
124
|
+
|
125
|
+
def is_running(pid):
|
126
|
+
"""
|
127
|
+
Return ``True`` if and only if there is a process with id pid running.
|
128
|
+
"""
|
129
|
+
try:
|
130
|
+
os.kill(int(pid), 0)
|
131
|
+
return True
|
132
|
+
except (OSError, ValueError):
|
133
|
+
return False
|
134
|
+
|
135
|
+
|
136
|
+
def invalidate_all():
|
137
|
+
"""
|
138
|
+
Invalidate all of the expect interfaces.
|
139
|
+
|
140
|
+
This is used, e.g., by the fork-based @parallel decorator.
|
141
|
+
|
142
|
+
EXAMPLES::
|
143
|
+
|
144
|
+
sage: # needs sage.libs.pari sage.symbolic
|
145
|
+
sage: a = maxima(2); b = gp(3)
|
146
|
+
sage: a, b
|
147
|
+
(2, 3)
|
148
|
+
sage: sage.interfaces.quit.invalidate_all()
|
149
|
+
sage: a
|
150
|
+
(invalid Maxima object -- The maxima session in which this object was defined is no longer running.)
|
151
|
+
sage: b
|
152
|
+
(invalid PARI/GP interpreter object -- The pari session in which this object was defined is no longer running.)
|
153
|
+
|
154
|
+
However the maxima and gp sessions should still work out, though with their state reset::
|
155
|
+
|
156
|
+
sage: a = maxima(2); b = gp(3) # needs sage.libs.pari sage.symbolic
|
157
|
+
sage: a, b # needs sage.libs.pari sage.symbolic
|
158
|
+
(2, 3)
|
159
|
+
"""
|
160
|
+
for I in expect_objects:
|
161
|
+
I1 = I()
|
162
|
+
if I1:
|
163
|
+
I1.detach()
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-repl
|
2
|
+
|
3
|
+
from sage.misc.all__sagemath_objects import *
|
4
|
+
|
5
|
+
from sage.misc.sage_eval import sage_eval, sageobj
|
6
|
+
|
7
|
+
from sage.misc.sage_input import sage_input
|
8
|
+
|
9
|
+
from sage.misc.banner import version
|
10
|
+
|
11
|
+
lazy_import('sage.misc.banner', 'banner', deprecation=34259)
|
12
|
+
|
13
|
+
lazy_import('sage.misc.sagedoc', ['browse_sage_doc',
|
14
|
+
'search_src', 'search_def', 'search_doc',
|
15
|
+
'tutorial', 'reference', 'manual', 'developer',
|
16
|
+
'constructions', 'help'])
|
17
|
+
|
18
|
+
lazy_import('pydoc', 'help', 'python_help')
|
19
|
+
|
20
|
+
from sage.misc.explain_pickle import (explain_pickle, unpickle_newobj, unpickle_build,
|
21
|
+
unpickle_instantiate, unpickle_persistent,
|
22
|
+
unpickle_extension, unpickle_appends)
|
23
|
+
|
24
|
+
lazy_import('sage.misc.trace', 'trace', deprecation=34259)
|
25
|
+
|
26
|
+
lazy_import('sage.misc.profiler', 'Profiler', deprecation=34259)
|
27
|
+
|
28
|
+
lazy_import('sage.misc.classgraph', 'class_graph')
|
29
|
+
|
30
|
+
from sage.misc.dev_tools import import_statements
|
31
|
+
|
32
|
+
lazy_import('sage.misc.dev_tools', 'runsnake', deprecation=34259)
|
33
|
+
|
34
|
+
from sage.misc.edit_module import edit
|
35
|
+
|
36
|
+
lazy_import('sage.misc.edit_module', 'set_edit_template', deprecation=34259)
|
37
|
+
|
38
|
+
lazy_import('sage.misc.pager', 'pager')
|
39
|
+
|
40
|
+
lazy_import('sage.misc.remote_file', 'get_remote_file')
|
41
|
+
|
42
|
+
lazy_import('sage.misc.sh', 'sh')
|
43
|
+
|
44
|
+
lazy_import("sage.misc.cython", "cython_lambda")
|
45
|
+
lazy_import("sage.misc.cython", "cython_compile", "cython")
|
46
|
+
lazy_import('sage.misc.inline_fortran', 'fortran')
|
47
|
+
|
48
|
+
lazy_import('sage.misc.package', ('installed_packages', 'is_package_installed',
|
49
|
+
'package_versions'),
|
50
|
+
deprecation=34259)
|
51
|
+
lazy_import('sage.misc.benchmark', 'benchmark', deprecation=34259)
|
sage/misc/banner.py
ADDED
@@ -0,0 +1,235 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-repl
|
2
|
+
r"""
|
3
|
+
SageMath version and banner info
|
4
|
+
"""
|
5
|
+
|
6
|
+
# ****************************************************************************
|
7
|
+
# Copyright (C) 2005 William Stein <wstein@gmail.com>
|
8
|
+
#
|
9
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
10
|
+
# as published by the Free Software Foundation; either version 2 of
|
11
|
+
# the License, or (at your option) any later version.
|
12
|
+
# https://www.gnu.org/licenses/
|
13
|
+
# ****************************************************************************
|
14
|
+
import sys
|
15
|
+
|
16
|
+
from sage.env import (SAGE_VERSION, SAGE_VERSION_BANNER, SAGE_BANNER)
|
17
|
+
|
18
|
+
|
19
|
+
def version():
|
20
|
+
"""
|
21
|
+
Return the version of Sage.
|
22
|
+
|
23
|
+
OUTPUT: string
|
24
|
+
|
25
|
+
EXAMPLES::
|
26
|
+
|
27
|
+
sage: version()
|
28
|
+
'... version ..., Release Date: ...'
|
29
|
+
"""
|
30
|
+
return SAGE_VERSION_BANNER
|
31
|
+
|
32
|
+
|
33
|
+
def banner_text(full=True):
|
34
|
+
"""
|
35
|
+
Text for the Sage banner.
|
36
|
+
|
37
|
+
INPUT:
|
38
|
+
|
39
|
+
- ``full`` -- boolean (default: ``True``)
|
40
|
+
|
41
|
+
OUTPUT:
|
42
|
+
|
43
|
+
A string containing the banner message.
|
44
|
+
|
45
|
+
If option full is ``False``, a simplified plain ASCII banner is
|
46
|
+
displayed; if ``True`` the full banner with box art is displayed.
|
47
|
+
|
48
|
+
EXAMPLES::
|
49
|
+
|
50
|
+
sage: print(sage.misc.banner.banner_text(full=True))
|
51
|
+
┌────────────────────────────────────────────────────────────────────┐
|
52
|
+
│ ... version ...
|
53
|
+
sage: print(sage.misc.banner.banner_text(full=False))
|
54
|
+
... version ..., Release Date: ...
|
55
|
+
"""
|
56
|
+
if not full:
|
57
|
+
return version()
|
58
|
+
|
59
|
+
bars = "─" * 68
|
60
|
+
s = []
|
61
|
+
a = s.append
|
62
|
+
a('┌' + bars + '┐')
|
63
|
+
a("\n│ %-66s │\n" % version())
|
64
|
+
python_version = sys.version_info[:3]
|
65
|
+
a("│ %-66s │\n" % 'Using Python {}.{}.{}. Type "help()" for help.'.format(*python_version))
|
66
|
+
a('└' + bars + '┘')
|
67
|
+
pre = version_dict()['prerelease']
|
68
|
+
try:
|
69
|
+
import sage.all
|
70
|
+
have_sage_all = True
|
71
|
+
except ImportError:
|
72
|
+
have_sage_all = False
|
73
|
+
if pre or not have_sage_all:
|
74
|
+
red_in = '\033[31m'
|
75
|
+
red_out = '\033[0m'
|
76
|
+
bars2 = bars.replace('─', '━')
|
77
|
+
a('\n')
|
78
|
+
a(red_in + '┏' + bars2 + '┓' + '\n')
|
79
|
+
if pre:
|
80
|
+
a("┃ %-66s ┃\n" % 'Warning: this is a prerelease version, and it may be unstable.')
|
81
|
+
if not have_sage_all:
|
82
|
+
a("┃ %-66s ┃\n" % 'Warning: sage.all is not available; this is a limited REPL.')
|
83
|
+
a('┗' + bars2 + '┛' + red_out)
|
84
|
+
return ''.join(s)
|
85
|
+
|
86
|
+
|
87
|
+
def banner():
|
88
|
+
"""
|
89
|
+
Print the Sage banner.
|
90
|
+
|
91
|
+
OUTPUT: none
|
92
|
+
|
93
|
+
If the environment variable ``SAGE_BANNER`` is set to ``no``, no
|
94
|
+
banner is displayed. If ``SAGE_BANNER`` is set to ``bare``, a
|
95
|
+
simplified plain ASCII banner is displayed. Otherwise, the full
|
96
|
+
banner with box art is displayed.
|
97
|
+
|
98
|
+
EXAMPLES::
|
99
|
+
|
100
|
+
sage: import sage.misc.banner; sage.misc.banner.SAGE_BANNER = ''
|
101
|
+
sage: sage.misc.banner.banner()
|
102
|
+
┌────────────────────────────────────────────────────────────────────┐
|
103
|
+
│ ... version ..., Release Date: ... │
|
104
|
+
│ Using Python .... Type "help()" for help. │
|
105
|
+
...
|
106
|
+
"""
|
107
|
+
typ = SAGE_BANNER.lower()
|
108
|
+
|
109
|
+
if typ == "no":
|
110
|
+
return
|
111
|
+
|
112
|
+
if typ != "bare":
|
113
|
+
try:
|
114
|
+
print(banner_text(full=True))
|
115
|
+
return
|
116
|
+
except UnicodeEncodeError:
|
117
|
+
pass
|
118
|
+
|
119
|
+
print(banner_text(full=False))
|
120
|
+
|
121
|
+
|
122
|
+
def version_dict():
|
123
|
+
"""
|
124
|
+
A dictionary describing the version of Sage.
|
125
|
+
|
126
|
+
OUTPUT: dictionary with keys 'major', 'minor', 'tiny', 'prerelease'
|
127
|
+
|
128
|
+
This process the Sage version string and produces a dictionary.
|
129
|
+
It expects the Sage version to be in one of these forms::
|
130
|
+
|
131
|
+
N.N
|
132
|
+
N.N.N
|
133
|
+
N.N.N.N
|
134
|
+
N.N.str
|
135
|
+
N.N.N.str
|
136
|
+
N.N.N.N.str
|
137
|
+
|
138
|
+
where 'N' stands for an integer and 'str' stands for a string.
|
139
|
+
The first integer is stored under the 'major' key and the second
|
140
|
+
integer under 'minor'. If there is one more integer, it is stored
|
141
|
+
under 'tiny'; if there are two more integers, then they are stored
|
142
|
+
together as a float N.N under 'tiny'. If there is a string, then
|
143
|
+
the key 'prerelease' returns True.
|
144
|
+
|
145
|
+
For example, if the Sage version is '3.2.1', then the dictionary
|
146
|
+
is {'major': 3, 'minor': 2, 'tiny': 1, 'prerelease': False}.
|
147
|
+
If the Sage version is '3.2.1.2', then the dictionary is
|
148
|
+
{'major': 3, 'minor': 2, 'tiny': 1.200..., 'prerelease': False}.
|
149
|
+
If the Sage version is '3.2.alpha0', then the dictionary is
|
150
|
+
{'major': 3, 'minor': 2, 'tiny': 0, 'prerelease': True}.
|
151
|
+
|
152
|
+
EXAMPLES::
|
153
|
+
|
154
|
+
sage: from sage.misc.banner import version_dict
|
155
|
+
sage: print("SageMath major version is %s" % version_dict()['major'])
|
156
|
+
SageMath major version is ...
|
157
|
+
sage: version_dict()['major'] == int(sage.version.version.split('.')[0])
|
158
|
+
True
|
159
|
+
"""
|
160
|
+
v = SAGE_VERSION.split('.')
|
161
|
+
dict = {}
|
162
|
+
dict['major'] = int(v[0])
|
163
|
+
dict['minor'] = int(v[1])
|
164
|
+
dict['tiny'] = 0
|
165
|
+
dict['prerelease'] = False
|
166
|
+
try:
|
167
|
+
int(v[-1])
|
168
|
+
except ValueError: # when last entry is not an integer
|
169
|
+
dict['prerelease'] = True
|
170
|
+
if (len(v) == 3 and not dict['prerelease']) or len(v) > 3:
|
171
|
+
dict['tiny'] = int(v[2])
|
172
|
+
try:
|
173
|
+
teeny = int(v[3])
|
174
|
+
dict['tiny'] += 0.1 * teeny
|
175
|
+
except (ValueError, IndexError):
|
176
|
+
pass
|
177
|
+
return dict
|
178
|
+
|
179
|
+
|
180
|
+
def require_version(major, minor=0, tiny=0, prerelease=False,
|
181
|
+
print_message=False):
|
182
|
+
"""
|
183
|
+
Return ``True`` if Sage version is at least ``major.minor.tiny``.
|
184
|
+
|
185
|
+
INPUT:
|
186
|
+
|
187
|
+
- ``major`` -- integer
|
188
|
+
- ``minor`` -- integer (default: 0)
|
189
|
+
- ``tiny`` -- float (default: 0)
|
190
|
+
- ``prerelease`` -- boolean (default: ``False``)
|
191
|
+
- ``print_message`` -- boolean (default: ``False``)
|
192
|
+
|
193
|
+
OUTPUT: ``True`` if ``major.minor.tiny`` is <= version of Sage, ``False``
|
194
|
+
otherwise
|
195
|
+
|
196
|
+
For example, if the Sage version number is 3.1.2, then
|
197
|
+
require_version(3, 1, 3) will return False, while
|
198
|
+
require_version(3, 1, 2) will return True.
|
199
|
+
If the Sage version is 3.1.2.alpha0, then
|
200
|
+
require_version(3, 1, 1) will return True, while, by default,
|
201
|
+
require_version(3, 1, 2) will return False. Note, though, that
|
202
|
+
require_version(3, 1, 2, prerelease=True) will return True:
|
203
|
+
if the optional argument prerelease is True, then a prerelease
|
204
|
+
version of Sage counts as if it were the released version.
|
205
|
+
|
206
|
+
If optional argument print_message is ``True`` and this function
|
207
|
+
is returning False, print a warning message.
|
208
|
+
|
209
|
+
EXAMPLES::
|
210
|
+
|
211
|
+
sage: from sage.misc.banner import require_version
|
212
|
+
sage: require_version(2, 1, 3)
|
213
|
+
True
|
214
|
+
sage: require_version(821, 4)
|
215
|
+
False
|
216
|
+
sage: require_version(821, 4, print_message=True)
|
217
|
+
This code requires at least version 821.4 of SageMath to run correctly.
|
218
|
+
You are running version ...
|
219
|
+
False
|
220
|
+
"""
|
221
|
+
vers = version_dict()
|
222
|
+
prerelease_checked = (prerelease if vers['prerelease'] else True)
|
223
|
+
if (vers['major'] > major
|
224
|
+
or (vers['major'] == major and vers['minor'] > minor)
|
225
|
+
or (vers['major'] == major and vers['minor'] == minor
|
226
|
+
and vers['tiny'] > tiny)
|
227
|
+
or (vers['major'] == major and vers['minor'] == minor
|
228
|
+
and vers['tiny'] == tiny and prerelease_checked)):
|
229
|
+
return True
|
230
|
+
else:
|
231
|
+
if print_message:
|
232
|
+
txt = "This code requires at least version {} of SageMath to run correctly."
|
233
|
+
print(txt.format(major + 0.1 * minor + 0.01 * tiny))
|
234
|
+
print("You are running version {}.".format(SAGE_VERSION))
|
235
|
+
return False
|