CheeseSignal 1.0.0__tar.gz → 1.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of CheeseSignal might be problematic. Click here for more details.

@@ -0,0 +1,6 @@
1
+ .DS_Store
2
+ __pycache__
3
+ .vscode
4
+ .conda
5
+ dist
6
+ logs
@@ -0,0 +1 @@
1
+ from CheeseSignal.signal import Receiver, Signal
@@ -1,18 +1,26 @@
1
- from typing import List, Callable, overload, Any
1
+ import asyncio
2
+ from typing import List, Callable, overload, Any, TYPE_CHECKING, Literal, Tuple
3
+
4
+ if TYPE_CHECKING:
5
+ class Signal:
6
+ ...
2
7
 
3
8
  class Receiver:
4
- def __init__(self, fn: Callable, *, expected_receive_num: int, auto_remove: bool):
9
+ def __init__(self, signal: 'Signal', fn: Callable, *, expected_receive_num: int, auto_remove: bool, runType: Literal['ORDERED', 'CONCURRENT', 'NO_WAIT'] = 'ORDERED'):
5
10
  '''
6
11
  - Args
7
-
8
12
  - expected_receive_num: 期望接受信号的次数,超过该次数则不再响应信号;0为无限次。
9
13
 
10
14
  - auto_remove: 是否自动删除响应次数超出期望次数的接收器。
11
15
  '''
16
+
17
+ self._signal: 'Signal' = signal
12
18
  self.fn: Callable = fn
13
19
  self._expected_receive_num: int = expected_receive_num
14
20
  self._auto_remove: bool = auto_remove
15
21
  self._total_receive_num: int = 0
22
+ self._active: bool = True
23
+ self._runType: Literal['ORDERED', 'CONCURRENT', 'NO_WAIT'] = runType
16
24
 
17
25
  def reset(self):
18
26
  '''
@@ -27,6 +35,8 @@ class Receiver:
27
35
  def expected_receive_num(self) -> int:
28
36
  '''
29
37
  期望接受信号的次数,超过该次数则不再响应信号;0为无限次。
38
+
39
+ 设置值小于`total_receive_num`且`auto_remove is True`,则会立刻删除。
30
40
  '''
31
41
 
32
42
  return self._expected_receive_num
@@ -35,10 +45,15 @@ class Receiver:
35
45
  def expected_receive_num(self, value: int):
36
46
  self._expected_receive_num = value
37
47
 
48
+ if self._auto_remove and self.is_expired:
49
+ self._signal.receivers.remove(self)
50
+
38
51
  @property
39
52
  def auto_remove(self) -> bool:
40
53
  '''
41
54
  是否自动删除响应次数超出期望次数的接收器。
55
+
56
+ 设置为`True`时若该receiver过期,则会立刻删除。
42
57
  '''
43
58
 
44
59
  return self._auto_remove
@@ -47,6 +62,21 @@ class Receiver:
47
62
  def auto_remove(self, value: bool):
48
63
  self._auto_remove = value
49
64
 
65
+ if self._auto_remove and self.is_expired:
66
+ self._signal.receivers.remove(self)
67
+
68
+ @property
69
+ def active(self) -> bool:
70
+ '''
71
+ 是否激活;未激活将忽略信号。
72
+ '''
73
+
74
+ return self._active
75
+
76
+ @active.setter
77
+ def active(self, value: bool):
78
+ self._active = value
79
+
50
80
  @property
51
81
  def total_receive_num(self) -> int:
52
82
  '''
@@ -66,9 +96,17 @@ class Receiver:
66
96
  return self.expected_receive_num - self.total_receive_num
67
97
 
68
98
  @property
69
- def receivable(self) -> bool:
99
+ def is_expired(self) -> bool:
70
100
  '''
71
- 【只读】 当前Receiver是否处于可接收信号状态。
101
+ 【只读】 是否过期。
102
+ '''
103
+
104
+ return not self.is_unexpired
105
+
106
+ @property
107
+ def is_unexpired(self) -> bool:
108
+ '''
109
+ 【只读】 是否未过期。
72
110
  '''
73
111
 
74
112
  if self.remaining_receive_num == -1:
@@ -76,12 +114,22 @@ class Receiver:
76
114
  return True if self.remaining_receive_num else False
77
115
 
78
116
  @property
79
- def unreceivable(self) -> bool:
117
+ def runType(self) -> Literal['ORDERED', 'CONCURRENT', 'NO_WAIT']:
80
118
  '''
81
- 【只读】 当前Receiver是否处于不可接收信号状态。
119
+ 【只读】 运行的方式,仅在`async_send`时有效。
120
+
121
+ - ORDERED: 按顺序执行,返回结果。
122
+
123
+ - CONCURRENT: 并行执行,返回结果。
124
+
125
+ - NO_WAIT: 并行执行,不阻塞代码。
82
126
  '''
83
127
 
84
- return not self.receivable
128
+ return self._runType
129
+
130
+ @runType.setter
131
+ def runType(self, value: Literal['ORDERED', 'CONCURRENT', 'NO_WAIT']):
132
+ self._runType = value
85
133
 
86
134
  class Signal:
87
135
  def __init__(self):
@@ -89,28 +137,24 @@ class Signal:
89
137
  self._total_send_num: int = 0
90
138
 
91
139
  @overload
92
- def connect(self, fn: Callable, *, expected_receive_num: int = 0, auto_remove: bool = False):
140
+ def connect(self, fn: Callable, *, expected_receive_num: int = 0, auto_remove: bool = False, runType: Literal['ORDERED', 'CONCURRENT', 'NO_WAIT'] = 'ORDERED'):
93
141
  '''
94
142
  通过函数注册响应函数。
95
143
 
96
- ```python
97
- from CheeseSignal import Signal
98
-
99
- def receiver(*args, **kwargs):
100
- ...
101
-
102
- signal = Signal()
103
- signal.connect(receiver)
104
- ```
144
+ >>> from CheeseSignal import Signal
145
+ >>>
146
+ >>> def receiver(*args, **kwargs):
147
+ ... ...
148
+ >>>
149
+ >>> signal = Signal()
150
+ >>> signal.connect(receiver)
105
151
 
106
152
  - Args
107
-
108
153
  - expected_receive_num: 期望接受信号的次数,超过该次数则不再响应信号;0为无限次。
109
154
 
110
155
  - auto_remove: 是否自动删除响应次数超出期望次数的接收器。
111
156
 
112
157
  - Raise
113
-
114
158
  - ValueError: 已有重复的函数接收器。
115
159
  '''
116
160
 
@@ -119,119 +163,109 @@ class Signal:
119
163
  '''
120
164
  通过装饰器注册响应函数。
121
165
 
122
- ```python
123
- from CheeseSignal import Signal
124
-
125
- signal = Signal()
126
-
127
- @signal.connect()
128
- def receiver(*args, **kwargs):
129
- ...
130
- ```
166
+ >>> from CheeseSignal import Signal
167
+ >>>
168
+ >>> signal = Signal()
169
+ >>>
170
+ >>> @signal.connect()
171
+ >>> def receiver(*args, **kwargs):
172
+ ... ...
131
173
 
132
174
  - Args
133
-
134
175
  - expected_receive_num: 期望接受信号的次数,超过该次数则不再响应信号;0为无限次。
135
176
 
136
177
  - auto_remove: 是否自动删除响应次数超出期望次数的接收器。
137
178
 
138
179
  - Raise
139
-
140
180
  - ValueError: 已有重复的函数接收器。
141
181
  '''
142
182
 
143
- def connect(self, arg1: Callable | None = None, *, expected_receive_num: int = 0, auto_remove: bool = False):
183
+ def connect(self, arg1: Callable | None = None, *, expected_receive_num: int = 0, auto_remove: bool = False, runType: Literal['ORDERED', 'CONCURRENT', 'NO_WAIT'] = 'ORDERED'):
144
184
  if not arg1:
145
185
  def wrapper(fn):
146
- self._connect(fn, expected_receive_num = expected_receive_num, auto_remove = auto_remove)
186
+ self._connect(fn, expected_receive_num = expected_receive_num, auto_remove = auto_remove, runType = runType)
147
187
  return fn
148
188
  return wrapper
149
189
 
150
- self._connect(arg1, expected_receive_num = expected_receive_num, auto_remove = auto_remove)
190
+ self._connect(arg1, expected_receive_num = expected_receive_num, auto_remove = auto_remove, runType = runType)
151
191
 
152
- def _connect(self, fn: Callable, *, expected_receive_num: int, auto_remove: bool):
192
+ def _connect(self, fn: Callable, *, expected_receive_num: int, auto_remove: bool, runType: Literal['ORDERED', 'CONCURRENT', 'NO_WAIT']):
153
193
  for receiver in self.receivers:
154
194
  if receiver.fn == fn:
155
195
  raise ValueError('已有重复的函数接收器')
156
196
 
157
- self.receivers.append(Receiver(fn, expected_receive_num = expected_receive_num, auto_remove = auto_remove))
197
+ self.receivers.append(Receiver(self, fn, expected_receive_num = expected_receive_num, auto_remove = auto_remove, runType = runType))
158
198
 
159
199
  def send(self, *args, **kwargs) -> List[Any]:
160
200
  '''
161
201
  发送信号。
162
202
 
163
- ```python
164
- from CheeseSignal import Signal
165
-
166
- signal = Signal()
167
- signal.send('data1', 'data2', **{
168
- 'key1': 'value1',
169
- 'key2': 'value2'
170
- })
171
- ```
203
+ >>> from CheeseSignal import Signal
204
+ >>>
205
+ >>> signal = Signal()
206
+ >>> signal.send('data1', 'data2', **{
207
+ ... 'key1': 'value1',
208
+ ... 'key2': 'value2'
209
+ >>> })
172
210
  '''
173
211
 
174
212
  self._total_send_num += 1
175
213
 
176
214
  results = []
177
215
  for receiver in self.receivers[:]:
178
- if receiver.remaining_receive_num > 0 or receiver.remaining_receive_num == -1:
216
+ if receiver.active and receiver.is_unexpired:
179
217
  receiver._total_receive_num += 1
180
218
  results.append(receiver.fn(*args, **kwargs))
181
219
 
182
- if receiver.remaining_receive_num == 0 and receiver.auto_remove:
220
+ if receiver.is_expired:
183
221
  self.receivers.remove(receiver)
184
222
  return results
185
223
 
186
- async def async_send(self, *args, **kwargs) -> List[Any]:
224
+ async def async_send(self, *args, **kwargs) -> Tuple[List[Any], List[Any]]:
187
225
  '''
188
226
  在协程环境中发送信号,并请保证所有接收函数都是协程函数。
189
227
 
190
- ```python
191
- import asyncio
228
+ >>> import asyncio
229
+ >>>
230
+ >>> from CheeseSignal import Signal
231
+ >>>
232
+ >>> async def run_asyncio():
233
+ ... signal = Signal()
234
+ ... await signal.async_send('data1', 'data2', **{
235
+ ... 'key1': 'value1',
236
+ ... 'key2': 'value2'
237
+ ... })
238
+ >>>
239
+ >>> asyncio.run(run_asyncio())
192
240
 
193
- from CheeseSignal import Signal
194
-
195
- async def run_asyncio():
196
- signal = Signal()
197
- await signal.async_send('data1', 'data2', **{
198
- 'key1': 'value1',
199
- 'key2': 'value2'
200
- })
201
-
202
- asyncio.run(run_asyncio())
203
- ```
241
+ - Returns
242
+ 返回长度为2的元祖,分别为ORDERED类型和CONCURRENT类型的结果。
204
243
  '''
205
244
 
206
245
  self._total_send_num += 1
246
+ receivers = [receiver for receiver in self.receivers.copy() if receiver.active and receiver.is_unexpired]
207
247
 
208
- results = []
209
- for receiver in self.receivers[:]:
210
- if receiver.remaining_receive_num > 0 or receiver.remaining_receive_num == -1:
211
- receiver._total_receive_num += 1
212
- results.append(await receiver.fn(*args, **kwargs))
248
+ [asyncio.create_task(receiver.fn(*args, **kwargs)) for receiver in receivers if receiver.runType == 'NO_WAIT']
249
+ concurrent_tasks = [receiver.fn(*args, **kwargs) for receiver in receivers if receiver.runType == 'CONCURRENT']
250
+ concurrent_results = await asyncio.gather(*concurrent_tasks) if concurrent_tasks else []
251
+ ordered_results = [await receiver.fn(*args, **kwargs) for receiver in receivers if receiver.runType == 'ORDERED']
213
252
 
214
- if receiver.remaining_receive_num == 0 and receiver.auto_remove:
215
- self.receivers.remove(receiver)
216
- return results
253
+ return concurrent_results, ordered_results
217
254
 
218
255
  def disconnect(self, fn: Callable):
219
256
  '''
220
257
  断开接收器。
221
258
 
222
- ```python
223
- from CheeseSignal import Signal
224
-
225
- def receiver(*args, **kwargs):
226
- ...
227
-
228
- signal = Signal()
229
- signal.connect(receiver)
230
- signal.disconnect(receiver)
231
- ```
259
+ >>> from CheeseSignal import Signal
260
+ >>>
261
+ >>> def receiver(*args, **kwargs):
262
+ ... ...
263
+ >>>
264
+ >>> signal = Signal()
265
+ >>> signal.connect(receiver)
266
+ >>> signal.disconnect(receiver)
232
267
 
233
268
  - Raise
234
-
235
269
  - ValueError: 未找到该函数的接收器。
236
270
  '''
237
271
 
@@ -262,20 +296,17 @@ class Signal:
262
296
  '''
263
297
  获取接收器。
264
298
 
265
- ```python
266
- from CheeseSignal import Signal
267
-
268
- def receiver(*args, **kwargs):
269
- ...
270
-
271
- signal = Signal()
272
- signal.connect(receiver)
273
-
274
- print(signal.get_receiver(receiver))
275
- ```
299
+ >>> from CheeseSignal import Signal
300
+ >>>
301
+ >>> def receiver(*args, **kwargs):
302
+ ... ...
303
+ >>>
304
+ >>> signal = Signal()
305
+ >>> signal.connect(receiver)
306
+ >>>
307
+ >>> print(signal.get_receiver(receiver))
276
308
 
277
309
  - Raise
278
-
279
310
  - ValueError: 未找到该函数的接收器。
280
311
  '''
281
312
 
@@ -289,20 +320,17 @@ class Signal:
289
320
  '''
290
321
  获取接收器的顺序位置。
291
322
 
292
- ```python
293
- from CheeseSignal import Signal
294
-
295
- def receiver(*args, **kwargs):
296
- ...
297
-
298
- signal = Signal()
299
- signal.connect(receiver)
300
-
301
- print(signal.index(receiver))
302
- ```
323
+ >>> from CheeseSignal import Signal
324
+ >>>
325
+ >>> def receiver(*args, **kwargs):
326
+ ... ...
327
+ >>>
328
+ >>> signal = Signal()
329
+ >>> signal.connect(receiver)
330
+ >>>
331
+ >>> print(signal.index(receiver))
303
332
 
304
333
  - Raise
305
-
306
334
  - ValueError: 未找到该函数的接收器。
307
335
  '''
308
336
 
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: CheeseSignal
3
- Version: 1.0.0
3
+ Version: 1.2.0
4
4
  Summary: 一款简约的信号系统。
5
5
  Project-URL: Source, https://github.com/CheeseUnknown/CheeseSignal
6
6
  Author-email: Cheese Unknown <cheese@cheese.ren>
7
7
  License-File: LICENSE
8
- Keywords: API,BackEnd
8
+ Keywords: Signal
9
9
  Description-Content-Type: text/markdown
10
10
 
11
11
  # **CheeseSignal**
@@ -192,7 +192,7 @@ print(signal.index(receiver))
192
192
  from CheeseSignal import Receiver
193
193
  ```
194
194
 
195
- #### **`def __init__(self, fn: Callable, *, expected_receive_num: int, auto_remove: bool)`**
195
+ #### **`def __init__(self, signal: Signal, fn: Callable, *, expected_receive_num: int, auto_remove: bool)`**
196
196
 
197
197
  - **参数**
198
198
 
@@ -204,10 +204,18 @@ from CheeseSignal import Receiver
204
204
 
205
205
  期望接受信号的次数,超过该次数则不再响应信号;0为无限次。
206
206
 
207
+ 设置值小于`total_receive_num`且`auto_remove is True`,则会立刻删除。
208
+
207
209
  #### **`self.auto_remove: bool`**
208
210
 
209
211
  是否自动删除响应次数超出期望次数的接收器。
210
212
 
213
+ 设置为`True`且`is_expired is True`,则会立刻删除。
214
+
215
+ #### **`self.active: bool`**
216
+
217
+ 是否激活;未激活将忽略信号。
218
+
211
219
  #### **`self.total_receive_num: int`**
212
220
 
213
221
  【只读】 总计信号接受次数。
@@ -216,13 +224,13 @@ from CheeseSignal import Receiver
216
224
 
217
225
  【只读】 剩余的期望信号接受次数;返回为-1代表无期望信号接受次数。
218
226
 
219
- #### **`self.receivable: bool`**
227
+ #### **`self.is_expired: bool`**
220
228
 
221
- 【只读】 当前Receiver是否处于可接收信号状态。
229
+ 【只读】 是否过期。
222
230
 
223
- #### **`self.unreceivable: bool`**
231
+ #### **`self.is_unexpired: bool`**
224
232
 
225
- 【只读】 当前Receiver是否处于不可接收信号状态。
233
+ 【只读】 是否未过期。
226
234
 
227
235
  #### **`def reset(self)`**
228
236
 
@@ -182,7 +182,7 @@ print(signal.index(receiver))
182
182
  from CheeseSignal import Receiver
183
183
  ```
184
184
 
185
- #### **`def __init__(self, fn: Callable, *, expected_receive_num: int, auto_remove: bool)`**
185
+ #### **`def __init__(self, signal: Signal, fn: Callable, *, expected_receive_num: int, auto_remove: bool)`**
186
186
 
187
187
  - **参数**
188
188
 
@@ -194,10 +194,18 @@ from CheeseSignal import Receiver
194
194
 
195
195
  期望接受信号的次数,超过该次数则不再响应信号;0为无限次。
196
196
 
197
+ 设置值小于`total_receive_num`且`auto_remove is True`,则会立刻删除。
198
+
197
199
  #### **`self.auto_remove: bool`**
198
200
 
199
201
  是否自动删除响应次数超出期望次数的接收器。
200
202
 
203
+ 设置为`True`且`is_expired is True`,则会立刻删除。
204
+
205
+ #### **`self.active: bool`**
206
+
207
+ 是否激活;未激活将忽略信号。
208
+
201
209
  #### **`self.total_receive_num: int`**
202
210
 
203
211
  【只读】 总计信号接受次数。
@@ -206,13 +214,13 @@ from CheeseSignal import Receiver
206
214
 
207
215
  【只读】 剩余的期望信号接受次数;返回为-1代表无期望信号接受次数。
208
216
 
209
- #### **`self.receivable: bool`**
217
+ #### **`self.is_expired: bool`**
210
218
 
211
- 【只读】 当前Receiver是否处于可接收信号状态。
219
+ 【只读】 是否过期。
212
220
 
213
- #### **`self.unreceivable: bool`**
221
+ #### **`self.is_unexpired: bool`**
214
222
 
215
- 【只读】 当前Receiver是否处于不可接收信号状态。
223
+ 【只读】 是否未过期。
216
224
 
217
225
  #### **`def reset(self)`**
218
226
 
@@ -4,14 +4,14 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "CheeseSignal"
7
- version = "1.0.0"
7
+ version = "1.2.0"
8
8
  description = "一款简约的信号系统。"
9
9
  readme = "README.md"
10
10
  license-files = { paths = [ "LICENSE" ] }
11
11
  authors = [
12
12
  { name = "Cheese Unknown", email = "cheese@cheese.ren" }
13
13
  ]
14
- keywords = [ 'API', 'BackEnd' ]
14
+ keywords = [ 'Signal' ]
15
15
 
16
16
  dependencies = []
17
17
 
@@ -1,9 +0,0 @@
1
- .DS_Store
2
-
3
- __pycache__
4
-
5
- /.vscode
6
- /.conda
7
- /dist
8
- /test.py
9
- /logs
File without changes