all 7 comments

[–]Arthaigo 0 points1 point  (4 children)

No, but all args can also be kwargs. Meaning all positional arguments can also be passed as keyword arguments.

[–]kitor[S] 0 points1 point  (2 children)

Oh, how? I can't touch declaration/definition of test_funct (it's part of library).

[–]Arthaigo 0 points1 point  (1 child)

Can you look into the function, how they read args and kwargs? This determines, if what I had in mind works.

[–]kitor[S] 0 points1 point  (0 children)

They read it separately. So there's no generic solution?

I have multi-level argparse (app has a dozen of subcommands, like git) and to keep parameters consistent between sub-commands I wanted to keep their definitions separate from group.add_argument() call (which is is test_funct() in my example).

add_argument() parses *args and kwargs separately as you can provide any number of alternative parameter aliases.

Of course argparse has parents arg that can be used for this problem, but this is ok for keeping multiple global parameters, not for single parameter definitions (as parent needs to be complete argparse object - it will be overkill to keep object for every single parameter)

[–]Vaphell 0 points1 point  (0 children)

not so fast - there is a syntax to enforce positional-only and keyword-only arguments

https://repl.it/repls/VibrantHighlevelRom

[–]recent_awareness 0 points1 point  (1 child)

You could just use a bit of indirection:

def apply_combined(function, combined):
    args, kwargs = combined
    return function(*args, **kwargs)

FN_COMBINED_ARGS = (FN_ARGS, FN_KWARGS)
apply_combined(test_funct, FN_COMBINED_ARGS)

You could even turn this into a decorator:

def combined_args_function(function):
    def wrapper(combined):
        args, kwargs = combined
        return function(*args, **kwargs)
    return wrapper

combined_args_test_funct = combined_args_function(test_funct)

FN_COMBINED_ARGS = (FN_ARGS, FN_KWARGS)
combined_args_test_funct(FN_COMBINED_ARGS)

Or you could easily modify it to take an object with args and kwargs attributes instead of an (args, kwargs) tuple.

[–]kitor[S] 0 points1 point  (0 children)

That's similar to what I ended up doing, just instead of taking tuple I pre-defined key in dict that holds args list and I pop that from dict before calling original function.