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 upon tab-completion when there's a non-subscriptable key in globals() #4861

Open
gerritholl opened this issue Jan 24, 2014 · 4 comments
Labels
Milestone

Comments

@gerritholl
Copy link

When I commit a serious crime, I can crash ipython. The crime is: globals()[0]=0. The problem is illustrated below:

$ ipython3
WARNING: IPython History requires SQLite, your history will not be saved
Python 3.3.3 (default, Dec 12 2013, 11:13:02) 
Type "copyright", "credits" or "license" for more information.

IPython 1.1.0 -- 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]: globals()[0]=0

In [3]: a<Tab>

Then follows the attached traceback, ultimately leading to TypeError: 'int' object is not subscriptable.

@gerritholl
Copy link
Author

TypeErrorPython 3.3.3: /nobackup/smhid10/sm_gerho/venv/python-3.3/bin/python3.3
                                                   Fri Jan 24 14:40:46 2014
A problem occured executing Python code.  Here is the sequence of function
calls leading up to the error, with the most recent (innermost) call last.
/nobackup/smhid10/sm_gerho/venv/python-3.3/lib/python3.3/site-packages/IPython/core/completer.py in complete(self=<IPython.core.completer.IPCompleter object>, text='a', line_buffer='a', cursor_pos=1)
    886 
    887         # Start with a clean slate of completions
    888         self.matches[:] = []
    889         custom_res = self.dispatch_custom_completer(text)
    890         if custom_res is not None:
    891             # did custom completers produce something?
    892             self.matches = custom_res
    893         else:
    894             # Extend the list of completions with the results of each
    895             # matcher, so we return results to the user from all
    896             # namespaces.
    897             if self.merge_completions:
    898                 self.matches = []
    899                 for matcher in self.matchers:
    900                     try:
--> 901                         self.matches.extend(matcher(text))
        self.matches.extend = <built-in method extend of list object at 0x7f5a79fbc050>
        matcher = <bound method IPCompleter.python_matches of <IPython.core.completer.IPCompleter object at 0x7f5a7a21cf10>>
        text = 'a'
    902                     except:
    903                         # Show the ugly traceback if the matcher causes an
    904                         # exception, but do NOT crash the kernel!
    905                         sys.excepthook(*sys.exc_info())
    906             else:
    907                 for matcher in self.matchers:
    908                     self.matches = matcher(text)
    909                     if self.matches:
    910                         break
    911         # FIXME: we should extend our api to return a dict with completions for
    912         # different types of objects.  The rlcomplete() method could then
    913         # simply collapse the dict into a list for readline, but we'd have
    914         # richer completion semantics in other evironments.
    915         self.matches = sorted(set(self.matches))
    916         #io.rprint('COMP TEXT, MATCHES: %r, %r' % (text, self.matches)) # dbg

/nobackup/smhid10/sm_gerho/venv/python-3.3/lib/python3.3/site-packages/IPython/core/completer.py in python_matches(self=<IPython.core.completer.IPCompleter object>, text='a')
    653                 matches = self.attr_matches(text)
    654                 if text.endswith('.') and self.omit__names:
    655                     if self.omit__names == 1:
    656                         # true if txt is _not_ a __ name, false otherwise:
    657                         no__name = (lambda txt:
    658                                     re.match(r'.*\.__.*?__',txt) is None)
    659                     else:
    660                         # true if txt is _not_ a _ name, false otherwise:
    661                         no__name = (lambda txt:
    662                                     re.match(r'.*\._.*?',txt) is None)
    663                     matches = list(filter(no__name, matches))
    664             except NameError:
    665                 # catches <undefined attributes>.<tab>
    666                 matches = []
    667         else:
--> 668             matches = self.global_matches(text)
        matches = undefined
        self.global_matches = <bound method IPCompleter.global_matches of <IPython.core.completer.IPCompleter object at 0x7f5a7a21cf10>>
        text = 'a'
    669 
    670         return matches
    671 
    672     def _default_arguments_from_docstring(self, doc):
    673         """Parse the first line of docstring for call signature.
    674 
    675         Docstring should be of the form 'min(iterable[, key=func])\n'.
    676         It can also parse cython docstring of the form
    677         'Minuit.migrad(self, int ncall=10000, resume=True, int nsplit=1)'.
    678         """
    679         if doc is None:
    680             return []
    681 
    682         #care only the firstline
    683         line = doc.lstrip().splitlines()[0]

/nobackup/smhid10/sm_gerho/venv/python-3.3/lib/python3.3/site-packages/IPython/core/completer.py in global_matches(self=<IPython.core.completer.IPCompleter object>, text='a')
    306         """Compute matches when text is a simple name.
    307 
    308         Return a list of all keywords, built-in functions and names currently
    309         defined in self.namespace or self.global_namespace that match.
    310 
    311         """
    312         #print 'Completer->global_matches, txt=%r' % text # dbg
    313         matches = []
    315         n = len(text)
    316         for lst in [keyword.kwlist,
    317                     list(builtins.__dict__.keys()),
    318                     list(self.namespace.keys()),
    319                     list(self.global_namespace.keys())]:
    320             for word in lst:
--> 321                 if word[:n] == text and word != "__builtins__":
        word = 0
        n = 1
        text = 'a'
    322                     match_append(word)
    323         return matches
    324 
    325     def attr_matches(self, text):
    326         """Compute matches when text contains a dot.
    327 
    328         Assuming the text is of the form NAME.NAME....[NAME], and is
    329         evaluatable in self.namespace or self.global_namespace, it will be
    330         evaluated and its attributes (as revealed by dir()) are used as
    331         possible completions.  (For class instances, class members are are
    332         also considered.)
    333 
    334         WARNING: this can still invoke arbitrary C code, if an object
    335         with a __getattr__ hook is evaluated.
    336 

TypeError: 'int' object is not subscriptable

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

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/sm_gerho/.ipython/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/sm_gerho/.ipython/Crash_report_ipython.txt

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

@minrk
Copy link
Member

minrk commented Jan 24, 2014

There are all kinds of ways to do horrible things that will crash IPython, or make Python in general unusable. How did you come across this particular case? I doubt it's worth protecting against it.

@gerritholl
Copy link
Author

It happened by accident quite deep in a long-lived ipython session, assigning a key in a dictionary not realising it was pointing to globals(). I don't know if it's worth fixing, but I reported it anyhow. To be honest, I would expect the Python interpreter to complain about assigning a key that is not a string in a namespace, but that's to be discussed at another forum.

@takluyver takluyver added this to the wishlist milestone Mar 26, 2014
@takluyver
Copy link
Member

It no longer crashes, but you still see a traceback. I think it's valid to say that IPython should be nice about this, so I'm leaving the issue open but giving it the lowest priority.

@minrk minrk removed the prio-low label Jan 14, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants