diff --git a/src/Transducers.jl b/src/Transducers.jl index 535773d9a0..32c9aca712 100644 --- a/src/Transducers.jl +++ b/src/Transducers.jl @@ -81,6 +81,9 @@ function __init__() @require OnlineStatsBase="925886fa-5bf2-5e8e-b522-a9147a512338" begin include("interop/onlinestats.jl") end + @require DataFrames="a93c6f00-e57d-5684-b7b6-d8193f3e46c0" begin + include("interop/dataframes.jl") + end end end # module diff --git a/src/core.jl b/src/core.jl index 4d28d3bb7a..4e19198c36 100644 --- a/src/core.jl +++ b/src/core.jl @@ -657,6 +657,7 @@ identityof(::typeof(right), ::Any) = nothing abstract type Reducible end abstract type Foldable <: Reducible end +asfoldable(x) = x abstract type AbstractInitializer end diff --git a/src/interop/dataframes.jl b/src/interop/dataframes.jl new file mode 100644 index 0000000000..3348a49179 --- /dev/null +++ b/src/interop/dataframes.jl @@ -0,0 +1,3 @@ +asfoldable(df::DataFrames.AbstractDataFrame) = DataFrames.eachrow(df) +# We can't use `Compat.eachrow` here. See: +# https://github.com/JuliaData/DataFrames.jl/pull/2067 diff --git a/src/processes.jl b/src/processes.jl index 8b554a0984..e9bacee43c 100644 --- a/src/processes.jl +++ b/src/processes.jl @@ -345,7 +345,8 @@ _unreduced__foldl__(rf, step, coll) = unreduced(__foldl__(rf, step, coll)) # `darkritual` below to work. rf = maybe_usesimd(rf0, simd) state = _start_init(rf, init) - result = __foldl__(rf, state, coll) + foldable = asfoldable(coll) + result = __foldl__(rf, state, foldable) if unreduced(result) isa DefaultInit throw(EmptyResultError(rf0)) # Should I check if `init` is a `MissingInit`? @@ -366,7 +367,7 @@ _unreduced__foldl__(rf, step, coll) = unreduced(__foldl__(rf, step, coll)) # not change the return type. realtype = _nonidtype(Core.Compiler.return_type( _unreduced__foldl__, - typeof((rf0, state, coll)), + typeof((rf0, state, foldable)), )) if realtype isa Type realvalue = convert(realtype, ur_result) @@ -633,7 +634,13 @@ julia> @assert copy(Map(x -> (a=x, b=x^2)), Table, 1:1) == Table(a=[1], b=[1]) julia> using StructArrays julia> @assert copy(Map(x -> (a=x, b=x^2)), StructVector, 1:1) == StructVector(a=[1], b=[1]) -``` + +julia> using DataFrames + +julia> @assert copy( + Map(x -> (A = x.a + 1, B = x.b + 1)), + DataFrame(a = [1], b = [2]), + ) == DataFrame(A = [2], B = [3]) """ Base.copy(xf::Transducer, ::Type{T}, foldable) where {T} = append!!(xf, Empty(T), foldable) Base.copy(xf::Transducer, foldable) = copy(xf, _materializer(foldable), foldable) diff --git a/test/test_copy.jl b/test/test_copy.jl index aaf03bbb31..6da1ff26f0 100644 --- a/test/test_copy.jl +++ b/test/test_copy.jl @@ -1,7 +1,7 @@ module TestCopy include("preamble.jl") -using DataFrames: DataFrame +using DataFrames: DataFrame, eachrow using StructArrays: StructVector using TypedTables: Table @@ -14,10 +14,15 @@ end @testset "$copy" for copy in [copy, tcopy, dcopy] @testset "$copy(_, ::$(prettytypeof(src)))" for src in Any[ - # DataFrame(a=[1], b=[2]), + DataFrame(a=[1], b=[2]), StructVector(a=[1:4;], b=[5:8;]), Table(a=[1:4;], b=[5:8;]), ] + if copy in (tcopy, dcopy) && src isa DataFrame + @test_broken copy(Map(identity), src) ==ₜ src + @test_broken copy(Map(identity), src; basesize=1) ==ₜ src + continue + end @test copy(Map(identity), src) ==ₜ src if copy in (tcopy, dcopy) @test copy(Map(identity), src; basesize=1) ==ₜ src