mirror of
https://src.fedoraproject.org/rpms/sagemath.git
synced 2025-04-22 03:39:03 -04:00
1696 lines
66 KiB
Diff
1696 lines
66 KiB
Diff
diff -up src/sage/repl/attach.py.orig src/sage/repl/attach.py
|
|
--- src/sage/repl/attach.py.orig 2016-08-18 13:12:59.071122164 -0400
|
|
+++ src/sage/repl/attach.py 2016-08-18 13:13:01.904122272 -0400
|
|
@@ -13,7 +13,7 @@ Check that no file clutter is produced::
|
|
sage: dir = tmp_dir()
|
|
sage: src = os.path.join(dir, 'foobar.sage')
|
|
sage: with open(src, 'w') as f:
|
|
- ....: f.write('print("<output from attached file>")\n')
|
|
+ ....: f.write('print "<output from attached file>"\n')
|
|
sage: attach(src)
|
|
<output from attached file>
|
|
sage: os.listdir(dir)
|
|
@@ -67,13 +67,11 @@ character-by-character::
|
|
# (at your option) any later version.
|
|
# http://www.gnu.org/licenses/
|
|
#*****************************************************************************
|
|
-from __future__ import print_function
|
|
|
|
import os
|
|
import six
|
|
import time
|
|
from sage.repl.load import load, load_wrap
|
|
-import sage.repl.inputhook
|
|
import sage.env
|
|
|
|
# The attached files as a dict of {filename:mtime}
|
|
@@ -165,7 +163,7 @@ def load_attach_path(path=None, replace=
|
|
['.']
|
|
sage: t_dir = tmp_dir()
|
|
sage: fullpath = os.path.join(t_dir, 'test.py')
|
|
- sage: open(fullpath, 'w').write("print(37 * 3)")
|
|
+ sage: open(fullpath, 'w').write("print 37 * 3")
|
|
sage: attach('test.py')
|
|
Traceback (most recent call last):
|
|
...
|
|
@@ -266,13 +264,6 @@ def attach(*files):
|
|
Attach a file or files to a running instance of Sage and also load
|
|
that file.
|
|
|
|
- .. NOTE::
|
|
-
|
|
- Attaching files uses the Python inputhook, which will conflict
|
|
- with other inputhook users. This generally includes GUI main loop
|
|
- integrations, for example tkinter. So you can only use tkinter or
|
|
- attach, but not both at the same time.
|
|
-
|
|
INPUT:
|
|
|
|
- ``files`` -- a list of filenames (strings) to attach.
|
|
@@ -313,9 +304,9 @@ def attach(*files):
|
|
|
|
sage: sage.repl.attach.reset()
|
|
sage: t1 = tmp_filename(ext='.py')
|
|
- sage: open(t1,'w').write("print('hello world')")
|
|
+ sage: open(t1,'w').write("print 'hello world'")
|
|
sage: t2 = tmp_filename(ext='.py')
|
|
- sage: open(t2,'w').write("print('hi there xxx')")
|
|
+ sage: open(t2,'w').write("print 'hi there xxx'")
|
|
sage: attach(t1, t2)
|
|
hello world
|
|
hi there xxx
|
|
@@ -371,7 +362,6 @@ def add_attached_file(filename):
|
|
sage: af.attached_files()
|
|
[]
|
|
"""
|
|
- sage.repl.inputhook.install()
|
|
fpath = os.path.abspath(filename)
|
|
attached[fpath] = os.path.getmtime(fpath)
|
|
|
|
@@ -389,7 +379,7 @@ def attached_files():
|
|
|
|
sage: sage.repl.attach.reset()
|
|
sage: t = tmp_filename(ext='.py')
|
|
- sage: open(t,'w').write("print('hello world')")
|
|
+ sage: open(t,'w').write("print 'hello world'")
|
|
sage: attach(t)
|
|
hello world
|
|
sage: attached_files()
|
|
@@ -415,7 +405,7 @@ def detach(filename):
|
|
|
|
sage: sage.repl.attach.reset()
|
|
sage: t = tmp_filename(ext='.py')
|
|
- sage: open(t,'w').write("print('hello world')")
|
|
+ sage: open(t,'w').write("print 'hello world'")
|
|
sage: attach(t)
|
|
hello world
|
|
sage: attached_files() == [t]
|
|
@@ -429,7 +419,7 @@ def detach(filename):
|
|
['.']
|
|
sage: t_dir = tmp_dir()
|
|
sage: fullpath = os.path.join(t_dir, 'test.py')
|
|
- sage: open(fullpath, 'w').write("print(37 * 3)")
|
|
+ sage: open(fullpath, 'w').write("print 37 * 3")
|
|
sage: load_attach_path(t_dir)
|
|
sage: attach('test.py')
|
|
111
|
|
@@ -441,7 +431,7 @@ def detach(filename):
|
|
sage: attach('test.py')
|
|
111
|
|
sage: fullpath = os.path.join(t_dir, 'test2.py')
|
|
- sage: open(fullpath, 'w').write("print(3)")
|
|
+ sage: open(fullpath, 'w').write("print 3")
|
|
sage: attach('test2.py')
|
|
3
|
|
sage: detach(attached_files())
|
|
@@ -474,8 +464,6 @@ def detach(filename):
|
|
attached.pop(fpath)
|
|
else:
|
|
raise ValueError("file '{0}' is not attached, see attached_files()".format(filename))
|
|
- if not attached:
|
|
- sage.repl.inputhook.uninstall()
|
|
|
|
def reset():
|
|
"""
|
|
@@ -485,7 +473,7 @@ def reset():
|
|
|
|
sage: sage.repl.attach.reset()
|
|
sage: t = tmp_filename(ext='.py')
|
|
- sage: open(t,'w').write("print('hello world')")
|
|
+ sage: open(t,'w').write("print 'hello world'")
|
|
sage: attach(t)
|
|
hello world
|
|
sage: attached_files() == [t]
|
|
diff -up src/sage/repl/display/fancy_repr.py.orig src/sage/repl/display/fancy_repr.py
|
|
--- src/sage/repl/display/fancy_repr.py.orig 2016-08-18 13:12:59.078122164 -0400
|
|
+++ src/sage/repl/display/fancy_repr.py 2016-08-18 13:13:01.906122272 -0400
|
|
@@ -119,7 +119,8 @@ class SomeIPythonRepr(ObjectReprABC):
|
|
.. automethod:: __call__
|
|
"""
|
|
type_repr = _type_pprinters.copy()
|
|
- del type_repr[type]
|
|
+ del type_repr[types.TypeType]
|
|
+ del type_repr[types.ClassType]
|
|
del type_repr[types.BuiltinFunctionType]
|
|
del type_repr[types.FunctionType]
|
|
del type_repr[str]
|
|
@@ -250,7 +251,7 @@ class PlainPythonRepr(ObjectReprABC):
|
|
a custom representer. Note that it is undesirable to have a
|
|
trailing newline, and if we don't display it you can't fix
|
|
it::
|
|
-
|
|
+
|
|
sage: class Newline(object):
|
|
....: def __repr__(self):
|
|
....: return 'newline\n'
|
|
@@ -316,37 +317,12 @@ class TallListRepr(ObjectReprABC):
|
|
sage: format_list = TallListRepr().format_string
|
|
sage: format_list([1, 2, identity_matrix(2)])
|
|
'[\n [1 0]\n1, 2, [0 1]\n]'
|
|
-
|
|
- Check that :trac:`18743` is fixed::
|
|
-
|
|
- sage: class Foo(object):
|
|
- ....: def __repr__(self):
|
|
- ....: return '''BBB AA RRR
|
|
- ....: B B A A R R
|
|
- ....: BBB AAAA RRR
|
|
- ....: B B A A R R
|
|
- ....: BBB A A R R'''
|
|
- ....: def _repr_option(self, key):
|
|
- ....: return key == 'ascii_art'
|
|
- sage: F = Foo()
|
|
- sage: [F, F]
|
|
- [
|
|
- BBB AA RRR BBB AA RRR
|
|
- B B A A R R B B A A R R
|
|
- BBB AAAA RRR BBB AAAA RRR
|
|
- B B A A R R B B A A R R
|
|
- BBB A A R R, BBB A A R R
|
|
- ]
|
|
"""
|
|
if not (isinstance(obj, (tuple, list)) and len(obj) > 0):
|
|
return False
|
|
ascii_art_repr = False
|
|
for o in obj:
|
|
try:
|
|
- ascii_art_repr = ascii_art_repr or o._repr_option('ascii_art')
|
|
- except (AttributeError, TypeError):
|
|
- pass
|
|
- try:
|
|
ascii_art_repr = ascii_art_repr or o.parent()._repr_option('element_ascii_art')
|
|
except (AttributeError, TypeError):
|
|
pass
|
|
diff -up src/sage/repl/display/formatter.py.orig src/sage/repl/display/formatter.py
|
|
--- src/sage/repl/display/formatter.py.orig 2016-08-18 13:12:59.083122164 -0400
|
|
+++ src/sage/repl/display/formatter.py 2016-08-18 13:13:01.907122273 -0400
|
|
@@ -97,7 +97,7 @@ class SageDisplayFormatter(DisplayFormat
|
|
self.dm.check_backend_class(BackendIPython)
|
|
|
|
def format(self, obj, include=None, exclude=None):
|
|
- r"""
|
|
+ """
|
|
Use the Sage rich output instead of IPython
|
|
|
|
INPUT/OUTPUT:
|
|
@@ -124,44 +124,9 @@ class SageDisplayFormatter(DisplayFormat
|
|
10*x + 9*x + 8*x + 7*x + 6*x + 5*x + 4*x + 3*x + 2*x + x
|
|
sage: shell.run_cell('%display default')
|
|
sage: shell.quit()
|
|
-
|
|
- TESTS::
|
|
-
|
|
- sage: import os
|
|
- sage: from sage.env import SAGE_EXTCODE
|
|
- sage: example_png = os.path.join(SAGE_EXTCODE, 'doctest', 'rich_output', 'example.png')
|
|
- sage: from sage.repl.rich_output.backend_ipython import BackendIPython
|
|
- sage: backend = BackendIPython()
|
|
- sage: shell = get_test_shell()
|
|
- sage: backend.install(shell=shell)
|
|
- sage: shell.run_cell('get_ipython().display_formatter')
|
|
- <sage.repl.display.formatter.SageDisplayFormatter object at 0x...>
|
|
- sage: shell.run_cell('from IPython.display import Image')
|
|
- sage: shell.run_cell('ipython_image = Image("{0}")'.format(example_png))
|
|
- sage: shell.run_cell('ipython_image')
|
|
- <IPython.core.display.Image object>
|
|
- sage: shell.run_cell('get_ipython().display_formatter.format(ipython_image)')
|
|
- ({u'image/png': '\x89PNG...',
|
|
- u'text/plain': u'<IPython.core.display.Image object>'},
|
|
- {})
|
|
"""
|
|
- # First, use Sage rich output if there is any
|
|
- PLAIN_TEXT = u'text/plain'
|
|
- sage_format, sage_metadata = self.dm.displayhook(obj)
|
|
- assert PLAIN_TEXT in sage_format, 'plain text is always present'
|
|
- if sage_format.keys() != [PLAIN_TEXT]:
|
|
- return sage_format, sage_metadata
|
|
- # Second, try IPython widgets (obj._ipython_display_ and type registry)
|
|
- if self.ipython_display_formatter(obj):
|
|
- return {}, {}
|
|
- # Finally, try IPython rich representation (obj._repr_foo_ methods)
|
|
- if exclude is not None:
|
|
- exclude = list(exclude) + [PLAIN_TEXT]
|
|
- ipy_format, ipy_metadata = super(SageDisplayFormatter, self).format(
|
|
- obj, include=include, exclude=exclude)
|
|
- ipy_format.update(sage_format)
|
|
- ipy_metadata.update(sage_metadata)
|
|
- return ipy_format, ipy_metadata
|
|
+ return self.dm.displayhook(obj)
|
|
+
|
|
|
|
|
|
class SagePlainTextFormatter(PlainTextFormatter):
|
|
@@ -190,7 +155,7 @@ class SagePlainTextFormatter(PlainTextFo
|
|
sage: from sage.repl.interpreter import get_test_shell
|
|
sage: shell = get_test_shell()
|
|
sage: shell.display_formatter.formatters['text/plain']
|
|
- <IPython.core.formatters.PlainTextFormatter object at 0x...>
|
|
+ <sage.repl.display.formatter.SagePlainTextFormatter object at 0x...>
|
|
sage: shell.quit()
|
|
"""
|
|
super(SagePlainTextFormatter, self).__init__(*args, **kwds)
|
|
diff -up src/sage/repl/display/jsmol_iframe.py.orig src/sage/repl/display/jsmol_iframe.py
|
|
--- src/sage/repl/display/jsmol_iframe.py.orig 2016-08-18 13:12:59.088122165 -0400
|
|
+++ src/sage/repl/display/jsmol_iframe.py 2016-08-18 13:13:01.908122273 -0400
|
|
@@ -249,7 +249,7 @@ class JSMolHtml(SageObject):
|
|
String.
|
|
|
|
EXAMPLES::
|
|
-
|
|
+
|
|
sage: from sage.repl.display.jsmol_iframe import JSMolHtml
|
|
sage: from sage.repl.rich_output.output_graphics3d import OutputSceneJmol
|
|
sage: jmol = JSMolHtml(OutputSceneJmol.example())
|
|
@@ -276,7 +276,7 @@ class JSMolHtml(SageObject):
|
|
String
|
|
|
|
EXAMPLES::
|
|
-
|
|
+
|
|
sage: from sage.repl.display.jsmol_iframe import JSMolHtml
|
|
sage: from sage.repl.rich_output.output_graphics3d import OutputSceneJmol
|
|
sage: jmol = JSMolHtml(OutputSceneJmol.example(), width=500, height=300)
|
|
diff -up src/sage/repl/display/pretty_print.py.orig src/sage/repl/display/pretty_print.py
|
|
--- src/sage/repl/display/pretty_print.py.orig 2016-08-18 13:12:59.093122165 -0400
|
|
+++ src/sage/repl/display/pretty_print.py 2016-08-18 13:13:01.909122273 -0400
|
|
@@ -74,12 +74,12 @@ class SagePrettyPrinter(PrettyPrinter):
|
|
See IPython documentation.
|
|
|
|
EXAMPLES::
|
|
-
|
|
+
|
|
sage: 123
|
|
123
|
|
|
|
IPython pretty printers::
|
|
-
|
|
+
|
|
sage: set({1, 2, 3})
|
|
{1, 2, 3}
|
|
sage: dict(zzz=123, aaa=99, xab=10) # sorted by keys
|
|
@@ -88,16 +88,20 @@ class SagePrettyPrinter(PrettyPrinter):
|
|
These are overridden in IPython in a way that we feel is somewhat
|
|
confusing, and we prefer to print them like plain Python which is
|
|
more informative. See :trac:`14466` ::
|
|
-
|
|
+
|
|
sage: 'this is a string'
|
|
'this is a string'
|
|
sage: type(123)
|
|
<type 'sage.rings.integer.Integer'>
|
|
sage: type
|
|
<type 'type'>
|
|
+ sage: [type, type]
|
|
+ [<type 'type'>, <type 'type'>]
|
|
sage: import types
|
|
- sage: type('name', (), {})
|
|
- <class '__main__.name'>
|
|
+ sage: types.ClassType('name', (), {})
|
|
+ <class __main__.name at 0x...>
|
|
+ sage: types.TypeType
|
|
+ <type 'type'>
|
|
sage: types.BuiltinFunctionType
|
|
<type 'builtin_function_or_method'>
|
|
|
|
diff -up src/sage/repl/display/util.py.orig src/sage/repl/display/util.py
|
|
--- src/sage/repl/display/util.py.orig 2016-08-18 13:12:59.099122165 -0400
|
|
+++ src/sage/repl/display/util.py 2016-08-18 13:13:01.909122273 -0400
|
|
@@ -14,7 +14,6 @@ methods elsewhere.
|
|
# the License, or (at your option) any later version.
|
|
# http://www.gnu.org/licenses/
|
|
#*****************************************************************************
|
|
-from __future__ import print_function
|
|
|
|
|
|
class TallListFormatter(object):
|
|
@@ -75,8 +74,8 @@ class TallListFormatter(object):
|
|
TESTS::
|
|
|
|
sage: from sage.repl.display.util import format_list
|
|
- sage: print(format_list.try_format(
|
|
- ....: [matrix([[1, 2, 3, 4], [5, 6, 7, 8]]) for i in xrange(7)]))
|
|
+ sage: print format_list.try_format(
|
|
+ ....: [matrix([[1, 2, 3, 4], [5, 6, 7, 8]]) for i in xrange(7)])
|
|
[
|
|
[1 2 3 4] [1 2 3 4] [1 2 3 4] [1 2 3 4] [1 2 3 4] [1 2 3 4]
|
|
[5 6 7 8], [5 6 7 8], [5 6 7 8], [5 6 7 8], [5 6 7 8], [5 6 7 8],
|
|
diff -up src/sage/repl/image.py.orig src/sage/repl/image.py
|
|
--- src/sage/repl/image.py.orig 2016-08-18 13:12:59.104122165 -0400
|
|
+++ src/sage/repl/image.py 2016-08-18 13:13:01.910122273 -0400
|
|
@@ -14,9 +14,8 @@ EXAMPLES::
|
|
sage: from sage.repl.image import Image
|
|
sage: img = Image('RGB', (256, 256), 'white')
|
|
sage: pixels = img.pixels()
|
|
- sage: for x in range(img.width()):
|
|
- ....: for y in range(img.height()):
|
|
- ....: pixels[x, y] = (x, y, 100)
|
|
+ sage: for x, y in CartesianProduct(range(img.width()), range(img.height())):
|
|
+ ....: pixels[x, y] = (x, y, 100)
|
|
sage: img
|
|
256x256px 24-bit RGB image
|
|
sage: type(img)
|
|
@@ -39,7 +38,7 @@ from sage.structure.sage_object import S
|
|
|
|
class Image(SageObject):
|
|
|
|
- def __init__(self, mode, size, color='white'):
|
|
+ def __init__(self, mode, size, color=0):
|
|
"""
|
|
Creates a new image with the given mode and size.
|
|
|
|
@@ -76,12 +75,13 @@ class Image(SageObject):
|
|
|
|
- ``size`` -- 2-tuple, containing (width, height) in pixels.
|
|
|
|
- - ``color`` -- string or tuple of numeric. What colour to use
|
|
- for the image. Default is black. If given, this should be a
|
|
- a tuple with one value per band. When creating RGB images,
|
|
- you can also use colour strings as supported by the
|
|
- ImageColor module. If the colour is None, the image is not
|
|
- initialised.
|
|
+ - ``color`` -- string or numeric. What colour to use for the
|
|
+ image. Default is black. If given, this should be a single
|
|
+ integer or floating point value for single-band modes, and a
|
|
+ tuple for multi-band modes (one value per band). When
|
|
+ creating RGB images, you can also use colour strings as
|
|
+ supported by the ImageColor module. If the colour is None,
|
|
+ the image is not initialised.
|
|
|
|
OUTPUT:
|
|
|
|
@@ -90,7 +90,7 @@ class Image(SageObject):
|
|
EXAMPLES::
|
|
|
|
sage: from sage.repl.image import Image
|
|
- sage: Image('P', (16, 16), (13,))
|
|
+ sage: Image('P', (16, 16), 13)
|
|
16x16px 8-bit Color image
|
|
"""
|
|
self._pil = PIL.Image.new(mode, size, color)
|
|
@@ -232,7 +232,7 @@ class Image(SageObject):
|
|
EXAMPLES::
|
|
|
|
sage: from sage.repl.image import Image
|
|
- sage: img = Image('P', (12, 34), (13,))
|
|
+ sage: img = Image('P', (12, 34), 13)
|
|
sage: filename = tmp_filename(ext='.png')
|
|
sage: img.save(filename)
|
|
sage: open(filename).read().startswith('\x89PNG')
|
|
diff -up src/sage/repl/interpreter.py.orig src/sage/repl/interpreter.py
|
|
--- src/sage/repl/interpreter.py.orig 2016-08-18 13:12:59.109122165 -0400
|
|
+++ src/sage/repl/interpreter.py 2016-08-18 13:13:01.911122273 -0400
|
|
@@ -76,18 +76,14 @@ Check that Cython source code appears in
|
|
sage: shell = get_test_shell()
|
|
sage: shell.run_cell('1/0')
|
|
---------------------------------------------------------------------------
|
|
- ZeroDivisionError Traceback (most recent call last)
|
|
- <ipython-input-...> in <module>()
|
|
- ----> 1 Integer(1)/Integer(0)
|
|
+ .../sage/rings/integer_ring.pyx in sage.rings.integer_ring.IntegerRing_class._div (.../cythonized/sage/rings/integer_ring.c:...)()
|
|
+ ... cdef rational.Rational x = rational.Rational.__new__(rational.Rational)
|
|
+ ... if mpz_sgn(right.value) == 0:
|
|
+ ... raise ZeroDivisionError('Rational division by zero')
|
|
+ ... mpz_set(mpq_numref(x.value), left.value)
|
|
+ ... mpz_set(mpq_denref(x.value), right.value)
|
|
<BLANKLINE>
|
|
- .../src/sage/rings/integer.pyx in sage.rings.integer.Integer.__div__ (.../cythonized/sage/rings/integer.c:...)()
|
|
- ... if type(left) is type(right):
|
|
- ... if mpz_sgn((<Integer>right).value) == 0:
|
|
- -> ... raise ZeroDivisionError("rational division by zero")
|
|
- ... x = <Rational> Rational.__new__(Rational)
|
|
- ... mpq_div_zz(x.value, (<Integer>left).value, (<Integer>right).value)
|
|
- <BLANKLINE>
|
|
- ZeroDivisionError: rational division by zero
|
|
+ ZeroDivisionError: Rational division by zero
|
|
sage: shell.quit()
|
|
"""
|
|
|
|
@@ -108,8 +104,8 @@ import re
|
|
import sys
|
|
from sage.repl.preparse import preparse
|
|
|
|
-from traitlets.config.loader import Config
|
|
-from traitlets import Bool, Type
|
|
+from IPython import Config
|
|
+from IPython.utils.traitlets import Bool, Type
|
|
|
|
from sage.env import SAGE_LOCAL
|
|
|
|
@@ -184,6 +180,10 @@ class SageShellOverride(object):
|
|
"""
|
|
Run a system command.
|
|
|
|
+ If the command is not a sage-specific binary, adjust the library
|
|
+ paths before calling system commands. See :trac:`975` for a
|
|
+ discussion of running system commands.
|
|
+
|
|
This is equivalent to the sage-native-execute shell script.
|
|
|
|
EXAMPLES::
|
|
@@ -196,12 +196,22 @@ class SageShellOverride(object):
|
|
sage: shell.system_raw('true')
|
|
sage: shell.user_ns['_exit_code']
|
|
0
|
|
+ sage: shell.system_raw('env | grep "^LD_LIBRARY_PATH=" | grep $SAGE_LOCAL')
|
|
+ sage: shell.user_ns['_exit_code']
|
|
+ 1
|
|
sage: shell.system_raw('R --version')
|
|
R version ...
|
|
sage: shell.user_ns['_exit_code']
|
|
0
|
|
sage: shell.quit()
|
|
"""
|
|
+ path = os.path.join(SAGE_LOCAL, 'bin',
|
|
+ re.split(r'[\s|;&]', cmd)[0])
|
|
+ if not os.access(path, os.X_OK):
|
|
+ libraries = 'LD_LIBRARY_PATH="$SAGE_ORIG_LD_LIBRARY_PATH";export LD_LIBRARY_PATH;'
|
|
+ if os.uname()[0]=='Darwin':
|
|
+ libraries += 'DYLD_LIBRARY_PATH="$SAGE_ORIG_DYLD_LIBRARY_PATH";export DYLD_LIBRARY_PATH;'
|
|
+ cmd = libraries+cmd
|
|
return super(SageShellOverride, self).system_raw(cmd)
|
|
|
|
|
|
@@ -362,7 +372,7 @@ class SageTestShell(SageShellOverride, T
|
|
---------------------------------------------------------------------------
|
|
ZeroDivisionError Traceback (most recent call last)
|
|
...
|
|
- ZeroDivisionError: rational division by zero
|
|
+ ZeroDivisionError: Rational division by zero
|
|
sage: rc is None
|
|
True
|
|
sage: shell.quit()
|
|
@@ -680,6 +690,10 @@ def get_test_shell():
|
|
app.shell._restart()
|
|
except AttributeError:
|
|
pass
|
|
+ # overwrite the default (console + graphics) formatter with the plain text one
|
|
+ import sage.repl.display.formatter as formatter
|
|
+ app.shell.display_formatter.formatters['text/plain'] = (
|
|
+ formatter.SagePlainTextFormatter(config=app.shell.config))
|
|
# No quit noise
|
|
app.shell.verbose_quit = False
|
|
return app.shell
|
|
@@ -721,10 +735,10 @@ class SageTerminalApp(TerminalIPythonApp
|
|
name = u'Sage'
|
|
crash_handler_class = SageCrashHandler
|
|
|
|
- test_shell = Bool(False, help='Whether the shell is a test shell')
|
|
- test_shell.tag(config=True)
|
|
- shell_class = Type(InteractiveShell, help='Type of the shell')
|
|
- shell_class.tag(config=True)
|
|
+ test_shell = Bool(False, config=True,
|
|
+ help='Whether the shell is a test shell')
|
|
+ shell_class = Type(InteractiveShell, config=True,
|
|
+ help='Type of the shell')
|
|
|
|
def load_config_file(self, *args, **kwds):
|
|
r"""
|
|
@@ -741,7 +755,7 @@ class SageTerminalApp(TerminalIPythonApp
|
|
sage: from sage.misc.temporary_file import tmp_dir
|
|
sage: from sage.repl.interpreter import SageTerminalApp
|
|
sage: d = tmp_dir()
|
|
- sage: from IPython.paths import get_ipython_dir
|
|
+ sage: from IPython.utils.path import get_ipython_dir
|
|
sage: IPYTHONDIR = get_ipython_dir()
|
|
sage: os.environ['IPYTHONDIR'] = d
|
|
sage: SageTerminalApp().load_config_file()
|
|
diff -up src/sage/repl/ipython_extension.py.orig src/sage/repl/ipython_extension.py
|
|
--- src/sage/repl/ipython_extension.py.orig 2016-08-18 13:12:59.114122166 -0400
|
|
+++ src/sage/repl/ipython_extension.py 2016-08-18 13:13:01.912122273 -0400
|
|
@@ -15,8 +15,6 @@ A Sage extension which adds sage-specifi
|
|
|
|
- ``%mode`` (like ``%maxima``, etc.)
|
|
|
|
- - ``%%cython``
|
|
-
|
|
* preparsing of input
|
|
|
|
* loading Sage library
|
|
@@ -57,13 +55,12 @@ In contrast, input to the ``%time`` magi
|
|
2 * 3^3 * 11
|
|
sage: shell.quit()
|
|
"""
|
|
-from __future__ import absolute_import
|
|
|
|
-from IPython.core.magic import Magics, magics_class, line_magic, cell_magic
|
|
+from IPython.core.magic import Magics, magics_class, line_magic
|
|
|
|
from sage.repl.load import load_wrap
|
|
+
|
|
from sage.env import SAGE_IMPORTALL, SAGE_STARTUP_FILE
|
|
-from sage.misc.lazy_import import LazyImport
|
|
|
|
@magics_class
|
|
class SageMagics(Magics):
|
|
@@ -324,38 +321,6 @@ class SageMagics(Magics):
|
|
except ValueError as err:
|
|
print(err) # do not show traceback
|
|
|
|
- @cell_magic
|
|
- def cython(self, line, cell):
|
|
- """
|
|
- Cython cell magic
|
|
-
|
|
- This is syntactic sugar on the
|
|
- :func:`~sage.misc.cython_c.cython` function.
|
|
-
|
|
- INPUT::
|
|
-
|
|
- - ``line`` -- ignored.
|
|
-
|
|
- - ``cell`` -- string. The Cython source code to process.
|
|
-
|
|
- OUTPUT:
|
|
-
|
|
- None. The Cython code is compiled and loaded.
|
|
-
|
|
- EXAMPLES::
|
|
-
|
|
- sage: from sage.repl.interpreter import get_test_shell
|
|
- sage: shell = get_test_shell()
|
|
- sage: shell.run_cell('''
|
|
- ....: %%cython
|
|
- ....: def f():
|
|
- ....: print('test')
|
|
- ....: ''')
|
|
- ....: shell.run_cell('f()')
|
|
- """
|
|
- from sage.misc.cython_c import cython_compile
|
|
- return cython_compile(cell)
|
|
-
|
|
|
|
class SageCustomizations(object):
|
|
|
|
@@ -368,12 +333,19 @@ class SageCustomizations(object):
|
|
self.auto_magics = SageMagics(shell)
|
|
self.shell.register_magics(self.auto_magics)
|
|
|
|
+ import sage.repl.display.formatter as formatter
|
|
+ self.shell.display_formatter.formatters['text/plain'] = (
|
|
+ formatter.SagePlainTextFormatter(config=shell.config))
|
|
+
|
|
import sage.misc.edit_module as edit_module
|
|
self.shell.set_hook('editor', edit_module.edit_devel)
|
|
|
|
self.init_inspector()
|
|
self.init_line_transforms()
|
|
|
|
+ import inputhook
|
|
+ inputhook.install()
|
|
+
|
|
import sage.all # until sage's import hell is fixed
|
|
|
|
self.shell.verbose_quit = True
|
|
@@ -384,12 +356,31 @@ class SageCustomizations(object):
|
|
if SAGE_IMPORTALL == 'yes':
|
|
self.init_environment()
|
|
|
|
+
|
|
def register_interface_magics(self):
|
|
"""
|
|
Register magics for each of the Sage interfaces
|
|
"""
|
|
- from sage.repl.interface_magic import InterfaceMagic
|
|
- InterfaceMagic.register_all(self.shell)
|
|
+ from sage.misc.superseded import deprecation
|
|
+ import sage.interfaces.all
|
|
+ interfaces = [(name, obj)
|
|
+ for name, obj in sage.interfaces.all.__dict__.items()
|
|
+ if isinstance(obj, sage.interfaces.interface.Interface)]
|
|
+
|
|
+ for real_name, obj in interfaces:
|
|
+ def tmp(line, name=real_name):
|
|
+ self.shell.run_cell('%s.interact()' % name)
|
|
+ tmp.__doc__ = "Interact with %s" % real_name
|
|
+ self.shell.register_magic_function(tmp, magic_name=real_name)
|
|
+
|
|
+ obj_name = obj.name()
|
|
+ if real_name != obj_name:
|
|
+ def tmp_deprecated(line, name=real_name, badname=obj_name):
|
|
+ deprecation(6288, 'Use %%%s instead of %%%s.' % (name,
|
|
+ badname))
|
|
+ self.shell.run_cell('%s.interact()' % name)
|
|
+ tmp_deprecated.__doc__ = "Interact with %s" % real_name
|
|
+ self.shell.register_magic_function(tmp_deprecated, magic_name=obj_name)
|
|
|
|
def set_quit_hook(self):
|
|
"""
|
|
@@ -426,17 +417,19 @@ class SageCustomizations(object):
|
|
# that we could override; however, IPython looks them up in
|
|
# the global :class:`IPython.core.oinspect` module namespace.
|
|
# Thus, we have to monkey-patch.
|
|
+ import sage.misc.sagedoc as sagedoc
|
|
+ import sage.misc.sageinspect as sageinspect
|
|
import IPython.core.oinspect
|
|
- IPython.core.oinspect.getdoc = LazyImport("sage.misc.sageinspect", "sage_getdoc")
|
|
- IPython.core.oinspect.getsource = LazyImport("sage.misc.sagedoc", "my_getsource")
|
|
- IPython.core.oinspect.find_file = LazyImport("sage.misc.sageinspect", "sage_getfile")
|
|
- IPython.core.oinspect.getargspec = LazyImport("sage.misc.sageinspect", "sage_getargspec")
|
|
+ IPython.core.oinspect.getdoc = sageinspect.sage_getdoc
|
|
+ IPython.core.oinspect.getsource = sagedoc.my_getsource
|
|
+ IPython.core.oinspect.find_file = sageinspect.sage_getfile
|
|
+ IPython.core.oinspect.getargspec = sageinspect.sage_getargspec
|
|
|
|
def init_line_transforms(self):
|
|
"""
|
|
Set up transforms (like the preparser).
|
|
"""
|
|
- from .interpreter import (SagePreparseTransformer,
|
|
+ from interpreter import (SagePreparseTransformer,
|
|
SagePromptTransformer)
|
|
|
|
for s in (self.shell.input_splitter, self.shell.input_transformer_manager):
|
|
diff -up src/sage/repl/ipython_kernel/install.py.orig src/sage/repl/ipython_kernel/install.py
|
|
--- src/sage/repl/ipython_kernel/install.py.orig 2016-08-18 13:12:59.119122166 -0400
|
|
+++ src/sage/repl/ipython_kernel/install.py 2016-08-18 13:13:01.912122273 -0400
|
|
@@ -1,38 +1,41 @@
|
|
"""
|
|
-Installing the SageMath Jupyter Kernel and extensions
|
|
+Installing the Sage IPython Kernel
|
|
|
|
-Kernels have to register themselves with Jupyter so that they appear
|
|
-in the Jupyter notebook's kernel drop-down. This is done by
|
|
+Kernels have to register themselves with IPython so that they appear
|
|
+in the IPython notebook's kernel drop-down. This is done by
|
|
:class:`SageKernelSpec`.
|
|
"""
|
|
|
|
import os
|
|
import errno
|
|
+import copy
|
|
+
|
|
+from IPython.kernel.kernelspec import (
|
|
+ get_kernel_spec, install_kernel_spec, NoSuchKernel)
|
|
+from IPython.utils.path import get_ipython_dir
|
|
|
|
from sage.env import (
|
|
SAGE_ROOT, SAGE_DOC, SAGE_LOCAL, SAGE_EXTCODE,
|
|
SAGE_VERSION
|
|
)
|
|
-from jupyter_core.paths import ENV_JUPYTER_PATH
|
|
-JUPYTER_PATH = ENV_JUPYTER_PATH[0]
|
|
+from sage.misc.temporary_file import tmp_dir
|
|
|
|
|
|
class SageKernelSpec(object):
|
|
|
|
def __init__(self):
|
|
"""
|
|
- Utility to manage SageMath kernels and extensions
|
|
+ Utility to manage Sage kernels
|
|
|
|
EXAMPLES::
|
|
|
|
sage: from sage.repl.ipython_kernel.install import SageKernelSpec
|
|
sage: spec = SageKernelSpec()
|
|
sage: spec._display_name # random output
|
|
- 'SageMath 6.9'
|
|
+ 'Sage 6.6.beta2'
|
|
"""
|
|
- self._display_name = 'SageMath {0}'.format(SAGE_VERSION)
|
|
- self.nbextensions_dir = os.path.join(JUPYTER_PATH, "nbextensions")
|
|
- self.kernel_dir = os.path.join(JUPYTER_PATH, "kernels", self.identifier())
|
|
+ self._display_name = 'Sage {0}'.format(SAGE_VERSION)
|
|
+ self._ipython_dir = get_ipython_dir()
|
|
self._mkdirs()
|
|
|
|
def _mkdirs(self):
|
|
@@ -44,33 +47,40 @@ class SageKernelSpec(object):
|
|
sage: from sage.repl.ipython_kernel.install import SageKernelSpec
|
|
sage: spec = SageKernelSpec()
|
|
sage: spec._mkdirs()
|
|
- sage: os.path.isdir(spec.nbextensions_dir)
|
|
+ sage: nbextensions = os.path.join(spec._ipython_dir, 'nbextensions')
|
|
+ sage: os.path.exists(nbextensions)
|
|
True
|
|
"""
|
|
- def mkdir_p(path):
|
|
+ def mkdir_p(*path_components):
|
|
+ path = os.path.join(*path_components)
|
|
try:
|
|
os.makedirs(path)
|
|
- except OSError:
|
|
- if not os.path.isdir(path):
|
|
+ except OSError as err:
|
|
+ if err.errno == errno.EEXIST and os.path.isdir(path):
|
|
+ pass
|
|
+ else:
|
|
raise
|
|
- mkdir_p(self.nbextensions_dir)
|
|
- mkdir_p(self.kernel_dir)
|
|
+ mkdir_p(self._ipython_dir, 'nbextensions')
|
|
|
|
@classmethod
|
|
- def identifier(cls):
|
|
+ def identifier(self):
|
|
"""
|
|
- Internal identifier for the SageMath kernel
|
|
+ Internal identifier for the Sage kernel
|
|
+
|
|
+ OUTPUT:
|
|
|
|
- OUTPUT: the string ``"sagemath"``.
|
|
+ String.
|
|
|
|
EXAMPLES::
|
|
|
|
sage: from sage.repl.ipython_kernel.install import SageKernelSpec
|
|
- sage: SageKernelSpec.identifier()
|
|
- 'sagemath'
|
|
+ sage: SageKernelSpec.identifier() # random output
|
|
+ 'sage_6_6_beta3'
|
|
+ sage: SageKernelSpec.identifier().startswith('sage_')
|
|
+ True
|
|
"""
|
|
- return 'sagemath'
|
|
-
|
|
+ return 'Sage {0}'.format(SAGE_VERSION).lower().replace(' ', '_').replace('.', '_')
|
|
+
|
|
def symlink(self, src, dst):
|
|
"""
|
|
Symlink ``src`` to ``dst``
|
|
@@ -95,48 +105,38 @@ class SageKernelSpec(object):
|
|
if err.errno == errno.EEXIST:
|
|
return
|
|
os.symlink(src, dst)
|
|
-
|
|
+
|
|
def use_local_mathjax(self):
|
|
"""
|
|
- Symlink SageMath's Mathjax install to the Jupyter notebook.
|
|
+ Symlink Sage's Mathjax Install to the IPython notebook.
|
|
|
|
EXAMPLES::
|
|
|
|
sage: from sage.repl.ipython_kernel.install import SageKernelSpec
|
|
+ sage: from IPython.utils.path import get_ipython_dir
|
|
sage: spec = SageKernelSpec()
|
|
sage: spec.use_local_mathjax()
|
|
- sage: mathjax = os.path.join(spec.nbextensions_dir, 'mathjax')
|
|
- sage: os.path.isdir(mathjax)
|
|
+ sage: ipython_dir = get_ipython_dir()
|
|
+ sage: mathjax = os.path.join(ipython_dir, 'nbextensions', 'mathjax')
|
|
+ sage: os.path.exists(mathjax)
|
|
True
|
|
"""
|
|
src = os.path.join(SAGE_LOCAL, 'share', 'mathjax')
|
|
- dst = os.path.join(self.nbextensions_dir, 'mathjax')
|
|
+ dst = os.path.join(self._ipython_dir, 'nbextensions', 'mathjax')
|
|
self.symlink(src, dst)
|
|
|
|
def use_local_jsmol(self):
|
|
- """
|
|
- Symlink jsmol to the Jupyter notebook.
|
|
-
|
|
- EXAMPLES::
|
|
-
|
|
- sage: from sage.repl.ipython_kernel.install import SageKernelSpec
|
|
- sage: spec = SageKernelSpec()
|
|
- sage: spec.use_local_jsmol()
|
|
- sage: jsmol = os.path.join(spec.nbextensions_dir, 'jsmol')
|
|
- sage: os.path.isdir(jsmol)
|
|
- True
|
|
- """
|
|
src = os.path.join(SAGE_LOCAL, 'share', 'jsmol')
|
|
- dst = os.path.join(self.nbextensions_dir, 'jsmol')
|
|
+ dst = os.path.join(self._ipython_dir, 'nbextensions', 'jsmol')
|
|
self.symlink(src, dst)
|
|
|
|
def _kernel_cmd(self):
|
|
"""
|
|
- Helper to construct the SageMath kernel command.
|
|
-
|
|
+ Helper to construct the Sage kernel command.
|
|
+
|
|
OUTPUT:
|
|
|
|
- List of strings. The command to start a new SageMath kernel.
|
|
+ List of strings. The command to start a new Sage kernel.
|
|
|
|
EXAMPLES::
|
|
|
|
@@ -144,7 +144,7 @@ class SageKernelSpec(object):
|
|
sage: spec = SageKernelSpec()
|
|
sage: spec._kernel_cmd()
|
|
['/.../sage',
|
|
- '--python',
|
|
+ '-python',
|
|
'-m',
|
|
'sage.repl.ipython_kernel',
|
|
'-f',
|
|
@@ -152,34 +152,40 @@ class SageKernelSpec(object):
|
|
"""
|
|
return [
|
|
os.path.join(SAGE_ROOT, 'sage'),
|
|
- '--python',
|
|
+ '-python',
|
|
'-m', 'sage.repl.ipython_kernel',
|
|
'-f', '{connection_file}',
|
|
]
|
|
-
|
|
+
|
|
def kernel_spec(self):
|
|
"""
|
|
Return the kernel spec as Python dictionary
|
|
|
|
OUTPUT:
|
|
|
|
- A dictionary. See the Jupyter documentation for details.
|
|
+ A dictionary. See the IPython documentation for details.
|
|
|
|
EXAMPLES::
|
|
|
|
sage: from sage.repl.ipython_kernel.install import SageKernelSpec
|
|
sage: spec = SageKernelSpec()
|
|
sage: spec.kernel_spec()
|
|
- {'argv': ..., 'display_name': 'SageMath ...'}
|
|
+ {'argv': ..., 'display_name': 'Sage ...'}
|
|
"""
|
|
return dict(
|
|
argv=self._kernel_cmd(),
|
|
display_name=self._display_name,
|
|
)
|
|
-
|
|
+
|
|
def _install_spec(self):
|
|
"""
|
|
- Install the SageMath Jupyter kernel
|
|
+ Install the Sage IPython kernel
|
|
+
|
|
+ It is safe to call this method multiple times, only one Sage
|
|
+ kernel spec is ever installed for any given Sage
|
|
+ version. However, it resets the IPython kernel spec directory
|
|
+ so additional resources symlinked there are lost. See
|
|
+ :meth:`symlink_resources`.
|
|
|
|
EXAMPLES::
|
|
|
|
@@ -187,17 +193,21 @@ class SageKernelSpec(object):
|
|
sage: spec = SageKernelSpec()
|
|
sage: spec._install_spec() # not tested
|
|
"""
|
|
- jsonfile = os.path.join(self.kernel_dir, "kernel.json")
|
|
import json
|
|
- with open(jsonfile, 'w') as f:
|
|
+ temp = tmp_dir()
|
|
+ kernel_spec = os.path.join(temp, 'kernel.json')
|
|
+ with open(kernel_spec, 'w') as f:
|
|
json.dump(self.kernel_spec(), f)
|
|
+ identifier = self.identifier()
|
|
+ install_kernel_spec(temp, identifier, user=True, replace=True)
|
|
+ self._spec = get_kernel_spec(identifier)
|
|
|
|
def _symlink_resources(self):
|
|
"""
|
|
Symlink miscellaneous resources
|
|
|
|
- This method symlinks additional resources (like the SageMath
|
|
- documentation) into the SageMath kernel directory. This is
|
|
+ This method symlinks additional resources (like the Sage
|
|
+ documentation) into the Sage kernel directory. This is
|
|
necessary to make the help links in the notebook work.
|
|
|
|
EXAMPLES::
|
|
@@ -207,23 +217,25 @@ class SageKernelSpec(object):
|
|
sage: spec._install_spec() # not tested
|
|
sage: spec._symlink_resources() # not tested
|
|
"""
|
|
+ assert self._spec, 'call _install_spec() first'
|
|
+ spec_dir = self._spec.resource_dir
|
|
path = os.path.join(SAGE_EXTCODE, 'notebook-ipython')
|
|
for filename in os.listdir(path):
|
|
self.symlink(
|
|
os.path.join(path, filename),
|
|
- os.path.join(self.kernel_dir, filename)
|
|
+ os.path.join(spec_dir, filename)
|
|
)
|
|
self.symlink(
|
|
- os.path.join(SAGE_DOC, 'html', 'en'),
|
|
- os.path.join(self.kernel_dir, 'doc')
|
|
+ os.path.join(SAGE_DOC, 'output', 'html', 'en'),
|
|
+ os.path.join(spec_dir, 'doc')
|
|
)
|
|
-
|
|
+
|
|
@classmethod
|
|
def update(cls):
|
|
"""
|
|
- Configure the Jupyter notebook for the SageMath kernel
|
|
-
|
|
- This method does everything necessary to use the SageMath kernel,
|
|
+ Configure the IPython notebook for the Sage kernel
|
|
+
|
|
+ This method does everything necessary to use the Sage kernel,
|
|
you should never need to call any of the other methods
|
|
directly.
|
|
|
|
@@ -231,7 +243,7 @@ class SageKernelSpec(object):
|
|
|
|
sage: from sage.repl.ipython_kernel.install import SageKernelSpec
|
|
sage: spec = SageKernelSpec()
|
|
- sage: spec.update() # not tested
|
|
+ sage: spec.update()
|
|
"""
|
|
instance = cls()
|
|
instance.use_local_mathjax()
|
|
@@ -239,18 +251,13 @@ class SageKernelSpec(object):
|
|
instance._install_spec()
|
|
instance._symlink_resources()
|
|
|
|
-
|
|
-def have_prerequisites(debug=True):
|
|
+
|
|
+def have_prerequisites():
|
|
"""
|
|
- Check that we have all prerequisites to run the Jupyter notebook.
|
|
+ Check that we have all prerequisites to run the IPython notebook.
|
|
|
|
- In particular, the Jupyter notebook requires OpenSSL whether or
|
|
- not you are using https. See :trac:`17318`.
|
|
-
|
|
- INPUT:
|
|
-
|
|
- ``debug`` -- boolean (default: ``True``). Whether to print debug
|
|
- information in case that prerequisites are missing.
|
|
+ In particular, the IPython notebook requires OpenSSL whether or
|
|
+ not you are using https. See trac:`17318`.
|
|
|
|
OUTPUT:
|
|
|
|
@@ -259,14 +266,15 @@ def have_prerequisites(debug=True):
|
|
EXAMPLES::
|
|
|
|
sage: from sage.repl.ipython_kernel.install import have_prerequisites
|
|
- sage: have_prerequisites(debug=False) in [True, False]
|
|
+ sage: have_prerequisites() in [True, False]
|
|
True
|
|
"""
|
|
try:
|
|
- from notebook.notebookapp import NotebookApp
|
|
+ from IPython.html.notebookapp import NotebookApp
|
|
return True
|
|
- except ImportError:
|
|
- if debug:
|
|
- import traceback
|
|
- traceback.print_exc()
|
|
+ except ImportError as err:
|
|
return False
|
|
+
|
|
+
|
|
+
|
|
+
|
|
diff -up src/sage/repl/ipython_kernel/kernel.py.orig src/sage/repl/ipython_kernel/kernel.py
|
|
--- src/sage/repl/ipython_kernel/kernel.py.orig 2016-08-18 13:12:59.125122166 -0400
|
|
+++ src/sage/repl/ipython_kernel/kernel.py 2016-08-18 13:13:01.913122273 -0400
|
|
@@ -1,8 +1,8 @@
|
|
"""
|
|
The Sage ZMQ Kernel
|
|
|
|
-Version of the Jupyter kernel when running Sage inside the Jupyter
|
|
-notebook or remote Jupyter sessions.
|
|
+Version of the IPython kernel when running Sage inside the IPython
|
|
+notebook or remote IPython sessions.
|
|
"""
|
|
|
|
#*****************************************************************************
|
|
@@ -15,9 +15,9 @@ notebook or remote Jupyter sessions.
|
|
#*****************************************************************************
|
|
|
|
import sys
|
|
-from ipykernel.ipkernel import IPythonKernel
|
|
-from ipykernel.zmqshell import ZMQInteractiveShell
|
|
-from traitlets import Type
|
|
+from IPython.kernel.zmq.ipkernel import IPythonKernel
|
|
+from IPython.kernel.zmq.zmqshell import ZMQInteractiveShell
|
|
+from IPython.utils.traitlets import Type
|
|
|
|
from sage.env import SAGE_VERSION, SAGE_EXTCODE, SAGE_DOC
|
|
from sage.repl.interpreter import SageNotebookInteractiveShell
|
|
@@ -27,7 +27,7 @@ class SageZMQInteractiveShell(SageNotebo
|
|
pass
|
|
|
|
|
|
-class SageKernel(IPythonKernel):
|
|
+class SageKernel(IPythonKernel):
|
|
implementation = 'sage'
|
|
implementation_version = SAGE_VERSION
|
|
|
|
@@ -35,11 +35,11 @@ class SageKernel(IPythonKernel):
|
|
|
|
def __init__(self, **kwds):
|
|
"""
|
|
- The Sage Jupyter Kernel
|
|
+ The Sage IPython Kernel
|
|
|
|
INPUT:
|
|
|
|
- See the Jupyter documentation
|
|
+ See the IPython documentation
|
|
|
|
EXAMPLES::
|
|
|
|
@@ -54,8 +54,8 @@ class SageKernel(IPythonKernel):
|
|
def banner(self):
|
|
r"""
|
|
The Sage Banner
|
|
-
|
|
- The value of this property is displayed in the Jupyter
|
|
+
|
|
+ The value of this property is displayed in the IPython
|
|
notebook.
|
|
|
|
OUTPUT:
|
|
@@ -67,7 +67,7 @@ class SageKernel(IPythonKernel):
|
|
sage: from sage.repl.ipython_kernel.kernel import SageKernel
|
|
sage: sk = SageKernel.__new__(SageKernel)
|
|
sage: sk.banner
|
|
- '...SageMath version...'
|
|
+ '\xe2\x94\x8c\xe2...SageMath Version...'
|
|
"""
|
|
from sage.misc.banner import banner_text
|
|
return banner_text()
|
|
@@ -75,16 +75,11 @@ class SageKernel(IPythonKernel):
|
|
@property
|
|
def help_links(self):
|
|
r"""
|
|
- Help in the Jupyter Notebook
|
|
-
|
|
+ Help in the IPython Notebook
|
|
+
|
|
OUTPUT:
|
|
|
|
- See the Jupyter documentation.
|
|
-
|
|
- .. NOTE::
|
|
-
|
|
- Urls starting with "kernelspecs" are prepended by the
|
|
- browser with the appropriate path.
|
|
+ See the IPython documentation.
|
|
|
|
EXAMPLES::
|
|
|
|
@@ -92,16 +87,16 @@ class SageKernel(IPythonKernel):
|
|
sage: sk = SageKernel.__new__(SageKernel)
|
|
sage: sk.help_links
|
|
[{'text': 'Sage Documentation',
|
|
- 'url': 'kernelspecs/sagemath/doc/index.html'},
|
|
+ 'url': '/kernelspecs/sage_.../doc/index.html'},
|
|
...]
|
|
"""
|
|
from sage.repl.ipython_kernel.install import SageKernelSpec
|
|
identifier = SageKernelSpec.identifier()
|
|
- kernel_url = lambda x: 'kernelspecs/{0}/{1}'.format(identifier, x)
|
|
+ kernel_url = lambda x: '/kernelspecs/{0}/{1}'.format(identifier, x)
|
|
return [
|
|
{
|
|
'text': 'Sage Documentation',
|
|
- 'url': kernel_url('doc/index.html'),
|
|
+ 'url': kernel_url('doc/index.html')
|
|
},
|
|
{
|
|
'text': 'Sage Tutorial',
|
|
@@ -124,7 +119,7 @@ class SageKernel(IPythonKernel):
|
|
'url': kernel_url('doc/reference/index.html'),
|
|
},
|
|
{
|
|
- 'text': "Developer's Guide",
|
|
+ 'text': 'Developers Guide',
|
|
'url': kernel_url('doc/developer/index.html'),
|
|
},
|
|
{
|
|
@@ -164,7 +159,3 @@ class SageKernel(IPythonKernel):
|
|
'url': "http://help.github.com/articles/github-flavored-markdown",
|
|
},
|
|
]
|
|
-
|
|
- def pre_handler_hook(self):
|
|
- from cysignals import init_cysignals
|
|
- self.saved_sigint_handler = init_cysignals()
|
|
diff -up src/sage/repl/ipython_kernel/__main__.py.orig src/sage/repl/ipython_kernel/__main__.py
|
|
--- src/sage/repl/ipython_kernel/__main__.py.orig 2016-08-18 13:12:59.131122166 -0400
|
|
+++ src/sage/repl/ipython_kernel/__main__.py 2016-08-18 13:13:01.913122273 -0400
|
|
@@ -1,3 +1,3 @@
|
|
-from ipykernel.kernelapp import IPKernelApp
|
|
+from IPython.kernel.zmq.kernelapp import IPKernelApp
|
|
from sage.repl.ipython_kernel.kernel import SageKernel
|
|
IPKernelApp.launch_instance(kernel_class=SageKernel)
|
|
diff -up src/sage/repl/preparse.py.orig src/sage/repl/preparse.py
|
|
--- src/sage/repl/preparse.py.orig 2016-08-18 13:12:59.137122166 -0400
|
|
+++ src/sage/repl/preparse.py 2016-08-18 13:13:01.914122273 -0400
|
|
@@ -216,7 +216,7 @@ Behind the scenes what happens is the fo
|
|
# (at your option) any later version.
|
|
# http://www.gnu.org/licenses/
|
|
#*****************************************************************************
|
|
-from __future__ import print_function
|
|
+
|
|
|
|
import os
|
|
import re
|
|
@@ -321,9 +321,9 @@ def strip_string_literals(code, state=No
|
|
'[%(L1)s, %(L2)s, %(L3)s, %(L4)s]'
|
|
sage: literals
|
|
{'L1': "'a'", 'L2': '"b"', 'L3': "'c'", 'L4': '"d\\""'}
|
|
- sage: print(s % literals)
|
|
+ sage: print s % literals
|
|
['a', "b", 'c', "d\""]
|
|
- sage: print(strip_string_literals(r'-"\\\""-"\\"-')[0])
|
|
+ sage: print strip_string_literals(r'-"\\\""-"\\"-')[0]
|
|
-%(L1)s-%(L2)s-
|
|
|
|
Triple-quotes are handled as well::
|
|
@@ -331,7 +331,7 @@ def strip_string_literals(code, state=No
|
|
sage: s, literals, state = strip_string_literals("[a, '''b''', c, '']")
|
|
sage: s
|
|
'[a, %(L1)s, c, %(L2)s]'
|
|
- sage: print(s % literals)
|
|
+ sage: print s % literals
|
|
[a, '''b''', c, '']
|
|
|
|
Comments are substitute too::
|
|
@@ -449,9 +449,8 @@ def containing_block(code, ix, delimiter
|
|
sage: s = "factor(next_prime(L[5]+1))"
|
|
sage: s[22]
|
|
'+'
|
|
- sage: start, end = containing_block(s, 22)
|
|
- sage: start, end
|
|
- (17, 25)
|
|
+ sage: start, end = containing_block(s, 22); print start, end
|
|
+ 17 25
|
|
sage: s[start:end]
|
|
'(L[5]+1)'
|
|
sage: s[20]
|
|
@@ -524,9 +523,9 @@ def parse_ellipsis(code, preparse_step=T
|
|
sage: [1.0..2.0]
|
|
[1.00000000000000, 2.00000000000000]
|
|
|
|
- TESTS:
|
|
+ TESTS:
|
|
|
|
- Check that nested ellipsis is processed correctly (:trac:`17378`)::
|
|
+ Check that nested ellipsis is processed correctly (:trac:`17378`)::
|
|
|
|
sage: preparse('[1,..,2,..,len([1..3])]')
|
|
'(ellipsis_range(Integer(1),Ellipsis,Integer(2),Ellipsis,len((ellipsis_range(Integer(1),Ellipsis,Integer(3))))))'
|
|
@@ -586,9 +585,9 @@ def extract_numeric_literals(code):
|
|
|
|
sage: from sage.repl.preparse import extract_numeric_literals
|
|
sage: code, nums = extract_numeric_literals("1.2 + 5")
|
|
- sage: print(code)
|
|
+ sage: print code
|
|
_sage_const_1p2 + _sage_const_5
|
|
- sage: print(nums)
|
|
+ sage: print nums
|
|
{'_sage_const_1p2': "RealNumber('1.2')", '_sage_const_5': 'Integer(5)'}
|
|
|
|
sage: extract_numeric_literals("[1, 1.1, 1e1, -1e-1, 1.]")[0]
|
|
@@ -662,9 +661,9 @@ def preparse_numeric_literals(code, extr
|
|
sage: preparse_numeric_literals("0x10.sqrt()")
|
|
'Integer(0x10).sqrt()'
|
|
sage: preparse_numeric_literals('0o100')
|
|
- 'Integer(0o100)'
|
|
+ "Integer('100', 8)"
|
|
sage: preparse_numeric_literals('0b111001')
|
|
- 'Integer(0b111001)'
|
|
+ "Integer('111001', 2)"
|
|
sage: preparse_numeric_literals('0xe')
|
|
'Integer(0xe)'
|
|
sage: preparse_numeric_literals('0xEAR')
|
|
@@ -721,18 +720,25 @@ def preparse_numeric_literals(code, extr
|
|
end += 1
|
|
num += '.'
|
|
|
|
- num_name = numeric_literal_prefix + num.replace('.', 'p').replace('-', 'n').replace('+', '')
|
|
|
|
- if 'J' in postfix:
|
|
- num_make = "ComplexNumber(0, '%s')" % num
|
|
- num_name += 'j'
|
|
- elif len(num) < 2 or num[1] in 'oObBxX':
|
|
- num_make = "Integer(%s)" % num
|
|
- elif '.' in num or 'e' in num or 'E' in num:
|
|
- num_make = "RealNumber('%s')" % num
|
|
- elif num[0] == "0":
|
|
- num_make = "Integer('%s')" % num
|
|
+ if len(num)>2 and num[1] in 'oObBxX':
|
|
+ # Py3 oct and bin support
|
|
+ num_name = numeric_literal_prefix + num
|
|
+ if num[1] in 'bB':
|
|
+ num_make = "Integer('%s', 2)" % num[2:]
|
|
+ elif num[1] in 'oO':
|
|
+ num_make = "Integer('%s', 8)" % num[2:]
|
|
+ else:
|
|
+ num_make = "Integer(%s)" % num
|
|
+ elif '.' in num or 'e' in num or 'E' in num or 'J' in postfix:
|
|
+ num_name = numeric_literal_prefix + num.replace('.', 'p').replace('-', 'n').replace('+', '')
|
|
+ if 'J' in postfix:
|
|
+ num_make = "ComplexNumber(0, '%s')" % num
|
|
+ num_name += 'j'
|
|
+ else:
|
|
+ num_make = "RealNumber('%s')" % num
|
|
else:
|
|
+ num_name = numeric_literal_prefix + num
|
|
num_make = "Integer(%s)" % num
|
|
|
|
literals[num_name] = num_make
|
|
@@ -1100,7 +1106,7 @@ def preparse(line, reset=True, do_time=F
|
|
'a * BackslashOperator() * b \\'
|
|
|
|
sage: preparse("time R.<x> = ZZ[]", do_time=True)
|
|
- '__time__=misc.cputime(); __wall__=misc.walltime(); R = ZZ[\'x\']; print("Time: CPU %.2f s, Wall: %.2f s"%(misc.cputime(__time__), misc.walltime(__wall__))); (x,) = R._first_ngens(1)'
|
|
+ '__time__=misc.cputime(); __wall__=misc.walltime(); R = ZZ[\'x\']; print "Time: CPU %.2f s, Wall: %.2f s"%(misc.cputime(__time__), misc.walltime(__wall__)); (x,) = R._first_ngens(1)'
|
|
"""
|
|
global quote_state
|
|
if reset:
|
|
@@ -1171,8 +1177,8 @@ def preparse(line, reset=True, do_time=F
|
|
if do_time:
|
|
# Time keyword
|
|
L = re.sub(r';time;(\s*)(\S[^;]*)',
|
|
- r';\1__time__=misc.cputime(); __wall__=misc.walltime(); \2; print(' +
|
|
- '"Time: CPU %%.2f s, Wall: %%.2f s"%%(misc.cputime(__time__), misc.walltime(__wall__)))',
|
|
+ r';\1__time__=misc.cputime(); __wall__=misc.walltime(); \2; print ' +
|
|
+ '"Time: CPU %%.2f s, Wall: %%.2f s"%%(misc.cputime(__time__), misc.walltime(__wall__))',
|
|
L)
|
|
|
|
# Remove extra ;'s
|
|
@@ -1216,7 +1222,7 @@ def preparse_file(contents, globals=None
|
|
sage: from sage.repl.preparse import preparse_file
|
|
sage: lots_of_numbers = "[%s]" % ", ".join(str(i) for i in range(3000))
|
|
sage: _ = preparse_file(lots_of_numbers)
|
|
- sage: print(preparse_file("type(100r), type(100)"))
|
|
+ sage: print preparse_file("type(100r), type(100)")
|
|
_sage_const_100 = Integer(100)
|
|
type(100 ), type(_sage_const_100 )
|
|
"""
|
|
@@ -1424,10 +1430,10 @@ def handle_encoding_declaration(contents
|
|
|
|
Two hash marks are okay; this shows up in SageTeX-generated scripts::
|
|
|
|
- sage: contents = '## -*- coding: utf-8 -*-\nimport os, sys\nprint(x)'
|
|
+ sage: contents = '## -*- coding: utf-8 -*-\nimport os, sys\nprint x'
|
|
sage: handle_encoding_declaration(contents, sys.stdout)
|
|
## -*- coding: utf-8 -*-
|
|
- 'import os, sys\nprint(x)'
|
|
+ 'import os, sys\nprint x'
|
|
|
|
When the encoding declaration doesn't match the specification, we
|
|
spit out a default UTF-8 encoding.
|
|
@@ -1454,24 +1460,24 @@ def handle_encoding_declaration(contents
|
|
'#!/usr/local/bin/python\nimport os, sys'
|
|
|
|
|
|
- NOTES:
|
|
+ NOTES::
|
|
|
|
- - PEP 263: http://www.python.org/dev/peps/pep-0263/
|
|
+ PEP 263: http://www.python.org/dev/peps/pep-0263/
|
|
|
|
- - PEP 263 says that Python will interpret a UTF-8 byte order mark
|
|
- as a declaration of UTF-8 encoding, but I don't think we do
|
|
- that; this function only sees a Python string so it can't
|
|
- account for a BOM.
|
|
+ PEP 263 says that Python will interpret a UTF-8 byte order mark
|
|
+ as a declaration of UTF-8 encoding, but I don't think we do
|
|
+ that; this function only sees a Python string so it can't
|
|
+ account for a BOM.
|
|
|
|
- - We default to UTF-8 encoding even though PEP 263 says that
|
|
- Python files should default to ASCII.
|
|
+ We default to UTF-8 encoding even though PEP 263 says that
|
|
+ Python files should default to ASCII.
|
|
|
|
- - Also see http://docs.python.org/ref/encodings.html.
|
|
+ Also see http://docs.python.org/ref/encodings.html.
|
|
|
|
- AUTHORS:
|
|
+ AUTHORS::
|
|
|
|
- - Lars Fischer
|
|
- - Dan Drake (2010-12-08, rewrite for :trac:`10440`)
|
|
+ - Lars Fischer
|
|
+ - Dan Drake (2010-12-08, rewrite for ticket #10440)
|
|
"""
|
|
lines = contents.splitlines()
|
|
for num, line in enumerate(lines[:2]):
|
|
diff -up src/sage/repl/rich_output/backend_base.py.orig src/sage/repl/rich_output/backend_base.py
|
|
--- src/sage/repl/rich_output/backend_base.py.orig 2016-08-18 13:12:59.143122167 -0400
|
|
+++ src/sage/repl/rich_output/backend_base.py 2016-08-18 13:14:03.167124618 -0400
|
|
@@ -47,7 +47,6 @@ EXAMPLES::
|
|
# the License, or (at your option) any later version.
|
|
# http://www.gnu.org/licenses/
|
|
#*****************************************************************************
|
|
-from __future__ import absolute_import
|
|
|
|
from sage.structure.sage_object import SageObject
|
|
|
|
@@ -187,27 +186,6 @@ class BackendBase(SageObject):
|
|
"""
|
|
raise NotImplementedError('derived classes must implement this method')
|
|
|
|
- def is_in_terminal(self):
|
|
- """
|
|
- Test whether the UI is meant to run in a terminal
|
|
-
|
|
- See
|
|
- :meth:`sage.repl.rich_output.display_manager.DisplayManager.is_in_terminal`
|
|
- for details.
|
|
-
|
|
- OUTPUT:
|
|
-
|
|
- Defaults to ``False``.
|
|
-
|
|
- EXAMPLES::
|
|
-
|
|
- sage: from sage.repl.rich_output.backend_base import BackendBase
|
|
- sage: backend = BackendBase()
|
|
- sage: backend.is_in_terminal()
|
|
- False
|
|
- """
|
|
- return False
|
|
-
|
|
def max_width(self):
|
|
"""
|
|
Return the number of characters that fit into one output line
|
|
@@ -510,8 +488,8 @@ class BackendBase(SageObject):
|
|
sage: _ # indirect doctest
|
|
'foo'
|
|
"""
|
|
- from six.moves import builtins
|
|
- builtins._ = obj
|
|
+ import __builtin__
|
|
+ __builtin__._ = obj
|
|
|
|
def displayhook(self, plain_text, rich_output):
|
|
"""
|
|
diff -up src/sage/repl/rich_output/backend_doctest.py.orig src/sage/repl/rich_output/backend_doctest.py
|
|
--- src/sage/repl/rich_output/backend_doctest.py.orig 2016-08-18 13:12:59.148122167 -0400
|
|
+++ src/sage/repl/rich_output/backend_doctest.py 2016-08-18 13:13:39.071123696 -0400
|
|
@@ -86,7 +86,7 @@ class BackendDoctest(BackendBase):
|
|
backend.
|
|
|
|
EXAMPLES::
|
|
-
|
|
+
|
|
sage: from sage.repl.rich_output.backend_doctest import BackendDoctest
|
|
sage: backend = BackendDoctest()
|
|
sage: backend.install()
|
|
@@ -104,7 +104,7 @@ class BackendDoctest(BackendBase):
|
|
should never call it by hand.
|
|
|
|
EXAMPLES::
|
|
-
|
|
+
|
|
sage: from sage.repl.rich_output.backend_doctest import BackendDoctest
|
|
sage: backend = BackendDoctest()
|
|
sage: backend.install()
|
|
@@ -137,9 +137,6 @@ class BackendDoctest(BackendBase):
|
|
OutputImagePng, OutputImageGif, OutputImageJpg,
|
|
OutputImageSvg, OutputImagePdf, OutputImageDvi,
|
|
OutputSceneJmol, OutputSceneCanvas3d, OutputSceneWavefront,
|
|
- OutputVideoOgg, OutputVideoWebM, OutputVideoMp4,
|
|
- OutputVideoFlash, OutputVideoMatroska, OutputVideoAvi,
|
|
- OutputVideoWmv, OutputVideoQuicktime,
|
|
])
|
|
|
|
def displayhook(self, plain_text, rich_output):
|
|
@@ -249,14 +246,6 @@ class BackendDoctest(BackendBase):
|
|
sage: backend.validate(dm.types.OutputSceneJmol.example())
|
|
sage: backend.validate(dm.types.OutputSceneWavefront.example())
|
|
sage: backend.validate(dm.types.OutputSceneCanvas3d.example())
|
|
- sage: backend.validate(dm.types.OutputVideoOgg.example())
|
|
- sage: backend.validate(dm.types.OutputVideoWebM.example())
|
|
- sage: backend.validate(dm.types.OutputVideoMp4.example())
|
|
- sage: backend.validate(dm.types.OutputVideoFlash.example())
|
|
- sage: backend.validate(dm.types.OutputVideoMatroska.example())
|
|
- sage: backend.validate(dm.types.OutputVideoAvi.example())
|
|
- sage: backend.validate(dm.types.OutputVideoWmv.example())
|
|
- sage: backend.validate(dm.types.OutputVideoQuicktime.example())
|
|
"""
|
|
if isinstance(rich_output, OutputPlainText):
|
|
pass
|
|
@@ -286,34 +275,5 @@ class BackendDoctest(BackendBase):
|
|
assert rich_output.mtl.get().startswith('newmtl ')
|
|
elif isinstance(rich_output, OutputSceneCanvas3d):
|
|
assert rich_output.canvas3d.get().startswith('[{vertices:')
|
|
- elif isinstance(rich_output, OutputVideoOgg):
|
|
- assert rich_output.video.get().startswith('OggS')
|
|
- elif isinstance(rich_output, OutputVideoWebM):
|
|
- data = rich_output.video.get()
|
|
- assert data.startswith('\x1a\x45\xdf\xa3')
|
|
- assert '\x42\x82\x84webm' in data
|
|
- elif isinstance(rich_output, OutputVideoMp4):
|
|
- data = rich_output.video.get()
|
|
- assert data[4:8] == 'ftyp'
|
|
- assert data.startswith('\0\0\0')
|
|
- # See http://www.ftyps.com/
|
|
- ftyps = [data[i:i+4] for i in range(8, ord(data[3]), 4)]
|
|
- del ftyps[1] # version number, not an ftyp
|
|
- expected = ['avc1', 'iso2', 'mp41', 'mp42']
|
|
- assert any(i in ftyps for i in expected)
|
|
- elif isinstance(rich_output, OutputVideoFlash):
|
|
- assert rich_output.video.get().startswith('FLV\x01')
|
|
- elif isinstance(rich_output, OutputVideoMatroska):
|
|
- data = rich_output.video.get()
|
|
- assert data.startswith('\x1a\x45\xdf\xa3')
|
|
- assert '\x42\x82\x88matroska' in data
|
|
- elif isinstance(rich_output, OutputVideoAvi):
|
|
- data = rich_output.video.get()
|
|
- assert data[:4] == 'RIFF' and data[8:12] == 'AVI '
|
|
- elif isinstance(rich_output, OutputVideoWmv):
|
|
- assert rich_output.video.get().startswith('\x30\x26\xb2\x75')
|
|
- elif isinstance(rich_output, OutputVideoQuicktime):
|
|
- data = rich_output.video.get()
|
|
- assert data[4:12] == 'ftypqt ' or data[4:8] == 'moov'
|
|
else:
|
|
raise TypeError('rich_output type not supported')
|
|
diff -up src/sage/repl/rich_output/backend_ipython.py.orig src/sage/repl/rich_output/backend_ipython.py
|
|
--- src/sage/repl/rich_output/backend_ipython.py.orig 2016-08-18 13:12:59.154122167 -0400
|
|
+++ src/sage/repl/rich_output/backend_ipython.py 2016-08-18 13:14:14.599125056 -0400
|
|
@@ -1,4 +1,4 @@
|
|
-# -*- coding: utf-8 -*-
|
|
+# -*- encoding: utf-8 -*-
|
|
"""
|
|
IPython Backend for the Sage Rich Output System
|
|
|
|
@@ -108,7 +108,6 @@ class BackendIPython(BackendBase):
|
|
if not formatted:
|
|
return
|
|
publish_display_data(data=formatted, metadata=metadata)
|
|
-
|
|
|
|
class BackendIPythonCommandline(BackendIPython):
|
|
"""
|
|
@@ -371,26 +370,38 @@ class BackendIPythonCommandline(BackendI
|
|
.format(jmol_cmd, launch_script))
|
|
return 'Launched jmol viewer for {0}'.format(plain_text)
|
|
|
|
- def is_in_terminal(self):
|
|
+ def launch_sage3d(self, output_wavefront, plain_text):
|
|
"""
|
|
- Test whether the UI is meant to run in a terminal
|
|
+ Launch the stand-alone java3d viewer
|
|
|
|
- See
|
|
- :meth:`sage.repl.rich_output.display_manager.DisplayManager.is_in_terminal`
|
|
- for details.
|
|
+ INPUT:
|
|
+
|
|
+ - ``output_wavefront`` --
|
|
+ :class:`~sage.repl.rich_output.output_graphics3d.OutputSceneWavefront`. The
|
|
+ scene to launch Java3d with.
|
|
+
|
|
+ - ``plain_text`` -- string. The plain text representation.
|
|
|
|
OUTPUT:
|
|
|
|
- ``True`` for the IPython commandline.
|
|
+ String. Human-readable message indicating that the viewer was launched.
|
|
|
|
EXAMPLES::
|
|
|
|
sage: from sage.repl.rich_output.backend_ipython import BackendIPythonCommandline
|
|
sage: backend = BackendIPythonCommandline()
|
|
- sage: backend.is_in_terminal()
|
|
- True
|
|
+ sage: from sage.repl.rich_output.output_graphics3d import OutputSceneWavefront
|
|
+ sage: backend.launch_sage3d(OutputSceneWavefront.example(), 'Graphics3d object')
|
|
+ 'Launched Java 3D viewer for Graphics3d object'
|
|
"""
|
|
- return True
|
|
+ from sage.env import SAGE_LOCAL
|
|
+ sage3d = os.path.join(SAGE_LOCAL, 'bin', 'sage3d')
|
|
+ obj = output_wavefront.obj_filename()
|
|
+ from sage.doctest import DOCTEST_MODE
|
|
+ if not DOCTEST_MODE:
|
|
+ os.system('{0} {1} 2>/dev/null 1>/dev/null &'
|
|
+ .format(sage3d, obj))
|
|
+ return 'Launched Java 3D viewer for {0}'.format(plain_text)
|
|
|
|
class BackendIPythonNotebook(BackendIPython):
|
|
"""
|
|
@@ -450,8 +461,8 @@ class BackendIPythonNotebook(BackendIPyt
|
|
False
|
|
"""
|
|
return set([
|
|
- OutputPlainText, OutputAsciiArt, OutputUnicodeArt, OutputLatex,
|
|
OutputHtml,
|
|
+ OutputPlainText, OutputAsciiArt, OutputUnicodeArt, OutputLatex,
|
|
OutputImagePng, OutputImageJpg,
|
|
OutputImageSvg, OutputImagePdf,
|
|
OutputSceneJmol,
|
|
diff -up src/sage/repl/rich_output/backend_sagenb.py.orig src/sage/repl/rich_output/backend_sagenb.py
|
|
--- src/sage/repl/rich_output/backend_sagenb.py.orig 2016-08-18 13:12:59.160122167 -0400
|
|
+++ src/sage/repl/rich_output/backend_sagenb.py 2016-08-18 13:14:20.303125275 -0400
|
|
@@ -38,21 +38,6 @@ filenames::
|
|
sage: os.path.exists('sage0.png')
|
|
True
|
|
sage: os.remove('sage0.png')
|
|
-
|
|
-Tables are typeset as html in SageNB::
|
|
-
|
|
- sage: table([1, 2, 3])
|
|
- <html><div class="notruncate">
|
|
- <table class="table_form">
|
|
- <tbody>
|
|
- <tr class ="row-a">
|
|
- <td><script type="math/tex">1</script></td>
|
|
- <td><script type="math/tex">2</script></td>
|
|
- <td><script type="math/tex">3</script></td>
|
|
- </tr>
|
|
- </tbody>
|
|
- </table>
|
|
- </div></html>
|
|
"""
|
|
|
|
#*****************************************************************************
|
|
@@ -67,12 +52,10 @@ Tables are typeset as html in SageNB::
|
|
import os
|
|
import stat
|
|
from sage.misc.cachefunc import cached_method
|
|
-from sage.misc.html import html
|
|
from sage.misc.temporary_file import graphics_filename
|
|
from sage.doctest import DOCTEST_MODE
|
|
from sage.repl.rich_output.backend_base import BackendBase
|
|
from sage.repl.rich_output.output_catalog import *
|
|
-from sage.repl.rich_output.output_video import OutputVideoBase
|
|
|
|
|
|
def world_readable(filename):
|
|
@@ -320,13 +303,12 @@ class BackendSageNB(BackendBase):
|
|
True
|
|
"""
|
|
return set([
|
|
- OutputPlainText, OutputAsciiArt, OutputLatex,
|
|
OutputHtml,
|
|
+ OutputPlainText, OutputAsciiArt, OutputLatex,
|
|
OutputImagePng, OutputImageGif, OutputImageJpg,
|
|
OutputImagePdf, OutputImageSvg,
|
|
SageNbOutputSceneJmol,
|
|
OutputSceneCanvas3d,
|
|
- OutputVideoOgg, OutputVideoWebM, OutputVideoMp4,
|
|
])
|
|
|
|
def display_immediately(self, plain_text, rich_output):
|
|
@@ -382,8 +364,6 @@ class BackendSageNB(BackendBase):
|
|
rich_output.embed()
|
|
elif isinstance(rich_output, OutputSceneCanvas3d):
|
|
self.embed_image(rich_output.canvas3d, '.canvas3d')
|
|
- elif isinstance(rich_output, OutputVideoBase):
|
|
- self.embed_video(rich_output)
|
|
else:
|
|
raise TypeError('rich_output type not supported, got {0}'.format(rich_output))
|
|
|
|
@@ -423,11 +403,4 @@ class BackendSageNB(BackendBase):
|
|
output_buffer.save_as(filename)
|
|
world_readable(filename)
|
|
|
|
- def embed_video(self, video_output):
|
|
- filename = graphics_filename(ext=video_output.ext)
|
|
- video_output.video.save_as(filename)
|
|
- world_readable(filename)
|
|
- html(video_output.html_fragment(
|
|
- url='cell://' + filename,
|
|
- link_attrs='class="file_link"',
|
|
- ))
|
|
+
|
|
diff -up src/sage/repl/rich_output/display_manager.py.orig src/sage/repl/rich_output/display_manager.py
|
|
--- src/sage/repl/rich_output/display_manager.py.orig 2016-08-18 13:12:59.166122168 -0400
|
|
+++ src/sage/repl/rich_output/display_manager.py 2016-08-18 13:13:01.918122273 -0400
|
|
@@ -343,26 +343,6 @@ class DisplayManager(SageObject):
|
|
"""
|
|
return self._preferences
|
|
|
|
- def is_in_terminal(self):
|
|
- """
|
|
- Test whether the UI is meant to run in a terminal
|
|
-
|
|
- When this method returns ``True``, you can assume that it is
|
|
- possible to use ``raw_input`` or launch external programs that
|
|
- take over the input.
|
|
-
|
|
- Otherwise, you should assume that the backend runs remotely or
|
|
- in a pty controlled by another program. Then you should not
|
|
- launch external programs with a (text or graphical) UI.
|
|
-
|
|
- This is used to enable/disable interpreter consoles.
|
|
-
|
|
- OUTPUT:
|
|
-
|
|
- Boolean.
|
|
- """
|
|
- return self._backend.is_in_terminal()
|
|
-
|
|
def check_backend_class(self, backend_class):
|
|
"""
|
|
Check that the current backend is an instance of
|
|
diff -up src/sage/repl/rich_output/output_catalog.py.orig src/sage/repl/rich_output/output_catalog.py
|
|
--- src/sage/repl/rich_output/output_catalog.py.orig 2016-08-18 13:12:59.172122168 -0400
|
|
+++ src/sage/repl/rich_output/output_catalog.py 2016-08-18 13:14:45.136126226 -0400
|
|
@@ -40,14 +40,3 @@ from .output_graphics3d import (
|
|
OutputSceneWavefront,
|
|
OutputSceneCanvas3d,
|
|
)
|
|
-
|
|
-from .output_video import (
|
|
- OutputVideoOgg,
|
|
- OutputVideoWebM,
|
|
- OutputVideoMp4,
|
|
- OutputVideoFlash,
|
|
- OutputVideoMatroska,
|
|
- OutputVideoAvi,
|
|
- OutputVideoWmv,
|
|
- OutputVideoQuicktime,
|
|
-)
|
|
diff -up src/sage/repl/rich_output/pretty_print.py.orig src/sage/repl/rich_output/pretty_print.py
|
|
--- src/sage/repl/rich_output/pretty_print.py.orig 2016-08-18 13:12:59.177122168 -0400
|
|
+++ src/sage/repl/rich_output/pretty_print.py 2016-08-18 13:13:01.919122273 -0400
|
|
@@ -210,20 +210,23 @@ def pretty_print(*args, **kwds):
|
|
sage: pretty_print(LatexExpr(r"\frac{x^2 + 1}{x - 2}"))
|
|
<html><script type="math/tex">\newcommand{\Bold}[1]{\mathbf{#1}}\frac{x^2 + 1}{x - 2}</script></html>
|
|
|
|
+ Iterators and generators are unwrapped::
|
|
+
|
|
+ sage: iterator = iter(range(3)); iterator
|
|
+ <listiterator object at 0x...>
|
|
+ sage: pretty_print(iterator)
|
|
+ <html><script type="math/tex">\newcommand{\Bold}[1]{\mathbf{#1}}0 1 2</script></html>
|
|
+
|
|
TESTS::
|
|
|
|
sage: plt = plot(sin)
|
|
sage: pretty_print(plt) # graphics output
|
|
- sage: pretty_print(ZZ, 123, plt) # optional - latex
|
|
- <html><script type="math/tex">\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Z} 123 %% Creator: Matplotlib, PGF backend...</script></html>
|
|
+ sage: pretty_print(ZZ, 123, plt) # latex output
|
|
+ <html><script type="math/tex">\newcommand{\Bold}[1]{\mathbf{#1}}\Bold{Z} 123 \verb|Graphics|\phantom{\verb!x!}\verb|object|\phantom{\verb!x!}\verb|consisting|\phantom{\verb!x!}\verb|of|\phantom{\verb!x!}\verb|1|\phantom{\verb!x!}\verb|graphics|\phantom{\verb!x!}\verb|primitive|</script></html>
|
|
sage: pretty_print(plt, plt) # graphics output
|
|
"""
|
|
- # Support deprecation trac #18292
|
|
- if len(args) == 1:
|
|
- import sage.misc.html
|
|
- if sage.misc.html.WarnIfNotPrinted.skip_pretty_print(args[0]):
|
|
- return
|
|
-
|
|
+ if len(args) == 1 and isinstance(args[0], (types.GeneratorType, collections.Iterator)):
|
|
+ args = tuple(args[0])
|
|
dm = get_display_manager()
|
|
old_preferences_text = dm.preferences.text
|
|
try:
|