[Python-3000] exceptions with keyword arguments

tomer filiba tomerfiliba at gmail.com
Thu May 18 21:28:42 CEST 2006


> Positional support is deprecated; there will only be support for a
> single argument. Read
> PEP 352 to see how BaseException will end up in Python 3000.

i don't see how BaseException addresses issues like accessing
attributes rather than positional args, or introducing something equivalent
to ArgumentError. raising a TypeError is just semantically wrong in that
case -- it has nothing to do with types whatsoever.

from the pep:
> This PEP proposes introducing a new exception named BaseException
> that is a new-style class and has a single attribute, message (that will
> cause the deprecation of the existing args attribute)
well, how do you suggest passing back the error-code, or file name of
exceptions like IOError, or the attribute name of an AttributeError?
a single argument can only be used for pretty printing, not really providing
information *about* the exception. so unless people would want to
use regular expressions to *parse* the message, why not allow keyword
arguments for extra info about the exception?

> And I brought this up with Guido once and he was not enthusiastic
> about it.  Basically, keep exceptions simple.  They are important
> and basic enough to keep it simple.  If you want fancier support,
> subclass Exception and add the support you want.
well, if guido pronounced on it than i guess it's settled, but why do you
condsider *args to be simple and **kwargs not as simple? don't you
think "ex.filename" is simpler/clearer than "ex[1]"?


-tomer

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


More information about the Python-3000 mailing list