# Buggy code
def handle(self, line_info):
    """Handle lines which can be auto-executed, quoting if requested."""
    line = line_info.line
    ifun = line_info.ifun
    the_rest = line_info.the_rest
    pre = line_info.pre
    esc = line_info.esc
    continue_prompt = line_info.continue_prompt
    obj = line_info.ofind(self)["obj"]
    # print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun,the_rest)  # dbg

    # This should only be active for single-line input!
    if continue_prompt:
        return line

    force_auto = isinstance(obj, IPyAutocall)
    auto_rewrite = getattr(obj, "rewrite", True)

    if esc == ESC_QUOTE:
        # Auto-quote splitting on whitespace
        newcmd = '%s("%s")' % (ifun, '", "'.join(the_rest.split()))
    elif esc == ESC_QUOTE2:
        # Auto-quote whole string
        newcmd = '%s("%s")' % (ifun, the_rest)
    elif esc == ESC_PAREN:
        newcmd = "%s(%s)" % (ifun, ",".join(the_rest.split()))
    else:
        # Auto-paren.
        # We only apply it to argument-less calls if the autocall
        # parameter is set to 2.  We only need to check that autocall is <
        # 2, since this function isn't called unless it's at least 1.
        if not the_rest and (self.shell.autocall < 2) and not force_auto:
            newcmd = "%s %s" % (ifun, the_rest)
            auto_rewrite = False
        else:
            if not force_auto and the_rest.startswith("["):
                if hasattr(obj, "__getitem__"):
                    # Don't autocall in this case: item access for an object
                    # which is BOTH callable and implements __getitem__.
                    newcmd = "%s %s" % (ifun, the_rest)
                    auto_rewrite = False
                else:
                    # if the object doesn't support [] access, go ahead and
                    # autocall
                    newcmd = "%s(%s)" % (ifun.rstrip(), the_rest)
            elif the_rest.endswith(";"):
                newcmd = "%s(%s);" % (ifun.rstrip(), the_rest[:-1])
            else:
                newcmd = "%s(%s)" % (ifun.rstrip(), the_rest)

    if auto_rewrite:
        self.shell.auto_rewrite_input(newcmd)

    return newcmd


# Traceback (KeyError)
I1 from scipy import io
I2 s1 = io.idl.readsav('test.sav')

I3 s1?
Type:       AttrDict
Base Class: <class 'scipy.io.idl.AttrDict'>
String Form:
{'dn': array([  1.02282184e+07,   1.05383408e+07,   1.08758739e+07,
1.12449965e+07,   1. <...>  (('r', 'R'), '>f8'), (('v', 'V'), '>f8')]), 'tfit': array([  4.82394886e+02,   4.18176107e-01])}
Namespace:  Interactive
Length:     11
File:       /usr/lib64/python2.7/site-packages/scipy/io/idl.py
Definition: s1(self, name)


I4 s1['dn']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
/home/gsever/Desktop/python-repo/ipython/IPython/core/prefilter.pyc in prefilter_lines(self, lines, continue_prompt)
358                              for lnum, line in enumerate(llines) ])
359         else:
--> 360             out = self.prefilter_line(llines[0], continue_prompt)
361
362         return out

/home/gsever/Desktop/python-repo/ipython/IPython/core/prefilter.pyc in prefilter_line(self, line, continue_prompt)
333             return normal_handler.handle(line_info)
334
--> 335         prefiltered = self.prefilter_line_info(line_info)
336         # print "prefiltered line: %r" % prefiltered

337         return prefiltered

/home/gsever/Desktop/python-repo/ipython/IPython/core/prefilter.pyc in prefilter_line_info(self, line_info)
273         # print "prefilter_line_info: ", line_info

274         handler = self.find_handler(line_info)
--> 275         return handler.handle(line_info)
276
277     def find_handler(self, line_info):

/home/gsever/Desktop/python-repo/ipython/IPython/core/prefilter.pyc in handle(self, line_info)
813
814         force_auto = isinstance(obj, IPyAutocall)
--> 815         auto_rewrite = getattr(obj, 'rewrite', True)
816
817         if esc == ESC_QUOTE:

/usr/lib64/python2.7/site-packages/scipy/io/idl.pyc in __getitem__(self, name)
657
658     def __getitem__(self, name):
--> 659         return super(AttrDict, self).__getitem__(name.lower())
660
661     def __setitem__(self, key, value):

KeyError: 'rewrite'

# Fixed code
def handle(self, line_info):
    """Handle lines which can be auto-executed, quoting if requested."""
    line = line_info.line
    ifun = line_info.ifun
    the_rest = line_info.the_rest
    pre = line_info.pre
    esc = line_info.esc
    continue_prompt = line_info.continue_prompt
    obj = line_info.ofind(self)["obj"]
    # print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun,the_rest)  # dbg

    # This should only be active for single-line input!
    if continue_prompt:
        return line

    force_auto = isinstance(obj, IPyAutocall)

    # User objects sometimes raise exceptions on attribute access other
    # than AttributeError (we've seen it in the past), so it's safest to be
    # ultra-conservative here and catch all.
    try:
        auto_rewrite = obj.rewrite
    except Exception:
        auto_rewrite = True

    if esc == ESC_QUOTE:
        # Auto-quote splitting on whitespace
        newcmd = '%s("%s")' % (ifun, '", "'.join(the_rest.split()))
    elif esc == ESC_QUOTE2:
        # Auto-quote whole string
        newcmd = '%s("%s")' % (ifun, the_rest)
    elif esc == ESC_PAREN:
        newcmd = "%s(%s)" % (ifun, ",".join(the_rest.split()))
    else:
        # Auto-paren.
        # We only apply it to argument-less calls if the autocall
        # parameter is set to 2.  We only need to check that autocall is <
        # 2, since this function isn't called unless it's at least 1.
        if not the_rest and (self.shell.autocall < 2) and not force_auto:
            newcmd = "%s %s" % (ifun, the_rest)
            auto_rewrite = False
        else:
            if not force_auto and the_rest.startswith("["):
                if hasattr(obj, "__getitem__"):
                    # Don't autocall in this case: item access for an object
                    # which is BOTH callable and implements __getitem__.
                    newcmd = "%s %s" % (ifun, the_rest)
                    auto_rewrite = False
                else:
                    # if the object doesn't support [] access, go ahead and
                    # autocall
                    newcmd = "%s(%s)" % (ifun.rstrip(), the_rest)
            elif the_rest.endswith(";"):
                newcmd = "%s(%s);" % (ifun.rstrip(), the_rest[:-1])
            else:
                newcmd = "%s(%s)" % (ifun.rstrip(), the_rest)

    if auto_rewrite:
        self.shell.auto_rewrite_input(newcmd)

    return newcmd