<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.8.1: http://docutils.sourceforge.net/" />
<title></title>
<style type="text/css">

/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7056 2011-06-17 10:50:48Z milde $
:Copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.

See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/

/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
  border: 0 }

table.borderless td, table.borderless th {
  /* Override padding for "table.docutils td" with "! important".
     The right padding separates the table cells. */
  padding: 0 0.5em 0 0 ! important }

.first {
  /* Override more specific margin styles with "! important". */
  margin-top: 0 ! important }

.last, .with-subtitle {
  margin-bottom: 0 ! important }

.hidden {
  display: none }

a.toc-backref {
  text-decoration: none ;
  color: black }

blockquote.epigraph {
  margin: 2em 5em ; }

dl.docutils dd {
  margin-bottom: 0.5em }

object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
  overflow: hidden;
}

/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
  font-weight: bold }
*/

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

/* Uncomment (and remove this text!) to get reduced vertical space in
   compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
  margin-bottom: 0.5em }

div.compound .compound-last, div.compound .compound-middle {
  margin-top: 0.5em }
*/

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em ;
  margin-right: 2em }

div.footer, div.header {
  clear: both;
  font-size: smaller }

div.line-block {
  display: block ;
  margin-top: 1em ;
  margin-bottom: 1em }

div.line-block div.line-block {
  margin-top: 0 ;
  margin-bottom: 0 ;
  margin-left: 1.5em }

div.sidebar {
  margin: 0 0 0.5em 1em ;
  border: medium outset ;
  padding: 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
  margin-top: 0.4em }

h1.title {
  text-align: center }

h2.subtitle {
  text-align: center }

hr.docutils {
  width: 75% }

img.align-left, .figure.align-left, object.align-left {
  clear: left ;
  float: left ;
  margin-right: 1em }

img.align-right, .figure.align-right, object.align-right {
  clear: right ;
  float: right ;
  margin-left: 1em }

img.align-center, .figure.align-center, object.align-center {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

.align-left {
  text-align: left }

.align-center {
  clear: both ;
  text-align: center }

.align-right {
  text-align: right }

/* reset inner alignment in figures */
div.align-right {
  text-align: inherit }

/* div.align-center * { */
/*   text-align: left } */

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.attribution {
  text-align: right ;
  margin-left: 50% }

p.caption {
  font-style: italic }

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font: inherit }

pre.literal-block, pre.doctest-block, pre.math {
  margin-left: 2em ;
  margin-right: 2em }

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option {
  white-space: nowrap }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

span.section-subtitle {
  /* font-size relative to parent (h1..h6 element) */
  font-size: 80% }

table.citation {
  border-left: solid 1px gray;
  margin-left: 1px }

table.docinfo {
  margin: 2em 4em }

table.docutils {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.footnote {
  border-left: solid 1px black;
  margin-left: 1px }

table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

table.docutils th.field-name, table.docinfo th.docinfo-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap ;
  padding-left: 0 }

h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
  font-size: 100% }

ul.auto-toc {
  list-style-type: none }

</style>
</head>
<body>
<div class="document">


<p>PEP: XXX
Title: Sample reStructuredText PEP Template
Version: $Revision$
Last-Modified: $Date$
Author: Sebastian Kreft <<a class="reference external" href="mailto:skreft@deezer.com">skreft@deezer.com</a>>
Status: Draft
Type: Standards Track
Content-Type: text/x-rst
Created: 29-Mar-2014
Post-History:</p>
<div class="section" id="abstract">
<h1>Abstract</h1>
<p>Exceptions like <tt class="docutils literal">KeyError</tt>, <tt class="docutils literal">IndexError</tt>, <tt class="docutils literal">AttributeError</tt> and
<tt class="docutils literal">NameError</tt> do not provide all information required by programmers to debug
and better understand what caused them.
Furthermore, in some cases the messages even have slightly different formats,
which makes it really difficult for tools to automatically provide additional
information to diagnose the problem.
To tackle the former and to lay ground for the latter, it is proposed to expand
these exceptions so to hold both the offending and affected entities.</p>
</div>
<div class="section" id="rationale">
<h1>Rationale</h1>
<p>The main issue this PEP aims to solve is the fact that currently error messages
are not that expressive and lack some key information to resolve the exceptions.
Additionally, the information present on the error message is not always in the
same format, which makes it very difficult for third-party libraries to
provide automated diagnosis of the error.</p>
<p>These automated tools could, for example, detect typos or display or log extra
debug information. These could be particularly useful when running tests or in a
long running application.</p>
<p>Although it is in theory possible to have such libraries, they need to resort to
hacks in order to achieve the goal. One such example is
python-improved-exceptions <a class="footnote-reference" href="#id7" id="id1">[1]</a>, which modifies the byte-code to keep references
to the possibly interesting objects and also parses the error messages to
extract information like types or names. Unfortunately, such approach is
extremely fragile and not portable.</p>
<p>A similar proposal <a class="footnote-reference" href="#id8" id="id2">[2]</a> has been implemented for <tt class="docutils literal">ImportError</tt> and in the same
fashion this idea has received support <a class="footnote-reference" href="#id9" id="id3">[3]</a>.</p>
</div>
<div class="section" id="examples">
<h1>Examples</h1>
<div class="section" id="indexerror">
<h2>IndexError</h2>
<p>The error message does not reference the list's length nor the index used.</p>
<pre class="literal-block">
a = [1, 2, 3, 4, 5]
a[5]
IndexError: list index out of range
</pre>
</div>
<div class="section" id="keyerror">
<h2>KeyError</h2>
<p>By convention the key is the first element of the error's argument, but there's
no other information regarding the affected dictionary (keys types, size, etc.)</p>
<pre class="literal-block">
b = {'foo': 1}
b['fo']
KeyError: 'fo'
</pre>
</div>
<div class="section" id="attributeerror">
<h2>AttributeError</h2>
<p>The object's type and the offending attribute are part of the error message.
However, there are some different formats and the information is not always
available. Furthermore, although the object type is useful in some cases, given
the dynamic nature of Python, it would be much more useful to have a reference
to the object itself. Additionally the reference to the type is not fully
qualified and in some cases the type is just too generic to provide useful
information, for example in case of accessing a module's attribute.</p>
<pre class="literal-block">
c = object()
c.foo
AttributeError: 'object' object has no attribute 'foo'

import string
string.foo
AttributeError: 'module' object has no attribute 'foo'

a = string.Formatter()
a.foo
AttributeError: 'Formatter' object has no attribute 'foo'
</pre>
</div>
<div class="section" id="nameerror">
<h2>NameError</h2>
<p>The error message provides typically the name.</p>
<pre class="literal-block">
foo = 1
fo
NameError: global name 'fo' is not defined
</pre>
</div>
<div class="section" id="other-cases">
<h2>Other Cases</h2>
<p>Issues are even harder to debug when the target object is the result of
another expression, for example:</p>
<pre class="literal-block">
a[b[c[0]]]
</pre>
<p>This issue is also related to the fact that opcodes only have line number
information and not the offset. This proposal would help in this case but not as
much as having offsets.</p>
</div>
</div>
<div class="section" id="proposal">
<h1>Proposal</h1>
<p>Extend the exceptions <tt class="docutils literal">IndexError</tt>, <tt class="docutils literal">KeyError</tt>, <tt class="docutils literal">AttributeError</tt> and
<tt class="docutils literal">NameError</tt> with the following:</p>
<ul class="simple">
<li><tt class="docutils literal">IndexError</tt>: target, index</li>
<li><tt class="docutils literal">KeyError</tt>: target, key</li>
<li><tt class="docutils literal">AttributeError</tt>: target, attribute</li>
<li><tt class="docutils literal">NameError</tt>: name, scope?</li>
</ul>
<p>To remain backwards compatible these new attributes will be optional and keyword
only.</p>
<p>It is proposed to add this information, rather than just improve the error, as
the former would allow new debugging frameworks and tools and also in the future
to switch to a lazy generated message. Generated messages are discussed in <a class="footnote-reference" href="#id8" id="id4">[2]</a>,
although they are not implemented at the moment. They would not only save some
resources, but also uniform the messages.</p>
</div>
<div class="section" id="potential-uses">
<h1>Potential Uses</h1>
<p>An automated tool could for example search for similar keys within the object,
allowing to display the following::</p>
<pre class="literal-block">
a = {'foo': 1}
a['fo']
KeyError: 'fo'. Did you mean 'foo'?

foo = 1
fo
NameError: global name 'fo' is not defined. Did you mean 'foo'?
</pre>
<p>See <a class="footnote-reference" href="#id9" id="id5">[3]</a> for the output a TestRunner could display.</p>
</div>
<div class="section" id="performance">
<h1>Performance</h1>
<p>Filling these new attributes would only require two extra parameters with data
already available so the impact should be marginal. However, it may need
special care for <tt class="docutils literal">KeyError</tt> as the following pattern is already widespread.</p>
<pre class="literal-block">
try:
  a[foo] = a[foo] + 1
except:
  a[foo] = 0
</pre>
<p>Note as well that storing these objects into the error itself would allow the
lazy generation of the error message, as discussed in <a class="footnote-reference" href="#id8" id="id6">[2]</a>.</p>
</div>
<div class="section" id="references">
<h1>References</h1>
<table class="docutils footnote" frame="void" id="id7" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>Python Exceptions Improved
(<a class="reference external" href="https://www.github.com/sk-/python-exceptions-improved">https://www.github.com/sk-/python-exceptions-improved</a>)</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id8" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label">[2]</td><td><em>(<a class="fn-backref" href="#id2">1</a>, <a class="fn-backref" href="#id4">2</a>, <a class="fn-backref" href="#id6">3</a>)</em> ImportError needs attributes for module and file name
(<a class="reference external" href="http://bugs.python.org/issue1559549">http://bugs.python.org/issue1559549</a>)</td></tr>
</tbody>
</table>
<table class="docutils footnote" frame="void" id="id9" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label">[3]</td><td><em>(<a class="fn-backref" href="#id3">1</a>, <a class="fn-backref" href="#id5">2</a>)</em> Enhance exceptions by attaching some more  information to them
(<a class="reference external" href="https://mail.python.org/pipermail/python-ideas/2014-February/025601.html">https://mail.python.org/pipermail/python-ideas/2014-February/025601.html</a>)</td></tr>
</tbody>
</table>
</div>
<div class="section" id="copyright">
<h1>Copyright</h1>
<p>This document has been placed in the public domain.</p>
<!-- Local Variables:
mode: indented-text
indent-tabs-mode: nil
sentence-end-double-space: t
fill-column: 70
coding: utf-8
End: -->
</div>
</div>
</body>
</html>