How to fix ambiguities found through Aqua.jl?

Hello!

I am using Aqua to find ambiguities in my package (GitHub - AhmedSalih3d/SPHExample: Simple SPH dam-break simulation in Julia) and the following ones have been found:

julia> @testset "aqua test ambiguities" begin
           Aqua.test_ambiguities([SPHExample, Core, Base])
       end
16 ambiguities found. To get a list, set `broken = false`.
Ambiguity #1
<(a::SentinelArrays.ChainedVectorIndex, b::Integer) @ SentinelArrays IWillNotTellYouMyDriveLetter:\SomeRandomUser\.julia\packages\SentinelArrays\V85ev\src\chainedvector.jl:211
<(i::Integer, x::BigInt) @ Base.GMP gmp.jl:737

Possible fix, define
  <(::SentinelArrays.ChainedVectorIndex, ::BigInt)

Ambiguity #2
<(a::Integer, b::SentinelArrays.ChainedVectorIndex) @ SentinelArrays IWillNotTellYouMyDriveLetter:\SomeRandomUser\.julia\packages\SentinelArrays\V85ev\src\chainedvector.jl:212
<(x::BigInt, i::Integer) @ Base.GMP gmp.jl:736

Possible fix, define
  <(::BigInt, ::SentinelArrays.ChainedVectorIndex)

Ambiguity #3
<=(a::Integer, b::SentinelArrays.ChainedVectorIndex) @ SentinelArrays IWillNotTellYouMyDriveLetter:\SomeRandomUser\.julia\packages\SentinelArrays\V85ev\src\chainedvector.jl:212
<=(x::BigInt, i::Integer) @ Base.GMP gmp.jl:730

Possible fix, define
  <=(::BigInt, ::SentinelArrays.ChainedVectorIndex)

Ambiguity #4
<=(a::SentinelArrays.ChainedVectorIndex, b::Integer) @ SentinelArrays IWillNotTellYouMyDriveLetter:\SomeRandomUser\.julia\packages\SentinelArrays\V85ev\src\chainedvector.jl:211
<=(i::Integer, x::BigInt) @ Base.GMP gmp.jl:731

Possible fix, define
  <=(::SentinelArrays.ChainedVectorIndex, ::BigInt)

Ambiguity #5
==(a::SentinelArrays.ChainedVectorIndex, b::Integer) @ SentinelArrays IWillNotTellYouMyDriveLetter:\SomeRandomUser\.julia\packages\SentinelArrays\V85ev\src\chainedvector.jl:211
==(i::Integer, x::BigInt) @ Base.GMP gmp.jl:723

Possible fix, define
  ==(::SentinelArrays.ChainedVectorIndex, ::BigInt)

Ambiguity #6
==(a::Integer, b::SentinelArrays.ChainedVectorIndex) @ SentinelArrays IWillNotTellYouMyDriveLetter:\SomeRandomUser\.julia\packages\SentinelArrays\V85ev\src\chainedvector.jl:212
==(x::BigInt, i::Integer) @ Base.GMP gmp.jl:722

Possible fix, define
  ==(::BigInt, ::SentinelArrays.ChainedVectorIndex)

Ambiguity #7
broadcasted(f::F, A::SentinelArrays.ChainedVector) where F @ SentinelArrays IWillNotTellYouMyDriveLetter:\SomeRandomUser\.julia\packages\SentinelArrays\V85ev\src\chainedvector.jl:940
broadcasted(style::Base.Broadcast.BroadcastStyle, f::F, args...) where F @ Base.Broadcast broadcast.jl:1349

Possible fix, define
  broadcasted(::F, ::F) where {F<:SentinelArrays.ChainedVector, F<:Base.Broadcast.BroadcastStyle}

Ambiguity #8
copyto!(dest::AbstractVector, src::SentinelArrays.ChainedVector) @ SentinelArrays IWillNotTellYouMyDriveLetter:\SomeRandomUser\.julia\packages\SentinelArrays\V85ev\src\chainedvector.jl:388
copyto!(dest::PermutedDimsArray, src::AbstractArray) @ Base.PermutedDimsArrays permuteddimsarray.jl:234

Possible fix, define
  copyto!(::PermutedDimsArray{T, 1} where T, ::SentinelArrays.ChainedVector)

Ambiguity #9
copyto!(dest::AbstractVector, src::SentinelArrays.ChainedVector) @ SentinelArrays IWillNotTellYouMyDriveLetter:\SomeRandomUser\.julia\packages\SentinelArrays\V85ev\src\chainedvector.jl:388
copyto!(dest::PermutedDimsArray{T, N}, src::AbstractArray{T, N}) where {T, N} @ Base.PermutedDimsArrays permuteddimsarray.jl:230

Possible fix, define
  copyto!(::PermutedDimsArray{T, 1}, ::SentinelArrays.ChainedVector{T, A} where A<:AbstractVector{T}) where T

Ambiguity #10
defalg(::AbstractArray{<:Union{Missing, InlineStrings.String1, InlineStrings.String15, InlineStrings.String3, InlineStrings.String7}}) @ InlineStrings IWillNotTellYouMyDriveLetter:\SomeRandomUser\.julia\packages\InlineStrings\79NvI\src\InlineStrings.jl:892
defalg(v::AbstractArray{<:Union{Missing, Number}}) @ Base.Sort sort.jl:1350

Possible fix, define
  defalg(::AbstractArray{<:Missing})

Ambiguity #11
findall(f::Function, x::SentinelArrays.ChainedVector) @ SentinelArrays IWillNotTellYouMyDriveLetter:\SomeRandomUser\.julia\packages\SentinelArrays\V85ev\src\chainedvector.jl:913
findall(pred::Base.Fix2{typeof(in)}, x::AbstractArray) @ Base array.jl:2617

Possible fix, define
  findall(::Base.Fix2{typeof(in)}, ::SentinelArrays.ChainedVector)

Ambiguity #12
reduce(op::OP, x::SentinelArrays.ChainedVector) where OP @ SentinelArrays IWillNotTellYouMyDriveLetter:\SomeRandomUser\.julia\packages\SentinelArrays\V85ev\src\chainedvector.jl:785
reduce(::typeof(vcat), A::AbstractVector{<:AbstractVecOrMat}) @ Base abstractarray.jl:1718

Possible fix, define
  reduce(::typeof(vcat), ::SentinelArrays.ChainedVector{T, A} where {T<:(AbstractVecOrMat), A<:AbstractVector{T}})

Ambiguity #13
reduce(op::OP, x::SentinelArrays.ChainedVector) where OP @ SentinelArrays IWillNotTellYouMyDriveLetter:\SomeRandomUser\.julia\packages\SentinelArrays\V85ev\src\chainedvector.jl:785
reduce(::typeof(hcat), A::AbstractVector{<:AbstractVecOrMat}) @ Base abstractarray.jl:1721

Possible fix, define
  reduce(::typeof(hcat), ::SentinelArrays.ChainedVector{T, A} where {T<:(AbstractVecOrMat), A<:AbstractVector{T}})

Ambiguity #14
reshape(s::StructArrays.StructArray{T}, d::Tuple{Vararg{Union{Colon, Integer}}}) where T @ StructArrays IWillNotTellYouMyDriveLetter:\SomeRandomUser\.julia\packages\StructArrays\CjQ4L\src\structarray.jl:471
reshape(parent::AbstractArray, shp::Tuple{Union{Integer, Base.OneTo}, Vararg{Union{Integer, Base.OneTo}}}) @ Base reshapedarray.jl:111

Possible fix, define
  reshape(::StructArrays.StructArray{T}, ::Tuple{Integer, Vararg{Integer}}) where T

Ambiguity #15
similar(s::StructArrays.StructArray, S::Type, sz::Tuple{Union{Integer, AbstractUnitRange}, Vararg{Union{Integer, AbstractUnitRange}}}) @ StructArrays IWillNotTellYouMyDriveLetter:\SomeRandomUser\.julia\packages\StructArrays\CjQ4L\src\structarray.jl:297
similar(a::AbstractArray, ::Type{T}, dims::Tuple{Integer, Vararg{Integer}}) where T @ Base abstractarray.jl:840

Possible fix, define
  similar(::StructArrays.StructArray, ::Type{T}, ::Tuple{Integer, Vararg{Integer}}) where T

Ambiguity #16
similar(s::StructArrays.StructArray, S::Type, sz::Tuple{Union{Integer, Base.OneTo}, Vararg{Union{Integer, Base.OneTo}}}) @ StructArrays IWillNotTellYouMyDriveLetter:\SomeRandomUser\.julia\packages\StructArrays\CjQ4L\src\structarray.jl:297        
similar(a::AbstractArray, ::Type{T}, dims::Tuple{Integer, Vararg{Integer}}) where T @ Base abstractarray.jl:840

Possible fix, define
  similar(::StructArrays.StructArray, ::Type{T}, ::Tuple{Integer, Vararg{Integer}}) where T

But when I test only on my package it says:

julia> @testset "aqua test ambiguities" begin
           Aqua.test_ambiguities(SPHExample)
       end
Test Summary:         | Pass  Total  Time
aqua test ambiguities |    1      1  6.4s
Test.DefaultTestSet("aqua test ambiguities", Any[], 1, false, false, true, 1.723806076676e9, 1.723806083029e9, false, "REPL[79]")

So I am a bit unsure on what to do and how to proceed?

I guess my question is more: does this impact the performance of my code, if yes, how can I resolve it from my code?

Kind regards

I found that following the advice given with Possible fix, define works well … (I use a separate file, “aqua.jl” and include it last).

[the rest is an informal suggestion]
Then rerunning Aqua will let you know if there remain additional possible fixes – if so, add them.) If ambiguates still persist – look deeper at the clashes for guidance in making them disappear. Many ambiguities that Aqua finds arise from not-your-code (at least in half part). Do not be overly concerned about those, easily resolved, cases.

1 Like

That is actually a really nice suggestion!

So I got the part about making a file aqua.jl, defining the methods and then include it last.

Apologize if a basic question, but how would you for example do this one though?

16 ambiguities found. To get a list, set `broken = false`.
Ambiguity #1
<(a::SentinelArrays.ChainedVectorIndex, b::Integer)
<(i::Integer, x::BigInt) @ Base.GMP gmp.jl:737

Possible fix, define
  <(::SentinelArrays.ChainedVectorIndex, ::BigInt)

I understand the concept as:

#file: aqua.jl

Base.<(::SentinelArrays.ChainedVectorIndex, ::BigInt) #= ? - What should be here, or am I misunderstanding something?

Kind regards

After a bit of a chat with ChatGPT, I found this:

#https://discourse.julialang.org/t/how-to-fix-ambiguities-found-through-aqua-jl/118269/2

using SentinelArrays
using StructArrays: StructArray
using InlineStrings

# Resolving ambiguity #1
Base.:<(a::SentinelArrays.ChainedVectorIndex, b::BigInt) = <(Int(a), b)

# Resolving ambiguity #2
Base.:<(a::BigInt, b::SentinelArrays.ChainedVectorIndex) = <(a, Int(b))

# Resolving ambiguity #3
Base.:<=(a::BigInt, b::SentinelArrays.ChainedVectorIndex) = <=(a, Int(b))

# Resolving ambiguity #4
Base.:<=(a::SentinelArrays.ChainedVectorIndex, b::BigInt) = <=(Int(a), b)

# Resolving ambiguity #5
Base.:(==)(a::SentinelArrays.ChainedVectorIndex, b::BigInt) = ==(BigInt(a), b)

# Resolving ambiguity #6
Base.:(==)(a::BigInt, b::SentinelArrays.ChainedVectorIndex) = ==(a, BigInt(b))

# Resolving ambiguity #8
Base.copyto!(dest::PermutedDimsArray{T, 1}, src::SentinelArrays.ChainedVector) where T = Base.copyto!(dest, collect(src))

# Resolving ambiguity #9
Base.copyto!(dest::PermutedDimsArray{T, 1}, src::SentinelArrays.ChainedVector{T, A} where A<:AbstractVector{T}) where T = Base.copyto!(dest, collect(src))

# Resolving ambiguity #12
Base.reduce(::typeof(vcat), x::SentinelArrays.ChainedVector{T, A} where {T<:(AbstractVecOrMat), A<:AbstractVector{T}}) = Base.reduce(vcat, collect(x))

# Resolving ambiguity #13
Base.reduce(::typeof(hcat), x::SentinelArrays.ChainedVector{T, A} where {T<:(AbstractVecOrMat), A<:AbstractVector{T}}) = Base.reduce(hcat, collect(x))

# Resolving ambiguity #14
Base.reshape(s::StructArray{T}, d::Tuple{Integer, Vararg{Integer}}) where T = Base.reshape(collect(s), d)

# Resolving ambiguity #15
Base.similar(s::StructArray, S::Type, sz::Tuple{Integer, Vararg{Integer}}) = Base.similar(collect(s), S, sz)

# Resolving Ambiguity #1
Base.Broadcast.broadcasted(::Base.Broadcast.BroadcastStyle, f::F, A::SentinelArrays.ChainedVector) where {F} = Base.Broadcast.broadcasted(f, collect(A))

# Resolving Ambiguity #2
Base.Broadcast.broadcasted(::Type{InlineStrings.InlineString}, A::SentinelArrays.ChainedVector) = Base.Broadcast.broadcasted(InlineStrings.InlineString, collect(A))

# Resolving Ambiguity #3
Base.Sort.defalg(::AbstractArray{<:Missing}) = Base.Sort.defalg(collect(Missing[]))

# Correct way to resolve the ambiguity
Base.Broadcast.broadcasted(::F1, ::F2) where {F1<:Base.Broadcast.BroadcastStyle, F2<:SentinelArrays.ChainedVector} = Base.Broadcast.broadcasted(F1, collect(F2))

# Resolving Ambiguity #4
Base.findall(pred::Base.Fix2{typeof(in)}, x::SentinelArrays.ChainedVector) = Base.findall(pred, collect(x))

Which turns out:

julia> @testset "aqua test ambiguities" begin
           Aqua.test_ambiguities([SPHExample, Core, Base])
       end
Skipping Base.active_repl
Skipping Base.active_repl_backend
Test Summary:         | Pass  Total  Time
aqua test ambiguities |    1      1  4.3s
Test.DefaultTestSet("aqua test ambiguities", Any[], 1, false, false, true, 1.723812839725e9, 1.723812844051e9, false, "REPL[3]")


Which is great, but now it errors out on type piracy… so seems like no easy way out?

Kind regards

You had your type piracy already before you started to resolve the ambiguities, see the one I quotes. Neither BigInt nor Integer are your types.