<br><br><div><span class="gmail_quote">On 5/17/06, <b class="gmail_sendername">tomer filiba</b> &lt;<a href="mailto:tomerfiliba@gmail.com">tomerfiliba@gmail.com</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
hi all<br><br>i would like to suggest changing the base-exception class, whatever<br>it may be (Exception/BaseException) to work with keyword arguments<br>instead of positional ones.</blockquote><div><br><br>Positional support is deprecated; there will only be support for a single argument.&nbsp; Read PEP 352 to see how BaseException will end up in Python 3000.
<br><br>And I brought this up with Guido once and he was not enthusiastic about it.&nbsp; Basically, keep exceptions simple.&nbsp; They are important and basic enough to keep it simple.&nbsp; If you want fancier support, subclass Exception and add the support you want.
<br><br>-Brett<br>&nbsp;</div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">instead of<br><br>try:<br>&nbsp;&nbsp;&nbsp;&nbsp;...<br>except IOError, ex:<br>&nbsp;&nbsp;&nbsp;&nbsp;print ex[1]
<br># or<br>except IOError, (code, text, filename):<br>&nbsp;&nbsp;&nbsp;&nbsp;...<br>&nbsp;&nbsp;&nbsp;&nbsp;# which means changes to code/text/filename do not change<br>&nbsp;&nbsp;&nbsp;&nbsp;# the exception object<br><br>use<br><br>try:<br>&nbsp;&nbsp;&nbsp;&nbsp;raise IOError(filename = &quot;lala&quot;, code=17, text=&quot;blah blah blah&quot;)
<br>except IOError, ex:<br>&nbsp;&nbsp;&nbsp;&nbsp;ex.code = 18<br>&nbsp;&nbsp;&nbsp;&nbsp;raise<br><br>raise IndexError(&quot;invalid index&quot;, index = the_index)<br>raise KeyError(&quot;key not found&quot;, key = the_key)<br>raise AttributeError(&quot;attribute not found&quot;, name = name)
<br><br>where the new exception can be something like<br><br>class Exception:<br>&nbsp;&nbsp;&nbsp;&nbsp;def __init__(self, message = None, **kw):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self._message = message<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.__dict__.update(kw)<br>&nbsp;&nbsp;&nbsp;&nbsp;def __repr__(self):
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;attrs = sorted(&quot;%s = %r&quot; % (k, v)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for k, v in self.__dict__.iteritems()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if not k.startswith(&quot;_&quot;))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &quot;&lt;%s(%s, %s)&gt;&quot; % (self.__class__.__name__,
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self._message, &quot;, &quot;.join(attrs))<br><br>class IOError(Exception):<br>&nbsp;&nbsp; pass<br><br>raise IOError(code = 17, text = &quot;EBLAH&quot;, filename = &quot;lalala&quot;)<br><br>the builtin errors might want to enforce an &quot;exception signature&quot;,
<br><br>class ExceptionSignature(Exception):<br>&nbsp;&nbsp;&nbsp;&nbsp;attributes = []<br>&nbsp;&nbsp;&nbsp;&nbsp;def __init__(self, *args, **kw):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for name in self.attributes:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assert name in kw, &quot;expected an attribute named %s&quot; % (name,)
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Exception.__init__(self, *args, **kw)<br><br>class IOError(ExceptionSignature):<br>&nbsp;&nbsp;&nbsp;&nbsp;attributes = [&quot;code&quot;, &quot;text&quot;, &quot;filename&quot;]<br><br>or something like that, so the attributes of the exception are part
<br>of its official interface.<br><br>rationale:<br>* today, AttributeError's are raised as<br>AttributeError(&quot;%s object has no attribute %s&quot; % ...)<br>which means analyzing the exception requires parsing text!<br>
 * IOError (among others), for instance, does nasty and not-so-well documented<br>overloading of named/positional arguments: when you pass 1-3 arguments,<br>they are stored in .args, but also in .errno, .strerror, and<br>
.filename. if you pass<br>more than 3 arguments, the attributes are all set to None and only<br>.args is filled.<br>yuck.<br><br>you can see this for reference:<br><a href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496698">
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496698</a><br><br>----<br><br>that said, i would also want to introduce ArgumentError. there are<br>many times just a ValueError isn't enough. instead, having a builtin
<br>ArgumentError would made things more clear:<br><br>def write_to_file(the_file):<br>&nbsp;&nbsp;&nbsp;&nbsp;if the_file.closed:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise ArgumentError(&quot;the file must be open&quot;, name = &quot;the_file&quot;)<br>&nbsp;&nbsp;&nbsp;&nbsp;the_file.write(...)
<br><br>and with ArgumentError included, calling functions with invalid<br>signatures would also raise ArgumentError. TypeError is quite<br>silly in this case, as it has nothing to do with the *type* of<br>the function or its arguments.
<br><br>&gt;&gt;&gt; def f(a): pass<br>&gt;&gt;&gt; f(1,2)<br>Traceback (most recent call last):<br>&nbsp;&nbsp;File &quot;&lt;stdin&gt;&quot;, line 1, in ?<br>*TypeError*: f() takes exactly 1 argument (2 given)<br>&gt;&gt;&gt; type(f)
<br>&lt;type 'function'&gt; # like any other function<br><br>TypeError is too-broadly overloaded this way.<br><br><br>-tomer<br>_______________________________________________<br>Python-3000 mailing list<br><a href="mailto:Python-3000@python.org">
Python-3000@python.org</a><br><a href="http://mail.python.org/mailman/listinfo/python-3000">http://mail.python.org/mailman/listinfo/python-3000</a><br>Unsubscribe: <a href="http://mail.python.org/mailman/options/python-3000/brett%40python.org">
http://mail.python.org/mailman/options/python-3000/brett%40python.org</a><br></blockquote></div><br>