Skip to content

Commit

Permalink
Fix terminal size in tox commands (tox-dev#2999)
Browse files Browse the repository at this point in the history
  • Loading branch information
ziima committed Oct 17, 2023
1 parent 9ebcfef commit ff85f88
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/changelog/2999.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix terminal size of tox subcommands (fixes ipython, ipdb, prompt_toolkit, ...).
2 changes: 1 addition & 1 deletion src/tox/execute/local_sub_process/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ def _pty(key: str) -> tuple[int, int] | None:
# adjust sub-process terminal size
columns, lines = shutil.get_terminal_size(fallback=(-1, -1))
if columns != -1 and lines != -1:
size = struct.pack("HHHH", columns, lines, 0, 0)
size = struct.pack("HHHH", lines, columns, 0, 0)
fcntl.ioctl(child, termios.TIOCSWINSZ, size)

return main, child
Expand Down
32 changes: 32 additions & 0 deletions tests/execute/local_subprocess/test_local_subprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import json
import logging
import os
import pty
import shutil
import stat
import subprocess
Expand All @@ -19,6 +20,7 @@

from tox.execute.api import ExecuteOptions, Outcome
from tox.execute.local_sub_process import SIG_INTERRUPT, LocalSubProcessExecuteInstance, LocalSubProcessExecutor
from tox.execute.local_sub_process.read_via_thread_unix import ReadViaThreadUnix
from tox.execute.request import ExecuteRequest, StdinSource
from tox.execute.stream import SyncWrite
from tox.report import NamedBytesIO
Expand Down Expand Up @@ -140,6 +142,36 @@ def test_local_execute_write_a_lot(os_env: dict[str, str]) -> None:
assert outcome.err == expected_err, expected_err[len(outcome.err) :]


@pytest.mark.skipif(sys.platform == "win32", reason="Unix terminal size test")
def test_local_execute_terminal_size(os_env: dict[str, str], monkeypatch: MonkeyPatch) -> None:
"""Regression test for #2999 - check terminal size is set correctly in tox subprocess."""
terminal_size = os.terminal_size((int(os_env["COLUMNS"]), int(os_env["LINES"])))
main, child = pty.openpty()
# Use ReadViaThreadUnix to help with debugging the test itself.
with ReadViaThreadUnix(main, sys.stdout.buffer.write, name="testout", drain=True), monkeypatch.context() as monkey:
# Switch stdout with test pty
monkey.setattr(sys, "stdout", open(child, "w"))

executor = LocalSubProcessExecutor(colored=False)
request = ExecuteRequest(
cmd=[sys.executable, "-c", "import os; print(os.get_terminal_size())"],
cwd=Path(),
env=os_env,
stdin=StdinSource.OFF,
run_id="",
)
out_err = FakeOutErr()
with executor.call(request, show=False, out_err=out_err.out_err, env=MagicMock()) as status:
while status.exit_code is None: # pragma: no branch
status.wait()
outcome = status.outcome
assert outcome is not None
assert bool(outcome), outcome
expected_out = f"{terminal_size!r}\r\n"
assert outcome.out == expected_out, expected_out[len(outcome.out) :]
assert not outcome.err


def test_local_execute_basic_fail(capsys: CaptureFixture, caplog: LogCaptureFixture, monkeypatch: MonkeyPatch) -> None:
monkeypatch.chdir(Path(__file__).parents[3])
caplog.set_level(logging.NOTSET)
Expand Down

0 comments on commit ff85f88

Please sign in to comment.