Skip to content

Commit

Permalink
Make many dependencies optional using Requires.jl
Browse files Browse the repository at this point in the history
  • Loading branch information
nalimilan committed Sep 17, 2021
1 parent 1fe8ba9 commit 7904fc9
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 63 deletions.
13 changes: 8 additions & 5 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@ version = "0.10.0"
[deps]
DataAPI = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
Future = "9fa8497b-333b-5362-9e8d-4d0656e87820"
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
Missings = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
SentinelArrays = "91c51154-3ec4-41a3-a24f-3f23e20d615c"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
StructTypes = "856f2bd8-1eba-4b0a-8007-ebc267875bd4"
Unicode = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"

[compat]
Expand All @@ -20,16 +17,22 @@ JSON = "0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.21"
JSON3 = "1.1.2"
Missings = "0.4.3, 1"
RecipesBase = "1.1"
Requires = "1"
SentinelArrays = "1"
StructTypes = "1"
julia = "1"

[extras]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
PooledArrays = "2dfb63ee-cc39-5dd5-95bd-886bf059d720"
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
SentinelArrays = "91c51154-3ec4-41a3-a24f-3f23e20d615c"
StructTypes = "856f2bd8-1eba-4b0a-8007-ebc267875bd4"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Dates", "JSON3", "Plots", "PooledArrays", "Test"]
test = ["Dates", "JSON", "JSON3", "Plots", "PooledArrays",
"RecipesBase", "SentinelArrays", "StructTypes", "Test"]
68 changes: 64 additions & 4 deletions src/CategoricalArrays.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,10 @@ module CategoricalArrays
import DataAPI: unwrap
export unwrap

using JSON
using DataAPI
using Missings
using Printf
import RecipesBase
import SentinelArrays
import StructTypes
using Requires: @require

# JuliaLang/julia#36810
if VERSION < v"1.5.2"
Expand All @@ -37,4 +34,67 @@ module CategoricalArrays
include("recode.jl")

include("deprecated.jl")

function __init__()
@require JSON="682c06a0-de6a-54ab-a142-c8b1cf79cde6" begin
# JSON of CategoricalValue is JSON of the value it refers to
JSON.lower(x::CategoricalValue) = JSON.lower(unwrap(x))
end

@require RecipesBase="3cdcf5f2-1ef4-517c-9805-6587b60abb01" @eval begin
RecipesBase.@recipe function f(::Type{T}, v::T) where T <: CategoricalValue
level_strings = [map(string, levels(v)); missing]
ticks --> eachindex(level_strings)
v -> ismissing(v) ? length(level_strings) : Int(refcode(v)),
i -> level_strings[Int(i)]
end
end

@require SentinelArrays="91c51154-3ec4-41a3-a24f-3f23e20d615c" begin
copyto!(dest::CatArrOrSub{<:Any, 1}, src::SentinelArrays.ChainedVector) =
copyto!(dest, 1, src, 1, length(src))
copyto!(dest::CatArrOrSub{<:Any, 1}, dstart::Union{Signed, Unsigned},
src::SentinelArrays.ChainedVector, sstart::Union{Signed, Unsigned},
n::Union{Signed, Unsigned}) =
invoke(copyto!, Tuple{AbstractArray, Union{Signed, Unsigned},
SentinelArrays.ChainedVector,
Union{Signed, Unsigned}, Union{Signed, Unsigned}},
dest, dstart, src, sstart, n)
end

@require StructTypes="856f2bd8-1eba-4b0a-8007-ebc267875bd4" begin
# define appropriate handlers for JSON3 interface
StructTypes.StructType(x::CategoricalValue) = StructTypes.StructType(unwrap(x))
StructTypes.StructType(::Type{<:CategoricalValue{T}}) where {T} = StructTypes.StructType(T)
StructTypes.numbertype(::Type{<:CategoricalValue{T}}) where {T <: Number} = T
StructTypes.construct(::Type{T}, x::CategoricalValue{T}) where {T} = T(unwrap(x))

# JSON3 writing/reading
StructTypes.StructType(::Type{<:CategoricalVector}) = StructTypes.ArrayType()

StructTypes.construct(::Type{<:CategoricalArray}, A::AbstractVector) =
constructgeneral(A)
StructTypes.construct(::Type{<:CategoricalArray}, A::Vector) =
constructgeneral(A)

function constructgeneral(A)
if eltype(A) === Any
# unlike `replace`, broadcast narrows the type, which allows us to return small
# union eltypes (e.g. Union{String,Missing})
categorical(ifelse.(A .=== nothing, missing, A))
elseif eltype(A) >: Nothing
categorical(replace(A, nothing=>missing))
else
categorical(A)
end
end

StructTypes.construct(::Type{<:CategoricalArray{Union{Missing, T}}},
A::AbstractVector) where {T} =
CategoricalArray{Union{Missing, T}}(replace(A, nothing=>missing))
StructTypes.construct(::Type{<:CategoricalArray{Union{Missing, T}}},
A::Vector) where {T} =
CategoricalArray{Union{Missing, T}}(replace(A, nothing=>missing))
end
end
end
37 changes: 0 additions & 37 deletions src/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -630,16 +630,6 @@ copy!(dest::CatArrOrSub{<:Any, 1}, src::AbstractArray{<:Any, 1}) =
copy!(dest::CatArrOrSub{T, 1}, src::AbstractArray{T, 1}) where {T} =
copyto!(dest, 1, src, 1, length(src))

copyto!(dest::CatArrOrSub{<:Any, 1}, src::SentinelArrays.ChainedVector) =
copyto!(dest, 1, src, 1, length(src))
copyto!(dest::CatArrOrSub{<:Any, 1}, dstart::Union{Signed, Unsigned},
src::SentinelArrays.ChainedVector, sstart::Union{Signed, Unsigned},
n::Union{Signed, Unsigned}) =
invoke(copyto!, Tuple{AbstractArray, Union{Signed, Unsigned},
SentinelArrays.ChainedVector,
Union{Signed, Unsigned}, Union{Signed, Unsigned}},
dest, dstart, src, sstart, n)

similar(A::CategoricalArray{S, M, R}, ::Type{T},
dims::NTuple{N, Int}) where {T, N, S, M, R} =
Array{T, N}(undef, dims)
Expand Down Expand Up @@ -1109,33 +1099,6 @@ Base.repeat(a::CatArrOrSub{T, N};
inner = nothing, outer = nothing) where {T, N} =
CategoricalArray{T, N}(repeat(refs(a), inner=inner, outer=outer), copy(pool(a)))

# JSON3 writing/reading
StructTypes.StructType(::Type{<:CategoricalVector}) = StructTypes.ArrayType()

StructTypes.construct(::Type{<:CategoricalArray}, A::AbstractVector) =
constructgeneral(A)
StructTypes.construct(::Type{<:CategoricalArray}, A::Vector) =
constructgeneral(A)

function constructgeneral(A)
if eltype(A) === Any
# unlike `replace`, broadcast narrows the type, which allows us to return small
# union eltypes (e.g. Union{String,Missing})
categorical(ifelse.(A .=== nothing, missing, A))
elseif eltype(A) >: Nothing
categorical(replace(A, nothing=>missing))
else
categorical(A)
end
end

StructTypes.construct(::Type{<:CategoricalArray{Union{Missing, T}}},
A::AbstractVector) where {T} =
CategoricalArray{Union{Missing, T}}(replace(A, nothing=>missing))
StructTypes.construct(::Type{<:CategoricalArray{Union{Missing, T}}},
A::Vector) where {T} =
CategoricalArray{Union{Missing, T}}(replace(A, nothing=>missing))

# DataAPI refarray/refvalue/refpool support
struct CategoricalRefPool{T, P} <: AbstractVector{T}
pool::P
Expand Down
19 changes: 2 additions & 17 deletions src/value.jl
Original file line number Diff line number Diff line change
Expand Up @@ -179,22 +179,7 @@ Base.:<(x::CategoricalValue, y::SupportedTypes) =
"or `CategoricalValue(v, catarray)` first"))
Base.:<(y::SupportedTypes, x::CategoricalValue) = x < y

# JSON of CategoricalValue is JSON of the value it refers to
JSON.lower(x::CategoricalValue) = JSON.lower(unwrap(x))
DataAPI.defaultarray(::Type{CategoricalValue{T, R}}, N) where {T, R} =
CategoricalArray{T, N, R}
CategoricalArray{T, N, R}
DataAPI.defaultarray(::Type{Union{CategoricalValue{T, R}, Missing}}, N) where {T, R} =
CategoricalArray{Union{T, Missing}, N, R}

# define appropriate handlers for JSON3 interface
StructTypes.StructType(x::CategoricalValue) = StructTypes.StructType(unwrap(x))
StructTypes.StructType(::Type{<:CategoricalValue{T}}) where {T} = StructTypes.StructType(T)
StructTypes.numbertype(::Type{<:CategoricalValue{T}}) where {T <: Number} = T
StructTypes.construct(::Type{T}, x::CategoricalValue{T}) where {T} = T(unwrap(x))

RecipesBase.@recipe function f(::Type{T}, v::T) where T <: CategoricalValue
level_strings = [map(string, levels(v)); missing]
ticks --> eachindex(level_strings)
v -> ismissing(v) ? length(level_strings) : Int(refcode(v)),
i -> level_strings[Int(i)]
end
CategoricalArray{Union{T, Missing}, N, R}

0 comments on commit 7904fc9

Please # to comment.