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,217 @@
1
+ # sage_setup: distribution = sagemath-repl
2
+ """
3
+ The Sage ZMQ Kernel
4
+
5
+ Version of the Jupyter kernel when running Sage inside the Jupyter
6
+ notebook or remote Jupyter sessions.
7
+ """
8
+
9
+ # ***************************************************************************
10
+ # Copyright (C) 2015 Volker Braun <vbraun.name@gmail.com>
11
+ #
12
+ # Distributed under the terms of the GNU General Public License (GPL)
13
+ # as published by the Free Software Foundation; either version 2 of
14
+ # the License, or (at your option) any later version.
15
+ # https://www.gnu.org/licenses/
16
+ # ***************************************************************************
17
+
18
+ import sys
19
+ import warnings
20
+ with warnings.catch_warnings():
21
+ # When upstream pydevd (as opposed to the bundled version) is used
22
+ # with debugpy, a PEP 420 warning is emitted. Debugpy and/or
23
+ # pydevd will eventually work around this, but as of September
24
+ # 2023, hiding the warning gives us more flexibility in the
25
+ # versions of those packages that we can accept.
26
+ warnings.filterwarnings("ignore",
27
+ message=r".*pkg_resources\.declare_namespace",
28
+ category=DeprecationWarning)
29
+ from ipykernel.ipkernel import IPythonKernel
30
+
31
+ from ipykernel.zmqshell import ZMQInteractiveShell
32
+ from traitlets import Type
33
+
34
+ from sage.env import SAGE_VERSION
35
+ from sage.repl.interpreter import SageNotebookInteractiveShell
36
+ from sage.repl.ipython_extension import SageJupyterCustomizations
37
+
38
+
39
+ class SageZMQInteractiveShell(SageNotebookInteractiveShell, ZMQInteractiveShell):
40
+ pass
41
+
42
+
43
+ class SageKernel(IPythonKernel):
44
+ implementation = 'sage'
45
+ implementation_version = SAGE_VERSION
46
+
47
+ shell_class = Type(SageZMQInteractiveShell)
48
+
49
+ def __init__(self, **kwds):
50
+ """
51
+ The Sage Jupyter Kernel.
52
+
53
+ INPUT:
54
+
55
+ See the Jupyter documentation.
56
+
57
+ EXAMPLES::
58
+
59
+ sage: from sage.repl.ipython_kernel.kernel import SageKernel
60
+ sage: SageKernel.__new__(SageKernel)
61
+ <sage.repl.ipython_kernel.kernel.SageKernel object at 0x...>
62
+ """
63
+ super().__init__(**kwds)
64
+ SageJupyterCustomizations(self.shell)
65
+
66
+ @property
67
+ def banner(self):
68
+ r"""
69
+ The Sage Banner.
70
+
71
+ The value of this property is displayed in the Jupyter
72
+ notebook.
73
+
74
+ OUTPUT: string
75
+
76
+ EXAMPLES::
77
+
78
+ sage: from sage.repl.ipython_kernel.kernel import SageKernel
79
+ sage: sk = SageKernel.__new__(SageKernel)
80
+ sage: print(sk.banner)
81
+ ┌... version...
82
+ """
83
+ from sage.misc.banner import banner_text
84
+ return banner_text()
85
+
86
+ @property
87
+ def help_links(self):
88
+ r"""
89
+ Help in the Jupyter Notebook.
90
+
91
+ OUTPUT: see the Jupyter documentation
92
+
93
+ EXAMPLES::
94
+
95
+ sage: from sage.repl.ipython_kernel.kernel import SageKernel
96
+ sage: sk = SageKernel.__new__(SageKernel)
97
+ sage: sk.help_links
98
+ [{'text': 'Sage Documentation',
99
+ 'url': '.../html/en/index.html'},
100
+ ...]
101
+ """
102
+ # A Sage doc server starts when Jupyter notebook launches if the Sage
103
+ # documentation is available locally. See the corresponding code in
104
+ # src/bin/sage-notebook.
105
+
106
+ from sage.env import SAGE_DOC_SERVER_URL
107
+ from sage.env import SAGE_DOC_LOCAL_PORT as port
108
+ from sage.features.sagemath import sagemath_doc_html
109
+
110
+ if SAGE_DOC_SERVER_URL:
111
+ def doc_url(path):
112
+ return f'{SAGE_DOC_SERVER_URL}/{path}'
113
+ elif sagemath_doc_html().is_present() and int(port):
114
+ def doc_url(path):
115
+ return f'http://127.0.0.1:{port}/{path}'
116
+ else:
117
+ def doc_url(path):
118
+ return f'https://doc.sagemath.org/{path}'
119
+
120
+ return [
121
+ {
122
+ 'text': 'Sage Documentation',
123
+ 'url': doc_url('html/en/index.html'),
124
+ },
125
+ {
126
+ 'text': 'A Tour of Sage',
127
+ 'url': doc_url('html/en/a_tour_of_sage/index.html'),
128
+ },
129
+ {
130
+ 'text': 'Tutorial',
131
+ 'url': doc_url('html/en/tutorial/index.html'),
132
+ },
133
+ {
134
+ 'text': 'Thematic Tutorials',
135
+ 'url': doc_url('html/en/thematic_tutorials/index.html'),
136
+ },
137
+ {
138
+ 'text': 'PREP Tutorials',
139
+ 'url': doc_url('html/en/prep/index.html'),
140
+ },
141
+ {
142
+ 'text': 'Constructions',
143
+ 'url': doc_url('html/en/constructions/index.html'),
144
+ },
145
+ {
146
+ 'text': 'FAQ',
147
+ 'url': doc_url('html/en/faq/index.html'),
148
+ },
149
+ {
150
+ 'text': 'Reference Manual',
151
+ 'url': doc_url('html/en/reference/index.html'),
152
+ },
153
+ {
154
+ 'text': "Installation Guide",
155
+ 'url': doc_url('html/en/installation/index.html'),
156
+ },
157
+ {
158
+ 'text': "Developer Guide",
159
+ 'url': doc_url('html/en/developer/index.html'),
160
+ },
161
+ {
162
+ 'text': "Python",
163
+ 'url': "http://docs.python.org/%i.%i" % sys.version_info[:2],
164
+ },
165
+ {
166
+ 'text': "IPython",
167
+ 'url': "http://ipython.org/documentation.html",
168
+ },
169
+ {
170
+ 'text': 'Singular',
171
+ 'url': 'http://www.singular.uni-kl.de/Manual/latest/index.htm',
172
+ },
173
+ {
174
+ 'text': 'GAP',
175
+ 'url': 'http://gap-system.org/Manuals/doc/ref/chap0.html',
176
+ },
177
+ {
178
+ 'text': "NumPy",
179
+ 'url': "http://docs.scipy.org/doc/numpy/reference/",
180
+ },
181
+ {
182
+ 'text': "SciPy",
183
+ 'url': "http://docs.scipy.org/doc/scipy/reference/",
184
+ },
185
+ {
186
+ 'text': "SymPy",
187
+ 'url': 'http://docs.sympy.org/latest/index.html',
188
+ },
189
+ {
190
+ 'text': "Matplotlib",
191
+ 'url': "https://matplotlib.org/contents.html",
192
+ },
193
+ {
194
+ 'text': "Markdown",
195
+ 'url': "http://help.github.com/articles/github-flavored-markdown",
196
+ },
197
+ ]
198
+
199
+ def pre_handler_hook(self):
200
+ """
201
+ Restore the signal handlers to their default values at Sage
202
+ startup, saving the old handler at the ``saved_sigint_handler``
203
+ attribute. This is needed because Jupyter needs to change the
204
+ ``SIGINT`` handler.
205
+
206
+ See :issue:`19135`.
207
+
208
+ TESTS::
209
+
210
+ sage: from sage.repl.ipython_kernel.kernel import SageKernel
211
+ sage: k = SageKernel.__new__(SageKernel)
212
+ sage: k.pre_handler_hook()
213
+ sage: k.saved_sigint_handler
214
+ <cyfunction python_check_interrupt at ...>
215
+ """
216
+ from cysignals import init_cysignals
217
+ self.saved_sigint_handler = init_cysignals()
@@ -0,0 +1,466 @@
1
+ # sage_setup: distribution = sagemath-repl
2
+ r"""
3
+ Widgets to be used for the Sage Jupyter notebook
4
+
5
+ These are all based on widgets from ``ipywidgets``, changing or
6
+ combining existing widgets.
7
+
8
+ TESTS:
9
+
10
+ We need to setup a proper test environment for widgets::
11
+
12
+ sage: from ipywidgets.widgets.tests.utils import setup_test_comm
13
+ sage: setup_test_comm()
14
+ """
15
+
16
+ # ****************************************************************************
17
+ # Copyright (C) 2017 Jeroen Demeyer <jdemeyer@cage.ugent.be>
18
+ #
19
+ # This program is free software: you can redistribute it and/or modify
20
+ # it under the terms of the GNU General Public License as published by
21
+ # the Free Software Foundation, either version 2 of the License, or
22
+ # (at your option) any later version.
23
+ # http://www.gnu.org/licenses/
24
+ # ****************************************************************************
25
+
26
+
27
+ from ipywidgets.widgets import (IntSlider, IntRangeSlider,
28
+ FloatSlider, FloatRangeSlider, Text,
29
+ Textarea, ColorPicker, HTMLMath, Label,
30
+ HBox, VBox, ValueWidget)
31
+ from traitlets import List, Unicode, link
32
+
33
+ from sage.misc.sage_eval import sage_eval
34
+ from sage.repl.user_globals import get_globals
35
+ from sage.misc.lazy_import import lazy_import
36
+ lazy_import("sage.plot.colors", "Color")
37
+
38
+
39
+ class HTMLText(HTMLMath):
40
+ """
41
+ An HTML widget whose ``description`` is always empty.
42
+
43
+ This is used to display arbitrary HTML text in interacts without
44
+ a label. The :func:`text_control` function from SageNB is an alias
45
+ of :class:`HTMLText`.
46
+
47
+ EXAMPLES::
48
+
49
+ sage: from sage.repl.ipython_kernel.widgets import HTMLText
50
+ sage: w = HTMLText("Hello")
51
+ sage: w.description
52
+ ''
53
+ sage: w.description = "text"
54
+ sage: w.description
55
+ ''
56
+ """
57
+ @property
58
+ def description(self):
59
+ """
60
+ Always return empty string.
61
+
62
+ EXAMPLES::
63
+
64
+ sage: from sage.repl.ipython_kernel.widgets import HTMLText
65
+ sage: w = HTMLText("Hello")
66
+ sage: w.description
67
+ ''
68
+ """
69
+ return ''
70
+
71
+ @description.setter
72
+ def description(self, value):
73
+ """
74
+ Do not set anything.
75
+
76
+ EXAMPLES::
77
+
78
+ sage: from sage.repl.ipython_kernel.widgets import HTMLText
79
+ sage: w = HTMLText("Hello")
80
+ sage: w.description = "text"
81
+ sage: w.description
82
+ ''
83
+ """
84
+ pass
85
+
86
+
87
+ class TransformWidget:
88
+ """
89
+ A mixin class for a widget to transform the bare widget value for
90
+ use in interactive functions.
91
+
92
+ INPUT:
93
+
94
+ - ``transform`` -- a one-argument function which transforms the
95
+ value of the widget for use by an interactive function
96
+
97
+ - other arguments are passed to the base class
98
+
99
+ EXAMPLES::
100
+
101
+ sage: from ipywidgets import ToggleButtons
102
+ sage: from sage.repl.ipython_kernel.widgets import TransformWidget
103
+ sage: class TransformToggleButtons(TransformWidget, ToggleButtons): pass
104
+ sage: w = TransformToggleButtons(options=["pi", "e"], transform=lambda x: x + x)
105
+ sage: w
106
+ TransformToggleButtons(options=('pi', 'e'), value='pi')
107
+ sage: w.get_interact_value()
108
+ 'pipi'
109
+ """
110
+ def __init__(self, *args, **kwds):
111
+ """
112
+ Construct a :class:`TransformWidget`.
113
+
114
+ TESTS::
115
+
116
+ sage: from sage.repl.ipython_kernel.widgets import TransformWidget
117
+ sage: w = TransformWidget(transform=dict)
118
+ sage: w._TransformWidget__transform
119
+ <... 'dict'>
120
+ """
121
+ self.__transform = kwds.pop("transform", None)
122
+ return super().__init__(*args, **kwds)
123
+
124
+ def get_value(self):
125
+ """
126
+ Return ``self.value``.
127
+
128
+ This is meant to be overridden by sub-classes to change the
129
+ input of the transform function.
130
+
131
+ EXAMPLES::
132
+
133
+ sage: from ipywidgets import ColorPicker
134
+ sage: from sage.repl.ipython_kernel.widgets import TransformWidget
135
+ sage: class TransformColorPicker(TransformWidget, ColorPicker): pass
136
+ sage: TransformColorPicker(value='red').get_value()
137
+ 'red'
138
+ """
139
+ return self.value
140
+
141
+ def get_interact_value(self):
142
+ """
143
+ Return the transformed value of this widget, by calling
144
+ the ``transform`` function.
145
+
146
+ EXAMPLES::
147
+
148
+ sage: from ipywidgets import Checkbox
149
+ sage: from sage.repl.ipython_kernel.widgets import TransformWidget
150
+ sage: class TransformCheckbox(TransformWidget, Checkbox): pass
151
+ sage: w = TransformCheckbox(value=True, transform=int); w
152
+ TransformCheckbox(value=True)
153
+ sage: w.get_interact_value()
154
+ 1
155
+ """
156
+ v = self.get_value()
157
+ f = self.__transform
158
+ if f is None:
159
+ return v
160
+ else:
161
+ return f(v)
162
+
163
+
164
+ class EvalWidget(TransformWidget):
165
+ """
166
+ A mixin class for a widget to evaluate (using :func:`sage_eval`) the
167
+ widget value and possibly transform it like :class:`TransformWidget`.
168
+
169
+ EXAMPLES::
170
+
171
+ sage: from ipywidgets import ToggleButtons
172
+ sage: from sage.repl.ipython_kernel.widgets import EvalWidget
173
+ sage: class EvalToggleButtons(EvalWidget, ToggleButtons): pass
174
+ sage: w = EvalToggleButtons(options=["pi", "e"], transform=lambda x: x+x)
175
+ sage: w
176
+ EvalToggleButtons(options=('pi', 'e'), value='pi')
177
+ sage: w.get_interact_value() # needs sage.symbolic
178
+ 2*pi
179
+ """
180
+ def get_value(self):
181
+ """
182
+ Evaluate the bare widget value using :func:`sage_eval`.
183
+
184
+ EXAMPLES::
185
+
186
+ sage: from ipywidgets import Dropdown
187
+ sage: from sage.repl.ipython_kernel.widgets import EvalWidget
188
+ sage: class EvalDropdown(EvalWidget, Dropdown): pass
189
+ sage: w = EvalDropdown(options=["the_answer"], transform=RR)
190
+ sage: w
191
+ EvalDropdown(options=('the_answer',), value='the_answer')
192
+ sage: the_answer = 42
193
+ sage: w.get_value()
194
+ 42
195
+ sage: w.get_interact_value()
196
+ 42.0000000000000
197
+ """
198
+ return sage_eval(self.value, get_globals())
199
+
200
+
201
+ class TransformIntSlider(TransformWidget, IntSlider):
202
+ """
203
+ An :class:`ipywidgets.IntSlider` widget with an optional
204
+ transformation.
205
+
206
+ EXAMPLES::
207
+
208
+ sage: from sage.repl.ipython_kernel.widgets import TransformIntSlider
209
+ sage: w = TransformIntSlider(min=0, max=100, value=7, transform=lambda x: x^2)
210
+ sage: w
211
+ TransformIntSlider(value=7)
212
+ sage: w.get_interact_value()
213
+ 49
214
+ """
215
+ pass
216
+
217
+
218
+ class TransformFloatSlider(TransformWidget, FloatSlider):
219
+ """
220
+ A :class:`ipywidgets.FloatSlider` widget with an optional
221
+ transformation.
222
+
223
+ EXAMPLES::
224
+
225
+ sage: from sage.repl.ipython_kernel.widgets import TransformFloatSlider
226
+ sage: w = TransformFloatSlider(min=0, max=100, value=7, transform=lambda x: sqrt(x))
227
+ sage: w
228
+ TransformFloatSlider(value=7.0)
229
+ sage: w.get_interact_value() # needs sage.symbolic
230
+ 2.6457513110645907
231
+ """
232
+ pass
233
+
234
+
235
+ class TransformIntRangeSlider(TransformWidget, IntRangeSlider):
236
+ """
237
+ An :class:`ipywidgets.IntRangeSlider` widget with an optional
238
+ transformation.
239
+
240
+ EXAMPLES::
241
+
242
+ sage: from sage.repl.ipython_kernel.widgets import TransformIntRangeSlider
243
+ sage: w = TransformIntRangeSlider(min=0, max=100, value=(7, 9),
244
+ ....: transform=lambda x: x[1] - x[0])
245
+ sage: w
246
+ TransformIntRangeSlider(value=(7, 9))
247
+ sage: w.get_interact_value()
248
+ 2
249
+ """
250
+ pass
251
+
252
+
253
+ class TransformFloatRangeSlider(TransformWidget, FloatRangeSlider):
254
+ """
255
+ An :class:`ipywidgets.FloatRangeSlider` widget with an optional
256
+ transformation.
257
+
258
+ EXAMPLES::
259
+
260
+ sage: from sage.repl.ipython_kernel.widgets import TransformFloatRangeSlider
261
+ sage: w = TransformFloatRangeSlider(min=0, max=100, value=(7, 9),
262
+ ....: transform=lambda x: x[1] - x[0])
263
+ sage: w
264
+ TransformFloatRangeSlider(value=(7.0, 9.0))
265
+ sage: w.get_interact_value()
266
+ 2.0
267
+ """
268
+ pass
269
+
270
+
271
+ class TransformText(TransformWidget, Text):
272
+ """
273
+ A :class:`ipywidgets.Text` widget with an optional
274
+ transformation.
275
+
276
+ EXAMPLES::
277
+
278
+ sage: from sage.repl.ipython_kernel.widgets import TransformText
279
+ sage: w = TransformText(value='hello', transform=lambda x: x + x)
280
+ sage: w
281
+ TransformText(value='hello')
282
+ sage: w.get_interact_value()
283
+ 'hellohello'
284
+ """
285
+ pass
286
+
287
+
288
+ class TransformTextarea(TransformWidget, Textarea):
289
+ """
290
+ A :class:`ipywidgets.Textarea` widget with an optional
291
+ transformation.
292
+
293
+ EXAMPLES::
294
+
295
+ sage: from sage.repl.ipython_kernel.widgets import TransformTextarea
296
+ sage: w = TransformTextarea(value='hello', transform=lambda x: x + x)
297
+ sage: w
298
+ TransformTextarea(value='hello')
299
+ sage: w.get_interact_value()
300
+ 'hellohello'
301
+ """
302
+ pass
303
+
304
+
305
+ class EvalText(EvalWidget, Text):
306
+ """
307
+ A :class:`ipywidgets.Text` widget which evaluates (using
308
+ :func:`sage_eval`) its contents and applies an optional transformation.
309
+
310
+ EXAMPLES::
311
+
312
+ sage: from sage.repl.ipython_kernel.widgets import EvalText
313
+ sage: w = EvalText(value='pi', transform=lambda x: x^2)
314
+ sage: w
315
+ EvalText(value='pi')
316
+ sage: w.get_interact_value() # needs sage.symbolic
317
+ pi^2
318
+ """
319
+ pass
320
+
321
+
322
+ class EvalTextarea(EvalWidget, Textarea):
323
+ """
324
+ A :class:`ipywidgets.Textarea` widget which evaluates (using
325
+ :func:`sage_eval`) its contents and applies an optional transformation.
326
+
327
+ EXAMPLES::
328
+
329
+ sage: from sage.repl.ipython_kernel.widgets import EvalTextarea
330
+ sage: w = EvalTextarea(value='pi', transform=lambda x: x^2)
331
+ sage: w
332
+ EvalTextarea(value='pi')
333
+ sage: w.get_interact_value() # needs sage.symbolic
334
+ pi^2
335
+ """
336
+ pass
337
+
338
+
339
+ class SageColorPicker(ColorPicker):
340
+ """
341
+ A color picker widget returning a Sage :class:`Color`.
342
+
343
+ EXAMPLES::
344
+
345
+ sage: from sage.repl.ipython_kernel.widgets import SageColorPicker
346
+ sage: SageColorPicker()
347
+ SageColorPicker(value='black')
348
+ """
349
+ def get_interact_value(self):
350
+ """
351
+ Return a Sage :class:`Color` corresponding to the value of this
352
+ widget.
353
+
354
+ EXAMPLES::
355
+
356
+ sage: from sage.repl.ipython_kernel.widgets import SageColorPicker
357
+ sage: SageColorPicker().get_interact_value() # needs sage.plot
358
+ RGB color (0.0, 0.0, 0.0)
359
+ """
360
+ return Color(self.value)
361
+
362
+
363
+ class Grid(TransformWidget, HBox, ValueWidget):
364
+ """
365
+ A square grid of widgets whose value is a list of lists of the
366
+ values of the individual widgets.
367
+
368
+ This is usually created using the :func:`input_grid` function.
369
+
370
+ EXAMPLES::
371
+
372
+ sage: from ipywidgets import Text
373
+ sage: from sage.repl.ipython_kernel.widgets import Grid
374
+ sage: w = Grid(2, 2, lambda i,j: Text(value="%s,%s"%(i,j)))
375
+ sage: w
376
+ Grid(value=[['0,0', '0,1'], ['1,0', '1,1']],
377
+ children=(Label(value=''),
378
+ VBox(children=(Text(value='0,0'), Text(value='1,0'))),
379
+ VBox(children=(Text(value='0,1'), Text(value='1,1')))))
380
+ sage: w.get_interact_value()
381
+ [['0,0', '0,1'], ['1,0', '1,1']]
382
+ """
383
+ value = List()
384
+ description = Unicode()
385
+
386
+ def __init__(self, nrows, ncols, make_widget, description="", transform=None):
387
+ """
388
+ Create a :class:`Grid` widget.
389
+
390
+ INPUT:
391
+
392
+ - ``nrows``, ``ncols`` -- number of rows and columns in the grid
393
+
394
+ - ``make_widget`` -- a function of two arguments ``(i,j)``
395
+ returning the widget to be placed at position ``(i,j)``
396
+
397
+ - ``description`` -- an optional label
398
+
399
+ - ``transform`` -- an optional transformation, see :class:`TransformWidget`
400
+
401
+ EXAMPLES::
402
+
403
+ sage: from sage.repl.ipython_kernel.widgets import Grid, EvalText
404
+ sage: w = Grid(2, 2, lambda i,j: EvalText(str(j+4*i)), # needs sage.modules
405
+ ....: description="2x2 matrix", transform=matrix); w
406
+ Grid(value=[[0, 1], [4, 5]],
407
+ children=(Label(value='2x2 matrix'),
408
+ VBox(children=(EvalText(value='0'), EvalText(value='4'))),
409
+ VBox(children=(EvalText(value='1'), EvalText(value='5')))))
410
+ sage: w.get_interact_value() # needs sage.modules
411
+ [0 1]
412
+ [4 5]
413
+
414
+ TESTS::
415
+
416
+ sage: w = Grid(0, 1, lambda i,j: EvalText())
417
+ Traceback (most recent call last):
418
+ ...
419
+ ValueError: Grid requires a positive number of rows and columns
420
+ """
421
+ if nrows < 1 or ncols < 1:
422
+ raise ValueError("Grid requires a positive number of rows and columns")
423
+ super().__init__(transform=transform)
424
+
425
+ label = Label(description)
426
+ link((label, "value"), (self, "description"))
427
+
428
+ self.cols = []
429
+ for j in range(ncols):
430
+ col = VBox()
431
+ widgets = []
432
+ for i in range(nrows):
433
+ w = make_widget(i, j)
434
+ w.observe(self._update, names='value')
435
+ widgets.append(w)
436
+ col.children = widgets
437
+ self.cols.append(col)
438
+ self.children = [label] + self.cols
439
+ self._update()
440
+
441
+ def _update(self, *args):
442
+ """
443
+ Compute the ``value`` of the grid.
444
+
445
+ Thanks to traitlets magic, this is automatically called
446
+ whenever one of the child widgets changes.
447
+
448
+ EXAMPLES::
449
+
450
+ sage: from ipywidgets import Text
451
+ sage: from sage.repl.ipython_kernel.widgets import Grid
452
+ sage: w = Grid(2, 2, lambda i,j: Text(value="%s,%s"%(i,j)))
453
+ sage: w._update()
454
+ sage: w.value
455
+ [['0,0', '0,1'], ['1,0', '1,1']]
456
+ sage: w.cols[0].children[0].value = "abc"
457
+ sage: w.value
458
+ [['abc', '0,1'], ['1,0', '1,1']]
459
+ """
460
+ v = [[]]
461
+ for col in self.cols:
462
+ for i in range(len(col.children)):
463
+ if i >= len(v):
464
+ v.append([])
465
+ v[i].append(col.children[i].get_interact_value())
466
+ self.value = v