Skip to content

mypy produces mangled output when run with a pty #8144

Closed
@asottile

Description

@asottile

version information:

$ mypy --version
mypy 0.750
$ python3 --version --version
Python 3.6.8 (default, Oct  7 2019, 12:59:55) 
[GCC 8.3.0]

test pty script:

import errno
import os
import subprocess
import sys

x: int = 'nope'


class Pty(object):
    def __init__(self):
        self.r = self.w = None

    def __enter__(self):
        self.r, self.w = os.openpty()

        return self

    def close_w(self):
        if self.w is not None:
            os.close(self.w)
            self.w = None

    def close_r(self):
        assert self.r is not None
        os.close(self.r)
        self.r = None

    def __exit__(self, exc_type, exc_value, traceback):
        self.close_w()
        self.close_r()


def cmd_output_p(*cmd, **kwargs):
    with open(os.devnull) as devnull, Pty() as pty:
        kwargs = {'stdin': devnull, 'stdout': pty.w, 'stderr': pty.w}
        proc = subprocess.Popen(cmd, **kwargs)
        pty.close_w()

        buf = b''
        while True:
            try:
                bts = os.read(pty.r, 4096)
            except OSError as e:
                if e.errno == errno.EIO:
                    bts = b''
                else:
                    raise
            else:
                buf += bts
            if not bts:
                break

    return proc.wait(), buf, None


_, buf, _ = cmd_output_p(*sys.argv[1:])
sys.stdout.buffer.write(buf)

Output:

$ python3 t.py mypy --pretty t.py
t.py:6: error:
Incompatible
types
in
assignment
(expression
has
type
"str",
variable
has
type
"int")
    x: int = 'nope'
             ^
Found 1 error in 1 file (checked 1 source file)

the output is colored (as expected) but has strange line breaks, almost like there's some wrapping logic that assumes the terminal is zero width or something (?)

Screenshot from 2019-12-13 12-03-53

Interestingly, the output appears correct when not using --pretty:

$ python3 t.py mypy t.py
t.py:6: error: Incompatible types in assignment (expression has type "str", variable has type "int")
Found 1 error in 1 file (checked 1 source file)

going a bit further, here's some info that potentially confirms my suspicion:

$ python3 t.py python3 -c 'import shutil; print(shutil.get_terminal_size())'
os.terminal_size(columns=0, lines=0)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions