sagemath/sagemath-ipython3.patch
2016-08-20 13:51:55 -04:00

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: