From d28006cebd61fc19a41423d4d14541d47bdfce83 Mon Sep 17 00:00:00 2001 From: Nanaloveyuki <136328617+Nanaloveyuki@users.noreply.github.com> Date: Tue, 6 May 2025 13:57:45 +0800 Subject: [PATCH] =?UTF-8?q?:speech=5Fballoon:=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=B3=A8=E9=87=8A,=20=E5=88=A0=E9=99=A4test?= =?UTF-8?q?=5Fchan.py=E7=9A=84=E6=97=A0=E7=94=A8=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- magicoca/__init__.py | 11 ++++-- magicoca/chan.py | 90 +++++++++++++++++++++++++++++--------------- tests/test_chan.py | 5 +-- 3 files changed, 69 insertions(+), 37 deletions(-) diff --git a/magicoca/__init__.py b/magicoca/__init__.py index d0690cf..d29eee4 100644 --- a/magicoca/__init__.py +++ b/magicoca/__init__.py @@ -13,10 +13,15 @@ set_start_method("spawn", force=True) def select(*args: Chan[T]) -> Generator[T, None, None]: """ - 当其中一个通道接收到数据时,yield 该数据。 + When one of the channels receives data, yield that data. + 当其中一个通道接收到数据时, yield 该数据 - 参数: - args: 多个 Chan 对象 + Args: + args: Multiple Chan objects + 多个 Chan 对象 + Returns: + Generator[T, None, None]: A generator that yields data from the channels. + 一个生成器, 用于从通道中 yield 数据 """ # 构造管道到通道列表的映射,避免重复的 recv_conn 对象 pipe_to_chs: dict[Connection, list[Chan[T]]] = {} diff --git a/magicoca/chan.py b/magicoca/chan.py index be7a0b5..edb655c 100644 --- a/magicoca/chan.py +++ b/magicoca/chan.py @@ -1,5 +1,7 @@ """ Chan is a simple channel implementation using multiprocessing.Pipe. + +Chan 是一个简单的通道实现,使用 multiprocessing.Pipe。 """ from multiprocessing import Pipe from typing import TypeVar, Generic, Any @@ -9,6 +11,8 @@ T = TypeVar("T") class NoRecvValue(Exception): """ Exception raised when there is no value to receive. + + 当没有值可以接收时引发的异常。 """ pass @@ -17,60 +21,62 @@ class Chan(Generic[T]): """ Chan is a simple channel implementation using multiprocessing.Pipe. + Chan 是一个简单的通道实现,使用 multiprocessing.Pipe。 + Attributes: send_conn: The sending end of the pipe. + 管道的发送端。 recv_conn: The receiving end of the pipe. - - Methods: - send: Send a value to the channel. - recv: Receive a value from the channel. - close: Close the channel. - __iter__: Return the channel object. - __next__: Receive a value from the channel. - __lshift__: Send a value to the channel. - __rlshift__: Receive a value from the channel. + 管道的接收端。 """ def __init__(self): """ Initialize the channel. + + 初始化通道。 """ self.send_conn, self.recv_conn = Pipe() - self.is_closed = False def send(self, value: T): """ Send a value to the channel. + + 发送一个值到通道。 + Args: value: The value to send. + 要发送的值。 """ self.send_conn.send(value) def recv(self, timeout: float | None = None) -> T | NoRecvValue: - """Receive a value from the channel. - If the timeout is None, it will block until a value is received. - If the timeout is a positive number, it will wait for the specified time, and if no value is received, it will return None. - 接收通道中的值。 - 如果超时为None,则它将阻塞,直到接收到值。 - 如果超时是正数,则它将等待指定的时间,如果没有接收到值,则返回NoRecvValue。 + """ + Receive a value from the channel. + + 从通道接收一个值。 + Args: - timeout: - The maximum time to wait for a value. - 等待值的最长时间。 + timeout: The maximum time to wait for a value. + 等待值的最长时间。 + If None, it will block until a value is received. + 如果为 None,则阻塞直到接收到值。 + Returns: T: The value received from the channel. - 从通道接收的值。 + 从通道接收的值。 """ if timeout is not None: if not self.recv_conn.poll(timeout): return NoRecvValue("No value to receive.") return self.recv_conn.recv() - def close(self): """ - Close the channel. destructor + Close the channel. + + 关闭通道。 """ self.send_conn.close() self.recv_conn.close() @@ -78,42 +84,66 @@ class Chan(Generic[T]): def __iter__(self) -> "Chan[T]": """ - Returns: The channel object. + Return the channel object. + + 返回通道对象。 """ return self def __next__(self) -> T | NoRecvValue: + """ + Receive a value from the channel. + + 从通道接收一个值。 + """ return self.recv() def __lshift__(self, other: T): """ - chan << obj + Send an object to the channel. + + 发送一个对象到通道。 + Args: other: The object to send. - Returns: self + 要发送的对象。 + + Returns: + self: The channel object. + 通道对象。 """ self.send(other) return self def __rlshift__(self, other: Any) -> T | NoRecvValue: """ - << chan - Returns: The value received from the channel. + Receive a value from the channel. + + 从通道接收一个值。 + + Returns: + T: The value received from the channel. + 从通道接收的值。 """ return self.recv(None) def __add__(self, other: "Chan[T]"): """ - Connect 1 channel.send to another channel.recv. + Connect one channel's send to another channel's recv. + + 将一个通道的发送端连接到另一个通道的接收端。 + Args: - other: - Returns: + other: The other channel to connect. + 要连接的另一个通道。 """ self.recv_conn, other.recv_conn = other.recv_conn, self.recv_conn def __del__(self): """ Close the channel when the object is deleted. + + 当对象被删除时关闭通道。 """ self.close() diff --git a/tests/test_chan.py b/tests/test_chan.py index fd30cc2..ca5e16d 100644 --- a/tests/test_chan.py +++ b/tests/test_chan.py @@ -1,8 +1,5 @@ -import time -from select import select - from magicoca.chan import Chan -from multiprocessing import Process, set_start_method +from multiprocessing import Process