From b54980dfe20c6331a016a2c30de49976e92a691f Mon Sep 17 00:00:00 2001 From: Mike Werezak Date: Mon, 19 Aug 2024 12:07:49 -0400 Subject: [PATCH 1/8] Export channel.Connection (for type hinting) --- CHANGES | 2 ++ curio/channel.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index ba652f0..02f490c 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,8 @@ may have moved code there. Many features of Curio were simply higher-level modules implemented on top of an existing core and can be added back to your code without much effort. -- Dave +08/19/2024 Export Connection class to help with type hinting. + 04/11/2024 Removed undocumented ProcessPool and ThreadPool names. 04/11/2024 Removed block_in_thread(). This functionality can be diff --git a/curio/channel.py b/curio/channel.py index 2a54952..5c69d31 100644 --- a/curio/channel.py +++ b/curio/channel.py @@ -4,7 +4,7 @@ # Python objects on a stream. Compatible with the Connection class in the # multiprocessing module, but rewritten for a purely asynchronous runtime. -__all__ = ['Channel'] +__all__ = ['Channel', 'Connection'] # -- Standard Library From 79d17094f5ec498943398f53c60ab81efe062cce Mon Sep 17 00:00:00 2001 From: Mike Werezak Date: Tue, 4 Feb 2025 14:58:55 -0500 Subject: [PATCH 2/8] Add empty pyproject.toml so that the buildpkg tool recognizes curio as a package that can be built --- curio/io.py | 1 - pyproject.toml | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 pyproject.toml diff --git a/curio/io.py b/curio/io.py index 6bd45de..618ab9b 100644 --- a/curio/io.py +++ b/curio/io.py @@ -634,4 +634,3 @@ async def write(self, data): except errors.CancelledError as e: e.bytes_written = nwritten raise - diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..69dc89a --- /dev/null +++ b/pyproject.toml @@ -0,0 +1 @@ +# this is a hack so that buildpkg recognizes this package \ No newline at end of file From 674c1ac62790c2933ed6186b1a79afd7034da8d9 Mon Sep 17 00:00:00 2001 From: Mike Werezak Date: Wed, 19 Feb 2025 16:55:17 -0500 Subject: [PATCH 3/8] Release v1.6.1+cmat --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 0cb4a25..0c35bef 100755 --- a/setup.py +++ b/setup.py @@ -10,12 +10,13 @@ maintained as a PyPi project. Latest version is available on GitHub. """ +CURIO_VERSION = "1.6.1+cmat" setup(name="curio", description="Curio", long_description=long_description, license="BSD", - version="1.6", + version=CURIO_VERSION, author="David Beazley", author_email="dave@dabeaz.com", maintainer="David Beazley", From ad6fa41c6c2a93c71509d5832249e752e38e5081 Mon Sep 17 00:00:00 2001 From: Mike Werezak Date: Fri, 31 Oct 2025 15:19:44 -0400 Subject: [PATCH 4/8] Update Monitor address after binding socket Log address after updating it --- curio/monitor.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/curio/monitor.py b/curio/monitor.py index 71bdd4d..4adfa79 100644 --- a/curio/monitor.py +++ b/curio/monitor.py @@ -125,7 +125,6 @@ def start(self): ''' Function to start the monitor ''' - log.info('Starting Curio monitor at %s', self.address) self._closing = threading.Event() self._ui_thread = threading.Thread(target=self.server, args=(), daemon=True) self._ui_thread.start() @@ -142,6 +141,8 @@ def server(self): # blocking indefinitaly on sock.accept() sock.settimeout(0.5) sock.bind(self.address) + self.address = sock.getsockname() + log.info('Starting Curio monitor at %s', self.address) sock.listen(1) with sock: while not self._closing.is_set(): From fd95d1ce5f84c4109174aaa3a653a0b68f2446da Mon Sep 17 00:00:00 2001 From: Mike Werezak Date: Mon, 3 Nov 2025 14:17:22 -0500 Subject: [PATCH 5/8] Release v1.6.2+cmat --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 0c35bef..9c0fdfd 100755 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ maintained as a PyPi project. Latest version is available on GitHub. """ -CURIO_VERSION = "1.6.1+cmat" +CURIO_VERSION = "1.6.2+cmat" setup(name="curio", description="Curio", From 590473e87775bfec955628609347e89de00a6700 Mon Sep 17 00:00:00 2001 From: Mike Werezak Date: Sun, 1 Mar 2026 12:11:42 -0500 Subject: [PATCH 6/8] Update README Signed-off-by: Mike Werezak --- README.rst | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/README.rst b/README.rst index 83f9ee7..9c1c808 100644 --- a/README.rst +++ b/README.rst @@ -8,13 +8,18 @@ well as some advanced features such as support for structured concurrency. It works on Unix and Windows and has zero dependencies. You'll find it to be familiar, small, fast, and fun. -Important Notice: October 25, 2022 ----------------------------------- -The Curio project is no longer making package releases. I'm more than -happy to accept bug reports and may continue to work on it from time -to time as the mood strikes. If you want the absolute latest version, you -should vendor the source code from here. Curio has no dependencies -other than the Python standard library. --Dave +CMAT Fork +--------- +On December 21, 2025, the development of the original curio source code +at https://github.com/dabeaz/curio officially ceased and the repository +was made read-only. + +Consequently, this fork will focus on continued development of curio in +support of projects at CANMETMaterials that rely on the curio async +runtime, and upstreaming/backwards compatibility will no longer be a +consideration for future development efforts. + +For further information please contact Mike Werezak . Curio is Different ------------------ From 6e8c714816de34d0ca2ff6c04ebc9f3d307676eb Mon Sep 17 00:00:00 2001 From: Mike Werezak Date: Sun, 1 Mar 2026 13:27:08 -0500 Subject: [PATCH 7/8] Add tests for SchedFIFO, Condition notify before wait Tests #1 --- tests/test_sched.py | 54 +++++++++++++++++++++++++++++++++++++++++++++ tests/test_sync.py | 9 ++++++++ 2 files changed, 63 insertions(+) create mode 100644 tests/test_sched.py diff --git a/tests/test_sched.py b/tests/test_sched.py new file mode 100644 index 0000000..464d911 --- /dev/null +++ b/tests/test_sched.py @@ -0,0 +1,54 @@ +""" +Copyright (C) Natural Resources Canada - All Rights Reserved. + +Unauthorized copying of this file, via any medium is strictly prohibited. +Proprietary and confidential. + +| Author: Mike Werezak +| Created: 2026-03-01 +""" + +from __future__ import annotations +from typing import TYPE_CHECKING + +from curio import * +from curio.sched import SchedFIFO + +if TYPE_CHECKING: + pass + + +class TestSchedFIFO: + def test_suspend_then_wake(self, kernel): + results = [] + async def worker(sched): + results.append('suspend') + await sched.suspend() + results.append('worker_done') + + async def waker(seconds): + sched = SchedFIFO() + await spawn(worker, sched) + results.append('sleep') + await sleep(seconds) + results.append('wake') + await sched.wake(1) + results.append('waker_done') + + kernel.run(waker(1)) + kernel.run() # allow the worker to finish + + assert results == [ + 'sleep', + 'suspend', + 'wake', + 'waker_done', + 'worker_done', + ] + + def test_wait_when_queue_empty(self, kernel): + async def main(): + sched = SchedFIFO() + await sched.wake(1) + + kernel.run(main) diff --git a/tests/test_sync.py b/tests/test_sync.py index 0059c39..7f55d08 100644 --- a/tests/test_sync.py +++ b/tests/test_sync.py @@ -694,6 +694,15 @@ async def main(): kernel.run(main) + # See + def test_condition_notify_without_wait(self, kernel): + async def main(): + c = Condition() + async with c: + await c.notify() + + kernel.run(main) + class TestUniversalEvent: def test_uevent_get_wait(self, kernel): From e08dea6e6456101c295bec3babce48f5db373f7c Mon Sep 17 00:00:00 2001 From: mwerezak Date: Mon, 13 Oct 2025 23:41:02 -0400 Subject: [PATCH 8/8] Don't pop an empty queue. Fixes #365 --- curio/sched.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/curio/sched.py b/curio/sched.py index 52bfb47..289e650 100644 --- a/curio/sched.py +++ b/curio/sched.py @@ -84,7 +84,7 @@ def remove(): def _kernel_wake(self, ntasks=1): tasks = [] - while ntasks > 0: + while self._queue and ntasks > 0: task, = self._queue.popleft() if task: tasks.append(task)