# Check if function accepts specific keyword argument

**URL:** https://discourse.julialang.org/t/check-if-function-accepts-specific-keyword-argument/108605
**Category:** General Usage
**Tags:** functions
**Created:** [January 10, 2024, 4:49am UTC](https://discourse.julialang.org/t/check-if-function-accepts-specific-keyword-argument/108605 "2024-01-10T04:49:05Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![sandyspiers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sandyspiers/32/205992_2.png) [@sandyspiers](https://discourse.julialang.org/u/sandyspiers)
#### Post date: [January 10, 2024, 4:49am UTC](https://discourse.julialang.org/t/check-if-function-accepts-specific-keyword-argument/108605/1 "2024-01-10T04:49:05Z")

</div>

Suppose I have

```julia
julia> f(;y=1) = y
f (generic function with 1 method)

```

If I want to check whether `f` accepts `y` as a keyword argument I can do

```julia
julia> hasmethod(f, Tuple{}, (:y,))
true

```

But this requires knowing the number of non-keyword arguments.  
For instance

```julia
julia> g(x1, x2; y=1) = (x1 + x2) * y
g (generic function with 1 method)

julia> hasmethod(g, Tuple{Any, Any}, (:y,))
true

julia> hasmethod(g, Tuple{Any}, (:y,))
false

julia> hasmethod(g, Tuple{}, (:y,))
false

```

How can I check whether `g` accepts `y` as a keyword, **without** knowing how many non-keyword arguments it accepts?

Thanks in advance!!

---

<div class="post-metadata">

### Author: ![sandyspiers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sandyspiers/32/205992_2.png) [@sandyspiers](https://discourse.julialang.org/u/sandyspiers)
#### Post date: [January 10, 2024, 5:04am UTC](https://discourse.julialang.org/t/check-if-function-accepts-specific-keyword-argument/108605/2 "2024-01-10T05:04:15Z")

</div>

This is the best I’ve got so far,

```julia
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.

Is there anything more Julia-like?

Cheers

---

<div class="post-metadata">

### Author: ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)
#### Post date: [January 10, 2024, 6:26am UTC](https://discourse.julialang.org/t/check-if-function-accepts-specific-keyword-argument/108605/3 "2024-01-10T06:26:51Z")

</div>

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-repl
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)

```

1. There is no method that corresponding to `foo(Any, Any)` so your `check_if_keyword_accepted` would always return false.
2. 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-repl
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-repl
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

```

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [January 10, 2024, 7:06am UTC](https://discourse.julialang.org/t/check-if-function-accepts-specific-keyword-argument/108605/4 "2024-01-10T07:06:15Z")

</div>

> [@abraemer](#):
>
> `methods(foo)`

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`.
