Ticket #5405 (closed enhancement: fixed)

Opened 18 months ago

Last modified 4 months ago

create a decorator for adding default keyword arguments to a function

Reported by: mhansen Owned by: cwitty
Priority: minor Milestone: sage-4.4.2
Component: misc Keywords:
Cc: mhansen, jason Author(s): Tim Dumol
Report Upstream: N/A Reviewer(s): Mike Hansen
Merged in: sage-4.4.2.alpha0 Work issues:

Description (last modified by nthiery) (diff)

The typical usage of this decorator would be to be applied above a :obj:cached_method or :obj:cached_function decorator so that the correct cached object is returned.

Attachments

trac_5405.patch Download (1.6 KB) - added by mhansen 18 months ago.
trac_5405-decorator-partial.patch Download (1.8 KB) - added by timdumol 9 months ago.
Adds module sage.misc.decorators with content specialize.
trac_5405-decorator-partial.2.patch Download (2.0 KB) - added by mvngu 4 months ago.
same as previous but with username

Change History

Changed 18 months ago by mhansen

  Changed 18 months ago by nthiery

Hi Mike!

I am not so sure about the name, although I can't propose much better than default_values, or set_default_values.

Could it be generalized to handle both positional and non positional arguments?

I'd suggest to have the doc by starting with what the thing actually does, followed by the typical usage. Speaking of which: could you add an example of this typical usage? (it was not clear to me).

  Changed 18 months ago by jason

  • cc jason added

  Changed 17 months ago by nthiery

  • cc mhansen added; jason removed
  • summary changed from [with patch, needs review] create a decorator for adding default keyword arguments to a function to [with patch, needs work] create a decorator for adding default keyword arguments to a function

Oops, should have set the subject to needs work. Done.

  Changed 11 months ago by jason

  • cc jason added

  Changed 10 months ago by timdumol

Sorry if I don't get this right, but doesn't functools.partial already fulfill this purpose?

  Changed 10 months ago by jason

Do you mean something like this?

from functools import partial

def partial_dec(*args, **kwds):
    def p(f):
        return partial(f,*args,**kwds)
    return p
    
@partial_dec(b=2)
def f(a,b):
    return 10*a+b

f(4)

  Changed 10 months ago by timdumol

Actually I meant something like this:

from functools import partial

@partial(partial, b=4)
def f(a,b):
    return 10*a + b

f(4)

  Changed 10 months ago by jason

Cute. Very nice!

  Changed 10 months ago by jason

So now can you use @wraps or something so that g? works correctly below?

from functools import partial, wraps

@partial(partial, b=4)
def g(a,b):
    """Docs"""
    return 10*a + b

g?

  Changed 10 months ago by timdumol

This works, but it certainly isn't obvious:

from functools import partial, wraps

@partial(lambda x: wraps(x)(partial(partial, b = 4))(x))
def g(a,b):
    """Docs"""
    return 10*a + b

print(g(5))

g?

  Changed 10 months ago by jason

and at that point, I'd say

@default_keywords...
def g...

is nicer. However, one might use partial in the above decorator. I think our discussion is evidence for the usefulness of the idea on this ticket.

  Changed 10 months ago by timdumol

Yep. It's certainly much clearer. Using partial should deal with the positional and non-positional arguments thing.

  Changed 10 months ago by jason

So we've agreed that we should create a partial decorator that allows something like:

from sage.misc.decorators (or wherever) import partial

@partial(*args, **kwds) # Same as calling partial(g, *args, **kwds) and wrapping with @wraps
def g(a,b):
   ...

just works as expected.

follow-up: ↓ 15   Changed 10 months ago by timdumol

Perhaps a name of curry [1] would be better, since it prevents name collision with functools.partial? Then again, it supersedes functools.partial anyways.

[1]  http://en.wikipedia.org/wiki/Currying

in reply to: ↑ 14 ; follow-up: ↓ 16   Changed 10 months ago by nthiery

  • description modified (diff)

Thanks much for pointing out functools.partial and functool.wrapper; I have several other use cases for them!

Replying to timdumol:

Perhaps a name of curry [1] would be better, since it prevents name collision with functools.partial? Then again, it supersedes functools.partial anyways. [1]  http://en.wikipedia.org/wiki/Currying

I prefer partial, since curry does not really encompass the specialization of named arguments. It's really functools.partial, but made into a decorator.

in reply to: ↑ 15   Changed 10 months ago by timdumol

I prefer partial, since curry does not really encompass the specialization of named arguments. It's really functools.partial, but made into a decorator.

Fair enough -- but just to clarify, functools.partial *is* a decorator, just that it doesn't update the documentation string.

Changed 9 months ago by timdumol

Adds module sage.misc.decorators with content specialize.

  Changed 9 months ago by timdumol

  • status changed from needs_work to needs_review
  • upstream set to N/A

Nevermind, functools.partial is not a decorator. My apologies.

This patch should do the trick. I named it specialize rather than partial, since partial conflicts with functools.partial.

  Changed 4 months ago by mhansen

  • status changed from needs_review to positive_review
  • reviewer set to Mike Hansen
  • author set to Tim Dumol

Looks good to me.

Changed 4 months ago by mvngu

same as previous but with username

  Changed 4 months ago by mvngu

  • summary changed from [with patch, needs work] create a decorator for adding default keyword arguments to a function to create a decorator for adding default keyword arguments to a function

The patch  trac_5405-decorator-partial.2.patch is the same as Tim's patch, but with his username.

  Changed 4 months ago by mvngu

  • status changed from positive_review to closed
  • resolution set to fixed
  • merged set to sage-4.4.2.alpha0
Note: See TracTickets for help on using tickets.