Skip to content

Commit afc9e73

Browse files
authored
Merge pull request #6 from davidanthoff/julia-0.7
julia 0.7
2 parents 0ee48cb + 8b0ab10 commit afc9e73

File tree

8 files changed

+67
-90
lines changed

8 files changed

+67
-90
lines changed

.travis.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ os:
44
- linux
55
- osx
66
julia:
7-
- 0.6
7+
- 0.7
8+
- nightly
89
notifications:
910
email: false
1011
git:

LICENSE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The TableTraitsUtils.jl package is licensed under the MIT "Expat" License:
22

3-
> Copyright (c) 2017: David Anthoff.
3+
> Copyright (c) 2017-2018: David Anthoff.
44
>
55
>
66
> Permission is hereby granted, free of charge, to any person obtaining a copy

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# TableTraitsUtils.jl v0.2.0 Release Notes
2+
* Drop julia 0.6 support, add julia 0.7 support
3+
14
# TableTraitsUtils.jl v0.1.3 Release Notes
25
* Add missing eltype method
36

REQUIRE

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
julia 0.6
2-
NamedTuples 4.0.0
3-
DataValues 0.0.1
4-
TableTraits 0.0.1
1+
julia 0.7-
2+
DataValues 0.4.1
3+
TableTraits 0.3.0
4+
IteratorInterfaceExtensions 0.1.0
5+
Missings 0.2.10

appveyor.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
environment:
22
matrix:
3-
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe"
4-
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe"
3+
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.7/julia-0.7-latest-win32.exe"
4+
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.7/julia-0.7-latest-win64.exe"
5+
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
6+
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
57

68
## uncomment the following lines to allow failures on nightly julia
79
## (tests will run but not make your overall status red)

src/TableTraitsUtils.jl

Lines changed: 39 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
__precompile__()
22
module TableTraitsUtils
33

4-
using TableTraits, NamedTuples, DataValues
4+
using IteratorInterfaceExtensions, TableTraits, DataValues, Missings
55

66
export create_tableiterator, create_columns_from_iterabletable
77

@@ -12,71 +12,45 @@ struct TableIterator{T, TS}
1212
end
1313

1414
function create_tableiterator(columns, names::Vector{Symbol})
15-
col_expressions = Array{Expr,1}()
16-
df_columns_tuple_type = Expr(:curly, :Tuple)
17-
for i in 1:length(columns)
18-
etype = eltype(columns[i])
19-
if etype <: Nullable
20-
push!(col_expressions, Expr(:(::), names[i], DataValue{etype.parameters[1]}))
15+
field_types = Type[]
16+
for i in eltype.(columns)
17+
if i >: Missing
18+
push!(field_types, DataValue{Missings.T(i)})
2119
else
22-
push!(col_expressions, Expr(:(::), names[i], etype))
20+
push!(field_types, i)
2321
end
24-
push!(df_columns_tuple_type.args, typeof(columns[i]))
2522
end
26-
t_expr = NamedTuples.make_tuple(col_expressions)
27-
28-
t2 = :(TableIterator{Float64,Float64})
29-
t2.args[2] = t_expr
30-
t2.args[3] = df_columns_tuple_type
31-
32-
t = eval(t2)
33-
34-
e_df = t((columns...))
35-
36-
return e_df
23+
return TableIterator{NamedTuple{(names...,), Tuple{field_types...}}, Tuple{typeof.(columns)...}}((columns...,))
3724
end
3825

3926
function Base.length(iter::TableIterator{T,TS}) where {T,TS}
4027
return length(iter.columns[1])
4128
end
4229

43-
function Base.eltype(iter::TableIterator{T,TS}) where {T,TS}
44-
return T
45-
end
46-
4730
Base.eltype(::Type{TableIterator{T,TS}}) where {T,TS} = T
4831

49-
function Base.start(iter::TableIterator{T,TS}) where {T,TS}
50-
return 1
51-
end
52-
53-
@generated function Base.next(iter::TableIterator{T,TS}, state) where {T,TS}
54-
constructor_call = Expr(:call, :($T))
55-
for (i,t) in enumerate(T.parameters)
56-
if eltype(iter.parameters[2].parameters[i]) <: Nullable
57-
push!(constructor_call.args, :(DataValue(columns[$i][i])))
32+
@generated function Base.iterate(iter::TableIterator{T,TS}, state=1) where {T,TS}
33+
columns = map(1:length(TS.parameters)) do i
34+
if fieldtype(T,i) <: DataValue && eltype(TS.parameters[i]) >: Missing
35+
return :($(fieldtype(T,i))(iter.columns[$i][state]))
5836
else
59-
push!(constructor_call.args, :(columns[$i][i]))
37+
return :(iter.columns[$i][state])
6038
end
6139
end
62-
63-
quote
64-
i = state
65-
columns = iter.columns
66-
a = $constructor_call
67-
return a, state+1
40+
return quote
41+
if state > length(iter)
42+
return nothing
43+
else
44+
return $(T)(($(columns...),)), state+1
45+
end
6846
end
6947
end
7048

71-
function Base.done(iter::TableIterator{T,TS}, state) where {T,TS}
72-
return state>length(iter.columns[1])
73-
end
74-
7549
# Sink
7650

7751
@generated function _fill_cols_without_length(columns, enumerable)
7852
push_exprs = Expr(:block)
79-
for i in find(collect(columns.types) .!= Void)
53+
for i in findall(collect(columns.types) .!= Nothing)
8054
ex = :( push!(columns[$i], i[$i]) )
8155
push!(push_exprs.args, ex)
8256
end
@@ -90,7 +64,7 @@ end
9064

9165
@generated function _fill_cols_with_length(columns, enumerable)
9266
push_exprs = Expr(:block)
93-
for col_idx in find(collect(columns.types) .!= Void)
67+
for col_idx in findall(collect(columns.types) .!= Nothing)
9468
ex = :( columns[$col_idx][i] = v[$col_idx] )
9569
push!(push_exprs.args, ex)
9670
end
@@ -102,26 +76,30 @@ end
10276
end
10377
end
10478

105-
function _default_array_factory(t,rows)
106-
if isa(t, TypeVar)
107-
return Array{Any}(rows)
108-
else
109-
return Array{t}(rows)
110-
end
111-
end
112-
113-
function create_columns_from_iterabletable(source, sel_cols = :all; array_factory::Function=_default_array_factory)
79+
function create_columns_from_iterabletable(source; sel_cols=:all, na_representation=:datavalue)
11480
iter = getiterator(source)
11581

11682
T = eltype(iter)
11783
if !(T<:NamedTuple)
11884
error("Can only collect a NamedTuple iterator.")
11985
end
12086

121-
column_types = TableTraits.column_types(iter)
122-
column_names = TableTraits.column_names(iter)
87+
array_factory = if na_representation==:datavalue
88+
(t,rows) -> Array{t}(undef, rows)
89+
elseif na_representation==:missing
90+
(t,rows) -> begin
91+
if t <: DataValue
92+
return Array{Union{eltype(t),Missing}}(undef, rows)
93+
else
94+
return Array{t}(undef, rows)
95+
end
96+
end
97+
end
98+
99+
column_types = collect(T.parameters[2].parameters)
100+
column_names = collect(T.parameters[1])
123101

124-
rows = Base.iteratorsize(typeof(iter))==Base.HasLength() ? length(iter) : 0
102+
rows = Base.IteratorSize(typeof(iter))==Base.HasLength() ? length(iter) : 0
125103

126104
columns = []
127105
for (i, t) in enumerate(column_types)
@@ -132,10 +110,10 @@ function create_columns_from_iterabletable(source, sel_cols = :all; array_factor
132110
end
133111
end
134112

135-
if Base.iteratorsize(typeof(iter))==Base.HasLength()
136-
_fill_cols_with_length((columns...), iter)
113+
if Base.IteratorSize(typeof(iter))==Base.HasLength()
114+
_fill_cols_with_length((columns...,), iter)
137115
else
138-
_fill_cols_without_length((columns...), iter)
116+
_fill_cols_without_length((columns...,), iter)
139117
end
140118

141119
if sel_cols == :all

test/runtests.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using TableTraitsUtils
22
using DataValues
3-
using Base.Test
3+
using Test
44

55
include("test_source_without_length.jl")
66

@@ -13,9 +13,9 @@ it = TableTraitsUtils.create_tableiterator(columns, names)
1313

1414
columns2, names2 = TableTraitsUtils.create_columns_from_iterabletable(it)
1515

16-
columns3, names3 = TableTraitsUtils.create_columns_from_iterabletable(it, :all)
16+
columns3, names3 = TableTraitsUtils.create_columns_from_iterabletable(it, sel_cols=:all)
1717

18-
columns23, names23 = TableTraitsUtils.create_columns_from_iterabletable(it, [2,3])
18+
columns23, names23 = TableTraitsUtils.create_columns_from_iterabletable(it, sel_cols=[2,3])
1919

2020
@test columns[1] == columns2[1] == columns3[1]
2121
@test columns[2] == columns2[2] == columns3[2]
@@ -35,16 +35,16 @@ columns4, names4 = TableTraitsUtils.create_columns_from_iterabletable(it2)
3535
@test columns4[2] == [1.,2.]
3636
@test names4 == [:a, :b]
3737

38-
columns5, names5 = TableTraitsUtils.create_columns_from_iterabletable(it2, :all)
38+
columns5, names5 = TableTraitsUtils.create_columns_from_iterabletable(it2, sel_cols=:all)
3939
@test columns5[1] == [1,2]
4040
@test columns5[2] == [1.,2.]
4141
@test names5 == [:a, :b]
4242

43-
columns6, names6 = TableTraitsUtils.create_columns_from_iterabletable(it2, [2])
43+
columns6, names6 = TableTraitsUtils.create_columns_from_iterabletable(it2, sel_cols=[2])
4444
@test columns6[1] == [1.,2.]
4545
@test names6 == [:b]
4646

47-
columns_with_nulls = (Nullable{Int}[Nullable(3), Nullable(2), Nullable{Int}()], [2.,5.,9.], Nullable{String}[Nullable("a"), Nullable{String}(), Nullable("b")])
47+
columns_with_nulls = (Union{Int,Missing}[3, 2, missing], Float64[2.,5.,9.], Union{String,Missing}["a", missing, "b"])
4848
it3 = TableTraitsUtils.create_tableiterator(columns_with_nulls, names)
4949

5050
columns7, names7 = TableTraitsUtils.create_columns_from_iterabletable(it3)

test/test_source_without_length.jl

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,18 @@
1-
using NamedTuples
2-
31
struct TestSourceWithoutLength
42
end
53

64
function Base.eltype(iter::TestSourceWithoutLength)
7-
return @NT(a::Int, b::Float64)
5+
return NamedTuple{(:a, :b), Tuple{Int, Float64}}
86
end
97

10-
Base.iteratorsize(::Type{T}) where {T <: TestSourceWithoutLength} = Base.SizeUnknown()
11-
12-
function Base.start(iter::TestSourceWithoutLength)
13-
return 1
14-
end
8+
Base.IteratorSize(::Type{T}) where {T <: TestSourceWithoutLength} = Base.SizeUnknown()
159

16-
function Base.next(iter::TestSourceWithoutLength, state)
10+
function Base.iterate(iter::TestSourceWithoutLength, state=1)
1711
if state==1
18-
return @NT(a=1, b=1.), 2
12+
return (a=1, b=1.), 2
1913
elseif state==2
20-
return @NT(a=2, b=2.), 3
14+
return (a=2, b=2.), 3
15+
else
16+
return nothing
2117
end
2218
end
23-
24-
function Base.done(iter::TestSourceWithoutLength, state)
25-
return state>2
26-
end

0 commit comments

Comments
 (0)