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
sage/tests/cmdline.py
ADDED
@@ -0,0 +1,790 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-repl
|
2
|
+
r"""
|
3
|
+
This file contains some tests that Sage command line options actually
|
4
|
+
do something.
|
5
|
+
|
6
|
+
We test the following command line options:
|
7
|
+
|
8
|
+
test.py
|
9
|
+
/path/to/test.py
|
10
|
+
test.sage
|
11
|
+
/path/to/test.sage
|
12
|
+
test.spyx
|
13
|
+
/path/to/test.spyx
|
14
|
+
--advanced
|
15
|
+
-c
|
16
|
+
--cython
|
17
|
+
--dev
|
18
|
+
--ecl
|
19
|
+
--experimental
|
20
|
+
--fixdoctests
|
21
|
+
--gap
|
22
|
+
--gdb
|
23
|
+
--gp
|
24
|
+
-h
|
25
|
+
--help
|
26
|
+
--info
|
27
|
+
--ipython
|
28
|
+
--lisp
|
29
|
+
--maxima
|
30
|
+
--min
|
31
|
+
--mwrank
|
32
|
+
--optional
|
33
|
+
--preparse
|
34
|
+
--python
|
35
|
+
--python3
|
36
|
+
-q
|
37
|
+
--R
|
38
|
+
--root
|
39
|
+
--rst2ipynb
|
40
|
+
--ipynb2rst
|
41
|
+
--sh
|
42
|
+
--singular
|
43
|
+
--sqlite3
|
44
|
+
--standard
|
45
|
+
--startuptime
|
46
|
+
-t
|
47
|
+
-v
|
48
|
+
--zzfoobar (illegal option)
|
49
|
+
|
50
|
+
|
51
|
+
AUTHORS:
|
52
|
+
|
53
|
+
- Jeroen Demeyer (2010-11-20): initial version (:issue:`10300`)
|
54
|
+
"""
|
55
|
+
from subprocess import Popen, PIPE
|
56
|
+
import os
|
57
|
+
import sys
|
58
|
+
import select
|
59
|
+
|
60
|
+
|
61
|
+
def test_executable(args, input='', timeout=100.0, pydebug_ignore_warnings=False, **kwds):
|
62
|
+
r"""
|
63
|
+
Run the program defined by ``args`` using the string ``input`` on
|
64
|
+
the standard input.
|
65
|
+
|
66
|
+
INPUT:
|
67
|
+
|
68
|
+
- ``args`` -- list of program arguments, the first being the
|
69
|
+
executable
|
70
|
+
|
71
|
+
- ``input`` -- string serving as standard input; usually, this
|
72
|
+
should end with a newline
|
73
|
+
|
74
|
+
- ``timeout`` -- if the program produces no output for ``timeout``
|
75
|
+
seconds, a :exc:`RuntimeError` is raised
|
76
|
+
|
77
|
+
- ``pydebug_ignore_warnings`` -- boolean. Set the PYTHONWARNINGS environment variable to ignore
|
78
|
+
Python warnings when on a Python debug build (`--with-pydebug`, e.g. from building with
|
79
|
+
`SAGE_DEBUG=yes`). Debug builds do not install the default warning filters, which can break
|
80
|
+
some doctests. Unfortunately the environment variable does not support regex message filters,
|
81
|
+
so the filter will catch a bit more than the default filters. Hence we only enable it on debug
|
82
|
+
builds.
|
83
|
+
|
84
|
+
- ``**kwds`` -- additional keyword arguments passed to the
|
85
|
+
:class:`Popen` constructor
|
86
|
+
|
87
|
+
OUTPUT: a tuple ``(out, err, ret)`` with the standard output,
|
88
|
+
standard error and exitcode of the program run.
|
89
|
+
|
90
|
+
EXAMPLES::
|
91
|
+
|
92
|
+
sage: from sage.tests.cmdline import test_executable
|
93
|
+
sage: (out, err, ret) = test_executable(["cat"], "Hello World!")
|
94
|
+
sage: out
|
95
|
+
'Hello World!'
|
96
|
+
sage: err
|
97
|
+
''
|
98
|
+
sage: ret
|
99
|
+
0
|
100
|
+
|
101
|
+
We test the timeout option::
|
102
|
+
|
103
|
+
sage: (out, err, ret) = test_executable(["sleep", "1"], timeout=0.1)
|
104
|
+
Traceback (most recent call last):
|
105
|
+
...
|
106
|
+
RuntimeError: timeout in test_executable()
|
107
|
+
|
108
|
+
TESTS:
|
109
|
+
|
110
|
+
Run Sage itself with various options::
|
111
|
+
|
112
|
+
sage: # long time
|
113
|
+
sage: (out, err, ret) = test_executable([
|
114
|
+
....: "sage"], pydebug_ignore_warnings=True)
|
115
|
+
sage: out.find(version()) >= 0
|
116
|
+
True
|
117
|
+
sage: err
|
118
|
+
''
|
119
|
+
sage: ret
|
120
|
+
0
|
121
|
+
|
122
|
+
sage: # long time
|
123
|
+
sage: (out, err, ret) = test_executable([
|
124
|
+
....: "sage"], "3^33\n", pydebug_ignore_warnings=True)
|
125
|
+
sage: out.find(version()) >= 0
|
126
|
+
True
|
127
|
+
sage: out.find("5559060566555523") >= 0
|
128
|
+
True
|
129
|
+
sage: err
|
130
|
+
''
|
131
|
+
sage: ret
|
132
|
+
0
|
133
|
+
|
134
|
+
sage: # long time
|
135
|
+
sage: (out, err, ret) = test_executable([
|
136
|
+
....: "sage", "-q"], "3^33\n", pydebug_ignore_warnings=True)
|
137
|
+
sage: out.find(version()) >= 0
|
138
|
+
False
|
139
|
+
sage: out.find("5559060566555523") >= 0
|
140
|
+
True
|
141
|
+
sage: err
|
142
|
+
''
|
143
|
+
sage: ret
|
144
|
+
0
|
145
|
+
|
146
|
+
sage: # long time
|
147
|
+
sage: (out, err, ret) = test_executable([
|
148
|
+
....: "sage", "-c", "print(3^33)"])
|
149
|
+
sage: print(out)
|
150
|
+
5559060566555523
|
151
|
+
sage: err
|
152
|
+
''
|
153
|
+
sage: ret
|
154
|
+
0
|
155
|
+
|
156
|
+
sage: # long time
|
157
|
+
sage: (out, err, ret) = test_executable([
|
158
|
+
....: "sage", "--min", "-c", "print(3^33)"])
|
159
|
+
sage: print(out)
|
160
|
+
5559060566555523
|
161
|
+
sage: err
|
162
|
+
''
|
163
|
+
sage: ret
|
164
|
+
0
|
165
|
+
|
166
|
+
sage: # long time
|
167
|
+
sage: (out, err, ret) = test_executable([
|
168
|
+
....: "sage", "--startuptime"])
|
169
|
+
sage: out.find("Slowest module import") >= 0
|
170
|
+
True
|
171
|
+
sage: err
|
172
|
+
''
|
173
|
+
sage: ret
|
174
|
+
0
|
175
|
+
|
176
|
+
Test help::
|
177
|
+
|
178
|
+
sage: (out, err, ret) = test_executable(["sage", "-h"])
|
179
|
+
sage: out.find("evaluate cmd as sage") >= 0
|
180
|
+
True
|
181
|
+
sage: err
|
182
|
+
''
|
183
|
+
sage: ret
|
184
|
+
0
|
185
|
+
|
186
|
+
sage: (out, err, ret) = test_executable(["sage", "--help"])
|
187
|
+
sage: out.find("evaluate cmd as sage") >= 0
|
188
|
+
True
|
189
|
+
sage: err
|
190
|
+
''
|
191
|
+
sage: ret
|
192
|
+
0
|
193
|
+
|
194
|
+
sage: (out, err, ret) = test_executable(["sage", "--advanced"])
|
195
|
+
sage: out.find("run the Sage cleaner.") >= 0
|
196
|
+
True
|
197
|
+
sage: err
|
198
|
+
''
|
199
|
+
sage: ret
|
200
|
+
0
|
201
|
+
sage: out.find("print the Sage root directory") >= 0 # optional - sage_spkg
|
202
|
+
True
|
203
|
+
sage: out.find("regular expression search through the Sage") >= 0 # optional - sage_spkg
|
204
|
+
True
|
205
|
+
|
206
|
+
Basic information about the Sage installation::
|
207
|
+
|
208
|
+
sage: (out, err, ret) = test_executable(["sage", "-v"])
|
209
|
+
sage: out.find(version()) >= 0
|
210
|
+
True
|
211
|
+
sage: err
|
212
|
+
''
|
213
|
+
sage: ret
|
214
|
+
0
|
215
|
+
|
216
|
+
sage: # optional - sage_spkg
|
217
|
+
sage: (out, err, ret) = test_executable(["sage", "--root"])
|
218
|
+
sage: len(out) >= 2
|
219
|
+
True
|
220
|
+
sage: err
|
221
|
+
''
|
222
|
+
sage: ret
|
223
|
+
0
|
224
|
+
|
225
|
+
Test ``sage --info [packages]``::
|
226
|
+
|
227
|
+
sage: # optional - sage_spkg
|
228
|
+
sage: out, err, ret = test_executable(["sage", "--info", "sqlite"])
|
229
|
+
sage: print(out)
|
230
|
+
sqlite...
|
231
|
+
SQLite is a software library that implements a self-contained,
|
232
|
+
serverless, zero-configuration, transactional SQL database engine.
|
233
|
+
...
|
234
|
+
sage: err
|
235
|
+
''
|
236
|
+
sage: ret
|
237
|
+
0
|
238
|
+
|
239
|
+
Test ``sage-run`` on a Python file, both with an absolute and with a relative path::
|
240
|
+
|
241
|
+
sage: import tempfile
|
242
|
+
sage: with tempfile.TemporaryDirectory() as dir:
|
243
|
+
....: name = 'python_test_file.py'
|
244
|
+
....: fullname = os.path.join(dir, name)
|
245
|
+
....: with open(fullname, 'w') as F:
|
246
|
+
....: _ = F.write("print(3^33)\n")
|
247
|
+
....: test_executable(["sage", fullname])
|
248
|
+
....: test_executable(["sage", name], cwd=dir)
|
249
|
+
('34\n', '', 0)
|
250
|
+
('34\n', '', 0)
|
251
|
+
|
252
|
+
The same as above, but now with a ``.sage`` file. This indirectly
|
253
|
+
also tests the preparser::
|
254
|
+
|
255
|
+
sage: import tempfile
|
256
|
+
sage: with tempfile.TemporaryDirectory() as dir: # long time
|
257
|
+
....: name = 'sage_test_file.sage'
|
258
|
+
....: fullname = os.path.join(dir, name)
|
259
|
+
....: with open(fullname, 'w') as F:
|
260
|
+
....: _ = F.write("k.<a> = GF(5^3); print(a^124)\n")
|
261
|
+
....: test_executable(["sage", fullname])
|
262
|
+
....: test_executable(["sage", name], cwd=dir)
|
263
|
+
('1\n', '', 0)
|
264
|
+
('1\n', '', 0)
|
265
|
+
|
266
|
+
Test running a ``.spyx`` file::
|
267
|
+
|
268
|
+
sage: import tempfile
|
269
|
+
sage: with tempfile.TemporaryDirectory() as dir: # long time
|
270
|
+
....: name = 'sage_test_file.spyx'
|
271
|
+
....: fullname = os.path.join(dir, name)
|
272
|
+
....: with open(fullname, 'w') as F:
|
273
|
+
....: _ = F.write("from cysignals.signals cimport *\n")
|
274
|
+
....: _ = F.write("from sage.rings.integer cimport Integer\n")
|
275
|
+
....: _ = F.write("cdef long i, s = 0\n")
|
276
|
+
....: _ = F.write("sig_on()\n")
|
277
|
+
....: _ = F.write("for i in range(5): s += i\n")
|
278
|
+
....: _ = F.write("sig_off()\n")
|
279
|
+
....: _ = F.write("print(Integer(s))")
|
280
|
+
....: test_executable(["sage", fullname], pydebug_ignore_warnings=True)
|
281
|
+
....: test_executable(["sage", name], cwd=dir, pydebug_ignore_warnings=True)
|
282
|
+
('10\n', 'Compiling .../sage_test_file.spyx...\n', 0)
|
283
|
+
('10\n', 'Compiling sage_test_file.spyx...\n', 0)
|
284
|
+
|
285
|
+
Testing ``sage --preparse FILE`` and ``sage -t FILE``. First create
|
286
|
+
a file and preparse it::
|
287
|
+
|
288
|
+
sage: s = "# -*- coding: utf-8 -*-\n'''This is a test file.\nAnd I am its doctest'''\ndef my_add(a):\n '''\n Add 2 to a.\n\n EXAMPLES::\n\n sage: my_add(2)\n 4\n '''\n return a + 2\n"
|
289
|
+
sage: script = os.path.join(tmp_dir(), 'my_script.sage')
|
290
|
+
sage: script_py = script + '.py'
|
291
|
+
sage: F = open(script, 'w')
|
292
|
+
sage: _ = F.write(s)
|
293
|
+
sage: F.close()
|
294
|
+
sage: (out, err, ret) = test_executable(["sage", "--preparse", script])
|
295
|
+
sage: ret
|
296
|
+
0
|
297
|
+
sage: os.path.isfile(script_py)
|
298
|
+
True
|
299
|
+
|
300
|
+
Now test my_script.sage and the preparsed version my_script.sage.py::
|
301
|
+
|
302
|
+
sage: # long time
|
303
|
+
sage: (out, err, ret) = test_executable([
|
304
|
+
....: "sage", "-t", "--optional=sage", script])
|
305
|
+
sage: ret
|
306
|
+
0
|
307
|
+
sage: out.find("All tests passed!") >= 0
|
308
|
+
True
|
309
|
+
sage: (out, err, ret) = test_executable([
|
310
|
+
....: "sage", "-t", "--optional=sage", script_py])
|
311
|
+
sage: ret
|
312
|
+
0
|
313
|
+
sage: out.find("All tests passed!") >= 0
|
314
|
+
True
|
315
|
+
|
316
|
+
Test that the coding line and doctest are preserved::
|
317
|
+
|
318
|
+
sage: Fpy = open(script_py, "r")
|
319
|
+
sage: Fpy.readline()
|
320
|
+
'# -*- coding: utf-8 -*-\n'
|
321
|
+
sage: Fpy.readline()
|
322
|
+
"'''This is a test file.\n"
|
323
|
+
sage: Fpy.readline()
|
324
|
+
"And I am its doctest'''\n"
|
325
|
+
|
326
|
+
Now for a file which should fail tests::
|
327
|
+
|
328
|
+
sage: s = s.replace('4', '5') # (2+2 != 5)
|
329
|
+
sage: F = open(script, 'w')
|
330
|
+
sage: _ = F.write(s)
|
331
|
+
sage: F.close()
|
332
|
+
sage: (out, err, ret) = test_executable([ # long time
|
333
|
+
....: "sage", "-t", "--optional=sage", script])
|
334
|
+
sage: ret # long time
|
335
|
+
1
|
336
|
+
sage: out.find("1 item had failures:") >= 0 # long time
|
337
|
+
True
|
338
|
+
|
339
|
+
Test ``sage -t --debug -p 2`` on a ReST file, the ``-p 2`` should
|
340
|
+
be ignored. In Pdb, we run the ``help`` command::
|
341
|
+
|
342
|
+
sage: s = "::\n\n sage: assert True is False\n sage: 2 + 2\n 5"
|
343
|
+
sage: script = tmp_filename(ext='.rst')
|
344
|
+
sage: F = open(script, 'w')
|
345
|
+
sage: _ = F.write(s)
|
346
|
+
sage: F.close()
|
347
|
+
sage: (out, err, ret) = test_executable([ # long time
|
348
|
+
....: "sage", "-t", "--optional=sage", "--debug",
|
349
|
+
....: "-p", "2", "--warn-long", "0", script], "help")
|
350
|
+
sage: print(out) # long time
|
351
|
+
Debugging requires single-threaded operation, setting number of threads to 1.
|
352
|
+
Running doctests with ID...
|
353
|
+
Doctesting 1 file.
|
354
|
+
sage -t ...
|
355
|
+
**********************************************************************
|
356
|
+
File "...", line 3, in ...
|
357
|
+
Failed example:
|
358
|
+
assert True is False
|
359
|
+
Exception raised:
|
360
|
+
Traceback (most recent call last):
|
361
|
+
...
|
362
|
+
AssertionError
|
363
|
+
> <doctest ...>(1)<module>()
|
364
|
+
-> assert True is False
|
365
|
+
(Pdb)
|
366
|
+
Documented commands (type help <topic>):
|
367
|
+
========================================
|
368
|
+
...
|
369
|
+
**********************************************************************
|
370
|
+
File "...", line 4, in ...
|
371
|
+
Failed example:
|
372
|
+
2 + 2
|
373
|
+
Expected:
|
374
|
+
5
|
375
|
+
Got:
|
376
|
+
4
|
377
|
+
**********************************************************************
|
378
|
+
Previously executed commands:
|
379
|
+
s...: assert True is False
|
380
|
+
sage:
|
381
|
+
<BLANKLINE>
|
382
|
+
Returning to doctests...
|
383
|
+
**********************************************************************
|
384
|
+
1 item had failures:
|
385
|
+
2 of 3 in ...
|
386
|
+
[2 tests, 2 failures, ...]
|
387
|
+
...
|
388
|
+
sage: ret # long time
|
389
|
+
1
|
390
|
+
|
391
|
+
Now run a test for the fixdoctests script and, in particular, check that the
|
392
|
+
issues raised in :issue:`10589` are fixed. We have to go to slightly silly
|
393
|
+
lengths to doctest the output.::
|
394
|
+
|
395
|
+
sage: test='r\"\"\"Add a doc-test for the fixdoctest command line option and, in particular, check that\n:issue:`10589` is fixed.\n\nEXAMPLES::\n\n sage: 1+1 # incorrect output\n 3\n sage: m=matrix(ZZ,3) # output when none is expected\n [0 0 0]\n [0 0 0]\n [1 0 0]\n sage: (2/3)*m # no output when it is expected\n sage: mu=PartitionTuple([[4,4],[3,3,2,1],[1,1]]) # output when none is expected\n [4, 4, 3, 3, 2, 1, 1]\n sage: mu.pp() # uneven indentation\n ****\n ****\n sage: PartitionTuples.options(convention="French")\n sage: mu.pp() # fix doctest with uneven indentation\n sage: PartitionTuples.options._reset()\n\"\"\"\n'
|
396
|
+
sage: test_file = os.path.join(tmp_dir(), 'test_file.py')
|
397
|
+
sage: F = open(test_file, 'w')
|
398
|
+
sage: _ = F.write(test)
|
399
|
+
sage: F.close()
|
400
|
+
sage: (out, err, ret) = test_executable(["sage", "--fixdoctests", test_file]) # long time
|
401
|
+
sage: with open(test_file, 'r') as f: # long time
|
402
|
+
....: fixed_test = f.read()
|
403
|
+
sage: import difflib # long time
|
404
|
+
sage: list(difflib.unified_diff(test.splitlines(), fixed_test.splitlines()))[2:-1] # long time
|
405
|
+
['@@ -4,18 +4,23 @@\n',
|
406
|
+
' EXAMPLES::',
|
407
|
+
' ',
|
408
|
+
' sage: 1+1 # incorrect output',
|
409
|
+
'- 3',
|
410
|
+
'+ 2',
|
411
|
+
' sage: m=matrix(ZZ,3) # output when none is expected',
|
412
|
+
'+ sage: (2/3)*m # no output when it is expected',
|
413
|
+
' [0 0 0]',
|
414
|
+
' [0 0 0]',
|
415
|
+
'- [1 0 0]',
|
416
|
+
'- sage: (2/3)*m # no output when it is expected',
|
417
|
+
'+ [0 0 0]',
|
418
|
+
' sage: mu=PartitionTuple([[4,4],[3,3,2,1],[1,1]]) # output when none is expected',
|
419
|
+
'- [4, 4, 3, 3, 2, 1, 1]',
|
420
|
+
' sage: mu.pp() # uneven indentation',
|
421
|
+
'- ****',
|
422
|
+
'- ****',
|
423
|
+
'+ **** *** *',
|
424
|
+
'+ **** *** *',
|
425
|
+
'+ **',
|
426
|
+
'+ *',
|
427
|
+
' sage: PartitionTuples.options(convention="French")',
|
428
|
+
' sage: mu.pp() # fix doctest with uneven indentation',
|
429
|
+
'+ *',
|
430
|
+
'+ **',
|
431
|
+
'+ **** *** *',
|
432
|
+
'+ **** *** *',
|
433
|
+
' sage: PartitionTuples.options._reset()']
|
434
|
+
|
435
|
+
Test external programs being called by Sage::
|
436
|
+
|
437
|
+
sage: (out, err, ret) = test_executable(["sage", "--sh"], "echo Hello World\nexit 42\n")
|
438
|
+
sage: out.find("Hello World\n") >= 0
|
439
|
+
True
|
440
|
+
sage: ret
|
441
|
+
42
|
442
|
+
|
443
|
+
sage: (out, err, ret) = test_executable(["sage", "--sh", "-c", "echo Hello World; exit 42"])
|
444
|
+
sage: out.find("Hello World\n") >= 0
|
445
|
+
True
|
446
|
+
sage: ret
|
447
|
+
42
|
448
|
+
|
449
|
+
sage: # long time
|
450
|
+
sage: (out, err, ret) = test_executable([
|
451
|
+
....: "sage", "--ipython"], "\n3**33\n", pydebug_ignore_warnings=True)
|
452
|
+
sage: out.find("5559060566555523") >= 0
|
453
|
+
True
|
454
|
+
sage: err
|
455
|
+
''
|
456
|
+
sage: ret
|
457
|
+
0
|
458
|
+
|
459
|
+
sage: (out, err, ret) = test_executable(["sage", "--python"], "print(3^33)\n")
|
460
|
+
sage: out
|
461
|
+
'34\n'
|
462
|
+
sage: err
|
463
|
+
''
|
464
|
+
sage: ret
|
465
|
+
0
|
466
|
+
|
467
|
+
sage: (out, err, ret) = test_executable(["sage", "--python3"], "print(3^33)\n")
|
468
|
+
sage: out
|
469
|
+
'34\n'
|
470
|
+
sage: err
|
471
|
+
''
|
472
|
+
sage: ret
|
473
|
+
0
|
474
|
+
|
475
|
+
sage: (out, err, ret) = test_executable(["sage", "--cython"])
|
476
|
+
sage: print(err)
|
477
|
+
...
|
478
|
+
cython: error: cython: Need at least one source file
|
479
|
+
|
480
|
+
sage: def has_tty():
|
481
|
+
....: try:
|
482
|
+
....: os.open(os.ctermid(), os.O_RDONLY)
|
483
|
+
....: return True
|
484
|
+
....: except OSError:
|
485
|
+
....: return False
|
486
|
+
sage: (out, err, ret) = test_executable(["sage", "--ecl"], "(* 12345 54321)\n")
|
487
|
+
sage: out.find("Embeddable Common-Lisp") >= 0
|
488
|
+
True
|
489
|
+
sage: out.find("670592745") >= 0
|
490
|
+
True
|
491
|
+
sage: err
|
492
|
+
''
|
493
|
+
sage: ret
|
494
|
+
0
|
495
|
+
|
496
|
+
sage: (out, err, ret) = test_executable(["sage", "--lisp"], "(* 12345 54321)\n")
|
497
|
+
sage: out.find("Embeddable Common-Lisp") >= 0
|
498
|
+
True
|
499
|
+
sage: out.find("670592745") >= 0
|
500
|
+
True
|
501
|
+
sage: err
|
502
|
+
''
|
503
|
+
sage: ret
|
504
|
+
0
|
505
|
+
|
506
|
+
sage: # long time
|
507
|
+
sage: (out, err, ret) = test_executable([
|
508
|
+
....: "sage", "--gap", "-q"], "Size(SymmetricGroup(5));\n")
|
509
|
+
sage: out
|
510
|
+
'120\n'
|
511
|
+
sage: err.replace('gap: halving pool size.', '').strip()
|
512
|
+
''
|
513
|
+
sage: ret
|
514
|
+
0
|
515
|
+
|
516
|
+
sage: (out, err, ret) = test_executable([ # long time # optional - gdb
|
517
|
+
....: "sage", "--gdb"], 'quit\n')
|
518
|
+
sage: out.find('(gdb) ') >= 0 # long time # optional - gdb
|
519
|
+
True
|
520
|
+
sage: ret # long time # optional - gdb
|
521
|
+
0
|
522
|
+
|
523
|
+
sage: (out, err, ret) = test_executable(["sage", "--mwrank", "-v0", "-q"], "0 0 0 0 1\n")
|
524
|
+
sage: out
|
525
|
+
'Curve [0,0,0,0,1] :\tRank = 0\n\n'
|
526
|
+
sage: err
|
527
|
+
''
|
528
|
+
sage: ret
|
529
|
+
0
|
530
|
+
|
531
|
+
sage: (out, err, ret) = test_executable(["sage", "--singular"], "12345*54321;\n")
|
532
|
+
sage: out.find("A Computer Algebra System for Polynomial Computations") >= 0
|
533
|
+
True
|
534
|
+
sage: out.find("670592745") >= 0
|
535
|
+
True
|
536
|
+
sage: err
|
537
|
+
''
|
538
|
+
sage: ret
|
539
|
+
0
|
540
|
+
|
541
|
+
Test GP using the ``-f`` option which prevents the reading of a ``.gprc``
|
542
|
+
configuration file::
|
543
|
+
|
544
|
+
sage: (out, err, ret) = test_executable(["sage", "--gp", "-f"], "3^33\nquit(42)\n")
|
545
|
+
sage: out.find("PARI/GP") >= 0
|
546
|
+
True
|
547
|
+
sage: out.find("5559060566555523") >= 0
|
548
|
+
True
|
549
|
+
sage: err
|
550
|
+
''
|
551
|
+
sage: ret
|
552
|
+
42
|
553
|
+
|
554
|
+
Some programs of which we check functionality using only ``--version``::
|
555
|
+
|
556
|
+
sage: # needs sage.symbolic
|
557
|
+
sage: (out, err, ret) = test_executable(["sage", "--maxima", "--version"])
|
558
|
+
sage: out.find("Maxima ") >= 0
|
559
|
+
True
|
560
|
+
sage: err
|
561
|
+
''
|
562
|
+
sage: ret
|
563
|
+
0
|
564
|
+
|
565
|
+
sage: # optional - r
|
566
|
+
sage: (out, err, ret) = test_executable(["sage", "--R", "--version"])
|
567
|
+
sage: out.find("R version ") >= 0
|
568
|
+
True
|
569
|
+
sage: err
|
570
|
+
''
|
571
|
+
sage: ret
|
572
|
+
0
|
573
|
+
|
574
|
+
sage: (out, err, ret) = test_executable(["sage", "--sqlite3", "--version"])
|
575
|
+
sage: out.startswith("3.")
|
576
|
+
True
|
577
|
+
sage: err
|
578
|
+
''
|
579
|
+
sage: ret
|
580
|
+
0
|
581
|
+
|
582
|
+
Check some things requiring an internet connection::
|
583
|
+
|
584
|
+
sage: # optional - internet
|
585
|
+
sage: (out, err, ret) = test_executable(["sage", "--standard"])
|
586
|
+
sage: out.find("cython") >= 0
|
587
|
+
True
|
588
|
+
sage: err
|
589
|
+
''
|
590
|
+
sage: ret
|
591
|
+
0
|
592
|
+
|
593
|
+
sage: # optional - internet
|
594
|
+
sage: (out, err, ret) = test_executable(["sage", "--optional"])
|
595
|
+
sage: out.find("database_cremona_ellcurve") >= 0
|
596
|
+
True
|
597
|
+
sage: err
|
598
|
+
''
|
599
|
+
sage: ret
|
600
|
+
0
|
601
|
+
|
602
|
+
sage: # optional - internet
|
603
|
+
sage: (out, err, ret) = test_executable(["sage", "--experimental"])
|
604
|
+
sage: out.find("valgrind") >= 0
|
605
|
+
True
|
606
|
+
sage: err
|
607
|
+
''
|
608
|
+
sage: ret
|
609
|
+
0
|
610
|
+
|
611
|
+
Check an illegal command line option. This outputs an error to stdout,
|
612
|
+
but we allow stderr in case this changes in the future::
|
613
|
+
|
614
|
+
sage: (out, err, ret) = test_executable(["sage", "--zzfoobar"])
|
615
|
+
sage: (out+err).find("unknown option: --zzfoobar") >= 0
|
616
|
+
True
|
617
|
+
sage: ret > 0
|
618
|
+
True
|
619
|
+
|
620
|
+
Test ``sage --rst2ipynb file.rst`` on a ReST file::
|
621
|
+
|
622
|
+
sage: s = "::\n\n sage: 2^10\n 1024\n sage: 2 + 2\n 4"
|
623
|
+
sage: input = tmp_filename(ext='.rst')
|
624
|
+
sage: with open(input, 'w') as F:
|
625
|
+
....: _ = F.write(s)
|
626
|
+
sage: L = ["sage", "--rst2ipynb", input]
|
627
|
+
sage: (out, err, ret) = test_executable(L) # optional - rst2ipynb
|
628
|
+
sage: err # optional - rst2ipynb
|
629
|
+
''
|
630
|
+
sage: ret # optional - rst2ipynb
|
631
|
+
0
|
632
|
+
sage: from json import loads # optional - rst2ipynb
|
633
|
+
sage: d = loads(out) # optional - rst2ipynb
|
634
|
+
sage: sorted(d.keys()) # optional - rst2ipynb
|
635
|
+
['cells', 'metadata', 'nbformat', 'nbformat_minor']
|
636
|
+
sage: d['cells'][1]['source'] # optional - rst2ipynb
|
637
|
+
['2^10']
|
638
|
+
sage: d['cells'][2]['source'] # optional - rst2ipynb
|
639
|
+
['2 + 2']
|
640
|
+
|
641
|
+
Test ``sage --rst2ipynb file.rst file.ipynb`` on a ReST file::
|
642
|
+
|
643
|
+
sage: s = "::\n\n sage: 2^10\n 1024\n sage: 2 + 2\n 4"
|
644
|
+
sage: input = tmp_filename(ext='.rst')
|
645
|
+
sage: output = tmp_filename(ext='.ipynb')
|
646
|
+
sage: with open(input, 'w') as F:
|
647
|
+
....: _ = F.write(s)
|
648
|
+
sage: L = ["sage", "--rst2ipynb", input, output]
|
649
|
+
sage: test_executable(L) # optional - rst2ipynb
|
650
|
+
('', '', 0)
|
651
|
+
sage: import json # optional - rst2ipynb
|
652
|
+
sage: d = json.load(open(output,'r')) # optional - rst2ipynb
|
653
|
+
sage: type(d) # optional - rst2ipynb
|
654
|
+
<class 'dict'>
|
655
|
+
sage: sorted(d.keys()) # optional - rst2ipynb
|
656
|
+
['cells', 'metadata', 'nbformat', 'nbformat_minor']
|
657
|
+
sage: d['metadata'] # optional - rst2ipynb
|
658
|
+
{'kernelspec': {'display_name': 'sagemath', 'name': 'sagemath'}}
|
659
|
+
sage: d['cells'][1]['cell_type'] # optional - rst2ipynb
|
660
|
+
'code'
|
661
|
+
|
662
|
+
Test ``sage --ipynb2rst file.ipynb file.rst`` on a ipynb file::
|
663
|
+
|
664
|
+
sage: s = r'''{
|
665
|
+
....: "cells": [
|
666
|
+
....: {
|
667
|
+
....: "cell_type": "code",
|
668
|
+
....: "execution_count": 1,
|
669
|
+
....: "metadata": {},
|
670
|
+
....: "outputs": [
|
671
|
+
....: {
|
672
|
+
....: "data": {
|
673
|
+
....: "text/plain": [
|
674
|
+
....: "2"
|
675
|
+
....: ]
|
676
|
+
....: },
|
677
|
+
....: "execution_count": 1,
|
678
|
+
....: "metadata": {},
|
679
|
+
....: "output_type": "execute_result"
|
680
|
+
....: }
|
681
|
+
....: ],
|
682
|
+
....: "source": [
|
683
|
+
....: "1+1"
|
684
|
+
....: ]
|
685
|
+
....: },
|
686
|
+
....: {
|
687
|
+
....: "cell_type": "code",
|
688
|
+
....: "execution_count": null,
|
689
|
+
....: "metadata": {},
|
690
|
+
....: "outputs": [],
|
691
|
+
....: "source": []
|
692
|
+
....: }
|
693
|
+
....: ],
|
694
|
+
....: "metadata": {
|
695
|
+
....: "kernelspec": {
|
696
|
+
....: "display_name": "SageMath 8.3.beta4",
|
697
|
+
....: "language": "",
|
698
|
+
....: "name": "sagemath"
|
699
|
+
....: },
|
700
|
+
....: "language_info": {
|
701
|
+
....: "codemirror_mode": {
|
702
|
+
....: "name": "ipython",
|
703
|
+
....: "version": 2
|
704
|
+
....: },
|
705
|
+
....: "file_extension": ".py",
|
706
|
+
....: "mimetype": "text/x-python",
|
707
|
+
....: "name": "python",
|
708
|
+
....: "nbconvert_exporter": "python",
|
709
|
+
....: "pygments_lexer": "ipython2",
|
710
|
+
....: "version": "2.7.15"
|
711
|
+
....: }
|
712
|
+
....: },
|
713
|
+
....: "nbformat": 4,
|
714
|
+
....: "nbformat_minor": 2
|
715
|
+
....: }
|
716
|
+
....: '''
|
717
|
+
sage: t = '.. escape-backslashes\n.. default-role:: math\n\n\n::\n\n sage: 1+1\n 2\n\n\n\n\n'
|
718
|
+
sage: input = tmp_filename(ext='.ipynb')
|
719
|
+
sage: output = tmp_filename(ext='.rst')
|
720
|
+
sage: with open(input, 'w') as F:
|
721
|
+
....: _ = F.write(s)
|
722
|
+
sage: L = ["sage", "--ipynb2rst", input, output]
|
723
|
+
sage: _ = test_executable(L) # long time # optional - pandoc
|
724
|
+
sage: print(open(output, 'r').read() == t) # long time # optional - pandoc # known bug #32697
|
725
|
+
True
|
726
|
+
"""
|
727
|
+
pexpect_env = dict(os.environ)
|
728
|
+
try:
|
729
|
+
del pexpect_env["TERM"]
|
730
|
+
except KeyError:
|
731
|
+
pass
|
732
|
+
|
733
|
+
__with_pydebug = hasattr(sys, 'gettotalrefcount') # This is a Python debug build (--with-pydebug)
|
734
|
+
if __with_pydebug and pydebug_ignore_warnings:
|
735
|
+
pexpect_env['PYTHONWARNINGS'] = ','.join([
|
736
|
+
'ignore::DeprecationWarning',
|
737
|
+
])
|
738
|
+
|
739
|
+
kwds['encoding'] = kwds.pop('encoding', 'utf-8')
|
740
|
+
|
741
|
+
p = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE, env=pexpect_env,
|
742
|
+
**kwds)
|
743
|
+
if input:
|
744
|
+
p.stdin.write(input)
|
745
|
+
|
746
|
+
p.stdin.close()
|
747
|
+
fdout = p.stdout.fileno()
|
748
|
+
fderr = p.stderr.fileno()
|
749
|
+
out = []
|
750
|
+
err = []
|
751
|
+
|
752
|
+
while True:
|
753
|
+
# Try reading from fdout and fderr
|
754
|
+
rfd = []
|
755
|
+
if fdout:
|
756
|
+
rfd.append(fdout)
|
757
|
+
if fderr:
|
758
|
+
rfd.append(fderr)
|
759
|
+
if len(rfd) == 0:
|
760
|
+
break
|
761
|
+
timeout = float(timeout)
|
762
|
+
rlist = select.select(rfd, [], [], timeout)[0]
|
763
|
+
|
764
|
+
if len(rlist) == 0:
|
765
|
+
# Timeout!
|
766
|
+
p.terminate()
|
767
|
+
raise RuntimeError("timeout in test_executable()")
|
768
|
+
if fdout in rlist:
|
769
|
+
s = p.stdout.read(1024)
|
770
|
+
if not s:
|
771
|
+
fdout = None # EOF
|
772
|
+
p.stdout.close()
|
773
|
+
out.append(s)
|
774
|
+
if fderr in rlist:
|
775
|
+
s = p.stderr.read(1024)
|
776
|
+
if not s:
|
777
|
+
fderr = None # EOF
|
778
|
+
p.stderr.close()
|
779
|
+
err.append(s)
|
780
|
+
|
781
|
+
# In case out or err contains a quoted string, force the use of
|
782
|
+
# double quotes so that the output is enclosed in single
|
783
|
+
# quotes. This avoids some doctest failures with some versions of
|
784
|
+
# OS X and Xcode.
|
785
|
+
out = ''.join(out)
|
786
|
+
out = out.replace("'", '"')
|
787
|
+
err = ''.join(err)
|
788
|
+
err = err.replace("'", '"')
|
789
|
+
|
790
|
+
return (out, err, p.wait())
|