function check_if_keyword_accepted(func, keyword, max_args=15)
keyword = Symbol(keyword)
for i in 0:max_args
if hasmethod(func, NTuple{i,Any}, (keyword,))
return true
end
end
return false
end
Which works for my use case, if we know the maximum number of non-keyword arguments.
I think this question is not well posed. You need to know how many positional parameters and of which type you want/need to use before you can ask whether you can also add some keyword. This is because each method (identified by the types of the positional arguments) can have different keyword arguments. Consider this example:
julia> foo(x::Int, y::Int; z=3)=x+y*z
foo (generic function with 1 method)
julia> foo(a::String, b::String; c=2) = a*b^c
foo (generic function with 2 methods)
There is no method that corresponding to foo(Any, Any) so your check_if_keyword_accepted would always return false.
If you somehow checked whether some method could take a keyword c then just getting true would be rather useless without knowing more of the signature.
What you could probably do is check the output of methods(foo)
julia> methods(foo)
# 2 methods for generic function "foo" from Main:
[1] foo(a::String, b::String; c)
@ REPL[2]:1
[2] foo(x::Int64, y::Int64; z)
@ REPL[1]:1
I inspected the code for printing this using @edit show(stdout, methods(foo)[1]) and found the function Base.kwarg_decl that lists the possible keywords as symbols. So you could do:
julia> function check_if_keyword_accepted(func, keyword)
keyword = Symbol(keyword)
for m in methods(func)
if keyword in Base.kwarg_decl(m)
show(m) # or return m, or collect the compatible methods, ....
#return true
end
end
# return false
end
julia> check_if_keyword_accepted(foo, :c)
foo(a::String, b::String; c) @ Main REPL[3]:1
julia> check_if_keyword_accepted(foo, :z)
foo(x::Int64, y::Int64; z) @ Main REPL[1]:1
This would be my 2nd resort, too. Documentation would be the 1st. This works well because methods generally don’t vary keyword sets as much as your example. Doing so makes a function call like foo(L, M; c = N) not very generic, which warrants separating into different functions. I either see a documented keyword set apply to all methods of a function, or I see keywords be added (not removed) to 1 (not more) subset of the methods with an obvious condition, like dims when an argument is an AbstractArray.