Keyword Argument Support?

Hi, I just recently had a desire to use a keyword argument for a ROOT function, found it wasn’t supported, and searched the forum for any other information. Back in 2010 there was a post saying “looks like we should work on this!”

Is there any updated news on keyword argument support for PyROOT?

One of the posts said that often ROOT argument names aren’t in the header files - isn’t this terribly bad practice? Such occurrences should be filed as a bug in ROOT, the arguments should have useful names and should only be left blank if they are actually unused parameters.

In the case of less-than-useful parameter names, the help() function in Python also returns the type of the arguments. Usually the type + name of the arguments is enough information to figure out familiar functions without needing to load up the full documentation. Again though, misleading or useless argument names could be considered a documentation bug.

Regarding my particular need, I wanted to pass a non-default argument for the final argument of a function that takes many, leading the others default. Instead I have to manually type the defaults as listed with help().

Jean-François

Jean-François,

[quote=“jfcaron”]Is there any updated news on keyword argument support for PyROOT?[/quote]no, I’ve not spent any cycles on it.

[quote=“jfcaron”]One of the posts said that often ROOT argument names aren’t in the header files - isn’t this terribly bad practice?[/quote]It’s more a statement of fact that argument names are not part of the C++ API, so the C++ developer can freely change them without consideration for derived code, and thus unwittingly break python code that relies on argument names for keywords.

[quote=“jfcaron”]Regarding my particular need, I wanted to pass a non-default argument for the final argument of a function that takes many, leading the others default. Instead I have to manually type the defaults as listed with help().[/quote]Yes, that is one of those cases that is equally bad, as the default arguments could change in the API, and that would then not propagate to this call, even though you’d want the change to propagate.

Cheers,
Wim

Apparently there are proposals on the C++ side to have keyword arguments added to the language, but it’s something the library writers would have to opt-into. A less ambitious proposal is to add a new use for the “default” keyword in place of function arguments - it would explicitly use the default, allowing you to then specify non-default args after it, and without having to hardcode the current default value from the docs. This way existing libraries could be used with the new feature without the lib needing to be updated.

In line with that second proposal, to programmatically ask for the default values without having to type them, I noticed that PyROOT functions have a func_defaults tuple, e.g. ROOT.TString.Strip.func_defaults is (‘kTrailing’, ’ '). Is there a way to use these to auto-generate default arguments for PyROOT from these?

Unfortunately kTrailing is in ROOT.TString, while " " is actually just a c-char, so I don’t think there is enough information to fully reconstruct the signature with defaults. For a specific case you can do something like:

from ROOT TString TString(TString("foo ").Strip(getattr(TString,TString.Strip.func_defaults[0]),TString.Strip.func_defaults[1]))
Also for constructors with default arguments, those are not stored in func_defaults.

Jean-François

Jean-François,

[quote=“jfcaron”]In line with that second proposal, to programmatically ask for the default values without having to type them, I noticed that PyROOT functions have a func_defaults tuple, e.g. ROOT.TString.Strip.func_defaults is (‘kTrailing’, ’ '). Is there a way to use these to auto-generate default arguments for PyROOT from these?[/quote]yes, PyROOT generates func_defaults in call for the benefit of help(). See e.g. help(ROOT.TString.Strip).

[quote=“jfcaron”]Also for constructors with default arguments, those are not stored in func_defaults.[/quote]Are you sure? E.g. try ROOT.std.vector(int).init.func_defaults (see it’s help for the full list of overloads and where that default comes from).

It’s not that it’s not technically feasible to add keyword arguments, it just has been on the very low priority list since forever, as I’m doubtful of the use (as explained above).

Cheers,
WIm