Possible to know if a certain method supports a certain keyword?

Is it possible to know if a certain method supports a certain keyword argument, or one has to use exceptions?

Possible with hasmethod (not applicable), but this isn’t good practice. A particular call site doesn’t specify a method; method dispatch is handled for you as you provide various positional arguments. While different methods can have different keyword arguments, it’s good practice to keep the applicable keyword arguments consistent over interchangeable positional argument types or sometimes over a change in the function itself, like a plotting package’s functions sharing keyword arguments for graphics settings. You could add a keyword argument for all methods where a particular positional argument is narrowed down, like dims for AbstractArrays, but you wouldn’t use dims in calls that may interchange either Numbers or Arrays for that argument. You should mostly rely on consistent keyword argument applicability, then use hasmethod or handle MethodErrors as a last resort.

1 Like

Thank you.

Here an example:

struct Foo
    x::Int64
end
struct Goo
    x::Int64
end
oo(f::Foo) = Foo.x + 1
oo(g::Goo;extra=0) = Goo.x + 1 + extra 
hasmethod(oo,Tuple{Foo},(:extra,)) # false
hasmethod(oo,Tuple{Goo},(:extra,)) # true

I am doing this in a larger project. I cannot copy-paste code (MWE) from that, but here are the steps:

Use CodeTracking.code_string + MacroTools.splitdef

Provided you have the function and the candidate method at hand, you can do:

# where m is your method
types = tuple(m.sig.types[2:end]...)
# where fn is your function
codestring = CodeTracking.code_string(fn, types)

And now, your task is mainly parsing the codestring (using Meta.parse) and playing with the resulting expression.

I recommend using MacroTools.splitdef for this and you’ll be able to easily extract all the :kwargs (including their types and/or default values) from the expression above. So you can easily check if your target keyword is supported by a certain method.

Putting this together, you get a nice function that you call with function, method of interest, and your keyword symbol (+ bonus, you can check the type and value - if those were somehow set at the method definition).

Happy LLM function calling :slight_smile: (I suspect that is what you want to achieve).

Depending on the situation, a useful alternative can be to let all methods slurp extraneous keyword arguments, e.g.

oo(f::Foo; _...) = Foo.x + 1
oo(g::Goo;extra=0, _...) = Goo.x + 1 + extra 

The obvious drawbacks are that you need to have control of all methods yourself and that you lose all protection against misspelling of keywords or sending the wrong keywords to a method.