Function name unchanged in error message

Discussion in 'Python' started by andrew cooke, Jan 29, 2010.

  1. andrew cooke

    andrew cooke Guest

    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)

    >>> def foo():

    .... return 7
    ....
    >>> foo.__name__ = 'bar'
    >>> foo(123)

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

    Thanks,
    Andrew
     
    andrew cooke, Jan 29, 2010
    #1
    1. Advertising

  2. andrew cooke wrote:
    > 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)
    >
    >
    >>>> def foo():
    >>>>

    > ... return 7
    > ...
    >
    >>>> foo.__name__ = 'bar'
    >>>> foo(123)
    >>>>

    > 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
     
    Jean-Michel Pichavant, Jan 29, 2010
    #2
    1. Advertising

  3. andrew cooke

    Chris Rebert Guest

    On Fri, Jan 29, 2010 at 5:30 AM, andrew cooke <> wrote:
    > 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)
    >
    >>>> def foo():

    > ...     return 7
    > ...
    >>>> foo.__name__ = 'bar'
    >>>> foo(123)

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


    It gets weirder:

    >>> print(foo)

    <function bar at 0x37b830>

    Cheers,
    Chris
    --
    http://blog.rebertia.com
     
    Chris Rebert, Jan 29, 2010
    #3
  4. andrew cooke

    Peter Otten Guest

    andrew cooke wrote:

    > 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)
    >
    >>>> def foo():

    > ... return 7
    > ...
    >>>> foo.__name__ = 'bar'
    >>>> foo(123)

    > 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
     
    Peter Otten, Jan 29, 2010
    #4
  5. andrew cooke

    Guest

    On 02:10 pm, wrote:
    >On Fri, Jan 29, 2010 at 5:30 AM, andrew cooke <>
    >wrote:
    >>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)
    >>>>>def foo():

    >>...     return 7
    >>...
    >>>>>foo.__name__ = 'bar'
    >>>>>foo(123)

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

    >
    >It gets weirder:
    >>>>print(foo)

    ><function bar at 0x37b830>


    The name is represented in (at least) two places, on the function object
    and on the code object:

    >>> def foo(): pass

    ... >>> foo.func_name
    'foo'
    >>> foo.func_code.co_name

    'foo'
    >>> foo.func_name = 'bar'
    >>> foo

    <function bar at 0xb74f2cdc>
    >>> foo.func_code.co_name = 'baz'

    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: readonly attribute
    >>>

    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
     
    , Jan 29, 2010
    #5
  6. On Jan 29, 2:30 pm, andrew cooke <> wrote:
    > 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
     
    Michele Simionato, Jan 29, 2010
    #6
  7. En Fri, 29 Jan 2010 13:09:40 -0300, Michele Simionato
    <> escribió:

    > On Jan 29, 2:30 pm, andrew cooke <> wrote:
    >> 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


    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.

    --
    Gabriel Genellina
     
    Gabriel Genellina, Jan 29, 2010
    #7
  8. andrew cooke

    Peter Otten Guest

    Gabriel Genellina wrote:

    > En Fri, 29 Jan 2010 13:09:40 -0300, Michele Simionato
    > <> escribió:
    >
    >> On Jan 29, 2:30 pm, andrew cooke <> wrote:
    >>> 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

    >
    > 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:

    >>> from functools import wraps
    >>> def f(): pass

    ....
    >>> @wraps(f)

    .... def g(): pass
    ....
    >>> g.__name__

    'f'
    >>> try: g(42)

    .... except TypeError as e:
    .... print e
    ....
    g() takes no arguments (1 given)

    Peter
     
    Peter Otten, Jan 30, 2010
    #8
  9. andrew cooke

    andrew cooke Guest

    On Jan 29, 11:22 am, Peter Otten <> wrote:
    > 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
     
    andrew cooke, Jan 30, 2010
    #9
  10. andrew cooke

    andrew cooke Guest

    On Jan 29, 5:37 pm, "Gabriel Genellina" <>
    wrote:
    > 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
     
    andrew cooke, Jan 30, 2010
    #10
  11. andrew cooke

    andrew cooke Guest

    andrew cooke, Jan 30, 2010
    #11
  12. andrew cooke

    andrew cooke Guest

    On Jan 30, 7:17 pm, andrew cooke <> wrote:
    > On Jan 29, 5:37 pm, "Gabriel Genellina" <>
    > wrote:
    >
    > > 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


    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
     
    andrew cooke, Jan 30, 2010
    #12
  13. andrew cooke

    andrew cooke Guest

    On Jan 29, 1:09 pm, Michele Simionato <>
    wrote:
    > On Jan 29, 2:30 pm, andrew cooke <> wrote:
    >
    > > 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


    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
     
    andrew cooke, Jan 30, 2010
    #13
  14. On Sat, 30 Jan 2010 14:26:43 -0800, andrew cooke wrote:

    > On Jan 29, 11:50 am, wrote:
    >> new.function and new.code will let you construct new objects with
    >> different values (and copying over whichever existing attributes you
    >> want to preserve).

    >
    > 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.


    >>> newfunction = type(lambda: None)
    >>> newcode = type((lambda: None).__code__)



    Possibly even easier:

    >>> import types
    >>> types.FunctionType is newfunction

    True
    >>> types.CodeType is newcode

    True

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


    >>> help(newfunction)


    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(newcode)


    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.



    --
    Steven
     
    Steven D'Aprano, Jan 31, 2010
    #14
  15. En Sat, 30 Jan 2010 06:28:19 -0300, Peter Otten <>
    escribió:
    > Gabriel Genellina wrote:
    >> En Fri, 29 Jan 2010 13:09:40 -0300, Michele Simionato
    >> <> escribió:
    >>> On Jan 29, 2:30 pm, andrew cooke <> wrote:


    >>>> 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

    >>
    >> 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:


    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).

    --
    Gabriel Genellina
     
    Gabriel Genellina, Feb 1, 2010
    #15
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ahmed Jewahar
    Replies:
    1
    Views:
    4,806
    S. Justin Gengo [MCP]
    Jan 23, 2006
  2. Kevin D.
    Replies:
    4
    Views:
    368
    Kevin D.
    Mar 8, 2006
  3. Roedy Green

    detecting unchanged images

    Roedy Green, Jun 26, 2005, in forum: Java
    Replies:
    7
    Views:
    414
    Roedy Green
    Jun 27, 2005
  4. Bryan Parkoff
    Replies:
    1
    Views:
    358
    Malte Starostik
    Apr 5, 2005
  5. =?Utf-8?B?SklNLkgu?=

    q; DataSet RowState unchanged

    =?Utf-8?B?SklNLkgu?=, May 24, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    2,098
    =?Utf-8?B?SklNLkgu?=
    May 24, 2006
Loading...

Share This Page