From 4b5ed009ce93dee7cb944485c25115cae4f00206 Mon Sep 17 00:00:00 2001 From: ZoicSoftware Date: Mon, 16 Jan 2023 09:44:04 -0500 Subject: [PATCH 01/11] Add name parameter to spawn --- aiojobs/_job.py | 14 ++++++++++++-- aiojobs/_scheduler.py | 6 ++++-- tests/test_job.py | 8 ++++++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/aiojobs/_job.py b/aiojobs/_job.py index 5c3928d..233b1c8 100644 --- a/aiojobs/_job.py +++ b/aiojobs/_job.py @@ -14,9 +14,15 @@ class Job(Generic[_T]): - def __init__(self, coro: Coroutine[object, object, _T], scheduler: Scheduler): + def __init__( + self, + coro: Coroutine[object, object, _T], + scheduler: Scheduler, + name: Optional[str] = None, + ): self._coro = coro self._scheduler: Optional[Scheduler] = scheduler + self._name: Optional[str] = name loop = asyncio.get_running_loop() self._started = loop.create_future() @@ -50,6 +56,10 @@ def pending(self) -> bool: def closed(self) -> bool: return self._closed + @property + def name(self) -> str: + return self._task.get_name() if self._task else self._name + async def _do_wait(self, timeout: Optional[float]) -> _T: async with async_timeout.timeout(timeout): # TODO: add a test for waiting for a pending coro @@ -118,7 +128,7 @@ async def _close(self, timeout: Optional[float]) -> None: def _start(self) -> None: assert self._task is None - self._task = asyncio.create_task(self._coro) + self._task = asyncio.create_task(self._coro, name=self._name) self._task.add_done_callback(self._done_callback) self._started.set_result(None) diff --git a/aiojobs/_scheduler.py b/aiojobs/_scheduler.py index 43b7269..d7d08ce 100644 --- a/aiojobs/_scheduler.py +++ b/aiojobs/_scheduler.py @@ -85,10 +85,12 @@ def pending_count(self) -> int: def closed(self) -> bool: return self._closed - async def spawn(self, coro: Coroutine[object, object, _T]) -> Job[_T]: + async def spawn( + self, coro: Coroutine[object, object, _T], name: Optional[str] = None + ) -> Job[_T]: if self._closed: raise RuntimeError("Scheduling a new job after closing") - job = Job(coro, self) + job = Job(coro, self, name=name) should_start = self._limit is None or self.active_count < self._limit if should_start: job._start() diff --git a/tests/test_job.py b/tests/test_job.py index 73d4a10..4a67b85 100644 --- a/tests/test_job.py +++ b/tests/test_job.py @@ -287,3 +287,11 @@ async def coro() -> NoReturn: await scheduler.spawn(coro()) await scheduler.close() handler.assert_called_once() + + +async def test_job_name_set(scheduler: Scheduler) -> None: + async def coro() -> None: + await asyncio.sleep(1) + + job = await scheduler.spawn(coro(), name="test_job_name") + assert job.name == "test_job_name" From 2cea1f6e4a059524c5a1ba5eda16ed80573a6119 Mon Sep 17 00:00:00 2001 From: zoicsoftware <73088324+zoicsoftware@users.noreply.github.com> Date: Mon, 16 Jan 2023 17:17:09 -0500 Subject: [PATCH 02/11] Apply suggestions from code review Co-authored-by: Sam Bull --- aiojobs/_job.py | 3 +-- tests/test_job.py | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/aiojobs/_job.py b/aiojobs/_job.py index 233b1c8..f03524e 100644 --- a/aiojobs/_job.py +++ b/aiojobs/_job.py @@ -56,8 +56,7 @@ def pending(self) -> bool: def closed(self) -> bool: return self._closed - @property - def name(self) -> str: + def get_name(self) -> str: return self._task.get_name() if self._task else self._name async def _do_wait(self, timeout: Optional[float]) -> _T: diff --git a/tests/test_job.py b/tests/test_job.py index 4a67b85..33fbeac 100644 --- a/tests/test_job.py +++ b/tests/test_job.py @@ -291,7 +291,8 @@ async def coro() -> NoReturn: async def test_job_name_set(scheduler: Scheduler) -> None: async def coro() -> None: - await asyncio.sleep(1) + """Dummy function.""" job = await scheduler.spawn(coro(), name="test_job_name") assert job.name == "test_job_name" + assert job._task.get_name() == "test_job_name" From 5be8a34cff228f14774dc6152f3f447c4a62883b Mon Sep 17 00:00:00 2001 From: ZoicSoftware Date: Mon, 16 Jan 2023 17:27:24 -0500 Subject: [PATCH 03/11] Add python version check to creating named task --- aiojobs/_job.py | 5 ++++- tests/test_job.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/aiojobs/_job.py b/aiojobs/_job.py index f03524e..7c0987b 100644 --- a/aiojobs/_job.py +++ b/aiojobs/_job.py @@ -127,7 +127,10 @@ async def _close(self, timeout: Optional[float]) -> None: def _start(self) -> None: assert self._task is None - self._task = asyncio.create_task(self._coro, name=self._name) + if sys.version_info >= (3, 8): + self._task = asyncio.create_task(self._coro, name=self._name) + else: + self._task = asyncio.create_task(self._coro) self._task.add_done_callback(self._done_callback) self._started.set_result(None) diff --git a/tests/test_job.py b/tests/test_job.py index 33fbeac..ca842ef 100644 --- a/tests/test_job.py +++ b/tests/test_job.py @@ -294,5 +294,5 @@ async def coro() -> None: """Dummy function.""" job = await scheduler.spawn(coro(), name="test_job_name") - assert job.name == "test_job_name" + assert job.get_name() == "test_job_name" assert job._task.get_name() == "test_job_name" From 2db6c8c0a6550a5f6c67edcc5a528f5c574c82c0 Mon Sep 17 00:00:00 2001 From: ZoicSoftware Date: Wed, 18 Jan 2023 10:25:00 -0500 Subject: [PATCH 04/11] Added set_name functionality; Added fallback default job name; fixed 3.7 naming tests --- aiojobs/_job.py | 13 ++++++++++++- tests/test_job.py | 21 +++++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/aiojobs/_job.py b/aiojobs/_job.py index 7c0987b..403cdd9 100644 --- a/aiojobs/_job.py +++ b/aiojobs/_job.py @@ -57,7 +57,18 @@ def closed(self) -> bool: return self._closed def get_name(self) -> str: - return self._task.get_name() if self._task else self._name + name = self._name + if sys.version_info >= (3, 8) and self._task: + name = self._task.get_name() + if name is None: + # Return generated default name + name = f"Job({self._coro})" + return name + + def set_name(self, name): + if sys.version_info >= (3, 8): + return self._task.set_name(name) + self._name = name async def _do_wait(self, timeout: Optional[float]) -> _T: async with async_timeout.timeout(timeout): diff --git a/tests/test_job.py b/tests/test_job.py index ca842ef..2e8ab62 100644 --- a/tests/test_job.py +++ b/tests/test_job.py @@ -1,10 +1,12 @@ import asyncio +import sys from contextlib import suppress from typing import Awaitable, Callable, NoReturn from unittest import mock import pytest +from aiojobs._job import Job from aiojobs._scheduler import Scheduler _MakeScheduler = Callable[..., Awaitable[Scheduler]] @@ -289,10 +291,25 @@ async def coro() -> NoReturn: handler.assert_called_once() -async def test_job_name_set(scheduler: Scheduler) -> None: +async def test_get_job_name(scheduler: Scheduler) -> None: async def coro() -> None: """Dummy function.""" job = await scheduler.spawn(coro(), name="test_job_name") assert job.get_name() == "test_job_name" - assert job._task.get_name() == "test_job_name" + if sys.version_info >= (3, 8): + assert job._task.get_name() == "test_job_name" + # check default name generation + job2 = Job(coro, scheduler) + assert job2.get_name() == (f"Job({job2._coro})") + + +async def test_set_job_name(scheduler: Scheduler) -> None: + async def coro() -> None: + """Dummy function.""" + + job = await scheduler.spawn(coro(), name="original_name") + job.set_name("changed_name") + assert job.get_name() == "changed_name" + if sys.version_info >= (3, 8): + assert job._task.get_name() == "changed_name" From 872e72e860ae5c66f5bd8a22144d5fd0ca8b0db9 Mon Sep 17 00:00:00 2001 From: ZoicSoftware Date: Sat, 21 Jan 2023 14:42:08 -0500 Subject: [PATCH 05/11] Fix mypy errors --- aiojobs/_job.py | 12 +++++------- tests/test_job.py | 9 +++++++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/aiojobs/_job.py b/aiojobs/_job.py index 403cdd9..93585ea 100644 --- a/aiojobs/_job.py +++ b/aiojobs/_job.py @@ -60,15 +60,13 @@ def get_name(self) -> str: name = self._name if sys.version_info >= (3, 8) and self._task: name = self._task.get_name() - if name is None: - # Return generated default name - name = f"Job({self._coro})" - return name + return name or f"Job({self._coro})" - def set_name(self, name): - if sys.version_info >= (3, 8): + def set_name(self, name: str) -> None: + if sys.version_info >= (3, 8) and self._task is not None: return self._task.set_name(name) - self._name = name + else: + self._name = name async def _do_wait(self, timeout: Optional[float]) -> _T: async with async_timeout.timeout(timeout): diff --git a/tests/test_job.py b/tests/test_job.py index 2e8ab62..9a0961b 100644 --- a/tests/test_job.py +++ b/tests/test_job.py @@ -298,10 +298,14 @@ async def coro() -> None: job = await scheduler.spawn(coro(), name="test_job_name") assert job.get_name() == "test_job_name" if sys.version_info >= (3, 8): + assert job._task is not None assert job._task.get_name() == "test_job_name" # check default name generation - job2 = Job(coro, scheduler) - assert job2.get_name() == (f"Job({job2._coro})") + job2: Job[object] = await scheduler.spawn(coro()) + if sys.version_info >= (3, 8): + assert job2.get_name().startswith("Task-") + else: + assert job2.get_name() == f"Job({job2._coro})" async def test_set_job_name(scheduler: Scheduler) -> None: @@ -312,4 +316,5 @@ async def coro() -> None: job.set_name("changed_name") assert job.get_name() == "changed_name" if sys.version_info >= (3, 8): + assert job._task is not None assert job._task.get_name() == "changed_name" From 1d38c5b6bab43936fd062b911e9ca4d1cbd34d65 Mon Sep 17 00:00:00 2001 From: ZoicSoftware Date: Mon, 23 Jan 2023 19:07:46 -0500 Subject: [PATCH 06/11] Allow get_name to return None --- aiojobs/_job.py | 12 ++++++++---- tests/test_job.py | 6 ++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/aiojobs/_job.py b/aiojobs/_job.py index 93585ea..46fc4c3 100644 --- a/aiojobs/_job.py +++ b/aiojobs/_job.py @@ -56,11 +56,15 @@ def pending(self) -> bool: def closed(self) -> bool: return self._closed - def get_name(self) -> str: - name = self._name + def get_name(self) -> Optional[str]: + """Get the task name. + + See https://docs.python.org/3/library/asyncio-task.html#asyncio.Task.get_name. + Returns None if no name was set on the Job object and job has not yet started + """ if sys.version_info >= (3, 8) and self._task: - name = self._task.get_name() - return name or f"Job({self._coro})" + return self._task.get_name() + return self._name def set_name(self, name: str) -> None: if sys.version_info >= (3, 8) and self._task is not None: diff --git a/tests/test_job.py b/tests/test_job.py index 9a0961b..24a89f8 100644 --- a/tests/test_job.py +++ b/tests/test_job.py @@ -303,9 +303,11 @@ async def coro() -> None: # check default name generation job2: Job[object] = await scheduler.spawn(coro()) if sys.version_info >= (3, 8): - assert job2.get_name().startswith("Task-") + job_name = job2.get_name() + assert job_name is not None + assert job_name.startswith("Task-") else: - assert job2.get_name() == f"Job({job2._coro})" + assert job2.get_name() is None async def test_set_job_name(scheduler: Scheduler) -> None: From d19ab2a7f16e3635f912ac60e808aafbe2bdbdda Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Fri, 27 Jan 2023 17:13:16 +0000 Subject: [PATCH 07/11] Update aiojobs/_job.py --- aiojobs/_job.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aiojobs/_job.py b/aiojobs/_job.py index 46fc4c3..7c136a8 100644 --- a/aiojobs/_job.py +++ b/aiojobs/_job.py @@ -22,7 +22,7 @@ def __init__( ): self._coro = coro self._scheduler: Optional[Scheduler] = scheduler - self._name: Optional[str] = name + self._name = name loop = asyncio.get_running_loop() self._started = loop.create_future() From b0e958e0d4c7153bfab2f618d8d2f273157803b8 Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Fri, 27 Jan 2023 17:13:27 +0000 Subject: [PATCH 08/11] Update aiojobs/_job.py --- aiojobs/_job.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aiojobs/_job.py b/aiojobs/_job.py index 7c136a8..194fa19 100644 --- a/aiojobs/_job.py +++ b/aiojobs/_job.py @@ -60,7 +60,7 @@ def get_name(self) -> Optional[str]: """Get the task name. See https://docs.python.org/3/library/asyncio-task.html#asyncio.Task.get_name. - Returns None if no name was set on the Job object and job has not yet started + Returns None if no name was set on the Job object and job has not yet started. """ if sys.version_info >= (3, 8) and self._task: return self._task.get_name() From b4bd609106c291406b43653a417ecbd83ad495ea Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Fri, 27 Jan 2023 17:13:38 +0000 Subject: [PATCH 09/11] Update aiojobs/_job.py --- aiojobs/_job.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/aiojobs/_job.py b/aiojobs/_job.py index 194fa19..85ccbc6 100644 --- a/aiojobs/_job.py +++ b/aiojobs/_job.py @@ -67,10 +67,9 @@ def get_name(self) -> Optional[str]: return self._name def set_name(self, name: str) -> None: + self._name = name if sys.version_info >= (3, 8) and self._task is not None: - return self._task.set_name(name) - else: - self._name = name + self._task.set_name(name) async def _do_wait(self, timeout: Optional[float]) -> _T: async with async_timeout.timeout(timeout): From f1f00886d74c3bb3928473c67b91494c6520f0c5 Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Fri, 27 Jan 2023 17:13:53 +0000 Subject: [PATCH 10/11] Update tests/test_job.py --- tests/test_job.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/test_job.py b/tests/test_job.py index 24a89f8..e6cddcc 100644 --- a/tests/test_job.py +++ b/tests/test_job.py @@ -300,14 +300,19 @@ async def coro() -> None: if sys.version_info >= (3, 8): assert job._task is not None assert job._task.get_name() == "test_job_name" - # check default name generation - job2: Job[object] = await scheduler.spawn(coro()) + + +async def test_get_default_job_name(scheduler: Scheduler) -> None: + async def coro() -> None: + """Dummy function.""" + + job = await scheduler.spawn(coro()) if sys.version_info >= (3, 8): - job_name = job2.get_name() + job_name = job.get_name() assert job_name is not None assert job_name.startswith("Task-") else: - assert job2.get_name() is None + assert job.get_name() is None async def test_set_job_name(scheduler: Scheduler) -> None: From 654bd3f360a0992648357f8a170ea3f0f8ac2893 Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Fri, 27 Jan 2023 17:14:37 +0000 Subject: [PATCH 11/11] Update tests/test_job.py --- tests/test_job.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_job.py b/tests/test_job.py index e6cddcc..7013c7a 100644 --- a/tests/test_job.py +++ b/tests/test_job.py @@ -6,7 +6,6 @@ import pytest -from aiojobs._job import Job from aiojobs._scheduler import Scheduler _MakeScheduler = Callable[..., Awaitable[Scheduler]]