summaryrefslogtreecommitdiffstats
path: root/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop
diff options
context:
space:
mode:
authormonster <[email protected]>2022-07-07 14:41:37 +0300
committermonster <[email protected]>2022-07-07 14:41:37 +0300
commit06e5c21a835c0e923506c4ff27929f34e00761c2 (patch)
tree75efcbc6854ef9bd476eb8bf00cc5c900da436a2 /contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop
parent03f024c4412e3aa613bb543cf1660176320ba8f4 (diff)
fix ya.make
Diffstat (limited to 'contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop')
-rw-r--r--contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/__init__.py0
-rw-r--r--contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_base.py46
-rw-r--r--contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_posix.py113
-rw-r--r--contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_win32.py83
-rw-r--r--contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/base.py85
-rw-r--r--contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/callbacks.py29
-rw-r--r--contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/inputhook.py107
-rw-r--r--contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/posix.py306
-rw-r--r--contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/posix_utils.py82
-rw-r--r--contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/select.py216
-rw-r--r--contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/utils.py23
-rw-r--r--contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/win32.py187
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)