1"""Event loop and event loop policy.""" 2 3__all__ = ( 4 'AbstractEventLoopPolicy', 5 'AbstractEventLoop', 'AbstractServer', 6 'Handle', 'TimerHandle', 7 'get_event_loop_policy', 'set_event_loop_policy', 8 'get_event_loop', 'set_event_loop', 'new_event_loop', 9 'get_child_watcher', 'set_child_watcher', 10 '_set_running_loop', 'get_running_loop', 11 '_get_running_loop', 12) 13 14import contextvars 15import os 16import socket 17import subprocess 18import sys 19import threading 20 21from . import format_helpers 22 23 24class Handle: 25 """Object returned by callback registration methods.""" 26 27 __slots__ = ('_callback', '_args', '_cancelled', '_loop', 28 '_source_traceback', '_repr', '__weakref__', 29 '_context') 30 31 def __init__(self, callback, args, loop, context=None): 32 if context is None: 33 context = contextvars.copy_context() 34 self._context = context 35 self._loop = loop 36 self._callback = callback 37 self._args = args 38 self._cancelled = False 39 self._repr = None 40 if self._loop.get_debug(): 41 self._source_traceback = format_helpers.extract_stack( 42 sys._getframe(1)) 43 else: 44 self._source_traceback = None 45 46 def _repr_info(self): 47 info = [self.__class__.__name__] 48 if self._cancelled: 49 info.append('cancelled') 50 if self._callback is not None: 51 info.append(format_helpers._format_callback_source( 52 self._callback, self._args)) 53 if self._source_traceback: 54 frame = self._source_traceback[-1] 55 info.append(f'created at {frame[0]}:{frame[1]}') 56 return info 57 58 def __repr__(self): 59 if self._repr is not None: 60 return self._repr 61 info = self._repr_info() 62 return '<{}>'.format(' '.join(info)) 63 64 def cancel(self): 65 if not self._cancelled: 66 self._cancelled = True 67 if self._loop.get_debug(): 68 # Keep a representation in debug mode to keep callback and 69 # parameters. For example, to log the warning 70 # "Executing <Handle...> took 2.5 second" 71 self._repr = repr(self) 72 self._callback = None 73 self._args = None 74 75 def cancelled(self): 76 return self._cancelled 77 78 def _run(self): 79 try: 80 self._context.run(self._callback, *self._args) 81 except (SystemExit, KeyboardInterrupt): 82 raise 83 except BaseException as exc: 84 cb = format_helpers._format_callback_source( 85 self._callback, self._args) 86 msg = f'Exception in callback {cb}' 87 context = { 88 'message': msg, 89 'exception': exc, 90 'handle': self, 91 } 92 if self._source_traceback: 93 context['source_traceback'] = self._source_traceback 94 self._loop.call_exception_handler(context) 95 self = None # Needed to break cycles when an exception occurs. 96 97 98class TimerHandle(Handle): 99 """Object returned by timed callback registration methods.""" 100 101 __slots__ = ['_scheduled', '_when'] 102 103 def __init__(self, when, callback, args, loop, context=None): 104 super().__init__(callback, args, loop, context) 105 if self._source_traceback: 106 del self._source_traceback[-1] 107 self._when = when 108 self._scheduled = False 109 110 def _repr_info(self): 111 info = super()._repr_info() 112 pos = 2 if self._cancelled else 1 113 info.insert(pos, f'when={self._when}') 114 return info 115 116 def __hash__(self): 117 return hash(self._when) 118 119 def __lt__(self, other): 120 if isinstance(other, TimerHandle): 121 return self._when < other._when 122 return NotImplemented 123 124 def __le__(self, other): 125 if isinstance(other, TimerHandle): 126 return self._when < other._when or self.__eq__(other) 127 return NotImplemented 128 129 def __gt__(self, other): 130 if isinstance(other, TimerHandle): 131 return self._when > other._when 132 return NotImplemented 133 134 def __ge__(self, other): 135 if isinstance(other, TimerHandle): 136 return self._when > other._when or self.__eq__(other) 137 return NotImplemented 138 139 def __eq__(self, other): 140 if isinstance(other, TimerHandle): 141 return (self._when == other._when and 142 self._callback == other._callback and 143 self._args == other._args and 144 self._cancelled == other._cancelled) 145 return NotImplemented 146 147 def cancel(self): 148 if not self._cancelled: 149 self._loop._timer_handle_cancelled(self) 150 super().cancel() 151 152 def when(self): 153 """Return a scheduled callback time. 154 155 The time is an absolute timestamp, using the same time 156 reference as loop.time(). 157 """ 158 return self._when 159 160 161class AbstractServer: 162 """Abstract server returned by create_server().""" 163 164 def close(self): 165 """Stop serving. This leaves existing connections open.""" 166 raise NotImplementedError 167 168 def get_loop(self): 169 """Get the event loop the Server object is attached to.""" 170 raise NotImplementedError 171 172 def is_serving(self): 173 """Return True if the server is accepting connections.""" 174 raise NotImplementedError 175 176 async def start_serving(self): 177 """Start accepting connections. 178 179 This method is idempotent, so it can be called when 180 the server is already being serving. 181 """ 182 raise NotImplementedError 183 184 async def serve_forever(self): 185 """Start accepting connections until the coroutine is cancelled. 186 187 The server is closed when the coroutine is cancelled. 188 """ 189 raise NotImplementedError 190 191 async def wait_closed(self): 192 """Coroutine to wait until service is closed.""" 193 raise NotImplementedError 194 195 async def __aenter__(self): 196 return self 197 198 async def __aexit__(self, *exc): 199 self.close() 200 await self.wait_closed() 201 202 203class AbstractEventLoop: 204 """Abstract event loop.""" 205 206 # Running and stopping the event loop. 207 208 def run_forever(self): 209 """Run the event loop until stop() is called.""" 210 raise NotImplementedError 211 212 def run_until_complete(self, future): 213 """Run the event loop until a Future is done. 214 215 Return the Future's result, or raise its exception. 216 """ 217 raise NotImplementedError 218 219 def stop(self): 220 """Stop the event loop as soon as reasonable. 221 222 Exactly how soon that is may depend on the implementation, but 223 no more I/O callbacks should be scheduled. 224 """ 225 raise NotImplementedError 226 227 def is_running(self): 228 """Return whether the event loop is currently running.""" 229 raise NotImplementedError 230 231 def is_closed(self): 232 """Returns True if the event loop was closed.""" 233 raise NotImplementedError 234 235 def close(self): 236 """Close the loop. 237 238 The loop should not be running. 239 240 This is idempotent and irreversible. 241 242 No other methods should be called after this one. 243 """ 244 raise NotImplementedError 245 246 async def shutdown_asyncgens(self): 247 """Shutdown all active asynchronous generators.""" 248 raise NotImplementedError 249 250 async def shutdown_default_executor(self): 251 """Schedule the shutdown of the default executor.""" 252 raise NotImplementedError 253 254 # Methods scheduling callbacks. All these return Handles. 255 256 def _timer_handle_cancelled(self, handle): 257 """Notification that a TimerHandle has been cancelled.""" 258 raise NotImplementedError 259 260 def call_soon(self, callback, *args, context=None): 261 return self.call_later(0, callback, *args, context=context) 262 263 def call_later(self, delay, callback, *args, context=None): 264 raise NotImplementedError 265 266 def call_at(self, when, callback, *args, context=None): 267 raise NotImplementedError 268 269 def time(self): 270 raise NotImplementedError 271 272 def create_future(self): 273 raise NotImplementedError 274 275 # Method scheduling a coroutine object: create a task. 276 277 def create_task(self, coro, *, name=None, context=None): 278 raise NotImplementedError 279 280 # Methods for interacting with threads. 281 282 def call_soon_threadsafe(self, callback, *args, context=None): 283 raise NotImplementedError 284 285 def run_in_executor(self, executor, func, *args): 286 raise NotImplementedError 287 288 def set_default_executor(self, executor): 289 raise NotImplementedError 290 291 # Network I/O methods returning Futures. 292 293 async def getaddrinfo(self, host, port, *, 294 family=0, type=0, proto=0, flags=0): 295 raise NotImplementedError 296 297 async def getnameinfo(self, sockaddr, flags=0): 298 raise NotImplementedError 299 300 async def create_connection( 301 self, protocol_factory, host=None, port=None, 302 *, ssl=None, family=0, proto=0, 303 flags=0, sock=None, local_addr=None, 304 server_hostname=None, 305 ssl_handshake_timeout=None, 306 ssl_shutdown_timeout=None, 307 happy_eyeballs_delay=None, interleave=None): 308 raise NotImplementedError 309 310 async def create_server( 311 self, protocol_factory, host=None, port=None, 312 *, family=socket.AF_UNSPEC, 313 flags=socket.AI_PASSIVE, sock=None, backlog=100, 314 ssl=None, reuse_address=None, reuse_port=None, 315 ssl_handshake_timeout=None, 316 ssl_shutdown_timeout=None, 317 start_serving=True): 318 """A coroutine which creates a TCP server bound to host and port. 319 320 The return value is a Server object which can be used to stop 321 the service. 322 323 If host is an empty string or None all interfaces are assumed 324 and a list of multiple sockets will be returned (most likely 325 one for IPv4 and another one for IPv6). The host parameter can also be 326 a sequence (e.g. list) of hosts to bind to. 327 328 family can be set to either AF_INET or AF_INET6 to force the 329 socket to use IPv4 or IPv6. If not set it will be determined 330 from host (defaults to AF_UNSPEC). 331 332 flags is a bitmask for getaddrinfo(). 333 334 sock can optionally be specified in order to use a preexisting 335 socket object. 336 337 backlog is the maximum number of queued connections passed to 338 listen() (defaults to 100). 339 340 ssl can be set to an SSLContext to enable SSL over the 341 accepted connections. 342 343 reuse_address tells the kernel to reuse a local socket in 344 TIME_WAIT state, without waiting for its natural timeout to 345 expire. If not specified will automatically be set to True on 346 UNIX. 347 348 reuse_port tells the kernel to allow this endpoint to be bound to 349 the same port as other existing endpoints are bound to, so long as 350 they all set this flag when being created. This option is not 351 supported on Windows. 352 353 ssl_handshake_timeout is the time in seconds that an SSL server 354 will wait for completion of the SSL handshake before aborting the 355 connection. Default is 60s. 356 357 ssl_shutdown_timeout is the time in seconds that an SSL server 358 will wait for completion of the SSL shutdown procedure 359 before aborting the connection. Default is 30s. 360 361 start_serving set to True (default) causes the created server 362 to start accepting connections immediately. When set to False, 363 the user should await Server.start_serving() or Server.serve_forever() 364 to make the server to start accepting connections. 365 """ 366 raise NotImplementedError 367 368 async def sendfile(self, transport, file, offset=0, count=None, 369 *, fallback=True): 370 """Send a file through a transport. 371 372 Return an amount of sent bytes. 373 """ 374 raise NotImplementedError 375 376 async def start_tls(self, transport, protocol, sslcontext, *, 377 server_side=False, 378 server_hostname=None, 379 ssl_handshake_timeout=None, 380 ssl_shutdown_timeout=None): 381 """Upgrade a transport to TLS. 382 383 Return a new transport that *protocol* should start using 384 immediately. 385 """ 386 raise NotImplementedError 387 388 async def create_unix_connection( 389 self, protocol_factory, path=None, *, 390 ssl=None, sock=None, 391 server_hostname=None, 392 ssl_handshake_timeout=None, 393 ssl_shutdown_timeout=None): 394 raise NotImplementedError 395 396 async def create_unix_server( 397 self, protocol_factory, path=None, *, 398 sock=None, backlog=100, ssl=None, 399 ssl_handshake_timeout=None, 400 ssl_shutdown_timeout=None, 401 start_serving=True): 402 """A coroutine which creates a UNIX Domain Socket server. 403 404 The return value is a Server object, which can be used to stop 405 the service. 406 407 path is a str, representing a file system path to bind the 408 server socket to. 409 410 sock can optionally be specified in order to use a preexisting 411 socket object. 412 413 backlog is the maximum number of queued connections passed to 414 listen() (defaults to 100). 415 416 ssl can be set to an SSLContext to enable SSL over the 417 accepted connections. 418 419 ssl_handshake_timeout is the time in seconds that an SSL server 420 will wait for the SSL handshake to complete (defaults to 60s). 421 422 ssl_shutdown_timeout is the time in seconds that an SSL server 423 will wait for the SSL shutdown to finish (defaults to 30s). 424 425 start_serving set to True (default) causes the created server 426 to start accepting connections immediately. When set to False, 427 the user should await Server.start_serving() or Server.serve_forever() 428 to make the server to start accepting connections. 429 """ 430 raise NotImplementedError 431 432 async def connect_accepted_socket( 433 self, protocol_factory, sock, 434 *, ssl=None, 435 ssl_handshake_timeout=None, 436 ssl_shutdown_timeout=None): 437 """Handle an accepted connection. 438 439 This is used by servers that accept connections outside of 440 asyncio, but use asyncio to handle connections. 441 442 This method is a coroutine. When completed, the coroutine 443 returns a (transport, protocol) pair. 444 """ 445 raise NotImplementedError 446 447 async def create_datagram_endpoint(self, protocol_factory, 448 local_addr=None, remote_addr=None, *, 449 family=0, proto=0, flags=0, 450 reuse_address=None, reuse_port=None, 451 allow_broadcast=None, sock=None): 452 """A coroutine which creates a datagram endpoint. 453 454 This method will try to establish the endpoint in the background. 455 When successful, the coroutine returns a (transport, protocol) pair. 456 457 protocol_factory must be a callable returning a protocol instance. 458 459 socket family AF_INET, socket.AF_INET6 or socket.AF_UNIX depending on 460 host (or family if specified), socket type SOCK_DGRAM. 461 462 reuse_address tells the kernel to reuse a local socket in 463 TIME_WAIT state, without waiting for its natural timeout to 464 expire. If not specified it will automatically be set to True on 465 UNIX. 466 467 reuse_port tells the kernel to allow this endpoint to be bound to 468 the same port as other existing endpoints are bound to, so long as 469 they all set this flag when being created. This option is not 470 supported on Windows and some UNIX's. If the 471 :py:data:`~socket.SO_REUSEPORT` constant is not defined then this 472 capability is unsupported. 473 474 allow_broadcast tells the kernel to allow this endpoint to send 475 messages to the broadcast address. 476 477 sock can optionally be specified in order to use a preexisting 478 socket object. 479 """ 480 raise NotImplementedError 481 482 # Pipes and subprocesses. 483 484 async def connect_read_pipe(self, protocol_factory, pipe): 485 """Register read pipe in event loop. Set the pipe to non-blocking mode. 486 487 protocol_factory should instantiate object with Protocol interface. 488 pipe is a file-like object. 489 Return pair (transport, protocol), where transport supports the 490 ReadTransport interface.""" 491 # The reason to accept file-like object instead of just file descriptor 492 # is: we need to own pipe and close it at transport finishing 493 # Can got complicated errors if pass f.fileno(), 494 # close fd in pipe transport then close f and vice versa. 495 raise NotImplementedError 496 497 async def connect_write_pipe(self, protocol_factory, pipe): 498 """Register write pipe in event loop. 499 500 protocol_factory should instantiate object with BaseProtocol interface. 501 Pipe is file-like object already switched to nonblocking. 502 Return pair (transport, protocol), where transport support 503 WriteTransport interface.""" 504 # The reason to accept file-like object instead of just file descriptor 505 # is: we need to own pipe and close it at transport finishing 506 # Can got complicated errors if pass f.fileno(), 507 # close fd in pipe transport then close f and vice versa. 508 raise NotImplementedError 509 510 async def subprocess_shell(self, protocol_factory, cmd, *, 511 stdin=subprocess.PIPE, 512 stdout=subprocess.PIPE, 513 stderr=subprocess.PIPE, 514 **kwargs): 515 raise NotImplementedError 516 517 async def subprocess_exec(self, protocol_factory, *args, 518 stdin=subprocess.PIPE, 519 stdout=subprocess.PIPE, 520 stderr=subprocess.PIPE, 521 **kwargs): 522 raise NotImplementedError 523 524 # Ready-based callback registration methods. 525 # The add_*() methods return None. 526 # The remove_*() methods return True if something was removed, 527 # False if there was nothing to delete. 528 529 def add_reader(self, fd, callback, *args): 530 raise NotImplementedError 531 532 def remove_reader(self, fd): 533 raise NotImplementedError 534 535 def add_writer(self, fd, callback, *args): 536 raise NotImplementedError 537 538 def remove_writer(self, fd): 539 raise NotImplementedError 540 541 # Completion based I/O methods returning Futures. 542 543 async def sock_recv(self, sock, nbytes): 544 raise NotImplementedError 545 546 async def sock_recv_into(self, sock, buf): 547 raise NotImplementedError 548 549 async def sock_recvfrom(self, sock, bufsize): 550 raise NotImplementedError 551 552 async def sock_recvfrom_into(self, sock, buf, nbytes=0): 553 raise NotImplementedError 554 555 async def sock_sendall(self, sock, data): 556 raise NotImplementedError 557 558 async def sock_sendto(self, sock, data, address): 559 raise NotImplementedError 560 561 async def sock_connect(self, sock, address): 562 raise NotImplementedError 563 564 async def sock_accept(self, sock): 565 raise NotImplementedError 566 567 async def sock_sendfile(self, sock, file, offset=0, count=None, 568 *, fallback=None): 569 raise NotImplementedError 570 571 # Signal handling. 572 573 def add_signal_handler(self, sig, callback, *args): 574 raise NotImplementedError 575 576 def remove_signal_handler(self, sig): 577 raise NotImplementedError 578 579 # Task factory. 580 581 def set_task_factory(self, factory): 582 raise NotImplementedError 583 584 def get_task_factory(self): 585 raise NotImplementedError 586 587 # Error handlers. 588 589 def get_exception_handler(self): 590 raise NotImplementedError 591 592 def set_exception_handler(self, handler): 593 raise NotImplementedError 594 595 def default_exception_handler(self, context): 596 raise NotImplementedError 597 598 def call_exception_handler(self, context): 599 raise NotImplementedError 600 601 # Debug flag management. 602 603 def get_debug(self): 604 raise NotImplementedError 605 606 def set_debug(self, enabled): 607 raise NotImplementedError 608 609 610class AbstractEventLoopPolicy: 611 """Abstract policy for accessing the event loop.""" 612 613 def get_event_loop(self): 614 """Get the event loop for the current context. 615 616 Returns an event loop object implementing the BaseEventLoop interface, 617 or raises an exception in case no event loop has been set for the 618 current context and the current policy does not specify to create one. 619 620 It should never return None.""" 621 raise NotImplementedError 622 623 def set_event_loop(self, loop): 624 """Set the event loop for the current context to loop.""" 625 raise NotImplementedError 626 627 def new_event_loop(self): 628 """Create and return a new event loop object according to this 629 policy's rules. If there's need to set this loop as the event loop for 630 the current context, set_event_loop must be called explicitly.""" 631 raise NotImplementedError 632 633 # Child processes handling (Unix only). 634 635 def get_child_watcher(self): 636 "Get the watcher for child processes." 637 raise NotImplementedError 638 639 def set_child_watcher(self, watcher): 640 """Set the watcher for child processes.""" 641 raise NotImplementedError 642 643 644class BaseDefaultEventLoopPolicy(AbstractEventLoopPolicy): 645 """Default policy implementation for accessing the event loop. 646 647 In this policy, each thread has its own event loop. However, we 648 only automatically create an event loop by default for the main 649 thread; other threads by default have no event loop. 650 651 Other policies may have different rules (e.g. a single global 652 event loop, or automatically creating an event loop per thread, or 653 using some other notion of context to which an event loop is 654 associated). 655 """ 656 657 _loop_factory = None 658 659 class _Local(threading.local): 660 _loop = None 661 _set_called = False 662 663 def __init__(self): 664 self._local = self._Local() 665 666 def get_event_loop(self): 667 """Get the event loop for the current context. 668 669 Returns an instance of EventLoop or raises an exception. 670 """ 671 if (self._local._loop is None and 672 not self._local._set_called and 673 threading.current_thread() is threading.main_thread()): 674 self.set_event_loop(self.new_event_loop()) 675 676 if self._local._loop is None: 677 raise RuntimeError('There is no current event loop in thread %r.' 678 % threading.current_thread().name) 679 680 return self._local._loop 681 682 def set_event_loop(self, loop): 683 """Set the event loop.""" 684 self._local._set_called = True 685 if loop is not None and not isinstance(loop, AbstractEventLoop): 686 raise TypeError(f"loop must be an instance of AbstractEventLoop or None, not '{type(loop).__name__}'") 687 self._local._loop = loop 688 689 def new_event_loop(self): 690 """Create a new event loop. 691 692 You must call set_event_loop() to make this the current event 693 loop. 694 """ 695 return self._loop_factory() 696 697 698# Event loop policy. The policy itself is always global, even if the 699# policy's rules say that there is an event loop per thread (or other 700# notion of context). The default policy is installed by the first 701# call to get_event_loop_policy(). 702_event_loop_policy = None 703 704# Lock for protecting the on-the-fly creation of the event loop policy. 705_lock = threading.Lock() 706 707 708# A TLS for the running event loop, used by _get_running_loop. 709class _RunningLoop(threading.local): 710 loop_pid = (None, None) 711 712 713_running_loop = _RunningLoop() 714 715 716def get_running_loop(): 717 """Return the running event loop. Raise a RuntimeError if there is none. 718 719 This function is thread-specific. 720 """ 721 # NOTE: this function is implemented in C (see _asynciomodule.c) 722 loop = _get_running_loop() 723 if loop is None: 724 raise RuntimeError('no running event loop') 725 return loop 726 727 728def _get_running_loop(): 729 """Return the running event loop or None. 730 731 This is a low-level function intended to be used by event loops. 732 This function is thread-specific. 733 """ 734 # NOTE: this function is implemented in C (see _asynciomodule.c) 735 running_loop, pid = _running_loop.loop_pid 736 if running_loop is not None and pid == os.getpid(): 737 return running_loop 738 739 740def _set_running_loop(loop): 741 """Set the running event loop. 742 743 This is a low-level function intended to be used by event loops. 744 This function is thread-specific. 745 """ 746 # NOTE: this function is implemented in C (see _asynciomodule.c) 747 _running_loop.loop_pid = (loop, os.getpid()) 748 749 750def _init_event_loop_policy(): 751 global _event_loop_policy 752 with _lock: 753 if _event_loop_policy is None: # pragma: no branch 754 from . import DefaultEventLoopPolicy 755 _event_loop_policy = DefaultEventLoopPolicy() 756 757 758def get_event_loop_policy(): 759 """Get the current event loop policy.""" 760 if _event_loop_policy is None: 761 _init_event_loop_policy() 762 return _event_loop_policy 763 764 765def set_event_loop_policy(policy): 766 """Set the current event loop policy. 767 768 If policy is None, the default policy is restored.""" 769 global _event_loop_policy 770 if policy is not None and not isinstance(policy, AbstractEventLoopPolicy): 771 raise TypeError(f"policy must be an instance of AbstractEventLoopPolicy or None, not '{type(policy).__name__}'") 772 _event_loop_policy = policy 773 774 775def get_event_loop(): 776 """Return an asyncio event loop. 777 778 When called from a coroutine or a callback (e.g. scheduled with call_soon 779 or similar API), this function will always return the running event loop. 780 781 If there is no running event loop set, the function will return 782 the result of `get_event_loop_policy().get_event_loop()` call. 783 """ 784 # NOTE: this function is implemented in C (see _asynciomodule.c) 785 return _py__get_event_loop() 786 787 788def _get_event_loop(stacklevel=3): 789 # This internal method is going away in Python 3.12, left here only for 790 # backwards compatibility with 3.10.0 - 3.10.8 and 3.11.0. 791 # Similarly, this method's C equivalent in _asyncio is going away as well. 792 # See GH-99949 for more details. 793 current_loop = _get_running_loop() 794 if current_loop is not None: 795 return current_loop 796 return get_event_loop_policy().get_event_loop() 797 798 799def set_event_loop(loop): 800 """Equivalent to calling get_event_loop_policy().set_event_loop(loop).""" 801 get_event_loop_policy().set_event_loop(loop) 802 803 804def new_event_loop(): 805 """Equivalent to calling get_event_loop_policy().new_event_loop().""" 806 return get_event_loop_policy().new_event_loop() 807 808 809def get_child_watcher(): 810 """Equivalent to calling get_event_loop_policy().get_child_watcher().""" 811 return get_event_loop_policy().get_child_watcher() 812 813 814def set_child_watcher(watcher): 815 """Equivalent to calling 816 get_event_loop_policy().set_child_watcher(watcher).""" 817 return get_event_loop_policy().set_child_watcher(watcher) 818 819 820# Alias pure-Python implementations for testing purposes. 821_py__get_running_loop = _get_running_loop 822_py__set_running_loop = _set_running_loop 823_py_get_running_loop = get_running_loop 824_py_get_event_loop = get_event_loop 825_py__get_event_loop = _get_event_loop 826 827 828try: 829 # get_event_loop() is one of the most frequently called 830 # functions in asyncio. Pure Python implementation is 831 # about 4 times slower than C-accelerated. 832 from _asyncio import (_get_running_loop, _set_running_loop, 833 get_running_loop, get_event_loop, _get_event_loop) 834except ImportError: 835 pass 836else: 837 # Alias C implementations for testing purposes. 838 _c__get_running_loop = _get_running_loop 839 _c__set_running_loop = _set_running_loop 840 _c_get_running_loop = get_running_loop 841 _c_get_event_loop = get_event_loop 842 _c__get_event_loop = _get_event_loop 843