diff --git a/dvc/dagascii.py b/dvc/dagascii.py index 8faa2c882..68db1601a 100644 --- a/dvc/dagascii.py +++ b/dvc/dagascii.py @@ -7,7 +7,7 @@ from grandalf.routing import route_with_lines, EdgeViewer class AsciiCanvas(object): - TIMEOUT = 1 + TIMEOUT = 10 def __init__(self, cols, lines): assert cols > 1 @@ -27,6 +27,7 @@ class AsciiCanvas(object): print(''.join(line)) def _do_draw(self, screen): # pragma: no cover + from dvc.system import System from asciimatics.event import KeyboardEvent offset_x = 0 @@ -66,12 +67,12 @@ class AsciiCanvas(object): # NOTE: get_event() doesn't block by itself, # so we have to do the blocking ourselves. # - # NOTE: using formally private method while waiting for PR [1] - # to get merged. After that need to adjust asciimatics version - # requirements. + # NOTE: using this workaround while waiting for PR [1] + # to get merged and released. After that need to adjust + # asciimatics version requirements. # # [1] https://github.com/peterbrittain/asciimatics/pull/188 - screen._wait_for_input(self.TIMEOUT) + System.wait_for_input(self.TIMEOUT) event = screen.get_event() if not isinstance(event, KeyboardEvent): diff --git a/dvc/system.py b/dvc/system.py index bd008217a..bba11fa1e 100644 --- a/dvc/system.py +++ b/dvc/system.py @@ -205,3 +205,38 @@ class System(object): assert inode >= 0 assert inode < 2**64 return inode + + @staticmethod + def _wait_for_input_windows(timeout): + import sys + import ctypes + import msvcrt + from ctypes.wintypes import DWORD, HANDLE + + # https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-waitforsingleobject + WAIT_OBJECT_0 = 0 + WAIT_TIMEOUT = 0x00000102 + + func = ctypes.windll.kernel32.WaitForSingleObject + func.argtypes = [HANDLE, DWORD] + func.restype = DWORD + + rc = func(msvcrt.get_osfhandle(sys.stdin.fileno()), timeout * 1000) + if rc not in [WAIT_OBJECT_0, WAIT_TIMEOUT]: + raise RuntimeError(rc) + + @staticmethod + def _wait_for_input_posix(timeout): + import sys + import select + try: + select.select([sys.stdin], [], [], timeout) + except select.error: + pass + + @staticmethod + def wait_for_input(timeout): + if System.is_unix(): + return System._wait_for_input_posix(timeout) + else: + return System._wait_for_input_windows(timeout) diff --git a/requirements.txt b/requirements.txt index daae76efe..a0922bbe0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,5 +22,5 @@ wheel>=0.31.1 futures>=3.2.0; python_version == "2.7" grandalf==0.6 pydot>=1.2.4 -asciimatics==1.10.0 +asciimatics>=1.10.0 distro>=1.3.0 diff --git a/setup.py b/setup.py index 7f4a5e307..708f83b5e 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ install_requires = [ "jsonpath-rw==1.4.0", "requests>=2.18.4", "grandalf==0.6", - "asciimatics==1.10.0", + "asciimatics>=1.10.0", "distro>=1.3.0", ]