Roger-luo / Configurations.jl

Options & Configurations made easy.
https://configurations.rogerluo.dev/stable
MIT License
80 stars 12 forks source link

Type conversion breaks default parameter values #82

Closed VPetukhov closed 1 year ago

VPetukhov commented 1 year ago

Normal behavior. If I define an @option structure that has default values, and then initialize it from a Dict or kwargs with only some arguments provided, it works fine:

using Configurations

@option struct StringOpts
    x::String = "x"
    y::String = "y"
end

from_dict(StringOpts, Dict("x" => "xc")) # Only "x" is provided here!

StringOpts("xc", "y")

Broken behavior. However, if I want to change the type to Symbol, the function requires all arguments to be provided:

@option struct SymOpts
    x::Symbol = :y
    y::Symbol = :y
end

from_dict(SymOpts, Dict("x" => :xc))

ERROR: UndefVarError: y not defined Stacktrace: [1] macro expansion @ ~/.julia/packages/Configurations/uH65h/src/codegen.jl:0 [inlined] [2] from_dict_specialize(#unused#::Type{SymOpts}, d::Dict{String, Symbol}) @ Main ~/.julia/packages/Configurations/uH65h/src/codegen.jl:362 [3] #from_dict#4 @ ~/.julia/packages/Configurations/uH65h/src/from_dict.jl:46 [inlined] [4] from_dict(::Type{SymOpts}, d::Dict{String, Symbol}) @ Configurations ~/.julia/packages/Configurations/uH65h/src/from_dict.jl:33 [5] top-level scope @ REPL[42]:1

The following code works as expected:

from_dict(SymOpts, Dict("x" => :xc, "y" => :yc))

SymOpts(:xc, :yc)

Defining conversion functions like the following doesn't seem to change anything:

Configurations.from_dict(::Type{SymOpts}, ::Type{Symbol}, s::String) = Symbol(s)
Configurations.from_dict(::Type{SymOpts}, ::OptionField{:x}, ::Type{Symbol}, s::String) = Symbol(s)

Version: Configurations v0.17.4, julia v1.8.3

I'd be happy to submit a PR with a fix if you could point me to the place that needs to be changed. I got a bit overwhelmed by the generated code...

Roger-luo commented 1 year ago

It seems something went wrong in the from_dict_generated function, yeah the generated code is a bit large which is hard to debug but that's also why it's faster... I haven't had the time to dig into this function and locate which is causing this, but I'm expecting to have a rewrite of it to make it faster at some point or just switch to StructTypes parser.

Let me have a look this weekend and see if I can figure out what's wrong.

VPetukhov commented 1 year ago

Great, thank you! :)