Function name unchanged in error message

A

andrew cooke

Is there any way to change the name of the function in an error
message? In the example below I'd like the error to refer to bar(),
for example (the motivation is related function decorators - I'd like
the wrapper function to give the same name)
.... return 7
....Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() takes no arguments (1 given)

Thanks,
Andrew
 
J

Jean-Michel Pichavant

andrew said:
Is there any way to change the name of the function in an error
message? In the example below I'd like the error to refer to bar(),
for example (the motivation is related function decorators - I'd like
the wrapper function to give the same name)


... return 7
...

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() takes no arguments (1 given)

Thanks,
Andrew
In [9]: def foo():
...: return 7
...:

In [10]: bar = foo

In [11]: bar(54)

TypeError: foo() takes no arguments (1 given)

JM
 
C

Chris Rebert

Is there any way to change the name of the function in an error
message?  In the example below I'd like the error to refer to bar(),
for example (the motivation is related function decorators - I'd like
the wrapper function to give the same name)

...     return 7
...
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: foo() takes no arguments (1 given)

It gets weirder:
<function bar at 0x37b830>

Cheers,
Chris
 
P

Peter Otten

andrew said:
Is there any way to change the name of the function in an error
message? In the example below I'd like the error to refer to bar(),
for example (the motivation is related function decorators - I'd like
the wrapper function to give the same name)

... return 7
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() takes no arguments (1 given)

The name is looked up in the code object. As that is immutable you have to
make a new one:

argnames = 'argcount nlocals stacksize flags code consts names varnames
filename name firstlineno lnotab'.split()

def f(): return 42

code = type(f.func_code)
function = type(f)

def make_code(proto, **kw):
for name in argnames:
if name not in kw:
kw[name] = getattr(proto, "co_" + name)
values = [kw[name] for name in argnames]
return code(*values)

if __name__ == "__main__":
def foo():
print "foo"

c = make_code(foo.func_code, name="bar")
foo.func_code = c

foo(42)

Peter
 
E

exarkun

It gets weirder:
<function bar at 0x37b830>

The name is represented in (at least) two places, on the function object
and on the code object:
... >>> foo.func_name
'foo' Traceback (most recent call last):
new.function and new.code will let you construct new objects with
different values (and copying over whichever existing attributes you
want to preserve).

Jean-Paul
 
M

Michele Simionato

Is there any way to change the name of the function in an error
message?  In the example below I'd like the error to refer to bar(),
for example (the motivation is related function decorators - I'd like
the wrapper function to give the same name)

Use the decorator module which does the right thing:
http://pypi.python.org/pypi/decorator
 
P

Peter Otten

Gabriel said:
En Fri, 29 Jan 2010 13:09:40 -0300, Michele Simionato


The decorator module is a very fine addition to anyone's tool set -- but
in this case it is enough to use the wraps() function from the functools
standard module.

I don't know about the decorator module, but functools.wraps() doesn't
affect the error message:
.... def g(): pass
........ except TypeError as e:
.... print e
....
g() takes no arguments (1 given)

Peter
 
A

andrew cooke

The name is looked up in the code object. As that is immutable you have to
make a new one:
[details snipped]

thanks very much! sorry i didn't reply earlier - been travelling.

(also, thanks to any other replies - i'm just reading through at the
moment and this is the first one i've got to that will help me solve
it, but i don't mean to exclude anything later...!)

andrew
 
A

andrew cooke

The decorator module is a very fine addition to anyone's tool set -- but  
in this case it is enough to use the wraps() function from the functools  
standard module.

ah, thanks! i thought something like this existed in the standard
lib, but couldn't find it.

andrew
 
A

andrew cooke

ah, thanks!  i thought something like this existed in the standard
lib, but couldn't find it.

andrew

ah, sorry, peter's code uses types, so i assume that's the way to go
(i was hoping that there was something a bit simpler - i don't like
the fact that the code in peter's code has a fixed list of special
names).

andrew
 
A

andrew cooke

Use the decorator module which does the right thing:http://pypi.python.org/pypi/decorator

curiously, decorator doesn't have this issue, because the way it
defines decorators uses *args. so the error i gave cannot occur at
the level of the decorator - the extra arg is passed to the wrapped
function, and so the error message is correct because it is generated
by the inner function.

i need to look at my code; this might be the simplest solution of all.

thanks,
andrew
 
S

Steven D'Aprano

unfortunately new is deprecated and dropped from 3. i can't see how the
same functionality is available in the types module for 3 - am i missing
something obvious?

You have to get the constructor from an existing object. type(obj) will
always return the type object, which you can use as a constructor.



Possibly even easier:
True

So that's two ways to get a constructor. Now all we need is to learn how
they work:


Help on class function in module builtins:

class function(object)
| function(code, globals[, name[, argdefs[, closure]]])
|
| Create a function object from a code object and a dictionary.
[...]


Help on class code in module builtins:

class code(object)
| code(argcount, kwonlyargcount, nlocals, stacksize, flags, codestring,
| constants, names, varnames, filename, name, firstlineno,
| lnotab[, freevars[, cellvars]])
|
| Create a code object. Not for the faint of heart.
[...]


Not for the faint of heart indeed! The best way of using this is to copy
the parameters from an existing code object, one created by using def.
Look for attributes of f.__code__ starting with "co_".

Don't forget compile as well, which may help.
 
G

Gabriel Genellina

I don't know about the decorator module, but functools.wraps() doesn't
affect the error message:

It seems I misunderstood the original request and got it backwards - but
then I have to question the usefulness of doing so. If an error happens in
the "decorating" function (as opposed to inside the function being
decorated) I'd like the error to be reported as such, in the "decorating"
function (else tracebacks and line numbers would be lying).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top