Repository: JuliaData/Tables.jl
Pull request #310 (2022-10-11 17:54:13)

Update DictRows and DictColumns definition
Fixes https://github.com/JuliaData/Tables.jl/issues/309

codecov[bot]: # [Codecov](https://codecov.io/gh/JuliaData/Tables.jl/pull/310?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=JuliaData) Report
Base: **94.30**% // Head: **94.30**% // No change to project coverage :thumbsup:
> Coverage data is based on head [(`30d0530`)](https://codecov.io/gh/JuliaData/Tables.jl/pull/310?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=JuliaData) compared to base [(`e48ec0d`)](https://codecov.io/gh/JuliaData/Tables.jl/commit/e48ec0d17ddf8397bd25e95bfbbcdd54c5adeba0?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=JuliaData).
> Patch coverage: 75.00% of modified lines in pull request are covered.

> :exclamation: Current head 30d0530 differs from pull request most recent head 9de6e1a. Consider uploading reports for the commit 9de6e1a to get more accurate results

<details><summary>Additional details and impacted files</summary>


```diff
@@           Coverage Diff           @@
##             main     #310   +/-   ##
=======================================
  Coverage   94.30%   94.30%           
=======================================
  Files           7        7           
  Lines         720      720           
=======================================
  Hits          679      679           
  Misses         41       41           
```


| [Impacted Files](https://codecov.io/gh/JuliaData/Tables.jl/pull/310?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=JuliaData) | Coverage Δ | |
|---|---|---|
| [src/Tables.jl](https://codecov.io/gh/JuliaData/Tables.jl/pull/310/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=JuliaData#diff-c3JjL1RhYmxlcy5qbA==) | `87.35% <75.00%> (ø)` | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=JuliaData). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=JuliaData)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/JuliaData/Tables.jl/pull/310?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=JuliaData).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=JuliaData).

bkamins: I have left notes in places that change previous behavior.

Patch:
diff --git a/Project.toml b/Project.toml
index 311d5e8..0b02045 100644
--- a/Project.toml
+++ b/Project.toml
@@ -1,7 +1,7 @@
 name = "Tables"
 uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
 authors = ["quinnj <quinn.jacobd@gmail.com>"]
-version = "1.9.0"
+version = "1.10.0"
 
 [deps]
 DataAPI = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
diff --git a/src/Tables.jl b/src/Tables.jl
index b9bdc06..143c4a2 100644
--- a/src/Tables.jl
+++ b/src/Tables.jl
@@ -144,13 +144,13 @@ getcolumn(x::AbstractDict{Symbol}, nm::Symbol) = x[nm]
 getcolumn(x::AbstractDict{Symbol}, ::Type{T}, i::Int, nm::Symbol) where {T} = x[nm]
 columnnames(x::AbstractDict{Symbol}) = collect(keys(x))
 
-getcolumn(x::AbstractDict{String}, i::Int) = x[String(columnnames(x)[i])]
-getcolumn(x::AbstractDict{String}, nm::Symbol) = x[String(nm)]
-getcolumn(x::AbstractDict{String}, ::Type{T}, i::Int, nm::Symbol) where {T} = x[String(nm)]
-columnnames(x::AbstractDict{String}) = collect(Symbol(k) for k in keys(x))
+getcolumn(x::AbstractDict{<:AbstractString}, i::Int) = x[String(columnnames(x)[i])]
+getcolumn(x::AbstractDict{<:AbstractString}, nm::Symbol) = x[String(nm)]
+getcolumn(x::AbstractDict{<:AbstractString}, ::Type{T}, i::Int, nm::Symbol) where {T} = x[String(nm)]
+columnnames(x::AbstractDict{<:AbstractString}) = collect(Symbol(k) for k in keys(x))
 
 # AbstractVector of Dicts for Tables.rows
-const DictRows = AbstractVector{T} where {T <: Union{AbstractDict{String}, AbstractDict{Symbol}}}
+const DictRows = AbstractVector{T} where {T <: Union{AbstractDict{<:AbstractString}, AbstractDict{Symbol}}}
 isrowtable(::Type{<:DictRows}) = true
 # DictRows doesn't naturally lend itself to the `Tables.schema` requirement
 # we can't just look at the first row, because the types might change,
@@ -159,7 +159,7 @@ isrowtable(::Type{<:DictRows}) = true
 schema(x::DictRows) = nothing
 
 # Dict of AbstractVectors for Tables.columns
-const DictColumns = AbstractDict{K, V} where {K <: Union{Symbol, String}, V <: AbstractVector}
+const DictColumns = Union{<:AbstractDict{<:AbstractString, <:AbstractVector}, <:AbstractDict{Symbol, <:AbstractVector}}
 istable(::Type{<:DictColumns}) = true
 columnaccess(::Type{<:DictColumns}) = true
 columns(x::DictColumns) = x


Test patch:
diff --git a/test/runtests.jl b/test/runtests.jl
index 25206bb..fbbbc92 100644
--- a/test/runtests.jl
+++ b/test/runtests.jl
@@ -900,3 +900,34 @@ end
     @test_throws MethodError Tables.ByRow(identity)(1)
     @test_throws MethodError Tables.ByRow(identity)([1 2])
 end
+
+@testset "istable on dictionaries" begin
+    @test Tables.istable(Dict{Union{String}, Vector})
+    @test Tables.istable(Dict{Union{Symbol}, Vector})
+    @test Tables.istable(Dict{Union{SubString}, Vector})
+    @test Tables.istable(Dict{Union{AbstractString}, Vector})
+    @test !Tables.istable(Dict{Union{String, Symbol}, Vector})
+    @test Tables.istable(Vector{Dict{Symbol}})
+    @test Tables.istable(Vector{Dict{String}})
+    @test Tables.istable(Vector{Dict{SubString}})
+    @test Tables.istable(Vector{Dict{AbstractString}})
+                                                                                                                                                
+    @test Set(Tables.columnnames(Dict(:a=>1, :b=>2))) == Set([:a, :b])
+    @test Set(Tables.columnnames(Dict("a"=>1, "b"=>2))) == Set([:a, :b])
+    @test Set(Tables.columnnames(Dict("a"=>1, SubString("b")=>2))) == Set([:a, :b])
+    @test Set(Tables.columnnames(Dict(SubString("a")=>1, SubString("b")=>2))) == Set([:a, :b])
+
+    @test Tables.getcolumn(Dict(:a=>1, :b=>2), 1) == 1
+    @test Tables.getcolumn(Dict("a"=>1, "b"=>2), 1 + (Int === Int64)) == 1
+    @test Tables.getcolumn(Dict("a"=>1, SubString("b")=>2), 1 + (Int === Int64)) == 1
+    @test Tables.getcolumn(Dict(SubString("a")=>1, SubString("b")=>2), 1 + (Int === Int64)) == 1
+    @test Tables.getcolumn(Dict(:a=>1, :b=>2), :a) == 1
+    @test Tables.getcolumn(Dict("a"=>1, "b"=>2), :a) == 1
+    @test Tables.getcolumn(Dict("a"=>1, SubString("b")=>2), :a) == 1
+    @test Tables.getcolumn(Dict(SubString("a")=>1, SubString("b")=>2), :a) == 1
+    @test Tables.getcolumn(Dict(:a=>1, :b=>2), Int, 1, :a) == 1
+    @test Tables.getcolumn(Dict("a"=>1, "b"=>2), Int, 1, :a) == 1
+    @test Tables.getcolumn(Dict("a"=>1, SubString("b")=>2), Int, 1, :a) == 1
+    @test Tables.getcolumn(Dict(SubString("a")=>1, SubString("b")=>2), Int, 1, :a) == 1
+end
+