SimpleGraphs.SimpleEdgeIter implements ==, but does not have a custom Base.hash implementation, meaning that equal SimpleEdgeIters have differing hashes:
julia> using Graphs
julia> g1 = Graph(0);
julia> g2 = Graph(0);
julia> edges(g1) == edges(g2)
true
julia> hash(edges(g1)) == hash(edges(g2))
false
This breaks an important property of the == function and may lead to incorrect behavior of Dicts and Sets.
A straightforward way to fix this would be to implement something like this:
function Base.hash(edgeiter::Graphs.SimpleGraphs.SimpleEdgeIter, h::UInt)
for edge in edgeiter
h = hash(edge, h)
end
return h
end
But the problem with this is that ==(e1::SimpleEdgeIter, e2::AbstractVector{SimpleEdge}) is also defined, and the hash of a AbstractVector{SimpleEdge}, being an array, depends on the array hash seed and other Julia internals. Moreover, ==(e1::Set{SimpleEdge}, e2::SimpleEdgeIter is also defined and would imply that the value of hash(edgeiter) cannot depend on the order of the edges.
I guess the chance of this actually leading to problematic behavior is quite low, so maybe fixing this is not worth the effort. But in that case maybe the documentation of edges should warn against constructing Sets and Dicts of the returned edge iterator?
SimpleGraphs.SimpleEdgeIterimplements==, but does not have a customBase.hashimplementation, meaning that equalSimpleEdgeIters have differing hashes:This breaks an important property of the
==function and may lead to incorrect behavior ofDicts andSets.A straightforward way to fix this would be to implement something like this:
But the problem with this is that
==(e1::SimpleEdgeIter, e2::AbstractVector{SimpleEdge})is also defined, and the hash of aAbstractVector{SimpleEdge}, being an array, depends on the array hash seed and other Julia internals. Moreover,==(e1::Set{SimpleEdge}, e2::SimpleEdgeIteris also defined and would imply that the value ofhash(edgeiter)cannot depend on the order of the edges.I guess the chance of this actually leading to problematic behavior is quite low, so maybe fixing this is not worth the effort. But in that case maybe the documentation of
edgesshould warn against constructingSets andDicts of the returned edge iterator?