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.
Files changed (162) hide show
  1. passagemath_repl-10.5.1.data/scripts/sage-cachegrind +25 -0
  2. passagemath_repl-10.5.1.data/scripts/sage-callgrind +16 -0
  3. passagemath_repl-10.5.1.data/scripts/sage-cleaner +230 -0
  4. passagemath_repl-10.5.1.data/scripts/sage-coverage +327 -0
  5. passagemath_repl-10.5.1.data/scripts/sage-eval +14 -0
  6. passagemath_repl-10.5.1.data/scripts/sage-fixdoctests +710 -0
  7. passagemath_repl-10.5.1.data/scripts/sage-inline-fortran +12 -0
  8. passagemath_repl-10.5.1.data/scripts/sage-ipynb2rst +50 -0
  9. passagemath_repl-10.5.1.data/scripts/sage-ipython +16 -0
  10. passagemath_repl-10.5.1.data/scripts/sage-massif +25 -0
  11. passagemath_repl-10.5.1.data/scripts/sage-notebook +267 -0
  12. passagemath_repl-10.5.1.data/scripts/sage-omega +25 -0
  13. passagemath_repl-10.5.1.data/scripts/sage-preparse +302 -0
  14. passagemath_repl-10.5.1.data/scripts/sage-run +27 -0
  15. passagemath_repl-10.5.1.data/scripts/sage-run-cython +10 -0
  16. passagemath_repl-10.5.1.data/scripts/sage-runtests +9 -0
  17. passagemath_repl-10.5.1.data/scripts/sage-startuptime.py +163 -0
  18. passagemath_repl-10.5.1.data/scripts/sage-valgrind +34 -0
  19. passagemath_repl-10.5.1.dist-info/METADATA +77 -0
  20. passagemath_repl-10.5.1.dist-info/RECORD +162 -0
  21. passagemath_repl-10.5.1.dist-info/WHEEL +5 -0
  22. passagemath_repl-10.5.1.dist-info/top_level.txt +1 -0
  23. sage/all__sagemath_repl.py +119 -0
  24. sage/doctest/__init__.py +4 -0
  25. sage/doctest/__main__.py +236 -0
  26. sage/doctest/all.py +4 -0
  27. sage/doctest/check_tolerance.py +261 -0
  28. sage/doctest/control.py +1727 -0
  29. sage/doctest/external.py +534 -0
  30. sage/doctest/fixtures.py +383 -0
  31. sage/doctest/forker.py +2665 -0
  32. sage/doctest/marked_output.py +102 -0
  33. sage/doctest/parsing.py +1708 -0
  34. sage/doctest/parsing_test.py +79 -0
  35. sage/doctest/reporting.py +733 -0
  36. sage/doctest/rif_tol.py +124 -0
  37. sage/doctest/sources.py +1657 -0
  38. sage/doctest/test.py +584 -0
  39. sage/doctest/tests/1second.rst +4 -0
  40. sage/doctest/tests/99seconds.rst +4 -0
  41. sage/doctest/tests/abort.rst +5 -0
  42. sage/doctest/tests/atexit.rst +7 -0
  43. sage/doctest/tests/fail_and_die.rst +6 -0
  44. sage/doctest/tests/initial.rst +15 -0
  45. sage/doctest/tests/interrupt.rst +7 -0
  46. sage/doctest/tests/interrupt_diehard.rst +14 -0
  47. sage/doctest/tests/keyboardinterrupt.rst +11 -0
  48. sage/doctest/tests/longtime.rst +5 -0
  49. sage/doctest/tests/nodoctest +5 -0
  50. sage/doctest/tests/random_seed.rst +4 -0
  51. sage/doctest/tests/show_skipped.rst +18 -0
  52. sage/doctest/tests/sig_on.rst +9 -0
  53. sage/doctest/tests/simple_failure.rst +8 -0
  54. sage/doctest/tests/sleep_and_raise.rst +106 -0
  55. sage/doctest/tests/tolerance.rst +31 -0
  56. sage/doctest/util.py +750 -0
  57. sage/interfaces/cleaner.py +48 -0
  58. sage/interfaces/quit.py +163 -0
  59. sage/misc/all__sagemath_repl.py +51 -0
  60. sage/misc/banner.py +235 -0
  61. sage/misc/benchmark.py +221 -0
  62. sage/misc/classgraph.py +134 -0
  63. sage/misc/copying.py +22 -0
  64. sage/misc/cython.py +694 -0
  65. sage/misc/dev_tools.py +745 -0
  66. sage/misc/edit_module.py +304 -0
  67. sage/misc/explain_pickle.py +3079 -0
  68. sage/misc/gperftools.py +361 -0
  69. sage/misc/inline_fortran.py +212 -0
  70. sage/misc/messaging.py +86 -0
  71. sage/misc/pager.py +21 -0
  72. sage/misc/profiler.py +179 -0
  73. sage/misc/python.py +70 -0
  74. sage/misc/remote_file.py +53 -0
  75. sage/misc/sage_eval.py +249 -0
  76. sage/misc/sage_input.py +3621 -0
  77. sage/misc/sagedoc.py +1742 -0
  78. sage/misc/sh.py +38 -0
  79. sage/misc/trace.py +90 -0
  80. sage/repl/__init__.py +16 -0
  81. sage/repl/all.py +15 -0
  82. sage/repl/attach.py +625 -0
  83. sage/repl/configuration.py +186 -0
  84. sage/repl/display/__init__.py +1 -0
  85. sage/repl/display/fancy_repr.py +354 -0
  86. sage/repl/display/formatter.py +318 -0
  87. sage/repl/display/jsmol_iframe.py +290 -0
  88. sage/repl/display/pretty_print.py +153 -0
  89. sage/repl/display/util.py +163 -0
  90. sage/repl/image.py +302 -0
  91. sage/repl/inputhook.py +91 -0
  92. sage/repl/interface_magic.py +298 -0
  93. sage/repl/interpreter.py +854 -0
  94. sage/repl/ipython_extension.py +593 -0
  95. sage/repl/ipython_kernel/__init__.py +1 -0
  96. sage/repl/ipython_kernel/__main__.py +4 -0
  97. sage/repl/ipython_kernel/all_jupyter.py +10 -0
  98. sage/repl/ipython_kernel/install.py +301 -0
  99. sage/repl/ipython_kernel/interact.py +278 -0
  100. sage/repl/ipython_kernel/kernel.py +217 -0
  101. sage/repl/ipython_kernel/widgets.py +466 -0
  102. sage/repl/ipython_kernel/widgets_sagenb.py +587 -0
  103. sage/repl/ipython_tests.py +163 -0
  104. sage/repl/load.py +326 -0
  105. sage/repl/preparse.py +2218 -0
  106. sage/repl/prompts.py +90 -0
  107. sage/repl/rich_output/__init__.py +4 -0
  108. sage/repl/rich_output/backend_base.py +648 -0
  109. sage/repl/rich_output/backend_doctest.py +316 -0
  110. sage/repl/rich_output/backend_emacs.py +151 -0
  111. sage/repl/rich_output/backend_ipython.py +596 -0
  112. sage/repl/rich_output/buffer.py +311 -0
  113. sage/repl/rich_output/display_manager.py +829 -0
  114. sage/repl/rich_output/example.avi +0 -0
  115. sage/repl/rich_output/example.canvas3d +1 -0
  116. sage/repl/rich_output/example.dvi +0 -0
  117. sage/repl/rich_output/example.flv +0 -0
  118. sage/repl/rich_output/example.gif +0 -0
  119. sage/repl/rich_output/example.jpg +0 -0
  120. sage/repl/rich_output/example.mkv +0 -0
  121. sage/repl/rich_output/example.mov +0 -0
  122. sage/repl/rich_output/example.mp4 +0 -0
  123. sage/repl/rich_output/example.ogv +0 -0
  124. sage/repl/rich_output/example.pdf +0 -0
  125. sage/repl/rich_output/example.png +0 -0
  126. sage/repl/rich_output/example.svg +54 -0
  127. sage/repl/rich_output/example.webm +0 -0
  128. sage/repl/rich_output/example.wmv +0 -0
  129. sage/repl/rich_output/example_jmol.spt.zip +0 -0
  130. sage/repl/rich_output/example_wavefront_scene.mtl +7 -0
  131. sage/repl/rich_output/example_wavefront_scene.obj +17 -0
  132. sage/repl/rich_output/output_basic.py +391 -0
  133. sage/repl/rich_output/output_browser.py +103 -0
  134. sage/repl/rich_output/output_catalog.py +54 -0
  135. sage/repl/rich_output/output_graphics.py +320 -0
  136. sage/repl/rich_output/output_graphics3d.py +345 -0
  137. sage/repl/rich_output/output_video.py +231 -0
  138. sage/repl/rich_output/preferences.py +432 -0
  139. sage/repl/rich_output/pretty_print.py +339 -0
  140. sage/repl/rich_output/test_backend.py +201 -0
  141. sage/repl/user_globals.py +214 -0
  142. sage/tests/all.py +0 -0
  143. sage/tests/all__sagemath_repl.py +3 -0
  144. sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py +630 -0
  145. sage/tests/arxiv_0812_2725.py +351 -0
  146. sage/tests/benchmark.py +1925 -0
  147. sage/tests/book_schilling_zabrocki_kschur_primer.py +795 -0
  148. sage/tests/book_stein_ent.py +651 -0
  149. sage/tests/book_stein_modform.py +558 -0
  150. sage/tests/cmdline.py +796 -0
  151. sage/tests/combinatorial_hopf_algebras.py +52 -0
  152. sage/tests/finite_poset.py +623 -0
  153. sage/tests/functools_partial_src.py +27 -0
  154. sage/tests/gosper-sum.py +218 -0
  155. sage/tests/lazy_imports.py +28 -0
  156. sage/tests/modular_group_cohomology.py +80 -0
  157. sage/tests/numpy.py +21 -0
  158. sage/tests/parigp.py +76 -0
  159. sage/tests/startup.py +27 -0
  160. sage/tests/symbolic-series.py +76 -0
  161. sage/tests/sympy.py +16 -0
  162. sage/tests/test_deprecation.py +31 -0
@@ -0,0 +1,163 @@
1
+ # sage_setup: distribution = sagemath-repl
2
+ '''
3
+ Tests for the IPython integration
4
+
5
+ First, test the pinfo magic for Python code. This is what IPython
6
+ calls when you ask for the single-questionmark help, like `foo?` ::
7
+
8
+ sage: from sage.repl.interpreter import get_test_shell
9
+ sage: shell = get_test_shell()
10
+ sage: shell.run_cell(u'from sage.repl.ipython_tests import dummy')
11
+ sage: shell.run_cell(u'%pinfo dummy')
12
+ Signature: dummy(argument, optional=None)
13
+ Docstring:
14
+ Dummy Docstring Title.
15
+ <BLANKLINE>
16
+ Dummy docstring explanation.
17
+ <BLANKLINE>
18
+ INPUT:
19
+ <BLANKLINE>
20
+ ... "argument" -- anything; dummy argument
21
+ <BLANKLINE>
22
+ ... "optional" -- anything (optional); dummy optional
23
+ <BLANKLINE>
24
+ EXAMPLES...
25
+ <BLANKLINE>
26
+ ...
27
+ Init docstring: ...ee help(type(...)) for...signature...
28
+ File: .../sage/repl/ipython_tests.py
29
+ Type: function
30
+
31
+ Next, test the pinfo magic for Cython code::
32
+
33
+ sage: from sage.repl.interpreter import get_test_shell
34
+ sage: shell = get_test_shell()
35
+ sage: shell.run_cell(u'from sage.tests.stl_vector import stl_int_vector')
36
+ sage: shell.run_cell(u'%pinfo stl_int_vector')
37
+ ...
38
+ Example class wrapping an STL vector.
39
+ <BLANKLINE>
40
+ EXAMPLES...
41
+ <BLANKLINE>
42
+ ...
43
+ Init docstring: ...ee help(type(...)) for...signature...
44
+ File: .../sage/tests/stl_vector.pyx
45
+ Type: type
46
+ ...
47
+
48
+ Next, test the ``pinfo`` magic for ``R`` interface code, see :issue:`26906`::
49
+
50
+ sage: from sage.repl.interpreter import get_test_shell # optional - rpy2
51
+ sage: shell = get_test_shell() # optional - rpy2
52
+ sage: shell.run_cell(u'%pinfo r.lm') # optional - rpy2
53
+ Signature: r.lm(...*args, **kwds)
54
+ ...
55
+ String form: lm
56
+ File: .../sage/interfaces/r.py
57
+ Docstring:...
58
+ title
59
+ *****
60
+ <BLANKLINE>
61
+ Fitting Linear Models
62
+ ...
63
+
64
+ Next, test the pinfo2 magic for Python code. This is what IPython
65
+ calls when you ask for the double-questionmark help, like `foo??` ::
66
+
67
+ sage: from sage.repl.interpreter import get_test_shell
68
+ sage: shell = get_test_shell()
69
+ sage: shell.run_cell(u'from sage.repl.ipython_tests import dummy')
70
+ sage: shell.run_cell(u'%pinfo2 dummy')
71
+ Signature: dummy(argument, optional=None)
72
+ ...
73
+ Source:
74
+ def dummy(argument, optional=None):
75
+ """
76
+ Dummy Docstring Title.
77
+ <BLANKLINE>
78
+ Dummy docstring explanation.
79
+ <BLANKLINE>
80
+ INPUT:
81
+ <BLANKLINE>
82
+ - ``argument`` -- anything; dummy argument
83
+ <BLANKLINE>
84
+ - ``optional`` -- anything (optional); dummy optional
85
+ <BLANKLINE>
86
+ EXAMPLES::
87
+ <BLANKLINE>
88
+ ...
89
+ """
90
+ return 'Source code would be here'
91
+ File: .../sage/repl/ipython_tests.py
92
+ Type: function
93
+
94
+ Next, test the pinfo2 magic for Cython code::
95
+
96
+ sage: from sage.repl.interpreter import get_test_shell
97
+ sage: shell = get_test_shell()
98
+ sage: shell.run_cell(u'from sage.tests.stl_vector import stl_int_vector')
99
+ sage: shell.run_cell(u'%pinfo2 stl_int_vector')
100
+ ...
101
+ cdef class stl_int_vector(SageObject):
102
+ """
103
+ Example class wrapping an STL vector.
104
+ <BLANKLINE>
105
+ EXAMPLES::
106
+ <BLANKLINE>
107
+ ...
108
+ """
109
+ <BLANKLINE>
110
+ cdef vector[int] *data
111
+ cdef string *name
112
+ <BLANKLINE>
113
+ def __cinit__(self):
114
+ """
115
+ The Cython constructor.
116
+ <BLANKLINE>
117
+ EXAMPLES::
118
+ <BLANKLINE>
119
+ ...
120
+ File: .../sage/tests/stl_vector.pyx
121
+ Type: type
122
+ ...
123
+
124
+ Next, test the ``pinfo2`` magic for ``R`` interface code, see :issue:`26906`::
125
+
126
+ sage: from sage.repl.interpreter import get_test_shell # optional - rpy2
127
+ sage: shell = get_test_shell() # optional - rpy2
128
+ sage: shell.run_cell(u'%pinfo2 r.lm') # optional - rpy2
129
+ Signature: r.lm(...*args, **kwds)
130
+ ...
131
+ String form: lm
132
+ File: .../sage/interfaces/r.py
133
+ Source:
134
+ function (formula, data, subset, weights, na.action, method = "qr",
135
+ ...
136
+
137
+ Test that there are no warnings being ignored internally::
138
+
139
+ sage: import warnings
140
+ sage: warnings.simplefilter('error'); get_test_shell()
141
+ <sage.repl.interpreter.SageTestShell object at 0x...>
142
+ '''
143
+
144
+
145
+ def dummy(argument, optional=None):
146
+ """
147
+ Dummy Docstring Title.
148
+
149
+ Dummy docstring explanation.
150
+
151
+ INPUT:
152
+
153
+ - ``argument`` -- anything; dummy argument
154
+
155
+ - ``optional`` -- anything (optional); dummy optional
156
+
157
+ EXAMPLES::
158
+
159
+ sage: from sage.repl.ipython_tests import dummy
160
+ sage: dummy(1)
161
+ 'Source code would be here'
162
+ """
163
+ return 'Source code would be here'
sage/repl/load.py ADDED
@@ -0,0 +1,326 @@
1
+ # sage_setup: distribution = sagemath-repl
2
+ """
3
+ Load Python, Sage, Cython, Fortran and Magma files in Sage
4
+ """
5
+ # ****************************************************************************
6
+ # Copyright (C) 2006 William Stein <wstein@gmail.com>
7
+ #
8
+ # This program is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ # https://www.gnu.org/licenses/
13
+ # ****************************************************************************
14
+ import base64
15
+ from pathlib import Path
16
+
17
+ from sage.cpython.string import str_to_bytes, bytes_to_str, FS_ENCODING
18
+
19
+
20
+ def is_loadable_filename(filename):
21
+ """
22
+ Return whether a file can be loaded into Sage.
23
+
24
+ This checks only whether its name ends in one of the supported
25
+ extensions ``.py``, ``.pyx``, ``.sage``, ``.spyx``, ``.f``,
26
+ ``.f90`` and ``.m``.
27
+
28
+ .. NOTE:: :func:`load` assumes that `.m` signifies a Magma file.
29
+
30
+ INPUT:
31
+
32
+ - ``filename`` -- string or :class:`Path` object
33
+
34
+ OUTPUT: boolean
35
+
36
+ EXAMPLES::
37
+
38
+ sage: sage.repl.load.is_loadable_filename('foo.bar')
39
+ False
40
+ sage: sage.repl.load.is_loadable_filename('foo.c')
41
+ False
42
+ sage: sage.repl.load.is_loadable_filename('foo.sage')
43
+ True
44
+ sage: sage.repl.load.is_loadable_filename('FOO.F90')
45
+ True
46
+ sage: sage.repl.load.is_loadable_filename('foo.m')
47
+ True
48
+
49
+ sage: from pathlib import Path
50
+ sage: sage.repl.load.is_loadable_filename(Path('foo.py'))
51
+ True
52
+ """
53
+ ext = Path(filename).suffix.lower()
54
+ return ext in ('.py', '.pyx', '.sage', '.spyx', '.f', '.f90', '.m')
55
+
56
+
57
+ def load_cython(name):
58
+ """
59
+ Helper function to load a Cython file.
60
+
61
+ INPUT:
62
+
63
+ - ``name`` -- filename of the Cython file
64
+
65
+ OUTPUT:
66
+
67
+ - A string with Python code to import the names from the compiled
68
+ module.
69
+ """
70
+ from sage.misc.cython import cython
71
+ mod, dir = cython(str(name), compile_message=True, use_cache=True)
72
+ import sys
73
+ sys.path.append(dir)
74
+ return f'from {mod} import *'
75
+
76
+
77
+ def load(filename, globals, attach=False):
78
+ r"""
79
+ Execute a file in the scope given by ``globals``. If the name starts with
80
+ ``http://`` or ``https://``, it is treated as a URL and downloaded.
81
+
82
+ .. NOTE::
83
+
84
+ For Cython files, the situation is more complicated --
85
+ the module is first compiled to a temporary module ``t`` and
86
+ executed via::
87
+
88
+ from t import *
89
+
90
+ INPUT:
91
+
92
+ - ``filename`` -- string (denoting a filename or URL) or a :class:`Path` object
93
+
94
+ - ``globals`` -- string:object dictionary; the context in which
95
+ to execute the file contents
96
+
97
+ - ``attach`` -- boolean (default: ``False``); whether to add the
98
+ file to the list of attached files
99
+
100
+ Loading an executable Sage script from the command prompt will run whatever
101
+ code is inside an
102
+
103
+ if __name__ == "__main__":
104
+
105
+ section, as the condition on ``__name__`` will hold true (code run from the
106
+ command prompt is considered to be running in the ``__main__`` module.)
107
+
108
+ EXAMPLES:
109
+
110
+ Note that ``.py`` files are *not* preparsed::
111
+
112
+ sage: t = tmp_filename(ext='.py')
113
+ sage: with open(t, 'w') as f:
114
+ ....: _ = f.write("print(('hi', 2^3)); z = -2^7")
115
+ sage: z = 1
116
+ sage: sage.repl.load.load(t, globals())
117
+ ('hi', 1)
118
+ sage: z
119
+ -7
120
+
121
+ A ``.sage`` file *is* preparsed::
122
+
123
+ sage: t = tmp_filename(ext='.sage')
124
+ sage: with open(t, 'w') as f:
125
+ ....: _ = f.write("print(('hi', 2^3)); z = -2^7")
126
+ sage: z = 1
127
+ sage: sage.repl.load.load(t, globals())
128
+ ('hi', 8)
129
+ sage: z
130
+ -128
131
+
132
+ Cython files are *not* preparsed::
133
+
134
+ sage: t = tmp_filename(ext='.pyx')
135
+ sage: with open(t, 'w') as f:
136
+ ....: _ = f.write("print(('hi', 2^3)); z = -2^7")
137
+ sage: z = 1
138
+ sage: sage.repl.load.load(t, globals()) # needs sage.misc.cython
139
+ Compiling ...
140
+ ('hi', 1)
141
+ sage: z
142
+ -7
143
+
144
+ If the file is not a Cython, Python, or Sage file, a :exc:`ValueError`
145
+ is raised::
146
+
147
+ sage: sage.repl.load.load(tmp_filename(ext='.foo'), globals())
148
+ Traceback (most recent call last):
149
+ ...
150
+ ValueError: unknown file extension '.foo' for load or attach (supported extensions: .py, .pyx, .sage, .spyx, .f, .f90, .m)
151
+
152
+ We load a file given at a remote URL (not tested for security reasons)::
153
+
154
+ sage: sage.repl.load.load('https://www.sagemath.org/files/loadtest.py', globals()) # not tested
155
+ hi from the net
156
+ 5
157
+
158
+ We can load files using secure http (https)::
159
+
160
+ sage: sage.repl.load.load('https://raw.githubusercontent.com/sagemath/sage-patchbot/3.0.0/sage_patchbot/util.py', globals()) # optional - internet
161
+
162
+ We attach a file::
163
+
164
+ sage: t = tmp_filename(ext='.py')
165
+ sage: with open(t, 'w') as f:
166
+ ....: _ = f.write("print('hello world')")
167
+ sage: sage.repl.load.load(t, globals(), attach=True)
168
+ hello world
169
+ sage: t in attached_files()
170
+ True
171
+
172
+ You cannot attach remote URLs (yet)::
173
+
174
+ sage: sage.repl.load.load('https://www.sagemath.org/files/loadtest.py', globals(), attach=True) # optional - internet
175
+ Traceback (most recent call last):
176
+ ...
177
+ NotImplementedError: you cannot attach a URL
178
+
179
+ The default search path for loading and attaching files is the
180
+ current working directory, i.e., ``'.'``. But you can modify the
181
+ path with :func:`load_attach_path`::
182
+
183
+ sage: import tempfile
184
+ sage: sage.repl.attach.reset(); reset_load_attach_path()
185
+ sage: load_attach_path()
186
+ [PosixPath('.')]
187
+ sage: with tempfile.TemporaryDirectory() as t_dir:
188
+ ....: fname = 'test.py'
189
+ ....: fullpath = os.path.join(t_dir, fname)
190
+ ....: with open(fullpath, 'w') as f:
191
+ ....: _ = f.write("print(37 * 3)")
192
+ ....: load_attach_path(t_dir, replace=True)
193
+ ....: attach(fname)
194
+ 111
195
+ sage: sage.repl.attach.reset(); reset_load_attach_path() # clean up
196
+
197
+ or by setting the environment variable ``SAGE_LOAD_ATTACH_PATH``
198
+ to a colon-separated list before starting Sage::
199
+
200
+ $ export SAGE_LOAD_ATTACH_PATH="/path/to/my/library:/path/to/utils"
201
+ $ sage
202
+ sage: load_attach_path() # not tested
203
+ ['.', '/path/to/my/library', '/path/to/utils']
204
+
205
+ TESTS:
206
+
207
+ Make sure that load handles filenames with spaces in the name or path::
208
+
209
+ sage: t = tmp_filename(ext=' b.sage')
210
+ sage: with open(t, 'w') as f:
211
+ ....: _ = f.write("print(2)")
212
+ sage: sage.repl.load.load(t, globals())
213
+ 2
214
+
215
+ Non-existing files with spaces give correct messages::
216
+
217
+ sage: sage.repl.load.load("this file should not exist", globals())
218
+ Traceback (most recent call last):
219
+ ...
220
+ OSError: did not find file 'this file should not exist' to load or attach
221
+ """
222
+ if attach:
223
+ from sage.repl.attach import add_attached_file
224
+
225
+ if isinstance(filename, bytes):
226
+ # For Python 3 in particular, convert bytes filenames to str since the
227
+ # rest of this functions operate on filename as a str
228
+ filename = bytes_to_str(filename, FS_ENCODING, 'surrogateescape')
229
+
230
+ if isinstance(filename, str) and filename.lower().startswith(('http://', 'https://')):
231
+ if attach:
232
+ # But see https://en.wikipedia.org/wiki/HTTP_ETag for how
233
+ # we will do this.
234
+ # https://diveintopython3.net/http-web-services.html#etags
235
+ raise NotImplementedError("you cannot attach a URL")
236
+ from sage.misc.remote_file import get_remote_file
237
+ filename = get_remote_file(filename, verbose=False)
238
+
239
+ filename = Path(filename).expanduser()
240
+
241
+ from sage.repl.attach import load_attach_path
242
+ for path in load_attach_path():
243
+ fpath = (path / filename).expanduser()
244
+ if fpath.is_file():
245
+ break
246
+ else:
247
+ raise OSError('did not find file %r to load or attach' % str(filename))
248
+
249
+ ext = fpath.suffix.lower()
250
+ if ext == '.py':
251
+ if attach:
252
+ add_attached_file(fpath)
253
+ with fpath.open() as f:
254
+ code = compile(f.read(), fpath, 'exec')
255
+ exec(code, globals)
256
+ elif ext == '.sage':
257
+ from sage.repl.attach import load_attach_mode
258
+ from sage.repl.preparse import preparse_file_named, preparse_file
259
+ load_debug_mode, attach_debug_mode = load_attach_mode()
260
+ if (attach and attach_debug_mode) or ((not attach) and load_debug_mode):
261
+ # Preparse to a file to enable tracebacks with
262
+ # code snippets. Use preparse_file_named to make
263
+ # the file name appear in the traceback as well.
264
+ # See Issue 11812.
265
+ if attach:
266
+ add_attached_file(fpath)
267
+ parsed_file = preparse_file_named(fpath)
268
+ with parsed_file.open() as f:
269
+ code = compile(f.read(), parsed_file, 'exec')
270
+ exec(code, globals)
271
+ else:
272
+ # Preparse in memory only for speed.
273
+ if attach:
274
+ add_attached_file(fpath)
275
+ with fpath.open() as f:
276
+ exec(preparse_file(f.read()) + "\n", globals)
277
+ elif ext in ['.spyx', '.pyx']:
278
+ if attach:
279
+ add_attached_file(fpath)
280
+ exec(load_cython(fpath), globals)
281
+ elif ext in ['.f', '.f90']:
282
+ from sage.misc.inline_fortran import fortran
283
+ with fpath.open() as f:
284
+ fortran(f.read(), globals)
285
+ elif ext == '.m':
286
+ # Assume magma for now, though maybe .m is used by maple and
287
+ # mathematica too, and we should really analyze the file
288
+ # further.
289
+ s = globals['magma'].load(fpath)
290
+ i = s.find('\n')
291
+ print(s[i + 1:])
292
+ else:
293
+ raise ValueError('unknown file extension %r for load or attach (supported extensions: .py, .pyx, .sage, .spyx, .f, .f90, .m)' % ext)
294
+
295
+
296
+ def load_wrap(filename, attach=False):
297
+ """
298
+ Encode a load or attach command as valid Python code.
299
+
300
+ INPUT:
301
+
302
+ - ``filename`` -- string or :class:`Path` object; the argument
303
+ to the load or attach command
304
+
305
+ - ``attach`` -- boolean (default: ``False``); whether to attach
306
+ ``filename``, instead of loading it
307
+
308
+ OUTPUT: string
309
+
310
+ EXAMPLES::
311
+
312
+ sage: sage.repl.load.load_wrap('foo.py', True)
313
+ 'sage.repl.load.load(sage.repl.load.base64.b64decode("Zm9vLnB5"),globals(),True)'
314
+ sage: sage.repl.load.load_wrap('foo.sage')
315
+ 'sage.repl.load.load(sage.repl.load.base64.b64decode("Zm9vLnNhZ2U="),globals(),False)'
316
+ sage: m = sage.repl.load.base64.b64decode("Zm9vLnNhZ2U=")
317
+ sage: m == b'foo.sage'
318
+ True
319
+ """
320
+ if isinstance(filename, Path):
321
+ filename = str(filename)
322
+ # Note: In Python 3, b64encode only accepts bytes, and returns bytes.
323
+ b64 = base64.b64encode(str_to_bytes(filename, FS_ENCODING,
324
+ "surrogateescape"))
325
+ txt = 'sage.repl.load.load(sage.repl.load.base64.b64decode("{}"),globals(),{})'
326
+ return txt.format(bytes_to_str(b64, 'ascii'), attach)