The problem of anonymity with decorators

Franck Pommereau pommereau at univ-paris12.fr
Tue Feb 7 10:49:04 EST 2006


Dear all,

I would like to work around the "anonymizing" effect of decorators when
an exception is raised in the wrapped function. Let's consider the
following example:

    def int_result (fun) :
        def wrapped (*largs, **kwargs) :
            result = fun(*largs, **kwargs)
            if not isinstance(result, int) :
                raise TypeError, "should return int"
            return result
        return wrapped

    @int_result
    def add (a, b) :
        return a+b

    print add(1, 2)
    print add("foo", "bar")

As expected, the last line results in raising TypeError:

    Traceback (most recent call last):
      File "wrapping.py", line 14, in ?
        print add("foo", "bar")
      File "wrapping.py", line 5, in wrapped
        raise TypeError, "should return int"
    TypeError: should return int

My problem is that the errors comes from a function named "wrapped"
while I'd prefer to see here the name of the wrapped function. Indeed,
the code above is only a stripped down sample code but in my
application, I'll have a lot of functions, all wrapped the same way. So
I'd prefer a traceback like:

    Traceback (most recent call last):
      File "wrapping.py", line 14, in ?
        print add("foo", "bar")
      File "wrapping.py", line 8, in add (wrapped)
        @int_result
    TypeError: should return int

Where the exception seems to come from the point where add "was"
wrapped, instead of from the inside of the wrapper.

I tried to change wrapper.__name__ and wrapper.func_name but it does not
change the traceback, and wrapper.func_code.co_name is read-only. I also
tried, unsuccessfully, to rename functions with:

    import new
    def rename (fun, name) :
        return new.function(fun.func_code, {}, name)

So, my questions:
 - can I change a function name so that it affects the traceback when an
   exception is raised in the function?
 - is there some special trick to raise an exception making it, in
   appearance, coming from somewhere else?

Thanks in advance for any answer.

Regards,
Franck



More information about the Python-list mailing list