Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
version = "0.19.0-DEV"

[deps]
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"

[compat]
Expand Down
19 changes: 13 additions & 6 deletions src/dict_support.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
# support functions

using InteractiveUtils: methodswith

function not_iterator_of_pairs(kv)
return any(x->isempty(methodswith(typeof(kv), x, true)),
[iterate]) ||
any(x->!isa(x, Union{Tuple,Pair}), kv)
function not_iterator_of_pairs(kv::T) where T
# if the object is not iterable, return true, else check the eltype of the iteration
Base.isiterable(T) && return true
# else, check if we can check `eltype`:
if Base.IteratorEltype(kv) isa Base.HasEltype
typ = eltype(kv)
if !(typ == Any)
return !(typ <: Union{<: Tuple, <: Pair})

Check warning on line 10 in src/dict_support.jl

View check run for this annotation

Codecov / codecov/patch

src/dict_support.jl#L7-L10

Added lines #L7 - L10 were not covered by tests
end
end
# we can't check eltype, or eltype is not useful,
# so brute force it.
return any(x->!isa(x, Union{Tuple,Pair}), kv)

Check warning on line 15 in src/dict_support.jl

View check run for this annotation

Codecov / codecov/patch

src/dict_support.jl#L15

Added line #L15 was not covered by tests
end
34 changes: 34 additions & 0 deletions test/test_priority_queue.jl
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,40 @@ import Base.Order.Reverse
@test_throws ArgumentError PriorityQueue(Reverse, Reverse)
end

@testset "Strange eltype situations" begin
@testset "Eltype unknown" begin
struct EltypeUnknownIterator{T}
x::T
end
Base.IteratorEltype(::EltypeUnknownIterator) = Base.EltypeUnknown()
Base.iterate(i::EltypeUnknownIterator) = Base.iterate(i.x)
Base.iterate(i::EltypeUnknownIterator, state) = Base.iterate(i.x, state)
Base.IteratorSize(i::EltypeUnknownIterator) = Base.IteratorSize(i.x)
Base.length(i::EltypeUnknownIterator) = Base.length(i.x)
Base.size(i::EltypeUnknownIterator) = Base.size(i.x)

@test_nowarn PriorityQueue(Dict(zip(1:5, 2:6)))
@test_nowarn PriorityQueue(EltypeUnknownIterator(Dict(zip(1:5, 2:6))))
@test_throws ArgumentError PriorityQueue(EltypeUnknownIterator(['a']))
end

@testset "Eltype any" begin
struct EltypeAnyIterator{T}
x::T
end
Base.IteratorEltype(::EltypeAnyIterator) = Base.HasEltype()
Base.eltype(::EltypeAnyIterator) = Any
Base.iterate(i::EltypeAnyIterator) = Base.iterate(i.x)
Base.iterate(i::EltypeAnyIterator, state) = Base.iterate(i.x, state)
Base.IteratorSize(i::EltypeAnyIterator) = Base.IteratorSize(i.x)
Base.length(i::EltypeAnyIterator) = Base.length(i.x)
Base.size(i::EltypeAnyIterator) = Base.size(i.x)

@test_nowarn PriorityQueue(EltypeAnyIterator(Dict(zip(1:5, 2:6))))
@test_throws ArgumentError PriorityQueue(EltypeAnyIterator(['a']))
end
end

end

@testset "PriorityQueueMethods" begin
Expand Down
Loading