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.
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@python.org http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com