Ticket #12719: trac_12719_ipython_fixes.patch

File trac_12719_ipython_fixes.patch, 37.1 KB (added by jason, 9 years ago)

Updated patch

  • sage/all_cmdline.py

    # HG changeset patch
    # User Volker Braun <vbraun@stp.dias.ie>
    # Date 1338182716 25200
    # Node ID 50079a5fe44d9b00941350d773dd51be85234e45
    # Parent  30c7a8f0d56f66375da5531b16618b9472fe2514
    Some smaller fixes to the new IPython:
      * install the Sage displayhook into python again
      * fix pasting of Sage doctests
    
    diff --git a/sage/all_cmdline.py b/sage/all_cmdline.py
    a b  
     1"""
     2all_cmdline.py
     3   
     4This is all.py (load all sage functions) plus set-up for the Sage commandline.
     5"""
     6
    17#############################################################################
    28#       Copyright (C) 2007 William Stein <wstein@gmail.com>
    39#  Distributed under the terms of the GNU General Public License (GPL)
     
    2329        msg = str(msg) + '\n\n** In Sage, the easiest fix for this problem is to type "sage -ba"\n   to rebuild all the Cython code (this takes several minutes).\n   Alternatively, touch the last .pyx file in the traceback above. **\n'
    2430    raise ValueError(msg)
    2531
    26 
    2732sage.misc.session.init()
    2833
     34import sage.misc.displayhook
     35sage.misc.displayhook.install()
     36
     37
  • sage/misc/displayhook.py

    diff --git a/sage/misc/displayhook.py b/sage/misc/displayhook.py
    a b  
    168168    __builtin__._ = None
    169169    print_obj(sys.stdout, obj)
    170170    __builtin__._ = obj
     171
     172
     173def install():
     174    """
     175    Install the Sage displayhook into Python
     176
     177    In a full Sage session, IPython will override this setting later
     178    during the startup. But if you run `from sage.all_cmdline import *`
     179    in a python session, then this function will determine the
     180    displayhook. Importantly, this is what the doctest runner does!
     181   
     182    TESTS::
     183   
     184        sage: sys.displayhook
     185        <function displayhook at 0x...>
     186
     187    Note that you will get a `sage.misc.interpreter.SageDisplayHook`
     188    object if you run this in an interactive Sage shell. At some point
     189    in the future, the doctest framework will actually run in a Sage
     190    shell and this doctest will change.
     191    """
     192    sys.displayhook = displayhook
     193
  • sage/misc/interpreter.py

    diff --git a/sage/misc/interpreter.py b/sage/misc/interpreter.py
    a b  
    3535accepting input from the user and evaluating it.  From the command-line,
    3636this object can be retrieved by running::
    3737
    38     sage: shell = get_ipython() #not tested
     38    sage: shell = get_ipython()   # not tested
    3939
    4040The :class:`SageInteractiveShell` provides the following
    4141customizations:
    4242
    43   - Modifying the input before it is evaluated.  See
     43  - Modifying the input before it is evaluated. This is done in
     44    :class:`SageInputSplitter`, which uses
    4445    :class:`SagePromptTransformer`, :class:`SagePreparseTransformer`,
    45     :class:`LoadAttachTransformer`,
    46     :class:`InterfaceMagicTransformer`, and
    47     :meth:`~SageInteractiveShell.init_prefilter`.
     46    :class:`LoadAttachTransformer`, and
     47    :class:`InterfaceMagicTransformer` to do the actual work.
    4848
    4949  - Provide a number of IPython magic functions that work with Sage
    5050    and its preparser.  See :meth:`~SageInteractiveShell.magic_timeit`,
     
    7171that shell.  The bulk of this functionality is provided through
    7272:class:`InterfaceShellTransformer`.
    7373
    74 Auto-generated Documentation
    75 ----------------------------
    7674"""
    7775
    7876#*****************************************************************************
     
    8381#                  http://www.gnu.org/licenses/
    8482#*****************************************************************************
    8583import os, log, re, new, sys
     84from IPython.utils.py3compat import cast_unicode
     85from IPython.utils.traitlets import (Integer, CBool, CaselessStrEnum, Enum,
     86                                     List, Unicode, Instance, Type)
    8687from preparser import (preparse, preparse_file, load_wrap,
    8788                       modified_attached_files, attached_files)
    8889
     
    99100    import sage.server.support
    100101    return sage.server.support.EMBEDDED_MODE
    101102
     103
    102104#TODO: This global variable do_preparse should be associtated with an
    103105#IPython InteractiveShell as opposed to a global variable in this
    104106#module.
     
    149151        sage: shell.prompt_manager.in_template
    150152        u'new: '
    151153        sage: shell.run_cell('set_sage_prompt(u"sage: ")')
    152 
    153154    """
    154155    ipython = get_ipython()
    155156    ipython.prompt_manager.in_template = s
     
    217218            format_data['text/plain'] = s.getvalue().strip()
    218219        return format_data
    219220
     221
     222####################
     223# InteractiveShell #
     224####################
    220225from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
     226class SageInteractiveShell(TerminalInteractiveShell):
    221227
    222 class SageInteractiveShell(TerminalInteractiveShell):
    223     displayhook_class = SageDisplayHook #used by init_displayhook
     228    # used by init_displayhook
     229    displayhook_class = Type(SageDisplayHook)
    224230   
    225     def get_prefilter_transformer(self, cls):
    226         """
    227         Returns this shell's :class:`PrefilterTransformer` of type
    228         :class:`cls` if it has one.
    229        
    230         :param cls: the class of the transformer
    231         :type cls: a subclass of :class:`IPython.core.prefilter.PrefilterTransformer`
    232 
    233         :rtype: :class:`cls`
    234         :raises: :exc:`ValueError` if the shell does not have a
    235                  :class:`PrefilterTransformer` of type :class:`cls`
    236 
    237         EXAMPLES::
    238 
    239             sage: from sage.misc.interpreter import get_test_shell, SagePreparseTransformer, InterfaceShellTransformer
    240             sage: shell = get_test_shell()
    241             sage: shell.get_prefilter_transformer(SagePreparseTransformer)
    242             <SagePreparseTransformer(priority=1000, enabled=True)>
    243             sage: shell.get_prefilter_transformer(InterfaceShellTransformer)
    244             Traceback (most recent call last):
    245             ...
    246             ValueError: could not find transformer InterfaceShellTransformer
    247 
    248         """
    249         for transformer in self.prefilter_manager.transformers:
    250             if transformer.__class__ is cls:
    251                 return transformer
    252         raise ValueError("could not find transformer %s"%cls.__name__)
    253        
    254     def init_prefilter(self):
    255         """
    256         Initialize the input transformers used by the Sage shell.
    257         Currently, we use
    258 
    259           - :class:`SagePromptTransformer`
    260           - :class:`SagePreparseTransformer`
    261           - :class:`LoadAttachTransformer`
    262           - :class:`InterfaceMagicTransformer`
    263            
    264         EXAMPLES::
    265        
    266             sage: from sage.misc.interpreter import get_test_shell
    267             sage: shell = get_test_shell()
    268             sage: shell.prefilter_manager.transformers #indirect doctest
    269             [<SagePromptTransformer(priority=0, enabled=True)>,
    270              <PyPromptTransformer(priority=50, enabled=True)>,
    271              <IPyPromptTransformer(priority=50, enabled=True)>,
    272              <LoadAttachTransformer(priority=90, enabled=True)>,
    273              <AssignSystemTransformer(priority=100, enabled=True)>,
    274              <AssignMagicTransformer(priority=200, enabled=True)>,
    275              <InterfaceMagicTransformer(priority=900, enabled=True)>,
    276              <SagePreparseTransformer(priority=1000, enabled=True)>]
    277         """
    278         # Ideally, this code should be in a custom
    279         # :class:`PrefilterManager` class, but the code doesn't quite
    280         # make that clean as we'd have to reproduce the code from
    281         # :meth:`TerminalInteractiveShell.init_prefilter`
    282         super(SageInteractiveShell, self).init_prefilter()
    283        
    284         #Add the Sage input transformers
    285         for cls in [SagePreparseTransformer, SagePromptTransformer,
    286                     LoadAttachTransformer, InterfaceMagicTransformer]:
    287             t = cls(prefilter_manager=self.prefilter_manager,
    288                     shell=self, config=self.config)
    289         self.prefilter_manager.sort_transformers()
     231    # Input splitter, to split entire cells of input into either individual
     232    # interactive statements or whole blocks.
     233    input_splitter = Instance('sage.misc.interpreter.SageInputSplitter', (), {})
    290234
    291235    def run_cell(self, *args, **kwds):
    292236        r"""
     
    309253            sage: f = open(tmp, 'w'); f.write('a = 3\n'); f.close()
    310254            sage: shell.run_cell('a')
    311255            3
     256            sage: os.remove(tmp)
    312257        """
    313258        for f in modified_attached_files():
    314259            super(SageInteractiveShell, self).run_cell('%%load "%s"'%f)
     
    325270       
    326271            sage: import sage.all
    327272            sage: old_quit = sage.all.quit_sage
    328             sage: def new_quit(): print "Quitting..."
     273            sage: def new_quit(): print "Quitter!!!"
    329274            sage: sage.all.quit_sage = new_quit
    330275
    331 
    332276        Now, we can check to see that this method works::
    333277       
    334278            sage: from sage.misc.interpreter import get_test_shell
    335279            sage: shell = get_test_shell()
    336280            sage: shell.ask_exit()
    337             Quitting...
     281            Quitter!!!
    338282            sage: shell.exit_now
    339283            True
    340284
     
    352296        Adjust the libraries before calling system commands.  See Trac
    353297        #975 for a discussion of this function.
    354298
    355         .. note::
    356 
    357            There does not seem to be a good way to doctest this
    358            function.
     299        EXAMPLES::
     300       
     301            sage: from sage.misc.interpreter import get_test_shell
     302            sage: shell = get_test_shell()
     303            sage: shell.system_raw('false')
     304            sage: shell.user_ns['_exit_code']
     305            256
    359306        """
    360307        sage_commands = os.listdir(os.environ['SAGE_ROOT']+"/local/bin/")
    361308        DARWIN_SYSTEM = os.uname()[0]=='Darwin'
     
    403350            sage: from sage.misc.interpreter import get_test_shell
    404351            sage: shell = get_test_shell()
    405352            sage: shell.magic_prun('2+2')
    406                      2 function calls in 0.000 CPU seconds
     353                     2 function calls in 0.000 seconds
    407354            <BLANKLINE>
    408355               Ordered by: internal time
    409356            <BLANKLINE>
     
    474421
    475422        .. note::
    476423
    477            Currently, this cannot be doctested as it relies on
    478            :func:`raw_input`.
     424            Currently, this cannot be completely doctested as it
     425            relies on :func:`raw_input`.
     426
     427        EXAMPLES::
     428
     429            sage: ip = get_ipython()           # not tested: works only in interactive shell
     430            sage: ip.magic_iload('/dev/null')  # not tested: works only in interactive shell
     431            Interactively loading "/dev/null"  # not tested: works only in interactive shell
    479432        """
    480433        try:
    481434            name = str(eval(s))
     
    509462                source, source_raw = self.input_splitter.source_raw_reset()
    510463                self.run_cell(source_raw, store_history=True)
    511464
    512 #######################################################
    513 # Transformers - these modify the command line input before it gets
    514 # evaluated by the interpreter. See IPython.core.prefilter f
    515 #######################################################
    516 from IPython.core.prefilter import PrefilterTransformer
    517465
    518 class SagePreparseTransformer(PrefilterTransformer):
     466###################################################################
     467# Transformers used in the SageInputSplitter
     468###################################################################
     469# These used to be part of the older PrefilterTransformer framework,
     470# but that is not the modern way of doing things. For more details, see
     471# http://mail.scipy.org/pipermail/ipython-dev/2011-March/007334.html
     472
     473class SagePreparseTransformer():
    519474    """
    520     This transformer preparses the line of code before it get
    521     evaluated by IPython.
     475    Preparse the line of code before it get evaluated by IPython.
    522476    """
    523     priority = 1000
    524     def transform(self, line, continue_prompt):
     477    def __call__(self, line, line_number, block_start):
    525478        """
    526         Preparse *line* if necessary.
     479        Transform ``line``.
    527480
    528         :param line: the line to be transformed
    529         :type line: string
    530         :param continue_prompt: is this line a continuation in a sequence of multiline input?
    531         :type continue_prompt: bool
     481        INPUT:
     482
     483        - ``line`` -- string. The line to be transformed.
     484
     485        - ``line_number`` -- integer. The line number. For a single-line input, this is always zero.
     486       
     487        - ``block_start`` -- boolean. Whether the line is at the
     488          beginning of a new block.
     489
     490        OUTPUT:
     491
     492        A string, the transformed line.
    532493
    533494        EXAMPLES::
    534495
    535             sage: from sage.misc.interpreter import get_test_shell, SagePreparseTransformer
    536             sage: shell = get_test_shell()
    537             sage: spt = shell.get_prefilter_transformer(SagePreparseTransformer); spt
    538             <SagePreparseTransformer(priority=1000, enabled=True)>
    539             sage: spt.transform('2', False)
     496            sage: from sage.misc.interpreter import SagePreparseTransformer
     497            sage: spt = SagePreparseTransformer()
     498            sage: spt('2', 0, False)
    540499            'Integer(2)'
    541             sage: shell.run_cell('preparser(False)')
    542             sage: spt.transform('2', False)
     500            sage: preparser(False)
     501            sage: spt('2', 0, False)
    543502            '2'
    544             sage: shell.run_cell('preparser(True)')
     503            sage: preparser(True)
    545504        """
    546505        if do_preparse and not line.startswith('%'):
    547506            return preparse(line)
    548507        else:
    549508            return line
    550509
    551 class LoadAttachTransformer(PrefilterTransformer):
     510class LoadAttachTransformer():
    552511    r"""
    553     This transformer handles input lines that start out like
    554     ``load ...`` for ``attach ...``.  Since there are objects in the
    555     Sage namespace named ``load`` and ``attach``, IPython's automagic
    556     will not transform these lines into ``%load ...`` and
    557     ``%attach ...``, respectively.  Thus, we have to do it manually.
     512    Handle input lines that start out like ``load ...`` or ``attach
     513    ...``.
     514
     515    Since there are objects in the Sage namespace named ``load`` and
     516    ``attach``, IPython's automagic will not transform these lines
     517    into ``%load ...`` and ``%attach ...``, respectively.  Thus, we
     518    have to do it manually.
    558519    """
    559     priority = 90
    560     def transform(self, line, continue_prompt):
     520    def __call__(self, line, line_number, block_start):
    561521        """
    562         :param line: the line to be transformed
    563         :type line: string
    564         :param continue_prompt: is this line a continuation in a sequence of multiline input?
    565         :type continue_prompt: bool
     522        Transform ``line``.
     523
     524        INPUT:
     525
     526        - ``line`` -- string. The line to be transformed.
     527
     528        - ``line_number`` -- integer. The line number. For a single-line input, this is always zero.
     529       
     530        - ``block_start`` -- boolean. Whether the line is at the
     531          beginning of a new block.
     532
     533        OUTPUT:
     534
     535        A string, the transformed line.
    566536
    567537        EXAMPLES::
    568538
    569539            sage: from sage.misc.interpreter import get_test_shell, LoadAttachTransformer
    570             sage: shell = get_test_shell()
    571             sage: lat = shell.get_prefilter_transformer(LoadAttachTransformer); lat
    572             <LoadAttachTransformer(priority=90, enabled=True)>
    573             sage: lat.transform('load /path/to/file', False)
     540            sage: lat = LoadAttachTransformer()
     541            sage: lat('load /path/to/file', 0, False)
    574542            '%load /path/to/file'
    575             sage: lat.transform('attach /path/to/file', False)
     543            sage: lat('attach /path/to/file', 0, False)
    576544            '%attach /path/to/file'
    577545        """
     546        if line_number>0:
     547            return line
    578548        for cmd in ['load', 'attach']:
    579549            if line.startswith(cmd + ' '):
    580550                return '%' + line
    581551        return line
    582552   
    583 class SagePromptTransformer(PrefilterTransformer):
     553class SagePromptTransformer():
    584554    """
    585     This transformer removes Sage prompts from the imput line.
     555    Remove Sage prompts from the imput line.
    586556    """
    587     _sage_prompt_re = re.compile(r'(^[ \t]*sage: |^[ \t]*\.+: )+')
     557    _sage_prompt_re = re.compile(r'(^[ \t]*sage: |^[ \t]*\.+:? )+')
    588558
    589     priority = 0
    590     def transform(self, line, continue_prompt):
     559    def __call__(self, line, line_number, block_start):
    591560        """
    592         :param line: the line to be transformed
    593         :type line: string
    594         :param continue_prompt: is this line a continuation in a sequence of multiline input?
    595         :type continue_prompt: bool
     561        Transform ``line``.
     562
     563        INPUT:
     564
     565        - ``line`` -- string. The line to be transformed.
     566
     567        - ``line_number`` -- integer. The line number. For a single-line input, this is always zero.
     568       
     569        - ``block_start`` -- boolean. Whether the line is at the
     570          beginning of a new block.
     571
     572        OUTPUT:
     573
     574        A string, the transformed line.
    596575
    597576        EXAMPLES::
    598577
    599             sage: from sage.misc.interpreter import get_test_shell, SagePromptTransformer
    600             sage: shell = get_test_shell()
    601             sage: spt = shell.get_prefilter_transformer(SagePromptTransformer); spt
    602             <SagePromptTransformer(priority=0, enabled=True)>
    603             sage: spt.transform("sage: sage: 2 + 2", False)
     578            sage: from sage.misc.interpreter import SagePromptTransformer
     579            sage: spt = SagePromptTransformer()
     580            sage: spt("sage: sage: 2 + 2", 0, False)
    604581            '2 + 2'
    605             sage: spt.transform('', False)
     582            sage: spt('', 0, False)
    606583            ''
    607             sage: spt.transform("      sage: 2+2", False)
     584            sage: spt("      sage: 2+2", 0, False)
    608585            '2+2'
    609 
     586            sage: spt("      ... 2+2", 0, False)
     587            '2+2'
    610588        """
    611589        if not line or line.isspace() or line.strip() == '...':
    612590            # This allows us to recognize multiple input prompts separated by
     
    621599                break
    622600        return line
    623601
    624 class InterfaceMagicTransformer(PrefilterTransformer):
     602class InterfaceMagicTransformer():
    625603    """
    626     This transformer is for handling commands like ``%maxima`` which
    627     are designed to go into a Maxima shell.  This one is tricky since
    628     the magic commands are transformed in
    629     :mod:`IPython.core.inputsplitter` before they can even go into the
    630     :class:`PrefilterTransformer` framework.  Thus, we need to match
    631     the output of those transformations instead of something simple
    632     like ``"%maxima"``.
     604    This transformer is for handling commands like ``%maxima`` to
     605    switch to a Maxima shell.
     606    """
     607    _magic_command_re = re.compile(r"get_ipython\(\).magic\(u'([^\d\W]\w+)'\)", re.UNICODE)
    633608
    634     .. note::
     609    def interfaces(self):
     610        """
     611        Return the list of interfaces
    635612
    636         This will only work if the corresponding object is of type
    637         :class:`sage.interfaces.interface.Interface`.
    638     """
    639     priority = 900
    640     _magic_command_re = re.compile(r"get_ipython\(\).magic\(u'([^\d\W]\w+)'\)", re.UNICODE)
    641     def transform(self, line, continue_prompt):
    642         """
    643         :param line: the line to be transformed
    644         :type line: string
    645         :param continue_prompt: is this line a continuation in a sequence of multiline input?
    646         :type continue_prompt: bool
     613        OUTPUT:
     614
     615        A list of stings.
    647616
    648617        EXAMPLES::
    649618
    650             sage: from sage.misc.interpreter import get_test_shell, InterfaceMagicTransformer
    651             sage: shell = get_test_shell()
    652             sage: imt = shell.get_prefilter_transformer(InterfaceMagicTransformer); imt
    653             <InterfaceMagicTransformer(priority=900, enabled=True)>
    654             sage: imt.transform("get_ipython().magic(u'maxima')", False)
     619            sage: from sage.misc.interpreter import InterfaceMagicTransformer
     620            sage: imt = InterfaceMagicTransformer()
     621            sage: imt.interfaces()
     622            ['LiE', 'Lisp', 'MuPAD', 'axiom', 'fricas', 'gap', 'gap3', 'giac',
     623             'kash', 'macaulay2', 'magma', 'maple', 'mathematica', 'matlab',
     624             'maxima', 'mwrank', 'octave', 'pari', 'r', 'sage', 'scilab', 'singular']
     625        """
     626        if '_interfaces' in self.__dict__:
     627            return self._interfaces
     628        import sage.interfaces
     629        self._interfaces = sorted([ obj.name()
     630                                    for obj in sage.interfaces.all.__dict__.values()
     631                                    if isinstance(obj, sage.interfaces.interface.Interface) ])
     632        return self._interfaces
     633
     634    def __call__(self, line, line_number, block_start):
     635        """
     636        Transform ``line``.
     637
     638        INPUT:
     639
     640        - ``line`` -- string. The line to be transformed.
     641
     642        - ``line_number`` -- integer. The line number. For a single-line input, this is always zero.
     643       
     644        - ``block_start`` -- boolean. Whether the line is at the
     645          beginning of a new block.
     646
     647        OUTPUT:
     648
     649        A string, the transformed line.
     650
     651        EXAMPLES::
     652
     653            sage: from sage.misc.interpreter import InterfaceMagicTransformer
     654            sage: imt = InterfaceMagicTransformer()
     655            sage: imt('%maxima', 0, False)
    655656            'maxima.interact()'
    656             sage: imt.transform("get_ipython().magic(u'prun')", False)
    657             "get_ipython().magic(u'prun')"
     657            sage: imt('%prun', 0, False)
     658            '%prun'
    658659        """
    659         match = self._magic_command_re.match(line)
    660         if match:
    661             interface, = match.groups()
    662             from sage.interfaces.interface import Interface
    663             if isinstance(self.shell.user_ns.get(interface, None), Interface):
     660        if line_number>0:
     661            return line
     662        if line.startswith('%'):
     663            interface = line[1:].strip()
     664            if interface in self.interfaces():
    664665                return interface + '.interact()'
    665666        return line
    666667
     668
     669###################################################################
     670# Input Splitter
     671###################################################################
     672# the main entry point for input handling in Sage
     673
     674from IPython.core.inputsplitter import InputSplitter
     675class SageInputSplitter(InputSplitter):
     676    """
     677    An input splitter for Sage syntax
     678    """
     679    # Whether a multi-line input is complete, i.e. line = empty line at the end
     680    _is_complete = False
     681
     682    # String with raw, untransformed input.
     683    source_raw = ''
     684
     685    ### Private attributes
     686    # List with lines of raw input accumulated so far.
     687    _buffer_raw = None
     688    _magic_interfaces = []
     689   
     690    def __init__(self, input_mode=None):
     691        """
     692        The Python constructor
     693       
     694        TESTS::
     695       
     696            sage: from sage.misc.interpreter import SageInputSplitter
     697            sage: SageInputSplitter()
     698            <sage.misc.interpreter.SageInputSplitter object at 0x...>
     699        """
     700        InputSplitter.__init__(self, input_mode)
     701        self._buffer_raw = []
     702        self._transforms = [
     703            InterfaceMagicTransformer(),
     704            SagePromptTransformer(),
     705            LoadAttachTransformer(),
     706            SagePreparseTransformer() ]
     707         
     708    def reset(self):
     709        """
     710        Reset the input buffer and associated state.
     711
     712        EXAMPLES::
     713 
     714            sage: from sage.misc.interpreter import SageInputSplitter
     715            sage: sis = SageInputSplitter()
     716            sage: sis.push('1')
     717            True
     718            sage: sis._buffer
     719            [u'Integer(1)\n']
     720            sage: sis.reset()
     721            sage: sis._buffer
     722            []
     723        """
     724        # print 'SageInputSplitter.reset buf = '+str(self._buffer)
     725        InputSplitter.reset(self)
     726        self._buffer_raw[:] = []
     727        self.source_raw = ''
     728
     729    def source_raw_reset(self):
     730        """
     731        Return input and raw source and perform a full reset.
     732
     733        EXAMPLES::
     734 
     735            sage: from sage.misc.interpreter import SageInputSplitter
     736            sage: sis = SageInputSplitter()
     737            sage: sis.push('1')
     738            True
     739            sage: sis._buffer
     740            [u'Integer(1)\n']
     741            sage: sis.source_raw_reset()
     742            (u'Integer(1)\n', u'1\n')
     743            sage: sis._buffer
     744            []
     745        """
     746        # print 'SageInputSplitter.source_raw_reset'
     747        out = self.source
     748        out_r = self.source_raw
     749        self.reset()
     750        return out, out_r
     751
     752    def push(self, lines):
     753        """
     754        Push one or more lines of Sage input.
     755
     756        This is mostly copy & paste from IPython, but with different transformers
     757       
     758        EXAMPLES::
     759
     760            sage: from sage.misc.interpreter import SageInputSplitter
     761            sage: sis = SageInputSplitter()
     762            sage: sis._buffer
     763            []
     764            sage: sis.push('1')
     765            True
     766            sage: sis._buffer
     767            [u'Integer(1)\n']
     768        """
     769        # print 'SageInputSplitter.push '+lines+' ('+str(len(self._buffer))+')'  # dbg
     770
     771        if not lines:
     772            return super(SageInputSplitter, self).push(lines)
     773
     774        # We must ensure all input is pure unicode
     775        lines = cast_unicode(lines, self.encoding)
     776        lines_list = lines.splitlines()
     777
     778        # Transform logic
     779        #
     780        # We only apply the line transformers to the input if we have either no
     781        # input yet, or complete input, or if the last line of the buffer ends
     782        # with ':' (opening an indented block).  This prevents the accidental
     783        # transformation of escapes inside multiline expressions like
     784        # triple-quoted strings or parenthesized expressions.
     785        #
     786        # The last heuristic, while ugly, ensures that the first line of an
     787        # indented block is correctly transformed.
     788        #
     789        # FIXME: try to find a cleaner approach for this last bit.
     790        # If we were in 'block' mode, since we're going to pump the parent
     791        # class by hand line by line, we need to temporarily switch out to
     792        # 'line' mode, do a single manual reset and then feed the lines one
     793        # by one.  Note that this only matters if the input has more than one
     794        # line.
     795        saved_input_mode = None
     796        if self.input_mode != 'line':
     797            saved_input_mode = self.input_mode
     798            self.reset()
     799            self.input_mode = 'line'
     800
     801        # Store raw source before applying any transformations to it.  Note
     802        # that this must be done *after* the reset() call that would otherwise
     803        # flush the buffer.
     804        self._store(lines, self._buffer_raw, 'source_raw')
     805       
     806        push = super(SageInputSplitter, self).push
     807        buf = self._buffer
     808        try:
     809            for line in lines_list:
     810                line_number = len(buf)
     811                block_start = self._is_complete or not buf or \
     812                    (buf and (buf[-1].rstrip().endswith(':') or
     813                              buf[-1].rstrip().endswith(',')) )
     814                for f in self._transforms:
     815                    line = f(line, line_number, block_start)
     816                out = push(line)
     817        finally:
     818            if saved_input_mode is not None:
     819                self.input_mode = saved_input_mode
     820        return out
     821
     822
    667823###################
    668824# Interface shell #
    669825###################
     826from IPython.core.prefilter import PrefilterTransformer
    670827from IPython.frontend.terminal.embed import InteractiveShellEmbed
    671828from IPython import Config
    672 
     829           
    673830class InterfaceShellTransformer(PrefilterTransformer):
    674831    priority = 50
    675832    def __init__(self, *args, **kwds):
     
    690847
    691848        EXAMPLES::
    692849
    693             sage: from sage.misc.interpreter import interface_shell_embed, InterfaceShellTransformer
     850            sage: from sage.misc.interpreter import interface_shell_embed
    694851            sage: shell = interface_shell_embed(maxima)
    695             sage: ift = InterfaceShellTransformer(shell=shell, config=shell.config, prefilter_manager=shell.prefilter_manager)
     852            sage: ift = shell.prefilter_manager.transformers[0]
    696853            sage: ift.lines_queue
    697854            []
    698855            sage: ift.temporary_objects
     
    726883        EXAMPLES::
    727884
    728885            sage: from sage.misc.interpreter import interface_shell_embed, InterfaceShellTransformer
    729             sage: maxima.quit()
    730886            sage: shell = interface_shell_embed(maxima)
    731887            sage: ift = InterfaceShellTransformer(shell=shell, config=shell.config, prefilter_manager=shell.prefilter_manager)
    732888            sage: ift.shell.ex('a = 3')
     
    748904        return line
    749905
    750906    def transform(self, line, continue_prompt):
    751         r'''
     907        """
    752908        Evaluates *line* in :attr:`shell.interface` and returns a
    753909        string representing the result of that evaluation.  If a line
    754910        ends in backspace, then this method will store *line* in
     
    763919        EXAMPLES::
    764920
    765921            sage: from sage.misc.interpreter import interface_shell_embed, InterfaceShellTransformer
    766             sage: maxima.quit()
    767922            sage: shell = interface_shell_embed(maxima)
    768923            sage: ift = InterfaceShellTransformer(shell=shell, config=shell.config, prefilter_manager=shell.prefilter_manager)
    769             sage: ift.transform('2+2', False)
    770             'sage.misc.all.logstr("""4""")'
     924            sage: ift.transform('2+2', False)   # note: output contains triple quotation marks
     925            'sage.misc.all.logstr(...4...)'
    771926            sage: ift.shell.ex('a = 4')
    772927            sage: ift.transform(r'sage(a)+\\', False)
    773928            sage: ift.shell.prompt_manager.in_template
    774929            u'....: '
    775930            sage: ift.lines_queue
    776             [' sage0+']
     931            [' sage2 +']
    777932            sage: ift.temporary_objects
     933            [4]
    778934            sage: ift.transform('4', False)
    779             'sage.misc.all.logstr("""8""")'
     935            'sage.misc.all.logstr(...8...)'
    780936            sage: ift.lines_queue
    781937            []
    782938            sage: ift.temporary_objects
     
    785941            sage: shell = interface_shell_embed(gap)
    786942            sage: ift = InterfaceShellTransformer(shell=shell, config=shell.config, prefilter_manager=shell.prefilter_manager)
    787943            sage: ift.transform('2+2', False)
    788             'sage.misc.all.logstr("""4""")'
    789         '''
     944            'sage.misc.all.logstr(...4...)'
     945        """
    790946        line = self.preparse_imports_from_sage(line)
    791947        line = line.rstrip()
    792948        if line.endswith('\\'):
     
    813969            self.temporary_objects = []
    814970            self.shell.prompt_manager.in_template = self.shell.interface.name() + ': '
    815971            return 'sage.misc.all.logstr("""%s""")'%t.strip()
    816            
     972
    817973def interface_shell_embed(interface):
    818974    """
    819975    Returns an IPython shell which uses a Sage interface on the
     
    824980    EXAMPLES::
    825981
    826982        sage: from sage.misc.interpreter import interface_shell_embed
    827         sage: shell = interface_shell_embed(maxima)
    828         sage: shell.run_cell('integrate(sin(x), x)')
    829         -cos(x)
     983        sage: shell = interface_shell_embed(gap)
     984        sage: shell.run_cell('List( [1..10], IsPrime )')
     985        [ false, true, true, false, true, false, true, false, false, false ]
    830986    """
    831     cfg = Config()
    832     cfg.PromptManager.in_template = interface.name() + ': '
    833     cfg.PromptManager.in2_template = u'....: '
    834     cfg.PromptManager.out_template = u''
    835     cfg.PromptManager.justify = False
    836     cfg.InteractiveShell.confirm_exit = False
     987    try:
     988        cfg = Config(get_ipython().config)
     989    except NameError:
     990        cfg = Config(SageTerminalApp.DEFAULT_SAGE_CONFIG)
     991    cfg.PromptManager['in_template'] = interface.name() + ': '
    837992
    838993    ipshell = InteractiveShellEmbed(config=cfg,
    839                                     banner1='\n  --> Switching to %s <--\n'%interface,
     994                                    banner1='\n  --> Switching to %s <--\n\n'%interface,
    840995                                    exit_msg = '\n  --> Exiting back to Sage <--\n')
    841996    ipshell.interface = interface
    842997
    843     #TODO: The following lines "should" be in the config
    844     ipshell.prompt_manager.color_scheme = 'NoColor'
    845     ipshell.separate_in = u''
    846 
    847998    while ipshell.prefilter_manager.transformers:
    848999        ipshell.prefilter_manager.transformers.pop()
    8491000    while ipshell.prefilter_manager.checkers:
    8501001        ipshell.prefilter_manager.checkers.pop()
    851     for cls in [InterfaceShellTransformer]:
    852         cls(shell=ipshell, prefilter_manager=ipshell.prefilter_manager,
    853             config=cfg)
    854        
    8551002    ipshell.ex('from sage.all import *')
    8561003
     1004    InterfaceShellTransformer(shell=ipshell,
     1005                              prefilter_manager=ipshell.prefilter_manager,
     1006                              config=cfg)
    8571007    return ipshell
    8581008   
    8591009def get_test_shell():
     
    9081058        contact_email = 'sage-support@googlegroups.com'
    9091059        bug_tracker = 'http://trac.sagemath.org/sage_trac'
    9101060        CrashHandler.__init__(self,
    911             app, contact_name, contact_email, bug_tracker, show_crash_traceback=False
    912         )
     1061            app, contact_name, contact_email, bug_tracker, show_crash_traceback=False)
    9131062        self.crash_report_fname = 'Sage_crash_report.txt'
    9141063
    9151064class SageTerminalApp(TerminalIPythonApp):
    9161065    name = u'Sage'
    917     ignore_old_config = True
    9181066    crash_handler_class = SageCrashHandler
    919     verbose_crash = True #Needed to use Sage Crash Handler
     1067    verbose_crash = True   # Needed to use Sage Crash Handler
    9201068    display_banner = False
    9211069    test_shell = False
    9221070   
    923     DEFAULT_SAGE_CONFIG = Config({'PromptManager': {'in_template': u'sage: ',
    924                                                     'in2_template': u'....: ',
    925                                                     'out_template': u'',
    926                                                     'justify': False},
    927                                   'InteractiveShell': {'separate_in': u'',
    928                                                        'colors': 'NoColor'},
    929                                   })
     1071    DEFAULT_SAGE_CONFIG = Config(
     1072        {'PromptManager':    {'in_template':  u'sage: ',
     1073                              'in2_template': u'....: ',
     1074                              'out_template': u'',
     1075                              'justify':      False},
     1076         'InteractiveShell': {'separate_in':  u'',
     1077                              'autoindent':   True,
     1078                              'confirm_exit': False,
     1079                              'colors':       'NoColor'},
     1080         })
    9301081
    9311082    def init_shell(self):
    9321083        r"""
     
    9761127        IPython.core.oinspect.getsource = sagedoc.my_getsource
    9771128        IPython.core.oinspect.getargspec = sageinspect.sage_getargspec
    9781129
    979 
    9801130        from sage.misc.edit_module import edit_devel
    9811131        self.shell.set_hook('editor', edit_devel)
    9821132
    983         if 'SAGE_CLEAN' in os.environ:
    984             return
    985        
    9861133        # Additional initalization code
    9871134        preparser(True)
    9881135        os.chdir(os.environ["CUR"])
     
    9951142        self.shell.ex('from sage.all import Integer, RealNumber')
    9961143        self.shell.push(dict(sage_prompt=sage_prompt))
    9971144
    998         if os.environ.get('SAGE_IMPORTALL', 'yes') != "no":
    999             self.shell.ex('from sage.all_cmdline import *')
    1000 
     1145        if os.environ.get('SAGE_IMPORTALL', 'yes') != 'yes':
     1146            return
     1147        self.shell.ex('from sage.all_cmdline import *')
    10011148        startup_file = os.environ.get('SAGE_STARTUP_FILE', '')
     1149       
    10021150        if os.path.exists(startup_file):
    10031151            self.shell.run_cell('%%load "%s"'%startup_file)
     1152
  • sage/structure/misc.pyx

    diff --git a/sage/structure/misc.pyx b/sage/structure/misc.pyx
    a b  
    156156        sage: getattr_from_other_class(PolynomialRing(QQ, name='x', implementation="FLINT").one(), A, "lazy_attribute")
    157157        Traceback (most recent call last):
    158158        ...
    159         AttributeError: 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint' object has no attribute 'lazy_attribute'
     159        AttributeError: 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'
     160        object has no attribute 'lazy_attribute'
    160161
    161162    In general, descriptors are not yet well supported, because they
    162163    often do not accept to be cheated with the type of their instance::
     
    164165        sage: A.__weakref__.__get__(1)
    165166        Traceback (most recent call last):
    166167        ...
    167         TypeError: descriptor '__weakref__' for 'A' objects doesn't apply to 'sage.rings.integer.Integer' object
     168        TypeError: descriptor '__weakref__' for 'A' objects doesn't apply
     169        to 'sage.rings.integer.Integer' object
    168170
    169171    When this occurs, an ``AttributeError`` is raised::
    170172
     
    183185        Traceback (most recent call last):
    184186        ...
    185187        AttributeError: 'sage.rings.integer.Integer' object has no attribute '__weakref__'
    186         sage: import IPython
    187         sage: _ip = IPython.ipapi.get()
    188         sage: _ip.IP.magic_psearch('n.__weakref__') # not tested: only works with an interactive shell running
     188
     189        sage: n = 1
     190        sage: ip = get_ipython()                 # not tested: only works in interactive shell
     191        sage: ip.magic_psearch('n.N')            # not tested: only works in interactive shell
     192        n.N
     193        sage: ip.magic_psearch('n.__weakref__')  # not tested: only works in interactive shell
    189194
    190195    Caveat: When __call__ is not defined for instances, using
    191196    ``A.__call__`` yields the method ``__call__`` of the class. We use