File: terminal.py

package info (click to toggle)
pytest-watcher 0.4.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 856 kB
  • sloc: python: 925; makefile: 28; sh: 13
file content (85 lines) | stat: -rw-r--r-- 2,090 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import abc
import logging
import os
import select
import sys
from typing import List, Optional

try:
    import termios
    import tty
except ImportError:
    pass


class Terminal(abc.ABC):
    def clear(self):
        pass

    def print(self, msg: str) -> None:
        pass

    def print_header(self, runner_args: List[str]):
        self.print(f"[pytest-watcher]\nCurrent runner args: [{' '.join(runner_args)}]")

    def print_short_menu(self, runner_args: List[str]) -> None:
        self.print_header(runner_args)
        self.print("\nPress w to show menu")

    def print_menu(self, runner_args: List[str]) -> None:
        from . import commands

        self.print_header(runner_args)
        self.print("\n\nControls:\n")

        for command in commands.Manager.list_commands():
            if command.show_in_menu:
                self.print(f"> {command.caption.ljust(5)} : {command.description}\n")

    def enter_capturing_mode(self) -> None:
        pass

    def capture_keystroke(self) -> Optional[str]:
        pass

    def reset(self) -> None:
        pass


class PosixTerminal(Terminal):
    def __init__(self) -> None:
        self._initial_state = termios.tcgetattr(sys.stdin.fileno())

    def print(self, msg: str) -> None:
        sys.stdout.write(msg)

    def clear(self) -> None:
        sys.stdout.write("\033c")
        sys.stdout.flush()

    def enter_capturing_mode(self) -> None:
        sys.stdin.flush()
        tty.setcbreak(sys.stdin.fileno())

    def capture_keystroke(self) -> Optional[str]:
        if select.select([sys.stdin], [], [], 0)[0]:
            return sys.stdin.read(1)
        return None

    def reset(self) -> None:
        termios.tcsetattr(sys.stdin, termios.TCSADRAIN, self._initial_state)


class DummyTerminal(Terminal):
    pass


def get_terminal() -> Terminal:
    if os.name == "posix":
        try:
            return PosixTerminal()
        except Exception:
            logging.exception(
                "Unable to initialize terminal state\nInteractive mode is disabled"
            )
    return DummyTerminal()