sycommon-python-lib 0.1.38__py3-none-any.whl → 0.1.40__py3-none-any.whl
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.
- sycommon/rabbitmq/rabbitmq_client.py +199 -899
- sycommon/rabbitmq/rabbitmq_pool.py +141 -65
- sycommon/rabbitmq/rabbitmq_service.py +19 -19
- {sycommon_python_lib-0.1.38.dist-info → sycommon_python_lib-0.1.40.dist-info}/METADATA +1 -1
- {sycommon_python_lib-0.1.38.dist-info → sycommon_python_lib-0.1.40.dist-info}/RECORD +8 -8
- {sycommon_python_lib-0.1.38.dist-info → sycommon_python_lib-0.1.40.dist-info}/WHEEL +0 -0
- {sycommon_python_lib-0.1.38.dist-info → sycommon_python_lib-0.1.40.dist-info}/entry_points.txt +0 -0
- {sycommon_python_lib-0.1.38.dist-info → sycommon_python_lib-0.1.40.dist-info}/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import asyncio
|
|
2
|
+
from typing import List, Set
|
|
2
3
|
from aio_pika import connect_robust, Channel
|
|
3
4
|
from aio_pika.abc import AbstractRobustConnection
|
|
4
|
-
from aio_pika.pool import Pool
|
|
5
5
|
|
|
6
6
|
from sycommon.logging.kafka_log import SYLogger
|
|
7
7
|
|
|
@@ -9,7 +9,7 @@ logger = SYLogger
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class RabbitMQConnectionPool:
|
|
12
|
-
"""RabbitMQ
|
|
12
|
+
"""RabbitMQ连接池管理(简化实现,避免上下文管理器冲突)"""
|
|
13
13
|
|
|
14
14
|
def __init__(
|
|
15
15
|
self,
|
|
@@ -33,72 +33,148 @@ class RabbitMQConnectionPool:
|
|
|
33
33
|
self.app_name = app_name or "rabbitmq-client"
|
|
34
34
|
self.heartbeat = heartbeat
|
|
35
35
|
|
|
36
|
-
#
|
|
37
|
-
self.connection_pool: Optional[Pool] = None
|
|
38
|
-
self.channel_pool: Optional[Pool] = None
|
|
36
|
+
# 连接池配置
|
|
39
37
|
self.connection_pool_size = connection_pool_size
|
|
40
38
|
self.channel_pool_size = channel_pool_size
|
|
41
39
|
|
|
40
|
+
# 实际存储的连接和通道
|
|
41
|
+
self._connections: List[AbstractRobustConnection] = []
|
|
42
|
+
self._free_channels: List[Channel] = []
|
|
43
|
+
self._used_channels: Set[Channel] = set()
|
|
44
|
+
|
|
45
|
+
# 锁用于线程安全
|
|
46
|
+
self._conn_lock = asyncio.Lock()
|
|
47
|
+
self._chan_lock = asyncio.Lock()
|
|
48
|
+
|
|
49
|
+
# 连接状态
|
|
50
|
+
self._initialized = False
|
|
51
|
+
|
|
42
52
|
async def init_pools(self):
|
|
43
|
-
"""
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
53
|
+
"""初始化连接池(创建指定数量的连接)"""
|
|
54
|
+
if self._initialized:
|
|
55
|
+
logger.warning("连接池已初始化,无需重复调用")
|
|
56
|
+
return
|
|
57
|
+
|
|
58
|
+
try:
|
|
59
|
+
# 创建核心连接(数量=connection_pool_size)
|
|
60
|
+
for i in range(self.connection_pool_size):
|
|
61
|
+
conn = await self._create_connection()
|
|
62
|
+
self._connections.append(conn)
|
|
63
|
+
# 为每个连接创建初始通道(数量=channel_pool_size//connection_pool_size)
|
|
64
|
+
chan_count_per_conn = self.channel_pool_size // self.connection_pool_size
|
|
65
|
+
for _ in range(chan_count_per_conn):
|
|
66
|
+
chan = await conn.channel()
|
|
67
|
+
self._free_channels.append(chan)
|
|
68
|
+
|
|
69
|
+
self._initialized = True
|
|
70
|
+
logger.info(
|
|
71
|
+
f"RabbitMQ连接池初始化成功 - 连接数: {len(self._connections)}, "
|
|
72
|
+
f"空闲通道数: {len(self._free_channels)}, 集群节点: {self.hosts}"
|
|
73
|
+
)
|
|
74
|
+
except Exception as e:
|
|
75
|
+
logger.error(f"连接池初始化失败: {str(e)}", exc_info=True)
|
|
76
|
+
# 清理异常状态
|
|
77
|
+
await self.close()
|
|
78
|
+
raise
|
|
79
|
+
|
|
80
|
+
async def _create_connection(self) -> AbstractRobustConnection:
|
|
81
|
+
"""创建单个RabbitMQ连接(支持集群节点轮询)"""
|
|
82
|
+
hosts = self.hosts.copy()
|
|
83
|
+
while hosts:
|
|
84
|
+
host = hosts.pop(0)
|
|
85
|
+
try:
|
|
86
|
+
connection = await connect_robust(
|
|
87
|
+
host=host,
|
|
88
|
+
port=self.port,
|
|
89
|
+
login=self.username,
|
|
90
|
+
password=self.password,
|
|
91
|
+
virtualhost=self.virtualhost,
|
|
92
|
+
heartbeat=self.heartbeat,
|
|
93
|
+
client_properties={
|
|
94
|
+
"connection_name": f"{self.app_name}@{host}"
|
|
95
|
+
},
|
|
96
|
+
reconnect_interval=2 # aio_pika 内置重连间隔
|
|
97
|
+
)
|
|
98
|
+
logger.info(f"成功连接到 RabbitMQ 节点: {host}:{self.port}")
|
|
99
|
+
return connection
|
|
100
|
+
except Exception as e:
|
|
101
|
+
logger.warning(
|
|
102
|
+
f"连接主机 {host}:{self.port} 失败,尝试下一个节点: {str(e)}")
|
|
103
|
+
if not hosts:
|
|
104
|
+
raise # 所有节点失败时抛出异常
|
|
105
|
+
|
|
106
|
+
async def acquire_channel(self) -> Channel:
|
|
107
|
+
"""获取通道(从空闲通道池获取,无则创建新通道)"""
|
|
108
|
+
if not self._initialized:
|
|
109
|
+
raise RuntimeError("连接池未初始化,请先调用 init_pools()")
|
|
110
|
+
|
|
111
|
+
async with self._chan_lock:
|
|
112
|
+
# 优先从空闲通道池获取
|
|
113
|
+
if self._free_channels:
|
|
114
|
+
channel = self._free_channels.pop()
|
|
115
|
+
# 检查通道是否有效
|
|
116
|
+
if not channel.is_closed:
|
|
117
|
+
self._used_channels.add(channel)
|
|
118
|
+
return channel
|
|
119
|
+
else:
|
|
120
|
+
logger.warning("发现无效通道,已自动清理")
|
|
121
|
+
|
|
122
|
+
# 空闲通道不足,创建新通道(不超过最大限制)
|
|
123
|
+
if len(self._used_channels) < self.channel_pool_size:
|
|
124
|
+
# 选择一个空闲连接创建通道
|
|
125
|
+
async with self._conn_lock:
|
|
126
|
+
for conn in self._connections:
|
|
127
|
+
if not conn.is_closed:
|
|
128
|
+
try:
|
|
129
|
+
channel = await conn.channel()
|
|
130
|
+
self._used_channels.add(channel)
|
|
131
|
+
logger.info(
|
|
132
|
+
f"创建新通道,当前通道数: {len(self._used_channels)}/{self.channel_pool_size}")
|
|
133
|
+
return channel
|
|
134
|
+
except Exception as e:
|
|
135
|
+
logger.warning(f"使用连接创建通道失败: {str(e)}")
|
|
136
|
+
# 所有连接都无效,尝试重新创建连接
|
|
137
|
+
conn = await self._create_connection()
|
|
138
|
+
self._connections.append(conn)
|
|
139
|
+
channel = await conn.channel()
|
|
140
|
+
self._used_channels.add(channel)
|
|
141
|
+
return channel
|
|
142
|
+
else:
|
|
143
|
+
raise RuntimeError(f"通道池已达最大限制: {self.channel_pool_size}")
|
|
144
|
+
|
|
145
|
+
async def release_channel(self, channel: Channel):
|
|
146
|
+
"""释放通道(归还到空闲通道池)"""
|
|
147
|
+
async with self._chan_lock:
|
|
148
|
+
if channel in self._used_channels:
|
|
149
|
+
self._used_channels.remove(channel)
|
|
150
|
+
# 通道有效则归还,无效则丢弃
|
|
151
|
+
if not channel.is_closed:
|
|
152
|
+
self._free_channels.append(channel)
|
|
153
|
+
else:
|
|
154
|
+
logger.warning("释放无效通道,已自动丢弃")
|
|
155
|
+
|
|
156
|
+
async def close(self):
|
|
157
|
+
"""关闭连接池(释放所有连接和通道)"""
|
|
158
|
+
# 释放所有通道
|
|
159
|
+
async with self._chan_lock:
|
|
160
|
+
for channel in self._free_channels + list(self._used_channels):
|
|
50
161
|
try:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
port=self.port,
|
|
54
|
-
login=self.username,
|
|
55
|
-
password=self.password,
|
|
56
|
-
virtualhost=self.virtualhost,
|
|
57
|
-
heartbeat=self.heartbeat,
|
|
58
|
-
client_properties={
|
|
59
|
-
"connection_name": f"{self.app_name}@{host}"
|
|
60
|
-
}
|
|
61
|
-
)
|
|
162
|
+
if not channel.is_closed:
|
|
163
|
+
await channel.close()
|
|
62
164
|
except Exception as e:
|
|
63
|
-
logger.warning(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
raise # 所有节点都失败时抛出异常
|
|
67
|
-
|
|
68
|
-
# 初始化连接池
|
|
69
|
-
self.connection_pool = Pool(
|
|
70
|
-
create_connection,
|
|
71
|
-
max_size=self.connection_pool_size
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
# 通道创建函数
|
|
75
|
-
async def create_channel() -> Channel:
|
|
76
|
-
async with self.connection_pool.acquire() as connection:
|
|
77
|
-
channel = await connection.channel()
|
|
78
|
-
return channel
|
|
79
|
-
|
|
80
|
-
# 初始化通道池
|
|
81
|
-
self.channel_pool = Pool(
|
|
82
|
-
create_channel,
|
|
83
|
-
max_size=self.channel_pool_size
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
logger.info(
|
|
87
|
-
f"RabbitMQ连接池初始化完成 - 连接池大小: {self.connection_pool_size}, "
|
|
88
|
-
f"通道池大小: {self.channel_pool_size}, 集群节点: {self.hosts}"
|
|
89
|
-
)
|
|
165
|
+
logger.warning(f"关闭通道失败: {str(e)}")
|
|
166
|
+
self._free_channels.clear()
|
|
167
|
+
self._used_channels.clear()
|
|
90
168
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
async def __aexit__(self, exc_type, exc, tb):
|
|
104
|
-
await self.close()
|
|
169
|
+
# 关闭所有连接
|
|
170
|
+
async with self._conn_lock:
|
|
171
|
+
for conn in self._connections:
|
|
172
|
+
try:
|
|
173
|
+
if not conn.is_closed:
|
|
174
|
+
await conn.close()
|
|
175
|
+
except Exception as e:
|
|
176
|
+
logger.warning(f"关闭连接失败: {str(e)}")
|
|
177
|
+
self._connections.clear()
|
|
178
|
+
|
|
179
|
+
self._initialized = False
|
|
180
|
+
logger.info("RabbitMQ连接池已完全关闭")
|
|
@@ -179,18 +179,14 @@ class RabbitMQService:
|
|
|
179
179
|
auto_delete=kwargs.get('auto_delete', False),
|
|
180
180
|
auto_parse_json=kwargs.get('auto_parse_json', True),
|
|
181
181
|
create_if_not_exists=create_if_not_exists,
|
|
182
|
-
connection_timeout=kwargs.get('connection_timeout', 10),
|
|
183
182
|
rpc_timeout=kwargs.get('rpc_timeout', 10),
|
|
184
|
-
reconnection_delay=kwargs.get('reconnection_delay', 1),
|
|
185
|
-
max_reconnection_attempts=kwargs.get(
|
|
186
|
-
'max_reconnection_attempts', 5),
|
|
187
183
|
prefetch_count=kwargs.get('prefetch_count', 2),
|
|
188
184
|
consumption_stall_threshold=kwargs.get(
|
|
189
185
|
'consumption_stall_threshold', 60), # 延长停滞阈值
|
|
190
186
|
)
|
|
191
187
|
|
|
192
|
-
#
|
|
193
|
-
await client.connect(
|
|
188
|
+
# 新客户端connect无declare_queue参数,自动根据create_if_not_exists处理
|
|
189
|
+
await client.connect()
|
|
194
190
|
|
|
195
191
|
# 监听器客户端连接后延迟1秒,确保消费状态就绪(仅首次启动)
|
|
196
192
|
if not is_sender and create_if_not_exists:
|
|
@@ -245,13 +241,13 @@ class RabbitMQService:
|
|
|
245
241
|
if not queue:
|
|
246
242
|
logger.info(f"客户端 '{client_name}' 队列未初始化,重新连接")
|
|
247
243
|
client.create_if_not_exists = True
|
|
248
|
-
await client.connect(force_reconnect
|
|
244
|
+
await client.connect() # 移除force_reconnect和declare_queue
|
|
249
245
|
return client
|
|
250
246
|
else:
|
|
251
247
|
logger.info(f"客户端 '{client_name}' 连接已关闭,重新连接")
|
|
252
248
|
if not is_sender:
|
|
253
249
|
client.create_if_not_exists = True
|
|
254
|
-
await client.connect(declare_queue
|
|
250
|
+
await client.connect() # 移除force_reconnect和declare_queue
|
|
255
251
|
return client
|
|
256
252
|
|
|
257
253
|
# 创建新客户端
|
|
@@ -267,7 +263,7 @@ class RabbitMQService:
|
|
|
267
263
|
app_name=cls._config.get("APP_NAME", ""),
|
|
268
264
|
**kwargs
|
|
269
265
|
)
|
|
270
|
-
await client.connect(declare_queue=False
|
|
266
|
+
await client.connect() # 移除declare_queue=False
|
|
271
267
|
cls._clients[client_name] = client
|
|
272
268
|
return client
|
|
273
269
|
|
|
@@ -280,7 +276,7 @@ class RabbitMQService:
|
|
|
280
276
|
client = await cls._create_client(
|
|
281
277
|
initial_queue_name, ** kwargs
|
|
282
278
|
)
|
|
283
|
-
await client.connect(declare_queue=True
|
|
279
|
+
await client.connect() # 移除declare_queue=True
|
|
284
280
|
cls._clients[client_name] = client
|
|
285
281
|
return client
|
|
286
282
|
|
|
@@ -292,14 +288,14 @@ class RabbitMQService:
|
|
|
292
288
|
)
|
|
293
289
|
|
|
294
290
|
client.create_if_not_exists = True
|
|
295
|
-
await client.connect(declare_queue=True
|
|
291
|
+
await client.connect() # 移除declare_queue=True
|
|
296
292
|
|
|
297
293
|
# 验证队列是否创建成功(异步获取队列)
|
|
298
294
|
_, _, queue = await client._get_connection_resources()
|
|
299
295
|
if not queue:
|
|
300
296
|
logger.error(f"队列 '{initial_queue_name}' 创建失败,尝试重新创建")
|
|
301
297
|
client.create_if_not_exists = True
|
|
302
|
-
await client.connect(
|
|
298
|
+
await client.connect()
|
|
303
299
|
_, _, queue = await client._get_connection_resources()
|
|
304
300
|
if not queue:
|
|
305
301
|
raise Exception(f"无法创建队列 '{initial_queue_name}'")
|
|
@@ -348,7 +344,7 @@ class RabbitMQService:
|
|
|
348
344
|
if normalized_name in cls._clients:
|
|
349
345
|
client = cls._clients[normalized_name]
|
|
350
346
|
if not await client.is_connected:
|
|
351
|
-
await client.connect(declare_queue=False
|
|
347
|
+
await client.connect() # 移除declare_queue=False
|
|
352
348
|
else:
|
|
353
349
|
client = await cls.get_client(
|
|
354
350
|
client_name=normalized_name,
|
|
@@ -535,15 +531,19 @@ class RabbitMQService:
|
|
|
535
531
|
while attempt < max_attempts and not stop_event.is_set() and not cls._is_shutdown:
|
|
536
532
|
try:
|
|
537
533
|
# 启动消费前再次校验连接和队列状态
|
|
538
|
-
if not await client.is_connected:
|
|
534
|
+
if not await client.is_connected: # 确保这里没有括号
|
|
539
535
|
logger.info(f"消费者 '{client_name}' 连接断开,尝试重连")
|
|
540
|
-
await client.connect(
|
|
536
|
+
await client.connect()
|
|
541
537
|
|
|
542
538
|
# 确保队列已就绪
|
|
543
539
|
_, _, queue = await client._get_connection_resources()
|
|
544
540
|
if not queue:
|
|
545
541
|
raise Exception("队列未初始化完成")
|
|
546
542
|
|
|
543
|
+
# 确保消息处理器已设置
|
|
544
|
+
if not hasattr(client, '_message_handler') or not client._message_handler:
|
|
545
|
+
raise Exception("消息处理器未设置")
|
|
546
|
+
|
|
547
547
|
consumer_tag = await client.start_consuming()
|
|
548
548
|
if consumer_tag:
|
|
549
549
|
break
|
|
@@ -552,7 +552,7 @@ class RabbitMQService:
|
|
|
552
552
|
logger.warning(
|
|
553
553
|
f"启动消费者尝试 {attempt}/{max_attempts} 失败: {str(e)}")
|
|
554
554
|
if attempt < max_attempts:
|
|
555
|
-
await asyncio.sleep(
|
|
555
|
+
await asyncio.sleep(2) # 延长重试间隔
|
|
556
556
|
|
|
557
557
|
if cls._is_shutdown:
|
|
558
558
|
logger.info("服务关闭中,消费者启动中止")
|
|
@@ -644,7 +644,7 @@ class RabbitMQService:
|
|
|
644
644
|
else:
|
|
645
645
|
logger.info(f"发送器 '{queue_name}' 连接已断开,尝试重连")
|
|
646
646
|
try:
|
|
647
|
-
await client.connect(declare_queue=False
|
|
647
|
+
await client.connect() # 移除declare_queue=False
|
|
648
648
|
if await client.is_connected:
|
|
649
649
|
return client
|
|
650
650
|
except Exception as e:
|
|
@@ -662,7 +662,7 @@ class RabbitMQService:
|
|
|
662
662
|
else:
|
|
663
663
|
logger.info(f"发送器 '{suffixed_name}' 连接已断开,尝试重连")
|
|
664
664
|
try:
|
|
665
|
-
await client.connect(declare_queue=False
|
|
665
|
+
await client.connect() # 移除declare_queue=False
|
|
666
666
|
if await client.is_connected:
|
|
667
667
|
return client
|
|
668
668
|
except Exception as e:
|
|
@@ -698,7 +698,7 @@ class RabbitMQService:
|
|
|
698
698
|
while retry_count < max_retry and not cls._is_shutdown:
|
|
699
699
|
try:
|
|
700
700
|
# 尝试重连,每次重试间隔1秒
|
|
701
|
-
await sender.connect(force_reconnect
|
|
701
|
+
await sender.connect() # 移除force_reconnect和declare_queue
|
|
702
702
|
if await sender.is_connected:
|
|
703
703
|
logger.info(
|
|
704
704
|
f"发送器 '{queue_name}' 第 {retry_count + 1} 次重连成功")
|
|
@@ -35,9 +35,9 @@ sycommon/models/mqlistener_config.py,sha256=vXp2uMmd0XQ5B9noSRXWHewTy-juQ2y7IsWt
|
|
|
35
35
|
sycommon/models/mqmsg_model.py,sha256=cxn0M5b0utQK6crMYmL-1waeGYHvK3AlGaRy23clqTE,277
|
|
36
36
|
sycommon/models/mqsend_config.py,sha256=NQX9dc8PpuquMG36GCVhJe8omAW1KVXXqr6lSRU6D7I,268
|
|
37
37
|
sycommon/models/sso_user.py,sha256=i1WAN6k5sPcPApQEdtjpWDy7VrzWLpOrOQewGLGoGIw,2702
|
|
38
|
-
sycommon/rabbitmq/rabbitmq_client.py,sha256=
|
|
39
|
-
sycommon/rabbitmq/rabbitmq_pool.py,sha256=
|
|
40
|
-
sycommon/rabbitmq/rabbitmq_service.py,sha256=
|
|
38
|
+
sycommon/rabbitmq/rabbitmq_client.py,sha256=vyyfIWJ0b7tXZSK1m8fKERW6D-LQCrDvmjKmsPvOG6M,12141
|
|
39
|
+
sycommon/rabbitmq/rabbitmq_pool.py,sha256=YmvvFO8xP2pNnwuyZ0vp28XnfTzPScIPnBMih34f7Wc,7390
|
|
40
|
+
sycommon/rabbitmq/rabbitmq_service.py,sha256=LXoL7zm-1_iTts6S9CreEMJ66ExwRm9y4zUmcOqI1YM,36597
|
|
41
41
|
sycommon/sse/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
42
42
|
sycommon/sse/event.py,sha256=k_rBJy23R7crtzQeetT0Q73D8o5-5p-eESGSs_BPOj0,2797
|
|
43
43
|
sycommon/sse/sse.py,sha256=__CfWEcYxOxQ-HpLor4LTZ5hLWqw9-2X7CngqbVHsfw,10128
|
|
@@ -52,8 +52,8 @@ sycommon/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
52
52
|
sycommon/tools/docs.py,sha256=OPj2ETheuWjXLyaXtaZPbwmJKfJaYXV5s4XMVAUNrms,1607
|
|
53
53
|
sycommon/tools/snowflake.py,sha256=DdEj3T5r5OEvikp3puxqmmmz6BrggxomoSlnsRFb5dM,1174
|
|
54
54
|
sycommon/tools/timing.py,sha256=OiiE7P07lRoMzX9kzb8sZU9cDb0zNnqIlY5pWqHcnkY,2064
|
|
55
|
-
sycommon_python_lib-0.1.
|
|
56
|
-
sycommon_python_lib-0.1.
|
|
57
|
-
sycommon_python_lib-0.1.
|
|
58
|
-
sycommon_python_lib-0.1.
|
|
59
|
-
sycommon_python_lib-0.1.
|
|
55
|
+
sycommon_python_lib-0.1.40.dist-info/METADATA,sha256=-9GpbSobbSHJj66au2M-0ThPFN5ynZEALO69lvLOClY,7037
|
|
56
|
+
sycommon_python_lib-0.1.40.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
57
|
+
sycommon_python_lib-0.1.40.dist-info/entry_points.txt,sha256=q_h2nbvhhmdnsOUZEIwpuoDjaNfBF9XqppDEmQn9d_A,46
|
|
58
|
+
sycommon_python_lib-0.1.40.dist-info/top_level.txt,sha256=98CJ-cyM2WIKxLz-Pf0AitWLhJyrfXvyY8slwjTXNuc,17
|
|
59
|
+
sycommon_python_lib-0.1.40.dist-info/RECORD,,
|
|
File without changes
|
{sycommon_python_lib-0.1.38.dist-info → sycommon_python_lib-0.1.40.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|