Skip to content

Commit 6356746

Browse files
authored
Merge pull request #93 from ljzloser/master
refactor: 改进类型注解并修复代码风格
2 parents 58c60dc + ce3dfd8 commit 6356746

File tree

24 files changed

+1900
-1275
lines changed

24 files changed

+1900
-1275
lines changed

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ zmq>=0.0.0
66
pywin32>=311
77
loguru>=0.7.3
88
debugpy>=1.8.20
9+
PyQt5-stubs>=5.15.6.0

src/lib_zmq_plugins/client/zmq_client.py

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -104,31 +104,6 @@ def connect(self) -> None:
104104
# 启动后立即发一次心跳作为探测
105105
self._probe_connection()
106106

107-
@property
108-
def is_connected(self) -> bool:
109-
"""当前连接状态"""
110-
return self._is_connected
111-
112-
@property
113-
def reconnect_count(self) -> int:
114-
"""重连次数"""
115-
return self._reconnect_count
116-
117-
@property
118-
def endpoint(self) -> str:
119-
"""当前端点地址"""
120-
return self._endpoint
121-
122-
@property
123-
def pub_endpoint(self) -> str:
124-
"""PUB 端点地址"""
125-
return self._pub_endpoint
126-
127-
@property
128-
def ctrl_endpoint(self) -> str:
129-
"""CTRL 端点地址"""
130-
return self._ctrl_endpoint
131-
132107
def disconnect(self) -> None:
133108
self._stopped.set()
134109
if self._thread and self._thread.is_alive():
@@ -145,6 +120,8 @@ def _create_sockets(self) -> None:
145120
return
146121
self._sub_socket = self._ctx.socket(zmq.SUB)
147122
self._dealer_socket = self._ctx.socket(zmq.DEALER)
123+
if self._dealer_socket is None:
124+
return
148125
self._dealer_socket.setsockopt_string(zmq.IDENTITY, uuid.uuid4().hex)
149126

150127
# 启用 ZMQ 原生心跳,自动检测服务端断开
@@ -154,7 +131,8 @@ def _create_sockets(self) -> None:
154131
self._dealer_socket.setsockopt(zmq.HEARTBEAT_IVL, 5000)
155132
self._dealer_socket.setsockopt(zmq.HEARTBEAT_TIMEOUT, 5000)
156133
self._dealer_socket.setsockopt(zmq.HEARTBEAT_TTL, 10000)
157-
134+
if self._sub_socket is None:
135+
return
158136
self._sub_socket.connect(self._pub_endpoint)
159137
self._dealer_socket.connect(self._ctrl_endpoint)
160138

@@ -202,7 +180,8 @@ def _request_snapshot(self, topic: str) -> None:
202180
try:
203181
self._dealer_socket.send(payload)
204182
except zmq.ZMQError:
205-
self._log.warning("Failed to send sync request for topic: %s", topic)
183+
self._log.warning(
184+
"Failed to send sync request for topic: %s", topic)
206185
self._sync_topics.pop(rid, None)
207186

208187
# ── 指令发送(可在任意线程调用) ──
@@ -231,7 +210,7 @@ def request(
231210
def _poll_loop(self) -> None:
232211
while not self._stopped.is_set():
233212
try:
234-
events = self._poller.poll(timeout=200)
213+
events = self._poller.poll(timeout=200) # type: ignore
235214
except zmq.ZMQError:
236215
self._handle_reconnect(0.1)
237216
continue
@@ -275,7 +254,7 @@ def _probe_connection(self) -> bool:
275254

276255
def _handle_sub_message(self) -> None:
277256
try:
278-
msg = self._sub_socket.recv_multipart(zmq.NOBLOCK)
257+
msg = self._sub_socket.recv_multipart(zmq.NOBLOCK) # type: ignore
279258
except zmq.Again:
280259
return
281260
if len(msg) < 2:
@@ -293,7 +272,8 @@ def _handle_sub_message(self) -> None:
293272

294273
def _handle_dealer_message(self) -> None:
295274
try:
296-
msg = self._dealer_socket.recv_multipart(zmq.NOBLOCK)
275+
msg = self._dealer_socket.recv_multipart( # type: ignore
276+
zmq.NOBLOCK)
297277
except zmq.Again:
298278
return
299279
if len(msg) < 2:
@@ -312,7 +292,8 @@ def _handle_dealer_message(self) -> None:
312292
snapshot = self._serializer.decode_event(resp.data)
313293
self._notify_subscribers(topic, snapshot)
314294
except Exception:
315-
self._log.warning("Failed to decode snapshot", exc_info=True)
295+
self._log.warning(
296+
"Failed to decode snapshot", exc_info=True)
316297
else:
317298
self._sync_topics.pop(resp.request_id, None)
318299

src/lib_zmq_plugins/serializer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def _make_union(types: list[type]) -> type:
2929
"""将类型列表转为 Union 类型,供 msgspec 多态反序列化使用"""
3030
if len(types) == 1:
3131
return types[0]
32-
return Union[tuple(types)]
32+
return Union[tuple(types)] # type: ignore
3333

3434

3535
class Serializer:

src/lib_zmq_plugins/server/zmq_server.py

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ def __init__(self, endpoint: str, log_handler: LogHandler | None = None) -> None
4646
self._pub_endpoint, self._ctrl_endpoint = _derive_endpoints(endpoint)
4747
self._serializer = Serializer()
4848
self._serializer.register_command_types(SyncCommand)
49-
self._handlers: dict[str, Callable[[BaseCommand], CommandResponse | None]] = {}
49+
self._handlers: dict[str, Callable[[
50+
BaseCommand], CommandResponse | None]] = {}
5051
self._snapshot_providers: dict[str, Callable[[], BaseEvent]] = {}
5152
self._log: LogHandler = log_handler or NullHandler()
5253

@@ -89,7 +90,8 @@ def start(self) -> None:
8990
self._ctx = zmq.Context()
9091
self._pub_socket = self._ctx.socket(zmq.PUB)
9192
self._router_socket = self._ctx.socket(zmq.ROUTER)
92-
93+
if self._pub_socket is None or self._router_socket is None:
94+
raise RuntimeError("Failed to create socket")
9395
# 启用 ZMQ 原生心跳,与客户端匹配
9496
# HEARTBEAT_IVL: 每 5 秒发送心跳
9597
# HEARTBEAT_TIMEOUT: 5 秒内没收到回复视为断连
@@ -108,7 +110,8 @@ def start(self) -> None:
108110
self._thread = threading.Thread(target=self._poll_loop, daemon=True)
109111
self._thread.start()
110112

111-
self._log.info("Server started: pub=%s, ctrl=%s", self._pub_endpoint, self._ctrl_endpoint)
113+
self._log.info("Server started: pub=%s, ctrl=%s",
114+
self._pub_endpoint, self._ctrl_endpoint)
112115

113116
def stop(self) -> None:
114117
self._stopped.set()
@@ -141,14 +144,15 @@ def publish(self, topic: type[BaseEvent], event: BaseEvent) -> None:
141144
def _poll_loop(self) -> None:
142145
while not self._stopped.is_set():
143146
try:
144-
events = self._poller.poll(timeout=100)
147+
events = self._poller.poll(timeout=100) # type: ignore
145148
except zmq.ZMQError:
146149
break
147150

148151
for socket, _ in events:
149152
if socket is self._router_socket:
150153
try:
151-
msg = self._router_socket.recv_multipart(zmq.NOBLOCK)
154+
msg = self._router_socket.recv_multipart( # type: ignore
155+
zmq.NOBLOCK)
152156
except zmq.Again:
153157
continue
154158
if len(msg) < 2:
@@ -158,7 +162,8 @@ def _poll_loop(self) -> None:
158162
try:
159163
cmd = self._serializer.decode_command(payload)
160164
except Exception:
161-
self._log.warning("Failed to decode command", exc_info=True)
165+
self._log.warning(
166+
"Failed to decode command", exc_info=True)
162167
continue
163168
self._dispatch(client_id, cmd)
164169

@@ -167,11 +172,12 @@ def _dispatch(self, client_id: bytes, cmd: BaseCommand) -> None:
167172
if isinstance(tag, type):
168173
tag = tag.__name__
169174
tag = str(tag)
170-
171-
self._log.info("[Server] 收到命令: tag=%s, request_id=%s", tag, cmd.request_id)
175+
176+
self._log.info("[Server] 收到命令: tag=%s, request_id=%s",
177+
tag, cmd.request_id)
172178

173179
if tag == "__sync__":
174-
self._handle_sync(client_id, cmd)
180+
self._handle_sync(client_id, cmd) # type: ignore
175181
return
176182

177183
handler = self._handlers.get(tag)
@@ -181,7 +187,8 @@ def _dispatch(self, client_id: bytes, cmd: BaseCommand) -> None:
181187

182188
try:
183189
result = handler(cmd)
184-
self._log.info("[Server] handler 执行完成: tag=%s, result=%s", tag, result)
190+
self._log.info(
191+
"[Server] handler 执行完成: tag=%s, result=%s", tag, result)
185192
except Exception as e:
186193
self._log.error("Handler error for %s: %s", tag, e, exc_info=True)
187194
if cmd.request_id:
@@ -211,7 +218,8 @@ def _handle_sync(self, client_id: bytes, cmd: SyncCommand) -> None:
211218
request_id=cmd.request_id, success=True, data=payload
212219
)
213220
except Exception as e:
214-
self._log.error("Snapshot provider error for %s: %s", topic, e, exc_info=True)
221+
self._log.error(
222+
"Snapshot provider error for %s: %s", topic, e, exc_info=True)
215223
resp = CommandResponse(
216224
request_id=cmd.request_id, success=False, error=str(e)
217225
)
@@ -225,4 +233,5 @@ def _send_to_client(self, client_id: bytes, resp: CommandResponse) -> None:
225233
[client_id, b"", self._serializer.encode_response(resp)]
226234
)
227235
except zmq.ZMQError:
228-
self._log.warning("Failed to send response to client", exc_info=True)
236+
self._log.warning(
237+
"Failed to send response to client", exc_info=True)

src/mineSweeperGUI.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ def game_state(self, game_state: str):
278278
current_status=state_map.get(game_state, 0),
279279
)
280280
GameServerBridge.instance().send_event(event)
281-
self._send_board_update_event()
281+
self._send_board_update_event()
282282

283283
@property
284284
def row(self):

src/plugin_manager/config_widget.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ def _setup_ui(self) -> None:
6767
return
6868

6969
for name, config_field in fields.items():
70+
# 跳过不可见的配置项(用于插件存储私有数据)
71+
if not config_field.visible:
72+
continue
73+
7074
# 使用 config_field 自己的 create_widget 方法
7175
widget = config_field.create_widget()
7276

src/plugin_manager/plugin_loader.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class PluginLoader:
2828
- 实例化插件类
2929
"""
3030

31-
def __init__(self, plugin_dirs: list[str | Path] | None = None):
31+
def __init__(self, plugin_dirs: list[Path] | None = None):
3232
self._plugin_dirs: list[Path] = []
3333
self._added_paths: set[Path] = set() # 已添加到 sys.path 的目录
3434
if plugin_dirs:

0 commit comments

Comments
 (0)