Skip to content

Commit

Permalink
Avoid iterating twice over generators when there is an exception (#137)
Browse files Browse the repository at this point in the history
... at least in Julia >= 1.11 which fixed it via JuliaLang/julia#53151
  • Loading branch information
fingolfin authored Nov 25, 2024
1 parent 6965fb9 commit 3ec011e
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 9 deletions.
23 changes: 14 additions & 9 deletions src/ordered_dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,20 @@ OrderedDict(kv::AbstractDict{K,V}) where {K,V} = OrderedDict{K,V}(kv)
OrderedDict(ps::Pair{K,V}...) where {K,V} = OrderedDict{K,V}(ps)
OrderedDict(ps::Pair...) = OrderedDict(ps)

function OrderedDict(kv)
try
dict_with_eltype((K, V) -> OrderedDict{K, V}, kv, eltype(kv))
catch e
if isempty(methods(iterate, (typeof(kv),))) ||
!all(x->isa(x, Union{Tuple,Pair}), kv)
throw(ArgumentError("OrderedDict(kv): kv needs to be an iterator of tuples or pairs"))
else
rethrow(e)
@static if VERSION >= v"1.11"
# see JuliaLang/julia#53151
OrderedDict(kv) = dict_with_eltype((K, V) -> OrderedDict{K, V}, kv, eltype(kv))
else
function OrderedDict(kv)
try
dict_with_eltype((K, V) -> OrderedDict{K, V}, kv, eltype(kv))
catch e
if isempty(methods(iterate, (typeof(kv),))) ||
!all(x->isa(x, Union{Tuple,Pair}), kv)
throw(ArgumentError("OrderedDict(kv): kv needs to be an iterator of tuples or pairs"))
else
rethrow(e)
end
end
end
end
Expand Down
11 changes: 11 additions & 0 deletions test/test_ordered_dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,17 @@ using OrderedCollections, Test
@test del_slots4 == 0
end

@testset "Issue #86" begin
counter = 0
expensive_function(k) = (counter += 1; k > 2 && error("too large!"))
@test_throws ErrorException OrderedDict(k => expensive_function(k) for k in 1:3)
if VERSION >= v"1.11"
@test counter == 3
else
@test_broken counter == 3 # gives 6 instead
end
end

@testset "ordered access" begin
od = OrderedDict(:a=>1, :b=>2, :c=>3)
@test popfirst!(od) == (:a => 1)
Expand Down

0 comments on commit 3ec011e

Please sign in to comment.