Ticket #12719: trac_12719.patch

File trac_12719.patch, 63.6 KB (added by mhansen, 9 years ago)
  • doc/en/reference/misc.rst

    # HG changeset patch
    # User Mike Hansen <mhansen@gmail.com>
    # Date 1334129352 25200
    # Node ID da9c3bd00c7d963e7df27a7867c7bda2469b7801
    # Parent  7d8ac0ee679de0e5eeba4966fe280f5f65295472
    #12719: Upgrade to IPython 0.12
    
    diff --git a/doc/en/reference/misc.rst b/doc/en/reference/misc.rst
    a b  
    2626   sage/misc/dist
    2727   sage/misc/hg
    2828   sage/misc/preparser
     29   sage/misc/interpreter
    2930   sage/misc/functional
    3031   sage/misc/latex
    3132   sage/misc/latex_macros
  • sage/all.py

    diff --git a/sage/all.py b/sage/all.py
    a b  
    274274    from sage.libs.all import symmetrica
    275275    symmetrica.end()
    276276       
    277 def _quit_sage_(self):
    278     import sage.misc.preparser_ipython
    279     if sage.misc.preparser_ipython.interface != None:
    280         sage.misc.preparser_ipython.switch_interface('sage')
    281         self.exit_now = False
    282         return
    283    
    284     from IPython.genutils import ask_yes_no
    285     if self.rc.confirm_exit:
    286         if ask_yes_no('Do you really want to exit ([y]/n)?','y'):
    287             self.exit_now = True
    288     else:
    289         self.exit_now = True
    290     if self.exit_now:
    291         quit_sage()
    292         self.exit_now = True
    293 
    294     return self.exit_now
    295 
    296 from IPython.iplib import InteractiveShell
    297 InteractiveShell.exit = _quit_sage_
    298 
    299 import sage.misc.displayhook
    300 sage.misc.displayhook.install()
    301 
    302277from sage.ext.interactive_constructors_c import inject_on, inject_off
    303278
    304279sage.structure.sage_object.register_unpickle_override('sage.categories.category', 'Sets', Sets)
  • sage/all_cmdline.py

    diff --git a/sage/all_cmdline.py b/sage/all_cmdline.py
    a b  
    2424    raise ValueError(msg)
    2525
    2626
     27sage.misc.session.init()
    2728
    28 def _init_cmdline(globs):
    29     from sage.misc.inline_fortran import InlineFortran
    30     fortran = InlineFortran(globs)
    31     globs['fortran'] = fortran
    32 
    33 
    34 
    35 sage.misc.session.init()
  • sage/interfaces/expect.py

    diff --git a/sage/interfaces/expect.py b/sage/interfaces/expect.py
    a b  
    293293            self._start()
    294294        return self._expect
    295295
    296     def interact(self):
    297         r"""
    298         This allows you to interactively interact with the child
    299         interpreter. Press Ctrl-D or type 'quit' or 'exit' to exit and
    300         return to Sage.
    301        
    302         .. note::
    303 
    304            This is completely different than the console() member
    305            function. The console function opens a new copy of the
    306            child interpreter, whereas the interact function gives you
    307            interactive access to the interpreter that is being used by
    308            Sage. Use sage(xxx) or interpretername(xxx) to pull objects
    309            in from sage to the interpreter.
    310         """
    311         if self._expect is None:
    312             self._start()
    313         import sage.misc.preparser_ipython
    314         sage.misc.preparser_ipython.switch_interface_general(self)
    315 
    316     def _pre_interact(self):
    317         pass
    318 
    319     def _post_interact(self):
    320         pass
    321 
    322296    def pid(self):
    323297        """
    324298        Return the PID of the underlying sub-process.
  • sage/interfaces/gap.py

    diff --git a/sage/interfaces/gap.py b/sage/interfaces/gap.py
    a b  
    178178import expect
    179179from expect import Expect, ExpectElement, FunctionElement, ExpectFunction
    180180from sage.misc.misc import SAGE_ROOT, SAGE_DATA, DOT_SAGE, is_64_bit, is_in_string
    181 from IPython.genutils import page
    182181import re
    183182import os
    184183import pexpect
     
    10691068                self._get_tmpfile()
    10701069            F = open(self._local_tmpfile(),"r")
    10711070            if pager:
     1071                from IPython.genutils import page
    10721072                page(F.read(), start = int(sline)-1)
    10731073            else:
    10741074                return F.read()
  • sage/interfaces/interface.py

    diff --git a/sage/interfaces/interface.py b/sage/interfaces/interface.py
    a b  
    8585           Sage. Use sage(xxx) or interpretername(xxx) to pull objects
    8686           in from sage to the interpreter.
    8787        """
    88         import sage.misc.preparser_ipython
    89         sage.misc.preparser_ipython.switch_interface_general(self)
     88        from sage.misc.interpreter import interface_shell_embed
     89        shell = interface_shell_embed(self)
     90        try:
     91            ipython = get_ipython()
     92        except NameError:
     93            shell()
     94        else:
     95            shell(local_ns=dict(ipython.user_ns))
    9096
    9197    def _pre_interact(self):
    9298        pass
  • sage/misc/displayhook.py

    diff --git a/sage/misc/displayhook.py b/sage/misc/displayhook.py
    a b  
    88- Bill Cauchois (2009): initial version
    99"""
    1010
    11 import IPython, sys, __builtin__
    12 from sage.matrix.matrix import is_Matrix
    13 from sage.modular.arithgroup.arithgroup_element import ArithmeticSubgroupElement
     11import sys, __builtin__
     12
    1413
    1514# This is used to wrap lines when printing "tall" lists.
    1615MAX_COLUMN = 70
     
    138137    # element is a matrix, or an ArithmeticSubgroupElement (a thin wrapper
    139138    # around a matrix). This should cover most cases.
    140139    if isinstance(obj, (tuple, list)):
     140        from sage.matrix.matrix import is_Matrix
     141        from sage.modular.arithgroup.arithgroup_element import ArithmeticSubgroupElement
    141142        if len(obj) > 0 and (is_Matrix(obj[0]) or isinstance(obj[0], ArithmeticSubgroupElement)):
    142143            if _check_tall_list_and_print(out_stream, obj):
    143144                return
    144145    print >>out_stream, `obj`
    145146
    146 def result_display(ip_self, obj):
    147     """
    148     This function implements the ``result_display`` hook for IPython.
    149     """
    150     # IPython's default result_display() uses the IPython.genutils.Term.cout stream.
    151     # See also local/lib/python2.6/site-packages/IPython/hooks.py.
    152     print_obj(IPython.genutils.Term.cout, obj)
    153 
    154147def displayhook(obj):
    155148    """
    156149    This function adheres to the displayhook protocol described in `PEP 217`_.
     
    175168    __builtin__._ = None
    176169    print_obj(sys.stdout, obj)
    177170    __builtin__._ = obj
    178 
    179 def install():
    180     """
    181     Install the new displayhook, so that subsequent output from the interpreter
    182     will be preprocessed by the mechanisms in this module.
    183     """
    184     # First, try to install the hook using the IPython hook API.
    185     ipapi = IPython.ipapi.get()
    186     if ipapi:
    187         ipapi.set_hook('result_display', result_display)
    188     else:
    189         # In certain modes where IPython is not in use, it is necessary to fall
    190         # back to setting Python's sys.displayhook.
    191         sys.displayhook = displayhook
  • sage/misc/edit_module.py

    diff --git a/sage/misc/edit_module.py b/sage/misc/edit_module.py
    a b  
    4545import inspect
    4646import os
    4747import re
    48 import IPython
    4948
    5049from string import Template
    5150
     
    302301    variable :envvar:`EDITOR`) with the file in which gcd is defined, and when your
    303302    editor supports it, also at the line in wich gcd is defined.
    304303    """
     304    import IPython.core.hooks
    305305    sageroot = sage.misc.sageinspect.SAGE_ROOT+'/'
    306306    runpathpattern = '^'+sageroot+'local/lib/python[^/]*/site-packages'
    307307    develbranch = sageroot+'devel/sage'
    308308    filename=re.sub(runpathpattern,develbranch,filename)
    309     IPython.hooks.editor(self, filename, linenum)
     309    IPython.core.hooks.editor(self, filename, linenum)
    310310
    311 
    312 ip = IPython.ipapi.get()
    313 if ip:
    314     ip.set_hook('editor', edit_devel)
    315 
    316 
  • sage/misc/interpreter.py

    diff --git a/sage/misc/interpreter.py b/sage/misc/interpreter.py
    a b  
    1 """
    2 Preparses input from the interpreter
     1r"""
     2Sage's IPython Modifications
    33
    4 Modified input.
     4This module contains all of Sage's customizations to the IPython
     5interpreter.  These changes consist of the following magjor components:
    56
    6   -- All ^'s (not in strings) are replaced by **'s.
     7  - :class:`SageTerminalApp`
     8  - :class:`SageInteractiveShell`
     9  - :func:`interface_shell_embed`
    710
    8   -- If M is a variable and i an integer,
    9      then M.i is replaced by M.gen(i), so generators can be
    10      accessed as in MAGMA.
     11SageTerminalApp
     12---------------
    1113
    12   -- quit alone on a line quits.
     14This is the main application object.  It is used by the
     15``$SAGE_ROOT/local/bin/sage-ipython`` script to start the Sage
     16command-line.  It's primary purpose is to
    1317
    14   -- load to load in scripts
     18  - Initialize the :class:`SageInteractiveShell`.
    1519
    16   -- Most int literals n are replaced by ZZ(n) Thus 2/3 is a rational
    17      number.  If they are in []'s right after a valid identifier they
    18      aren't replaced.
     20  - Provide default configuration options for the shell, and its
     21    subcomponents.  These work with (and can be overrided by)
     22    IPython's configuration system.
    1923
    20   -- real literals get wrapped in "RR" (with a precision)
    21      
    22   -- the R.<x,y,z> = ... notation
     24  - Monkey-patch IPython in order to support Sage's customization when
     25    introspecting objects.
    2326
    24 TODO:
    25   I have no plans for anything further, except to improve the
    26   robustness of the above.  Preparsing may work incorrectly for
    27   multi-line input lines in some cases; this will be fixed.
    28  
    29 All other input is processed normally.
     27  - Provide a custom :class:`SageCrashHandler` to give the user
     28    instructions on how to report the crash to the Sage support
     29    mailing list.
    3030
    31 It automatically converts *most* integer literals to Sage Integer's and 
    32 decimal literals to Sage Reals.  It does not convert indexes into
    33 1-d arrays, since those have to be ints.   
    34  
    35 I also extended the load command so it *really* works exactly
    36 like the Sage interpreter, so e.g., ^ for exponentiation is
    37 allowed.  Also files being loaded can themselves load other files.
    38 Finally, I added an "attach" command, e.g.,
    39     attach 'file'
    40 that works kind of like attach in MAGMA.  Whenever you enter a blank
    41 line in the Sage interpreter, *all* attached files that have changed
    42 are automatically reloaded.  Moreover, the attached files work according
    43 to the Sage interpreter rules, i.e., ^ --> **, etc. 
    44  
    45 I also fixed it so ^ is not replaced by ** inside strings.
    46  
    47 Finally, I added back the M.n notation for the n-th generator
    48 of object M, again like in MAGMA.
     31SageInteractiveShell
     32--------------------
    4933
    50 EXAMPLE:
    51     sage: 2/3
    52     2/3
    53     sage: type(2/3)
    54     <type 'sage.rings.rational.Rational'>
    55     sage: a = 49928420832092
    56     sage: type(a)
    57     <type 'sage.rings.integer.Integer'>
    58     sage: a.factor()
    59     2^2 * 11 * 1134736837093
    60     sage: v = [1,2,3]
    61     sage: type(v[0])
    62     <type 'sage.rings.integer.Integer'>
     34The :class:`SageInteractiveShell` object is the object responsible for
     35accepting input from the user and evaluating it.  From the command-line,
     36this object can be retrieved by running::
    6337
    64 If we don't make potential list indices int's, then lots of stuff
    65 breaks, or users have to type v[int(7)], which is insane. 
    66 A fix would be to only not make what's in the brackets an
    67 Integer if what's before the bracket is a valid identifier,
    68 so the w = [5] above would work right.
     38    sage: shell = get_ipython() #not tested
    6939
    70     sage: s = "x^3 + x + 1"
    71     sage: s
    72     'x^3 + x + 1'
    73     sage: pari(s)
    74     x^3 + x + 1
    75     sage: f = pari(s)
    76     sage: f^2
    77     x^6 + 2*x^4 + 2*x^3 + x^2 + 2*x + 1
    78     sage: V = VectorSpace(QQ,3)
    79     sage: V.0
    80     (1, 0, 0)
    81     sage: V.1
    82     (0, 1, 0)
    83     sage: s = "This. Is. It."
    84     sage: print s
    85     This. Is. It.
     40The :class:`SageInteractiveShell` provides the following
     41customizations:
     42
     43  - Modifying the input before it is evaluated.  See
     44    :class:`SagePromptTransformer`, :class:`SagePreparseTransformer`,
     45    :class:`LoadAttachTransformer`,
     46    :class:`InterfaceMagicTransformer`, and
     47    :meth:`~SageInteractiveShell.init_prefilter`.
     48
     49  - Provide a number of IPython magic functions that work with Sage
     50    and its preparser.  See :meth:`~SageInteractiveShell.magic_timeit`,
     51    :meth:`~SageInteractiveShell.magic_prun`,
     52    :meth:`~SageInteractiveShell.magic_load`,
     53    :meth:`~SageInteractiveShell.magic_attach`, and
     54    :meth:`~SageInteractiveShell.magic_iload`.
     55
     56  - Adding support for attached files.  See
     57    :meth:`~SageInteractiveShell.run_cell`.
     58
     59  - Cleanly deinitialize the Sage library before exiting.  See
     60    :meth:`~SageInteractiveShell.ask_exit`.
     61
     62  - Modify the libraries before calling system commands. See
     63    :meth:`~SageInteractiveShell.system_raw`.
     64
     65Interface Shell
     66---------------
     67
     68The function :func:`interface_shell_embed` takes a
     69:class:`~sage.interfaces.interface.Interface` object and returns an
     70embeddable IPython shell which can be used to directly interact with
     71that shell.  The bulk of this functionality is provided through
     72:class:`InterfaceShellTransformer`.
     73
     74Auto-generated Documentation
     75----------------------------
    8676"""
    8777
    8878#*****************************************************************************
    89 #       Copyright (C) 2004 William Stein <wstein@gmail.com>
     79#       Copyright (C) 2004-2012 William Stein <wstein@gmail.com>
    9080#
    9181#  Distributed under the terms of the GNU General Public License (GPL)
    9282#
    9383#                  http://www.gnu.org/licenses/
    9484#*****************************************************************************
    95 import IPython.ipapi
    96 _ip = IPython.ipapi.get()
    97 
    98 __author__ = 'William Stein <wstein@gmail.com> et al.'
    99 __license__ = 'GPL'
    100 
    101 import os
    102 import log
    103 import re
    104 
    105 import remote_file
    106 
    107 from IPython.iplib import InteractiveShell
    108 
    109 import preparser_ipython
    110 from preparser import preparse_file, load_wrap, modified_attached_files, attached_files
    111 
    112 import cython
    113 
    114 # IPython has a prefilter() function that analyzes each input line. We redefine
    115 # it here to first pre-process certain forms of input
    116 
    117 # The prototype of any alternate prefilter must be like this one (the name
    118 # doesn't matter):
    119 # - line is a string containing the user input line.
    120 # - continuation is a parameter which tells us if we are processing a first line of
    121 #   user input or the second or higher of a multi-line statement.
    122 
    123 
    124 
    125 def load_startup_file(file):
    126     if os.path.exists(file):
    127         X = do_prefilter_paste('load "%s"'%file,False)
    128         _ip.runlines(X)
    129     if os.path.exists('attach.sage'):
    130         X = do_prefilter_paste('attach "attach.sage"',False)
    131         _ip.runlines(X)
    132 
    133 
    134 def do_prefilter_paste(line, continuation):
    135     """
    136     Alternate prefilter for input.
    137 
    138     INPUT:
    139    
    140         - ``line`` -- a single line; must *not* have any newlines in it
    141         - ``continuation`` -- whether the input line is really part
    142           of the previous line, because of open parens or backslash.
    143     """
    144     if '\n' in line:
    145         raise RuntimeError, "bug in function that calls do_prefilter_paste -- there can be no newlines in the input"
    146 
    147     # This is so it's OK to have lots of blank space at the
    148     # beginning of any non-continuation line.
    149    
    150     if continuation:
    151         # strip ...'s that appear in examples
    152         L = line.lstrip()
    153         if L[:3] == '...':
    154             line = L[3:]
    155     else:
    156         line = line.lstrip()
    157        
    158     line = line.rstrip()
    159 
    160     # Process attached files.
    161     for F in modified_attached_files():
    162         # We attach the files again instead of loading them,
    163         # to preserve tracebacks or efficiency according
    164         # to the settings of load_attach_mode().
    165         _ip.runlines(load_wrap(F, attach=True))
    166        
    167     # Get rid of leading sage: prompts so that pasting of examples
    168     # from the documentation works.  This is like MAGMA's
    169     # SetLinePrompt(false).
    170     for prompt in ['sage:', '>>>']:
    171         if not continuation:
    172             while True:
    173                 strip = False
    174                 if line[:3] == prompt:
    175                     line = line[3:].lstrip()
    176                     strip = True
    177                 elif line[:5] == prompt:
    178                     line = line[5:].lstrip()
    179                     strip = True
    180                 if not strip:
    181                     break
    182                 else:
    183                     line = line.lstrip()
    184        
    185     # 'quit' alone on a line to quit.
    186     if line.lower() in ['quit', 'exit', 'quit;', 'exit;']:
    187         line = '%quit'
    188 
    189     # An interactive load command, like iload in MAGMA.
    190     if line[:6] == 'iload ':
    191         try:
    192             name = str(eval(line[6:]))
    193         except:
    194             name = str(line[6:].strip())
    195         try:
    196             F = open(name)
    197         except IOError:
    198             raise ImportError, 'Could not open file "%s"'%name
    199        
    200         print 'Interactively loading "%s"'%name
    201         n = len(__IPYTHON__.input_hist)
    202         for L in F.readlines():
    203             L = L.rstrip()
    204             Llstrip = L.lstrip()
    205             raw_input('sage: %s'%L.rstrip())
    206             __IPYTHON__.input_hist_raw.append(L)
    207             if Llstrip[:5] == 'load ' or Llstrip[:7] == 'attach ' \
    208                    or Llstrip[:6] == 'iload ':
    209                 log.offset -= 1                   
    210                 L = do_prefilter_paste(L, False)
    211                 if len(L.strip()) > 0:
    212                     _ip.runlines(L)
    213                 L = ''
    214             else:
    215                 L = preparser_ipython.preparse_ipython(L, not continuation)
    216             __IPYTHON__.input_hist.append(L)
    217             __IPYTHON__.push(L)
    218         log.offset += 1
    219         return ''
    220 
    221        
    222     #################################################################
    223     # load and attach commands
    224     #################################################################
    225     for cmd in ['load', 'attach']:
    226         if line.lstrip().startswith(cmd+' '):
    227             j = line.find(cmd+' ')
    228             s = line[j+len(cmd)+1:].strip()
    229             if not s.startswith('('):
    230                 line = ' '*j + load_wrap(s, cmd=='attach')
    231 
    232     if len(line) > 0:
    233         line = preparser_ipython.preparse_ipython(line, not continuation)
    234 
    235     return line
     85import os, log, re, new, sys
     86from preparser import (preparse, preparse_file, load_wrap,
     87                       modified_attached_files, attached_files)
    23688
    23789def load_cython(name):
     90    import cython
    23891    cur = os.path.abspath(os.curdir)
    23992    try:
    24093        mod, dir  = cython.cython(name, compile_message=True, use_cache=True)
     
    24699    return 'from %s import *'%mod
    247100
    248101def handle_encoding_declaration(contents, out):
    249     """Find a PEP 263-style Python encoding declaration in the first or
     102    r"""Find a PEP 263-style Python encoding declaration in the first or
    250103    second line of `contents`. If found, output it to `out` and return
    251104    `contents` without the encoding line; otherwise output a default
    252105    UTF-8 declaration and return `contents`.
     
    272125        # -*- coding: utf-8 -*-
    273126        'import os, sys\n...'
    274127
    275     TESTS::
     128    TESTS:
    276129
    277     These are some of the tests listed in PEP 263.
     130    These are some of the tests listed in PEP 263::
    278131
    279132        sage: contents = '#!/usr/bin/python\n# -*- coding: latin-1 -*-\nimport os, sys'
    280133        sage: handle_encoding_declaration(contents, sys.stdout)
     
    386239    out.close()
    387240    return tmpfilename
    388241
    389 def sage_prefilter(self, block, continuation):
     242def embedded():
    390243    """
    391     Sage's prefilter for input.  Given a string block (usually a
    392     line), return the preparsed version of it. 
     244    Returns True if Sage is being run from the notebook.
    393245
    394     INPUT:
    395         block -- string (usually a single line, but not always)
    396         continuation -- whether or not this line is a continuation.
     246    EXAMPLES::
     247   
     248        sage: from sage.misc.interpreter import embedded
     249        sage: embedded()
     250        False
    397251    """
    398     try:
    399         block2 = ''
    400         first = True
    401         B = block.split('\n')
    402         for i in range(len(B)):
    403             L = B[i]
    404             M = do_prefilter_paste(L, continuation or (not first))
    405             first = False
    406             # The L[:len(L)-len(L.lstrip())]  business here preserves
    407             # the whitespace at the beginning of L.
    408             if block2 != '':
    409                 block2 += '\n'
    410             lstrip = L.lstrip()
    411             if lstrip[:5] == 'sage:' or lstrip[:3] == '>>>' or i==0:
    412                 block2 += M
    413             else:
    414                 block2 += L[:len(L)-len(lstrip)] + M
    415 
    416     except None:
    417        
    418         print "WARNING: An error occurred in the Sage parser while"
    419         print "parsing the following block:"
    420         print block
    421         print "Please report this as a bug (include the output of typing '%hist')."
    422         block2 = block
    423        
    424     return InteractiveShell._prefilter(self, block2, continuation)
    425 
    426 
    427 import sage.server.support
    428 def embedded():
     252    import sage.server.support
    429253    return sage.server.support.EMBEDDED_MODE
    430254
    431 ipython_prefilter = InteractiveShell.prefilter
     255#TODO: This global variable do_preparse should be associtated with an
     256#IPython InteractiveShell as opposed to a global variable in this
     257#module.
    432258do_preparse=True
    433259def preparser(on=True):
    434260    """
    435261    Turn on or off the Sage preparser.
    436262
    437     INPUT:
    438         - ``on`` -- bool (default: True) if True turn on preparsing; if False, turn it off.
     263    :keyword on: if True turn on preparsing; if False, turn it off.
     264    :type on: bool
    439265
    440     EXAMPLES:
     266    EXAMPLES::
     267
    441268        sage: 2/3
    442269        2/3
    443270        sage: preparser(False)
     
    450277    global do_preparse
    451278    if on:
    452279        do_preparse = True
    453         InteractiveShell.prefilter = sage_prefilter
    454280    else:
    455281        do_preparse = False       
    456         InteractiveShell.prefilter = ipython_prefilter
    457282
    458283
    459 import sagedoc
    460 import sageinspect
    461 import IPython.OInspect
    462 IPython.OInspect.getdoc = sagedoc.my_getdoc
    463 IPython.OInspect.getsource = sagedoc.my_getsource
    464 IPython.OInspect.getargspec = sageinspect.sage_getargspec
     284###############################################################
     285# Old code for handling the sage prompt in previous verisons of
     286# IPython
     287###############################################################
     288def set_sage_prompt(s):
     289    """
     290    Sets the Sage prompt to the string ``s``.
    465291
    466 #We monkey-patch IPython to disable the showing of plots
    467 #when doing introspection on them. This fixes Trac #2163.
    468 old_pinfo = IPython.OInspect.Inspector.pinfo
    469 def sage_pinfo(self, *args, **kwds):
     292    :param s: the new prompt
     293    :type s: string
     294    :returns: None
     295
     296    EXAMPLES::
     297
     298        sage: from sage.misc.interpreter import get_test_shell
     299        sage: shell = get_test_shell()
     300        sage: shell.run_cell('from sage.misc.interpreter import set_sage_prompt')
     301        sage: shell.run_cell('set_sage_prompt(u"new: ")')
     302        sage: shell.prompt_manager.in_template
     303        u'new: '
     304        sage: shell.run_cell('set_sage_prompt(u"sage: ")')
     305
    470306    """
    471     A wrapper around IPython.OInspect.Inspector.pinfo which turns
    472     off show_default before it is called and then sets it back
    473     to its previous value.
    474 
    475     Since this requires an IPython shell to test and the doctests aren't,
    476     run under IPython, we cannot add doctests for this function.
    477     """
    478     from sage.plot.all import show_default
    479     old_value = show_default()
    480     show_default(False)
    481    
    482     result = old_pinfo(self, *args, **kwds)
    483    
    484     show_default(old_value)
    485     return result
    486 IPython.OInspect.Inspector.pinfo = sage_pinfo
    487 
    488 import __builtin__
    489 _prompt = 'sage'
    490 
    491 def set_sage_prompt(s):
    492     global _prompt
    493     _prompt = str(s)
     307    ipython = get_ipython()
     308    ipython.prompt_manager.in_template = s
    494309
    495310def sage_prompt():
    496     log.update()
    497     return '%s'%_prompt
     311    """
     312    Returns the current Sage prompt.
    498313
    499 __builtin__.sage_prompt = sage_prompt
     314    EXAMPLES::
    500315
     316        sage: from sage.misc.interpreter import get_test_shell
     317        sage: shell = get_test_shell()
     318        sage: shell.run_cell('sage_prompt()')
     319        u'sage: '
     320    """
     321    ipython = get_ipython()
     322    return ipython.prompt_manager.in_template
    501323
     324###############
     325# Displayhook #
     326###############
     327from IPython.core.displayhook import DisplayHook
     328class SageDisplayHook(DisplayHook):
     329    """
     330    A replacement for ``sys.displayhook`` which correctly print lists
     331    of matrices.
    502332
    503 #######################################
    504 #
    505 def load_a_file(argstr, globals):
    506     s = open(argstr).read()
    507     return preparse_file(s, globals=globals)
     333    EXAMPLES::
     334
     335        sage: from sage.misc.interpreter import SageDisplayHook, get_test_shell
     336        sage: shell = get_test_shell()
     337        sage: shell.displayhook
     338        <sage.misc.interpreter.SageDisplayHook object at 0x...>
     339        sage: shell.run_cell('a = identity_matrix(ZZ, 2); [a,a]')
     340        [
     341        [1 0]  [1 0]
     342        [0 1], [0 1]
     343        ]
     344    """
     345    def compute_format_data(self, result):
     346        r"""
     347        Computes the format data of ``result``.  If the
     348        :func:`sage.misc.displayhook.print_obj` writes a string, then
     349        we override IPython's :class:`DisplayHook` formatting.
     350
     351        EXAMPLES::
     352
     353            sage: from sage.misc.interpreter import get_test_shell
     354            sage: shell = get_test_shell()
     355            sage: shell.displayhook
     356            <sage.misc.interpreter.SageDisplayHook object at 0x...>
     357            sage: shell.displayhook.compute_format_data(2)
     358            {u'text/plain': '2'}
     359            sage: a = identity_matrix(ZZ, 2)
     360            sage: shell.displayhook.compute_format_data([a,a])
     361            {u'text/plain': '[\n[1 0]  [1 0]\n[0 1], [0 1]\n]'}
     362        """
     363        format_data = super(SageDisplayHook, self).compute_format_data(result)
     364
     365        from cStringIO import StringIO
     366        s = StringIO()
     367        from sage.misc.displayhook import print_obj
     368        print_obj(s, result)
     369        if s:
     370            format_data['text/plain'] = s.getvalue().strip()
     371        return format_data
     372
     373from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
     374
     375class SageInteractiveShell(TerminalInteractiveShell):
     376    displayhook_class = SageDisplayHook #used by init_displayhook
    508377   
     378    def get_prefilter_transformer(self, cls):
     379        """
     380        Returns this shell's :class:`PrefilterTransformer` of type
     381        :class:`cls` if it has one.
     382       
     383        :param cls: the class of the transformer
     384        :type cls: a subclass of :class:`IPython.core.prefilter.PrefilterTransformer`
     385
     386        :rtype: :class:`cls`
     387        :raises: :exc:`ValueError` if the shell does not have a
     388                 :class:`PrefilterTransformer` of type :class:`cls`
     389
     390        EXAMPLES::
     391
     392            sage: from sage.misc.interpreter import get_test_shell, SagePreparseTransformer, InterfaceShellTransformer
     393            sage: shell = get_test_shell()
     394            sage: shell.get_prefilter_transformer(SagePreparseTransformer)
     395            <SagePreparseTransformer(priority=1000, enabled=True)>
     396            sage: shell.get_prefilter_transformer(InterfaceShellTransformer)
     397            Traceback (most recent call last):
     398            ...
     399            ValueError: could not find transformer InterfaceShellTransformer
     400
     401        """
     402        for transformer in self.prefilter_manager.transformers:
     403            if transformer.__class__ is cls:
     404                return transformer
     405        raise ValueError("could not find transformer %s"%cls.__name__)
     406       
     407    def init_prefilter(self):
     408        """
     409        Initialize the input transformers used by the Sage shell.
     410        Currently, we use
     411
     412          - :class:`SagePromptTransformer`
     413          - :class:`SagePreparseTransformer`
     414          - :class:`LoadAttachTransformer`
     415          - :class:`InterfaceMagicTransformer`
     416           
     417        EXAMPLES::
     418       
     419            sage: from sage.misc.interpreter import get_test_shell
     420            sage: shell = get_test_shell()
     421            sage: shell.prefilter_manager.transformers #indirect doctest
     422            [<SagePromptTransformer(priority=0, enabled=True)>,
     423             <PyPromptTransformer(priority=50, enabled=True)>,
     424             <IPyPromptTransformer(priority=50, enabled=True)>,
     425             <LoadAttachTransformer(priority=90, enabled=True)>,
     426             <AssignSystemTransformer(priority=100, enabled=True)>,
     427             <AssignMagicTransformer(priority=200, enabled=True)>,
     428             <InterfaceMagicTransformer(priority=900, enabled=True)>,
     429             <SagePreparseTransformer(priority=1000, enabled=True)>]
     430        """
     431        # Ideally, this code should be in a custom
     432        # :class:`PrefilterManager` class, but the code doesn't quite
     433        # make that clean as we'd have to reproduce the code from
     434        # :meth:`TerminalInteractiveShell.init_prefilter`
     435        super(SageInteractiveShell, self).init_prefilter()
     436       
     437        #Add the Sage input transformers
     438        for cls in [SagePreparseTransformer, SagePromptTransformer,
     439                    LoadAttachTransformer, InterfaceMagicTransformer]:
     440            t = cls(prefilter_manager=self.prefilter_manager,
     441                    shell=self, config=self.config)
     442        self.prefilter_manager.sort_transformers()
     443
     444    def run_cell(self, *args, **kwds):
     445        r"""
     446        This method loads all modified attached files before executing
     447        any code.  Any arguments and keyword arguments are passed to
     448        :meth:`TerminalInteractiveShell.run_cell`.
     449
     450        EXAMPLES::
     451
     452            sage: import os
     453            sage: from sage.misc.interpreter import get_test_shell
     454            sage: from sage.misc.misc import tmp_dir
     455            sage: shell = get_test_shell()
     456            sage: tmp = os.path.join(tmp_dir(), 'run_cell.py')
     457            sage: f = open(tmp, 'w'); f.write('a = 2\n'); f.close()
     458            sage: shell.run_cell('%attach ' + tmp)
     459            sage: shell.run_cell('a')
     460            2
     461            sage: import time; time.sleep(1)
     462            sage: f = open(tmp, 'w'); f.write('a = 3\n'); f.close()
     463            sage: shell.run_cell('a')
     464            3
     465        """
     466        for f in modified_attached_files():
     467            super(SageInteractiveShell, self).run_cell('%%load "%s"'%f)
     468        return super(SageInteractiveShell, self).run_cell(*args, **kwds)
     469
     470    def ask_exit(self):
     471        """
     472        We need to run the :func:`sage.all.quit_sage` function when we
     473        exit the shell.
     474
     475        EXAMPLES:
     476
     477        We install a fake :func:`sage.all.quit_sage`::
     478       
     479            sage: import sage.all
     480            sage: old_quit = sage.all.quit_sage
     481            sage: def new_quit(): print "Quitting..."
     482            sage: sage.all.quit_sage = new_quit
     483
     484
     485        Now, we can check to see that this method works::
     486       
     487            sage: from sage.misc.interpreter import get_test_shell
     488            sage: shell = get_test_shell()
     489            sage: shell.ask_exit()
     490            Quitting...
     491            sage: shell.exit_now
     492            True
     493
     494        Clean up after ourselves::
     495
     496            sage: shell.exit_now = False
     497            sage: sage.all.quit_sage = old_quit
     498        """
     499        from sage.all import quit_sage
     500        quit_sage()
     501        super(SageInteractiveShell, self).ask_exit()
     502
     503    def system_raw(self, cmd):
     504        """
     505        Adjust the libraries before calling system commands.  See Trac
     506        #975 for a discussion of this function.
     507
     508        .. note::
     509
     510           There does not seem to be a good way to doctest this
     511           function.
     512        """
     513        sage_commands = os.listdir(os.environ['SAGE_ROOT']+"/local/bin/")
     514        DARWIN_SYSTEM = os.uname()[0]=='Darwin'
     515        if cmd in sage_commands:
     516            return super(SageInteractiveShell, self).system_raw(cmd)
     517        else:
     518            libraries = 'LD_LIBRARY_PATH=$$SAGE_ORIG_LD_LIBRARY_PATH;'
     519            if DARWIN_SYSTEM:
     520                libraries += 'DYLD_LIBRARY_PATH=$$SAGE_ORIG_DYLD_LIBRARY_PATH;'
     521            return super(SageInteractiveShell, self).system_raw(cmd)
     522   
     523    #######################################
     524    # Magic functions
     525    #######################################
     526    def magic_timeit(self, s):
     527        """
     528        Runs :func:`sage_timeit` on the code s.  This is designed to
     529        be used from the command line as ``%timeit 2+2``.
     530
     531        :param s: code to be timed
     532        :type s: string
     533
     534        EXAMPLES::
     535
     536            sage: from sage.misc.interpreter import get_test_shell
     537            sage: shell = get_test_shell()
     538            sage: shell.magic_timeit('2+2') #random output
     539            625 loops, best of 3: 525 ns per loop
     540            sage: shell.magic_timeit('2r+2r').__class__
     541            <class sage.misc.sage_timeit.SageTimeitResult at 0x...>
     542        """
     543        from sage.misc.sage_timeit import sage_timeit
     544        return sage_timeit(s, self.user_ns)
     545
     546    def magic_prun(self, parameter_s='', **kwds):
     547        """
     548        Profiles the code contained in ``parameter_s``. This is
     549        designed to be used from the command line as ``%prun 2+2``.
     550
     551        :param parameter_s: code to be profiled
     552        :type parameter_s: string
     553
     554        EXAMPLES::
     555
     556            sage: from sage.misc.interpreter import get_test_shell
     557            sage: shell = get_test_shell()
     558            sage: shell.magic_prun('2+2')
     559                     2 function calls in 0.000 CPU seconds
     560            <BLANKLINE>
     561               Ordered by: internal time
     562            <BLANKLINE>
     563               ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     564                    1    0.000    0.000    0.000    0.000 <string>:1(<module>)
     565                    1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
     566        """
     567        return super(SageInteractiveShell, self).magic_prun(parameter_s=preparse(parameter_s),
     568                                                            **kwds)
     569
     570    def magic_load(self, s):
     571        r"""     
     572        Loads the code contained in the file ``s``. This is designed
     573        to be used from the command line as ``%load /path/to/file``.
     574
     575        :param s: file to be loaded
     576        :type s: string
     577
     578        EXAMPLES::
     579
     580            sage: import os
     581            sage: from sage.misc.interpreter import get_test_shell
     582            sage: from sage.misc.misc import tmp_dir
     583            sage: shell = get_test_shell()
     584            sage: tmp = os.path.join(tmp_dir(), 'run_cell.py')
     585            sage: f = open(tmp, 'w'); f.write('a = 2\n'); f.close()
     586            sage: shell.magic_load(tmp)
     587            sage: shell.run_cell('a')
     588            2
     589        """
     590        from sage.misc.preparser import load_wrap
     591        return self.ex(load_wrap(s, attach=False))
     592
     593    def magic_attach(self, s):
     594        r"""     
     595        Attaches the code contained in the file ``s``. This is
     596        designed to be used from the command line as
     597        ``%attach /path/to/file``.
     598
     599        :param s: file to be attached
     600        :type s: string
     601
     602        EXAMPLES::
     603
     604            sage: import os
     605            sage: from sage.misc.interpreter import get_test_shell
     606            sage: from sage.misc.misc import tmp_dir
     607            sage: shell = get_test_shell()
     608            sage: tmp = os.path.join(tmp_dir(), 'run_cell.py')
     609            sage: f = open(tmp, 'w'); f.write('a = 2\n'); f.close()
     610            sage: shell.magic_attach(tmp)
     611            sage: shell.run_cell('a')
     612            2
     613            sage: import time; time.sleep(1)
     614            sage: f = open(tmp, 'a'); f.write('a = 3\n'); f.close()
     615            sage: shell.run_cell('a')
     616            3
     617        """
     618        from sage.misc.preparser import load_wrap
     619        return self.ex(load_wrap(s, attach=True))
     620
     621    def magic_iload(self, s):
     622        """
     623        A magic command to interactively load a file as in MAGMA.
     624
     625        :param s: the file to be interactively loaded
     626        :type s: string
     627
     628        .. note::
     629
     630           Currently, this cannot be doctested as it relies on
     631           :func:`raw_input`.
     632        """
     633        try:
     634            name = str(eval(s))
     635        except Exception:
     636            name = s.strip()
     637
     638        try:
     639            F = open(name)
     640        except IOError:
     641            raise ImportError, 'could not open file "%s"'%name
     642
     643        #We need to update the execution count so that the history for the
     644        #iload command and the history for the first line of the loaded
     645        #file are not written to the history database with the same line
     646        #number (execution count).  This happens since the execution count
     647        #is updated only after the magic command is run.
     648        self.execution_count += 1
     649
     650        print 'Interactively loading "%s"'%name
     651
     652        # The following code is base on IPython's
     653        # InteractiveShell.interact,
     654        more = False
     655        for line in F.readlines():
     656            prompt = self.prompt_manager.render('in' if not more else 'in2', color=True)
     657            raw_input(prompt.encode('utf-8') + ' ' + line.rstrip())
     658
     659            self.input_splitter.push(line)
     660            more = self.input_splitter.push_accepts_more()
     661            if not more:
     662                source, source_raw = self.input_splitter.source_raw_reset()
     663                self.run_cell(source_raw, store_history=True)
     664
     665#######################################################
     666# Transformers - these modify the command line input before it gets
     667# evaluated by the interpreter. See IPython.core.prefilter f
     668#######################################################
     669from IPython.core.prefilter import PrefilterTransformer
     670
     671class SagePreparseTransformer(PrefilterTransformer):
     672    """
     673    This transformer preparses the line of code before it get
     674    evaluated by IPython.
     675    """
     676    priority = 1000
     677    def transform(self, line, continue_prompt):
     678        """
     679        Preparse *line* if necessary.
     680
     681        :param line: the line to be transformed
     682        :type line: string
     683        :param continue_prompt: is this line a continuation in a sequence of multiline input?
     684        :type continue_prompt: bool
     685
     686        EXAMPLES::
     687
     688            sage: from sage.misc.interpreter import get_test_shell, SagePreparseTransformer
     689            sage: shell = get_test_shell()
     690            sage: spt = shell.get_prefilter_transformer(SagePreparseTransformer); spt
     691            <SagePreparseTransformer(priority=1000, enabled=True)>
     692            sage: spt.transform('2', False)
     693            'Integer(2)'
     694            sage: shell.run_cell('preparser(False)')
     695            sage: spt.transform('2', False)
     696            '2'
     697            sage: shell.run_cell('preparser(True)')
     698        """
     699        if do_preparse and not line.startswith('%'):
     700            return preparse(line)
     701        else:
     702            return line
     703
     704class LoadAttachTransformer(PrefilterTransformer):
     705    r"""
     706    This transformer handles input lines that start out like
     707    ``load ...`` for ``attach ...``.  Since there are objects in the
     708    Sage namespace named ``load`` and ``attach``, IPython's automagic
     709    will not transform these lines into ``%load ...`` and
     710    ``%attach ...``, respectively.  Thus, we have to do it manually.
     711    """
     712    priority = 90
     713    def transform(self, line, continue_prompt):
     714        """
     715        :param line: the line to be transformed
     716        :type line: string
     717        :param continue_prompt: is this line a continuation in a sequence of multiline input?
     718        :type continue_prompt: bool
     719
     720        EXAMPLES::
     721
     722            sage: from sage.misc.interpreter import get_test_shell, LoadAttachTransformer
     723            sage: shell = get_test_shell()
     724            sage: lat = shell.get_prefilter_transformer(LoadAttachTransformer); lat
     725            <LoadAttachTransformer(priority=90, enabled=True)>
     726            sage: lat.transform('load /path/to/file', False)
     727            '%load /path/to/file'
     728            sage: lat.transform('attach /path/to/file', False)
     729            '%attach /path/to/file'
     730        """
     731        for cmd in ['load', 'attach']:
     732            if line.startswith(cmd + ' '):
     733                return '%' + line
     734        return line
     735   
     736class SagePromptTransformer(PrefilterTransformer):
     737    """
     738    This transformer removes Sage prompts from the imput line.
     739    """
     740    _sage_prompt_re = re.compile(r'(^[ \t]*sage: |^[ \t]*\.+: )+')
     741
     742    priority = 0
     743    def transform(self, line, continue_prompt):
     744        """
     745        :param line: the line to be transformed
     746        :type line: string
     747        :param continue_prompt: is this line a continuation in a sequence of multiline input?
     748        :type continue_prompt: bool
     749
     750        EXAMPLES::
     751
     752            sage: from sage.misc.interpreter import get_test_shell, SagePromptTransformer
     753            sage: shell = get_test_shell()
     754            sage: spt = shell.get_prefilter_transformer(SagePromptTransformer); spt
     755            <SagePromptTransformer(priority=0, enabled=True)>
     756            sage: spt.transform("sage: sage: 2 + 2", False)
     757            '2 + 2'
     758            sage: spt.transform('', False)
     759            ''
     760            sage: spt.transform("      sage: 2+2", False)
     761            '2+2'
     762
     763        """
     764        if not line or line.isspace() or line.strip() == '...':
     765            # This allows us to recognize multiple input prompts separated by
     766            # blank lines and pasted in a single chunk, very common when
     767            # pasting doctests or long tutorial passages.
     768            return ''
     769        while True:
     770            m = self._sage_prompt_re.match(line)
     771            if m:
     772                line = line[len(m.group(0)):]
     773            else:
     774                break
     775        return line
     776
     777class InterfaceMagicTransformer(PrefilterTransformer):
     778    """
     779    This transformer is for handling commands like ``%maxima`` which
     780    are designed to go into a Maxima shell.  This one is tricky since
     781    the magic commands are transformed in
     782    :mod:`IPython.core.inputsplitter` before they can even go into the
     783    :class:`PrefilterTransformer` framework.  Thus, we need to match
     784    the output of those transformations instead of something simple
     785    like ``"%maxima"``.
     786
     787    .. note::
     788
     789        This will only work if the corresponding object is of type
     790        :class:`sage.interfaces.interface.Interface`.
     791    """
     792    priority = 900
     793    _magic_command_re = re.compile(r"get_ipython\(\).magic\(u'([^\d\W]\w+)'\)", re.UNICODE)
     794    def transform(self, line, continue_prompt):
     795        """
     796        :param line: the line to be transformed
     797        :type line: string
     798        :param continue_prompt: is this line a continuation in a sequence of multiline input?
     799        :type continue_prompt: bool
     800
     801        EXAMPLES::
     802
     803            sage: from sage.misc.interpreter import get_test_shell, InterfaceMagicTransformer
     804            sage: shell = get_test_shell()
     805            sage: imt = shell.get_prefilter_transformer(InterfaceMagicTransformer); imt
     806            <InterfaceMagicTransformer(priority=900, enabled=True)>
     807            sage: imt.transform("get_ipython().magic(u'maxima')", False)
     808            'maxima.interact()'
     809            sage: imt.transform("get_ipython().magic(u'prun')", False)
     810            "get_ipython().magic(u'prun')"
     811        """
     812        match = self._magic_command_re.match(line)
     813        if match:
     814            interface, = match.groups()
     815            from sage.interfaces.interface import Interface
     816            if isinstance(self.shell.user_ns.get(interface, None), Interface):
     817                return interface + '.interact()'
     818        return line
     819
     820###################
     821# Interface shell #
     822###################
     823from IPython.frontend.terminal.embed import InteractiveShellEmbed
     824from IPython import Config
     825
     826class InterfaceShellTransformer(PrefilterTransformer):
     827    priority = 50
     828    def __init__(self, *args, **kwds):
     829        """
     830        Initialize this class.  All of the arguments get passed to
     831        :meth:`PrefilterTransformer.__init__`.
     832
     833        .. attribute::  lines_queue
     834
     835            a list of lines to be evaluated
     836
     837        .. attribute:: temporary_objects
     838
     839           a list of hold onto interface objects and keep them from being
     840           garbage collected
     841
     842        .. seealso:: :func:`interface_shell_embed`
     843
     844        EXAMPLES::
     845
     846            sage: from sage.misc.interpreter import interface_shell_embed, InterfaceShellTransformer
     847            sage: shell = interface_shell_embed(maxima)
     848            sage: ift = InterfaceShellTransformer(shell=shell, config=shell.config, prefilter_manager=shell.prefilter_manager)
     849            sage: ift.lines_queue
     850            []
     851            sage: ift.temporary_objects
     852            []
     853            sage: ift._sage_import_re.findall('sage(a) + maxima(b)')
     854            ['a', 'b']
     855        """
     856        super(InterfaceShellTransformer, self).__init__(*args, **kwds) 
     857        self.lines_queue = []
     858        self.temporary_objects = []
     859        self._sage_import_re = re.compile(r'(?:sage|%s)\((.*?)\)'%self.shell.interface.name())
     860
     861    def preparse_imports_from_sage(self, line):
     862        """
     863        Finds occurrences of strings such as ``sage(object)`` in
     864        *line*, converts ``object`` to :attr:`shell.interface`,
     865        and replaces those strings with their identifier in the new
     866        system.  This also works with strings such as
     867        ``maxima(object`` if :attr:`shell.interface` is
     868        ``maxima``.
     869       
     870        :param line: the line to transform
     871        :type line: string
     872
     873        .. warning::
     874           
     875            This does not parse nested parentheses correctly.  Thus,
     876            lines like ``sage(a.foo())`` will not work correctly.
     877            This can't be done in generality with regular expressions.
     878
     879        EXAMPLES::
     880
     881            sage: from sage.misc.interpreter import interface_shell_embed, InterfaceShellTransformer
     882            sage: maxima.quit()
     883            sage: shell = interface_shell_embed(maxima)
     884            sage: ift = InterfaceShellTransformer(shell=shell, config=shell.config, prefilter_manager=shell.prefilter_manager)
     885            sage: ift.shell.ex('a = 3')
     886            sage: ift.preparse_imports_from_sage('2 + sage(a)')
     887            '2 + sage0 '
     888            sage: maxima.eval('sage0')
     889            '3'
     890            sage: ift.preparse_imports_from_sage('2 + maxima(a)')
     891            '2 +  sage1 '
     892            sage: ift.preparse_imports_from_sage('2 + gap(a)')
     893            '2 + gap(a)'
     894        """
     895        from sage_eval import sage_eval
     896        for sage_code in self._sage_import_re.findall(line):
     897            expr = preparse(sage_code)
     898            result = self.shell.interface(sage_eval(expr, self.shell.user_ns))
     899            self.temporary_objects.append(result)
     900            line = self._sage_import_re.sub(' ' + result.name() + ' ', line, 1)
     901        return line
     902
     903    def transform(self, line, continue_prompt):
     904        r'''
     905        Evaluates *line* in :attr:`shell.interface` and returns a
     906        string representing the result of that evaluation.  If a line
     907        ends in backspace, then this method will store *line* in
     908        :attr:`lines_queue` until it receives a line not ending in
     909        backspace.
     910       
     911        :param line: the line to be transformed *and evaluated*
     912        :type line: string
     913        :param continue_prompt: is this line a continuation in a sequence of multiline input?
     914        :type continue_prompt: bool
     915
     916        EXAMPLES::
     917
     918            sage: from sage.misc.interpreter import interface_shell_embed, InterfaceShellTransformer
     919            sage: maxima.quit()
     920            sage: shell = interface_shell_embed(maxima)
     921            sage: ift = InterfaceShellTransformer(shell=shell, config=shell.config, prefilter_manager=shell.prefilter_manager)
     922            sage: ift.transform('2+2', False)
     923            'sage.misc.all.logstr("""4""")'
     924            sage: ift.shell.ex('a = 4')
     925            sage: ift.transform(r'sage(a)+\\', False)
     926            sage: ift.shell.prompt_manager.in_template
     927            u'....: '
     928            sage: ift.lines_queue
     929            [' sage0+']
     930            sage: ift.temporary_objects
     931            sage: ift.transform('4', False)
     932            'sage.misc.all.logstr("""8""")'
     933            sage: ift.lines_queue
     934            []
     935            sage: ift.temporary_objects
     936            []
     937
     938            sage: shell = interface_shell_embed(gap)
     939            sage: ift = InterfaceShellTransformer(shell=shell, config=shell.config, prefilter_manager=shell.prefilter_manager)
     940            sage: ift.transform('2+2', False)
     941            'sage.misc.all.logstr("""4""")'
     942        '''
     943        line = self.preparse_imports_from_sage(line)
     944        line = line.rstrip()
     945        if line.endswith('\\'):
     946            line = line.strip('\\')
     947            self.lines_queue.append(line)
     948            #TODO: This should beter handled by getting IPython to
     949            #switch to a continuation prompt
     950            self.shell.prompt_manager.in_template = self.shell.prompt_manager.in2_template
     951        else:
     952            self.lines_queue.append(line)
     953            line = "".join(self.lines_queue)
     954
     955            if self.shell.interface.name() in ['gap', 'magma', 'kash', 'singular']:
     956                if not line.endswith(';'):
     957                    line += ';'
     958            elif self.shell.interface.name() == 'mathematica':
     959                line = 'InputForm[%s]'%line
     960
     961            t = self.shell.interface.eval(line)
     962
     963            #Once we've evaluated the lines, we can clear the queue
     964            #and temporary objects and switch the prompt back
     965            self.lines_queue = []
     966            self.temporary_objects = []
     967            self.shell.prompt_manager.in_template = self.shell.interface.name() + ': '
     968            return 'sage.misc.all.logstr("""%s""")'%t.strip()
     969           
     970def interface_shell_embed(interface):
     971    """
     972    Returns an IPython shell which uses a Sage interface on the
     973    backend to perform the evaluations.  It uses
     974    :class:`InterfaceShellTransformer` to transform the input into the
     975    appropriate ``interface.eval(...)`` input.
     976
     977    EXAMPLES::
     978
     979        sage: from sage.misc.interpreter import interface_shell_embed
     980        sage: shell = interface_shell_embed(maxima)
     981        sage: shell.run_cell('integrate(sin(x), x)')
     982        -cos(x)
     983    """
     984    cfg = Config()
     985    cfg.PromptManager.in_template = interface.name() + ': '
     986    cfg.PromptManager.in2_template = u'....: '
     987    cfg.PromptManager.out_template = u''
     988    cfg.PromptManager.justify = False
     989    cfg.InteractiveShell.confirm_exit = False
     990
     991    ipshell = InteractiveShellEmbed(config=cfg,
     992                                    banner1='\n  --> Switching to %s <--\n'%interface,
     993                                    exit_msg = '\n  --> Exiting back to Sage <--\n')
     994    ipshell.interface = interface
     995
     996    #TODO: The following lines "should" be in the config
     997    ipshell.prompt_manager.color_scheme = 'NoColor'
     998    ipshell.separate_in = u''
     999
     1000    while ipshell.prefilter_manager.transformers:
     1001        ipshell.prefilter_manager.transformers.pop()
     1002    while ipshell.prefilter_manager.checkers:
     1003        ipshell.prefilter_manager.checkers.pop()
     1004    for cls in [InterfaceShellTransformer]:
     1005        cls(shell=ipshell, prefilter_manager=ipshell.prefilter_manager,
     1006            config=cfg)
     1007       
     1008    ipshell.ex('from sage.all import *')
     1009
     1010    return ipshell
     1011   
     1012def get_test_shell():
     1013    """
     1014    Returns a IPython shell that can be used in testing the functions
     1015    in this module.
     1016
     1017    :keyword sage_ext: load the Sage extension
     1018    :type sage_ext: bool
     1019    :returns: an IPython shell
     1020
     1021    EXAMPLES::
     1022
     1023        sage: from sage.misc.interpreter import get_test_shell
     1024        sage: shell = get_test_shell(); shell
     1025        <sage.misc.interpreter.SageInteractiveShell object at 0x...>
     1026    """
     1027    app = SageTerminalApp.instance()
     1028    app.test_shell = True
     1029    if app.shell is None:
     1030        app.initialize()
     1031    return app.shell
     1032
     1033
     1034#######################
     1035# IPython TerminalApp #
     1036#######################
     1037from IPython.frontend.terminal.ipapp import TerminalIPythonApp, IPAppCrashHandler
     1038from IPython.core.crashhandler import CrashHandler
     1039from IPython import Config
     1040
     1041class SageCrashHandler(IPAppCrashHandler):
     1042    def __init__(self, app):
     1043        """
     1044        A custom :class:`CrashHandler` which gives the user
     1045        instructions on how to post the problem to sage-support.
     1046       
     1047        EXAMPLES::
     1048
     1049            sage: from sage.misc.interpreter import SageTerminalApp, SageCrashHandler
     1050            sage: app = SageTerminalApp.instance()
     1051            sage: sch = SageCrashHandler(app); sch
     1052            <sage.misc.interpreter.SageCrashHandler object at 0x...>
     1053            sage: sorted(sch.info.items())
     1054            [('app_name', u'Sage'),
     1055             ('bug_tracker', 'http://trac.sagemath.org/sage_trac'),
     1056             ('contact_email', 'sage-support@googlegroups.com'),
     1057             ('contact_name', 'sage-support'),
     1058             ('crash_report_fname', u'Crash_report_Sage.txt')]
     1059        """
     1060        contact_name = 'sage-support'
     1061        contact_email = 'sage-support@googlegroups.com'
     1062        bug_tracker = 'http://trac.sagemath.org/sage_trac'
     1063        CrashHandler.__init__(self,
     1064            app, contact_name, contact_email, bug_tracker, show_crash_traceback=False
     1065        )
     1066        self.crash_report_fname = 'Sage_crash_report.txt'
     1067
     1068class SageTerminalApp(TerminalIPythonApp):
     1069    name = u'Sage'
     1070    ignore_old_config = True
     1071    crash_handler_class = SageCrashHandler
     1072    verbose_crash = True #Needed to use Sage Crash Handler
     1073    display_banner = False
     1074    test_shell = False
     1075   
     1076    DEFAULT_SAGE_CONFIG = Config({'PromptManager': {'in_template': u'sage: ',
     1077                                                    'in2_template': u'....: ',
     1078                                                    'out_template': u'',
     1079                                                    'justify': False},
     1080                                  'InteractiveShell': {'separate_in': u'',
     1081                                                       'colors': 'NoColor'},
     1082                                  })
     1083
     1084    def init_shell(self):
     1085        r"""
     1086        Initialize the :class:`SageInteractiveShell` instance.
     1087        Additionally, this also does the following:
     1088
     1089          - Merges the default shell configuration with the user's.
     1090         
     1091          - Monkey-patch :mod:`IPython.core.oinspect` to add Sage
     1092            introspection functions.
     1093
     1094          - Run additional Sage startup code.
     1095         
     1096        .. note::
     1097
     1098            This code is based on
     1099            :meth:`TermintalIPythonApp.init_shell`.
     1100
     1101        EXAMPLES::
     1102
     1103            sage: from sage.misc.interpreter import SageTerminalApp
     1104            sage: app = SageTerminalApp.instance()
     1105            sage: app.initialize() #indirect doctest
     1106            sage: app.shell
     1107            <sage.misc.interpreter.SageInteractiveShell object at 0x...>
     1108        """
     1109        sys.path.insert(0, '')
     1110
     1111        # Overwrite the default Sage configuration with the user's.
     1112        new_config = Config()
     1113        new_config._merge(self.DEFAULT_SAGE_CONFIG)
     1114        new_config._merge(self.config)
     1115
     1116        # Shell initialization
     1117        self.shell = SageInteractiveShell.instance(config=new_config,
     1118                        display_banner=False, profile_dir=self.profile_dir,
     1119                        ipython_dir=self.ipython_dir)
     1120        self.shell.configurables.append(self)
     1121
     1122
     1123        # Ideally, these would just be methods of the Inspector class
     1124        # that we could override; however, IPython looks them up in
     1125        # the global :class:`IPython.core.oinspect` module namespace.
     1126        # Thus, we have to monkey-patch.
     1127        import sagedoc, sageinspect, IPython.core.oinspect
     1128        IPython.core.oinspect.getdoc = sagedoc.my_getdoc
     1129        IPython.core.oinspect.getsource = sagedoc.my_getsource
     1130        IPython.core.oinspect.getargspec = sageinspect.sage_getargspec
     1131
     1132
     1133        from sage.misc.edit_module import edit_devel
     1134        self.shell.set_hook('editor', edit_devel)
     1135
     1136        if 'SAGE_CLEAN' in os.environ:
     1137            return
     1138       
     1139        # Additional initalization code
     1140        preparser(True)
     1141        os.chdir(os.environ["CUR"])
     1142
     1143        from sage.misc.misc import branch_current_hg_notice, branch_current_hg
     1144        branch = branch_current_hg_notice(branch_current_hg())
     1145        if branch and self.test_shell is False:
     1146            print branch
     1147
     1148        self.shell.ex('from sage.all import Integer, RealNumber')
     1149        self.shell.push(dict(sage_prompt=sage_prompt))
     1150
     1151        if os.environ.get('SAGE_IMPORTALL', 'yes') != "no":
     1152            self.shell.ex('from sage.all_cmdline import *')
     1153
     1154        startup_file = os.environ.get('SAGE_STARTUP_FILE', '')
     1155        if os.path.exists(startup_file):
     1156            self.shell.run_cell('%%load "%s"'%startup_file)
  • sage/misc/preparser.py

    diff --git a/sage/misc/preparser.py b/sage/misc/preparser.py
    a b  
    11371137## Apply the preparser to an entire file
    11381138######################################################
    11391139
     1140#TODO: This global variable attached should be associtated with an
     1141#IPython InteractiveShell as opposed to a global variable in this
     1142#module.
    11401143attached = {}
    11411144
    11421145load_debug_mode = False
  • deleted file sage/misc/preparser_ipython.py

    diff --git a/sage/misc/preparser_ipython.py b/sage/misc/preparser_ipython.py
    deleted file mode 100644
    + -  
    1 ###########################################################################
    2 #       Copyright (C) 2006 William Stein <wstein@gmail.com>
    3 #
    4 #  Distributed under the terms of the GNU General Public License (GPL)
    5 #                  http://www.gnu.org/licenses/
    6 ###########################################################################
    7 
    8 import sage.misc.interpreter
    9 
    10 import preparser
    11 
    12 interface_name  = 'sage'
    13 interface       = None
    14 num_lines       = 0
    15 
    16 # TODO: Do this right?
    17 magma_colon_equals = False
    18 
    19 q_lines = []
    20 
    21 
    22 def switch_interface_general(new_interface, verbose=True):
    23     global interface
    24     global interface_name
    25     if not (interface is None):
    26         interface._post_interact()
    27     interface = new_interface
    28     interface_name = new_interface.name().lower()
    29     sage.misc.interpreter.set_sage_prompt('%s'%interface_name)
    30     if verbose:
    31         print "\n  --> Switching to %s <-- \n"%interface
    32     interface._pre_interact()
    33 
    34 def switch_interface(name, verbose=True):
    35     I = __import__('sage.interfaces.all',{},{},name)
    36     if not name in I.interfaces:
    37         raise RuntimeError, "Invalid interface %s"%name
    38     sage.misc.interpreter.PROMPT = '%s'%name
    39    
    40     global interface, interface_name
    41     interface_name = name
    42     if name == 'sage':
    43         interface = None
    44         if verbose:
    45             print "\n  --> Exiting back to Sage <-- \n"
    46     else:
    47         if not (interface is None):
    48             interface._post_interact()
    49         interface = I.__dict__[name]
    50         if verbose:
    51             print "\n  --> Switching to %s <-- \n"%interface
    52         interface._pre_interact()
    53         if name in ['kash']:
    54             interface('0')     # hack that works.
    55            
    56     sage.misc.interpreter.set_sage_prompt('%s'%interface_name)
    57 
    58 def preparse_ipython(line, reset=True):
    59     """
    60     TESTS:
    61        
    62         Make sure #10933 is fixed
    63        
    64     ::
    65    
    66         sage: sage.misc.preparser_ipython.preparse_ipython("def foo(str):\n   time gp(str)\n\nprint gp('1')")
    67         'def foo(str):\n   __time__=misc.cputime(); __wall__=misc.walltime(); gp(str); print "Time: CPU %.2f s, Wall: %.2f s"%(misc.cputime(__time__), misc.walltime(__wall__))\n\nprint gp(\'1\')'
    68 
    69     """
    70     global num_lines
    71     global q_lines
    72    
    73     L = line.lstrip()
    74     if L.startswith('%'):
    75         # This should be installed as an Ipython magic command,
    76         # but I don't know how yet...
    77         L = L[1:].strip()
    78         import sage.interfaces.all
    79         if L.lower() in sage.interfaces.all.interfaces:
    80             switch_interface(L.lower())
    81             return "''"
    82         else:
    83             # only preparse non-magic lines
    84             return line
    85 
    86        
    87     if interface is None:
    88     #We could remove do_time=True if #10933 get's fixed upstream
    89         return preparser.preparse(line, reset=reset, do_time=True)
    90 
    91     if L.startswith('?') or L.endswith('?'):
    92         L = L.strip('?')
    93         interface.help(L)
    94         return ''
    95 
    96     line = preparse_imports_from_sage(interface, line)
    97     line = line.rstrip()
    98     ends_in_backslash = line.endswith('\\')
    99     if ends_in_backslash:
    100         line = line.rstrip('\\')
    101         num_lines += 1
    102     else:
    103         if interface_name in ['gap', 'magma', 'kash', 'singular']:
    104             if not line.endswith(';'):
    105                 line += ';'
    106         elif interface_name == 'mathematica':
    107             line = 'InputForm[%s]'%line
    108 
    109     if ends_in_backslash:
    110         q_lines.append(line)
    111     else:
    112         if len(q_lines) > 0:
    113             line = ''.join(q_lines) + line
    114         q_lines = []
    115         # TODO: do sage substitutions here
    116         #t = interface._eval_line(line)
    117         t = interface.eval(line)
    118        
    119     import sage.misc.interpreter
    120     if ends_in_backslash:
    121 
    122         sage.misc.interpreter.set_sage_prompt('.'*len(interface_name))
    123    
    124     else:
    125 
    126         sage.misc.interpreter.set_sage_prompt('%s'%interface_name)
    127         #print t
    128         #__IPYTHON__.output_hist[len(__IPYTHON__.input_hist_raw)] = t
    129 
    130     # TODO: this is a very lazy temporary bug fix.
    131     # Nobody uses this logging stuff anymore, anyways, because
    132     # of the Sage notebook.
    133     try:
    134         return """logstr(%r)"""%t
    135     except UnboundLocalError:
    136         return 'logstr("")'
    137 
    138 
    139 _v_ = None
    140 
    141 def preparse_imports_from_sage(interface, line, locals={}):
    142     """
    143     The input line is being fed to the given interface.
    144     This function extracts any "sage(zzz)"'s, parses
    145     them, and replaces them by appropriate objects
    146     in the interface.   This is used for moving
    147     objects from Sage back into the interface.
    148     """
    149     import sage_eval
    150     i = line.find('%s('%interface_name)
    151     n = len(interface_name)
    152     if i == -1:
    153         i = line.find('sage(')
    154         n = 4
    155         if i == -1:
    156             return line
    157     j = i + line[i:].find(')')
    158     expr = line[i+n+1:j]
    159     expr = preparser.preparse(expr)
    160     s = 'import sage.misc.preparser_ipython; \
    161          sage.misc.preparser_ipython._v_ = sage.misc.preparser_ipython.interface(%s)'%expr
    162     #print s
    163     __IPYTHON__.runsource(s)
    164     #print _v_
    165     line = line[:i] + _v_.name() + line[j+2:]
    166     return line
    167    
  • sage/misc/sage_unittest.py

    diff --git a/sage/misc/sage_unittest.py b/sage/misc/sage_unittest.py
    a b  
    105105
    106106     - Don't catch the exceptions if ``TestSuite(..).run()`` is called
    107107       under the debugger, or with ``%pdb`` on (how to detect this? see
    108        ``IPython.ipapi.get()``, ``IPython.Magic.shell.call_pdb``, ...)
     108       ``get_ipython()``, ``IPython.Magic.shell.call_pdb``, ...)
    109109       In the mean time, see the ``catch=False`` option.
    110110
    111111     - Run the tests according to the inheritance order, from most
  • sage/misc/trace.py

    diff --git a/sage/misc/trace.py b/sage/misc/trace.py
    a b  
    7575    if EMBEDDED_MODE:
    7676        raise NotImplementedError, "the trace command is not implemented in the Sage notebook; you must use the command line."
    7777
    78     import IPython.Debugger
    79     pdb = IPython.Debugger.Pdb()
     78    from IPython.core.debugger import Pdb
     79    pdb = Pdb()
    8080   
    81     import IPython.ipapi
    82     _ip = IPython.ipapi.get()
    83        
     81    try:
     82        ipython = get_ipython()
     83    except NameError:
     84        raise NotImplementedError("the trace command can only be run from the Sage command-line")
     85               
    8486    import preparser
    85 
    8687    code = preparser.preparse(code)
    87     return pdb.run(code, _ip.user_ns)
     88    return pdb.run(code, ipython.user_ns)
    8889   
    8990    # this could also be useful; it drops
    9091    # us into a debugger in an except block:
  • sage/structure/parent.pyx

    diff --git a/sage/structure/parent.pyx b/sage/structure/parent.pyx
    a b  
    310310        ...
    311311        AttributeError: 'sage.rings.integer.Integer' object has no attribute '__weakref__'
    312312        sage: import IPython
    313         sage: _ip = IPython.ipapi.get()
    314         sage: _ip.IP.magic_psearch('n.__weakref__') # not tested: only works with an interactive shell running
     313        sage: ipython = get_ipython()
     314        sage: ipython.magic_psearch('n.__weakref__') # not tested: only works with an interactive shell running
    315315
    316316    Caveat: When __call__ is not defined for instances, using
    317317    ``A.__call__`` yields the method ``__call__`` of the class. We use