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

Clean up terminal width handling #9143

Merged
merged 3 commits into from Jul 22, 2020
Merged

Clean up terminal width handling #9143

merged 3 commits into from Jul 22, 2020

Conversation

The-Compiler
Copy link
Contributor

This PR does three related cleanups (cc'ing @ilevkivskyi who seems to have implemented most of the underlying code):


Use shutil.get_terminal_size()

The documentation for Python's os.get_terminal_size() says:

shutil.get_terminal_size() is the high-level function which should normally be used, os.get_terminal_size is the low-level implementation.

shutil.get_terminal_size() already takes care of various corner cases such as:

  • Providing a fallback (to 80 columns, like the current DEFAULT_COLUMNS)
  • Returning that fallback if os.get_terminal_size() raises OSError
  • Doing the same if it returns a size of 0

In addition to that:

  • It takes care of some more corner cases ("stdout is None, closed, detached, or not a terminal, or os.get_terminal_size() is unsupported")
  • It adds support for the COLUMNS environment variable (rather than the non-standard MYPY_FORCE_TERMINAL_WIDTH)

Move MYPY_FORCE_TERMINAL_WIDTH handling into get_terminal_width()

Those two callers are the only two, and both check MYPY_FORCE_TERMINAL_WIDTH before calling get_terminal_width().


Remove fixed_terminal_width from utils.colorize docstring

This was added by 91adf61, yet colorize() doesn't actually have a fixed_terminal_width argument.

This was added by 91adf61, yet colorize()
doesn't actually have a fixed_terminal_width argument.
Those two callers are the only two, and both check MYPY_FORCE_TERMINAL_WIDTH
before calling get_terminal_width().
The documentation for Python's os.get_terminal_size() says:

    shutil.get_terminal_size() is the high-level function which should normally
    be used, os.get_terminal_size is the low-level implementation.

https://docs.python.org/3/library/os.html#os.get_terminal_size

shutil.get_terminal_size() already takes care of various corner cases such as:

- Providing a fallback (to 80 columns, like the current DEFAULT_COLUMNS)
- Returning that fallback if os.get_terminal_size() raises OSError
- Doing the same if it returns a size of 0

In addition to that:

- It takes care of some more corner cases ("stdout is None, closed, detached, or
  not a terminal, or os.get_terminal_size() is unsupported")
- It adds support for the COLUMNS environment variable (rather than the
  non-standard MYPY_FORCE_TERMINAL_WIDTH)

https://github.com/python/cpython/blob/v3.8.3/Lib/shutil.py#L1298-L1341
Copy link
Member

@ilevkivskyi ilevkivskyi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@JukkaL JukkaL merged commit 0a8967c into python:master Jul 22, 2020
@The-Compiler The-Compiler deleted the terminal-width branch July 22, 2020 14:05
@asottile
Copy link
Contributor

this regressed 9dcccca

@The-Compiler
Copy link
Contributor Author

@asottile Can you elaborate? shutil.get_terminal_size handles this case and the test you added there seems to pass as well.

@asottile
Copy link
Contributor

handles this case

look carefully, it handles when os.get_terminal_size raises but not when it returns (0, 0)

and the test you added there seems to pass as well

nope

=================================== FAILURES ===================================
_______ TestGetTerminalSize.test_get_terminal_size_in_pty_defaults_to_80 _______
[gw0] linux -- Python 3.8.5 /tmp/mypy/venv/bin/python

self = <t.TestGetTerminalSize testMethod=test_get_terminal_size_in_pty_defaults_to_80>

    def test_get_terminal_size_in_pty_defaults_to_80(self) -> None:
        # when run using a pty, `os.get_terminal_size()` returns `0, 0`
        ret = os.terminal_size((0, 0))
        with mock.patch.object(os, 'get_terminal_size', return_value=ret):
>           assert get_terminal_width() == 80
E           AssertionError: assert 0 == 80
E            +  where 0 = get_terminal_width()

t.py:12: AssertionError
=========================== short test summary info ============================
FAILED t.py::TestGetTerminalSize::test_get_terminal_size_in_pty_defaults_to_80
============================== 1 failed in 0.50s ===============================

@asottile
Copy link
Contributor

note that the test never made it into master because it was "not useful" #8145

@The-Compiler
Copy link
Contributor Author

Well, I agree the test would've been useful 😉 I didn't catch that it indeed didn't end up being committed...

Seems to me like this should really be handled correctly in the stdlib by shutil.get_terminal_size. I can re-add the workaround to mypy, unless you're already on it.

@asottile
Copy link
Contributor

feel free

The-Compiler added a commit to The-Compiler/mypy that referenced this pull request Oct 27, 2020
Contrary to what I assumed in python#9143, shutil.get_terminal_size() doesn't
actually handle a 0 width from os.get_terminal_size() - it only handles
a 0 COLUMNS environment variable.

Thus, this caused python#8144 to regress.

This change re-adds and uses DEFAULT_COLUMNS and also adds the test
which was deemed unnecessary in python#8145 - this regression proves that I'd
have been a good idea to add it in the first place.
(Test written by Anthony Sottile)

Fixes https://github.com/pre-commit/mirrors-mypy/issues/29
@The-Compiler
Copy link
Contributor Author

Sorry for the trouble - here's a fix: #9651

JukkaL pushed a commit that referenced this pull request Oct 28, 2020
Contrary to what I assumed in #9143, shutil.get_terminal_size() doesn't
actually handle a 0 width from os.get_terminal_size() - it only handles
a 0 COLUMNS environment variable.

Thus, this caused #8144 to regress.

This change re-adds and uses DEFAULT_COLUMNS and also adds the test
which was deemed unnecessary in #8145 - this regression proves that I'd
have been a good idea to add it in the first place.
(Test written by Anthony Sottile)

Fixes https://github.com/pre-commit/mirrors-mypy/issues/29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants