-
-
Notifications
You must be signed in to change notification settings - Fork 402
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow _AxisLookup
to fallback to Dict getindex
#3028
Conversation
- Allows e.g. looking up `String` key with another `AbstractString`
Codecov Report
@@ Coverage Diff @@
## master #3028 +/- ##
=======================================
Coverage 96.13% 96.13%
=======================================
Files 32 32
Lines 4143 4143
=======================================
Hits 3983 3983
Misses 160 160
Continue to review full report at Codecov.
|
So this PR removes tests for JuMP.jl/src/Containers/DenseAxisArray.jl Line 18 in 1844b21
but it still passes, so I guess we end up throwing the same key error. What happens if you try indexing now with a Symbol or something else? Perhaps it is preferable to add an explicit |
Yes, that's right, now Before: julia> D = DenseAxisArray([5.0 6.0; 7.0 8.0], 2:3, ["a", "b"])
2-dimensional DenseAxisArray{Float64,2,...} with index sets:
Dimension 1, 2:3
Dimension 2, ["a", "b"]
And data, a 2×2 Matrix{Float64}:
5.0 6.0
7.0 8.0
julia> D[2, :a]
ERROR: KeyError: key :a not found
Stacktrace:
[1] getindex(#unused#::JuMP.Containers._AxisLookup{Dict{String, Int64}}, key::Symbol)
@ JuMP.Containers ~/.julia/packages/JuMP/Y4piv/src/Containers/DenseAxisArray.jl:18
[2] _getindex_recurse(data::Tuple{JuMP.Containers._AxisLookup{Dict{String, Int64}}}, keys::Tuple{Symbol}, condition::JuMP.Containers.var"#10#12")
@ JuMP.Containers ~/.julia/packages/JuMP/Y4piv/src/Containers/DenseAxisArray.jl:309
[3] _getindex_recurse(data::Tuple{JuMP.Containers._AxisLookup{Tuple{Int64, Int64}}, JuMP.Containers._AxisLookup{Dict{String, Int64}}}, keys::Tuple{Int64, Symbol}, condition::JuMP.Containers.var"#10#12")
@ JuMP.Containers ~/.julia/packages/JuMP/Y4piv/src/Containers/DenseAxisArray.jl:308
[4] to_index(A::DenseAxisArray{Float64, 2, Tuple{UnitRange{Int64}, Vector{String}}, Tuple{JuMP.Containers._AxisLookup{Tuple{Int64, Int64}}, JuMP.Containers._AxisLookup{Dict{String, Int64}}}}, idx::Tuple{Int64, Symbol})
@ JuMP.Containers ~/.julia/packages/JuMP/Y4piv/src/Containers/DenseAxisArray.jl:318
[5] getindex(::DenseAxisArray{Float64, 2, Tuple{UnitRange{Int64}, Vector{String}}, Tuple{JuMP.Containers._AxisLookup{Tuple{Int64, Int64}}, JuMP.Containers._AxisLookup{Dict{String, Int64}}}}, ::Int64, ::Symbol)
@ JuMP.Containers ~/.julia/packages/JuMP/Y4piv/src/Containers/DenseAxisArray.jl:325
[6] top-level scope
@ REPL[37]:1
julia> D[2, ["a", :b]]
ERROR: KeyError: key Any["a", :b] not found
Stacktrace:
[1] getindex(#unused#::JuMP.Containers._AxisLookup{Dict{String, Int64}}, key::Vector{Any})
@ JuMP.Containers ~/.julia/packages/JuMP/Y4piv/src/Containers/DenseAxisArray.jl:18
[2] _getindex_recurse(data::Tuple{JuMP.Containers._AxisLookup{Dict{String, Int64}}}, keys::Tuple{Vector{Any}}, condition::JuMP.Containers.var"#10#12")
@ JuMP.Containers ~/.julia/packages/JuMP/Y4piv/src/Containers/DenseAxisArray.jl:309
[3] _getindex_recurse(data::Tuple{JuMP.Containers._AxisLookup{Tuple{Int64, Int64}}, JuMP.Containers._AxisLookup{Dict{String, Int64}}}, keys::Tuple{Int64, Vector{Any}}, condition::JuMP.Containers.var"#10#12")
@ JuMP.Containers ~/.julia/packages/JuMP/Y4piv/src/Containers/DenseAxisArray.jl:308
[4] to_index(A::DenseAxisArray{Float64, 2, Tuple{UnitRange{Int64}, Vector{String}}, Tuple{JuMP.Containers._AxisLookup{Tuple{Int64, Int64}}, JuMP.Containers._AxisLookup{Dict{String, Int64}}}}, idx::Tuple{Int64, Vector{Any}})
@ JuMP.Containers ~/.julia/packages/JuMP/Y4piv/src/Containers/DenseAxisArray.jl:318
[5] getindex(::DenseAxisArray{Float64, 2, Tuple{UnitRange{Int64}, Vector{String}}, Tuple{JuMP.Containers._AxisLookup{Tuple{Int64, Int64}}, JuMP.Containers._AxisLookup{Dict{String, Int64}}}}, ::Int64, ::Vector{Any})
@ JuMP.Containers ~/.julia/packages/JuMP/Y4piv/src/Containers/DenseAxisArray.jl:325
[6] top-level scope
@ REPL[38]:1 After (this PR): julia> D = DenseAxisArray([5.0 6.0; 7.0 8.0], 2:3, ["a", "b"]);
julia> D[2, :a]
ERROR: KeyError: key :a not found
Stacktrace:
[1] getindex(h::Dict{String, Int64}, key::Symbol)
@ Base ./dict.jl:498
[2] getindex(x::JuMP.Containers._AxisLookup{Dict{String, Int64}}, key::Symbol)
@ JuMP.Containers ~/repos/JuMP.jl/src/Containers/DenseAxisArray.jl:51
[3] _getindex_recurse(data::Tuple{JuMP.Containers._AxisLookup{Dict{String, Int64}}}, keys::Tuple{Symbol}, condition::JuMP.Containers.var"#10#12")
@ JuMP.Containers ~/repos/JuMP.jl/src/Containers/DenseAxisArray.jl:309
[4] _getindex_recurse(data::Tuple{JuMP.Containers._AxisLookup{Tuple{Int64, Int64}}, JuMP.Containers._AxisLookup{Dict{String, Int64}}}, keys::Tuple{Int64, Symbol}, condition::JuMP.Containers.var"#10#12")
@ JuMP.Containers ~/repos/JuMP.jl/src/Containers/DenseAxisArray.jl:308
[5] to_index(A::DenseAxisArray{Float64, 2, Tuple{UnitRange{Int64}, Vector{String}}, Tuple{JuMP.Containers._AxisLookup{Tuple{Int64, Int64}}, JuMP.Containers._AxisLookup{Dict{String, Int64}}}}, idx::Tuple{Int64, Symbol})
@ JuMP.Containers ~/repos/JuMP.jl/src/Containers/DenseAxisArray.jl:318
[6] getindex(::DenseAxisArray{Float64, 2, Tuple{UnitRange{Int64}, Vector{String}}, Tuple{JuMP.Containers._AxisLookup{Tuple{Int64, Int64}}, JuMP.Containers._AxisLookup{Dict{String, Int64}}}}, ::Int64, ::Symbol)
@ JuMP.Containers ~/repos/JuMP.jl/src/Containers/DenseAxisArray.jl:325
[7] top-level scope
@ REPL[9]:1
julia> D[2, ["a", :b]]
ERROR: KeyError: key :b not found
Stacktrace:
[1] getindex(h::Dict{String, Int64}, key::Symbol)
@ Base ./dict.jl:498
[2] getindex(x::JuMP.Containers._AxisLookup{Dict{String, Int64}}, key::Symbol)
@ JuMP.Containers ~/repos/JuMP.jl/src/Containers/DenseAxisArray.jl:51
[3] (::JuMP.Containers.var"#1#2"{JuMP.Containers._AxisLookup{Dict{String, Int64}}})(key::Symbol)
@ JuMP.Containers ./none:0
[4] iterate
@ ./generator.jl:47 [inlined]
[5] collect_to!(dest::Vector{Int64}, itr::Base.Generator{Vector{Any}, JuMP.Containers.var"#1#2"{JuMP.Containers._AxisLookup{Dict{String, Int64}}}}, offs::Int64, st::Int64)
@ Base ./array.jl:845
[6] collect_to_with_first!(dest::Vector{Int64}, v1::Int64, itr::Base.Generator{Vector{Any}, JuMP.Containers.var"#1#2"{JuMP.Containers._AxisLookup{Dict{String, Int64}}}}, st::Int64)
@ Base ./array.jl:823
[7] collect(itr::Base.Generator{Vector{Any}, JuMP.Containers.var"#1#2"{JuMP.Containers._AxisLookup{Dict{String, Int64}}}})
@ Base ./array.jl:797
[8] getindex
@ ~/repos/JuMP.jl/src/Containers/DenseAxisArray.jl:58 [inlined]
[9] _getindex_recurse
@ ~/repos/JuMP.jl/src/Containers/DenseAxisArray.jl:309 [inlined]
[10] _getindex_recurse
@ ~/repos/JuMP.jl/src/Containers/DenseAxisArray.jl:308 [inlined]
[11] to_index
@ ~/repos/JuMP.jl/src/Containers/DenseAxisArray.jl:318 [inlined]
[12] getindex(::DenseAxisArray{Float64, 2, Tuple{UnitRange{Int64}, Vector{String}}, Tuple{JuMP.Containers._AxisLookup{Tuple{Int64, Int64}}, JuMP.Containers._AxisLookup{Dict{String, Int64}}}}, ::Int64, ::Vector{Any})
@ JuMP.Containers ~/repos/JuMP.jl/src/Containers/DenseAxisArray.jl:325
[13] top-level scope
@ REPL[10]:1 The message is different in the vector case, but I think actually more accurate now: before it might suggest we were looking for the (single) key
We could do that if you prefer. I didn't do that because it'd be more code, and also because it's conceivable that other types will be purposefully implemented to be hash-equal (like InlineStrings are with Strings). Essentially I presumed that first time contributing here so please just let me know what if anything you'd like changed :) |
Sorry about that. Since I was only adding tests I didn't expect coverage to drop, but you're right that current tests, on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is okay. My main concern was users encountering a method error, but the stack trace is already opaque and we still throw the same top-level error.
Also.
This just feels soooo wrong. I get why in this particular case, but still. I guess the precedent is julia> hash(1)
0x5bca7c69b794f8ce
julia> hash(1.0)
0x5bca7c69b794f8ce So this would allow someone to create a set with integers and index with floats? I think I've seen a couple of posts asking for that over the years. Can't find them on discourse though. |
Thanks!
Yes, i suppose that is true. And likewise allow users to have an index set with e.g. |
If/when this is okay to be merged, I would be grateful if it could also be included in a release fairly soon after if possible, as at Invenia we have quite a lot of places where we need to workaround the current behaviour |
There's going to be a bit of a delay on that. The next release is going to be 1.2.0, which includes a bunch of massive changes to the NLP interface, and I want to get #2961 in for that. So no firm ETA, but it'd be in a week or two. |
Thanks @odow !
Okay, good to know - thanks |
String
key with anotherAbstractString
InlineString
keys but where this is an implementation detail and we want to be able to index with a regularString
Before:
After (this PR):