Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some compat for 0.7 #70

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
32 changes: 30 additions & 2 deletions src/Missings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -206,15 +206,19 @@ else
Base.float(A::AbstractArray{Missing}) = A
end

if isdefined(Base, :adjoint)
Base.adjoint(d::Missing) = missing
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be defined in Base as well, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, probably.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add indentation?

end

T(::Type{Union{T1, Missing}}) where {T1} = T1
T(::Type{Missing}) = Union{}
T(::Type{T1}) where {T1} = T1
T(::Type{Any}) = Any

# vector constructors
missings(dims...) = fill(missing, dims)
missings(::Type{T}, dims...) where {T >: Missing} = fill!(Array{T}(dims), missing)
missings(::Type{T}, dims...) where {T} = fill!(Array{Union{T, Missing}}(dims), missing)
missings(::Type{T}, dims...) where {T >: Missing} = fill!(Array{T}(uninitialized, dims), missing)
missings(::Type{T}, dims...) where {T} = fill!(Array{Union{T, Missing}}(uninitialized, dims), missing)

"""
allowmissing(x::AbstractArray)
Expand Down Expand Up @@ -272,10 +276,17 @@ struct EachReplaceMissing{T, U}
x::T
replacement::U
end
if VERSION < v"0.7.0-DEV.3309"
Base.iteratorsize(::Type{<:EachReplaceMissing{T}}) where {T} =
Base.iteratorsize(T)
Base.iteratoreltype(::Type{<:EachReplaceMissing{T}}) where {T} =
Base.iteratoreltype(T)
else
Base.IteratorSize(::Type{<:EachReplaceMissing{T}}) where {T} =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add this replacement to Compat.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to, but it's weird because IteratorSize is defined in 0.6 too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh it is? Hm, that is weird.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fredrik is adding it in Compat as Compat.IteratorSize, so we could use that if this PR is merged after his is merged and tagged.

Base.IteratorSize(T)
Base.IteratorEltype(::Type{<:EachReplaceMissing{T}}) where {T} =
Base.IteratorEltype(T)
end
Base.length(itr::EachReplaceMissing) = length(itr.x)
Base.size(itr::EachReplaceMissing) = size(itr.x)
Base.start(itr::EachReplaceMissing) = start(itr.x)
Expand All @@ -286,6 +297,7 @@ Base.eltype(itr::EachReplaceMissing) = Missings.T(eltype(itr.x))
(v isa Missing ? itr.replacement : v, s)
end

@static if !isdefined(Base, :skipmissing)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why @static here and not in other places? I'm not sure whether it's needed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not necessary at the top level (though I think you can use it to get around deprecations from the parser) but it doesn't hurt.

"""
skipmissing(itr)

Expand Down Expand Up @@ -315,10 +327,17 @@ skipmissing(itr) = EachSkipMissing(itr)
struct EachSkipMissing{T}
x::T
end
if VERSION < v"0.7.0-DEV.3309"
Base.iteratorsize(::Type{<:EachSkipMissing}) =
Base.SizeUnknown()
Base.iteratoreltype(::Type{EachSkipMissing{T}}) where {T} =
Base.iteratoreltype(T)
else
Base.IteratorSize(::Type{<:EachSkipMissing}) =
Base.SizeUnknown()
Base.IteratorEltype(::Type{EachSkipMissing{T}}) where {T} =
Base.IteratorEltype(T)
end
Base.eltype(itr::EachSkipMissing) = Missings.T(eltype(itr.x))
# Fallback implementation for general iterables: we cannot access a value twice,
# so after finding the next non-missing element in start() or next(), we have to
Expand Down Expand Up @@ -364,6 +383,8 @@ end
(v, _next_nonmissing_ind(itr.x, state))
end

end # isdefined

"""
Missings.fail(itr)

Expand Down Expand Up @@ -391,10 +412,17 @@ fail(itr) = EachFailMissing(itr)
struct EachFailMissing{T}
x::T
end
if VERSION < v"0.7.0-DEV.3309"
Base.iteratorsize(::Type{EachFailMissing{T}}) where {T} =
Base.iteratorsize(T)
Base.iteratoreltype(::Type{EachFailMissing{T}}) where {T} =
Base.iteratoreltype(T)
else
Base.IteratorSize(::Type{EachFailMissing{T}}) where {T} =
Base.IteratorSize(T)
Base.IteratorEltype(::Type{EachFailMissing{T}}) where {T} =
Base.IteratorEltype(T)
end
Base.length(itr::EachFailMissing) = length(itr.x)
Base.size(itr::EachFailMissing) = size(itr.x)
Base.start(itr::EachFailMissing) = start(itr.x)
Expand Down
16 changes: 13 additions & 3 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
using Base.Test, Missings, Compat
@static if VERSION < v"0.7.0-DEV.2005"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can just be using Compat, Compat.Test, Missings

using Base.Test
else
using Test
end
using Missings, Compat

@testset "Missings" begin
# test promote rules
Expand All @@ -17,7 +22,7 @@ using Base.Test, Missings, Compat
@test promote_type(Union{Int, Missing}, Union{Int, Missing}) == Union{Int, Missing}
@test promote_type(Union{Float64, Missing}, Union{String, Missing}) == Any
@test promote_type(Union{Float64, Missing}, Union{Int, Missing}) == Union{Float64, Missing}
@test promote_type(Union{Void, Missing, Int}, Float64) == Any
# @test_broken promote_type(Union{Nothing, Missing, Int}, Float64) == Any
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nalimilan, are we maybe missing a promote_rule in the Base definitions? I'm seeing

julia> promote_type(Union{Nothing, Missing, Int}, Float64)
Union{Missing, Float64}

on 0.7 (as of today).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But why comment this out? Isn't it still broken?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not broken on 0.6 though

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How did tests pass then? :-/

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's

@test promote_type(Union{Nothing, Missing, Int}, Float64) == Any

it passes on 0.6, fails on 0.7.

if it's

@test_broken promote_type(Union{Nothing, Missing, Int}, Float64) == Any

it passes 0.7, but fails 0.6 (because it's NOT broken on 0.6, "unexpected pass")

so to pass on 0.6 and 0.7, I just comment it out 😄

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. Why not make it conditional on the version then?


bit_operators = [&, |, ⊻]

Expand All @@ -32,7 +37,7 @@ using Base.Test, Missings, Compat
iseven, isodd, ispow2,
isfinite, isinf, isnan, iszero,
isinteger, isreal,
isempty, transpose, ctranspose, float]
isempty, transpose, float]
VERSION < v"0.7.0-DEV" && push!(elementary_functions, isimag)

rounding_functions = [ceil, floor, round, trunc]
Expand All @@ -46,6 +51,11 @@ using Base.Test, Missings, Compat
for f in elementary_functions
@test ismissing(f(missing))
end
if isdefined(Base, :adjoint)
@test ismissing(adjoint(missing))
else
@test ismissing(ctranspose(missing))
end

# All rounding functions return missing when evaluating missing as first argument
for f in rounding_functions
Expand Down