On Sun, Jul 02, 2017 at 12:19:54PM -0700, Ken Kundert wrote: > class BaseException: > def __init__(self, *args, **kwargs): > self.args = args > self.kwargs = kwargs > > def __str__(self): > template = self.kwargs.get('template') > if template is None: > sep = self.kwargs.get('sep', ' ') > return sep.join(str(a) for a in self.args) > else: > return template.format(*self.args, **self.kwargs)
I think this API is too general. It accepts arbitrary keyword arguments and stores them in the exception. I think that makes for a poor experience for the caller: try: something() except MyParsingError as err: if 'column' in err.kwargs: ... elif 'col' in err.kwargs: ... elif 'x' in err.kwargs: # 'x' is the column, or is it the row? ... The problem here is, unless the exception class offers a real API for extracting the column, how do you know what key to use? You can't expect BaseException to force the user of MyParsingError to be consistent: raise MyParsingError(17, 45, template='Error at line {} column {}') raise MyParsingError(45, 17, template='Error at column {} line {}') raise MyParsingError(45, 17, temlpate='Error at col {} row {}') # oops raise MyParsingError(17, template='Error at line {}') raise MyParsingError(99, 45, 17, template='Error code {} at column {} line {}') Unless MyParsingError offers a consistent (preferably using named attributes) API for extracting the data, pulling it out of args is just as much of a hack as scraping it from the error message. It seems to me that we can't solve this problem at BaseException. It has to be tackled by each exception class. Only the author of each exception class knows what information it carries and should be provided via named attributes. I think OSError has a good approach. https://docs.python.org/3/library/exceptions.html#OSError For backwards compatibility, when you raise OSError with a single argument, it looks like this: raise OSError('spam is my problem') => OSError: spam is my problem When you offer two or up to five arguments, they get formatted into a nicer error message, and stored into named attributes: raise OSError(99, 'spam is my problem', 'xxx', 123, 'yyy') => OSError: [Errno 99] foo is my problem: 'xxx' -> 'yyy' Missing arguments default to None. I don't think there is a generic recipe that will work for all exceptions, or even all exceptions in the standard exception heirarchy, that can make that pleasant. Perhaps I'm insufficiently imaginative, but I don't think this problem can be solved with a quick hack of the BaseException class. -- Steve _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/