Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash when doing "import math; math.sin?" #10229

Closed
jdemeyer opened this issue Feb 1, 2017 · 4 comments
Closed

Crash when doing "import math; math.sin?" #10229

jdemeyer opened this issue Feb 1, 2017 · 4 comments
Milestone

Comments

@jdemeyer
Copy link
Contributor

jdemeyer commented Feb 1, 2017

In the IPython session below, I executed

%config Application.verbose_crash=True

and

import math; math.sin?

When doing this, IPython crashes.

Below, you will see In [3]: import math; math.sin? but I have no idea where that came from. That was just displayed automatically.

Python 2.7.13 (default, Jan 25 2017, 11:01:10) 
Type "copyright", "credits" or "license" for more information.

IPython 5.2.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: %config Application.verbose_crash=True

In [2]: import math; math.sin?
Object `math.sin` not found.

In [3]: import math; math.sin?
---------------------------------------------------------------------------
---------------------------------------------------------------------------
AssertionError   Python 2.7.13: /usr/local/src/sage-config/local/bin/python
                                                   Wed Feb  1 10:17:47 2017
A problem occurred executing Python code.  Here is the sequence of function
calls leading up to the error, with the most recent (innermost) call last.
/usr/local/src/sage-config/local/bin/ipython in <module>()
      1 #!/usr/local/src/sage-config/local/bin/python
      2 
      3 # -*- coding: utf-8 -*-
      4 import re
      5 import sys
      6 
      7 from IPython import start_ipython
      8 
      9 if __name__ == '__main__':
     10     sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
---> 11     sys.exit(start_ipython())
        global sys.exit = <built-in function exit>
        global start_ipython = <function start_ipython at 0x7fcd69088e60>

/usr/local/src/sage-config/local/lib/python2.7/site-packages/IPython/__init__.pyc in start_ipython(argv=None, **kwargs={})
    104     This is a public API method, and will survive implementation changes.
    105     
    106     Parameters
    107     ----------
    108     
    109     argv : list or None, optional
    110         If unspecified or None, IPython will parse command-line options from sys.argv.
    111         To prevent any command-line parsing, pass an empty list: `argv=[]`.
    112     user_ns : dict, optional
    113         specify this dictionary to initialize the IPython user namespace with particular values.
    114     kwargs : various, optional
    115         Any other kwargs will be passed to the Application constructor,
    116         such as `config`.
    117     """
    118     from IPython.terminal.ipapp import launch_new_instance
--> 119     return launch_new_instance(argv=argv, **kwargs)
        launch_new_instance = <bound method MetaHasTraits.launch_instance of <class 'IPython.terminal.ipapp.TerminalIPythonApp'>>
        argv = None
        kwargs = {}
    120 
    121 def start_kernel(argv=None, **kwargs):
    122     """Launch a normal IPython kernel instance (as opposed to embedded)
    123     
    124     `IPython.embed_kernel()` puts a shell in a particular calling scope,
    125     such as a function or method for debugging purposes,
    126     which is often not desirable.
    127     
    128     `start_kernel()` does full, regular IPython initialization,
    129     including loading startup files, configuration, etc.
    130     much of which is skipped by `embed()`.
    131     
    132     Parameters
    133     ----------
    134     

/usr/local/src/sage-config/local/lib/python2.7/site-packages/traitlets/config/application.pyc in launch_instance(cls=<class 'IPython.terminal.ipapp.TerminalIPythonApp'>, argv=None, **kwargs={})
    643             lines.append(cls.class_config_section())
    644         return '\n'.join(lines)
    645 
    646     def exit(self, exit_status=0):
    647         self.log.debug("Exiting application: %s" % self.name)
    648         sys.exit(exit_status)
    649 
    650     @classmethod
    651     def launch_instance(cls, argv=None, **kwargs):
    652         """Launch a global instance of this Application
    653 
    654         If a global instance already exists, this reinitializes and starts it
    655         """
    656         app = cls.instance(**kwargs)
    657         app.initialize(argv)
--> 658         app.start()
        app.start = <bound method TerminalIPythonApp.start of <IPython.terminal.ipapp.TerminalIPythonApp object at 0x7fcd702dc750>>
    659 
    660 #-----------------------------------------------------------------------------
    661 # utility functions, for convenience
    662 #-----------------------------------------------------------------------------
    663 
    664 def boolean_flag(name, configurable, set_help='', unset_help=''):
    665     """Helper for building basic --trait, --no-trait flags.
    666 
    667     Parameters
    668     ----------
    669 
    670     name : str
    671         The name of the flag.
    672     configurable : str
    673         The 'Class.trait' string of the trait to be set/unset with the flag

/usr/local/src/sage-config/local/lib/python2.7/site-packages/IPython/terminal/ipapp.pyc in start(self=<IPython.terminal.ipapp.TerminalIPythonApp object>)
    333         if self.log_level <= logging.INFO: print()
    334 
    335     def _pylab_changed(self, name, old, new):
    336         """Replace --pylab='inline' with --pylab='auto'"""
    337         if new == 'inline':
    338             warnings.warn("'inline' not available as pylab backend, "
    339                       "using 'auto' instead.")
    340             self.pylab = 'auto'
    341 
    342     def start(self):
    343         if self.subapp is not None:
    344             return self.subapp.start()
    345         # perform any prexec steps:
    346         if self.interact:
    347             self.log.debug("Starting IPython's mainloop...")
--> 348             self.shell.mainloop()
        self.shell.mainloop = <bound method TerminalInteractiveShell.mainloop of <IPython.terminal.interactiveshell.TerminalInteractiveShell object at 0x7fcd6934c510>>
    349         else:
    350             self.log.debug("IPython not interactive...")
    351 
    352 def load_default_config(ipython_dir=None):
    353     """Load the default config file from the default ipython_dir.
    354 
    355     This is useful for embedded shells.
    356     """
    357     if ipython_dir is None:
    358         ipython_dir = get_ipython_dir()
    359 
    360     profile_dir = os.path.join(ipython_dir, 'profile_default')
    361 
    362     config = Config()
    363     for cf in Application._load_config_files("ipython_config", path=profile_dir):

/usr/local/src/sage-config/local/lib/python2.7/site-packages/IPython/terminal/interactiveshell.pyc in mainloop(self=<IPython.terminal.interactiveshell.TerminalInteractiveShell object>, display_banner=<object object>)
    440                 if (not self.confirm_exit) \
    441                         or self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
    442                     self.ask_exit()
    443 
    444             else:
    445                 if code:
    446                     self.run_cell(code, store_history=True)
    447 
    448     def mainloop(self, display_banner=DISPLAY_BANNER_DEPRECATED):
    449         # An extra layer of protection in case someone mashing Ctrl-C breaks
    450         # out of our internal code.
    451         if display_banner is not DISPLAY_BANNER_DEPRECATED:
    452             warn('mainloop `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2)
    453         while True:
    454             try:
--> 455                 self.interact()
        self.interact = <bound method TerminalInteractiveShell.interact of <IPython.terminal.interactiveshell.TerminalInteractiveShell object at 0x7fcd6934c510>>
    456                 break
    457             except KeyboardInterrupt as e:
    458                 print("\n%s escaped interact()\n" % type(e).__name__)
    459             finally:
    460                 # An interrupt during the eventloop will mess up the
    461                 # internal state of the prompt_toolkit library.
    462                 # Stopping the eventloop fixes this, see
    463                 # https://github.com/ipython/ipython/pull/9867
    464                 if hasattr(self, '_eventloop'):
    465                     self._eventloop.stop()
    466 
    467     _inputhook = None
    468     def inputhook(self, context):
    469         if self._inputhook is not None:
    470             self._inputhook(context)

/usr/local/src/sage-config/local/lib/python2.7/site-packages/IPython/terminal/interactiveshell.pyc in interact(self=<IPython.terminal.interactiveshell.TerminalInteractiveShell object>, display_banner=<object object>)
    423     def pre_prompt(self):
    424         if self.rl_next_input:
    425             self.pt_cli.application.buffer.text = cast_unicode_py2(self.rl_next_input)
    426             self.rl_next_input = None
    427 
    428     def interact(self, display_banner=DISPLAY_BANNER_DEPRECATED):
    429 
    430         if display_banner is not DISPLAY_BANNER_DEPRECATED:
    431             warn('interact `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2)
    432 
    433         self.keep_running = True
    434         while self.keep_running:
    435             print(self.separate_in, end='')
    436 
    437             try:
--> 438                 code = self.prompt_for_code()
        code = u'import math; math.sin?'
        self.prompt_for_code = <bound method TerminalInteractiveShell.prompt_for_code of <IPython.terminal.interactiveshell.TerminalInteractiveShell object at 0x7fcd6934c510>>
    439             except EOFError:
    440                 if (not self.confirm_exit) \
    441                         or self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
    442                     self.ask_exit()
    443 
    444             else:
    445                 if code:
    446                     self.run_cell(code, store_history=True)
    447 
    448     def mainloop(self, display_banner=DISPLAY_BANNER_DEPRECATED):
    449         # An extra layer of protection in case someone mashing Ctrl-C breaks
    450         # out of our internal code.
    451         if display_banner is not DISPLAY_BANNER_DEPRECATED:
    452             warn('mainloop `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2)
    453         while True:

/usr/local/src/sage-config/local/lib/python2.7/site-packages/IPython/terminal/interactiveshell.pyc in prompt_for_code(self=<IPython.terminal.interactiveshell.TerminalInteractiveShell object>)
    328                         processor=HighlightMatchingBracketProcessor(chars='[](){}'),
    329                         filter=HasFocus(DEFAULT_BUFFER) & ~IsDone() &
    330                             Condition(lambda cli: self.highlight_matching_brackets))],
    331                 }
    332 
    333     def _update_layout(self):
    334         """
    335         Ask for a re computation of the application layout, if for example ,
    336         some configuration options have changed.
    337         """
    338         if self._pt_app:
    339             self._pt_app.layout = create_prompt_layout(**self._layout_options())
    340 
    341     def prompt_for_code(self):
    342         document = self.pt_cli.run(
--> 343             pre_run=self.pre_prompt, reset_current_buffer=True)
        global pre_run = undefined
        self.pre_prompt = <bound method TerminalInteractiveShell.pre_prompt of <IPython.terminal.interactiveshell.TerminalInteractiveShell object at 0x7fcd6934c510>>
        global reset_current_buffer = undefined
        global True = undefined
    344         return document.text
    345 
    346     def enable_win_unicode_console(self):
    347         if sys.version_info >= (3, 6):
    348             # Since PEP 528, Python uses the unicode APIs for the Windows
    349             # console by default, so WUC shouldn't be needed.
    350             return
    351 
    352         import win_unicode_console
    353 
    354         if PY3:
    355             win_unicode_console.enable()
    356         else:
    357             # https://github.com/ipython/ipython/issues/9768
    358             from win_unicode_console.streams import (TextStreamWrapper,

/usr/local/src/sage-config/local/lib/python2.7/site-packages/prompt_toolkit/interface.pyc in run(self=<prompt_toolkit.interface.CommandLineInterface object>, reset_current_buffer=True, pre_run=<bound method TerminalInteractiveShell.pre_promp...nteractiveshell.TerminalInteractiveShell object>>)
    393         This runs the eventloop until a return value has been set.
    394 
    395         :param reset_current_buffer: XXX: Not used anymore.
    396         :param pre_run: Callable that is called right after the reset has taken
    397             place. This allows custom initialisation.
    398         """
    399         assert pre_run is None or callable(pre_run)
    400 
    401         try:
    402             self._is_running = True
    403 
    404             self.on_start.fire()
    405             self.reset()
    406 
    407             # Call pre_run.
--> 408             self._pre_run(pre_run)
        self._pre_run = <bound method CommandLineInterface._pre_run of <prompt_toolkit.interface.CommandLineInterface object at 0x7fcd6859a910>>
        pre_run = <bound method TerminalInteractiveShell.pre_prompt of <IPython.terminal.interactiveshell.TerminalInteractiveShell object at 0x7fcd6934c510>>
    409 
    410             # Run eventloop in raw mode.
    411             with self.input.raw_mode():
    412                 self.renderer.request_absolute_cursor_position()
    413                 self._redraw()
    414 
    415                 self.eventloop.run(self.input, self.create_eventloop_callbacks())
    416         finally:
    417             # Clean up renderer. (This will leave the alternate screen, if we use
    418             # that.)
    419 
    420             # If exit/abort haven't been called set, but another exception was
    421             # thrown instead for some reason, make sure that we redraw in exit
    422             # mode.
    423             if not self.is_done:

/usr/local/src/sage-config/local/lib/python2.7/site-packages/prompt_toolkit/interface.pyc in _pre_run(self=<prompt_toolkit.interface.CommandLineInterface object>, pre_run=<bound method TerminalInteractiveShell.pre_promp...nteractiveshell.TerminalInteractiveShell object>>)
    368         """
    369         # Erase, request position (when cursor is at the start position)
    370         # and redraw again. -- The order is important.
    371         self.renderer.erase(leave_alternate_screen=False, erase_title=False)
    372         self.renderer.request_absolute_cursor_position()
    373         self._redraw()
    374 
    375     def _load_next_buffer_indexes(self):
    376         for buff, index in self._next_buffer_indexes.items():
    377             if buff in self.buffers:
    378                 self.buffers[buff].working_index = index
    379 
    380     def _pre_run(self, pre_run=None):
    381         " Called during `run`. "
    382         if pre_run:
--> 383             pre_run()
        pre_run = <bound method TerminalInteractiveShell.pre_prompt of <IPython.terminal.interactiveshell.TerminalInteractiveShell object at 0x7fcd6934c510>>
    384 
    385         # Process registered "pre_run_callables" and clear list.
    386         for c in self.pre_run_callables:
    387             c()
    388         del self.pre_run_callables[:]
    389 
    390     def run(self, reset_current_buffer=False, pre_run=None):
    391         """
    392         Read input from the command line.
    393         This runs the eventloop until a return value has been set.
    394 
    395         :param reset_current_buffer: XXX: Not used anymore.
    396         :param pre_run: Callable that is called right after the reset has taken
    397             place. This allows custom initialisation.
    398         """

/usr/local/src/sage-config/local/lib/python2.7/site-packages/IPython/terminal/interactiveshell.pyc in pre_prompt(self=<IPython.terminal.interactiveshell.TerminalInteractiveShell object>)
    410     def __init__(self, *args, **kwargs):
    411         super(TerminalInteractiveShell, self).__init__(*args, **kwargs)
    412         self.init_prompt_toolkit_cli()
    413         self.init_term_title()
    414         self.keep_running = True
    415 
    416         self.debugger_history = InMemoryHistory()
    417 
    418     def ask_exit(self):
    419         self.keep_running = False
    420 
    421     rl_next_input = None
    422 
    423     def pre_prompt(self):
    424         if self.rl_next_input:
--> 425             self.pt_cli.application.buffer.text = cast_unicode_py2(self.rl_next_input)
        self.pt_cli.application.buffer.text = u'import math; math.sin?'
        global cast_unicode_py2 = <function cast_unicode at 0x7fcd6c2f6cf8>
        self.rl_next_input = 'import math; math.sin'
    426             self.rl_next_input = None
    427 
    428     def interact(self, display_banner=DISPLAY_BANNER_DEPRECATED):
    429 
    430         if display_banner is not DISPLAY_BANNER_DEPRECATED:
    431             warn('interact `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2)
    432 
    433         self.keep_running = True
    434         while self.keep_running:
    435             print(self.separate_in, end='')
    436 
    437             try:
    438                 code = self.prompt_for_code()
    439             except EOFError:
    440                 if (not self.confirm_exit) \

/usr/local/src/sage-config/local/lib/python2.7/site-packages/prompt_toolkit/buffer.pyc in text(self=<prompt_toolkit.buffer.Buffer object>, value=u'import math; math.sin')
    356 
    357         return value != original_position
    358 
    359     @property
    360     def text(self):
    361         return self._working_lines[self.working_index]
    362 
    363     @text.setter
    364     def text(self, value):
    365         """
    366         Setting text. (When doing this, make sure that the cursor_position is
    367         valid for this text. text/cursor_position should be consistent at any time,
    368         otherwise set a Document instead.)
    369         """
    370         assert isinstance(value, six.text_type), 'Got %r' % value
--> 371         assert self.cursor_position <= len(value)
        self.cursor_position = 22
        global len = undefined
        value = u'import math; math.sin'
    372 
    373         # Don't allow editing of read-only buffers.
    374         if self.read_only():
    375             raise EditReadOnlyBuffer()
    376 
    377         changed = self._set_text(value)
    378 
    379         if changed:
    380             self._text_changed()
    381 
    382             # Reset history search text.
    383             self.history_search_text = None
    384 
    385     @property
    386     def cursor_position(self):

AssertionError: 

**********************************************************************

Oops, ipython crashed. We do our best to make it stable, but...

A crash report was automatically generated with the following information:
  - A verbatim copy of the crash traceback.
  - A copy of your input history during this session.
  - Data on your current ipython configuration.

It was left in the file named:
        '/home/jdemeyer/.sage/ipython-5.0.0/Crash_report_ipython.txt'
If you can email this file to the developers, the information in it will help
them in understanding and correcting the problem.

You can mail it to: The IPython Development Team at ipython-dev@scipy.org
with the subject 'ipython Crash Report'.

If you want to do it now, the following command will work (under Unix):
mail -s 'ipython Crash Report' ipython-dev@scipy.org < /home/jdemeyer/.sage/ipython-5.0.0/Crash_report_ipython.txt

To ensure accurate tracking of this issue, please file a report about it at:
https://github.com/ipython/ipython/issues

Hit <Enter> to quit (your terminal may close):
@takluyver
Copy link
Member

Ping @jonathanslenders - I was only able to reproduce this after upgrading prompt_toolkit, so I think a recent change must have broken what we do. It looks like we should be setting a Document instead of a string?

@takluyver
Copy link
Member

#10231 fixes it at least on sufficiently recent prompt_toolkit; I haven't checked how recent it needs to be.

@Carreau Carreau added this to the 5.3 milestone Feb 1, 2017
@solstag
Copy link

solstag commented Feb 17, 2017

I can reproduce this (exact same error message) with a simpler command:

str().find?

It's likely the same problem but, just in case, you might want to check if the fix works for both.

Thanks!

@takluyver
Copy link
Member

Thanks, I believe that the problem & the fix don't depend on the details of what you enter - anything that calls shell.set_next_input() is affected.

lumberbot-app bot pushed a commit that referenced this issue Feb 21, 2017
Closes gh-10229

Please don't merge this just yet.

 jonathanslenders I discovered after updating that we can no longer set text in the buffer with a `pre_run` function, because `pre_run_callables` reset the buffer immediately after that. I've worked around this by adding another callable to `pre_run_callables` which sets the text that I want, but I don't know if this is the right way to do it, or whether it works with previous releases of prompt_toolkit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants