JLab or IPython issue: inconsistency in IPython.display behavior between JLab and classic notebook or google colab?

I think this is a JLab issue not an IPython issue, but before filing it as an issue I wanted to check.

  1. In words: a call to IPython.display(XXX) within a function called within another function in a cell sends the display to the JLab console rather than the cell output. If the call to IPython.display(XXX) is at the root level of the cell then the display is sent to the cell output. Classic Jupyter and Google Colab send both calls of display to the cell’s output.
  2. Example code for testing:
from ipywidgets import Textarea, Layout, Button, HBox
from IPython.display import HTML, clear_output
oldtext = Textarea(
    layout = Layout(width = '98%', height = '150px'),
    value = 'Old text line 1.\nReplace this line.'
)
toHTMLbutton = Button(description = 'to HTML')

def ontoHTML(change):
    display(HTML('<details><summary>Text as HTML (click to toggle visibility)</summary><div style="white-space:pre-line;">'+oldtext.value+'</div></details>'))
    pass

toHTMLbutton.on_click(ontoHTML)
    
TST = HBox([oldtext,toHTMLbutton])
display(TST)

Edit the text in the box. Then click on the “to HTML” button. In JLab the collapsed <detail> element is sent to the console. In the other two cases it goes to the cell output, which is what I expected to happen.

  • Is this difference in behavior intentional?

  • Personally, I would prefer JLab to behave the way Colab and the Classic Notebook do. It is also more consistent with IPython in a terminal.

Jonathan

NB: This topic appears to be asking about similar behavior. There was no answer.

I can sort of answer my own question. This is a JLab issue for which there is a “sort of” workaround implemented in ipywidgets. This “sort of” solution is to wrap all the other widgets in another widget of type Output. Then call this new object in the code cell where you wish all the outputs to appear. This does make the output appear in the cell output rather than the console in JLab, but at the cost of the output being a widget. The downside for me is that if a notebook is not trusted or the widget state was not saved the user cannot see the output when they reopen a notebook. This is not good for my use case. I am trying to produce notebooks that are records of what was done that do not have to be rerun to see the results. The tools I have built using ipywidgets are designed to help the user write code based on the notebook state at the time they are running. These are primarily for analysis of data in pandas dataframes. See Jupyter Pandas GUI.

Code implementing the “sort of” fix as it is probably useful in other cases.

def wrapped():
    """
    Wraps widgets in an output
    """
    from IPython.display import HTML, clear_output
    from ipywidgets import Output, Textarea, Button, HBox
    output = Output()
    sometext = Textarea(
    layout = Layout(width = '98%', height = '150px'),
    value = 'Some old text'
    )
    toHTMLbutton = Button(description = 'to HTML')

    def ontoHTML(change):
        output.clear_output()
        with output:
            display(HTML('<details><summary>Text (click to toggle visibility)</summary><div>'+sometext.value+'</div></details>'))
            display(HTML('<h3>Result<h3>'))
        pass

    toHTMLbutton.on_click(ontoHTML)
    TST = HBox([sometext,toHTMLbutton])
    
    with output:
        display(TST)
    return output

wrapped()

I will not be implementing this solution as it makes things worse in Classic Notebooks and Google Colab. If I could easily tell the Python kernel that it was running in JLab and not Colab, I suppose I could turn this on for just JLab.

The other solution would be to rewrite these as completely custom widgets, but I have still not been able to work my way through all the extra overhead necessary for that. Any better ideas?

I am assuming because of the existence of this workaround that reporting this as an issue will not produce any interest in changing the way things work to be more consistent with the behavior of classic notebook and colab.

Thanks,
Jonathan

Keep in mind the JupyterLab-“way” is the direction things are heading in the open source Jupyter development. The next version of the classic notebook will be built on JupyterLab components.
I cannot comment on the Google Colab “branch”.

Hopefully others will be able to provide more concrete ways you could adapt your awesome tool for working with Pandas to be more consistent with the current tech.

1 Like