sycommon-python-lib 0.1.56b10__py3-none-any.whl → 0.1.56b12__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.
@@ -42,7 +42,9 @@ class RabbitMQConsumerManager(RabbitMQClientManager):
42
42
  # 创建并初始化客户端
43
43
  await cls.get_client(
44
44
  client_name=queue_name,
45
- queue_name=queue_name, ** kwargs
45
+ client_type="listener",
46
+ queue_name=queue_name,
47
+ ** kwargs
46
48
  )
47
49
 
48
50
  # 注册消息处理器
@@ -70,8 +70,8 @@ class RabbitMQCoreService:
70
70
  virtualhost=cls._config.get('virtual-host', "/"),
71
71
  app_name=cls._config.get("APP_NAME", ""),
72
72
  prefetch_count=global_prefetch_count,
73
- heartbeat=cls._config.get('heartbeat', 30),
74
- connection_timeout=cls._config.get('connection_timeout', 30),
73
+ heartbeat=cls._config.get('heartbeat', 15),
74
+ connection_timeout=cls._config.get('connection_timeout', 15),
75
75
  reconnect_interval=cls._config.get('reconnect_interval', 5),
76
76
  )
77
77
 
@@ -24,7 +24,7 @@ class RabbitMQProducerManager(RabbitMQClientManager):
24
24
 
25
25
  @classmethod
26
26
  async def setup_senders(cls, senders: List[RabbitMQSendConfig], has_listeners: bool = False, **kwargs) -> None:
27
- """设置消息发送器"""
27
+ """设置消息发送器(适配client_type参数,确保发送器不创建队列)"""
28
28
  if cls._is_shutdown:
29
29
  logger.warning("服务已关闭,无法设置发送器")
30
30
  return
@@ -42,33 +42,36 @@ class RabbitMQProducerManager(RabbitMQClientManager):
42
42
  app_name = cls._config.get(
43
43
  "APP_NAME", "") if cls._config else ""
44
44
 
45
- # 处理发送器队列名称
45
+ # 处理发送器客户端名称(非队列名)
46
46
  normalized_name = queue_name
47
47
  if app_name and normalized_name.endswith(f".{app_name}"):
48
48
  normalized_name = normalized_name[:-len(f".{app_name}")]
49
- logger.info(f"发送器队列名称移除app-name后缀: {normalized_name}")
49
+ logger.info(f"发送器客户端名称移除app-name后缀: {normalized_name}")
50
50
 
51
51
  # 检查是否已初始化
52
52
  if normalized_name in cls._sender_client_names:
53
53
  logger.info(f"发送客户端 '{normalized_name}' 已存在,跳过")
54
54
  continue
55
55
 
56
- # 获取或创建客户端
56
+ # ===== 处理已有客户端重连 =====
57
57
  if normalized_name in cls._clients:
58
58
  client = cls._clients[normalized_name]
59
59
  if not await client.is_connected:
60
+ client.queue_name = normalized_name
60
61
  client.create_if_not_exists = False
61
62
  await client.connect()
62
63
  else:
63
64
  client = await cls.get_client(
64
65
  client_name=normalized_name,
66
+ client_type="sender",
65
67
  exchange_type=sender_config.exchange_type,
66
68
  durable=sender_config.durable,
67
69
  auto_delete=sender_config.auto_delete,
68
70
  auto_parse_json=sender_config.auto_parse_json,
69
71
  queue_name=queue_name,
70
72
  create_if_not_exists=False,
71
- prefetch_count=prefetch_count, ** kwargs
73
+ prefetch_count=prefetch_count,
74
+ **kwargs
72
75
  )
73
76
 
74
77
  # 记录客户端
@@ -2,6 +2,7 @@ import json
2
2
  import threading
3
3
  import time
4
4
  from typing import Callable, Optional, Dict, List
5
+ from sycommon.synacos.nacos_client_base import NacosClientBase
5
6
  import yaml
6
7
  from sycommon.logging.kafka_log import SYLogger
7
8
 
@@ -9,7 +10,7 @@ from sycommon.logging.kafka_log import SYLogger
9
10
  class NacosConfigManager:
10
11
  """Nacos配置管理类 - 负责配置读取、监听和更新"""
11
12
 
12
- def __init__(self, client_base):
13
+ def __init__(self, client_base: NacosClientBase):
13
14
  self.client_base = client_base
14
15
 
15
16
  # 配置
@@ -1,12 +1,14 @@
1
1
  import threading
2
2
  import time
3
3
  from sycommon.logging.kafka_log import SYLogger
4
+ from sycommon.synacos.nacos_client_base import NacosClientBase
5
+ from sycommon.synacos.nacos_service_registration import NacosServiceRegistration
4
6
 
5
7
 
6
8
  class NacosHeartbeatManager:
7
9
  """Nacos心跳管理类 - 负责心跳发送和监控"""
8
10
 
9
- def __init__(self, client_base, registration, heartbeat_interval: int = 15):
11
+ def __init__(self, client_base: NacosClientBase, registration: NacosServiceRegistration, heartbeat_interval: int = 15):
10
12
  self.client_base = client_base
11
13
  self.registration = registration
12
14
 
@@ -13,6 +13,7 @@ from sycommon.synacos.nacos_service_registration import NacosServiceRegistration
13
13
  from sycommon.synacos.nacos_heartbeat_manager import NacosHeartbeatManager
14
14
  from sycommon.synacos.nacos_config_manager import NacosConfigManager
15
15
  from sycommon.synacos.nacos_service_discovery import NacosServiceDiscovery
16
+ from sycommon.tools.env import check_env_flag, get_env_var
16
17
 
17
18
 
18
19
  class NacosService(metaclass=SingletonMeta):
@@ -23,9 +24,9 @@ class NacosService(metaclass=SingletonMeta):
23
24
  self.service_name = config['Name']
24
25
  self.host = config['Host']
25
26
  self.port = config['Port']
26
- self.version = os.getenv('VERSION')
27
- self.enable_register_nacos = os.getenv(
28
- 'REGISTER-NACOS', 'true').lower() == 'true'
27
+ self.version = get_env_var('VERSION')
28
+ self.enable_register_nacos = check_env_flag(
29
+ ['REGISTER-NACOS'], 'true')
29
30
 
30
31
  # 初始化基础模块
31
32
  self.client_base = NacosClientBase(
@@ -1,12 +1,14 @@
1
1
  import threading
2
2
  from typing import List, Dict
3
3
  from sycommon.logging.kafka_log import SYLogger
4
+ from sycommon.synacos.nacos_client_base import NacosClientBase
5
+ from sycommon.synacos.nacos_service_registration import NacosServiceRegistration
4
6
 
5
7
 
6
8
  class NacosServiceDiscovery:
7
9
  """Nacos服务发现类 - 负责服务实例发现和轮询"""
8
10
 
9
- def __init__(self, client_base):
11
+ def __init__(self, client_base: NacosClientBase):
10
12
  self.client_base = client_base
11
13
 
12
14
  # 轮询管理
@@ -91,7 +93,7 @@ class NacosServiceDiscovery:
91
93
  SYLogger.error(f"nacos:服务发现失败: {service_name}: {str(e)}")
92
94
  return []
93
95
 
94
- def monitor_connection(self, registration):
96
+ def monitor_connection(self, registration: NacosServiceRegistration):
95
97
  """连接监控线程"""
96
98
  with self._monitor_thread_lock:
97
99
  if self.client_base._shutdown_event.is_set() or self._monitor_thread_started:
@@ -2,12 +2,13 @@ import threading
2
2
  import time
3
3
  import atexit
4
4
  from sycommon.logging.kafka_log import SYLogger
5
+ from sycommon.synacos.nacos_client_base import NacosClientBase
5
6
 
6
7
 
7
8
  class NacosServiceRegistration:
8
9
  """Nacos服务注册类 - 负责服务注册、注销和状态验证"""
9
10
 
10
- def __init__(self, client_base, service_name: str, real_ip: str, port: int, version: str):
11
+ def __init__(self, client_base: NacosClientBase, service_name: str, real_ip: str, port: int, version: str):
11
12
  self.client_base = client_base
12
13
  self.service_name = service_name
13
14
  self.real_ip = real_ip
@@ -182,6 +183,8 @@ class NacosServiceRegistration:
182
183
  retry_count = 0
183
184
  last_error = None
184
185
  self.registered = False
186
+ # 首次注册尝试标记
187
+ first_attempt = True
185
188
 
186
189
  while (not self.registered) and (self.max_long_term_retries < 0 or retry_count < self.max_long_term_retries):
187
190
  if self.registered:
@@ -193,27 +196,42 @@ class NacosServiceRegistration:
193
196
  raise RuntimeError("nacos:服务注册请求失败")
194
197
 
195
198
  SYLogger.info(
196
- f"nacos:服务注册请求已发送,延迟 {self.registration_post_delay} 秒后开始验证")
197
- time.sleep(self.registration_post_delay)
199
+ f"nacos:服务注册请求已发送,{'首次启动信任注册,跳过阻塞验证' if first_attempt else f'延迟 {self.registration_post_delay} 秒后开始验证'}")
198
200
 
199
- registered = self.verify_registration()
200
- self.registered = registered
201
-
202
- if self.registered:
201
+ # 核心逻辑:首次注册跳过阻塞验证,非首次按原逻辑
202
+ if first_attempt:
203
+ # 首次注册:直接标记成功,不阻塞
204
+ self.registered = True
203
205
  self.client_base._client_initialized = True
204
206
  self.client_base._shutdown_event.set()
205
207
  self.client_base._shutdown_event.clear()
206
208
  self._long_term_retry_count = 0
207
209
 
208
- SYLogger.info(
209
- f"nacos:服务注册成功并通过验证: {self.service_name}")
210
+ SYLogger.info(f"nacos:首次启动信任注册成功: {self.service_name}")
211
+ first_attempt = False # 标记为非首次
210
212
  return True
211
213
  else:
212
- raise RuntimeError("nacos:服务注册验证失败")
214
+ # 非首次/重试:保留原有阻塞验证逻辑
215
+ time.sleep(self.registration_post_delay)
216
+ registered = self.verify_registration()
217
+ self.registered = registered
218
+
219
+ if self.registered:
220
+ self.client_base._client_initialized = True
221
+ self.client_base._shutdown_event.set()
222
+ self.client_base._shutdown_event.clear()
223
+ self._long_term_retry_count = 0
224
+
225
+ SYLogger.info(
226
+ f"nacos:服务注册成功并通过验证: {self.service_name}")
227
+ return True
228
+ else:
229
+ raise RuntimeError("nacos:服务注册验证失败")
213
230
 
214
231
  except Exception as e:
215
232
  last_error = str(e)
216
233
  retry_count += 1
234
+ first_attempt = False # 失败后标记为非首次
217
235
  delay = min(self.register_retry_interval,
218
236
  self.client_base.max_retry_delay)
219
237
 
sycommon/tools/env.py ADDED
@@ -0,0 +1,62 @@
1
+ import os
2
+
3
+
4
+ def _normalize_env_key(key: str) -> str:
5
+ """
6
+ 环境变量名标准化:
7
+ 1. 转小写
8
+ 2. 中划线(-)和下划线(_)统一替换为下划线(_)
9
+ :param key: 原始环境变量名
10
+ :return: 标准化后的key
11
+ """
12
+ return key.lower().replace('-', '_')
13
+
14
+
15
+ def check_env_flag(target_keys: list, default: str = 'false') -> bool:
16
+ """
17
+ 检查环境变量是否为"true"(自动兼容:大小写、中划线/下划线)
18
+ :param target_keys: 目标变量名列表(如 ['REGISTER-NACOS'],无需传双key)
19
+ :param default: 默认值(未找到变量时使用)
20
+ :return: 布尔值
21
+ """
22
+ # 1. 标准化目标key(小写+统一下划线)
23
+ target_keys_normalized = [_normalize_env_key(k) for k in target_keys]
24
+
25
+ # 2. 遍历所有环境变量,标准化后匹配
26
+ for env_key, env_val in os.environ.items():
27
+ env_key_normalized = _normalize_env_key(env_key)
28
+ if env_key_normalized in target_keys_normalized:
29
+ # 3. 值去空格 + 转小写 判断
30
+ return env_val.strip().lower() == 'true'
31
+
32
+ # 4. 未找到变量时,判断默认值
33
+ return default.strip().lower() == 'true'
34
+
35
+
36
+ def get_env_var(key: str, default='', case_insensitive: bool = True) -> str:
37
+ """
38
+ 获取环境变量值(自动兼容:大小写、中划线/下划线)
39
+ :param key: 目标环境变量名(如 'REGISTER-NACOS'/'version')
40
+ :param default: 无匹配时的默认值,默认空字符串
41
+ :param case_insensitive: 是否忽略变量名大小写(默认True,建议保持)
42
+ :return: 匹配到的环境变量值 / 默认值
43
+ """
44
+ if case_insensitive:
45
+ # 标准化目标key(小写+统一下划线)
46
+ target_key_normalized = _normalize_env_key(key)
47
+
48
+ # 遍历环境变量,标准化后匹配
49
+ for env_key, env_val in os.environ.items():
50
+ env_key_normalized = _normalize_env_key(env_key)
51
+ if env_key_normalized == target_key_normalized:
52
+ return env_val
53
+ return default
54
+ else:
55
+ # 不忽略大小写时,仅自动兼容中划线/下划线
56
+ target_key_1 = key # 原始key
57
+ target_key_2 = key.replace(
58
+ '-', '_') if '-' in key else key.replace('_', '-') # 替换格式的key
59
+ val = os.getenv(target_key_1)
60
+ if val is not None:
61
+ return val
62
+ return os.getenv(target_key_2, default)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sycommon-python-lib
3
- Version: 0.1.56b10
3
+ Version: 0.1.56b12
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -24,7 +24,7 @@ sycommon/llm/llm_logger.py,sha256=n4UeNy_-g4oHQOsw-VUzF4uo3JVRLtxaMp1FcI8FiEo,54
24
24
  sycommon/llm/llm_tokens.py,sha256=-udDyFcmyzx6UAwIi6_d_wwI5kMd5w0-WcS2soVPQxg,4309
25
25
  sycommon/logging/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
26
  sycommon/logging/async_sql_logger.py,sha256=_OY36XkUm__U3NhMgiecy-qd-nptZ_0gpE3J8lGAr58,2619
27
- sycommon/logging/kafka_log.py,sha256=1pUZ0N4FPRsTpg8PEY27iIa3xAMiLKYLBM3PDV804Lo,9934
27
+ sycommon/logging/kafka_log.py,sha256=gfOqdZe0HJ3PkIFfnNWG4DZVadxsCKJ6AmelR7_Z1Xs,9960
28
28
  sycommon/logging/logger_levels.py,sha256=_-uQ_T1N8NkNgcAmLrMmJ83nHTDw5ZNvXFPvdk89XGY,1144
29
29
  sycommon/logging/logger_wrapper.py,sha256=TiHsrIIHiQMzXgXK12-0KIpU9GhwQJOoHslakzmq2zc,357
30
30
  sycommon/logging/sql_logger.py,sha256=aEU3OGnI_51Tjyuuf4FpUi9KPTceFRuKAOyQbPzGhzM,2021
@@ -47,14 +47,14 @@ sycommon/models/mqsend_config.py,sha256=NQX9dc8PpuquMG36GCVhJe8omAW1KVXXqr6lSRU6
47
47
  sycommon/models/sso_user.py,sha256=i1WAN6k5sPcPApQEdtjpWDy7VrzWLpOrOQewGLGoGIw,2702
48
48
  sycommon/notice/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
49
  sycommon/notice/uvicorn_monitor.py,sha256=VryQYcAtjijJuGDBimbVurgwxlsLaLtkNnABPDY5Tao,7332
50
- sycommon/rabbitmq/rabbitmq_client.py,sha256=jClUm9Ao9vZ2IZg7IXIEaDbYYnV8qtmtm77vdmwpKE4,22599
51
- sycommon/rabbitmq/rabbitmq_pool.py,sha256=5ruFVViSCKA7ToZmR2dZIkP0zT0ZcfsnkSGbrdkg0Tk,16141
50
+ sycommon/rabbitmq/rabbitmq_client.py,sha256=JZ73fc0Z8iMnayvRhRsnkEkBfzKF3wbxDKTE98RwVIA,17809
51
+ sycommon/rabbitmq/rabbitmq_pool.py,sha256=BiFQgZPzSAFR-n5XhyIafoeWQXETF_31nFRDhMbe6aU,15577
52
52
  sycommon/rabbitmq/rabbitmq_service.py,sha256=XSHo9HuIJ_lq-vizRh4xJVdZr_2zLqeLhot09qb0euA,2025
53
- sycommon/rabbitmq/rabbitmq_service_client_manager.py,sha256=VL6hGaU5VXldLn5bmn3N6Lu3tBDD0zYB6aWurKJpAFM,8270
53
+ sycommon/rabbitmq/rabbitmq_service_client_manager.py,sha256=MM4r8Pa2rjAmzy_NpHFb4thGznr6AYk6m__IC8IIxEM,7852
54
54
  sycommon/rabbitmq/rabbitmq_service_connection_monitor.py,sha256=uvoMuJDzJ9i63uVRq1NKFV10CvkbGnTMyEoq2rgjQx8,3013
55
- sycommon/rabbitmq/rabbitmq_service_consumer_manager.py,sha256=qvq6dB30DkJrpk2OQ7PsWPXbp-7ILiMNt0sjZbfOzUs,11449
56
- sycommon/rabbitmq/rabbitmq_service_core.py,sha256=_9gqc7BOhrzfeYS557yIOfyCAraAKh-3ClMpKHn9ufY,4753
57
- sycommon/rabbitmq/rabbitmq_service_producer_manager.py,sha256=FKljvWhxuVq3QwBf-Ny7n5JvO3zyJ2B4K1SGb6fG2e0,9960
55
+ sycommon/rabbitmq/rabbitmq_service_consumer_manager.py,sha256=489r1RKd5WrTNMAcWCxUZpt9yWGrNunZlLCCp-M_rzM,11497
56
+ sycommon/rabbitmq/rabbitmq_service_core.py,sha256=6RMvIf78DmEOZmN8dA0duA9oy4ieNswdGrOeyJdD6tU,4753
57
+ sycommon/rabbitmq/rabbitmq_service_producer_manager.py,sha256=TJrLbvsjF55P9lwr7aCm9uRIRuC3z4EZNx74KEVKBtU,10190
58
58
  sycommon/sentry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
59
  sycommon/sentry/sy_sentry.py,sha256=e5Fbt9Gi2gIb048z0nuKbuhp3uCAEqYH2xXbF6qrZq4,1471
60
60
  sycommon/sse/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -66,19 +66,20 @@ sycommon/synacos/example2.py,sha256=adUaru3Hy482KrOA17DfaC4nwvLj8etIDS_KrWLWmCU,
66
66
  sycommon/synacos/feign.py,sha256=frB3D5LeFDtT3pJLFOwFzEOrNAJKeQNGk-BzUg9T3WM,8295
67
67
  sycommon/synacos/feign_client.py,sha256=ExO7Pd5B3eFKDjXqBRc260K1jkI49IYguLwJJaD2R-o,16166
68
68
  sycommon/synacos/nacos_client_base.py,sha256=l5jpall6nEt0Hy07Wk-PVU0VN0BmD_Mmtldmtyvvksg,4526
69
- sycommon/synacos/nacos_config_manager.py,sha256=IzSOSocJJrLnvVUKOXE2bq0ZDm9Na9esZLomZzOFtGo,4319
70
- sycommon/synacos/nacos_heartbeat_manager.py,sha256=_87KaKRA7kkq39rOc4ViYd20H-Y7iu4jMrq_n-ul8wg,5381
71
- sycommon/synacos/nacos_service.py,sha256=EPDNBAPwPP4EPIEIjuvD9_CmLRNNmhd_heCpxJD6wbM,6068
72
- sycommon/synacos/nacos_service_discovery.py,sha256=wTkUgauO8aFHKotnm6mFHlY2_yXHfltlPlBzg2XBOGE,5837
73
- sycommon/synacos/nacos_service_registration.py,sha256=TwhBZsQszkaSDo_zVQmQxkFlC6K3YHBK8hXpChZ9if8,9872
69
+ sycommon/synacos/nacos_config_manager.py,sha256=Cff-4gpp0aD7sQVi-nEvDO4BWqK9abEDDDJ9qXKFQgs,4399
70
+ sycommon/synacos/nacos_heartbeat_manager.py,sha256=G80_pOn37WdO_HpYUiAfpwMqAxW0ff0Bnw0NEuge9v0,5568
71
+ sycommon/synacos/nacos_service.py,sha256=BezQ1eDIYwBPE567Po_Qh1Ki_z9WmhZy1J1NiTPbdHY,6118
72
+ sycommon/synacos/nacos_service_discovery.py,sha256=vE72BCLBv4fQ1H9CQJ8efC6R2SPMQlAWPPTb8Ae7i2g,6024
73
+ sycommon/synacos/nacos_service_registration.py,sha256=plg2PmH8CWgmVnPtiIXBxtj-3BpyMdSzKr1wyWRdzh4,10968
74
74
  sycommon/synacos/param.py,sha256=KcfSkxnXOa0TGmCjY8hdzU9pzUsA8-4PeyBKWI2-568,1765
75
75
  sycommon/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
76
  sycommon/tools/docs.py,sha256=OPj2ETheuWjXLyaXtaZPbwmJKfJaYXV5s4XMVAUNrms,1607
77
+ sycommon/tools/env.py,sha256=Ah-tBwG2C0_hwLGFebVQgKdWWXCjTzBuF23gCkLHYy4,2437
77
78
  sycommon/tools/merge_headers.py,sha256=HV_i52Q-9se3SP8qh7ZGYl8bP7Fxtal4CGVkyMwEdM8,4373
78
79
  sycommon/tools/snowflake.py,sha256=lVEe5mNCOgz5OqGQpf5_nXaGnRJlI2STX2s-ppTtanA,11947
79
80
  sycommon/tools/timing.py,sha256=OiiE7P07lRoMzX9kzb8sZU9cDb0zNnqIlY5pWqHcnkY,2064
80
- sycommon_python_lib-0.1.56b10.dist-info/METADATA,sha256=vyV4lLpTKgbiPgOIBOgZFnACgzvrJk5s2Ghja70yztY,7270
81
- sycommon_python_lib-0.1.56b10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
82
- sycommon_python_lib-0.1.56b10.dist-info/entry_points.txt,sha256=q_h2nbvhhmdnsOUZEIwpuoDjaNfBF9XqppDEmQn9d_A,46
83
- sycommon_python_lib-0.1.56b10.dist-info/top_level.txt,sha256=98CJ-cyM2WIKxLz-Pf0AitWLhJyrfXvyY8slwjTXNuc,17
84
- sycommon_python_lib-0.1.56b10.dist-info/RECORD,,
81
+ sycommon_python_lib-0.1.56b12.dist-info/METADATA,sha256=dkuadRkMxJOl31ynqjcEezKtvoQ7On9qeGyGSnxCUZ0,7270
82
+ sycommon_python_lib-0.1.56b12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
83
+ sycommon_python_lib-0.1.56b12.dist-info/entry_points.txt,sha256=q_h2nbvhhmdnsOUZEIwpuoDjaNfBF9XqppDEmQn9d_A,46
84
+ sycommon_python_lib-0.1.56b12.dist-info/top_level.txt,sha256=98CJ-cyM2WIKxLz-Pf0AitWLhJyrfXvyY8slwjTXNuc,17
85
+ sycommon_python_lib-0.1.56b12.dist-info/RECORD,,