joouha / euporie

Jupyter notebooks in the terminal
https://euporie.readthedocs.io
MIT License
1.62k stars 38 forks source link

Exception 'TextArea' object has no attribute 'preferred_width' #12

Closed yingzhu146 closed 3 years ago

yingzhu146 commented 3 years ago

Trying to use the inline plotting, I'm using kitty.

Here's the code:

% matplotlib inline
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4])
plt.ylabel('some numbers')
plt.show()

This will immediately exit to the terminal and print the following strace

  File "/Users/yingzhu/miniconda3/envs/python38/lib/python3.8/site-packages/prompt_toolkit/layout/containers.py", line 716, in write_to_screen
    c.write_to_screen(
  File "/Users/yingzhu/miniconda3/envs/python38/lib/python3.8/site-packages/euporie/scroll.py", line 115, in write_to_screen
    self.to_draw = self.arrange_children(write_position)
  File "/Users/yingzhu/miniconda3/envs/python38/lib/python3.8/site-packages/euporie/scroll.py", line 426, in arrange_children
    size = self.get_child_size(i, refresh=True)
  File "/Users/yingzhu/miniconda3/envs/python38/lib/python3.8/site-packages/euporie/scroll.py", line 392, in get_child_size
    size = container.preferred_height(
  File "/Users/yingzhu/miniconda3/envs/python38/lib/python3.8/site-packages/prompt_toolkit/layout/containers.py", line 795, in preferred_height
    return self.content.preferred_height(width, max_available_height)
  File "/Users/yingzhu/miniconda3/envs/python38/lib/python3.8/site-packages/prompt_toolkit/layout/containers.py", line 325, in preferred_height
    dimensions = [
  File "/Users/yingzhu/miniconda3/envs/python38/lib/python3.8/site-packages/prompt_toolkit/layout/containers.py", line 326, in <listcomp>
    c.preferred_height(width, max_available_height) for c in self._all_children
  File "/Users/yingzhu/miniconda3/envs/python38/lib/python3.8/site-packages/prompt_toolkit/layout/containers.py", line 2625, in preferred_height
    return self.content.preferred_height(width, max_available_height)
  File "/Users/yingzhu/miniconda3/envs/python38/lib/python3.8/site-packages/prompt_toolkit/layout/containers.py", line 571, in preferred_height
    sizes = self._divide_widths(width)
  File "/Users/yingzhu/miniconda3/envs/python38/lib/python3.8/site-packages/prompt_toolkit/layout/containers.py", line 632, in _divide_widths
    dimensions = [c.preferred_width(width) for c in children]
  File "/Users/yingzhu/miniconda3/envs/python38/lib/python3.8/site-packages/prompt_toolkit/layout/containers.py", line 632, in <listcomp>
    dimensions = [c.preferred_width(width) for c in children]
  File "/Users/yingzhu/miniconda3/envs/python38/lib/python3.8/site-packages/prompt_toolkit/layout/containers.py", line 316, in preferred_width
    dimensions = [c.preferred_width(max_available_width) for c in self.children]
  File "/Users/yingzhu/miniconda3/envs/python38/lib/python3.8/site-packages/prompt_toolkit/layout/containers.py", line 316, in <listcomp>
    dimensions = [c.preferred_width(max_available_width) for c in self.children]
  File "/Users/yingzhu/miniconda3/envs/python38/lib/python3.8/site-packages/euporie/output.py", line 124, in preferred_width
    return self.content.preferred_width(*args, **kwargs)

Exception 'TextArea' object has no attribute 'preferred_width'

Some setup info:

❯ kitty --version
kitty 0.19.3 created by Kovid Goyal
❯ pip list | rg prompt-toolkit
prompt-toolkit                3.0.18
❯ pip list | rg matplot
matplotlib                    3.4.2
matplotlib-inline             0.1.2
❯ uname -a
Darwin MacBook-Air-4 20.3.0 Darwin Kernel Version 20.3.0: Mon Dec  7 22:03:58 PST 2020; root:xnu-7195.80.16.111.1~1/RELEASE_ARM64_T8101 arm64
❯ pip list | rg euporie
euporie                       0.1.9
❯ pip list | rg ipython
ipython                       7.16.0
ipython-genutils              0.2.0
ptipython                     1.0.1
❯ python --version
Python 3.8.6
yingzhu146 commented 3 years ago

For what it's worth: just tried to run using a direct install from master (0.1.11), didn't work either

yingzhu146 commented 3 years ago

This doesn't seem to be matplotlib related, the following causes the same error (works well in ipython)

from prompt_toolkit import print_formatted_text, HTML

print_formatted_text(HTML('<b>This is bold</b>'))
joouha commented 3 years ago

Hi,

I'm a bit surprised you were still experiencing this with 0.1.11, as after 76d78315507d3be34550ebc2c6ba76d8b24f4f40 TextArea is no longer used to display any outputs. Do you mind checking again you were actually using 0.1.11 or newer?

I've been working on fixing the display of ansi output containing carriage returns (which includes print_formatted_text output). A tentative fix for this is in 1d4884eddb8d275e01aaca9e4aafeb15092259a8.

The two code snippets you posted look currently give the following output with master in kitty terminal:

yingzhu146 commented 3 years ago

Yeah I mean I showed you the pip install output directly copy pasted so unless something with poetry is wonky it should've been 0.1.11.

I just tried to reinstall it (I have no experience with poetry, just doing poetry install), however I'm running into this:

https://github.com/python-poetry/poetry/issues/3628

I tried uninstalling poetry, and deleting the git project and reinstalling everything twice but to no avail so unfortunately I can help debug because I can't install euporie anymore and pip is still at 0.1.9.

joouha commented 3 years ago

Forgive me if I'm telling you what you already know.

It appears you might still have 0.1.9 installed on your main python distribution. To upgrade euporie to the latest version, you can run:

pip install --upgrade euporie

This should update euporie to 0.1.11 or later.


If you want to run euporie from master, you'll need to run something like:

git clone https://github.com/joouha/euporie.git
cd euporie
poetry install
poetry run euporie

Running poetry install from the cloned repo makes poetry install euporie as a development install (along with its dependencies) into a virtual environment, which is isolated from your system python installation. Running euporie without activating the virtual environment first will still run the version installed installed on your system distribution with pip.

You can run euporie from this virtual environment using poetry run euporie, or you can launch a shell with the virtual environment activated using poetry shell, and run euporie from there.

yingzhu146 commented 3 years ago

thanks a ton for the help with debugging here! We're making progress: so installing the new 0.1.11 from pip got rid of the error messages (I did however make sure that there is no 0.1.9 pip install in any of my envs before, however at time of my previous writing pip installs still installed 0.1.9 even for fresh installs, so now it's pulling correctly)

Now I'm not getting any errors, but also no outputs for the plotting

image

If you want to run euporie from master, you'll need to run something like:

git clone https://github.com/joouha/euporie.git
cd euporie
poetry install
poetry run euporie

Running poetry install from the cloned repo makes poetry install euporie as a development install (along with its dependencies) into a virtual environment, which is isolated from your system python installation. Running euporie without activating the virtual environment first will still run the version installed installed on your system distribution with pip.

You can run euporie from this virtual environment using poetry run euporie, or you can launch a shell with the virtual environment activated using poetry shell, and run euporie from there.

Thanks this is very helpful! However, unfortunately, like the issue I've linked, I can't run any poetry commands right now, even after wiping it from my system/fresh install. The linked issue mentiones potential to delete the cache folder fixing it, however, this cache isn't created on my machine (no ~/.cache/pypoetry or similar). There is osx specific caches in ~/Library/caches/pypoetry and I did try deleting that but to no avail). So unfortunately any poetry command (poetry show, poetry install right now results in

❯ poetry install

  TypeError

  expected string or bytes-like object

  at ~/.poetry/lib/poetry/_vendor/py3.8/poetry/core/utils/helpers.py:27 in canonicalize_name
       23│ _canonicalize_regex = re.compile(r"[-_]+")
       24│
       25│
       26│ def canonicalize_name(name):  # type: (str) -> str
    →  27│     return _canonicalize_regex.sub("-", name).lower()
       28│
       29│
       30│ def module_name(name):  # type: (str) -> str
       31│     return canonicalize_name(name).replace(".", "_").replace("-", "_")
❯ pwd
/Users/yingzhu_/euporie
joouha commented 3 years ago

If you install timg do you get ansi images when you try plotting?

You can install it as an optional dependency of euporie with:

pip install --upgrade euporie[images-timg]

Have you tried upgrading poetry? You appear to be running 1.10.0b or similar.

yingzhu146 commented 3 years ago

poetry is/was on 1.16 according to it's CLI. timg doesn't seem to help

image
yingzhu146 commented 3 years ago

I solved the poetry issue (was a package installed somehow with invalid metadata file). However, on the master branch's version of 0.1.12 the display issues still persist

joouha commented 3 years ago

I'm a bit perplexed!

This could be a bug with kitty image rendering. I know the way I have implemented kitty image rendering needs work. What version of kitty are you using? (Unfortunately I do not have access to a Mac).

If you create a cell with an image output then scroll so the cell is partially off-screen, do you see the image rendered as text?

Are you able to get text-mode image output in another terminal?

yingzhu146 commented 3 years ago

Using kitty 0.19.3

both timg and the matplotlib kitty backend work well

image

Again thanks a lot for helping debugging this.

wrt to Mac: I know a lot of co's use https://www.macstadium.com/ for their CI to test things.

yingzhu146 commented 3 years ago

Just noticed something odd - if I open a notebook that contains images, the images are displayed correctly.

2021-05-21 at 8 53 AM

and indeed, when i scroll it half off the page, they become text like

image
joouha commented 3 years ago

Interesting. Feels like we're getting closer!

The kitty graphics protocol allows you to do more complex things with images then sixel graphics, such as hide & show, duplicate, and move images. Currently I'm not making full use of it's capabilities - I'm just clearing all images from a notebook and re-drawing them every time the display is drawn.

I'm already aware of some issues with with the way I implemented this (one is that images are cleared per notebook, which means that if you have multiple notebooks, only the images from one notebook will be displayed). I suspect the problem you are having may be related.

Rewriting the euporie's kitty graphics code so images are shown, hidden, and moved without re-drawing them is on my to-do list.

joouha commented 3 years ago

The "colinear!" text you are seeing is OS-level standard error output from the kernel (reportlab prints directly to stderr in it's c-extensions - see here).

The same thing happens with JupyterLab - output is printed to the terminal where the kernel was started rather than being displayed in the notebook:

image

There is an old IPython issue about this I remember from years ago: https://github.com/ipython/ipython/issues/1230

The issue mentions a nice IPython extension wurlitzer you can use to work around this:

image

yingzhu146 commented 3 years ago

Yes I had realized that this actually occurs in other frontends as well (which is why I had deleted the comment). Thanks a lot this is super helpful though

yingzhu146 commented 3 years ago

@joouha I think this isn't a png specific issue btw - also occurs for svg's - just no output created when printing them.

image
joouha commented 3 years ago

The reason this occurs with SVGs is because euporie converts them to PNG format to render them.

Could you try upgrading to 0.1.14 and printing a notebook with the --dump command line flag? I'd be interested to see if you get image output.

yingzhu146 commented 3 years ago

Unfortunately doesn't

image
yingzhu146 commented 3 years ago

Also just updated kitty to 0.20.3, didn't help either :/

yingzhu146 commented 3 years ago

FYI @joouha - i finally had time to dig deeper here and now see where the opening of another NB with image works vs local fails. Appears to have something todo with the kernel's response. Here is the msg returned when executing a command

message {'header': {'msg_id': '7fb602e6-758acaed5578b6bb8bb27ea9_9', 'msg_type': 'status', 'username': 'yingzhu', 'session': '7fb602e6-758acaed5578b6bb8bb27ea9', 'date': datetime.datetime(2021, 6, 20, 4, 14, 13, 446180, tzinfo=tzutc()), 'version': '5.3'}, 'msg_id': '7fb602e6-758acaed5578b6bb8bb27ea9_9', 'msg_type': 'status', 'parent_header': {'msg_id': 'db07f97c-9ee867c0ccc2844ddf569eaa_1', 'msg_type': 'execute_request', 'username': 'yingzhu', 'session': 'db07f97c-9ee867c0ccc2844ddf569eaa', 'date': datetime.datetime(2021, 6, 20, 4, 14, 13, 413123, tzinfo=tzutc()), 'version': '5.3'}, 'metadata': {}, 'content': {'execution_state': 'busy'}, 'buffers': []}
message {'header': {'msg_id': '7fb602e6-758acaed5578b6bb8bb27ea9_10', 'msg_type': 'execute_input', 'username': 'yingzhu', 'session': '7fb602e6-758acaed5578b6bb8bb27ea9', 'date': datetime.datetime(2021, 6, 20, 4, 14, 13, 446630, tzinfo=tzutc()), 'version': '5.3'}, 'msg_id': '7fb602e6-758acaed5578b6bb8bb27ea9_10', 'msg_type': 'execute_input', 'parent_header': {'msg_id': 'db07f97c-9ee867c0ccc2844ddf569eaa_1', 'msg_type': 'execute_request', 'username': 'yingzhu', 'session': 'db07f97c-9ee867c0ccc2844ddf569eaa', 'date': datetime.datetime(2021, 6, 20, 4, 14, 13, 413123, tzinfo=tzutc()), 'version': '5.3'}, 'metadata': {}, 'content': {'code': "%matplotlib inline\nimport matplotlib.pyplot as plt\nplt.plot([1, 2, 3, 4])\nplt.ylabel('some numbers')\nplt.show()", 'execution_count': 2}, 'buffers': []}
message {'header': {'msg_id': '7fb602e6-758acaed5578b6bb8bb27ea9_12', 'msg_type': 'status', 'username': 'yingzhu', 'session': '7fb602e6-758acaed5578b6bb8bb27ea9', 'date': datetime.datetime(2021, 6, 20, 4, 14, 13, 491437, tzinfo=tzutc()), 'version': '5.3'}, 'msg_id': '7fb602e6-758acaed5578b6bb8bb27ea9_12', 'msg_type': 'status', 'parent_header': {'msg_id': 'db07f97c-9ee867c0ccc2844ddf569eaa_1', 'msg_type': 'execute_request', 'username': 'yingzhu', 'session': 'db07f97c-9ee867c0ccc2844ddf569eaa', 'date': datetime.datetime(2021, 6, 20, 4, 14, 13, 413123, tzinfo=tzutc()), 'version': '5.3'}, 'metadata': {}, 'content': {'execution_state': 'idle'}, 'buffers': []}

You can see that

        elif msg_type == "stream":
        elif msg_type in ("error", "display_data", "execute_result"):

are never hit so it'll never render.

I'm not too familiar w/ the jupyter message protocol but will debug further

yingzhu146 commented 3 years ago

Fixed it!

image

poetry made this extra difficult to debug as it had a lot of issues I never encountered with normal pip repos, ran into a lot of open issues on the repo, just my 2cents, you might want to consider to switch to pip (I appreciate the design decision of poetry and the problem it tries to solve, but in practice it didn't solve it for me while the conda/pip combo with pinned versions in requirements works good enough).

joouha commented 3 years ago

Awesome - I'm so pleased you fixed this!

What actually was the problem in the end?

yingzhu146 commented 3 years ago

realized that for pngs the ipykernel would not send the correct data for the mimetypes back - it would just choke and then switch to idle instead of sending the display data. If, however, I overwrote the handling by using IPython.display.Image(<myobj>._repr_png_) directly, it would work. Turned out that I had a custom matplotlib backend in my syspath that was loaded in my ipython_config I had put there months ago, which hijacked the rendering. removing that resolved the issue :)

On Mon, Jun 21, 2021 at 3:25 PM Josiah Outram Halstead < @.***> wrote:

Awesome - I'm so pleased you fixed this!

What actually was the problem in the end?

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/joouha/euporie/issues/12#issuecomment-865321296, or unsubscribe https://github.com/notifications/unsubscribe-auth/AOD5NN6P2XSRG5W7GGVAZIDTT6N2VANCNFSM446PAXZQ .