Temporary solution from user side for type piracy between packages?

Is there a quick fix for a package introducing type piracy? Currently, importing Images clobbers Distances because it imports ImageDistances that overloads evaluate (see avoid type piracy? · Issue #28 · JuliaImages/ImageDistances.jl · GitHub). Is there a temporary fix as a user that I can do till this is figured out?

julia> using Distances

julia> evaluate(WeightedEuclidean([1,1,1000]), [1,2,3], [1,2,4])
31.622776601683793

julia> sqrt(1000)
31.622776601683793

julia> using Images

julia> evaluate(WeightedEuclidean([1,1,1000]), [1,2,3], [1,2,4])
ERROR: MethodError: Distances.result_type(::WeightedEuclidean{Array{Int64,1}}, ::Array{Int64,1}, ::Array{Int64,1}) is ambiguous. Candidates:
  result_type(dist::PreMetric, ::AbstractArray{#s19,N} where N where #s19<:Union{Colorant{T1,N} where N, AbstractArray{#s12,N} where #s12<:Union{Colorant{T1,N} where N, T1} where N, T1}, ::AbstractArray{#s17,N} where N where #s17<:Union{Colorant{T2,N} where N, AbstractArray{#s12,N} where #s12<:Union{Colorant{T2,N} where N, T2} where N, T2}) where {T1<:Number, T2<:Number} in ImageDistances at /home/tamas/.julia/packages/ImageDistances/okX3M/src/generic.jl:83
  result_type(dist::Union{WeightedCityblock{W}, WeightedEuclidean{W}, WeightedHamming{W}, WeightedSqEuclidean{W}, WeightedMinkowski{W,T} where T<:Real} where W, ::AbstractArray{T1,N} where N, ::AbstractArray{T2,N} where N) where {T1, T2} in Distances at /home/tamas/.julia/packages/Distances/HOWRG/src/wmetrics.jl:46
Possible fix, define
  result_type(::Union{WeightedCityblock{W}, WeightedEuclidean{W}, WeightedHamming{W}, WeightedSqEuclidean{W}, WeightedMinkowski{W,T} where T<:Real} where W, ::AbstractArray{T1<:(Union{Colorant{T1,N} where N, AbstractArray{#s12,N} where #s12<:Union{Colorant{T1,N} where N, T1} where N, T1} where T1<:Number),N} where N, ::AbstractArray{T2<:(Union{Colorant{T2,N} where N, AbstractArray{#s12,N} where #s12<:Union{Colorant{T2,N} where N, T2} where N, T2} where T2<:Number),N} where N)
Stacktrace:
 [1] evaluate(::WeightedEuclidean{Array{Int64,1}}, ::Array{Int64,1}, ::Array{Int64,1}) at /home/tamas/.julia/packages/Distances/HOWRG/src/wmetrics.jl:0
 [2] top-level scope at none:0


import instead?

You should still be able to do Distances.evaluate(...), if that’s what you’re looking for.

That gives the same error:

julia> Distances.evaluate(WeightedEuclidean([1,1,1000]), [1,2,3], [1,2,4])
ERROR: MethodError: Distances.result_type(::WeightedEuclidean{Array{Int64,1}}, ::Array{Int64,1}, ::Array{Int64,1}) is ambiguous. Candidates:
  result_type(dist::PreMetric, ::AbstractArray{#s19,N} where N where #s19<:Union{Colorant{T1,N} where N, AbstractArray{#s12,N} where #s12<:Union{Colorant{T1,N} where N, T1} where N, T1}, ::AbstractArray{#s17,N} where N where #s17<:Union{Colorant{T2,N} where N, AbstractArray{#s12,N} where #s12<:Union{Colorant{T2,N} where N, T2} where N, T2}) where {T1<:Number, T2<:Number} in ImageDistances at /home/tamas/.julia/packages/ImageDistances/okX3M/src/generic.jl:83
  result_type(dist::Union{WeightedCityblock{W}, WeightedEuclidean{W}, WeightedHamming{W}, WeightedSqEuclidean{W}, WeightedMinkowski{W,T} where T<:Real} where W, ::AbstractArray{T1,N} where N, ::AbstractArray{T2,N} where N) where {T1, T2} in Distances at /home/tamas/.julia/packages/Distances/HOWRG/src/wmetrics.jl:46
Possible fix, define
  result_type(::Union{WeightedCityblock{W}, WeightedEuclidean{W}, WeightedHamming{W}, WeightedSqEuclidean{W}, WeightedMinkowski{W,T} where T<:Real} where W, ::AbstractArray{T1<:(Union{Colorant{T1,N} where N, AbstractArray{#s12,N} where #s12<:Union{Colorant{T1,N} where N, T1} where N, T1} where T1<:Number),N} where N, ::AbstractArray{T2<:(Union{Colorant{T2,N} where N, AbstractArray{#s12,N} where #s12<:Union{Colorant{T2,N} where N, T2} where N, T2} where T2<:Number),N} where N)
Stacktrace:
 [1] evaluate(::WeightedEuclidean{Array{Int64,1}}, ::Array{Int64,1}, ::Array{Int64,1}) at /home/tamas/.julia/packages/Distances/HOWRG/src/wmetrics.jl:0
 [2] top-level scope at none:
julia> import Distances

julia> evaluate(WeightedEuclidean([1,1,1000]), [1,2,3], [1,2,4])
ERROR: UndefVarError: WeightedEuclidean not defined
Stacktrace:
 [1] top-level scope at none:0

julia> evaluate(Distances.WeightedEuclidean([1,1,1000]), [1,2,3], [1,2,4])
ERROR: UndefVarError: evaluate not defined
Stacktrace:
 [1] top-level scope at none:0

julia> Distances.evaluate(Distances.WeightedEuclidean([1,1,1000]), [1,2,3], [1,2,4])
31.622776601683793

julia> import Images

julia> Distances.evaluate(Distances.WeightedEuclidean([1,1,1000]), [1,2,3], [1,2,4])
ERROR: MethodError: Distances.result_type(::Distances.WeightedEuclidean{Array{Int64,1}}, ::Array{Int64,1}, ::Array{Int64,1}) is ambiguous. Candidates:
  result_type(dist::Distances.PreMetric, ::AbstractArray{#s19,N} where N where #s19<:Union{Colorant{T1,N} where N, AbstractArray{#s12,N} where #s12<:Union{Colorant{T1,N} where N, T1} where N, T1}, ::AbstractArray{#s17,N} where N where #s17<:Union{Colorant{T2,N} where N, AbstractArray{#s12,N} where #s12<:Union{Colorant{T2,N} where N, T2} where N, T2}) where {T1<:Number, T2<:Number} in ImageDistances at /home/tamas/.julia/packages/ImageDistances/okX3M/src/generic.jl:83
  result_type(dist::Union{WeightedCityblock{W}, WeightedEuclidean{W}, WeightedHamming{W}, WeightedSqEuclidean{W}, WeightedMinkowski{W,T} where T<:Real} where W, ::AbstractArray{T1,N} where N, ::AbstractArray{T2,N} where N) where {T1, T2} in Distances at /home/tamas/.julia/packages/Distances/HOWRG/src/wmetrics.jl:46
Possible fix, define
  result_type(::Union{WeightedCityblock{W}, WeightedEuclidean{W}, WeightedHamming{W}, WeightedSqEuclidean{W}, WeightedMinkowski{W,T} where T<:Real} where W, ::AbstractArray{T1<:(Union{Colorant{T1,N} where N, AbstractArray{#s12,N} where #s12<:Union{Colorant{T1,N} where N, T1} where N, T1} where T1<:Number),N} where N, ::AbstractArray{T2<:(Union{Colorant{T2,N} where N, AbstractArray{#s12,N} where #s12<:Union{Colorant{T2,N} where N, T2} where N, T2} where T2<:Number),N} where N)
Stacktrace:
 [1] evaluate(::Distances.WeightedEuclidean{Array{Int64,1}}, ::Array{Int64,1}, ::Array{Int64,1}) at /home/tamas/.julia/packages/Distances/HOWRG/src/wmetrics.jl:0
 [2] top-level scope at none:0

The import solution cannot work. Either:

  • use Base.delete_method(@which result_type(...)) to delete the unwanted method
  • Define the method that’s suggested in the MethodError: result_type(...) = invoke(result_type, ...)
1 Like

I am actually confused to why import still overrides things

There is no difference between using and import in this respect: both cause the module to be loaded, and loading the module causes the pirate method to be added. using has the additional effect of bringing the exported symbols into the current namespace, but it doesn’t change the way module loading happens.

5 Likes

Read the error message and copy-paste the signature of the method you want. Then write

julia> const _sig = Tuple{Union{WeightedCityblock{W}, WeightedEuclidean{W}, WeightedHamming{W}, WeightedSqEuclidean{W}, WeightedMinkowski{W,T} where T<:Real} where W, AbstractArray{T1,N} where N, AbstractArray{T2,N} where N} where {T1, T2}
Tuple{Union{WeightedCityblock{W}, WeightedEuclidean{W}, WeightedHamming{W}, WeightedSqEuclidean{W}, WeightedMinkowski{W,T} where T<:Real} where W,AbstractArray{T1,N} where N,AbstractArray{T2,N} where N} where T2 where T1

julia> Distances.result_type(d::WeightedEuclidean{Array{T,1}}, a::Array{T,1}, b::Array{T,1}) where T<:Number = invoke(Distances.result_type, _sig, d, a, b)

julia> evaluate(WeightedEuclidean([1,1,1000]), [1,2,3], [1,2,4])
31.622776601683793
3 Likes