Skip to content

Commit

Permalink
Make Date/Time Printing Consistent (JuliaLang#34387)
Browse files Browse the repository at this point in the history
- Use 3 arg compact show for array elements.
- Add show/print methods for periods
- Periods imply their typeinfo, so set typeinfo_implicit to true for all period types

fixes JuliaLang#30901
  • Loading branch information
fchorney authored and JeffBezanson committed Jan 28, 2020
1 parent fba188c commit 5f176e0
Show file tree
Hide file tree
Showing 12 changed files with 68 additions and 58 deletions.
4 changes: 2 additions & 2 deletions base/abstractdict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ Dict{Char,Int64} with 2 entries:
julia> collect(keys(D))
2-element Array{Char,1}:
'a'
'b'
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
```
"""
keys(a::AbstractDict) = KeySet(a)
Expand Down
14 changes: 12 additions & 2 deletions base/arrayshow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,14 @@ function print_matrix_row(io::IO,
if isassigned(X,Int(i),Int(j)) # isassigned accepts only `Int` indices
x = X[i,j]
a = alignment(io, x)
sx = sprint(show, x, context=io, sizehint=0)

# First try 3-arg show
sx = sprint(show, "text/plain", x, context=io, sizehint=0)

# If the output contains line breaks, try 2-arg show instead.
if occursin('\n', sx)
sx = sprint(show, x, context=io, sizehint=0)
end
else
a = undef_ref_alignment
sx = undef_ref_str
Expand Down Expand Up @@ -317,6 +324,7 @@ function show(io::IO, ::MIME"text/plain", X::AbstractArray)
summary(io, X)
isempty(X) && return
print(io, ":")
show_circular(io, X) && return

# 1) compute new IOContext
if !haskey(io, :compact) && length(axes(X, 2)) > 1
Expand All @@ -343,7 +351,8 @@ function show(io::IO, ::MIME"text/plain", X::AbstractArray)
io = IOContext(io, :typeinfo => eltype(X))

# 2) show actual content
print_array(io, X)
recur_io = IOContext(io, :SHOWN_SET => X)
print_array(recur_io, X)
end

## printing with `show`
Expand Down Expand Up @@ -448,6 +457,7 @@ function show_vector(io::IO, v, opn='[', cls=']')
# directly or indirectly, the context now knows about eltype(v)
io = IOContext(io, :typeinfo => eltype(v))
limited = get(io, :limit, false)

if limited && length(v) > 20
axs1 = axes1(v)
f, l = first(axs1), last(axs1)
Expand Down
16 changes: 8 additions & 8 deletions base/combinatorics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -213,17 +213,17 @@ julia> A = ['a','b','c','d'];
julia> B = A[v]
4-element Array{Char,1}:
'b'
'd'
'c'
'a'
'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
julia> B[invperm(v)]
4-element Array{Char,1}:
'a'
'b'
'c'
'd'
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)
```
"""
function invperm(a::AbstractVector)
Expand Down
14 changes: 7 additions & 7 deletions base/iterators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -534,8 +534,8 @@ julia> a
julia> collect(rest)
2-element Array{Char,1}:
'b'
'c'
'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
```
"""
function peel(itr)
Expand Down Expand Up @@ -1179,14 +1179,14 @@ julia> popfirst!(a)
julia> collect(Iterators.take(a, 3))
3-element Array{Char,1}:
'b'
'c'
'd'
'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)
julia> collect(a)
2-element Array{Char,1}:
'e'
'f'
'e': ASCII/Unicode U+0065 (category Ll: Letter, lowercase)
'f': ASCII/Unicode U+0066 (category Ll: Letter, lowercase)
```
```jldoctest
Expand Down
6 changes: 3 additions & 3 deletions base/operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -844,9 +844,9 @@ and splatting `∘(fs...)` for composing an iterable collection of functions.
```jldoctest
julia> map(uppercase∘first, ["apple", "banana", "carrot"])
3-element Array{Char,1}:
'A'
'B'
'C'
'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)
'B': ASCII/Unicode U+0042 (category Lu: Letter, uppercase)
'C': ASCII/Unicode U+0043 (category Lu: Letter, uppercase)
julia> fs = [
x -> 2x
Expand Down
12 changes: 6 additions & 6 deletions doc/src/manual/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -737,12 +737,12 @@ The next example composes three functions and maps the result over an array of s
```jldoctest
julia> map(first ∘ reverse ∘ uppercase, split("you can compose functions like this"))
6-element Array{Char,1}:
'U'
'N'
'E'
'S'
'E'
'S'
'U': ASCII/Unicode U+0055 (category Lu: Letter, uppercase)
'N': ASCII/Unicode U+004E (category Lu: Letter, uppercase)
'E': ASCII/Unicode U+0045 (category Lu: Letter, uppercase)
'S': ASCII/Unicode U+0053 (category Lu: Letter, uppercase)
'E': ASCII/Unicode U+0045 (category Lu: Letter, uppercase)
'S': ASCII/Unicode U+0053 (category Lu: Letter, uppercase)
```

Function chaining (sometimes called "piping" or "using a pipe" to send data to a subsequent function) is when you apply a function to the previous function's output:
Expand Down
2 changes: 1 addition & 1 deletion doc/src/manual/performance-tips.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ julia> push!(a, 1); push!(a, 2.0); push!(a, π)
3-element Array{Real,1}:
1
2.0
π
π = 3.1415926535897...
```

Because `a` is a an array of abstract type [`Real`](@ref), it must be able to hold any
Expand Down
6 changes: 3 additions & 3 deletions stdlib/Dates/docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ Date
value: Int64 735264
julia> t.instant
Dates.UTInstant{Day}(735264 days)
Dates.UTInstant{Day}(Day(735264))
julia> Dates.value(t)
735264
Expand Down Expand Up @@ -400,7 +400,7 @@ As a bonus, all period arithmetic objects work directly with ranges:

```jldoctest
julia> dr = Date(2014,1,29):Day(1):Date(2014,2,3)
2014-01-29:1 day:2014-02-03
Date("2014-01-29"):Day(1):Date("2014-02-03")
julia> collect(dr)
6-element Array{Date,1}:
Expand All @@ -412,7 +412,7 @@ julia> collect(dr)
2014-02-03
julia> dr = Date(2014,1,29):Dates.Month(1):Date(2014,07,29)
2014-01-29:1 month:2014-07-29
Date("2014-01-29"):Month(1):Date("2014-07-29")
julia> collect(dr)
7-element Array{Date,1}:
Expand Down
31 changes: 14 additions & 17 deletions stdlib/Dates/src/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -578,33 +578,30 @@ function format(dt::TimeType, f::AbstractString; locale::Locale=ENGLISH)
end

# show

function Base.show(io::IO, dt::DateTime)
if millisecond(dt) == 0
format(io, dt, dateformat"YYYY-mm-dd\THH:MM:SS")
else
format(io, dt, dateformat"YYYY-mm-dd\THH:MM:SS.s")
end
end

function Base.show(io::IO, dt::Date)
format(io, dt, dateformat"YYYY-mm-dd")
end

function Base.string(dt::DateTime)
if millisecond(dt) == 0
function Base.print(io::IO, dt::DateTime)
str = if millisecond(dt) == 0
format(dt, dateformat"YYYY-mm-dd\THH:MM:SS", 24)
else
format(dt, dateformat"YYYY-mm-dd\THH:MM:SS.s", 26)
end
print(io, str)
end

function Base.string(dt::Date)
function Base.print(io::IO, dt::Date)
# don't use format - bypassing IOBuffer creation
# saves a bit of time here.
y,m,d = yearmonthday(value(dt))
yy = y < 0 ? @sprintf("%05i", y) : lpad(y, 4, "0")
mm = lpad(m, 2, "0")
dd = lpad(d, 2, "0")
return "$yy-$mm-$dd"
print(io, "$yy-$mm-$dd")
end

for date_type in (:Date, :DateTime)
# Human readable output (i.e. "2012-01-01")
@eval Base.show(io::IO, ::MIME"text/plain", dt::$date_type) = print(io, dt)
# Parsable output (i.e. Date("2012-01-01"))
@eval Base.show(io::IO, dt::$date_type) = print(io, typeof(dt), "(\"", dt, "\")")
# Parsable output will have type info displayed, thus it is implied
@eval Base.typeinfo_implicit(::Type{$date_type}) = true
end
7 changes: 5 additions & 2 deletions stdlib/Dates/src/periods.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ for period in (:Year, :Month, :Week, :Day, :Hour, :Minute, :Second, :Millisecond
@eval periodisless(x::$period, y::$period) = value(x) < value(y)
# AbstractString parsing (mainly for IO code)
@eval $period(x::AbstractString) = $period(Base.parse(Int64, x))
# The period type is printed when output, thus it already implies its own typeinfo
@eval Base.typeinfo_implicit(::Type{$period}) = true
# Period accessors
typs = period in (:Microsecond, :Nanosecond) ? ["Time"] :
period in (:Hour, :Minute, :Second, :Millisecond) ? ["Time", "DateTime"] : ["Date", "DateTime"]
Expand All @@ -45,8 +47,9 @@ for period in (:Year, :Month, :Week, :Day, :Hour, :Minute, :Second, :Millisecond
end

#Print/show/traits
Base.string(x::Period) = string(value(x), _units(x))
Base.show(io::IO,x::Period) = print(io, string(x))
Base.print(io::IO, x::Period) = print(io, value(x), _units(x))
Base.show(io::IO, ::MIME"text/plain", x::Period) = print(io, x)
Base.show(io::IO, p::P) where {P<:Period} = print(io, P, '(', value(p), ')')
Base.zero(::Union{Type{P},P}) where {P<:Period} = P(0)
Base.one(::Union{Type{P},P}) where {P<:Period} = 1 # see #16116
Base.typemin(::Type{P}) where {P<:Period} = P(typemin(Int64))
Expand Down
4 changes: 2 additions & 2 deletions stdlib/Dates/test/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ using Dates

@testset "string/show representation of Date" begin
@test string(Dates.Date(1, 1, 1)) == "0001-01-01" # January 1st, 1 AD/CE
@test sprint(show, Dates.Date(1, 1, 1)) == "0001-01-01"
@test sprint(show, Dates.Date(1, 1, 1)) == "Dates.Date(\"0001-01-01\")"
@test string(Dates.Date(0, 12, 31)) == "0000-12-31" # December 31, 1 BC/BCE
@test Dates.Date(1, 1, 1) - Dates.Date(0, 12, 31) == Dates.Day(1)
@test Dates.Date(Dates.UTD(-306)) == Dates.Date(0, 2, 29)
Expand All @@ -16,7 +16,7 @@ using Dates
@test string(Dates.Date(-1000000, 1, 1)) == "-1000000-01-01"
@test string(Dates.Date(1000000, 1, 1)) == "1000000-01-01"
@test string(Dates.DateTime(2000, 1, 1, 0, 0, 0, 1)) == "2000-01-01T00:00:00.001"
@test sprint(show, Dates.DateTime(2000, 1, 1, 0, 0, 0, 1)) == "2000-01-01T00:00:00.001"
@test sprint(show, Dates.DateTime(2000, 1, 1, 0, 0, 0, 1)) == "Dates.DateTime(\"2000-01-01T00:00:00.001\")"
@test string(Dates.DateTime(2000, 1, 1, 0, 0, 0, 2)) == "2000-01-01T00:00:00.002"
@test string(Dates.DateTime(2000, 1, 1, 0, 0, 0, 500)) == "2000-01-01T00:00:00.5"
@test string(Dates.DateTime(2000, 1, 1, 0, 0, 0, 998)) == "2000-01-01T00:00:00.998"
Expand Down
10 changes: 5 additions & 5 deletions test/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1150,7 +1150,7 @@ let x = [], y = [], z = Base.ImmutableDict(x => y)
push!(x, y)
push!(y, x)
push!(y, z)
@test replstr(x) == "1-element Array{Any,1}:\n Any[Any[Any[#= circular reference @-2 =#]], Base.ImmutableDict{Array{Any,1},Array{Any,1}}([Any[#= circular reference @-3 =#]] => [#= circular reference @-2 =#])]"
@test replstr(x) == "1-element Array{Any,1}:\n Any[Any[#= circular reference @-2 =#], Base.ImmutableDict{Array{Any,1},Array{Any,1}}([#= circular reference @-3 =#] => [#= circular reference @-2 =#])]"
@test repr(z) == "Base.ImmutableDict{Array{Any,1},Array{Any,1}}([Any[Any[#= circular reference @-2 =#], Base.ImmutableDict{Array{Any,1},Array{Any,1}}(#= circular reference @-3 =#)]] => [Any[Any[#= circular reference @-2 =#]], Base.ImmutableDict{Array{Any,1},Array{Any,1}}(#= circular reference @-2 =#)])"
@test sprint(dump, x) == """
Array{Any}((1,))
Expand Down Expand Up @@ -1478,10 +1478,10 @@ end
"[3.14159 3.14159; 3.14159 3.14159]"
@test showstr([x x; x x]) == showstr([x x; x x], :compact => false) ==
"[3.141592653589793 3.141592653589793; 3.141592653589793 3.141592653589793]"
@test replstr([x, x]) == replstr([x, x], :compact => false) ==
@test replstr([x, x], :compact => false) ==
"2-element Array{Float64,1}:\n 3.141592653589793\n 3.141592653589793"
@test replstr([x, x], :compact => true) ==
"2-element Array{Float64,1}:\n 3.14159\n 3.14159"
@test replstr([x, x]) == "2-element Array{Float64,1}:\n 3.141592653589793\n 3.141592653589793"
@test replstr([x, x], :compact => true) == "2-element Array{Float64,1}:\n 3.14159\n 3.14159"
@test replstr([x x; x x]) == replstr([x x; x x], :compact => true) ==
"2×2 Array{Float64,2}:\n 3.14159 3.14159\n 3.14159 3.14159"
@test showstr([x x; x x], :compact => false) ==
Expand Down Expand Up @@ -1922,7 +1922,7 @@ Z = Array{Float64}(undef,0,0)
@test showstr(vec_undefined) == "Any[#undef, #undef]"
@test showstr(vec_initialisers) == "[$undef, $undef]"
@test replstr(vec_undefined) == "2-element Array{Any,1}:\n #undef\n #undef"
@test replstr(vec_initialisers) == "2-element Array{UndefInitializer,1}:\n $undef\n $undef"
@test replstr(vec_initialisers) == "2-element Array{UndefInitializer,1}:\n UndefInitializer(): array initializer with undefined values\n UndefInitializer(): array initializer with undefined values"
end

# issue #31065, do not print parentheses for nested dot expressions
Expand Down

0 comments on commit 5f176e0

Please sign in to comment.