Consider this code:
def spam(*args, **kwargs):
args, kwargs = __pre_spam(*args, **kwargs)
# args & kwargs are OK: proceed
# ...
def __pre_spam(*args, **kwargs):
# validate args & kwargs;
# return canonicalized versions of args & kwargs;
# on failure, raise some *informative* exception
# ...
return canonicalized_args, canonicalized_kwargs
I write functions like __pre_spam for one reason only: to remove
clutter from a corresponding spam function that has a particularly
complex argument-validation/canonicalization stage. In effect,
spam "outsources" to __pre_spam the messy business of checking and
conditioning its arguments.
The one thing I don't like about this strategy is that the tracebacks
of exceptions raised during the execution of __pre_spam include one
unwanted stack level (namely, the one corresponding to __pre_spam
itself).
__pre_spam should be completely invisible and unobtrusive, as if
it had been textually "inlined" into spam prior to the code's
interpretation. And I want to achieve this without in any way
cluttering spam with try/catches, decorators, and whatnot. (After
all, the whole point of introducing __pre_spam is to declutter
spam.)
It occurs to me, in my innocence (since I don't know the first
thing about the Python internals), that one way to achieve this
would be to have __pre_spam trap any exceptions (with a try/catch
around its entire body), and somehow pop its frame from the
interpreter stack before re-raising the exception. (Or some
clueful/non-oxymoronic version of this.) How feasible is this?
And, if it is quite unfeasible, is there some other way to achieve
the same overall design goals described above?
TIA!
~kj
--
http://mail.python.org/mailman/listinfo/python-list