I have a lot of functions that perform the same argument checking each time:
def spam(a, b): if condition(a) or condition(b): raise TypeError if other_condition(a) or something_else(b): raise ValueError if whatever(a): raise SomethingError ... def eggs(a, b): if condition(a) or condition(b): raise TypeError if other_condition(a) or something_else(b): raise ValueError if whatever(a): raise SomethingError ... Since the code is repeated, I naturally pull it out into a function: def _validate(a, b): if condition(a) or condition(b): raise TypeError if other_condition(a) or something_else(b): raise ValueError if whatever(a): raise SomethingError def spam(a, b): _validate(a, b) ... def eggs(a, b): _validate(a, b) ... But when the argument checking fails, the traceback shows the error occurring in _validate, not eggs or spam. (Naturally, since that is where the exception is raised.) That makes the traceback more confusing than it need be. So I can change the raise to return in the _validate function: def _validate(a, b): if condition(a) or condition(b): return TypeError if other_condition(a) or something_else(b): return ValueError if whatever(a): return SomethingError and then write spam and eggs like this: def spam(a, b): ex = _validate(a, b) if ex is not None: raise ex ... It's not much of a gain though. I save an irrelevant level in the traceback, but only at the cost of an extra line of code everywhere I call the argument checking function. But suppose we allowed "raise None" to do nothing. Then I could rename _validate to _if_error and write this: def spam(a, b): raise _if_error(a, b) ... and have the benefits of "Don't Repeat Yourself" without the unnecessary, and misleading, extra level in the traceback. Obviously this doesn't work now, since raise None is an error, but if it did work, what do you think? -- Steven -- https://mail.python.org/mailman/listinfo/python-list