mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-04-23 11:56:36 +00:00
Initial commit
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
"""Minimal backported implementation of asyncio._PyTask from 3.11 compatible down to Python 3.8."""
|
||||
|
||||
import asyncio.tasks
|
||||
import sys
|
||||
from asyncio import AbstractEventLoop
|
||||
from typing import Coroutine, TypeVar, Any, Optional
|
||||
|
||||
_T = TypeVar("_T")
|
||||
|
||||
|
||||
# See https://github.com/python/cpython/blob/3.11/Lib/asyncio/tasks.py
|
||||
|
||||
|
||||
class Task(asyncio.tasks._PyTask): # type: ignore[name-defined, misc]
|
||||
"""A coroutine wrapped in a Future."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coro: Coroutine[Any, Any, _T],
|
||||
*,
|
||||
loop: Optional[AbstractEventLoop] = None,
|
||||
name: Optional[str] = None,
|
||||
) -> None:
|
||||
self._num_cancels_requested = 0
|
||||
# https://github.com/python/cpython/blob/3.11/Modules/_asynciomodule.c#L2026
|
||||
# Backport Note: self._context is temporarily patched in Runner.run() instead.
|
||||
super().__init__(coro, loop=loop, name=name)
|
||||
|
||||
def cancel(self, msg: Optional[str] = None) -> bool:
|
||||
"""Request that this task cancel itself.
|
||||
|
||||
This arranges for a CancelledError to be thrown into the
|
||||
wrapped coroutine on the next cycle through the event loop.
|
||||
The coroutine then has a chance to clean up or even deny
|
||||
the request using try/except/finally.
|
||||
|
||||
Unlike Future.cancel, this does not guarantee that the
|
||||
task will be cancelled: the exception might be caught and
|
||||
acted upon, delaying cancellation of the task or preventing
|
||||
cancellation completely. The task may also return a value or
|
||||
raise a different exception.
|
||||
|
||||
Immediately after this method is called, Task.cancelled() will
|
||||
not return True (unless the task was already cancelled). A
|
||||
task will be marked as cancelled when the wrapped coroutine
|
||||
terminates with a CancelledError exception (even if cancel()
|
||||
was not called).
|
||||
|
||||
This also increases the task's count of cancellation requests.
|
||||
"""
|
||||
self._log_traceback = False
|
||||
if self.done():
|
||||
return False
|
||||
self._num_cancels_requested += 1
|
||||
# These two lines are controversial. See discussion starting at
|
||||
# https://github.com/python/cpython/pull/31394#issuecomment-1053545331
|
||||
# Also remember that this is duplicated in _asynciomodule.c.
|
||||
# if self._num_cancels_requested > 1:
|
||||
# return False
|
||||
if self._fut_waiter is not None:
|
||||
if sys.version_info >= (3, 9):
|
||||
if self._fut_waiter.cancel(msg=msg):
|
||||
# Leave self._fut_waiter; it may be a Task that
|
||||
# catches and ignores the cancellation so we may have
|
||||
# to cancel it again later.
|
||||
return True
|
||||
else:
|
||||
if self._fut_waiter.cancel():
|
||||
return True
|
||||
# It must be the case that self.__step is already scheduled.
|
||||
self._must_cancel = True
|
||||
if sys.version_info >= (3, 9):
|
||||
self._cancel_message = msg
|
||||
return True
|
||||
|
||||
def cancelling(self) -> int:
|
||||
"""Return the count of the task's cancellation requests.
|
||||
|
||||
This count is incremented when .cancel() is called
|
||||
and may be decremented using .uncancel().
|
||||
"""
|
||||
return self._num_cancels_requested
|
||||
|
||||
def uncancel(self) -> int:
|
||||
"""Decrement the task's count of cancellation requests.
|
||||
|
||||
This should be called by the party that called `cancel()` on the task
|
||||
beforehand.
|
||||
|
||||
Returns the remaining number of cancellation requests.
|
||||
"""
|
||||
if self._num_cancels_requested > 0:
|
||||
self._num_cancels_requested -= 1
|
||||
return self._num_cancels_requested
|
||||
Reference in New Issue
Block a user