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.
Files changed (162) hide show
  1. passagemath_repl-10.4.62.data/scripts/sage-cachegrind +25 -0
  2. passagemath_repl-10.4.62.data/scripts/sage-callgrind +16 -0
  3. passagemath_repl-10.4.62.data/scripts/sage-cleaner +230 -0
  4. passagemath_repl-10.4.62.data/scripts/sage-coverage +327 -0
  5. passagemath_repl-10.4.62.data/scripts/sage-eval +14 -0
  6. passagemath_repl-10.4.62.data/scripts/sage-fixdoctests +708 -0
  7. passagemath_repl-10.4.62.data/scripts/sage-inline-fortran +12 -0
  8. passagemath_repl-10.4.62.data/scripts/sage-ipynb2rst +50 -0
  9. passagemath_repl-10.4.62.data/scripts/sage-ipython +16 -0
  10. passagemath_repl-10.4.62.data/scripts/sage-massif +25 -0
  11. passagemath_repl-10.4.62.data/scripts/sage-notebook +267 -0
  12. passagemath_repl-10.4.62.data/scripts/sage-omega +25 -0
  13. passagemath_repl-10.4.62.data/scripts/sage-preparse +302 -0
  14. passagemath_repl-10.4.62.data/scripts/sage-run +27 -0
  15. passagemath_repl-10.4.62.data/scripts/sage-run-cython +10 -0
  16. passagemath_repl-10.4.62.data/scripts/sage-runtests +9 -0
  17. passagemath_repl-10.4.62.data/scripts/sage-startuptime.py +163 -0
  18. passagemath_repl-10.4.62.data/scripts/sage-valgrind +34 -0
  19. passagemath_repl-10.4.62.dist-info/METADATA +77 -0
  20. passagemath_repl-10.4.62.dist-info/RECORD +162 -0
  21. passagemath_repl-10.4.62.dist-info/WHEEL +5 -0
  22. passagemath_repl-10.4.62.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 +131 -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 +246 -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/__init__.py +1 -0
  143. sage/tests/all.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 +1923 -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 +790 -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,829 @@
1
+ # sage_setup: distribution = sagemath-repl
2
+ r"""
3
+ Display Manager
4
+
5
+ This is the heart of the rich output system, the display manager
6
+ arbitrates between
7
+
8
+ * Backend capabilities: what can be displayed
9
+
10
+ * Backend preferences: what gives good quality on the backend
11
+
12
+ * Sage capabilities: every Sage object can only generate certain
13
+ representations, and
14
+
15
+ * User preferences: typeset vs. plain text vs. ascii art, etc.
16
+
17
+ The display manager is a singleton class, Sage always has exactly one
18
+ instance of it. Use :func:`get_display_manager` to obtain it.
19
+
20
+ EXAMPLES::
21
+
22
+ sage: from sage.repl.rich_output import get_display_manager
23
+ sage: dm = get_display_manager(); dm
24
+ The Sage display manager using the doctest backend
25
+ """
26
+
27
+ # ****************************************************************************
28
+ # Copyright (C) 2015 Volker Braun <vbraun.name@gmail.com>
29
+ #
30
+ # Distributed under the terms of the GNU General Public License (GPL)
31
+ # as published by the Free Software Foundation; either version 2 of
32
+ # the License, or (at your option) any later version.
33
+ # https://www.gnu.org/licenses/
34
+ # ****************************************************************************
35
+
36
+
37
+ import warnings
38
+
39
+ from sage.structure.sage_object import SageObject
40
+ from sage.repl.rich_output.output_basic import (
41
+ OutputPlainText, OutputAsciiArt, OutputUnicodeArt, OutputLatex,
42
+ )
43
+ from sage.repl.rich_output.output_browser import (
44
+ OutputHtml,
45
+ )
46
+ from sage.repl.rich_output.preferences import DisplayPreferences
47
+
48
+
49
+ class DisplayException(Exception):
50
+ """
51
+ Base exception for all rich output-related exceptions.
52
+
53
+ EXAMPLES::
54
+
55
+ sage: from sage.repl.rich_output.display_manager import DisplayException
56
+ sage: raise DisplayException('foo')
57
+ Traceback (most recent call last):
58
+ ...
59
+ DisplayException: foo
60
+ """
61
+ pass
62
+
63
+
64
+ class OutputTypeException(DisplayException):
65
+ """
66
+ Wrong Output container.
67
+
68
+ The output containers are the subclasses of
69
+ :class:`~sage.repl.rich_output.output_basic.OutputBase` that
70
+ contain the entire output. The display backends must create output
71
+ containers of a suitable type depending on the displayed Python
72
+ object. This exception indicates that there is a mistake in the
73
+ backend and it returned the wrong type of output container.
74
+
75
+ EXAMPLES::
76
+
77
+ sage: from sage.repl.rich_output.display_manager import OutputTypeException
78
+ sage: raise OutputTypeException('foo')
79
+ Traceback (most recent call last):
80
+ ...
81
+ OutputTypeException: foo
82
+ """
83
+ pass
84
+
85
+
86
+ class RichReprWarning(UserWarning):
87
+ """
88
+ Warning that is throws if a call to ``_rich_repr_`` fails.
89
+
90
+ If an object implements ``_rich_repr_`` then it must return a
91
+ value, possibly ``None`` to indicate that no rich output can be
92
+ generated. But it may not raise an exception as it is very
93
+ confusing for the user if the displayhook fails.
94
+
95
+ EXAMPLES::
96
+
97
+ sage: from sage.repl.rich_output.display_manager import RichReprWarning
98
+ sage: raise RichReprWarning('foo')
99
+ Traceback (most recent call last):
100
+ ...
101
+ RichReprWarning: foo
102
+ """
103
+ pass
104
+
105
+
106
+ class restricted_output:
107
+
108
+ def __init__(self, display_manager, output_classes):
109
+ """
110
+ Context manager to temporarily restrict the accepted output types.
111
+
112
+ In the context, the output is restricted to the output
113
+ container types listed in ``output_classes``. Additionally,
114
+ display preferences are changed not to show graphics.
115
+
116
+ INPUT:
117
+
118
+ - ``display_manager`` -- the display manager
119
+
120
+ - ``output_classes`` -- iterable of output container types
121
+
122
+ EXAMPLES::
123
+
124
+ sage: from sage.repl.rich_output.display_manager import (
125
+ ....: get_display_manager, restricted_output)
126
+ sage: dm = get_display_manager()
127
+ sage: restricted_output(dm, [dm.types.OutputPlainText])
128
+ <sage.repl.rich_output.display_manager.restricted_output object at 0x...>
129
+ """
130
+ self._display_manager = display_manager
131
+ self._output_classes = frozenset(output_classes)
132
+
133
+ def __enter__(self):
134
+ """
135
+ Enter the restricted output context.
136
+
137
+ EXAMPLES::
138
+
139
+ sage: from sage.repl.rich_output.display_manager import (
140
+ ....: get_display_manager, restricted_output)
141
+ sage: dm = get_display_manager()
142
+ sage: len(dm.supported_output()) > 1
143
+ True
144
+ sage: with restricted_output(dm, [dm.types.OutputPlainText]):
145
+ ....: dm.supported_output()
146
+ frozenset({<class 'sage.repl.rich_output.output_basic.OutputPlainText'>})
147
+
148
+ sage: dm.preferences.supplemental_plot
149
+ 'never'
150
+ sage: dm.preferences.supplemental_plot = 'always'
151
+ sage: with restricted_output(dm, [dm.types.OutputPlainText]):
152
+ ....: dm.preferences
153
+ Display preferences:
154
+ * align_latex is not specified
155
+ * graphics = disable
156
+ * supplemental_plot = never
157
+ * text is not specified
158
+ sage: dm.preferences.supplemental_plot = 'never'
159
+ """
160
+ dm = self._display_manager
161
+ self._original = dm._supported_output
162
+ dm._supported_output = self._output_classes
163
+ self._original_prefs = DisplayPreferences(dm.preferences)
164
+ dm.preferences.graphics = 'disable'
165
+ dm.preferences.supplemental_plot = 'never'
166
+
167
+ def __exit__(self, exception_type, value, traceback):
168
+ """
169
+ Exit the restricted output context.
170
+
171
+ EXAMPLES::
172
+
173
+ sage: from sage.repl.rich_output.display_manager import (
174
+ ....: get_display_manager, restricted_output)
175
+ sage: dm = get_display_manager()
176
+ sage: with restricted_output(dm, [dm.types.OutputPlainText]):
177
+ ....: assert len(dm.supported_output()) == 1
178
+ sage: assert len(dm.supported_output()) > 1
179
+ """
180
+ dm = self._display_manager
181
+ dm._supported_output = self._original
182
+ dm.preferences.graphics = self._original_prefs.graphics
183
+ dm.preferences.supplemental_plot = self._original_prefs.supplemental_plot
184
+
185
+
186
+ class DisplayManager(SageObject):
187
+
188
+ _instance = None
189
+
190
+ def __init__(self):
191
+ """
192
+ The Display Manager.
193
+
194
+ Used to decide what kind of rich output is best.
195
+
196
+ EXAMPLES::
197
+
198
+ sage: from sage.repl.rich_output import get_display_manager
199
+ sage: get_display_manager()
200
+ The Sage display manager using the doctest backend
201
+ """
202
+ assert DisplayManager._instance is None
203
+ DisplayManager._instance = self
204
+ from sage.repl.rich_output.backend_base import BackendSimple
205
+ self.switch_backend(BackendSimple())
206
+
207
+ @classmethod
208
+ def get_instance(cls):
209
+ """
210
+ Get the singleton instance.
211
+
212
+ This class method is equivalent to
213
+ :func:`get_display_manager`.
214
+
215
+ OUTPUT: the display manager singleton
216
+
217
+ EXAMPLES::
218
+
219
+ sage: from sage.repl.rich_output.display_manager import DisplayManager
220
+ sage: DisplayManager.get_instance()
221
+ The Sage display manager using the doctest backend
222
+ """
223
+ if cls._instance is not None:
224
+ return cls._instance
225
+ else:
226
+ return cls()
227
+
228
+ def _repr_(self):
229
+ """
230
+ Return a string representation.
231
+
232
+ OUTPUT: string
233
+
234
+ EXAMPLES::
235
+
236
+ sage: from sage.repl.rich_output import get_display_manager
237
+ sage: get_display_manager()
238
+ The Sage display manager using the doctest backend
239
+ """
240
+ s = 'The Sage display manager using the {0} backend'.format(self._backend)
241
+ return s
242
+
243
+ @property
244
+ def types(self):
245
+ """
246
+ Catalog of all output container types.
247
+
248
+ Note that every output type must be registered in
249
+ :mod:`sage.repl.rich_output.output_catalog`.
250
+
251
+ OUTPUT:
252
+
253
+ Returns the :mod:`sage.repl.rich_output.output_catalog`
254
+ module.
255
+
256
+ EXAMPLES::
257
+
258
+ sage: from sage.repl.rich_output import get_display_manager
259
+ sage: dm = get_display_manager()
260
+ sage: dm.types.OutputPlainText
261
+ <class 'sage.repl.rich_output.output_basic.OutputPlainText'>
262
+ """
263
+ import sage.repl.rich_output.output_catalog
264
+ return sage.repl.rich_output.output_catalog
265
+
266
+ def switch_backend(self, backend, **kwds):
267
+ """
268
+ Switch to a new backend.
269
+
270
+ INPUT:
271
+
272
+ - ``backend`` -- instance of
273
+ :class:`~sage.repl.rich_output.backend_base.BackendBase`
274
+
275
+ - ``kwds`` -- optional keyword arguments that are passed on to
276
+ the :meth:`~sage.repl.rich_output.backend_base.BackendBase.install`
277
+ method
278
+
279
+ OUTPUT: the previous backend
280
+
281
+ EXAMPLES::
282
+
283
+ sage: from sage.repl.rich_output.backend_base import BackendSimple
284
+ sage: simple = BackendSimple()
285
+ sage: from sage.repl.rich_output import get_display_manager
286
+ sage: dm = get_display_manager(); dm
287
+ The Sage display manager using the doctest backend
288
+
289
+ sage: previous = dm.switch_backend(simple)
290
+ sage: dm
291
+ The Sage display manager using the simple backend
292
+
293
+ Restore the doctest backend::
294
+
295
+ sage: dm.switch_backend(previous) is simple
296
+ True
297
+ """
298
+ from sage.repl.rich_output.backend_base import BackendBase
299
+ if not isinstance(backend, BackendBase):
300
+ raise ValueError('backend must be instance of BackendBase class')
301
+ supported = backend.supported_output()
302
+ if not any(issubclass(out, OutputPlainText) for out in supported):
303
+ raise ValueError('every backend must support plain text')
304
+ try:
305
+ self._backend.uninstall()
306
+ except AttributeError:
307
+ pass # first time we switch
308
+ # clear caches
309
+ self._output_promotions = dict()
310
+ self._supported_output = frozenset(
311
+ map(self._demote_output_class, backend.supported_output()))
312
+ # install new backend
313
+ try:
314
+ old_backend = self._backend
315
+ except AttributeError:
316
+ old_backend = None
317
+ self._backend = backend
318
+ self._backend.install(**kwds)
319
+ self._preferences = DisplayPreferences(self._backend.default_preferences())
320
+ return old_backend
321
+
322
+ @property
323
+ def preferences(self):
324
+ """
325
+ Return the preferences.
326
+
327
+ OUTPUT:
328
+
329
+ The display preferences as instance of
330
+ :class:`~sage.repl.rich_output.preferences.DisplayPreferences`.
331
+
332
+ EXAMPLES::
333
+
334
+ sage: from sage.repl.rich_output import get_display_manager
335
+ sage: dm = get_display_manager()
336
+ sage: dm.preferences
337
+ Display preferences:
338
+ * align_latex is not specified
339
+ * graphics is not specified
340
+ * supplemental_plot = never
341
+ * text is not specified
342
+ """
343
+ return self._preferences
344
+
345
+ def is_in_terminal(self):
346
+ """
347
+ Test whether the UI is meant to run in a terminal.
348
+
349
+ When this method returns ``True``, you can assume that it is
350
+ possible to use ``raw_input`` or launch external programs that
351
+ take over the input.
352
+
353
+ Otherwise, you should assume that the backend runs remotely or
354
+ in a pty controlled by another program. Then you should not
355
+ launch external programs with a (text or graphical) UI.
356
+
357
+ This is used to enable/disable interpreter consoles.
358
+
359
+ OUTPUT:
360
+
361
+ Boolean.
362
+ """
363
+ return self._backend.is_in_terminal()
364
+
365
+ def check_backend_class(self, backend_class):
366
+ """
367
+ Check that the current backend is an instance of
368
+ ``backend_class``.
369
+
370
+ This is, for example, used by the Sage IPython display
371
+ formatter to ensure that the IPython backend is in use.
372
+
373
+ INPUT:
374
+
375
+ - ``backend_class`` -- type of a backend class
376
+
377
+ OUTPUT:
378
+
379
+ This method returns nothing. A :exc:`RuntimeError` is raised if
380
+ ``backend_class`` is not the type of the current backend.
381
+
382
+ EXAMPLES::
383
+
384
+ sage: from sage.repl.rich_output.backend_base import BackendSimple
385
+ sage: from sage.repl.rich_output import get_display_manager
386
+ sage: dm = get_display_manager()
387
+ sage: dm.check_backend_class(BackendSimple)
388
+ Traceback (most recent call last):
389
+ ...
390
+ RuntimeError: check failed: current backend is invalid
391
+ """
392
+ if not isinstance(self._backend, backend_class):
393
+ raise RuntimeError('check failed: current backend is invalid')
394
+
395
+ def _demote_output_class(self, output_class):
396
+ """
397
+ Helper for :meth:`switch_backend`.
398
+
399
+ INPUT:
400
+
401
+ - ``output_class`` -- a possibly derived class from one of the
402
+ output container classes in :meth:`types`
403
+
404
+ OUTPUT: the underlying container class that it was derived from
405
+
406
+ EXAMPLES::
407
+
408
+ sage: from sage.repl.rich_output import get_display_manager
409
+ sage: dm = get_display_manager()
410
+ sage: dm._demote_output_class(dm.types.OutputPlainText)
411
+ <class 'sage.repl.rich_output.output_basic.OutputPlainText'>
412
+ """
413
+ from sage.repl.rich_output.output_basic import OutputBase
414
+ if not issubclass(output_class, OutputBase):
415
+ raise OutputTypeException(
416
+ 'invalid output container type: {0} is not subclass of OutputBase'
417
+ .format(output_class))
418
+ result = None
419
+ for type_name in dir(self.types):
420
+ if type_name.startswith('_'):
421
+ continue
422
+ tp = getattr(self.types, type_name)
423
+ if not issubclass(tp, OutputBase):
424
+ continue
425
+ if issubclass(output_class, tp):
426
+ if result is not None:
427
+ raise OutputTypeException(
428
+ '{0} inherits from multiple output classes'
429
+ .format(output_class))
430
+ else:
431
+ self._output_promotions[tp] = output_class
432
+ result = tp
433
+ if result is None:
434
+ raise OutputTypeException(
435
+ '{0} does not inherit from any known output class'
436
+ .format(output_class))
437
+ return result
438
+
439
+ def _promote_output(self, output):
440
+ """
441
+ Promote output container to a backend-specific subclass.
442
+
443
+ INPUT:
444
+
445
+ - ``output`` -- instance of a subclass of
446
+ :class:`~sage.repl.rich_output.output_basic.OutputBase`. Backend-agnostic
447
+ output container.
448
+
449
+ OUTPUT:
450
+
451
+ If the backend returned a subclass of the type of ``output``:
452
+ promote the class to the subclass and return it. Otherwise,
453
+ the unchanged output is returned.
454
+
455
+ EXAMPLES::
456
+
457
+ sage: from sage.repl.rich_output import get_display_manager
458
+ sage: dm = get_display_manager()
459
+ sage: out = dm._promote_output(dm.types.OutputPlainText('test'))
460
+ sage: type(out)
461
+ <class 'sage.repl.rich_output.output_basic.OutputPlainText'>
462
+ """
463
+ try:
464
+ specialized_class = self._output_promotions[type(output)]
465
+ except KeyError:
466
+ return output
467
+ output.__class__ = specialized_class
468
+ return output
469
+
470
+ def _preferred_text_formatter(self, obj, plain_text=None, **kwds):
471
+ r"""
472
+ Return the preferred textual representation.
473
+
474
+ INPUT:
475
+
476
+ - ``obj`` -- anything; the objects to format
477
+
478
+ - ``plain_text`` -- ``None`` (default) or string. The plain
479
+ text representation. If specified, this will be used for
480
+ plain text output.
481
+
482
+ OUTPUT:
483
+
484
+ One of
485
+ :class:`~sage.repl.rich_output.output_basic.OutputPlainText`,
486
+ :class:`~sage.repl.rich_output.output_basic.OutputAsciiArt`,
487
+ :class:`~sage.repl.rich_output.output_basic.OutputUnicodeArt`,
488
+ or
489
+ :class:`~sage.repl.rich_output.output_basic.OutputLatex`
490
+ containing the preferred textual representation of ``obj``
491
+ supported by the backend.
492
+
493
+ EXAMPLES::
494
+
495
+ sage: from sage.repl.rich_output import get_display_manager
496
+ sage: dm = get_display_manager()
497
+ sage: dm.preferences.text is None
498
+ True
499
+ sage: dm._preferred_text_formatter([1/42])
500
+ OutputPlainText container
501
+
502
+ sage: dm.preferences.text = 'plain'
503
+ sage: dm._preferred_text_formatter([1/42])
504
+ OutputPlainText container
505
+
506
+ sage: dm.preferences.text = 'ascii_art'
507
+ sage: dm._preferred_text_formatter([1/42])
508
+ OutputAsciiArt container
509
+
510
+ sage: dm.preferences.text = 'unicode_art'
511
+ sage: dm._preferred_text_formatter([1/42])
512
+ OutputUnicodeArt container
513
+
514
+ sage: dm.preferences.text = 'latex'
515
+ sage: dm._preferred_text_formatter([1/42]) # doctest backend does not support html
516
+ OutputPlainText container
517
+
518
+ sage: del dm.preferences.text # reset to default
519
+ """
520
+ want = self.preferences.text
521
+ supported = self._backend.supported_output()
522
+ if want == 'ascii_art' and OutputAsciiArt in supported:
523
+ out = self._backend.ascii_art_formatter(obj, **kwds)
524
+ if type(out) is not OutputAsciiArt:
525
+ raise OutputTypeException('backend returned wrong output type, require AsciiArt')
526
+ return out
527
+ if want == 'unicode_art' and OutputUnicodeArt in supported:
528
+ out = self._backend.unicode_art_formatter(obj, **kwds)
529
+ if type(out) is not OutputUnicodeArt:
530
+ raise OutputTypeException('backend returned wrong output type, require UnicodeArt')
531
+ return out
532
+ if want == 'latex' and OutputHtml in supported:
533
+ out = self._backend.latex_formatter(obj, **kwds)
534
+ if type(out) is not OutputHtml:
535
+ raise OutputTypeException('backend returned wrong output type, require Html')
536
+ return out
537
+ if plain_text is not None:
538
+ if type(plain_text) is not OutputPlainText:
539
+ raise OutputTypeException('backend returned wrong output type, require PlainText')
540
+ return plain_text
541
+ out = self._backend.plain_text_formatter(obj, **kwds)
542
+ if type(out) is not OutputPlainText:
543
+ raise OutputTypeException('backend returned wrong output type, require PlainText')
544
+ return out
545
+
546
+ def _call_rich_repr(self, obj, rich_repr_kwds):
547
+ """
548
+ Call the ``_rich_repr_`` method.
549
+
550
+ This method calls ``obj._rich_repr_``. If this raises an
551
+ exception, it is caught and a suitable warning is displayed.
552
+
553
+ INPUT:
554
+
555
+ - ``obj`` -- anything
556
+
557
+ - ``rich_repr_kwds`` -- dictionary; optional keyword arguments
558
+ that are passed through to ``obj._rich_repr_``
559
+
560
+ OUTPUT:
561
+
562
+ Whatever ``_rich_repr_`` returned. If it raises an exception,
563
+ then a :class:`DisplayFormatterWarning` is displayed and
564
+ ``None`` is returned.
565
+
566
+ EXAMPLES::
567
+
568
+ sage: class Foo(SageObject):
569
+ ....: def _rich_repr_(self, display_manager, **kwds):
570
+ ....: raise ValueError('reason')
571
+
572
+ sage: from sage.repl.rich_output import get_display_manager
573
+ sage: dm = get_display_manager()
574
+ sage: dm._call_rich_repr(Foo(), {})
575
+ doctest:...: ...RichReprWarning: Exception in _rich_repr_ while displaying object: reason
576
+ """
577
+ if rich_repr_kwds:
578
+ # do not ignore errors from invalid options
579
+ return obj._rich_repr_(self, **rich_repr_kwds)
580
+ try:
581
+ return obj._rich_repr_(self)
582
+ except NotImplementedError:
583
+ # don't warn on NotImplementedErrors
584
+ return None
585
+ except Exception as e:
586
+ warnings.warn(
587
+ 'Exception in _rich_repr_ while displaying object: {0}'.format(e),
588
+ RichReprWarning,
589
+ )
590
+
591
+ def _rich_output_formatter(self, obj, rich_repr_kwds):
592
+ """
593
+ Generate appropriate rich output containers.
594
+
595
+ INPUT:
596
+
597
+ - ``obj`` -- anything
598
+
599
+ - ``rich_repr_kwds`` -- dictionary; optional keyword arguments
600
+ that are passed through to ``obj._rich_repr_``
601
+
602
+ OUTPUT:
603
+
604
+ A pair of rich output containers. The first is plain text,
605
+ that is, an instance of
606
+ :class:`~sage.repl.rich_output.output_basic.OutputPlainText`. The
607
+ second is the best rich output available, subject to the
608
+ constraints of the backend.
609
+
610
+ EXAMPLES::
611
+
612
+ sage: from sage.repl.rich_output import get_display_manager
613
+ sage: dm = get_display_manager()
614
+ sage: dm._rich_output_formatter(1/2, dict())
615
+ (OutputPlainText container, OutputPlainText container)
616
+ """
617
+ rich_output = None
618
+ plain_text = None
619
+ has_rich_repr = isinstance(obj, SageObject) and hasattr(obj, '_rich_repr_')
620
+ if has_rich_repr:
621
+ rich_output = self._call_rich_repr(obj, rich_repr_kwds)
622
+ if isinstance(rich_output, OutputPlainText):
623
+ plain_text = rich_output
624
+ elif has_rich_repr:
625
+ with restricted_output(self, [OutputPlainText]):
626
+ plain_text = self._call_rich_repr(obj, rich_repr_kwds)
627
+ if plain_text is None:
628
+ plain_text = self._backend.plain_text_formatter(obj, **rich_repr_kwds)
629
+ if rich_output is None:
630
+ rich_output = self._preferred_text_formatter(
631
+ obj, plain_text=plain_text, **rich_repr_kwds)
632
+ # promote output container types to backend-specific containers
633
+ plain_text = self._promote_output(plain_text)
634
+ rich_output = self._promote_output(rich_output)
635
+ # check that the output container types are valid for the backend
636
+ supported = self._backend.supported_output()
637
+ if type(plain_text) not in supported:
638
+ raise OutputTypeException(
639
+ 'text output container not supported: {0}'.format(type(plain_text)))
640
+ if type(rich_output) not in supported:
641
+ raise OutputTypeException(
642
+ 'output container not supported: {0}'.format(type(rich_output)))
643
+ return plain_text, rich_output
644
+
645
+ def graphics_from_save(self, save_function, save_kwds,
646
+ file_extension, output_container,
647
+ figsize=None, dpi=None):
648
+ r"""
649
+ Helper to construct graphics.
650
+
651
+ This method can be used to simplify the implementation of a
652
+ ``_rich_repr_`` method of a graphics object if there is
653
+ already a function to save graphics to a file.
654
+
655
+ INPUT:
656
+
657
+ - ``save_function`` -- callable that can save graphics to a file
658
+ and accepts options like :meth:`sage.plot.graphics.Graphics.save`
659
+
660
+ - ``save_kwds`` -- dictionary; keyword arguments that are
661
+ passed to the save function
662
+
663
+ - ``file_extension`` -- string starting with ``'.'``; the file
664
+ extension of the graphics file
665
+
666
+ - ``output_container`` -- subclass of
667
+ :class:`sage.repl.rich_output.output_basic.OutputBase`. The
668
+ output container to use. Must be one of the types in
669
+ :meth:`supported_output`.
670
+
671
+ - ``figsize`` -- pair of integers (optional). The desired graphics
672
+ size in pixels. Suggested, but need not be respected by the
673
+ output.
674
+
675
+ - ``dpi`` -- integer (optional). The desired resolution in dots
676
+ per inch. Suggested, but need not be respected by the output.
677
+
678
+ OUTPUT: an instance of ``output_container``
679
+
680
+ EXAMPLES::
681
+
682
+ sage: # needs sage.plot sage.symbolic
683
+ sage: from sage.repl.rich_output import get_display_manager
684
+ sage: dm = get_display_manager()
685
+ sage: plt = plot(sin)
686
+ sage: out = dm.graphics_from_save(plt.save, dict(), '.png',
687
+ ....: dm.types.OutputImagePng)
688
+ sage: out
689
+ OutputImagePng container
690
+ sage: out.png.get().startswith(b'\x89PNG')
691
+ True
692
+ sage: out.png.filename() # random
693
+ '/home/user/.sage/temp/localhost.localdomain/23903/tmp_pu5woK.png'
694
+ """
695
+ import os
696
+ if not file_extension.startswith(os.path.extsep):
697
+ raise ValueError('file_extension must start with a period')
698
+ if output_container not in self.supported_output():
699
+ raise OutputTypeException('output_container is not supported by backend')
700
+ from sage.misc.temporary_file import tmp_filename
701
+ filename = tmp_filename(ext=file_extension)
702
+ # Call the save_function with the right arguments
703
+ kwds = dict(save_kwds)
704
+ if figsize is not None:
705
+ kwds['figsize'] = figsize
706
+ if dpi is not None:
707
+ kwds['dpi'] = dpi
708
+ save_function(filename, **kwds)
709
+ from sage.repl.rich_output.buffer import OutputBuffer
710
+ buf = OutputBuffer.from_file(filename)
711
+ return output_container(buf)
712
+
713
+ def threejs_scripts(self, online):
714
+ """
715
+ Return Three.js script tag for the current backend.
716
+
717
+ INPUT:
718
+
719
+ - ``online`` -- boolean determining script usage context
720
+
721
+ OUTPUT: string containing script tag
722
+
723
+ .. NOTE::
724
+
725
+ This base method handles ``online=True`` case only, serving CDN
726
+ script tag. Location of script for offline usage is
727
+ backend-specific.
728
+
729
+ EXAMPLES::
730
+
731
+ sage: from sage.repl.rich_output import get_display_manager
732
+ sage: get_display_manager().threejs_scripts(online=True) # needs sage.plot
733
+ '...<script src="https://cdn.jsdelivr.net/gh/sagemath/threejs-sage@...'
734
+ sage: get_display_manager().threejs_scripts(online=False) # needs sage.plot
735
+ Traceback (most recent call last):
736
+ ...
737
+ ValueError: current backend does not support
738
+ offline threejs graphics
739
+ """
740
+ from sage.features.threejs import Threejs
741
+ if online:
742
+ version = Threejs().required_version()
743
+ return """
744
+ <script src="https://cdn.jsdelivr.net/gh/sagemath/threejs-sage@{0}/build/three.min.js"></script>
745
+ """.format(version)
746
+ try:
747
+ return self._backend.threejs_offline_scripts()
748
+ except AttributeError:
749
+ raise ValueError(
750
+ 'current backend does not support offline threejs graphics')
751
+
752
+ def supported_output(self):
753
+ """
754
+ Return the output container classes that can be used.
755
+
756
+ OUTPUT:
757
+
758
+ Frozen set of subclasses of
759
+ :class:`~sage.repl.rich_output.output_basic.OutputBase`. If
760
+ the backend defines derived container classes, this method
761
+ will always return their base classes.
762
+
763
+ EXAMPLES::
764
+
765
+ sage: from sage.repl.rich_output import get_display_manager
766
+ sage: dm = get_display_manager()
767
+ sage: dm.types.OutputPlainText in dm.supported_output()
768
+ True
769
+ sage: type(dm.supported_output())
770
+ <... 'frozenset'>
771
+ """
772
+ return self._supported_output
773
+
774
+ def displayhook(self, obj):
775
+ """
776
+ Implementation of the displayhook.
777
+
778
+ Every backend must pass the value of the last statement of a
779
+ line / cell to this method. See also
780
+ :meth:`display_immediately` if you want do display rich output
781
+ while a program is running.
782
+
783
+ INPUT:
784
+
785
+ - ``obj`` -- anything; the object to be shown
786
+
787
+ OUTPUT: whatever the backend's displayhook method returned
788
+
789
+ EXAMPLES::
790
+
791
+ sage: from sage.repl.rich_output import get_display_manager
792
+ sage: dm = get_display_manager()
793
+ sage: dm.displayhook(1/2)
794
+ 1/2
795
+ """
796
+ if obj is None:
797
+ return
798
+ self._backend.set_underscore_variable(obj)
799
+ plain_text, rich_output = self._rich_output_formatter(obj, dict())
800
+ return self._backend.displayhook(plain_text, rich_output)
801
+
802
+ def display_immediately(self, obj, **rich_repr_kwds):
803
+ """
804
+ Show output without going back to the command line prompt.
805
+
806
+ This method must be called to create rich output from an
807
+ object when we are not returning to the command line prompt,
808
+ for example during program execution. Typically, it is being
809
+ called by :meth:`sage.plot.graphics.Graphics.show`.
810
+
811
+ INPUT:
812
+
813
+ - ``obj`` -- anything; the object to be shown
814
+
815
+ - ``rich_repr_kwds`` -- optional keyword arguments that are
816
+ passed through to ``obj._rich_repr_``
817
+
818
+ EXAMPLES::
819
+
820
+ sage: from sage.repl.rich_output import get_display_manager
821
+ sage: dm = get_display_manager()
822
+ sage: dm.display_immediately(1/2)
823
+ 1/2
824
+ """
825
+ plain_text, rich_output = self._rich_output_formatter(obj, rich_repr_kwds)
826
+ self._backend.display_immediately(plain_text, rich_output)
827
+
828
+
829
+ get_display_manager = DisplayManager.get_instance