diff options
author | monster <[email protected]> | 2022-07-07 14:41:37 +0300 |
---|---|---|
committer | monster <[email protected]> | 2022-07-07 14:41:37 +0300 |
commit | 06e5c21a835c0e923506c4ff27929f34e00761c2 (patch) | |
tree | 75efcbc6854ef9bd476eb8bf00cc5c900da436a2 /contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop | |
parent | 03f024c4412e3aa613bb543cf1660176320ba8f4 (diff) |
fix ya.make
Diffstat (limited to 'contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop')
12 files changed, 0 insertions, 1277 deletions
diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/__init__.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/__init__.py +++ /dev/null diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_base.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_base.py deleted file mode 100644 index ace2b8db497..00000000000 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_base.py +++ /dev/null @@ -1,46 +0,0 @@ -""" -Eventloop for integration with Python3 asyncio. - -Note that we can't use "yield from", because the package should be installable -under Python 2.6 as well, and it should contain syntactically valid Python 2.6 -code. -""" -from __future__ import unicode_literals - -__all__ = ( - 'AsyncioTimeout', -) - - -class AsyncioTimeout(object): - """ - Call the `timeout` function when the timeout expires. - Every call of the `reset` method, resets the timeout and starts a new - timer. - """ - def __init__(self, timeout, callback, loop): - self.timeout = timeout - self.callback = callback - self.loop = loop - - self.counter = 0 - self.running = True - - def reset(self): - """ - Reset the timeout. Starts a new timer. - """ - self.counter += 1 - local_counter = self.counter - - def timer_timeout(): - if self.counter == local_counter and self.running: - self.callback() - - self.loop.call_later(self.timeout, timer_timeout) - - def stop(self): - """ - Ignore timeout. Don't call the callback anymore. - """ - self.running = False diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_posix.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_posix.py deleted file mode 100644 index 426ed96f67d..00000000000 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_posix.py +++ /dev/null @@ -1,113 +0,0 @@ -""" -Posix asyncio event loop. -""" -from __future__ import unicode_literals - -from ..terminal.vt100_input import InputStream -from .asyncio_base import AsyncioTimeout -from .base import EventLoop, INPUT_TIMEOUT -from .callbacks import EventLoopCallbacks -from .posix_utils import PosixStdinReader - -import asyncio -import signal - -__all__ = ( - 'PosixAsyncioEventLoop', -) - - -class PosixAsyncioEventLoop(EventLoop): - def __init__(self, loop=None): - self.loop = loop or asyncio.get_event_loop() - self.closed = False - - self._stopped_f = asyncio.Future(loop=self.loop) - - @asyncio.coroutine - def run_as_coroutine(self, stdin, callbacks): - """ - The input 'event loop'. - """ - assert isinstance(callbacks, EventLoopCallbacks) - - # Create reader class. - stdin_reader = PosixStdinReader(stdin.fileno()) - - if self.closed: - raise Exception('Event loop already closed.') - - inputstream = InputStream(callbacks.feed_key) - - try: - # Create a new Future every time. - self._stopped_f = asyncio.Future(loop=self.loop) - - # Handle input timouts - def timeout_handler(): - """ - When no input has been received for INPUT_TIMEOUT seconds, - flush the input stream and fire the timeout event. - """ - inputstream.flush() - - callbacks.input_timeout() - - timeout = AsyncioTimeout(INPUT_TIMEOUT, timeout_handler, self.loop) - - # Catch sigwinch - def received_winch(): - self.call_from_executor(callbacks.terminal_size_changed) - - self.loop.add_signal_handler(signal.SIGWINCH, received_winch) - - # Read input data. - def stdin_ready(): - data = stdin_reader.read() - inputstream.feed(data) - timeout.reset() - - # Quit when the input stream was closed. - if stdin_reader.closed: - self.stop() - - self.loop.add_reader(stdin.fileno(), stdin_ready) - - # Block this coroutine until stop() has been called. - for f in self._stopped_f: - yield f - - finally: - # Clean up. - self.loop.remove_reader(stdin.fileno()) - self.loop.remove_signal_handler(signal.SIGWINCH) - - # Don't trigger any timeout events anymore. - timeout.stop() - - def stop(self): - # Trigger the 'Stop' future. - self._stopped_f.set_result(True) - - def close(self): - # Note: we should not close the asyncio loop itself, because that one - # was not created here. - self.closed = True - - def run_in_executor(self, callback): - self.loop.run_in_executor(None, callback) - - def call_from_executor(self, callback, _max_postpone_until=None): - """ - Call this function in the main event loop. - Similar to Twisted's ``callFromThread``. - """ - self.loop.call_soon_threadsafe(callback) - - def add_reader(self, fd, callback): - " Start watching the file descriptor for read availability. " - self.loop.add_reader(fd, callback) - - def remove_reader(self, fd): - " Stop watching the file descriptor for read availability. " - self.loop.remove_reader(fd) diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_win32.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_win32.py deleted file mode 100644 index 45f5f526798..00000000000 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_win32.py +++ /dev/null @@ -1,83 +0,0 @@ -""" -Win32 asyncio event loop. - -Windows notes: -- Somehow it doesn't seem to work with the 'ProactorEventLoop'. -""" -from __future__ import unicode_literals - -from .base import EventLoop, INPUT_TIMEOUT -from ..terminal.win32_input import ConsoleInputReader -from .callbacks import EventLoopCallbacks -from .asyncio_base import AsyncioTimeout - -import asyncio - -__all__ = ( - 'Win32AsyncioEventLoop', -) - - -class Win32AsyncioEventLoop(EventLoop): - def __init__(self, loop=None): - self._console_input_reader = ConsoleInputReader() - self.running = False - self.closed = False - self.loop = loop or asyncio.get_event_loop() - - @asyncio.coroutine - def run_as_coroutine(self, stdin, callbacks): - """ - The input 'event loop'. - """ - # Note: We cannot use "yield from", because this package also - # installs on Python 2. - assert isinstance(callbacks, EventLoopCallbacks) - - if self.closed: - raise Exception('Event loop already closed.') - - timeout = AsyncioTimeout(INPUT_TIMEOUT, callbacks.input_timeout, self.loop) - self.running = True - - try: - while self.running: - timeout.reset() - - # Get keys - try: - g = iter(self.loop.run_in_executor(None, self._console_input_reader.read)) - while True: - yield next(g) - except StopIteration as e: - keys = e.args[0] - - # Feed keys to input processor. - for k in keys: - callbacks.feed_key(k) - finally: - timeout.stop() - - def stop(self): - self.running = False - - def close(self): - # Note: we should not close the asyncio loop itself, because that one - # was not created here. - self.closed = True - - self._console_input_reader.close() - - def run_in_executor(self, callback): - self.loop.run_in_executor(None, callback) - - def call_from_executor(self, callback, _max_postpone_until=None): - self.loop.call_soon_threadsafe(callback) - - def add_reader(self, fd, callback): - " Start watching the file descriptor for read availability. " - self.loop.add_reader(fd, callback) - - def remove_reader(self, fd): - " Stop watching the file descriptor for read availability. " - self.loop.remove_reader(fd) diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/base.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/base.py deleted file mode 100644 index db86face668..00000000000 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/base.py +++ /dev/null @@ -1,85 +0,0 @@ -from __future__ import unicode_literals -from abc import ABCMeta, abstractmethod -from six import with_metaclass - -__all__ = ( - 'EventLoop', - 'INPUT_TIMEOUT', -) - - -#: When to trigger the `onInputTimeout` event. -INPUT_TIMEOUT = .5 - - -class EventLoop(with_metaclass(ABCMeta, object)): - """ - Eventloop interface. - """ - def run(self, stdin, callbacks): - """ - Run the eventloop until stop() is called. Report all - input/timeout/terminal-resize events to the callbacks. - - :param stdin: :class:`~prompt_toolkit.input.Input` instance. - :param callbacks: :class:`~prompt_toolkit.eventloop.callbacks.EventLoopCallbacks` instance. - """ - raise NotImplementedError("This eventloop doesn't implement synchronous 'run()'.") - - def run_as_coroutine(self, stdin, callbacks): - """ - Similar to `run`, but this is a coroutine. (For asyncio integration.) - """ - raise NotImplementedError("This eventloop doesn't implement 'run_as_coroutine()'.") - - @abstractmethod - def stop(self): - """ - Stop the `run` call. (Normally called by - :class:`~prompt_toolkit.interface.CommandLineInterface`, when a result - is available, or Abort/Quit has been called.) - """ - - @abstractmethod - def close(self): - """ - Clean up of resources. Eventloop cannot be reused a second time after - this call. - """ - - @abstractmethod - def add_reader(self, fd, callback): - """ - Start watching the file descriptor for read availability and then call - the callback. - """ - - @abstractmethod - def remove_reader(self, fd): - """ - Stop watching the file descriptor for read availability. - """ - - @abstractmethod - def run_in_executor(self, callback): - """ - Run a long running function in a background thread. (This is - recommended for code that could block the event loop.) - Similar to Twisted's ``deferToThread``. - """ - - @abstractmethod - def call_from_executor(self, callback, _max_postpone_until=None): - """ - Call this function in the main event loop. Similar to Twisted's - ``callFromThread``. - - :param _max_postpone_until: `None` or `time.time` value. For interal - use. If the eventloop is saturated, consider this task to be low - priority and postpone maximum until this timestamp. (For instance, - repaint is done using low priority.) - - Note: In the past, this used to be a datetime.datetime instance, - but apparently, executing `time.time` is more efficient: it - does fewer system calls. (It doesn't read /etc/localtime.) - """ diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/callbacks.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/callbacks.py deleted file mode 100644 index 04adab6fd49..00000000000 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/callbacks.py +++ /dev/null @@ -1,29 +0,0 @@ -from __future__ import unicode_literals -from abc import ABCMeta, abstractmethod -from six import with_metaclass - -__all__ = ( - 'EventLoopCallbacks', -) - - -class EventLoopCallbacks(with_metaclass(ABCMeta, object)): - """ - This is the glue between the :class:`~prompt_toolkit.eventloop.base.EventLoop` - and :class:`~prompt_toolkit.interface.CommandLineInterface`. - - :meth:`~prompt_toolkit.eventloop.base.EventLoop.run` takes an - :class:`.EventLoopCallbacks` instance and operates on that one, driving the - interface. - """ - @abstractmethod - def terminal_size_changed(self): - pass - - @abstractmethod - def input_timeout(self): - pass - - @abstractmethod - def feed_key(self, key): - pass diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/inputhook.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/inputhook.py deleted file mode 100644 index bab1f4c003a..00000000000 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/inputhook.py +++ /dev/null @@ -1,107 +0,0 @@ -""" -Similar to `PyOS_InputHook` of the Python API. Some eventloops can have an -inputhook to allow easy integration with other event loops. - -When the eventloop of prompt-toolkit is idle, it can call such a hook. This -hook can call another eventloop that runs for a short while, for instance to -keep a graphical user interface responsive. - -It's the responsibility of this hook to exit when there is input ready. -There are two ways to detect when input is ready: - -- Call the `input_is_ready` method periodically. Quit when this returns `True`. - -- Add the `fileno` as a watch to the external eventloop. Quit when file descriptor - becomes readable. (But don't read from it.) - - Note that this is not the same as checking for `sys.stdin.fileno()`. The - eventloop of prompt-toolkit allows thread-based executors, for example for - asynchronous autocompletion. When the completion for instance is ready, we - also want prompt-toolkit to gain control again in order to display that. - -An alternative to using input hooks, is to create a custom `EventLoop` class that -controls everything. -""" -from __future__ import unicode_literals -import os -import threading -from prompt_toolkit.utils import is_windows -from .select import select_fds - -__all__ = ( - 'InputHookContext', -) - - -class InputHookContext(object): - """ - Given as a parameter to the inputhook. - """ - def __init__(self, inputhook): - assert callable(inputhook) - - self.inputhook = inputhook - self._input_is_ready = None - - self._r, self._w = os.pipe() - - def input_is_ready(self): - """ - Return True when the input is ready. - """ - return self._input_is_ready(wait=False) - - def fileno(self): - """ - File descriptor that will become ready when the event loop needs to go on. - """ - return self._r - - def call_inputhook(self, input_is_ready_func): - """ - Call the inputhook. (Called by a prompt-toolkit eventloop.) - """ - self._input_is_ready = input_is_ready_func - - # Start thread that activates this pipe when there is input to process. - def thread(): - input_is_ready_func(wait=True) - os.write(self._w, b'x') - - threading.Thread(target=thread).start() - - # Call inputhook. - self.inputhook(self) - - # Flush the read end of the pipe. - try: - # Before calling 'os.read', call select.select. This is required - # when the gevent monkey patch has been applied. 'os.read' is never - # monkey patched and won't be cooperative, so that would block all - # other select() calls otherwise. - # See: http://www.gevent.org/gevent.os.html - - # Note: On Windows, this is apparently not an issue. - # However, if we would ever want to add a select call, it - # should use `windll.kernel32.WaitForMultipleObjects`, - # because `select.select` can't wait for a pipe on Windows. - if not is_windows(): - select_fds([self._r], timeout=None) - - os.read(self._r, 1024) - except OSError: - # This happens when the window resizes and a SIGWINCH was received. - # We get 'Error: [Errno 4] Interrupted system call' - # Just ignore. - pass - self._input_is_ready = None - - def close(self): - """ - Clean up resources. - """ - if self._r: - os.close(self._r) - os.close(self._w) - - self._r = self._w = None diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/posix.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/posix.py deleted file mode 100644 index f631dbd8915..00000000000 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/posix.py +++ /dev/null @@ -1,306 +0,0 @@ -from __future__ import unicode_literals -import fcntl -import os -import signal -import threading -import time - -from prompt_toolkit.terminal.vt100_input import InputStream -from prompt_toolkit.utils import DummyContext, in_main_thread -from prompt_toolkit.input import Input -from .base import EventLoop, INPUT_TIMEOUT -from .callbacks import EventLoopCallbacks -from .inputhook import InputHookContext -from .posix_utils import PosixStdinReader -from .utils import TimeIt -from .select import AutoSelector, Selector, fd_to_int - -__all__ = ( - 'PosixEventLoop', -) - -_now = time.time - - -class PosixEventLoop(EventLoop): - """ - Event loop for posix systems (Linux, Mac os X). - """ - def __init__(self, inputhook=None, selector=AutoSelector): - assert inputhook is None or callable(inputhook) - assert issubclass(selector, Selector) - - self.running = False - self.closed = False - self._running = False - self._callbacks = None - - self._calls_from_executor = [] - self._read_fds = {} # Maps fd to handler. - self.selector = selector() - - # Create a pipe for inter thread communication. - self._schedule_pipe = os.pipe() - fcntl.fcntl(self._schedule_pipe[0], fcntl.F_SETFL, os.O_NONBLOCK) - - # Create inputhook context. - self._inputhook_context = InputHookContext(inputhook) if inputhook else None - - def run(self, stdin, callbacks): - """ - The input 'event loop'. - """ - assert isinstance(stdin, Input) - assert isinstance(callbacks, EventLoopCallbacks) - assert not self._running - - if self.closed: - raise Exception('Event loop already closed.') - - self._running = True - self._callbacks = callbacks - - inputstream = InputStream(callbacks.feed_key) - current_timeout = [INPUT_TIMEOUT] # Nonlocal - - # Create reader class. - stdin_reader = PosixStdinReader(stdin.fileno()) - - # Only attach SIGWINCH signal handler in main thread. - # (It's not possible to attach signal handlers in other threads. In - # that case we should rely on a the main thread to call this manually - # instead.) - if in_main_thread(): - ctx = call_on_sigwinch(self.received_winch) - else: - ctx = DummyContext() - - def read_from_stdin(): - " Read user input. " - # Feed input text. - data = stdin_reader.read() - inputstream.feed(data) - - # Set timeout again. - current_timeout[0] = INPUT_TIMEOUT - - # Quit when the input stream was closed. - if stdin_reader.closed: - self.stop() - - self.add_reader(stdin, read_from_stdin) - self.add_reader(self._schedule_pipe[0], None) - - with ctx: - while self._running: - # Call inputhook. - if self._inputhook_context: - with TimeIt() as inputhook_timer: - def ready(wait): - " True when there is input ready. The inputhook should return control. " - return self._ready_for_reading(current_timeout[0] if wait else 0) != [] - self._inputhook_context.call_inputhook(ready) - inputhook_duration = inputhook_timer.duration - else: - inputhook_duration = 0 - - # Calculate remaining timeout. (The inputhook consumed some of the time.) - if current_timeout[0] is None: - remaining_timeout = None - else: - remaining_timeout = max(0, current_timeout[0] - inputhook_duration) - - # Wait until input is ready. - fds = self._ready_for_reading(remaining_timeout) - - # When any of the FDs are ready. Call the appropriate callback. - if fds: - # Create lists of high/low priority tasks. The main reason - # for this is to allow painting the UI to happen as soon as - # possible, but when there are many events happening, we - # don't want to call the UI renderer 1000x per second. If - # the eventloop is completely saturated with many CPU - # intensive tasks (like processing input/output), we say - # that drawing the UI can be postponed a little, to make - # CPU available. This will be a low priority task in that - # case. - tasks = [] - low_priority_tasks = [] - now = None # Lazy load time. (Fewer system calls.) - - for fd in fds: - # For the 'call_from_executor' fd, put each pending - # item on either the high or low priority queue. - if fd == self._schedule_pipe[0]: - for c, max_postpone_until in self._calls_from_executor: - if max_postpone_until is None: - # Execute now. - tasks.append(c) - else: - # Execute soon, if `max_postpone_until` is in the future. - now = now or _now() - if max_postpone_until < now: - tasks.append(c) - else: - low_priority_tasks.append((c, max_postpone_until)) - self._calls_from_executor = [] - - # Flush all the pipe content. - os.read(self._schedule_pipe[0], 1024) - else: - handler = self._read_fds.get(fd) - if handler: - tasks.append(handler) - - # When there are high priority tasks, run all these. - # Schedule low priority tasks for the next iteration. - if tasks: - for t in tasks: - t() - - # Postpone low priority tasks. - for t, max_postpone_until in low_priority_tasks: - self.call_from_executor(t, _max_postpone_until=max_postpone_until) - else: - # Currently there are only low priority tasks -> run them right now. - for t, _ in low_priority_tasks: - t() - - else: - # Flush all pending keys on a timeout. (This is most - # important to flush the vt100 'Escape' key early when - # nothing else follows.) - inputstream.flush() - - # Fire input timeout event. - callbacks.input_timeout() - current_timeout[0] = None - - self.remove_reader(stdin) - self.remove_reader(self._schedule_pipe[0]) - - self._callbacks = None - - def _ready_for_reading(self, timeout=None): - """ - Return the file descriptors that are ready for reading. - """ - fds = self.selector.select(timeout) - return fds - - def received_winch(self): - """ - Notify the event loop that SIGWINCH has been received - """ - # Process signal asynchronously, because this handler can write to the - # output, and doing this inside the signal handler causes easily - # reentrant calls, giving runtime errors.. - - # Furthur, this has to be thread safe. When the CommandLineInterface - # runs not in the main thread, this function still has to be called - # from the main thread. (The only place where we can install signal - # handlers.) - def process_winch(): - if self._callbacks: - self._callbacks.terminal_size_changed() - - self.call_from_executor(process_winch) - - def run_in_executor(self, callback): - """ - Run a long running function in a background thread. - (This is recommended for code that could block the event loop.) - Similar to Twisted's ``deferToThread``. - """ - # Wait until the main thread is idle. - # We start the thread by using `call_from_executor`. The event loop - # favours processing input over `calls_from_executor`, so the thread - # will not start until there is no more input to process and the main - # thread becomes idle for an instant. This is good, because Python - # threading favours CPU over I/O -- an autocompletion thread in the - # background would cause a significantly slow down of the main thread. - # It is mostly noticable when pasting large portions of text while - # having real time autocompletion while typing on. - def start_executor(): - threading.Thread(target=callback).start() - self.call_from_executor(start_executor) - - def call_from_executor(self, callback, _max_postpone_until=None): - """ - Call this function in the main event loop. - Similar to Twisted's ``callFromThread``. - - :param _max_postpone_until: `None` or `time.time` value. For interal - use. If the eventloop is saturated, consider this task to be low - priority and postpone maximum until this timestamp. (For instance, - repaint is done using low priority.) - """ - assert _max_postpone_until is None or isinstance(_max_postpone_until, float) - self._calls_from_executor.append((callback, _max_postpone_until)) - - if self._schedule_pipe: - try: - os.write(self._schedule_pipe[1], b'x') - except (AttributeError, IndexError, OSError): - # Handle race condition. We're in a different thread. - # - `_schedule_pipe` could have become None in the meantime. - # - We catch `OSError` (actually BrokenPipeError), because the - # main thread could have closed the pipe already. - pass - - def stop(self): - """ - Stop the event loop. - """ - self._running = False - - def close(self): - self.closed = True - - # Close pipes. - schedule_pipe = self._schedule_pipe - self._schedule_pipe = None - - if schedule_pipe: - os.close(schedule_pipe[0]) - os.close(schedule_pipe[1]) - - if self._inputhook_context: - self._inputhook_context.close() - - def add_reader(self, fd, callback): - " Add read file descriptor to the event loop. " - fd = fd_to_int(fd) - self._read_fds[fd] = callback - self.selector.register(fd) - - def remove_reader(self, fd): - " Remove read file descriptor from the event loop. " - fd = fd_to_int(fd) - - if fd in self._read_fds: - del self._read_fds[fd] - - self.selector.unregister(fd) - - -class call_on_sigwinch(object): - """ - Context manager which Installs a SIGWINCH callback. - (This signal occurs when the terminal size changes.) - """ - def __init__(self, callback): - self.callback = callback - self.previous_callback = None - - def __enter__(self): - self.previous_callback = signal.signal(signal.SIGWINCH, lambda *a: self.callback()) - - def __exit__(self, *a, **kw): - if self.previous_callback is None: - # Normally, `signal.signal` should never return `None`. - # For some reason it happens here: - # https://github.com/jonathanslenders/python-prompt-toolkit/pull/174 - signal.signal(signal.SIGWINCH, 0) - else: - signal.signal(signal.SIGWINCH, self.previous_callback) diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/posix_utils.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/posix_utils.py deleted file mode 100644 index 320df438ca2..00000000000 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/posix_utils.py +++ /dev/null @@ -1,82 +0,0 @@ -from __future__ import unicode_literals - -from codecs import getincrementaldecoder -import os -import six - -__all__ = ( - 'PosixStdinReader', -) - - -class PosixStdinReader(object): - """ - Wrapper around stdin which reads (nonblocking) the next available 1024 - bytes and decodes it. - - Note that you can't be sure that the input file is closed if the ``read`` - function returns an empty string. When ``errors=ignore`` is passed, - ``read`` can return an empty string if all malformed input was replaced by - an empty string. (We can't block here and wait for more input.) So, because - of that, check the ``closed`` attribute, to be sure that the file has been - closed. - - :param stdin_fd: File descriptor from which we read. - :param errors: Can be 'ignore', 'strict' or 'replace'. - On Python3, this can be 'surrogateescape', which is the default. - - 'surrogateescape' is preferred, because this allows us to transfer - unrecognised bytes to the key bindings. Some terminals, like lxterminal - and Guake, use the 'Mxx' notation to send mouse events, where each 'x' - can be any possible byte. - """ - # By default, we want to 'ignore' errors here. The input stream can be full - # of junk. One occurrence of this that I had was when using iTerm2 on OS X, - # with "Option as Meta" checked (You should choose "Option as +Esc".) - - def __init__(self, stdin_fd, - errors=('ignore' if six.PY2 else 'surrogateescape')): - assert isinstance(stdin_fd, int) - self.stdin_fd = stdin_fd - self.errors = errors - - # Create incremental decoder for decoding stdin. - # We can not just do `os.read(stdin.fileno(), 1024).decode('utf-8')`, because - # it could be that we are in the middle of a utf-8 byte sequence. - self._stdin_decoder_cls = getincrementaldecoder('utf-8') - self._stdin_decoder = self._stdin_decoder_cls(errors=errors) - - #: True when there is nothing anymore to read. - self.closed = False - - def read(self, count=1024): - # By default we choose a rather small chunk size, because reading - # big amounts of input at once, causes the event loop to process - # all these key bindings also at once without going back to the - # loop. This will make the application feel unresponsive. - """ - Read the input and return it as a string. - - Return the text. Note that this can return an empty string, even when - the input stream was not yet closed. This means that something went - wrong during the decoding. - """ - if self.closed: - return b'' - - # Note: the following works better than wrapping `self.stdin` like - # `codecs.getreader('utf-8')(stdin)` and doing `read(1)`. - # Somehow that causes some latency when the escape - # character is pressed. (Especially on combination with the `select`.) - try: - data = os.read(self.stdin_fd, count) - - # Nothing more to read, stream is closed. - if data == b'': - self.closed = True - return '' - except OSError: - # In case of SIGWINCH - data = b'' - - return self._stdin_decoder.decode(data) diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/select.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/select.py deleted file mode 100644 index f678f84c557..00000000000 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/select.py +++ /dev/null @@ -1,216 +0,0 @@ -""" -Selectors for the Posix event loop. -""" -from __future__ import unicode_literals, absolute_import -import sys -import abc -import errno -import select -import six - -__all__ = ( - 'AutoSelector', - 'PollSelector', - 'SelectSelector', - 'Selector', - 'fd_to_int', -) - -def fd_to_int(fd): - assert isinstance(fd, int) or hasattr(fd, 'fileno') - - if isinstance(fd, int): - return fd - else: - return fd.fileno() - - -class Selector(six.with_metaclass(abc.ABCMeta, object)): - @abc.abstractmethod - def register(self, fd): - assert isinstance(fd, int) - - @abc.abstractmethod - def unregister(self, fd): - assert isinstance(fd, int) - - @abc.abstractmethod - def select(self, timeout): - pass - - @abc.abstractmethod - def close(self): - pass - - -class AutoSelector(Selector): - def __init__(self): - self._fds = [] - - self._select_selector = SelectSelector() - self._selectors = [self._select_selector] - - # When 'select.poll' exists, create a PollSelector. - if hasattr(select, 'poll'): - self._poll_selector = PollSelector() - self._selectors.append(self._poll_selector) - else: - self._poll_selector = None - - # Use of the 'select' module, that was introduced in Python3.4. We don't - # use it before 3.5 however, because this is the point where this module - # retries interrupted system calls. - if sys.version_info >= (3, 5): - self._py3_selector = Python3Selector() - self._selectors.append(self._py3_selector) - else: - self._py3_selector = None - - def register(self, fd): - assert isinstance(fd, int) - - self._fds.append(fd) - - for sel in self._selectors: - sel.register(fd) - - def unregister(self, fd): - assert isinstance(fd, int) - - self._fds.remove(fd) - - for sel in self._selectors: - sel.unregister(fd) - - def select(self, timeout): - # Try Python 3 selector first. - if self._py3_selector: - try: - return self._py3_selector.select(timeout) - except PermissionError: - # We had a situation (in pypager) where epoll raised a - # PermissionError when a local file descriptor was registered, - # however poll and select worked fine. So, in that case, just - # try using select below. - pass - - try: - # Prefer 'select.select', if we don't have much file descriptors. - # This is more universal. - return self._select_selector.select(timeout) - except ValueError: - # When we have more than 1024 open file descriptors, we'll always - # get a "ValueError: filedescriptor out of range in select()" for - # 'select'. In this case, try, using 'poll' instead. - if self._poll_selector is not None: - return self._poll_selector.select(timeout) - else: - raise - - def close(self): - for sel in self._selectors: - sel.close() - - -class Python3Selector(Selector): - """ - Use of the Python3 'selectors' module. - - NOTE: Only use on Python 3.5 or newer! - """ - def __init__(self): - assert sys.version_info >= (3, 5) - - import selectors # Inline import: Python3 only! - self._sel = selectors.DefaultSelector() - - def register(self, fd): - assert isinstance(fd, int) - import selectors # Inline import: Python3 only! - self._sel.register(fd, selectors.EVENT_READ, None) - - def unregister(self, fd): - assert isinstance(fd, int) - self._sel.unregister(fd) - - def select(self, timeout): - events = self._sel.select(timeout=timeout) - return [key.fileobj for key, mask in events] - - def close(self): - self._sel.close() - - -class PollSelector(Selector): - def __init__(self): - self._poll = select.poll() - - def register(self, fd): - assert isinstance(fd, int) - self._poll.register(fd, select.POLLIN) - - def unregister(self, fd): - assert isinstance(fd, int) - - def select(self, timeout): - tuples = self._poll.poll(timeout) # Returns (fd, event) tuples. - return [t[0] for t in tuples] - - def close(self): - pass # XXX - - -class SelectSelector(Selector): - """ - Wrapper around select.select. - - When the SIGWINCH signal is handled, other system calls, like select - are aborted in Python. This wrapper will retry the system call. - """ - def __init__(self): - self._fds = [] - - def register(self, fd): - self._fds.append(fd) - - def unregister(self, fd): - self._fds.remove(fd) - - def select(self, timeout): - while True: - try: - return select.select(self._fds, [], [], timeout)[0] - except select.error as e: - # Retry select call when EINTR - if e.args and e.args[0] == errno.EINTR: - continue - else: - raise - - def close(self): - pass - - -def select_fds(read_fds, timeout, selector=AutoSelector): - """ - Wait for a list of file descriptors (`read_fds`) to become ready for - reading. This chooses the most appropriate select-tool for use in - prompt-toolkit. - """ - # Map to ensure that we return the objects that were passed in originally. - # Whether they are a fd integer or an object that has a fileno(). - # (The 'poll' implementation for instance, returns always integers.) - fd_map = dict((fd_to_int(fd), fd) for fd in read_fds) - - # Wait, using selector. - sel = selector() - try: - for fd in read_fds: - sel.register(fd) - - result = sel.select(timeout) - - if result is not None: - return [fd_map[fd_to_int(fd)] for fd in result] - finally: - sel.close() diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/utils.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/utils.py deleted file mode 100644 index ff3a4cfd697..00000000000 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/utils.py +++ /dev/null @@ -1,23 +0,0 @@ -from __future__ import unicode_literals -import time - -__all__ = ( - 'TimeIt', -) - - -class TimeIt(object): - """ - Context manager that times the duration of the code body. - The `duration` attribute will contain the execution time in seconds. - """ - def __init__(self): - self.duration = None - - def __enter__(self): - self.start = time.time() - return self - - def __exit__(self, *args): - self.end = time.time() - self.duration = self.end - self.start diff --git a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/win32.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/win32.py deleted file mode 100644 index 18e356f0882..00000000000 --- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/win32.py +++ /dev/null @@ -1,187 +0,0 @@ -""" -Win32 event loop. - -Windows notes: - - Somehow it doesn't seem to work with the 'ProactorEventLoop'. -""" -from __future__ import unicode_literals - -from ..terminal.win32_input import ConsoleInputReader -from ..win32_types import SECURITY_ATTRIBUTES -from .base import EventLoop, INPUT_TIMEOUT -from .inputhook import InputHookContext -from .utils import TimeIt - -from ctypes import windll, pointer -from ctypes.wintypes import DWORD, BOOL, HANDLE - -import msvcrt -import threading - -__all__ = ( - 'Win32EventLoop', -) - -WAIT_TIMEOUT = 0x00000102 -INPUT_TIMEOUT_MS = int(1000 * INPUT_TIMEOUT) - - -class Win32EventLoop(EventLoop): - """ - Event loop for Windows systems. - - :param recognize_paste: When True, try to discover paste actions and turn - the event into a BracketedPaste. - """ - def __init__(self, inputhook=None, recognize_paste=True): - assert inputhook is None or callable(inputhook) - - self._event = HANDLE(_create_event()) - self._console_input_reader = ConsoleInputReader(recognize_paste=recognize_paste) - self._calls_from_executor = [] - - self.closed = False - self._running = False - - # Additional readers. - self._read_fds = {} # Maps fd to handler. - - # Create inputhook context. - self._inputhook_context = InputHookContext(inputhook) if inputhook else None - - def run(self, stdin, callbacks): - if self.closed: - raise Exception('Event loop already closed.') - - current_timeout = INPUT_TIMEOUT_MS - self._running = True - - while self._running: - # Call inputhook. - with TimeIt() as inputhook_timer: - if self._inputhook_context: - def ready(wait): - " True when there is input ready. The inputhook should return control. " - return bool(self._ready_for_reading(current_timeout if wait else 0)) - self._inputhook_context.call_inputhook(ready) - - # Calculate remaining timeout. (The inputhook consumed some of the time.) - if current_timeout == -1: - remaining_timeout = -1 - else: - remaining_timeout = max(0, current_timeout - int(1000 * inputhook_timer.duration)) - - # Wait for the next event. - handle = self._ready_for_reading(remaining_timeout) - - if handle == self._console_input_reader.handle.value: - # When stdin is ready, read input and reset timeout timer. - keys = self._console_input_reader.read() - for k in keys: - callbacks.feed_key(k) - current_timeout = INPUT_TIMEOUT_MS - - elif handle == self._event.value: - # When the Windows Event has been trigger, process the messages in the queue. - windll.kernel32.ResetEvent(self._event) - self._process_queued_calls_from_executor() - - elif handle in self._read_fds: - callback = self._read_fds[handle] - callback() - else: - # Fire input timeout event. - callbacks.input_timeout() - current_timeout = -1 - - def _ready_for_reading(self, timeout=None): - """ - Return the handle that is ready for reading or `None` on timeout. - """ - handles = [self._event, self._console_input_reader.handle] - handles.extend(self._read_fds.keys()) - return _wait_for_handles(handles, timeout) - - def stop(self): - self._running = False - - def close(self): - self.closed = True - - # Clean up Event object. - windll.kernel32.CloseHandle(self._event) - - if self._inputhook_context: - self._inputhook_context.close() - - self._console_input_reader.close() - - def run_in_executor(self, callback): - """ - Run a long running function in a background thread. - (This is recommended for code that could block the event loop.) - Similar to Twisted's ``deferToThread``. - """ - # Wait until the main thread is idle for an instant before starting the - # executor. (Like in eventloop/posix.py, we start the executor using - # `call_from_executor`.) - def start_executor(): - threading.Thread(target=callback).start() - self.call_from_executor(start_executor) - - def call_from_executor(self, callback, _max_postpone_until=None): - """ - Call this function in the main event loop. - Similar to Twisted's ``callFromThread``. - """ - # Append to list of pending callbacks. - self._calls_from_executor.append(callback) - - # Set Windows event. - windll.kernel32.SetEvent(self._event) - - def _process_queued_calls_from_executor(self): - # Process calls from executor. - calls_from_executor, self._calls_from_executor = self._calls_from_executor, [] - for c in calls_from_executor: - c() - - def add_reader(self, fd, callback): - " Start watching the file descriptor for read availability. " - h = msvcrt.get_osfhandle(fd) - self._read_fds[h] = callback - - def remove_reader(self, fd): - " Stop watching the file descriptor for read availability. " - h = msvcrt.get_osfhandle(fd) - if h in self._read_fds: - del self._read_fds[h] - - -def _wait_for_handles(handles, timeout=-1): - """ - Waits for multiple handles. (Similar to 'select') Returns the handle which is ready. - Returns `None` on timeout. - - http://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx - """ - arrtype = HANDLE * len(handles) - handle_array = arrtype(*handles) - - ret = windll.kernel32.WaitForMultipleObjects( - len(handle_array), handle_array, BOOL(False), DWORD(timeout)) - - if ret == WAIT_TIMEOUT: - return None - else: - h = handle_array[ret] - return h - - -def _create_event(): - """ - Creates a Win32 unnamed Event . - - http://msdn.microsoft.com/en-us/library/windows/desktop/ms682396(v=vs.85).aspx - """ - return windll.kernel32.CreateEventA(pointer(SECURITY_ATTRIBUTES()), BOOL(True), BOOL(False), None) |