Buckets:
MisterAI/LocalAI_Demo_backends / cpu-diffusers /venv /lib /python3.10 /site-packages /nest_asyncio2.py
| """Patch asyncio to allow nested event loops.""" | |
| import asyncio | |
| import asyncio.events as events | |
| import os | |
| import sys | |
| import threading | |
| from contextlib import contextmanager, suppress | |
| from heapq import heappop | |
| _run_close_loop = True | |
| class _NestAsyncio2: | |
| '''Internal class of `nest_asyncio2`. | |
| Mainly for holding the original properties to support unapply() and nest_asyncio2.run(). | |
| ''' | |
| pass | |
| def apply( | |
| loop=None, | |
| *, | |
| run_close_loop: bool = False, | |
| error_on_mispatched: bool = False | |
| ): | |
| '''Patch asyncio to make its event loop reentrant. | |
| - `run_close_loop`: Close the event loop created by `asyncio.run()`, if any. | |
| See README for details. | |
| - `error_on_mispatched`: | |
| - `False` (default): Warn if asyncio is already patched by `nest_asyncio` on Python 3.12+. | |
| - `True`: Raise `RuntimeError` if asyncio is already patched by `nest_asyncio`. | |
| ''' | |
| global _run_close_loop | |
| _patch_asyncio(error_on_mispatched=error_on_mispatched) | |
| _patch_policy() | |
| _patch_tornado() | |
| loop = loop or _get_event_loop() | |
| if loop is not None: | |
| _patch_loop(loop) | |
| _run_close_loop &= run_close_loop | |
| if sys.version_info < (3, 12, 0): | |
| def _get_event_loop(): | |
| return asyncio.get_event_loop() | |
| elif sys.version_info < (3, 14, 0): | |
| def _get_event_loop(): | |
| # Python 3.12~3.13: | |
| # Calling get_event_loop() will result in ResourceWarning: unclosed event loop | |
| loop = events._get_running_loop() | |
| if loop is None: | |
| policy = events.get_event_loop_policy() | |
| loop = policy._local._loop | |
| return loop | |
| else: | |
| def _get_event_loop(): | |
| # Python 3.14: Raises a RuntimeError if there is no current event loop. | |
| try: | |
| return asyncio.get_event_loop() | |
| except RuntimeError: | |
| return None | |
| if sys.version_info < (3, 12, 0): | |
| def run(main, *, debug=False): | |
| loop = asyncio.get_event_loop() | |
| loop.set_debug(debug) | |
| task = asyncio.ensure_future(main) | |
| try: | |
| return loop.run_until_complete(task) | |
| finally: | |
| if not task.done(): | |
| task.cancel() | |
| with suppress(asyncio.CancelledError): | |
| loop.run_until_complete(task) | |
| else: | |
| def run(main, *, debug=False, loop_factory=None): | |
| new_event_loop = False | |
| set_event_loop = None | |
| try: | |
| loop = asyncio.get_running_loop() | |
| except RuntimeError: | |
| # if sys.version_info < (3, 16, 0): | |
| # policy = asyncio.events._get_event_loop_policy() | |
| # try: | |
| # loop = policy.get_event_loop() | |
| # except RuntimeError: | |
| # loop = loop_factory() | |
| # else: | |
| # loop = loop_factory() | |
| if not _run_close_loop: | |
| # Not running | |
| loop = _get_event_loop() | |
| if loop is None: | |
| if loop_factory is None: | |
| loop_factory = asyncio.new_event_loop | |
| loop = loop_factory() | |
| asyncio.set_event_loop(loop) | |
| else: | |
| if loop_factory is None: | |
| loop = asyncio.new_event_loop() | |
| # Not running | |
| set_event_loop = _get_event_loop() | |
| asyncio.set_event_loop(loop) | |
| else: | |
| loop = loop_factory() | |
| new_event_loop = True | |
| _patch_loop(loop) | |
| loop.set_debug(debug) | |
| task = asyncio.ensure_future(main, loop=loop) | |
| try: | |
| return loop.run_until_complete(task) | |
| finally: | |
| if not task.done(): | |
| task.cancel() | |
| with suppress(asyncio.CancelledError): | |
| loop.run_until_complete(task) | |
| if set_event_loop: | |
| # asyncio.Runner just set_event_loop(None) but we are nested | |
| asyncio.set_event_loop(set_event_loop) | |
| if new_event_loop: | |
| # Avoid ResourceWarning: unclosed event loop | |
| loop.close() | |
| def _patch_asyncio(*, error_on_mispatched: bool = False): | |
| """Patch asyncio module to use pure Python tasks and futures.""" | |
| def _get_event_loop(stacklevel=3): | |
| loop = events._get_running_loop() | |
| if loop is None: | |
| loop = events.get_event_loop_policy().get_event_loop() | |
| return loop | |
| # Use module level _current_tasks, all_tasks and patch run method. | |
| if hasattr(asyncio, '_nest_patched'): | |
| if not hasattr(asyncio, '_nest_asyncio2'): | |
| if error_on_mispatched: | |
| raise RuntimeError('asyncio is already patched by nest_asyncio') | |
| elif sys.version_info >= (3, 12, 0): | |
| import warnings | |
| warnings.warn('asyncio is already patched by nest_asyncio. You may encounter bugs related to asyncio') | |
| return | |
| # Using _PyTask on Python 3.14+ will break current_task() (and all_tasks(), | |
| # _swap_current_task()) | |
| # Even we replace it with _py_current_task(), it only works with _PyTask, but | |
| # the external loop is probably using _CTask. | |
| # https://github.com/python/cpython/pull/129899 | |
| if sys.version_info >= (3, 6, 0) and sys.version_info < (3, 14, 0): | |
| asyncio.Task = asyncio.tasks._CTask = asyncio.tasks.Task = \ | |
| asyncio.tasks._PyTask | |
| asyncio.Future = asyncio.futures._CFuture = asyncio.futures.Future = \ | |
| asyncio.futures._PyFuture | |
| if sys.version_info < (3, 7, 0): | |
| asyncio.tasks._current_tasks = asyncio.tasks.Task._current_tasks | |
| asyncio.all_tasks = asyncio.tasks.Task.all_tasks | |
| # The same as asyncio.get_event_loop() on at least Python 3.14 | |
| if sys.version_info >= (3, 9, 0) and sys.version_info < (3, 14, 0): | |
| events._get_event_loop = events.get_event_loop = \ | |
| asyncio.get_event_loop = _get_event_loop | |
| asyncio.run = run | |
| asyncio._nest_patched = True | |
| asyncio._nest_asyncio2 = _NestAsyncio2() | |
| def _patch_policy(): | |
| """Patch the policy to always return a patched loop.""" | |
| # Python 3.14: | |
| # get_event_loop() raises a RuntimeError if there is no current event loop. | |
| # So there is no need to _patch_loop() in it. | |
| # Patching new_event_loop() may be better, but policy is going to be removed... | |
| # Removed in Python 3.16 | |
| # https://github.com/python/cpython/issues/127949 | |
| if sys.version_info >= (3, 14, 0): | |
| return | |
| def get_event_loop(self): | |
| if self._local._loop is None: | |
| loop = self.new_event_loop() | |
| _patch_loop(loop) | |
| self.set_event_loop(loop) | |
| return self._local._loop | |
| if sys.version_info < (3, 14, 0): | |
| policy = events.get_event_loop_policy() | |
| else: | |
| policy = events._get_event_loop_policy() | |
| policy.__class__.get_event_loop = get_event_loop | |
| def _context_entered(context): | |
| """Return True if ``context`` is already entered (and so cannot be run).""" | |
| if context is None: # Python < 3.7 handles have no Context | |
| return False | |
| try: | |
| # Context has no public "entered" flag; running a no-op (int) is the easy check | |
| context.run(int) | |
| except RuntimeError: | |
| return True | |
| return False | |
| def _patch_loop(loop): | |
| """Patch loop to make it reentrant.""" | |
| def run_forever(self): | |
| with manage_run(self), manage_asyncgens(self): | |
| while True: | |
| self._run_once() | |
| if self._stopping: | |
| break | |
| self._stopping = False | |
| def run_until_complete(self, future): | |
| with manage_run(self): | |
| f = asyncio.ensure_future(future, loop=self) | |
| if f is not future: | |
| f._log_destroy_pending = False | |
| while not f.done(): | |
| self._run_once() | |
| if self._stopping: | |
| break | |
| if not f.done(): | |
| raise RuntimeError( | |
| 'Event loop stopped before Future completed.') | |
| # When a task completes inside _run_once(), Task.__step calls | |
| # Future.set_result(), which schedules all done callbacks via call_soon(). | |
| # These callbacks are added to loop._ready but the `while not f.done()` loop | |
| # exits immediately — before the next _run_once() that would process them. | |
| # https://github.com/Chaoses-Ib/nest-asyncio2/issues/3 | |
| # Process any callbacks scheduled during task completion | |
| # (e.g. task done callbacks added via call_soon in set_result). | |
| if self._ready: | |
| self._run_once() | |
| return f.result() | |
| def _run_once(self): | |
| """ | |
| Simplified re-implementation of asyncio's _run_once that | |
| runs handles as they become ready. | |
| """ | |
| ready = self._ready | |
| scheduled = self._scheduled | |
| while scheduled and scheduled[0]._cancelled: | |
| heappop(scheduled) | |
| timeout = ( | |
| 0 if ready or self._stopping | |
| else min(max( | |
| scheduled[0]._when - self.time(), 0), 86400) if scheduled | |
| else None) | |
| event_list = self._selector.select(timeout) | |
| self._process_events(event_list) | |
| end_time = self.time() + self._clock_resolution | |
| while scheduled and scheduled[0]._when < end_time: | |
| handle = heappop(scheduled) | |
| ready.append(handle) | |
| for _ in range(len(ready)): | |
| if not ready: | |
| break | |
| handle = ready.popleft() | |
| if not handle._cancelled: | |
| if _context_entered(getattr(handle, '_context', None)): | |
| # The handle's Context is entered further up the stack (e.g., | |
| # ipykernel >= 7 runs every cell in one shared Context), so | |
| # running it now would raise; defer it until this nested run | |
| # exits. | |
| deferred = self._nest_deferred | |
| if deferred is None: | |
| ready.append(handle) | |
| else: | |
| deferred.append(handle) | |
| continue | |
| # preempt the current task so that that checks in | |
| # Task.__step do not raise | |
| if sys.version_info < (3, 14, 0): | |
| curr_task = curr_tasks.pop(self, None) | |
| else: | |
| # Work with both C and Py | |
| try: | |
| curr_task = asyncio.tasks._swap_current_task(self, None) | |
| except KeyError: | |
| curr_task = None | |
| try: | |
| handle._run() | |
| finally: | |
| # restore the current task | |
| if curr_task is not None: | |
| if sys.version_info < (3, 14, 0): | |
| curr_tasks[self] = curr_task | |
| else: | |
| # Work with both C and Py | |
| asyncio.tasks._swap_current_task(self, curr_task) | |
| handle = None | |
| def manage_run(self): | |
| """Set up the loop for running.""" | |
| self._check_closed() | |
| old_thread_id = self._thread_id | |
| old_running_loop = events._get_running_loop() | |
| old_deferred = self._nest_deferred | |
| self._nest_deferred = [] | |
| try: | |
| self._thread_id = threading.get_ident() | |
| events._set_running_loop(self) | |
| self._num_runs_pending += 1 | |
| if self._is_proactorloop: | |
| if self._self_reading_future is None: | |
| self.call_soon(self._loop_self_reading) | |
| yield | |
| finally: | |
| self._ready.extendleft(reversed(self._nest_deferred)) | |
| self._nest_deferred = old_deferred | |
| self._thread_id = old_thread_id | |
| events._set_running_loop(old_running_loop) | |
| self._num_runs_pending -= 1 | |
| if self._is_proactorloop: | |
| if (self._num_runs_pending == 0 | |
| and self._self_reading_future is not None): | |
| ov = self._self_reading_future._ov | |
| self._self_reading_future.cancel() | |
| if ov is not None: | |
| self._proactor._unregister(ov) | |
| self._self_reading_future = None | |
| def manage_asyncgens(self): | |
| if not hasattr(sys, 'get_asyncgen_hooks'): | |
| # Python version is too old. | |
| return | |
| old_agen_hooks = sys.get_asyncgen_hooks() | |
| try: | |
| self._set_coroutine_origin_tracking(self._debug) | |
| if self._asyncgens is not None: | |
| sys.set_asyncgen_hooks( | |
| firstiter=self._asyncgen_firstiter_hook, | |
| finalizer=self._asyncgen_finalizer_hook) | |
| yield | |
| finally: | |
| self._set_coroutine_origin_tracking(False) | |
| if self._asyncgens is not None: | |
| sys.set_asyncgen_hooks(*old_agen_hooks) | |
| def _check_running(self): | |
| """Do not throw exception if loop is already running.""" | |
| pass | |
| if hasattr(loop, '_nest_patched'): | |
| return | |
| if not isinstance(loop, asyncio.BaseEventLoop): | |
| raise ValueError('Can\'t patch loop of type %s' % type(loop)) | |
| cls = loop.__class__ | |
| cls.run_forever = run_forever | |
| cls.run_until_complete = run_until_complete | |
| cls._run_once = _run_once | |
| cls._check_running = _check_running | |
| cls._check_runnung = _check_running # typo in Python 3.7 source | |
| cls._num_runs_pending = 1 if loop.is_running() else 0 | |
| cls._is_proactorloop = ( | |
| os.name == 'nt' and issubclass(cls, asyncio.ProactorEventLoop)) | |
| if sys.version_info < (3, 7, 0): | |
| cls._set_coroutine_origin_tracking = cls._set_coroutine_wrapper | |
| curr_tasks = asyncio.tasks._current_tasks \ | |
| if sys.version_info >= (3, 7, 0) else asyncio.Task._current_tasks | |
| cls._nest_deferred = None | |
| cls._nest_patched = True | |
| cls._nest_asyncio2 = _NestAsyncio2() | |
| def _patch_tornado(): | |
| """ | |
| If tornado is imported before nest_asyncio, make tornado aware of | |
| the pure-Python asyncio Future. | |
| """ | |
| if 'tornado' in sys.modules: | |
| import tornado.concurrent as tc # type: ignore | |
| tc.Future = asyncio.Future | |
| if asyncio.Future not in tc.FUTURES: | |
| tc.FUTURES += (asyncio.Future,) | |
Xet Storage Details
- Size:
- 15 kB
- Xet hash:
- 43226af6085083493365ca0a4a27de0249744e73c9ce522d91d3df28f1913722
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.