From 2d0a924a30d2e561ab5bcdfd1b6881c9775fb505 Mon Sep 17 00:00:00 2001 From: rokke <66498307+rokke-git@users.noreply.github.com> Date: Wed, 15 Jul 2026 20:21:23 -0400 Subject: [PATCH 1/3] use normal entrypoints into base's display pipeline Base and SparseArrays had some funky action-at-a-distance stuff going on, this fully disentangles them. this also makes SparseArrays a little smarter about when to swap to braille, and actually uses the whole screen instead of just the left half. it's also theoretically doing less work now, but it's just a printing function so whatever. width of displayed zeros also doesn't depend on the type anymore, so that error goes away; added in a warning to replace it. --- src/sparsematrix.jl | 66 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/src/sparsematrix.jl b/src/sparsematrix.jl index 51ff5caf..953b02a6 100644 --- a/src/sparsematrix.jl +++ b/src/sparsematrix.jl @@ -334,10 +334,7 @@ function Base.isstored(A::AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC}, i::Intege return false end -Base.replace_in_print_matrix(A::AbstractSparseMatrixCSCInclAdjointAndTranspose, i::Integer, j::Integer, s::AbstractString) = - Base.isstored(A, i, j) ? s : Base.replace_with_centered_mark(s) - -function Base.array_summary(io::IO, S::AbstractSparseMatrixCSCInclAdjointAndTranspose, dims::Tuple{Vararg{Base.OneTo}}) +function Base.summary(io::IO, S::AbstractSparseMatrixCSCInclAdjointAndTranspose) _checkbuffers(S) xnnz = nnz(S) @@ -347,12 +344,23 @@ function Base.array_summary(io::IO, S::AbstractSparseMatrixCSCInclAdjointAndTran nothing end -# called by `show(io, MIME("text/plain"), ::AbstractSparseMatrixCSCInclAdjointAndTranspose)` -function Base.print_array(io::IO, S::AbstractSparseMatrixCSCInclAdjointAndTranspose) - if max(size(S)...) < 16 - Base.print_matrix(io, S) - else +using Base: show_circular +function Base.show(io::IO, ::MIME"text/plain", S::AbstractSparseMatrixCSCInclAdjointAndTranspose) + isempty(S) && get(io, :compact, false) && return show(io, S) + summary(io, S) + isempty(S) && return + + screen = displaysize(io) + get(io, :limit, false) && screen[1] <= 4 && return print(io, ": …") + println(io, ":") + + show_circular(io, S) && return + io = IOContext(io, :compact=>true, :typeinfo=>eltype(S), :SHOWN_SET=>S) + + if (screen[1] < size(S, 1) + 4) | (screen[2] < 3size(S, 2)) _show_with_braille_patterns(io, S) + else + _show_with_dotted_zeros(io, S) end end @@ -399,13 +407,19 @@ end const brailleBlocks = UInt16['⠁', '⠂', '⠄', '⡀', '⠈', '⠐', '⠠', '⢀'] function _show_with_braille_patterns(io::IO, S::AbstractSparseMatrixCSCInclAdjointAndTranspose) + try + zero(eltype(S)) + catch + printstyled(io, "WARNING: could not find generic zero for given elements. expect errors and wrong results\n", color=:red) + end + m, n = size(S) (m == 0 || n == 0) && return show(io, MIME("text/plain"), S) # The maximal number of characters we allow to display the matrix local maxHeight::Int, maxWidth::Int maxHeight = displaysize(io)[1] - 4 # -4 from [Prompt, header, newline after elements, new prompt] - maxWidth = displaysize(io)[2] ÷ 2 + maxWidth = displaysize(io)[2] - 2 # -2 from brackets # In the process of generating the braille pattern to display the nonzero # structure of `S`, we need to be able to scale the matrix `S` to a @@ -489,6 +503,38 @@ function _show_with_braille_patterns(io::IO, S::AbstractSparseMatrixCSCInclAdjoi foreach(c -> print(io, Char(c)), @view brailleGrid[1:end-1]) end +using Base: alignment +function _show_with_dotted_zeros(io::IO, S::AbstractSparseMatrixCSCInclAdjointAndTranspose) + rows, cols, vals = rowvals(parent(S)), ColumnIndices(parent(S)), nonzeros(parent(S)) + (S isa Adjoint) | (S isa Transpose) && ((rows, cols) = (cols, rows)) + + align = [alignment(io, val) for val in vals] + colwidths = [max.((0, 0), align[findall(==(col), cols)]...) for col in axes(S,2)] + displaysize(io)[2] < sum(sum.(colwidths) .+ 2) && return _show_with_braille_patterns(io, S) + + try + zero(eltype(S)) + catch + printstyled(io, "WARNING: could not find generic zero for given elements. expect errors and wrong results\n", color=:red) + end + + for row in axes(S,1) + for col in axes(S,2) + index = findall(==(col), cols) + index = index[findall(==(row), rows[index])] + l, r = colwidths[col] + if isempty(index) # no value here, print an aligned dot + l, r = cld(l+r-1, 2) + 1, div(l+r-1, 2) + 1 + print(io, " "^l * "⋅" * (col==axes(S,2)[end] ? "" : " "^r)) + else + l, r = (l+1, r+1) .- align[index][] + print(io, " "^l, vals[index][], (col==axes(S,2)[end] ? "" : " "^r)) + end + end + row == axes(S,1)[end] || println(io) + end +end + for QT in (:LinAlgLeftQs, :LQPackedQ) @eval (*)(Q::$QT, B::AbstractSparseMatrixCSC) = Q * Matrix(B) @eval (*)(Q::$QT, B::AdjOrTrans{<:Any,<:AbstractSparseMatrixCSC}) = Q * copy(B) From d75d9276763b537a90bbd8ca3c8fa231c392b3fa Mon Sep 17 00:00:00 2001 From: rokke <66498307+rokke-git@users.noreply.github.com> Date: Wed, 15 Jul 2026 20:56:58 -0400 Subject: [PATCH 2/3] add/fix tests --- docs/src/index.md | 7 +++- src/linalg.jl | 12 +++--- src/solvers/spqr.jl | 12 +++--- src/sparsematrix.jl | 45 ++++++++++++++-------- test/issues.jl | 13 ++++++- test/sparsematrix_constructors_indexing.jl | 6 +-- 6 files changed, 59 insertions(+), 36 deletions(-) diff --git a/docs/src/index.md b/docs/src/index.md index cb2760c5..27fc0521 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -113,8 +113,11 @@ julia> I = [1, 4, 3, 5]; J = [4, 7, 18, 9]; V = [1, 2, -5, 3]; julia> S = sparse(I,J,V) 5×18 SparseMatrixCSC{Int64, Int64} with 4 stored entries: -⎡⠀⠈⠀⠀⠀⠀⠀⠀⢀⎤ -⎣⠀⠀⠀⠂⡀⠀⠀⠀⠀⎦ + ⋅ ⋅ ⋅ 1 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ + ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ + ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ -5 + ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 2 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ + ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 3 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ julia> R = sparsevec(I,V) 5-element SparseVector{Int64, Int64} with 4 stored entries: diff --git a/src/linalg.jl b/src/linalg.jl index 69e2a0d5..2f6f6ab6 100644 --- a/src/linalg.jl +++ b/src/linalg.jl @@ -2094,9 +2094,9 @@ julia> A[4:4:8] .= 1; julia> A 3×3 SparseMatrixCSC{Float64, Int64} with 2 stored entries: - ⋅ 1.0 ⋅ - ⋅ ⋅ 1.0 - ⋅ ⋅ ⋅ + ⋅ 1.0 ⋅ + ⋅ ⋅ 1.0 + ⋅ ⋅ ⋅ julia> C = spzeros(3,3); @@ -2104,9 +2104,9 @@ julia> C[2:4:6] .= 2; julia> C 3×3 SparseMatrixCSC{Float64, Int64} with 2 stored entries: - ⋅ ⋅ ⋅ - 2.0 ⋅ ⋅ - ⋅ 2.0 ⋅ + ⋅ ⋅ ⋅ + 2.0 ⋅ ⋅ + ⋅ 2.0 ⋅ julia> SparseArrays.mergeinds!(C, A) 3×3 SparseMatrixCSC{Float64, Int64} with 4 stored entries: diff --git a/src/solvers/spqr.jl b/src/solvers/spqr.jl index 2f71dd65..9e5f2ebb 100644 --- a/src/solvers/spqr.jl +++ b/src/solvers/spqr.jl @@ -192,8 +192,8 @@ Q factor: 4×4 SparseArrays.SPQR.QRSparseQ{Float64, Int64} R factor: 2×2 SparseMatrixCSC{Float64, Int64} with 2 stored entries: - -1.41421 ⋅ - ⋅ -1.41421 + -1.41421 ⋅ + ⋅ -1.41421 Row permutation: 4-element Vector{Int64}: 1 @@ -471,10 +471,10 @@ when the problem is underdetermined. ```jldoctest julia> A = sparse([1,2,4], [1,1,1], [1.0,1.0,1.0], 4, 2) 4×2 SparseMatrixCSC{Float64, Int64} with 3 stored entries: - 1.0 ⋅ - 1.0 ⋅ - ⋅ ⋅ - 1.0 ⋅ + 1.0 ⋅ + 1.0 ⋅ + ⋅ ⋅ + 1.0 ⋅ julia> qr(A)\\fill(1.0, 4) 2-element Vector{Float64}: diff --git a/src/sparsematrix.jl b/src/sparsematrix.jl index 953b02a6..8893c052 100644 --- a/src/sparsematrix.jl +++ b/src/sparsematrix.jl @@ -357,7 +357,7 @@ function Base.show(io::IO, ::MIME"text/plain", S::AbstractSparseMatrixCSCInclAdj show_circular(io, S) && return io = IOContext(io, :compact=>true, :typeinfo=>eltype(S), :SHOWN_SET=>S) - if (screen[1] < size(S, 1) + 4) | (screen[2] < 3size(S, 2)) + if (screen[1] < size(S, 1) + 5) | (screen[2] < 3size(S, 2)) _show_with_braille_patterns(io, S) else _show_with_dotted_zeros(io, S) @@ -407,12 +407,6 @@ end const brailleBlocks = UInt16['⠁', '⠂', '⠄', '⡀', '⠈', '⠐', '⠠', '⢀'] function _show_with_braille_patterns(io::IO, S::AbstractSparseMatrixCSCInclAdjointAndTranspose) - try - zero(eltype(S)) - catch - printstyled(io, "WARNING: could not find generic zero for given elements. expect errors and wrong results\n", color=:red) - end - m, n = size(S) (m == 0 || n == 0) && return show(io, MIME("text/plain"), S) @@ -421,6 +415,14 @@ function _show_with_braille_patterns(io::IO, S::AbstractSparseMatrixCSCInclAdjoi maxHeight = displaysize(io)[1] - 4 # -4 from [Prompt, header, newline after elements, new prompt] maxWidth = displaysize(io)[2] - 2 # -2 from brackets + warn = false + try + zero(eltype(S)) + catch + warn = true + maxHeight -= 1 + end + # In the process of generating the braille pattern to display the nonzero # structure of `S`, we need to be able to scale the matrix `S` to a # smaller matrix with the same aspect ratio as `S`, but fits on the @@ -464,6 +466,13 @@ function _show_with_braille_patterns(io::IO, S::AbstractSparseMatrixCSCInclAdjoi rvals = rowvals(parent(S)) rowscale = max(1, scaleHeight - 1) / max(1, m - 1) colscale = max(1, scaleWidth - 1) / max(1, n - 1) + + if rowscale != 1 || colscale != 1 + print(io, " (downscaled to fit on screen)") + end + println(io, ":") + warn && printstyled(stderr, "WARNING: could not find generic zero for given elements. expect errors and wrong results\n", color=:red) + if isa(S, AbstractSparseMatrixCSC) @inbounds for j in axes(S,2) # Scale the column index `j` to the best matching column index @@ -508,14 +517,14 @@ function _show_with_dotted_zeros(io::IO, S::AbstractSparseMatrixCSCInclAdjointAn rows, cols, vals = rowvals(parent(S)), ColumnIndices(parent(S)), nonzeros(parent(S)) (S isa Adjoint) | (S isa Transpose) && ((rows, cols) = (cols, rows)) - align = [alignment(io, val) for val in vals] + align = [isassigned(vals, val) ? alignment(io, vals[val]) : (3, 3) for val in eachindex(vals)] colwidths = [max.((0, 0), align[findall(==(col), cols)]...) for col in axes(S,2)] displaysize(io)[2] < sum(sum.(colwidths) .+ 2) && return _show_with_braille_patterns(io, S) try zero(eltype(S)) catch - printstyled(io, "WARNING: could not find generic zero for given elements. expect errors and wrong results\n", color=:red) + printstyled(stderr, "WARNING: could not find generic zero for given elements. expect errors and wrong results\n", color=:red) end for row in axes(S,1) @@ -528,7 +537,9 @@ function _show_with_dotted_zeros(io::IO, S::AbstractSparseMatrixCSCInclAdjointAn print(io, " "^l * "⋅" * (col==axes(S,2)[end] ? "" : " "^r)) else l, r = (l+1, r+1) .- align[index][] - print(io, " "^l, vals[index][], (col==axes(S,2)[end] ? "" : " "^r)) + print(io, " "^l) + isassigned(vals, index[]) ? show(io, vals[index][]) : print(io, "#undef") + col == axes(S,2)[end] || print(io, " "^r) end end row == axes(S,1)[end] || println(io) @@ -1951,9 +1962,9 @@ julia> A = sparse([1, 2, 3], [1, 2, 3], [1.0, 0.0, 1.0]) julia> dropzeros(A) 3×3 SparseMatrixCSC{Float64, Int64} with 2 stored entries: - 1.0 ⋅ ⋅ - ⋅ ⋅ ⋅ - ⋅ ⋅ 1.0 + 1.0 ⋅ ⋅ + ⋅ ⋅ ⋅ + ⋅ ⋅ 1.0 ``` """ dropzeros(A::AbstractSparseMatrixCSC) = dropzeros!(copy(A)) @@ -2123,7 +2134,7 @@ argument specifies a random number generator, see [Random Numbers](@ref). ```jldoctest; setup = :(using Random; Random.seed!(0)) julia> sprandn(2, 2, 0.75) 2×2 SparseMatrixCSC{Float64, Int64} with 3 stored entries: - -1.20577 ⋅ + -1.20577 ⋅ 0.311817 -0.234641 ``` """ @@ -2150,9 +2161,9 @@ specified. ```jldoctest julia> spzeros(3, 3) 3×3 SparseMatrixCSC{Float64, Int64} with 0 stored entries: - ⋅ ⋅ ⋅ - ⋅ ⋅ ⋅ - ⋅ ⋅ ⋅ + ⋅ ⋅ ⋅ + ⋅ ⋅ ⋅ + ⋅ ⋅ ⋅ julia> spzeros(Float32, 4) 4-element SparseVector{Float32, Int64} with 0 stored entries diff --git a/test/issues.jl b/test/issues.jl index 9f46a639..c65683f3 100644 --- a/test/issues.jl +++ b/test/issues.jl @@ -758,14 +758,14 @@ let B = similar(A, T12960) @test repr(B) == "sparse([1, 2, 3], [1, 2, 3], $T12960[#undef, #undef, #undef], 3, 3)" @test occursin( - "\n #undef ⋅ ⋅ \n ⋅ #undef ⋅ \n ⋅ ⋅ #undef", + " #undef ⋅ ⋅\n ⋅ #undef ⋅\n ⋅ ⋅ #undef", repr(MIME("text/plain"), B), ) B[1,2] = T12960() @test repr(B) == "sparse([1, 1, 2, 3], [1, 2, 2, 3], $T12960[#undef, $T12960(), #undef, #undef], 3, 3)" @test occursin( - "\n #undef T12960() ⋅ \n ⋅ #undef ⋅ \n ⋅ ⋅ #undef", + "\n #undef T12960() ⋅\n ⋅ #undef ⋅\n ⋅ ⋅ #undef", repr(MIME("text/plain"), B), ) end @@ -805,6 +805,15 @@ end 7 16 4]) end +@testset "Issue #512" begin # suppresses but does not fix the error mentioned + x = sparse([1, 1, 3], [1, 4, 3], [20, 0, [2]]) + @test_warn "WARNING: could not find generic zero" repr(MIME("text/plain"), x) + x = sparse([1, 100, 3], [1, 4, 300], [20, 0, [2]]) + @test_warn "WARNING: could not find generic zero" repr(MIME("text/plain"), x) + + @test_broken repr(MIME("text/plain"), transpose(x')) +end + @testset "Issue #574" begin a = spzeros(Float32, Int16, 2, 3) v = spzeros(Float32, Int16, 2) diff --git a/test/sparsematrix_constructors_indexing.jl b/test/sparsematrix_constructors_indexing.jl index 9fd1567c..95b0fffa 100644 --- a/test/sparsematrix_constructors_indexing.jl +++ b/test/sparsematrix_constructors_indexing.jl @@ -1514,9 +1514,9 @@ end A = spzeros(Float32, Int64, 2, 2) for (transform, showstring) in zip( (identity, adjoint, transpose), ( - "2×2 $SparseMatrixCSC{Float32, Int64} with 0 stored entries:\n ⋅ ⋅ \n ⋅ ⋅ ", - "2×2 $Adjoint{Float32, $SparseMatrixCSC{Float32, Int64}} with 0 stored entries:\n ⋅ ⋅ \n ⋅ ⋅ ", - "2×2 $Transpose{Float32, $SparseMatrixCSC{Float32, Int64}} with 0 stored entries:\n ⋅ ⋅ \n ⋅ ⋅ ", + "2×2 $SparseMatrixCSC{Float32, Int64} with 0 stored entries:\n ⋅ ⋅\n ⋅ ⋅", + "2×2 $Adjoint{Float32, $SparseMatrixCSC{Float32, Int64}} with 0 stored entries:\n ⋅ ⋅\n ⋅ ⋅", + "2×2 $Transpose{Float32, $SparseMatrixCSC{Float32, Int64}} with 0 stored entries:\n ⋅ ⋅\n ⋅ ⋅", )) show(io, MIME"text/plain"(), transform(A)) @test String(take!(io)) == showstring From 7969cbebaeac5b4e5977ff760df7cac1f9d28fe7 Mon Sep 17 00:00:00 2001 From: rokke <66498307+rokke-git@users.noreply.github.com> Date: Thu, 16 Jul 2026 09:09:46 -0400 Subject: [PATCH 3/3] fix related issues, add new test --- src/sparsematrix.jl | 35 ++++++++++++++++------ test/issues.jl | 15 ++++++++++ test/sparsematrix_constructors_indexing.jl | 26 ++++++++-------- 3 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/sparsematrix.jl b/src/sparsematrix.jl index 8893c052..eb59a85e 100644 --- a/src/sparsematrix.jl +++ b/src/sparsematrix.jl @@ -352,7 +352,6 @@ function Base.show(io::IO, ::MIME"text/plain", S::AbstractSparseMatrixCSCInclAdj screen = displaysize(io) get(io, :limit, false) && screen[1] <= 4 && return print(io, ": …") - println(io, ":") show_circular(io, S) && return io = IOContext(io, :compact=>true, :typeinfo=>eltype(S), :SHOWN_SET=>S) @@ -433,7 +432,7 @@ function _show_with_braille_patterns(io::IO, S::AbstractSparseMatrixCSCInclAdjoi # `scaleHeight` and `scaleWidth` accordingly. Note that each available # character can contain up to 4 braille dots in its height (⡇) and up to # 2 braille dots in its width (⠉). - if get(io, :limit, true) && (m > 4maxHeight || n > 2maxWidth) + if get(io, :limit, false) && (m > 4maxHeight || n > 2maxWidth) s = min(2maxWidth / n, 4maxHeight / m) scaleHeight = floor(Int, s * m) scaleWidth = floor(Int, s * n) @@ -521,6 +520,8 @@ function _show_with_dotted_zeros(io::IO, S::AbstractSparseMatrixCSCInclAdjointAn colwidths = [max.((0, 0), align[findall(==(col), cols)]...) for col in axes(S,2)] displaysize(io)[2] < sum(sum.(colwidths) .+ 2) && return _show_with_braille_patterns(io, S) + println(io, ":") + try zero(eltype(S)) catch @@ -536,10 +537,26 @@ function _show_with_dotted_zeros(io::IO, S::AbstractSparseMatrixCSCInclAdjointAn l, r = cld(l+r-1, 2) + 1, div(l+r-1, 2) + 1 print(io, " "^l * "⋅" * (col==axes(S,2)[end] ? "" : " "^r)) else - l, r = (l+1, r+1) .- align[index][] - print(io, " "^l) - isassigned(vals, index[]) ? show(io, vals[index][]) : print(io, "#undef") - col == axes(S,2)[end] || print(io, " "^r) + try # print the element with 1 space of buffer on each side + l, r = (l+1, r+1) .- align[index][] + print(io, " "^l) + isassigned(vals, index[]) ? show(io, vals[index][]) : print(io, "#undef") + col == axes(S,2)[end] || print(io, " "^r) + catch # if there's overlapping entries, [] will error. default to summing + # entries, but print in red to warn user that something's wrong + elm = any(!isassigned(vals, id) for id in index) ? "#undef" : + try repr(sum(vals[index]); context=:compact=>true) catch e "#NaN" end + + if length(elm) <= l+r # give up on alignment, center item in column + l, r = cld(l+r-length(elm), 2) + 1, div(l+r-length(elm), 2) + 1 + else # len of new item does not fit in column + elm = ' ' * "▒"^(l+r) * ' ' + l, r = 0, 0 + end + + printstyled(io, " "^l, elm, color=:red) + col == axes(S,2)[end] || print(io, " "^r) + end end end row == axes(S,1)[end] || println(io) @@ -688,7 +705,7 @@ function _sparse_copyto!(dest::AbstractMatrix, src::AbstractSparseMatrixCSC) @inbounds for col in axes(src, 2), ptr in nzrange(src, col) row = rowvals(src)[ptr] val = nonzeros(src)[ptr] - dest[isrc[row, col]] = val + dest[isrc[row, col]] += val end return dest end @@ -712,7 +729,7 @@ function copyto!(dest::AbstractMatrix, Rdest::CartesianIndices{2}, if row in rows val = nonzeros(src′)[ptr] I = Rdest[lin[row, col]] - dest[I] = val + dest[I] += val end end return dest @@ -737,7 +754,7 @@ function Base.copyto!(A::Array{T}, S::SparseMatrixCSC{<:Number}) where {T<:Numbe for i in nzrange(S, col) row = rowval[i] val = nzval[i] - A[linear_index_col0+row] = val + A[linear_index_col0+row] += val end linear_index_col0 += num_rows end diff --git a/test/issues.jl b/test/issues.jl index c65683f3..7667e88a 100644 --- a/test/issues.jl +++ b/test/issues.jl @@ -821,6 +821,21 @@ end @test eltype(rowvals(zero(v))) <: Int16 end +@testset "Issue #618" begin + x = SparseMatrixCSC(3, 3, [1, 3, 4, 5], [1, 1, 2, 3], [1.0, 1.0, 1.0, 1.0]) + @test contains(repr(MIME"text/plain"(), x), "2.0") + x = SparseMatrixCSC(3, 3, [1, 3, 4, 5], [1, 1, 2, 3], [7.0, 7.0, 1.0, 1.0]) + @test contains(repr(MIME"text/plain"(), x), "▒▒▒") + x = SparseMatrixCSC(3, 3, [1, 3, 4, 5], [1, 1, 2, 3], [7.0, 'o', 1.0, 1.0]) + @test contains(repr(MIME"text/plain"(), x), "#NaN") + v = similar(Any[1, 2, 3, 4]); v[2:4] = [1.0, 1.0, 1.0] + x = SparseMatrixCSC(3, 3, [1, 3, 4, 5], [1, 1, 2, 3], v) + @test contains(repr(MIME"text/plain"(), x), "#undef") + + x = SparseMatrixCSC(3, 3, [1, 3, 4, 5], [1, 1, 2, 3], [1, 1, 1, 1]) + @test 2 == Matrix(x)[1,1] +end + end # SparseTestsBase end # module diff --git a/test/sparsematrix_constructors_indexing.jl b/test/sparsematrix_constructors_indexing.jl index 95b0fffa..48141b61 100644 --- a/test/sparsematrix_constructors_indexing.jl +++ b/test/sparsematrix_constructors_indexing.jl @@ -1538,7 +1538,7 @@ end show(io, MIME"text/plain"(), transform(A)) @test String(take!(io)) == showstring _show_with_braille_patterns(convert(IOContext, io), transform(A)) - @test String(take!(io)) == braille + @test contains(String(take!(io)), braille) end # every 1-dot braille pattern @@ -1559,7 +1559,7 @@ end for transform in (identity, adjoint, transpose) expected = "⎡" * Char(10240)^2 * "⎤\n⎣" * Char(10240)^2 * "⎦" _show_with_braille_patterns(convert(IOContext, io), transform(A)) - @test String(take!(io)) == expected + @test contains(String(take!(io)), expected) end A = sparse(Int64[1, 2, 4, 2, 3], Int64[1, 1, 1, 2, 2], Int64[1, 1, 1, 1, 1], 4, 2) @@ -1578,7 +1578,7 @@ end show(io, MIME"text/plain"(), transform(A)) @test String(take!(io)) == showstring _show_with_braille_patterns(convert(IOContext, io), transform(A)) - @test String(take!(io)) == braille + @test contains(String(take!(io)), braille) end A = sparse(Int64[1, 3, 2, 4], Int64[1, 1, 2, 2], Int64[1, 1, 1, 1], 7, 3) @@ -1597,7 +1597,7 @@ end show(io, MIME"text/plain"(), transform(A)) @test String(take!(io)) == showstring _show_with_braille_patterns(convert(IOContext, io), transform(A)) - @test String(take!(io)) == braille + @test contains(String(take!(io)), braille) end A = sparse(Int64[1:10;], Int64[1:10;], fill(Float64(1), 10)) @@ -1606,7 +1606,7 @@ end "⎣⠀⠀⠀⠀⠑⎦" for transform in (identity, adjoint, transpose) _show_with_braille_patterns(convert(IOContext, io), transform(A)) - @test String(take!(io)) == brailleString + @test contains(String(take!(io)), brailleString) end # Issue #30589 @@ -1622,22 +1622,22 @@ end # vertical scaling ioc = IOContext(io, :displaysize => (5, 80), :limit => true) _show_with_braille_patterns(ioc, _filled_sparse(10, 10)) - @test String(take!(io)) == "⎡⣿⣿⎤\n" * - "⎣⣿⣿⎦" + @test contains(String(take!(io)), "⎡⣿⣿⎤\n" * + "⎣⣿⣿⎦") _show_with_braille_patterns(ioc, _filled_sparse(20, 10)) - @test String(take!(io)) == "⎡⣿⣿⎤\n" * - "⎣⣿⣿⎦" + @test contains(String(take!(io)), "⎡⣿⣿⎤\n" * + "⎣⣿⣿⎦") # horizontal scaling ioc = IOContext(io, :displaysize => (80, 4), :limit => true) _show_with_braille_patterns(ioc, _filled_sparse(8, 8)) - @test String(take!(io)) == "⎡⣿⣿⎤\n" * - "⎣⣿⣿⎦" + @test contains(String(take!(io)), "⎡⣿⣿⎤\n" * + "⎣⣿⣿⎦") _show_with_braille_patterns(ioc, _filled_sparse(8, 16)) - @test String(take!(io)) == "⎡⣿⣿⎤\n" * - "⎣⣿⣿⎦" + @test contains(String(take!(io)), "⎡⣿⣿⎤\n" * + "⎣⣿⣿⎦") # respect IOContext while displaying J I, J, V = shuffle(1:50), shuffle(1:50), [1:50;]