Skip to content

Commit f6bcfd1

Browse files
committed
Add EmptyTask class
1 parent 0041c80 commit f6bcfd1

File tree

4 files changed

+39
-12
lines changed

4 files changed

+39
-12
lines changed

reportportal_client/aio/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@
2222
BatchedRPClient,
2323
ThreadedRPClient,
2424
)
25-
from reportportal_client.aio.tasks import BlockingOperationError, Task
25+
from reportportal_client.aio.tasks import BlockingOperationError, EmptyTask, Task
2626

2727
__all__ = [
2828
"Task",
29+
"EmptyTask",
2930
"BlockingOperationError",
3031
"DEFAULT_TASK_TIMEOUT",
3132
"DEFAULT_SHUTDOWN_TIMEOUT",

reportportal_client/aio/client.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
# noinspection PyProtectedMember
5757
from reportportal_client._internal.static.abstract import AbstractBaseClass, abstractmethod
5858
from reportportal_client._internal.static.defines import DEFAULT_LOG_LEVEL
59+
from reportportal_client.aio import EmptyTask
5960

6061
# noinspection PyProtectedMember
6162
from reportportal_client.aio.tasks import Task
@@ -1311,7 +1312,7 @@ def __init__(
13111312
set_current(self)
13121313

13131314
@abstractmethod
1314-
def create_task(self, coro: Coroutine[Any, Any, _T]) -> Optional[Task[_T]]:
1315+
def create_task(self, coro: Coroutine[Any, Any, _T]) -> Task[_T]:
13151316
"""Create a Task from given Coroutine.
13161317
13171318
:param coro: Coroutine which will be used for the Task creation.
@@ -1572,7 +1573,7 @@ def get_launch_ui_url(self) -> Task[Optional[str]]:
15721573
result_task = self.create_task(result_coro)
15731574
return result_task
15741575

1575-
def get_project_settings(self) -> Task[Optional[str]]:
1576+
def get_project_settings(self) -> Task[Optional[dict]]:
15761577
"""Get settings of the current Project.
15771578
15781579
:return: Settings response in Dictionary.
@@ -1685,8 +1686,9 @@ def __init_loop(self, loop: Optional[asyncio.AbstractEventLoop] = None):
16851686
self._loop = asyncio.new_event_loop()
16861687
self._loop.set_task_factory(ThreadedTaskFactory(self.task_timeout))
16871688
self.__heartbeat()
1688-
self._thread = threading.Thread(target=self._loop.run_forever, name="RP-Async-Client", daemon=True)
1689-
self._thread.start()
1689+
thread = threading.Thread(target=self._loop.run_forever, name="RP-Async-Client", daemon=True)
1690+
thread.start()
1691+
self._thread = thread
16901692

16911693
async def __return_value(self, value):
16921694
return value
@@ -1758,14 +1760,14 @@ def __init__(
17581760
else:
17591761
super().__init__(endpoint, project, launch_uuid=launch_uuid, **kwargs)
17601762

1761-
def create_task(self, coro: Coroutine[Any, Any, _T]) -> Optional[Task[_T]]:
1763+
def create_task(self, coro: Coroutine[Any, Any, _T]) -> Task[_T]:
17621764
"""Create a Task from given Coroutine.
17631765
17641766
:param coro: Coroutine which will be used for the Task creation.
17651767
:return: Task instance.
17661768
"""
17671769
if not getattr(self, "_loop", None):
1768-
return None
1770+
return EmptyTask()
17691771
result = self._loop.create_task(coro)
17701772
with self._task_mutex:
17711773
self._task_list.append(result)
@@ -1951,14 +1953,14 @@ def __init__(
19511953
else:
19521954
super().__init__(endpoint, project, launch_uuid=launch_uuid, **kwargs)
19531955

1954-
def create_task(self, coro: Coroutine[Any, Any, _T]) -> Optional[Task[_T]]:
1956+
def create_task(self, coro: Coroutine[Any, Any, _T]) -> Task[_T]:
19551957
"""Create a Task from given Coroutine.
19561958
19571959
:param coro: Coroutine which will be used for the Task creation.
19581960
:return: Task instance.
19591961
"""
19601962
if not getattr(self, "_loop", None):
1961-
return None
1963+
return EmptyTask()
19621964
result = self._loop.create_task(coro)
19631965
with self._task_mutex:
19641966
tasks = self._task_list.append(result)

reportportal_client/aio/tasks.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def __init__(
5555
self,
5656
coro: _TaskCompatibleCoro,
5757
*,
58-
loop: asyncio.AbstractEventLoop,
58+
loop: Optional[asyncio.AbstractEventLoop],
5959
name: Optional[str] = None,
6060
) -> None:
6161
"""Initialize an instance of the Task.
@@ -92,3 +92,26 @@ def __str__(self):
9292
if self.done():
9393
return str(self.result())
9494
return super().__str__()
95+
96+
97+
class EmptyTask(Task[None]):
98+
"""Task implementation which always returns None."""
99+
100+
@staticmethod
101+
async def __empty_coro() -> None:
102+
return None
103+
104+
def __init__(self) -> None:
105+
"""Initialize an EmptyTask.
106+
107+
The class provides a no-op coroutine because ``asyncio.Task`` requires a non-None coroutine object.
108+
"""
109+
super().__init__(self.__empty_coro(), loop=None)
110+
111+
def blocking_result(self) -> None:
112+
"""Return None without blocking."""
113+
return None
114+
115+
def result(self) -> None:
116+
"""Return None regardless of the task state."""
117+
return None

reportportal_client/helpers/common_helpers.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@
2323
from datetime import datetime, timezone
2424
from platform import machine, processor, system
2525
from types import MappingProxyType
26-
from typing import Any, Callable, Generic, Iterable, Optional, Sized, TypeVar, Union
26+
from typing import Any, Callable, Coroutine, Generic, Iterable, Optional, Sized, TypeVar, Union
2727

28+
from reportportal_client.aio import Task
2829
from reportportal_client.core.rp_file import RPFile
2930

3031
try:
@@ -401,7 +402,7 @@ def agent_name_version(attributes: Optional[Union[list, dict]] = None) -> tuple[
401402
return agent_name, agent_version
402403

403404

404-
async def await_if_necessary(obj: Optional[Any]) -> Optional[Any]:
405+
async def await_if_necessary(obj: Union[_T, Task[_T], Coroutine[_T, None, None]]) -> Optional[_T]:
405406
"""Await Coroutine, Feature or coroutine Function if given argument is one of them, or return immediately.
406407
407408
:param obj: value, Coroutine, Feature or coroutine Function

0 commit comments

Comments
 (0)