Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functoolz.reorder_args #546

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open

Conversation

groutr
Copy link
Contributor

@groutr groutr commented Aug 18, 2022

Candidate function to reorder arguments of an existing function.
Allows alternative function signatures that might be more useful to curry. The wrapped function name reflects the argument remapping for easier debugging.

@groutr
Copy link
Contributor Author

groutr commented Aug 18, 2022

Apparently the .replace method on code objects wasn't introduced till Python 3.8. Code objects have readonly attributes though, so I need to figure out a workaround for updating the wrapper function name.

@groutr
Copy link
Contributor Author

groutr commented Aug 7, 2023

@eriknw The test failures I think are caused by the linter. This is ready to look over though.

@ZeroBomb
Copy link

ZeroBomb commented Jan 2, 2025

I have also reached for and missed a 'reorder' function, especially when dealing with some of the dicttoolz functionality like assoc (I don't always want the dictionary as the first arg). I'm not as big a fan of the two-argument approach here. I would prefer a single argument to designate the order, and there are a few ways to do that:

  • you could supply a tuple indicating the position you want each argument to come from or go to, so you'd do something like
def reorder(f, ordering):
    def inner(*args, **kwargs):
        return f(*[args[i] for i in ordering], **kwargs)
   return inner   
  • you could supply a dictionary defining the positional changes you want to make. This would free you from needing to specify the position of every argument, but would be a a little tricky to specify correctly if you had a lot of args. So you'd do something like this:
def reorder(f, ordering):
    # handle the case of incomplete specification by assuming flips, e.g. {2:1} requires a corresponding {1:2}
   complete_ordering = merge(dict(map(reverse, ordering.items())), ordering)

    def inner(*args, **kwargs):
        return f(*[args[get_in(complete_ordering, [i], default=i)] for i  in range(len(args))], **kwargs)
   return inner   

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants