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

[BUG] Can't print in Jupyter console or qtconsole (but can in jupyter lab) #870

Closed
quantum-booty opened this issue Dec 31, 2020 · 20 comments

Comments

@quantum-booty
Copy link

quantum-booty commented Dec 31, 2020

image
This is what I get when I try to do rich.print in jupyter console or qtconsole. But in jupyterlab it is able to print.

I have installed rich using pip install rich[jupyter]
Python version: 3.9
Jupyter (qt)console version: Latest

@nathanrpage97
Copy link
Contributor

Can you run in ipython:

%run -m rich.diagnose

And provide the output?

Also, can you post the source code of what you are running.

@nathanrpage97
Copy link
Contributor

Ahh rich.diagnose wont work with a qtconsole. Will need to look deeper.

@nathanrpage97
Copy link
Contributor

nathanrpage97 commented Jan 4, 2021

The issue comes down to qtconsole not supporting html displays like jupyter. Not sure how to proceed.

@willmcgugan
Copy link
Collaborator

The Jupyter ecosystem is somewhat frustrating, there doesn't seem to be a clear way of querying for capabilities. I think the issue comes down to this bit of code. https://github.com/willmcgugan/rich/blob/master/rich/console.py#L312

If qtconsole doesn't use that protocol, we will need a way of detecting it.

@nathanrpage97
Copy link
Contributor

nathanrpage97 commented Jan 4, 2021

There is the environment variable QT_API that is commonly set for the qtconsole version.

@nathanrpage97
Copy link
Contributor

nathanrpage97 commented Jan 4, 2021

The larger issue is that such a qtconsole isn't a terminal and can't use the full ANSI character-set, but also doesn't have the ability to render html.

@henryiii
Copy link
Contributor

henryiii commented Jan 8, 2021

You can connect multiple clients to a single session; one can be a QtConsole, the other a notebook. So there is no "correct" answer to the question, "what am I running in"? That's the main reason for this design. Usually you can implement an object with several repr*_ methods, and it will display the "best" one where it is, if it's displaying an object.

Just happened by and saw this, just about to play with Rich. :)

@aroberge
Copy link

aroberge commented Mar 7, 2021

I don't know if this information can be useful, so submitting just in case.

First: it looks like the QtConsole is rather limited in its ANSI escape sequences when printing from Python: jupyter/qtconsole#273

Still, it can print in colour.

I have been playing with Mu (https://codewith.mu/), an editor intended for beginners. Mu uses a Jupyter QtConsole for its REPL mode (but not when executing a program). I found out that I can print in colour but only until I import modules from Rich: afterwards, the colour escape sequences no longer seem to work.

I would get Rich processing (modulo the colour support) to work by using the force_jupyter=False option.

Here is some test code (in a file named "test.py"):

class style():
    RED = '\033[31m'
    GREEN = '\033[32m'
    RESET = '\033[0m'
    
print("Before importing Rich:", style.RED + "Hello", style.GREEN + "World!", style.RESET)

from rich.console import Console
from rich.markdown import Markdown
from rich.syntax import Syntax
print("After importing Rich:", style.RED + "Hello", style.GREEN + "World!", style.RESET)


console = Console(force_jupyter=False)

md_source = """
# This is an h1

**Rich** rendering of *markdown*.

1. This is a list item
2. This is another list item

(Python code using markdown removed)
"""
md = Markdown(md_source)
syn = Syntax("print('Hello world!'  # using Syntax)\n", "python")

console.print(md)
console.print(syn)

And the result:

mu_qtconsole

@willmcgugan
Copy link
Collaborator

I wonder if you would be able to get color with color_system="standard"

@aroberge
Copy link

aroberge commented Mar 7, 2021

No, it does not work. As mentioned, as soon as (one of) the import statement from rich is excuted, the ability to display colours is removed.

However, simply doing import rich does not disable colours.

@willmcgugan
Copy link
Collaborator

Is this on Windows? There is a frustrating issue with colorama, it will strip ansi codes if it doesn't think it is writing to a terminal, and it has global effect.

Could you try this:

import sys
console = Console(file=sys.__stdout__, force_jupyter=False)

@aroberge
Copy link

aroberge commented Mar 7, 2021 via email

@willmcgugan
Copy link
Collaborator

I think I know what's going on. I installed Mu to test.

In Mu sys.stdout.isatty() return False, which declares it is not a terminal. When colorama is imported via Rich, colorama calls isatty and helpfully removes all ANSI codes because it thinks it is writing to a file.

The trouble with colorama is that its a global setting. There's no way for Rich to override it. A solution would be to implement similar functionality within Rich console that I can selectively disable if necessary. Alas, that's a fairly big job and I'm reluctant to start it. Perhaps if I get corporate sponsorship...

@aroberge
Copy link

aroberge commented Mar 7, 2021

I have been playing with colorama.deinit() after importing modules from Rich, and doing colorama.init() with different options.
This seems to work after a fashion: the colour output is renabled when printing with ansi codes directly; italics in markdown are supported and the number for list items are in red (I don't know if this is supposed to be the case).

I'll play with it some more and see if I can get something to work.
image

@aroberge
Copy link

aroberge commented Mar 7, 2021

import colorama
from rich.console import Console
from rich.markdown import Markdown
from rich.syntax import Syntax

colorama.deinit()
colorama.init(convert=False, strip=False)
console = Console(force_jupyter=False, color_system="truecolor")
# same example as before follows

image

That's probably a work around which could be suggested to other QtConsole users on Windows. For my own purpose, I'll just need to change the theme.

@nathanrpage97
Copy link
Contributor

nathanrpage97 commented Mar 7, 2021

I think overriding JupyterRenderable.__repr__ with an unformatted version of the text is the best way to proceed. This would keep it in line with working across multiple clients as @henryiii mentioned. Users who would like it to work better in QTConsole can use some of these work arounds with the understanding it is not cross-client compatible.

@willmcgugan
Copy link
Collaborator

I've made some changes which I think should fix the qtconsole issue. I understand more about how the Jupyter protocol works now.

For anyone interested, please try v10.1.0

@willmcgugan
Copy link
Collaborator

Closing for now because I think it is fixed in v10.1.0.

@real-yfprojects

This comment has been minimized.

@willmcgugan
Copy link
Collaborator

Pypi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants