On 5/17/06, tomer filiba <[EMAIL PROTECTED]> 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
[email protected]
http://mail.python.org/mailman/listinfo/python-3000
Unsubscribe: http://mail.python.org/mailman/options/python-3000/brett%40python.org

_______________________________________________
Python-3000 mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-3000
Unsubscribe: 
http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com

Reply via email to