Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add :color attribute to IOContext, prefer get(io,:color,false) to Base.have_color #25067

Merged
merged 15 commits into from
Dec 18, 2017

Conversation

stevengj
Copy link
Member

@stevengj stevengj commented Dec 13, 2017

Fixes #19682 by making the use of ANSI color/formatting codes specific to the io device. Instead of accessing the Base.have_color global, you should call Base.hascolor(io) (not exported) get(io, :color, false). By default this uses Base.have_color for TTY devices, but can be overridden by the :color => {true,false} property of IOContext.

Also fixes a problem noted on discourse where Markdown was overriding display to do terminal output. Now it overrides show and uses hascolor(io) to decide in a device-specific way whether to output formatting codes.

@stevengj stevengj added the display and printing Aesthetics and correctness of printed representations of objects. label Dec 13, 2017
@KristofferC
Copy link
Member

I wonder if it should be possible to distinguish between supporting 16, 256, 24bit colors. Just a random thought, just ignore if this is off topic.

@test length(methods(method_c1)) <= 3 # because of '...' in candidate printing
test_have_color(buf,
"\e[0m\nClosest candidates are:\n method_c1(\e[1m\e[31m::Float64\e[0m, \e[1m\e[31m::AbstractString...\e[0m)$cfile$c1line\e[0m",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be nice to keep (some of?) these, now that we can actually test both code path properly:

Base.show_method_candidates(IOContext(buf, :color => true), Base.MethodError(method_c1,(1, 1, "")))
@test String(take!(buf)) == "\e[0m\nClosest candidates are:\n  method_c1(\e[1m\e[31m::Float64\e[0m, \e[1m\e[31m::AbstractString...\e[0m)$cfile$c1line\e[0m"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think color codes in warnings are tested elsewhere....

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But sure, I'll add a few back in with color enabled.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interestingly enough, the have_color testcase was totally wrong, since at least Julia 0.6. It seems that this hasn't been tested in a long while.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a test.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proving once again that bitrot is inevitable for code that doesn't actually run!

base/show.jl Outdated

Return `true` if `io` supports/expects ANSI color codes.

(This is determined when Julia is started for terminals, and can be
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parens don't seem necessary to me.

@@ -67,6 +67,9 @@ The following properties are in common use:
can be avoided (e.g. `[Float16(0)]` can be shown as "Float16[0.0]" instead
of "Float16[Float16(0.0)]" : while displaying the elements of the array, the `:typeinfo`
property will be set to `Float16`).
- `:color`: Boolean specifying whether ANSI color/escape codes are supported/expected.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Longer term, I think we may want to try to distinguish between policy ("wants color") and mechanism ("ansi", "xterm256", "html"). But this PR is already strictly better than what we have now, so I think we should merge this and then consider iterating (as needed).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can add new IO context attributes that Base understand in the future as long as the behavior of the existing ones remains the same.

@stevengj stevengj changed the title add :color attribute to IOContext, prefer Base.hascolor(io) to Base.have_color add :color attribute to IOContext, prefer get(io,:color,false) to Base.have_color Dec 14, 2017
@stevengj
Copy link
Member Author

Note that with this PR, a Markdown object rendered to text/plain is now the "rendered" text (with or without color), since this is how it is displayed (rather than overriding display as was done previously, contrary to usual practice). Previously, text/plain output was identical to text/markdown output, erasing a useful distinction — now, if you want text/markdown output you should show to text/markdown.

(In general, there is a lot of stuff in the documentation system that hooks into the display system a little oddly, e.g. using side-effects … this required some crude hacks in IJulia to get a "clean" docstring out of a help request.)

@StefanKarpinski
Copy link
Member

Error in docs:

Error in testset docs:
Test Failed at /tmp/julia/share/julia/test/docs.jl:29
  Expression: stringmime("text/plain", Docs.doc(C74685)) == "Doc abstract type\n"
   Evaluated: "  Doc abstract type\n" == "Doc abstract type\n"
Error in testset compile:
Error During Test at nothing:1
  Test threw an exception of type Test.TestSetException
  Expression: compile
  Some tests did not pass: 90 passed, 2 failed, 0 errored, 0 broken.
ERROR: LoadError: Test run finished with errors
in expression starting at /tmp/julia/share/julia/test/runtests.jl:46

@stevengj
Copy link
Member Author

stevengj commented Dec 15, 2017

Yes, the text/plain output has changed. If you just do sprint or string you will still get the old output, though. I'll fix the test.

@stevengj
Copy link
Member Author

Looks like it needs a rebase after #24913 to fix the new deprecation.

@stevengj
Copy link
Member Author

stevengj commented Dec 16, 2017

I'm getting

Error in testset misc:
Error During Test at /tmp/julia/share/julia/test/testdefs.jl:19
  Got an exception of type LoadError outside of a @test
  LoadError: `warn()` is deprecated, use `@warn` instead.

I guess someone flipped a switch to turn deprecations into errors so that now everything is breaking? (I'm confused.)

@StefanKarpinski
Copy link
Member

We now had standard logging infrastructure in Base: #24490. Among other changes, warn("message") should now be written as @warn "message".

@stevengj
Copy link
Member Author

stevengj commented Dec 16, 2017

I'm confused, because tests/misc.jl seems to contain a ton of calls to warn(...) besides the one I added in this PR. @c42f, shouldn't those calls have been updated in #24490?

@c42f
Copy link
Member

c42f commented Dec 16, 2017

shouldn't those calls have been updated

These test deprecated functionality - the new system is tested separately in test/logging.jl. I could have just removed the old tests, but that seemed premature because deprecated functionality should continue to work until it's removed.

@stevengj
Copy link
Member Author

Oh, now I see the if Base.JLOptions().depwarn != 2 at the top...

@c42f
Copy link
Member

c42f commented Dec 17, 2017

Yeah it's a bit nasty I'm afraid - this is why I want to remove deperror - if it's enabled it's all or nothing, there's really no nice way to test deprecated functionality.

@StefanKarpinski
Copy link
Member

I would just delete the deprecated functionality tests. After all, we’re going to delete the in 1.0 anyway.

stevengj referenced this pull request Dec 18, 2017
To capture messages from Base, users should install a logger instead,
for example, using `with_logger()`.
@stevengj
Copy link
Member Author

ci/circleci seems to be an unrelated libgit2 "Error deserializing a remote exception" distributed-test failure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
display and printing Aesthetics and correctness of printed representations of objects.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

with_output_color writes control codes to non-terminal streams
5 participants