-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Add missing and Missing #24653
Add missing and Missing #24653
Changes from all commits
99fd46f
a4f57b6
31031cd
34e136b
c6a076d
8daa601
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
# This file is a part of Julia. License is MIT: https://julialang.org/license | ||
|
||
# Missing, missing and ismissing are defined in essentials.jl | ||
|
||
show(io::IO, x::Missing) = print(io, "missing") | ||
|
||
""" | ||
MissingException(msg) | ||
|
||
Exception thrown when a [`missing`](@ref) value is encountered in a situation | ||
where it is not supported. The error message, in the `msg` field | ||
may provide more specific details. | ||
""" | ||
struct MissingException <: Exception | ||
msg::AbstractString | ||
end | ||
|
||
showerror(io::IO, ex::MissingException) = | ||
print(io, "MissingException: ", ex.msg) | ||
|
||
promote_rule(::Type{Missing}, ::Type{T}) where {T} = Union{T, Missing} | ||
promote_rule(::Type{Union{S,Missing}}, ::Type{T}) where {T,S} = Union{promote_type(T, S), Missing} | ||
promote_rule(::Type{Any}, ::Type{T}) where {T} = Any | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does anyone have any qualms about this definition? Should it perhaps live in |
||
promote_rule(::Type{Any}, ::Type{Missing}) = Any | ||
promote_rule(::Type{Missing}, ::Type{Any}) = Any | ||
promote_rule(::Type{Missing}, ::Type{Missing}) = Missing | ||
|
||
convert(::Type{Union{T, Missing}}, x) where {T} = convert(T, x) | ||
# To print more appropriate message than "T not defined" | ||
convert(::Type{Missing}, x) = throw(MethodError(convert, (Missing, x))) | ||
convert(::Type{Missing}, ::Missing) = missing | ||
|
||
# Comparison operators | ||
==(::Missing, ::Missing) = missing | ||
==(::Missing, ::Any) = missing | ||
==(::Any, ::Missing) = missing | ||
# To fix ambiguity | ||
==(::Missing, ::WeakRef) = missing | ||
==(::WeakRef, ::Missing) = missing | ||
isequal(::Missing, ::Missing) = true | ||
isequal(::Missing, ::Any) = false | ||
isequal(::Any, ::Missing) = false | ||
<(::Missing, ::Missing) = missing | ||
<(::Missing, ::Any) = missing | ||
<(::Any, ::Missing) = missing | ||
isless(::Missing, ::Missing) = false | ||
isless(::Missing, ::Any) = false | ||
isless(::Any, ::Missing) = true | ||
|
||
# Unary operators/functions | ||
for f in (:(!), :(+), :(-), :(identity), :(zero), :(one), :(oneunit), | ||
:(abs), :(abs2), :(sign), | ||
:(acos), :(acosh), :(asin), :(asinh), :(atan), :(atanh), | ||
:(sin), :(sinh), :(cos), :(cosh), :(tan), :(tanh), | ||
:(exp), :(exp2), :(expm1), :(log), :(log10), :(log1p), | ||
:(log2), :(exponent), :(sqrt), :(gamma), :(lgamma), | ||
:(iseven), :(ispow2), :(isfinite), :(isinf), :(isodd), | ||
:(isinteger), :(isreal), :(isnan), :(isempty), | ||
:(iszero), :(transpose), :(float)) | ||
@eval Math.$(f)(::Missing) = missing | ||
end | ||
|
||
for f in (:(Base.zero), :(Base.one), :(Base.oneunit)) | ||
@eval function $(f)(::Type{Union{T, Missing}}) where T | ||
T === Any && throw(MethodError($f, (Any,))) # To prevent StackOverflowError | ||
$f(T) | ||
end | ||
end | ||
|
||
# Binary operators/functions | ||
for f in (:(+), :(-), :(*), :(/), :(^), | ||
:(div), :(mod), :(fld), :(rem), :(min), :(max)) | ||
@eval begin | ||
# Scalar with missing | ||
($f)(::Missing, ::Missing) = missing | ||
($f)(d::Missing, x::Number) = missing | ||
($f)(d::Number, x::Missing) = missing | ||
end | ||
end | ||
|
||
# Rounding and related functions | ||
for f in (:(ceil), :(floor), :(round), :(trunc)) | ||
@eval begin | ||
($f)(::Missing, digits::Integer=0, base::Integer=0) = missing | ||
($f)(::Type{>:Missing}, ::Missing) = missing | ||
($f)(::Type{T}, ::Missing) where {T} = | ||
throw(MissingException("cannot convert a missing value to type $T")) | ||
end | ||
end | ||
|
||
# to avoid ambiguity warnings | ||
(^)(::Missing, ::Integer) = missing | ||
|
||
# Bit operators | ||
(&)(::Missing, ::Missing) = missing | ||
(&)(a::Missing, b::Bool) = ifelse(b, missing, false) | ||
(&)(b::Bool, a::Missing) = ifelse(b, missing, false) | ||
(&)(::Missing, ::Integer) = missing | ||
(&)(::Integer, ::Missing) = missing | ||
(|)(::Missing, ::Missing) = missing | ||
(|)(a::Missing, b::Bool) = ifelse(b, true, missing) | ||
(|)(b::Bool, a::Missing) = ifelse(b, true, missing) | ||
(|)(::Missing, ::Integer) = missing | ||
(|)(::Integer, ::Missing) = missing | ||
xor(::Missing, ::Missing) = missing | ||
xor(a::Missing, b::Bool) = missing | ||
xor(b::Bool, a::Missing) = missing | ||
xor(::Missing, ::Integer) = missing | ||
xor(::Integer, ::Missing) = missing | ||
|
||
*(d::Missing, x::AbstractString) = missing | ||
*(d::AbstractString, x::Missing) = missing | ||
|
||
function float(A::AbstractArray{Union{T, Missing}}) where {T} | ||
U = typeof(float(zero(T))) | ||
convert(AbstractArray{Union{U, Missing}}, A) | ||
end | ||
float(A::AbstractArray{Missing}) = A |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -112,7 +112,7 @@ function reducedim_init(f, op::typeof(*), A::AbstractArray, region) | |
end | ||
function _reducedim_init(f, op, fv, fop, A, region) | ||
T = promote_union(eltype(A)) | ||
if applicable(zero, T) | ||
if T !== Any && applicable(zero, T) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one isn't totally satisfying, but I had to add it due to the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That would be good, although probably just the ones which throw a |
||
x = f(zero(T)) | ||
z = op(fv(x), fv(x)) | ||
Tr = typeof(z) == typeof(x) && !isbits(T) ? T : typeof(z) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could use
ifelse
here, similarly inreduce.jl
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That doesn't make any difference for simple cases like this: