| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | """Event loop and event loop policy.""" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  | __all__ = ( | 
					
						
							|  |  |  |     'AbstractEventLoopPolicy', | 
					
						
							|  |  |  |     'AbstractEventLoop', 'AbstractServer', | 
					
						
							| 
									
										
										
										
											2018-09-11 10:13:04 -07:00
										 |  |  |     'Handle', 'TimerHandle', | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |     'get_event_loop_policy', 'set_event_loop_policy', | 
					
						
							|  |  |  |     'get_event_loop', 'set_event_loop', 'new_event_loop', | 
					
						
							|  |  |  |     'get_child_watcher', 'set_child_watcher', | 
					
						
							| 
									
										
										
										
											2017-12-11 10:07:44 -05:00
										 |  |  |     '_set_running_loop', 'get_running_loop', | 
					
						
							|  |  |  |     '_get_running_loop', | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  | ) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-22 19:11:18 -05:00
										 |  |  | import contextvars | 
					
						
							| 
									
										
										
										
											2017-03-02 20:07:11 -05:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | import socket | 
					
						
							| 
									
										
										
										
											2014-07-29 12:58:23 +02:00
										 |  |  | import subprocess | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  | import sys | 
					
						
							| 
									
										
										
										
											2014-07-29 12:58:23 +02:00
										 |  |  | import threading | 
					
						
							| 
									
										
										
										
											2014-06-12 18:39:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-15 07:04:38 +02:00
										 |  |  | from . import format_helpers | 
					
						
							| 
									
										
										
										
											2018-01-19 20:04:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | class Handle: | 
					
						
							|  |  |  |     """Object returned by callback registration methods.""" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-27 13:52:20 +02:00
										 |  |  |     __slots__ = ('_callback', '_args', '_cancelled', '_loop', | 
					
						
							| 
									
										
										
										
											2018-01-22 19:11:18 -05:00
										 |  |  |                  '_source_traceback', '_repr', '__weakref__', | 
					
						
							|  |  |  |                  '_context') | 
					
						
							| 
									
										
										
										
											2014-02-12 17:01:52 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-22 19:11:18 -05:00
										 |  |  |     def __init__(self, callback, args, loop, context=None): | 
					
						
							|  |  |  |         if context is None: | 
					
						
							|  |  |  |             context = contextvars.copy_context() | 
					
						
							|  |  |  |         self._context = context | 
					
						
							| 
									
										
										
										
											2014-02-18 18:02:19 -05:00
										 |  |  |         self._loop = loop | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self._callback = callback | 
					
						
							|  |  |  |         self._args = args | 
					
						
							|  |  |  |         self._cancelled = False | 
					
						
							| 
									
										
										
										
											2014-09-17 23:24:13 +02:00
										 |  |  |         self._repr = None | 
					
						
							| 
									
										
										
										
											2014-06-27 13:52:20 +02:00
										 |  |  |         if self._loop.get_debug(): | 
					
						
							| 
									
										
										
										
											2017-12-15 07:04:38 +02:00
										 |  |  |             self._source_traceback = format_helpers.extract_stack( | 
					
						
							|  |  |  |                 sys._getframe(1)) | 
					
						
							| 
									
										
										
										
											2014-06-27 13:52:20 +02:00
										 |  |  |         else: | 
					
						
							|  |  |  |             self._source_traceback = None | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-17 23:24:13 +02:00
										 |  |  |     def _repr_info(self): | 
					
						
							| 
									
										
										
										
											2014-07-10 22:32:58 +02:00
										 |  |  |         info = [self.__class__.__name__] | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         if self._cancelled: | 
					
						
							| 
									
										
										
										
											2014-06-25 21:41:58 +02:00
										 |  |  |             info.append('cancelled') | 
					
						
							| 
									
										
										
										
											2014-07-10 22:32:58 +02:00
										 |  |  |         if self._callback is not None: | 
					
						
							| 
									
										
										
										
											2017-12-15 07:04:38 +02:00
										 |  |  |             info.append(format_helpers._format_callback_source( | 
					
						
							|  |  |  |                 self._callback, self._args)) | 
					
						
							| 
									
										
										
										
											2014-07-10 22:32:58 +02:00
										 |  |  |         if self._source_traceback: | 
					
						
							|  |  |  |             frame = self._source_traceback[-1] | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |             info.append(f'created at {frame[0]}:{frame[1]}') | 
					
						
							| 
									
										
										
										
											2014-09-17 23:24:13 +02:00
										 |  |  |         return info | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __repr__(self): | 
					
						
							|  |  |  |         if self._repr is not None: | 
					
						
							|  |  |  |             return self._repr | 
					
						
							|  |  |  |         info = self._repr_info() | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |         return '<{}>'.format(' '.join(info)) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def cancel(self): | 
					
						
							| 
									
										
										
										
											2014-09-25 12:07:56 -04:00
										 |  |  |         if not self._cancelled: | 
					
						
							|  |  |  |             self._cancelled = True | 
					
						
							|  |  |  |             if self._loop.get_debug(): | 
					
						
							|  |  |  |                 # Keep a representation in debug mode to keep callback and | 
					
						
							|  |  |  |                 # parameters. For example, to log the warning | 
					
						
							|  |  |  |                 # "Executing <Handle...> took 2.5 second" | 
					
						
							|  |  |  |                 self._repr = repr(self) | 
					
						
							|  |  |  |             self._callback = None | 
					
						
							|  |  |  |             self._args = None | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-07 12:06:05 +03:00
										 |  |  |     def cancelled(self): | 
					
						
							|  |  |  |         return self._cancelled | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def _run(self): | 
					
						
							|  |  |  |         try: | 
					
						
							| 
									
										
										
										
											2018-01-22 19:11:18 -05:00
										 |  |  |             self._context.run(self._callback, *self._args) | 
					
						
							| 
									
										
										
										
											2019-05-27 14:45:12 +02:00
										 |  |  |         except (SystemExit, KeyboardInterrupt): | 
					
						
							|  |  |  |             raise | 
					
						
							|  |  |  |         except BaseException as exc: | 
					
						
							| 
									
										
										
										
											2017-12-15 07:04:38 +02:00
										 |  |  |             cb = format_helpers._format_callback_source( | 
					
						
							|  |  |  |                 self._callback, self._args) | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |             msg = f'Exception in callback {cb}' | 
					
						
							| 
									
										
										
										
											2014-06-27 13:52:20 +02:00
										 |  |  |             context = { | 
					
						
							| 
									
										
										
										
											2014-02-18 18:02:19 -05:00
										 |  |  |                 'message': msg, | 
					
						
							|  |  |  |                 'exception': exc, | 
					
						
							|  |  |  |                 'handle': self, | 
					
						
							| 
									
										
										
										
											2014-06-27 13:52:20 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |             if self._source_traceback: | 
					
						
							|  |  |  |                 context['source_traceback'] = self._source_traceback | 
					
						
							|  |  |  |             self._loop.call_exception_handler(context) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self = None  # Needed to break cycles when an exception occurs. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TimerHandle(Handle): | 
					
						
							|  |  |  |     """Object returned by timed callback registration methods.""" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-25 12:07:56 -04:00
										 |  |  |     __slots__ = ['_scheduled', '_when'] | 
					
						
							| 
									
										
										
										
											2014-02-12 17:01:52 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-22 19:11:18 -05:00
										 |  |  |     def __init__(self, when, callback, args, loop, context=None): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         assert when is not None | 
					
						
							| 
									
										
										
										
											2018-01-22 19:11:18 -05:00
										 |  |  |         super().__init__(callback, args, loop, context) | 
					
						
							| 
									
										
										
										
											2014-06-27 13:52:20 +02:00
										 |  |  |         if self._source_traceback: | 
					
						
							|  |  |  |             del self._source_traceback[-1] | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         self._when = when | 
					
						
							| 
									
										
										
										
											2014-09-25 12:07:56 -04:00
										 |  |  |         self._scheduled = False | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-17 23:24:13 +02:00
										 |  |  |     def _repr_info(self): | 
					
						
							|  |  |  |         info = super()._repr_info() | 
					
						
							|  |  |  |         pos = 2 if self._cancelled else 1 | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |         info.insert(pos, f'when={self._when}') | 
					
						
							| 
									
										
										
										
											2014-09-17 23:24:13 +02:00
										 |  |  |         return info | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __hash__(self): | 
					
						
							|  |  |  |         return hash(self._when) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __lt__(self, other): | 
					
						
							| 
									
										
										
										
											2019-08-08 08:42:54 +03:00
										 |  |  |         if isinstance(other, TimerHandle): | 
					
						
							|  |  |  |             return self._when < other._when | 
					
						
							|  |  |  |         return NotImplemented | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __le__(self, other): | 
					
						
							| 
									
										
										
										
											2019-08-08 08:42:54 +03:00
										 |  |  |         if isinstance(other, TimerHandle): | 
					
						
							|  |  |  |             return self._when < other._when or self.__eq__(other) | 
					
						
							|  |  |  |         return NotImplemented | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __gt__(self, other): | 
					
						
							| 
									
										
										
										
											2019-08-08 08:42:54 +03:00
										 |  |  |         if isinstance(other, TimerHandle): | 
					
						
							|  |  |  |             return self._when > other._when | 
					
						
							|  |  |  |         return NotImplemented | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __ge__(self, other): | 
					
						
							| 
									
										
										
										
											2019-08-08 08:42:54 +03:00
										 |  |  |         if isinstance(other, TimerHandle): | 
					
						
							|  |  |  |             return self._when > other._when or self.__eq__(other) | 
					
						
							|  |  |  |         return NotImplemented | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __eq__(self, other): | 
					
						
							|  |  |  |         if isinstance(other, TimerHandle): | 
					
						
							|  |  |  |             return (self._when == other._when and | 
					
						
							|  |  |  |                     self._callback == other._callback and | 
					
						
							|  |  |  |                     self._args == other._args and | 
					
						
							|  |  |  |                     self._cancelled == other._cancelled) | 
					
						
							|  |  |  |         return NotImplemented | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-25 12:07:56 -04:00
										 |  |  |     def cancel(self): | 
					
						
							|  |  |  |         if not self._cancelled: | 
					
						
							|  |  |  |             self._loop._timer_handle_cancelled(self) | 
					
						
							|  |  |  |         super().cancel() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-01 19:59:32 +02:00
										 |  |  |     def when(self): | 
					
						
							|  |  |  |         """Return a scheduled callback time.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         The time is an absolute timestamp, using the same time | 
					
						
							|  |  |  |         reference as loop.time(). | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         return self._when | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | class AbstractServer: | 
					
						
							| 
									
										
										
										
											2013-12-03 18:23:52 +01:00
										 |  |  |     """Abstract server returned by create_server().""" | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def close(self): | 
					
						
							|  |  |  |         """Stop serving.  This leaves existing connections open.""" | 
					
						
							| 
									
										
										
										
											2017-12-30 18:52:56 +02:00
										 |  |  |         raise NotImplementedError | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-25 18:08:09 -05:00
										 |  |  |     def get_loop(self): | 
					
						
							|  |  |  |         """Get the event loop the Server object is attached to.""" | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def is_serving(self): | 
					
						
							|  |  |  |         """Return True if the server is accepting connections.""" | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async def start_serving(self): | 
					
						
							|  |  |  |         """Start accepting connections.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         This method is idempotent, so it can be called when | 
					
						
							|  |  |  |         the server is already being serving. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async def serve_forever(self): | 
					
						
							|  |  |  |         """Start accepting connections until the coroutine is cancelled.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         The server is closed when the coroutine is cancelled. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |     async def wait_closed(self): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         """Coroutine to wait until service is closed.""" | 
					
						
							| 
									
										
										
										
											2017-12-30 18:52:56 +02:00
										 |  |  |         raise NotImplementedError | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-25 18:08:09 -05:00
										 |  |  |     async def __aenter__(self): | 
					
						
							|  |  |  |         return self | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async def __aexit__(self, *exc): | 
					
						
							|  |  |  |         self.close() | 
					
						
							|  |  |  |         await self.wait_closed() | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:32 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | class AbstractEventLoop: | 
					
						
							|  |  |  |     """Abstract event loop.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Running and stopping the event loop. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def run_forever(self): | 
					
						
							|  |  |  |         """Run the event loop until stop() is called.""" | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def run_until_complete(self, future): | 
					
						
							|  |  |  |         """Run the event loop until a Future is done.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Return the Future's result, or raise its exception. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def stop(self): | 
					
						
							|  |  |  |         """Stop the event loop as soon as reasonable.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Exactly how soon that is may depend on the implementation, but | 
					
						
							|  |  |  |         no more I/O callbacks should be scheduled. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def is_running(self): | 
					
						
							|  |  |  |         """Return whether the event loop is currently running.""" | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 11:29:25 +02:00
										 |  |  |     def is_closed(self): | 
					
						
							|  |  |  |         """Returns True if the event loop was closed.""" | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-01 14:19:04 -07:00
										 |  |  |     def close(self): | 
					
						
							|  |  |  |         """Close the loop.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         The loop should not be running. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         This is idempotent and irreversible. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         No other methods should be called after this one. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |     async def shutdown_asyncgens(self): | 
					
						
							| 
									
										
										
										
											2016-09-15 13:10:51 -04:00
										 |  |  |         """Shutdown all active asynchronous generators.""" | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-19 08:47:22 -04:00
										 |  |  |     async def shutdown_default_executor(self): | 
					
						
							|  |  |  |         """Schedule the shutdown of the default executor.""" | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     # Methods scheduling callbacks.  All these return Handles. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-25 12:07:56 -04:00
										 |  |  |     def _timer_handle_cancelled(self, handle): | 
					
						
							|  |  |  |         """Notification that a TimerHandle has been cancelled.""" | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     def call_soon(self, callback, *args): | 
					
						
							|  |  |  |         return self.call_later(0, callback, *args) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def call_later(self, delay, callback, *args): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def call_at(self, when, callback, *args): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def time(self): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-16 15:38:39 -04:00
										 |  |  |     def create_future(self): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 11:29:25 +02:00
										 |  |  |     # Method scheduling a coroutine object: create a task. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-09 00:06:47 +03:00
										 |  |  |     def create_task(self, coro, *, name=None): | 
					
						
							| 
									
										
										
										
											2014-07-08 11:29:25 +02:00
										 |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     # Methods for interacting with threads. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def call_soon_threadsafe(self, callback, *args): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-17 15:19:46 +01:00
										 |  |  |     def run_in_executor(self, executor, func, *args): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def set_default_executor(self, executor): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Network I/O methods returning Futures. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |     async def getaddrinfo(self, host, port, *, | 
					
						
							|  |  |  |                           family=0, type=0, proto=0, flags=0): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |     async def getnameinfo(self, sockaddr, flags=0): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-19 19:45:42 +00:00
										 |  |  |     async def create_connection( | 
					
						
							|  |  |  |             self, protocol_factory, host=None, port=None, | 
					
						
							|  |  |  |             *, ssl=None, family=0, proto=0, | 
					
						
							|  |  |  |             flags=0, sock=None, local_addr=None, | 
					
						
							|  |  |  |             server_hostname=None, | 
					
						
							| 
									
										
										
										
											2019-05-05 19:14:35 +08:00
										 |  |  |             ssl_handshake_timeout=None, | 
					
						
							|  |  |  |             happy_eyeballs_delay=None, interleave=None): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-19 19:45:42 +00:00
										 |  |  |     async def create_server( | 
					
						
							|  |  |  |             self, protocol_factory, host=None, port=None, | 
					
						
							|  |  |  |             *, family=socket.AF_UNSPEC, | 
					
						
							|  |  |  |             flags=socket.AI_PASSIVE, sock=None, backlog=100, | 
					
						
							|  |  |  |             ssl=None, reuse_address=None, reuse_port=None, | 
					
						
							| 
									
										
										
										
											2018-01-25 18:08:09 -05:00
										 |  |  |             ssl_handshake_timeout=None, | 
					
						
							|  |  |  |             start_serving=True): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         """A coroutine which creates a TCP server bound to host and port.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         The return value is a Server object which can be used to stop | 
					
						
							|  |  |  |         the service. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         If host is an empty string or None all interfaces are assumed | 
					
						
							|  |  |  |         and a list of multiple sockets will be returned (most likely | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |         one for IPv4 and another one for IPv6). The host parameter can also be | 
					
						
							|  |  |  |         a sequence (e.g. list) of hosts to bind to. | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         family can be set to either AF_INET or AF_INET6 to force the | 
					
						
							|  |  |  |         socket to use IPv4 or IPv6. If not set it will be determined | 
					
						
							|  |  |  |         from host (defaults to AF_UNSPEC). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         flags is a bitmask for getaddrinfo(). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         sock can optionally be specified in order to use a preexisting | 
					
						
							|  |  |  |         socket object. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         backlog is the maximum number of queued connections passed to | 
					
						
							|  |  |  |         listen() (defaults to 100). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ssl can be set to an SSLContext to enable SSL over the | 
					
						
							|  |  |  |         accepted connections. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         reuse_address tells the kernel to reuse a local socket in | 
					
						
							|  |  |  |         TIME_WAIT state, without waiting for its natural timeout to | 
					
						
							|  |  |  |         expire. If not specified will automatically be set to True on | 
					
						
							|  |  |  |         UNIX. | 
					
						
							| 
									
										
										
										
											2015-10-05 09:15:28 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         reuse_port tells the kernel to allow this endpoint to be bound to | 
					
						
							|  |  |  |         the same port as other existing endpoints are bound to, so long as | 
					
						
							|  |  |  |         they all set this flag when being created. This option is not | 
					
						
							|  |  |  |         supported on Windows. | 
					
						
							| 
									
										
										
										
											2017-12-19 19:45:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         ssl_handshake_timeout is the time in seconds that an SSL server | 
					
						
							|  |  |  |         will wait for completion of the SSL handshake before aborting the | 
					
						
							| 
									
										
										
										
											2018-06-04 11:32:35 -04:00
										 |  |  |         connection. Default is 60s. | 
					
						
							| 
									
										
										
										
											2018-01-25 18:08:09 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         start_serving set to True (default) causes the created server | 
					
						
							|  |  |  |         to start accepting connections immediately.  When set to False, | 
					
						
							|  |  |  |         the user should await Server.start_serving() or Server.serve_forever() | 
					
						
							|  |  |  |         to make the server to start accepting connections. | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-27 21:22:47 +02:00
										 |  |  |     async def sendfile(self, transport, file, offset=0, count=None, | 
					
						
							|  |  |  |                        *, fallback=True): | 
					
						
							|  |  |  |         """Send a file through a transport.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Return an amount of sent bytes. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-30 00:35:36 -05:00
										 |  |  |     async def start_tls(self, transport, protocol, sslcontext, *, | 
					
						
							|  |  |  |                         server_side=False, | 
					
						
							|  |  |  |                         server_hostname=None, | 
					
						
							| 
									
										
										
										
											2021-05-03 16:21:59 +01:00
										 |  |  |                         ssl_handshake_timeout=None): | 
					
						
							| 
									
										
										
										
											2017-12-30 00:35:36 -05:00
										 |  |  |         """Upgrade a transport to TLS.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Return a new transport that *protocol* should start using | 
					
						
							|  |  |  |         immediately. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-19 19:45:42 +00:00
										 |  |  |     async def create_unix_connection( | 
					
						
							|  |  |  |             self, protocol_factory, path=None, *, | 
					
						
							|  |  |  |             ssl=None, sock=None, | 
					
						
							|  |  |  |             server_hostname=None, | 
					
						
							| 
									
										
										
										
											2021-05-03 16:21:59 +01:00
										 |  |  |             ssl_handshake_timeout=None): | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-19 19:45:42 +00:00
										 |  |  |     async def create_unix_server( | 
					
						
							|  |  |  |             self, protocol_factory, path=None, *, | 
					
						
							|  |  |  |             sock=None, backlog=100, ssl=None, | 
					
						
							| 
									
										
										
										
											2018-01-25 18:08:09 -05:00
										 |  |  |             ssl_handshake_timeout=None, | 
					
						
							|  |  |  |             start_serving=True): | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         """A coroutine which creates a UNIX Domain Socket server.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 22:27:48 -05:00
										 |  |  |         The return value is a Server object, which can be used to stop | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         the service. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-14 08:04:32 +08:00
										 |  |  |         path is a str, representing a file system path to bind the | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         server socket to. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         sock can optionally be specified in order to use a preexisting | 
					
						
							|  |  |  |         socket object. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         backlog is the maximum number of queued connections passed to | 
					
						
							|  |  |  |         listen() (defaults to 100). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ssl can be set to an SSLContext to enable SSL over the | 
					
						
							|  |  |  |         accepted connections. | 
					
						
							| 
									
										
										
										
											2017-12-19 19:45:42 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         ssl_handshake_timeout is the time in seconds that an SSL server | 
					
						
							| 
									
										
										
										
											2018-06-04 11:32:35 -04:00
										 |  |  |         will wait for the SSL handshake to complete (defaults to 60s). | 
					
						
							| 
									
										
										
										
											2018-01-25 18:08:09 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         start_serving set to True (default) causes the created server | 
					
						
							|  |  |  |         to start accepting connections immediately.  When set to False, | 
					
						
							|  |  |  |         the user should await Server.start_serving() or Server.serve_forever() | 
					
						
							|  |  |  |         to make the server to start accepting connections. | 
					
						
							| 
									
										
										
										
											2014-02-18 12:15:06 -05:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-26 12:09:12 +02:00
										 |  |  |     async def connect_accepted_socket( | 
					
						
							|  |  |  |             self, protocol_factory, sock, | 
					
						
							|  |  |  |             *, ssl=None, | 
					
						
							| 
									
										
										
										
											2021-05-03 16:21:59 +01:00
										 |  |  |             ssl_handshake_timeout=None): | 
					
						
							| 
									
										
										
										
											2020-11-26 12:09:12 +02:00
										 |  |  |         """Handle an accepted connection.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         This is used by servers that accept connections outside of | 
					
						
							|  |  |  |         asyncio, but use asyncio to handle connections. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         This method is a coroutine.  When completed, the coroutine | 
					
						
							|  |  |  |         returns a (transport, protocol) pair. | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |     async def create_datagram_endpoint(self, protocol_factory, | 
					
						
							|  |  |  |                                        local_addr=None, remote_addr=None, *, | 
					
						
							|  |  |  |                                        family=0, proto=0, flags=0, | 
					
						
							|  |  |  |                                        reuse_address=None, reuse_port=None, | 
					
						
							|  |  |  |                                        allow_broadcast=None, sock=None): | 
					
						
							| 
									
										
										
										
											2015-10-05 09:15:28 -07:00
										 |  |  |         """A coroutine which creates a datagram endpoint.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         This method will try to establish the endpoint in the background. | 
					
						
							|  |  |  |         When successful, the coroutine returns a (transport, protocol) pair. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         protocol_factory must be a callable returning a protocol instance. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-30 14:43:02 +01:00
										 |  |  |         socket family AF_INET, socket.AF_INET6 or socket.AF_UNIX depending on | 
					
						
							|  |  |  |         host (or family if specified), socket type SOCK_DGRAM. | 
					
						
							| 
									
										
										
										
											2015-10-05 09:15:28 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         reuse_address tells the kernel to reuse a local socket in | 
					
						
							|  |  |  |         TIME_WAIT state, without waiting for its natural timeout to | 
					
						
							|  |  |  |         expire. If not specified it will automatically be set to True on | 
					
						
							|  |  |  |         UNIX. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         reuse_port tells the kernel to allow this endpoint to be bound to | 
					
						
							|  |  |  |         the same port as other existing endpoints are bound to, so long as | 
					
						
							|  |  |  |         they all set this flag when being created. This option is not | 
					
						
							|  |  |  |         supported on Windows and some UNIX's. If the | 
					
						
							|  |  |  |         :py:data:`~socket.SO_REUSEPORT` constant is not defined then this | 
					
						
							|  |  |  |         capability is unsupported. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         allow_broadcast tells the kernel to allow this endpoint to send | 
					
						
							|  |  |  |         messages to the broadcast address. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         sock can optionally be specified in order to use a preexisting | 
					
						
							|  |  |  |         socket object. | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-01 14:19:04 -07:00
										 |  |  |     # Pipes and subprocesses. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |     async def connect_read_pipe(self, protocol_factory, pipe): | 
					
						
							| 
									
										
										
										
											2014-05-29 00:14:03 +02:00
										 |  |  |         """Register read pipe in event loop. Set the pipe to non-blocking mode.
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         protocol_factory should instantiate object with Protocol interface. | 
					
						
							| 
									
										
										
										
											2014-05-29 00:14:03 +02:00
										 |  |  |         pipe is a file-like object. | 
					
						
							|  |  |  |         Return pair (transport, protocol), where transport supports the | 
					
						
							| 
									
										
										
										
											2013-11-30 15:35:42 -08:00
										 |  |  |         ReadTransport interface."""
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         # The reason to accept file-like object instead of just file descriptor | 
					
						
							|  |  |  |         # is: we need to own pipe and close it at transport finishing | 
					
						
							|  |  |  |         # Can got complicated errors if pass f.fileno(), | 
					
						
							|  |  |  |         # close fd in pipe transport then close f and vise versa. | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |     async def connect_write_pipe(self, protocol_factory, pipe): | 
					
						
							| 
									
										
										
										
											2014-02-18 22:27:48 -05:00
										 |  |  |         """Register write pipe in event loop.
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         protocol_factory should instantiate object with BaseProtocol interface. | 
					
						
							|  |  |  |         Pipe is file-like object already switched to nonblocking. | 
					
						
							|  |  |  |         Return pair (transport, protocol), where transport support | 
					
						
							| 
									
										
										
										
											2013-11-30 15:35:42 -08:00
										 |  |  |         WriteTransport interface."""
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         # The reason to accept file-like object instead of just file descriptor | 
					
						
							|  |  |  |         # is: we need to own pipe and close it at transport finishing | 
					
						
							|  |  |  |         # Can got complicated errors if pass f.fileno(), | 
					
						
							|  |  |  |         # close fd in pipe transport then close f and vise versa. | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |     async def subprocess_shell(self, protocol_factory, cmd, *, | 
					
						
							|  |  |  |                                stdin=subprocess.PIPE, | 
					
						
							|  |  |  |                                stdout=subprocess.PIPE, | 
					
						
							|  |  |  |                                stderr=subprocess.PIPE, | 
					
						
							|  |  |  |                                **kwargs): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |     async def subprocess_exec(self, protocol_factory, *args, | 
					
						
							|  |  |  |                               stdin=subprocess.PIPE, | 
					
						
							|  |  |  |                               stdout=subprocess.PIPE, | 
					
						
							|  |  |  |                               stderr=subprocess.PIPE, | 
					
						
							|  |  |  |                               **kwargs): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Ready-based callback registration methods. | 
					
						
							|  |  |  |     # The add_*() methods return None. | 
					
						
							|  |  |  |     # The remove_*() methods return True if something was removed, | 
					
						
							|  |  |  |     # False if there was nothing to delete. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def add_reader(self, fd, callback, *args): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def remove_reader(self, fd): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def add_writer(self, fd, callback, *args): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def remove_writer(self, fd): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Completion based I/O methods returning Futures. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |     async def sock_recv(self, sock, nbytes): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |     async def sock_recv_into(self, sock, buf): | 
					
						
							| 
									
										
										
										
											2017-10-19 21:46:40 +02:00
										 |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |     async def sock_sendall(self, sock, data): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |     async def sock_connect(self, sock, address): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-09 00:23:48 +02:00
										 |  |  |     async def sock_accept(self, sock): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-16 19:59:34 +02:00
										 |  |  |     async def sock_sendfile(self, sock, file, offset=0, count=None, | 
					
						
							|  |  |  |                             *, fallback=None): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     # Signal handling. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def add_signal_handler(self, sig, callback, *args): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def remove_signal_handler(self, sig): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-11 14:23:38 -04:00
										 |  |  |     # Task factory. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def set_task_factory(self, factory): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_task_factory(self): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 18:02:19 -05:00
										 |  |  |     # Error handlers. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-16 15:20:38 -04:00
										 |  |  |     def get_exception_handler(self): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-18 18:02:19 -05:00
										 |  |  |     def set_exception_handler(self, handler): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def default_exception_handler(self, context): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def call_exception_handler(self, context): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-19 23:15:02 +01:00
										 |  |  |     # Debug flag management. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_debug(self): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def set_debug(self, enabled): | 
					
						
							|  |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | class AbstractEventLoopPolicy: | 
					
						
							|  |  |  |     """Abstract policy for accessing the event loop.""" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def get_event_loop(self): | 
					
						
							| 
									
										
										
										
											2014-06-05 12:06:44 +02:00
										 |  |  |         """Get the event loop for the current context.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Returns an event loop object implementing the BaseEventLoop interface, | 
					
						
							|  |  |  |         or raises an exception in case no event loop has been set for the | 
					
						
							|  |  |  |         current context and the current policy does not specify to create one. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         It should never return None."""
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def set_event_loop(self, loop): | 
					
						
							| 
									
										
										
										
											2014-06-05 12:06:44 +02:00
										 |  |  |         """Set the event loop for the current context to loop.""" | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def new_event_loop(self): | 
					
						
							| 
									
										
										
										
											2014-06-05 12:06:44 +02:00
										 |  |  |         """Create and return a new event loop object according to this
 | 
					
						
							|  |  |  |         policy's rules. If there's need to set this loop as the event loop for | 
					
						
							|  |  |  |         the current context, set_event_loop must be called explicitly."""
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-04 15:50:46 -08:00
										 |  |  |     # Child processes handling (Unix only). | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-04 15:50:46 -08:00
										 |  |  |     def get_child_watcher(self): | 
					
						
							| 
									
										
										
										
											2014-06-05 12:06:44 +02:00
										 |  |  |         "Get the watcher for child processes." | 
					
						
							| 
									
										
										
										
											2013-11-04 15:50:46 -08:00
										 |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def set_child_watcher(self, watcher): | 
					
						
							| 
									
										
										
										
											2014-06-05 12:06:44 +02:00
										 |  |  |         """Set the watcher for child processes.""" | 
					
						
							| 
									
										
										
										
											2013-11-04 15:50:46 -08:00
										 |  |  |         raise NotImplementedError | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BaseDefaultEventLoopPolicy(AbstractEventLoopPolicy): | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     """Default policy implementation for accessing the event loop.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     In this policy, each thread has its own event loop.  However, we | 
					
						
							|  |  |  |     only automatically create an event loop by default for the main | 
					
						
							|  |  |  |     thread; other threads by default have no event loop. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Other policies may have different rules (e.g. a single global | 
					
						
							|  |  |  |     event loop, or automatically creating an event loop per thread, or | 
					
						
							|  |  |  |     using some other notion of context to which an event loop is | 
					
						
							|  |  |  |     associated). | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-04 15:50:46 -08:00
										 |  |  |     _loop_factory = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     class _Local(threading.local): | 
					
						
							|  |  |  |         _loop = None | 
					
						
							|  |  |  |         _set_called = False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self): | 
					
						
							|  |  |  |         self._local = self._Local() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def get_event_loop(self): | 
					
						
							| 
									
										
										
										
											2019-10-04 00:08:29 +03:00
										 |  |  |         """Get the event loop for the current context.
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-04 00:08:29 +03:00
										 |  |  |         Returns an instance of EventLoop or raises an exception. | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2013-11-04 15:50:46 -08:00
										 |  |  |         if (self._local._loop is None and | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  |                 not self._local._set_called and | 
					
						
							| 
									
										
										
										
											2019-12-05 04:40:12 -08:00
										 |  |  |                 threading.current_thread() is threading.main_thread()): | 
					
						
							| 
									
										
										
										
											2013-11-27 10:37:13 -08:00
										 |  |  |             self.set_event_loop(self.new_event_loop()) | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-18 01:20:10 +01:00
										 |  |  |         if self._local._loop is None: | 
					
						
							|  |  |  |             raise RuntimeError('There is no current event loop in thread %r.' | 
					
						
							|  |  |  |                                % threading.current_thread().name) | 
					
						
							| 
									
										
										
										
											2017-12-10 18:36:12 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-04 15:50:46 -08:00
										 |  |  |         return self._local._loop | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def set_event_loop(self, loop): | 
					
						
							|  |  |  |         """Set the event loop.""" | 
					
						
							| 
									
										
										
										
											2013-11-04 15:50:46 -08:00
										 |  |  |         self._local._set_called = True | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |         assert loop is None or isinstance(loop, AbstractEventLoop) | 
					
						
							| 
									
										
										
										
											2013-11-04 15:50:46 -08:00
										 |  |  |         self._local._loop = loop | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def new_event_loop(self): | 
					
						
							|  |  |  |         """Create a new event loop.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         You must call set_event_loop() to make this the current event | 
					
						
							|  |  |  |         loop. | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2013-11-04 15:50:46 -08:00
										 |  |  |         return self._loop_factory() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Event loop policy.  The policy itself is always global, even if the | 
					
						
							|  |  |  | # policy's rules say that there is an event loop per thread (or other | 
					
						
							|  |  |  | # notion of context).  The default policy is installed by the first | 
					
						
							|  |  |  | # call to get_event_loop_policy(). | 
					
						
							|  |  |  | _event_loop_policy = None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-04 15:50:46 -08:00
										 |  |  | # Lock for protecting the on-the-fly creation of the event loop policy. | 
					
						
							|  |  |  | _lock = threading.Lock() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-04 14:29:28 -04:00
										 |  |  | # A TLS for the running event loop, used by _get_running_loop. | 
					
						
							|  |  |  | class _RunningLoop(threading.local): | 
					
						
							| 
									
										
										
										
											2017-09-05 17:36:59 -07:00
										 |  |  |     loop_pid = (None, None) | 
					
						
							| 
									
										
										
										
											2017-03-02 20:07:11 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-04 14:29:28 -04:00
										 |  |  | _running_loop = _RunningLoop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-11 10:07:44 -05:00
										 |  |  | def get_running_loop(): | 
					
						
							|  |  |  |     """Return the running event loop.  Raise a RuntimeError if there is none.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     This function is thread-specific. | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  |     # NOTE: this function is implemented in C (see _asynciomodule.c) | 
					
						
							| 
									
										
										
										
											2017-12-11 10:07:44 -05:00
										 |  |  |     loop = _get_running_loop() | 
					
						
							|  |  |  |     if loop is None: | 
					
						
							|  |  |  |         raise RuntimeError('no running event loop') | 
					
						
							|  |  |  |     return loop | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-04 14:29:28 -04:00
										 |  |  | def _get_running_loop(): | 
					
						
							|  |  |  |     """Return the running event loop or None.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     This is a low-level function intended to be used by event loops. | 
					
						
							|  |  |  |     This function is thread-specific. | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  |     # NOTE: this function is implemented in C (see _asynciomodule.c) | 
					
						
							| 
									
										
										
										
											2017-09-05 17:36:59 -07:00
										 |  |  |     running_loop, pid = _running_loop.loop_pid | 
					
						
							|  |  |  |     if running_loop is not None and pid == os.getpid(): | 
					
						
							| 
									
										
										
										
											2017-03-02 23:57:33 -05:00
										 |  |  |         return running_loop | 
					
						
							| 
									
										
										
										
											2016-11-04 14:29:28 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _set_running_loop(loop): | 
					
						
							|  |  |  |     """Set the running event loop.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     This is a low-level function intended to be used by event loops. | 
					
						
							|  |  |  |     This function is thread-specific. | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  |     # NOTE: this function is implemented in C (see _asynciomodule.c) | 
					
						
							| 
									
										
										
										
											2017-09-05 17:36:59 -07:00
										 |  |  |     _running_loop.loop_pid = (loop, os.getpid()) | 
					
						
							| 
									
										
										
										
											2016-11-04 14:29:28 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-04 15:50:46 -08:00
										 |  |  | def _init_event_loop_policy(): | 
					
						
							|  |  |  |     global _event_loop_policy | 
					
						
							|  |  |  |     with _lock: | 
					
						
							|  |  |  |         if _event_loop_policy is None:  # pragma: no branch | 
					
						
							|  |  |  |             from . import DefaultEventLoopPolicy | 
					
						
							|  |  |  |             _event_loop_policy = DefaultEventLoopPolicy() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | def get_event_loop_policy(): | 
					
						
							| 
									
										
										
										
											2014-06-05 12:06:44 +02:00
										 |  |  |     """Get the current event loop policy.""" | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     if _event_loop_policy is None: | 
					
						
							| 
									
										
										
										
											2013-11-04 15:50:46 -08:00
										 |  |  |         _init_event_loop_policy() | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     return _event_loop_policy | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def set_event_loop_policy(policy): | 
					
						
							| 
									
										
										
										
											2014-06-05 12:06:44 +02:00
										 |  |  |     """Set the current event loop policy.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     If policy is None, the default policy is restored."""
 | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     global _event_loop_policy | 
					
						
							|  |  |  |     assert policy is None or isinstance(policy, AbstractEventLoopPolicy) | 
					
						
							|  |  |  |     _event_loop_policy = policy | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def get_event_loop(): | 
					
						
							| 
									
										
										
										
											2016-11-04 14:29:28 -04:00
										 |  |  |     """Return an asyncio event loop.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     When called from a coroutine or a callback (e.g. scheduled with call_soon | 
					
						
							|  |  |  |     or similar API), this function will always return the running event loop. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     If there is no running event loop set, the function will return | 
					
						
							|  |  |  |     the result of `get_event_loop_policy().get_event_loop()` call. | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  |     # NOTE: this function is implemented in C (see _asynciomodule.c) | 
					
						
							| 
									
										
										
										
											2021-04-25 13:40:44 +03:00
										 |  |  |     return _py__get_event_loop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def _get_event_loop(stacklevel=3): | 
					
						
							| 
									
										
										
										
											2016-11-04 14:29:28 -04:00
										 |  |  |     current_loop = _get_running_loop() | 
					
						
							|  |  |  |     if current_loop is not None: | 
					
						
							|  |  |  |         return current_loop | 
					
						
							| 
									
										
										
										
											2021-04-25 13:40:44 +03:00
										 |  |  |     import warnings | 
					
						
							|  |  |  |     warnings.warn('There is no current event loop', | 
					
						
							|  |  |  |                   DeprecationWarning, stacklevel=stacklevel) | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     return get_event_loop_policy().get_event_loop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def set_event_loop(loop): | 
					
						
							| 
									
										
										
										
											2014-06-05 12:06:44 +02:00
										 |  |  |     """Equivalent to calling get_event_loop_policy().set_event_loop(loop).""" | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     get_event_loop_policy().set_event_loop(loop) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def new_event_loop(): | 
					
						
							| 
									
										
										
										
											2014-06-05 12:06:44 +02:00
										 |  |  |     """Equivalent to calling get_event_loop_policy().new_event_loop().""" | 
					
						
							| 
									
										
										
										
											2013-10-17 13:40:50 -07:00
										 |  |  |     return get_event_loop_policy().new_event_loop() | 
					
						
							| 
									
										
										
										
											2013-11-04 15:50:46 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def get_child_watcher(): | 
					
						
							| 
									
										
										
										
											2014-06-05 12:06:44 +02:00
										 |  |  |     """Equivalent to calling get_event_loop_policy().get_child_watcher().""" | 
					
						
							| 
									
										
										
										
											2013-11-04 15:50:46 -08:00
										 |  |  |     return get_event_loop_policy().get_child_watcher() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def set_child_watcher(watcher): | 
					
						
							| 
									
										
										
										
											2014-06-05 12:06:44 +02:00
										 |  |  |     """Equivalent to calling
 | 
					
						
							|  |  |  |     get_event_loop_policy().set_child_watcher(watcher)."""
 | 
					
						
							| 
									
										
										
										
											2013-11-04 15:50:46 -08:00
										 |  |  |     return get_event_loop_policy().set_child_watcher(watcher) | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Alias pure-Python implementations for testing purposes. | 
					
						
							|  |  |  | _py__get_running_loop = _get_running_loop | 
					
						
							|  |  |  | _py__set_running_loop = _set_running_loop | 
					
						
							|  |  |  | _py_get_running_loop = get_running_loop | 
					
						
							|  |  |  | _py_get_event_loop = get_event_loop | 
					
						
							| 
									
										
										
										
											2021-04-25 13:40:44 +03:00
										 |  |  | _py__get_event_loop = _get_event_loop | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | try: | 
					
						
							|  |  |  |     # get_event_loop() is one of the most frequently called | 
					
						
							|  |  |  |     # functions in asyncio.  Pure Python implementation is | 
					
						
							|  |  |  |     # about 4 times slower than C-accelerated. | 
					
						
							|  |  |  |     from _asyncio import (_get_running_loop, _set_running_loop, | 
					
						
							| 
									
										
										
										
											2021-04-25 13:40:44 +03:00
										 |  |  |                           get_running_loop, get_event_loop, _get_event_loop) | 
					
						
							| 
									
										
										
										
											2017-12-13 14:49:42 -05:00
										 |  |  | except ImportError: | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | else: | 
					
						
							|  |  |  |     # Alias C implementations for testing purposes. | 
					
						
							|  |  |  |     _c__get_running_loop = _get_running_loop | 
					
						
							|  |  |  |     _c__set_running_loop = _set_running_loop | 
					
						
							|  |  |  |     _c_get_running_loop = get_running_loop | 
					
						
							|  |  |  |     _c_get_event_loop = get_event_loop | 
					
						
							| 
									
										
										
										
											2021-04-25 13:40:44 +03:00
										 |  |  |     _c__get_event_loop = _get_event_loop |