aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop
diff options
context:
space:
mode:
authorIvan Blinkov <ivan@blinkov.ru>2022-02-10 16:47:11 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:47:11 +0300
commit5b283123c882433dafbaf6b338adeea16c1a0ea0 (patch)
tree339adc63bce23800021202ae4a8328a843dc447a /contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop
parent1aeb9a455974457866f78722ad98114bafc84e8a (diff)
downloadydb-5b283123c882433dafbaf6b338adeea16c1a0ea0.tar.gz
Restoring authorship annotation for Ivan Blinkov <ivan@blinkov.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop')
-rw-r--r--contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_base.py92
-rw-r--r--contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_posix.py214
-rw-r--r--contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_win32.py162
-rw-r--r--contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/base.py160
-rw-r--r--contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/callbacks.py58
-rw-r--r--contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/inputhook.py184
-rw-r--r--contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/posix.py528
-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/utils.py46
-rw-r--r--contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/win32.py324
10 files changed, 925 insertions, 925 deletions
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
index 1ea41dda60..ace2b8db49 100644
--- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_base.py
+++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_base.py
@@ -1,46 +1,46 @@
-"""
-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
+"""
+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
index 26606e8493..426ed96f67 100644
--- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_posix.py
+++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_posix.py
@@ -1,113 +1,113 @@
-"""
-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
-
+"""
+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.
+
+ @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()
-
+
+ # 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)
+ 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
index adc538afe9..45f5f52679 100644
--- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_win32.py
+++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/asyncio_win32.py
@@ -1,83 +1,83 @@
-"""
-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
-
+"""
+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)
+ 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
index 0be339ca7c..db86face66 100644
--- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/base.py
+++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/base.py
@@ -1,85 +1,85 @@
-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``.
-
+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.)
+ 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
index 068d900f62..04adab6fd4 100644
--- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/callbacks.py
+++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/callbacks.py
@@ -1,29 +1,29 @@
-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
+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
index c49d5876a1..bab1f4c003 100644
--- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/inputhook.py
+++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/inputhook.py
@@ -1,80 +1,80 @@
-"""
-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
+"""
+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:
+
+__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
@@ -88,20 +88,20 @@ class InputHookContext(object):
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
+ 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
index a2ef2ac3d8..f631dbd891 100644
--- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/posix.py
+++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/posix.py
@@ -1,244 +1,244 @@
-from __future__ import unicode_literals
-import fcntl
-import os
-import signal
-import threading
+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 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',
-)
-
+
+__all__ = (
+ 'PosixEventLoop',
+)
+
_now = time.time
-
-
-class PosixEventLoop(EventLoop):
- """
- Event loop for posix systems (Linux, Mac os X).
- """
+
+
+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 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.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
-
+
+ # 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.
+ 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)
+ 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:
+
+ # 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 = []
+
+ # 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:
+
+ 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:
+ 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.
- """
+ 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``.
-
+
+ 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.)
- """
+ 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:
+ 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):
@@ -247,60 +247,60 @@ class PosixEventLoop(EventLoop):
# - 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. "
+
+ 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._read_fds[fd] = callback
self.selector.register(fd)
-
- def remove_reader(self, fd):
- " Remove read file descriptor from the event loop. "
+
+ 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]
-
+ 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)
+
+
+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
index af040650f0..320df438ca 100644
--- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/posix_utils.py
+++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/posix_utils.py
@@ -1,18 +1,18 @@
-from __future__ import unicode_literals
-
-from codecs import getincrementaldecoder
-import os
+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.
+
+__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,
@@ -29,54 +29,54 @@ class PosixStdinReader(object):
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
+ 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')
+
+ # 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.
+ 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)
+ # 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''
-
+ 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/utils.py b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/utils.py
index 56b4646d1c..ff3a4cfd69 100644
--- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/utils.py
+++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/utils.py
@@ -1,23 +1,23 @@
-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
+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
index 273c277de9..18e356f088 100644
--- a/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/win32.py
+++ b/contrib/python/prompt-toolkit/py2/prompt_toolkit/eventloop/win32.py
@@ -1,187 +1,187 @@
-"""
-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
-
+"""
+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.
+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)
-
+ 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
-
+ 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)
-
+ # 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
-
+ # 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()
-
+ # 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.
- """
+ 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()
-
+
+ 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. "
+ 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. "
+
+ 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)
+
+
+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)