poetry icon indicating copy to clipboard operation
poetry copied to clipboard

`poetry shell` locks terminal width

Open kovasap opened this issue 4 years ago • 5 comments

  • [x] I am on the latest Poetry version.
  • [x] I have searched the issues of this repo and believe that this is not a duplicate.
  • [x] If an exception occurs when executing a command, I executed it again in debug mode (-vvv option).
  • OS version and name: Debian Linux
  • Poetry version: 1.1.6
  • Link of a Gist with the contents of your pyproject.toml file: Happens with multiple files, I don't think it's related.

Issue

When I run poetry shell I'm placed into a sub-shell with my virtualenv activated, as I'd expect. However, my terminal gets locked to it's current width. What I mean is that my shell prompt and any terminal-based program I used (e.g. vim) thinks that the terminal is always at the "locked" width. When I then resize the terminal, these program/UI elements bug out by either wrapping awkwardly if the terminal is resized smaller or not extending all the way when the terminal is resized larger. This happens in both bash and zsh.

Anyone else have this problem or have ideas for how to debug?

kovasap avatar May 31 '21 22:05 kovasap

Any ideas or similar problems in this space?

kovasap avatar Jun 11 '21 05:06 kovasap

I can confirm this bug- have debugged it as far as line 86 in poetry/utils/shell.py; the values returned by Terminal.width/height are incorrect because $COLUMNS and $LINES appear to be unset at the point where the width/height are called by resize().

GooseYArd avatar Jul 19 '21 14:07 GooseYArd

Hello, I think I've found where the problem could came from but this is the first time I've go deep in this lib and I'm not really sure about it.

def resize(sig: Any, data: Any) -> None:
    terminal = Terminal()
    # ---------
    # This private function forces refreshing the dimensions
    Terminal._init_dimensions() 
    # ---------
    c.setwinsize(terminal.height, terminal.width)

I've found that the library that handles the Terminal is caching the width/height once it's measured so the next times the sizes are recovered the values are the same as the previous time. I don't know if this happens in every terminal but in my current env it does.

I'm running: TMUX > ZSH > POETRY > NVIM (could be anything that uses term width, even tmux panes breaks after the first resize)

I don't like this solution at all because is a "private" function and the resize is a little slow (it's like there is a little delay while calculating the new size). Any other ideas from experts????

https://user-images.githubusercontent.com/3719730/162390017-bdefd45d-045a-4b9a-8641-ebfa4f1860d5.mov

josex2r avatar Apr 08 '22 07:04 josex2r

Thanks @josex2r — that looks promising!

Something i don't quite understand — what is role of the python part of this script? I have tried running just the source script, which adds environment variables — and everything seems to work, without mangling the $ROWS & $COLUMNS behavior.

max-sixty avatar Apr 08 '22 18:04 max-sixty

I got a similar issue when poetry shell on 1.2.0b3, but resizing for me is fine on 1.1.14.

OSX, iTerm2, zsh, poetry shell, then any terminal app -- even "pretty" shell prompts are affected

Kache avatar Aug 08 '22 19:08 Kache

The issue definitely seems more pronounced now when using projects that I've moved over to using Poetry 1.2.0. Tmux is routinely freaking out about the panes I'm creating when I'm in a poetry shell, but when I leave it all things return to normal.

I'm not sure if this helps, but I remember running into something similar a while ago when creating a script with python that uses expect to log into a remote host via SSH. Because the script technically didn't exit until I leave the remote host, I encountered issues because this sub-shell would be initialized with a width and height that couldn't change (like the issue being encountered here).

The way I resolved it in that instance was to do something like the following (which is called out in the docs link as well for pexpect):

# This method allows for the window to be resized without mucking up everything!
# Ref: https://pexpect.readthedocs.io/en/stable/api/pexpect.html#pexpect.spawn.interact
def sigwinch_passthrough(sig, data):
    current_win_cols, current_win_lines = os.get_terminal_size()
    # note how "child" is from what we spawned earlier.
    if not child.closed:
        child.setwinsize(current_win_lines, current_win_cols)

# ... later, just before calling `child.interact()` ...

# This makes it to that resizing isn't broken!
signal.signal(signal.SIGWINCH, sigwinch_passthrough)

child.interact()

TLDR - terminals are weird, subshells are weird.

macintacos avatar Sep 14 '22 04:09 macintacos

Dupe #6351

neersighted avatar Sep 14 '22 06:09 neersighted

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

github-actions[bot] avatar Mar 01 '24 10:03 github-actions[bot]