From 9b22b75d4f4b4ef5203e117da41f82744437b5b9 Mon Sep 17 00:00:00 2001 From: Christopher Doris Date: Wed, 8 Oct 2025 11:27:38 +0100 Subject: [PATCH 1/3] better compact printing of Py --- src/Core/Py.jl | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/Core/Py.jl b/src/Core/Py.jl index 9faea130..b936ebdf 100644 --- a/src/Core/Py.jl +++ b/src/Core/Py.jl @@ -168,16 +168,23 @@ function Base.show(io::IO, ::MIME"text/plain", o::Py) end hasprefix = (get(io, :typeinfo, Any) != Py)::Bool compact = get(io, :compact, false)::Bool + limit = get(io, :limit, true)::Bool + if compact + # compact should output a single line, which we force by replacing newline + # characters with spaces + str = replace(str, "\n" => " ") + end multiline = '\n' in str - prefix = - hasprefix ? - compact ? "Py:$(multiline ? '\n' : ' ')" : "Python:$(multiline ? '\n' : ' ')" : "" + prefix = !hasprefix ? "" : compact ? "Py: " : multiline ? "Python:\n" : "Python: " print(io, prefix) h, w = displaysize(io) - if get(io, :limit, true) + if limit + # limit: fit the printed text into the display size h, w = displaysize(io) h = max(h - 3, 5) # use 3 fewer lines to allow for the prompt, but always allow at least 5 lines if multiline + # multiline: we truncate each line to the width of the screen, and skip + # middle lines if there are too many for the height h -= 1 # for the prefix lines = split(str, '\n') function printlines(io, lines, w) @@ -218,7 +225,25 @@ function Base.show(io::IO, ::MIME"text/plain", o::Py) println(io) printlines(io, lines[end-h1+1:end], w) end + elseif compact + # compact: we print up to one screen width, skipping characters in the + # middle if the string is too long for the width + maxlen = w - length(prefix) + if length(str) ≤ maxlen + print(io, str) + else + gap = " ... " + gaplen = length(gap) + w0 = cld(maxlen - gaplen, 2) + i0 = nextind(str, 1, w0 - 1) + i1 = prevind(str, ncodeunits(str), maxlen - gaplen - w0 - 1) + print(io, str[begin:i0]) + printstyled(io, gap, color = :light_black) + print(io, str[i1:end]) + end else + # single-line: we print up to one screenfull, skipping characters in the + # middle if the string is too long. We skip a whole line of characters. maxlen = h * w - length(prefix) if length(str) ≤ maxlen print(io, str) From 122a1396c860f79ad3066d0d826a78c0ff441dd9 Mon Sep 17 00:00:00 2001 From: Christopher Doris Date: Thu, 9 Oct 2025 20:52:13 +0100 Subject: [PATCH 2/3] add tests for compact printing --- test/Core.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/Core.jl b/test/Core.jl index 32b4d59f..175a4442 100644 --- a/test/Core.jl +++ b/test/Core.jl @@ -805,6 +805,9 @@ end @test sprint(show, MIME("text/plain"), Py(12)) == "Python: 12" # https://github.com/JuliaPy/PythonCall.jl/issues/522 @test sprint(show, MIME("text/plain"), PythonCall.pynew()) == "Python: NULL" + # test compact printing + @test sprint(show, MIME("text/plain"), Py(String('A':'Z')), context=(:compact=>true, :displaysize=>(50, 20))) == "Py: 'ABCDE ... WXYZ'" + @test sprint(show, MIME("text/plain"), Py(String('A':'Z')), context=(:compact=>true, :limit=>false, :displaysize=>(50, 20))) == "Py: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" @test_throws MethodError sprint(show, MIME("text/html"), PythonCall.pynew()) end end From 38b577a1b13fe5579e0baf5b58fe6f2a78923178 Mon Sep 17 00:00:00 2001 From: Christopher Doris Date: Thu, 9 Oct 2025 20:56:26 +0100 Subject: [PATCH 3/3] update release notes --- docs/src/releasenotes.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/src/releasenotes.md b/docs/src/releasenotes.md index c4b029cb..445d8b58 100644 --- a/docs/src/releasenotes.md +++ b/docs/src/releasenotes.md @@ -1,5 +1,10 @@ # Release Notes +## Unreleased +* Showing `Py` now respects the `compact` option - output is limited to a single line of + at most the display width. +* Bug fixes. + ## 0.9.28 (2025-09-17) * Added `NumpyDates`: NumPy-compatible DateTime64/TimeDelta64 types and units. * Added `pyconvert` rules for NumpyDates types.