I don’t know the answer, but here’s an old stack overflow question. The workings of kwargs have changed since then though, so I don’t know if it’s still relevant, but at the time this wasn’t possible.
The manual still says that kwargs don’t participate in dispatch, so you might achieve the same ends by just checking in the body of the function
We know here that the type of kwargs is Iterator.Pairs; therefore, it can not be restrict to type Int.
I think the feasible way should be: g(;kwargs::T...) where {T<:AbstractDict{Symbol, Int}} = println(kwargs)
test:
julia> g(x=1, y=2, z=3)
Base.Iterators.Pairs(:x=>1,:y=>2,:z=>3)
julia> g(x=1, y=2.5)
ERROR: MethodError: no method matching #g#3(::Base.Iterators.Pairs{Symbol,Real,Tuple{Symbol,Symbol},NamedTuple{(:x, :y),Tuple{Int64,Float64}}}, ::typeof(g))
Closest candidates are:
#g#3(::T<:AbstractDict{Symbol,Int64}, ::Any) where T<:AbstractDict{Symbol,Int64} at REPL[1]:1
Stacktrace:
[1] (::getfield(Main, Symbol("#kw##g")))(::NamedTuple{(:x, :y),Tuple{Int64,Float64}}, ::typeof(g)) at .\none:0
[2] top-level scope at none:0
julia>
If the type of kwargs is more than one, the second parameter of AbstractDict should be a abstract type that are the supertype of kwargs’ type; such as AbstractDict{Symbol, Real} for g(x=1.0, y=1).
If the type of the keywords is more arbitrary, there is no need to add a parameter type Abstract{Symbol, Any}. After all, function keywords do not participate in the dispatch.
Further, not adding keyword type does not affect the speed of the function, as long as the set of keyword parameters has been run once (compiled).
julia> handle_kva(d::D) where {D<:AbstractDict{Symbol,T}} where T = println(d)
handle_kva (generic function with 1 method)
julia> f(;kwargs...) = handle_kva(kwargs)
f (generic function with 1 method)
julia> f(;x=1)
Base.Iterators.Pairs(:x=>1)
julia> f()
ERROR: MethodError: no method matching handle_kva(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}})
Closest candidates are:
handle_kva(::D<:AbstractDict{Symbol,T}) where {T, D<:AbstractDict{Symbol,T}} at REPL[1]:1
Stacktrace:
[1] #f#3(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::Function) at ./REPL[2]:1
[2] f() at ./REPL[2]:1
[3] top-level scope at none:0
I assume you can solve it by handle_kva(d::D) where {D<:AbstractDict{M,T}} where {M,T} = Dict{Symbol,Any}()
but still It would be awesome to solve it on the function signature.
Is your question about the exception of empty keyword parameter?
I test that the type of kwargs is subtype of AbstractDict{Union{}, Union{}} where keyword parameter is empty. So may be Union{AbstractDict{Union{}, Union{}}, AbstractDict{Symbol, Int}} could be used to consider the exception.