pyloid 0.26.3__py3-none-any.whl → 0.26.5__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.
pyloid/tray.py CHANGED
@@ -1,48 +1,64 @@
1
- from enum import Enum
2
- from PySide6.QtWidgets import QSystemTrayIcon
1
+ from enum import (
2
+ Enum,
3
+ )
4
+ from PySide6.QtWidgets import (
5
+ QSystemTrayIcon,
6
+ )
3
7
 
4
8
 
5
9
  class TrayEvent(Enum):
6
- """
7
- TrayEvent is an enumeration class representing events related to the system tray icon.
8
-
9
- Enumeration Members
10
- -------------------
11
- DoubleClick : Event that occurs when the tray icon is double-clicked
12
- MiddleClick : Event that occurs when the tray icon is clicked with the middle button
13
- RightClick : Event that occurs when the tray icon is right-clicked (context menu)
14
- LeftClick : Event that occurs when the tray icon is left-clicked
15
- Unknown : Unknown event
16
-
17
- Usage Example
18
- -------------
19
- ```python
20
- from pyloid import Pyloid, TrayEvent
21
-
22
- app = Pyloid(app_name="Pyloid-App")
23
-
24
- app.set_tray_icon("icons/icon.ico")
25
-
26
- app.set_tray_actions(
27
- {
28
- TrayEvent.DoubleClick: lambda: print("Tray icon was double-clicked."),
29
- TrayEvent.MiddleClick: lambda: print("Tray icon was middle-clicked."),
30
- TrayEvent.RightClick: lambda: print("Tray icon was right-clicked."),
31
- TrayEvent.LeftClick: lambda: print("Tray icon was left-clicked."),
32
- }
33
- )
34
- ```
35
- """
36
- DoubleClick = QSystemTrayIcon.ActivationReason.DoubleClick
37
- MiddleClick = QSystemTrayIcon.ActivationReason.MiddleClick
38
- RightClick = QSystemTrayIcon.ActivationReason.Context
39
- LeftClick = QSystemTrayIcon.ActivationReason.Trigger
40
- Unknown = QSystemTrayIcon.ActivationReason.Unknown
41
-
42
- def __eq__(self, other):
43
- if isinstance(other, QSystemTrayIcon.ActivationReason):
44
- return self.value == other
45
- return super().__eq__(other)
46
-
47
- def __hash__(self):
48
- return hash(self.value)
10
+ """
11
+ TrayEvent is an enumeration class representing events related to the system tray icon.
12
+
13
+ Enumeration Members
14
+ -------------------
15
+ DoubleClick : Event that occurs when the tray icon is double-clicked
16
+ MiddleClick : Event that occurs when the tray icon is clicked with the middle button
17
+ RightClick : Event that occurs when the tray icon is right-clicked (context menu)
18
+ LeftClick : Event that occurs when the tray icon is left-clicked
19
+ Unknown : Unknown event
20
+
21
+ Usage Example
22
+ -------------
23
+ ```python
24
+ from pyloid import (
25
+ Pyloid,
26
+ TrayEvent,
27
+ )
28
+
29
+ app = Pyloid(app_name='Pyloid-App')
30
+
31
+ app.set_tray_icon('icons/icon.ico')
32
+
33
+ app.set_tray_actions(
34
+ {
35
+ TrayEvent.DoubleClick: lambda: print('Tray icon was double-clicked.'),
36
+ TrayEvent.MiddleClick: lambda: print('Tray icon was middle-clicked.'),
37
+ TrayEvent.RightClick: lambda: print('Tray icon was right-clicked.'),
38
+ TrayEvent.LeftClick: lambda: print('Tray icon was left-clicked.'),
39
+ }
40
+ )
41
+ ```
42
+ """
43
+
44
+ DoubleClick = QSystemTrayIcon.ActivationReason.DoubleClick
45
+ MiddleClick = QSystemTrayIcon.ActivationReason.MiddleClick
46
+ RightClick = QSystemTrayIcon.ActivationReason.Context
47
+ LeftClick = QSystemTrayIcon.ActivationReason.Trigger
48
+ Unknown = QSystemTrayIcon.ActivationReason.Unknown
49
+
50
+ def __eq__(
51
+ self,
52
+ other,
53
+ ):
54
+ if isinstance(
55
+ other,
56
+ QSystemTrayIcon.ActivationReason,
57
+ ):
58
+ return self.value == other
59
+ return super().__eq__(other)
60
+
61
+ def __hash__(
62
+ self,
63
+ ):
64
+ return hash(self.value)
pyloid/url_interceptor.py CHANGED
@@ -1,25 +1,42 @@
1
- from PySide6.QtWebEngineCore import QWebEngineUrlRequestInterceptor, QWebEngineUrlRequestInfo
1
+ from PySide6.QtWebEngineCore import (
2
+ QWebEngineUrlRequestInterceptor,
3
+ QWebEngineUrlRequestInfo,
4
+ )
5
+
2
6
 
3
7
  # interceptor ( all url request )
4
8
  class ServerUrlInterceptor(QWebEngineUrlRequestInterceptor):
5
- def __init__(self, server_url: str, window_id: str):
6
- super().__init__()
7
- self.server_url = server_url
8
- self.headers = {
9
- "X-Pyloid-Window-Id": window_id,
10
- }
11
-
12
- print("interceptor init")
9
+ def __init__(
10
+ self,
11
+ server_url: str,
12
+ window_id: str,
13
+ ):
14
+ super().__init__()
15
+ self.server_url = server_url
16
+ self.headers = {
17
+ 'X-Pyloid-Window-Id': window_id,
18
+ }
19
+
20
+ print('interceptor init')
21
+
22
+ def interceptRequest(
23
+ self,
24
+ info,
25
+ ):
26
+ # host = info.requestUrl().host()
27
+ url = info.requestUrl().toString()
13
28
 
14
- def interceptRequest(self, info):
15
- # host = info.requestUrl().host()
16
- url = info.requestUrl().toString()
17
-
18
- print(url)
29
+ print(url)
19
30
 
20
- if url.startswith(self.server_url):
21
- headers = info.httpHeaders()
22
- print("before", headers)
23
- headers.update(self.headers)
24
- print("after", headers)
25
- return
31
+ if url.startswith(self.server_url):
32
+ headers = info.httpHeaders()
33
+ print(
34
+ 'before',
35
+ headers,
36
+ )
37
+ headers.update(self.headers)
38
+ print(
39
+ 'after',
40
+ headers,
41
+ )
42
+ return
pyloid/utils.py CHANGED
@@ -1,208 +1,258 @@
1
1
  import sys
2
2
  import os
3
3
  import platform
4
- from typing import Optional
4
+ from typing import (
5
+ Optional,
6
+ )
5
7
  import socket
6
8
 
7
9
 
8
- def get_production_path(path: Optional[str] = None) -> Optional[str]:
9
- """
10
- Constructs the absolute path to a resource file, adjusting based on the execution environment.
11
-
12
- In a production environment (e.g., when packaged with PyInstaller or Nuitka),
13
- it prepends the application's base directory (sys._MEIPASS for PyInstaller,
14
- or the directory of the executable for Nuitka) to the provided relative path.
15
- If no path is provided, it returns the base path itself.
16
-
17
- If not running in a production environment (e.g., during development as a regular
18
- Python script), it simply returns the provided path as is. If no path is provided,
19
- it returns None in a non-production environment.
20
-
21
- Parameters
22
- ----------
23
- path : Optional[str], optional
24
- The relative path to the resource file from the application's root directory.
25
- Defaults to None.
26
-
27
- Returns
28
- -------
29
- Optional[str]
30
- - If in production: The absolute path to the resource file (or the base path if `path` is None).
31
- - If not in production: The original `path` value passed to the function.
32
-
33
- Examples
34
- --------
35
- >>> # Assume running NOT in production
36
- >>> get_production_path("assets/icon.ico")
37
- 'assets/icon.ico'
38
- >>> get_production_path()
39
- None
40
-
41
- >>> # Assume running IN production (e.g., PyInstaller bundle)
42
- >>> # where sys._MEIPASS might be '/tmp/_MEIabcde'
43
- >>> get_production_path("assets/icon.ico") # doctest: +SKIP
44
- '/tmp/_MEIabcde/assets/icon.ico'
45
- >>> get_production_path() # doctest: +SKIP
46
- '/tmp/_MEIabcde'
47
- """
48
- if is_production():
49
- if hasattr(sys, "_MEIPASS"):
50
- # PyInstaller
51
- base_path = sys._MEIPASS
52
- else:
53
- # Nuitka
54
- base_path = os.path.dirname(sys.executable)
55
-
56
- if base_path is None:
57
- # 환경변수가 없는 경우 실행 파일 디렉토리 사용
58
- base_path = os.path.dirname(os.path.abspath(sys.argv[0]))
59
-
60
- return os.path.join(base_path, path) if path else base_path
61
- else:
62
- return path
10
+ def get_production_path(
11
+ path: Optional[str] = None,
12
+ ) -> Optional[str]:
13
+ """
14
+ Constructs the absolute path to a resource file, adjusting based on the execution environment.
15
+
16
+ In a production environment (e.g., when packaged with PyInstaller or Nuitka),
17
+ it prepends the application's base directory (sys._MEIPASS for PyInstaller,
18
+ or the directory of the executable for Nuitka) to the provided relative path.
19
+ If no path is provided, it returns the base path itself.
20
+
21
+ If not running in a production environment (e.g., during development as a regular
22
+ Python script), it simply returns the provided path as is. If no path is provided,
23
+ it returns None in a non-production environment.
24
+
25
+ Parameters
26
+ ----------
27
+ path : Optional[str], optional
28
+ The relative path to the resource file from the application's root directory.
29
+ Defaults to None.
30
+
31
+ Returns
32
+ -------
33
+ Optional[str]
34
+ - If in production: The absolute path to the resource file (or the base path if `path` is None).
35
+ - If not in production: The original `path` value passed to the function.
36
+
37
+ Examples
38
+ --------
39
+ >>> # Assume running NOT in production
40
+ >>> get_production_path('assets/icon.ico')
41
+ 'assets/icon.ico'
42
+ >>> get_production_path()
43
+ None
44
+
45
+ >>> # Assume running IN production (e.g., PyInstaller bundle)
46
+ >>> # where sys._MEIPASS might be '/tmp/_MEIabcde'
47
+ >>> get_production_path('assets/icon.ico') # doctest: +SKIP
48
+ '/tmp/_MEIabcde/assets/icon.ico'
49
+ >>> get_production_path() # doctest: +SKIP
50
+ '/tmp/_MEIabcde'
51
+ """
52
+ if is_production():
53
+ if hasattr(
54
+ sys,
55
+ '_MEIPASS',
56
+ ):
57
+ # PyInstaller
58
+ base_path = sys._MEIPASS
59
+ else:
60
+ # Nuitka
61
+ base_path = os.path.dirname(sys.executable)
62
+
63
+ if base_path is None:
64
+ # 환경변수가 없는 경우 실행 파일 디렉토리 사용
65
+ base_path = os.path.dirname(os.path.abspath(sys.argv[0]))
66
+
67
+ return (
68
+ os.path.join(
69
+ base_path,
70
+ path,
71
+ )
72
+ if path
73
+ else base_path
74
+ )
75
+ else:
76
+ return path
63
77
 
64
78
 
65
79
  def is_production() -> bool:
66
- """
67
- Checks if the current environment is a production environment.
68
-
69
- Returns
70
- -------
71
- bool
72
- True if in a production environment, False otherwise.
73
-
74
- Examples
75
- --------
76
- >>> from pyloid.utils import is_production
77
- >>> if is_production():
78
- >>> print("Running in production environment.")
79
- >>> else:
80
- >>> print("Not in production environment.")
81
- """
82
- # Nuitka 환경 확인을 추가
83
- if "__compiled__" in globals():
84
- return True
85
- # PyInstaller 환경 확인
86
- return getattr(sys, "frozen", False)
80
+ """
81
+ Checks if the current environment is a production environment.
82
+
83
+ Returns
84
+ -------
85
+ bool
86
+ True if in a production environment, False otherwise.
87
+
88
+ Examples
89
+ --------
90
+ >>> from pyloid.utils import (
91
+ ... is_production,
92
+ ... )
93
+ >>> if is_production():
94
+ >>> print("Running in production environment.")
95
+ >>> else:
96
+ >>> print("Not in production environment.")
97
+ """
98
+ # Nuitka 환경 확인을 추가
99
+ if '__compiled__' in globals():
100
+ return True
101
+ # PyInstaller 환경 확인
102
+ return getattr(
103
+ sys,
104
+ 'frozen',
105
+ False,
106
+ )
87
107
 
88
108
 
89
109
  def get_platform() -> str:
90
- """
91
- Returns the name of the current system's platform.
92
-
93
- This function uses `platform.system()` to return the name of the current operating system.
94
-
95
- Returns
96
- -------
97
- "windows" | "macos" | "linux"
98
- - "windows" for Windows systems
99
- - "macos" for macOS systems
100
- - "linux" for Linux systems
101
-
102
- Examples
103
- --------
104
- >>> from pyloid.utils import get_platform
105
- >>> platform_name = get_platform()
106
- >>> print(platform_name)
107
- windows
108
- """
109
- os_name = platform.system().lower()
110
- os_type = {"darwin": "macos", "linux": "linux", "windows": "windows"}.get(os_name)
111
- if os_type is None:
112
- raise ValueError(f"Unsupported platform: {os_name}")
113
-
114
- return os_type
115
-
116
-
117
- def get_absolute_path(path: str) -> str:
118
- """
119
- Returns the absolute path of the given relative path.
120
-
121
- Parameters
122
- ----------
123
- path : str
124
- The relative path to get the absolute path of.
125
-
126
- Returns
127
- -------
128
- str
129
- The absolute path of the given relative path.
130
-
131
- Examples
132
- --------
133
- >>> from pyloid.utils import get_absolute_path
134
- >>> absolute_path = get_absolute_path("assets/icon.ico")
135
- >>> print(absolute_path)
136
- C:/Users/aaaap/Documents/pyloid/pyloid/assets/icon.ico
137
- """
138
- return os.path.normpath(os.path.abspath(path))
110
+ """
111
+ Returns the name of the current system's platform.
112
+
113
+ This function uses `platform.system()` to return the name of the current operating system.
114
+
115
+ Returns
116
+ -------
117
+ "windows" | "macos" | "linux"
118
+ - "windows" for Windows systems
119
+ - "macos" for macOS systems
120
+ - "linux" for Linux systems
121
+
122
+ Examples
123
+ --------
124
+ >>> from pyloid.utils import (
125
+ ... get_platform,
126
+ ... )
127
+ >>> platform_name = get_platform()
128
+ >>> print(platform_name)
129
+ windows
130
+ """
131
+ os_name = platform.system().lower()
132
+ os_type = {
133
+ 'darwin': 'macos',
134
+ 'linux': 'linux',
135
+ 'windows': 'windows',
136
+ }.get(os_name)
137
+ if os_type is None:
138
+ raise ValueError(f'Unsupported platform: {os_name}')
139
+
140
+ return os_type
141
+
142
+
143
+ def get_absolute_path(
144
+ path: str,
145
+ ) -> str:
146
+ """
147
+ Returns the absolute path of the given relative path.
148
+
149
+ Parameters
150
+ ----------
151
+ path : str
152
+ The relative path to get the absolute path of.
153
+
154
+ Returns
155
+ -------
156
+ str
157
+ The absolute path of the given relative path.
158
+
159
+ Examples
160
+ --------
161
+ >>> from pyloid.utils import (
162
+ ... get_absolute_path,
163
+ ... )
164
+ >>> absolute_path = get_absolute_path('assets/icon.ico')
165
+ >>> print(absolute_path)
166
+ C:/Users/aaaap/Documents/pyloid/pyloid/assets/icon.ico
167
+ """
168
+ return os.path.normpath(os.path.abspath(path))
139
169
 
140
170
 
141
171
  def get_free_port() -> int:
142
- """
143
- Finds and returns an available random network port number from the operating system.
144
-
145
- This function creates a socket and binds it to port '0', allowing the operating system
146
- to allocate a random available port. It retrieves the port number and safely closes
147
- the socket afterward.
148
-
149
- Returns
150
- -------
151
- int
152
- An available network port number (typically in the range 1024-65535)
153
-
154
- Notes
155
- -----
156
- - Since this function closes the socket immediately after finding a port, there is a
157
- possibility that the port could be reassigned to another process.
158
- - It is recommended to use the port number quickly after receiving it.
159
- - This function interacts with the operating system's network stack, so its behavior
160
- may vary depending on firewall or network settings.
161
-
162
- Examples
163
- --------
164
- >>> from pyloid.utils import get_free_port
165
- >>> port = get_free_port()
166
- >>> print(f"Found available port: {port}")
167
- Found available port: 49152
168
-
169
- >>> # Web server example
170
- >>> import http.server
171
- >>> server = http.server.HTTPServer(('localhost', port), http.server.SimpleHTTPRequestHandler)
172
- """
173
- with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
174
- s.bind(("", 0))
175
- return s.getsockname()[1]
176
-
177
-
178
- def set_qt_backend(backend="software"):
179
- """
180
- Sets the Qt Quick backend to force a specific rendering mode.
181
-
182
- This function allows changing the Qt Quick rendering backend by setting
183
- the QT_QUICK_BACKEND environment variable. Setting it to 'software'
184
- forces software rendering, which can be useful in environments with
185
- graphics driver issues or where hardware acceleration is not available.
186
-
187
- Parameters
188
- ----------
189
- backend : str, optional
190
- The backend to use for Qt Quick rendering. Default is 'software'.
191
-
192
- Returns
193
- -------
194
- None
195
-
196
- Notes
197
- -----
198
- - This setting must be applied before the Qt application is initialized
199
- - Software rendering may be slower but more compatible across systems
200
-
201
- Examples
202
- --------
203
- >>> from pyloid.utils import set_qt_backend
204
- >>> # Force software rendering
205
- >>> set_qt_backend("software")
206
- """
207
- print(f"Setting QT_QUICK_BACKEND to {backend}.")
208
- os.environ["QT_QUICK_BACKEND"] = backend
172
+ """
173
+ Finds and returns an available random network port number from the operating system.
174
+
175
+ This function creates a socket and binds it to port '0', allowing the operating system
176
+ to allocate a random available port. It retrieves the port number and safely closes
177
+ the socket afterward.
178
+
179
+ Returns
180
+ -------
181
+ int
182
+ An available network port number (typically in the range 1024-65535)
183
+
184
+ Notes
185
+ -----
186
+ - Since this function closes the socket immediately after finding a port, there is a
187
+ possibility that the port could be reassigned to another process.
188
+ - It is recommended to use the port number quickly after receiving it.
189
+ - This function interacts with the operating system's network stack, so its behavior
190
+ may vary depending on firewall or network settings.
191
+
192
+ Examples
193
+ --------
194
+ >>> from pyloid.utils import (
195
+ ... get_free_port,
196
+ ... )
197
+ >>> port = get_free_port()
198
+ >>> print(f'Found available port: {port}')
199
+ Found available port: 49152
200
+
201
+ >>> # Web server example
202
+ >>> import http.server
203
+ >>> server = http.server.HTTPServer(
204
+ ... (
205
+ ... 'localhost',
206
+ ... port,
207
+ ... ),
208
+ ... http.server.SimpleHTTPRequestHandler,
209
+ ... )
210
+ """
211
+ with socket.socket(
212
+ socket.AF_INET,
213
+ socket.SOCK_STREAM,
214
+ ) as s:
215
+ s.bind(
216
+ (
217
+ '',
218
+ 0,
219
+ )
220
+ )
221
+ return s.getsockname()[1]
222
+
223
+
224
+ def set_qt_backend(
225
+ backend='software',
226
+ ):
227
+ """
228
+ Sets the Qt Quick backend to force a specific rendering mode.
229
+
230
+ This function allows changing the Qt Quick rendering backend by setting
231
+ the QT_QUICK_BACKEND environment variable. Setting it to 'software'
232
+ forces software rendering, which can be useful in environments with
233
+ graphics driver issues or where hardware acceleration is not available.
234
+
235
+ Parameters
236
+ ----------
237
+ backend : str, optional
238
+ The backend to use for Qt Quick rendering. Default is 'software'.
239
+
240
+ Returns
241
+ -------
242
+ None
243
+
244
+ Notes
245
+ -----
246
+ - This setting must be applied before the Qt application is initialized
247
+ - Software rendering may be slower but more compatible across systems
248
+
249
+ Examples
250
+ --------
251
+ >>> from pyloid.utils import (
252
+ ... set_qt_backend,
253
+ ... )
254
+ >>> # Force software rendering
255
+ >>> set_qt_backend('software')
256
+ """
257
+ print(f'Setting QT_QUICK_BACKEND to {backend}.')
258
+ os.environ['QT_QUICK_BACKEND'] = backend
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pyloid
3
- Version: 0.26.3
3
+ Version: 0.26.5
4
4
  Summary:
5
5
  Author: aesthetics-of-record
6
6
  Author-email: 111675679+aesthetics-of-record@users.noreply.github.com
@@ -0,0 +1,23 @@
1
+ pyloid/__init__.py,sha256=qBmAo_EOAW4N-XYqv9fK3GD2VQhMkRCO-Yaar0dGqAE,60
2
+ pyloid/autostart.py,sha256=4q3YiYt2SKJiJV16FalISYVjg9X7b0l7eAmSWOhfXo0,3679
3
+ pyloid/base_ipc/base.py,sha256=eo0mkAOCl2h9NDD1sQNYauS15iyEGNpXY5oO5n4nNPo,8052
4
+ pyloid/base_ipc/event_api.py,sha256=JY8YfyTns4jMwZ43ob9KuGedMBSVML8FuQJHk_bDhFE,959
5
+ pyloid/base_ipc/window_api.py,sha256=-isphU3m2wGB5U0yZrSuK_4XiBz2mG45HsjYTUq7Fxs,7348
6
+ pyloid/browser_window.py,sha256=M2dKhVz0BLh_4rQI0tGLAmbgfDJ63yKjgDhwn4DNCbo,91674
7
+ pyloid/custom/titlebar.py,sha256=wkh3h6ZBOYJczTrOosgiTKiSL-ZU92RWQv4FjpnH9u8,3728
8
+ pyloid/filewatcher.py,sha256=Rdu76qpwXpFNQuapZZBajRN_0svcPZa2s-06IBH4dkk,4062
9
+ pyloid/ipc.py,sha256=W58SIYN8rfx4ZwdryMCfb-UMy8VkmpFBF-a0wIGhYsA,2256
10
+ pyloid/monitor.py,sha256=cCBQgX0OJg7Gt3WeNfb-koTNR17ZToN2Lq35o_2F350,23970
11
+ pyloid/pyloid.py,sha256=5WfbuiW8JYi1B2AadoScyI5rrc_fq2GEoVdn1VEQhHM,74638
12
+ pyloid/rpc.py,sha256=40KsbCnYotLm5M7S2Uo41ELV4N7ugz9tBtdfIfFIIG0,18964
13
+ pyloid/serve.py,sha256=w17OteQOGW5-Q2SOdkyv0R1tb-67wxbGjTzvFbSvwB4,6674
14
+ pyloid/store.py,sha256=hjv8c7h6EQUzbBY7g2tXX9sRGFnfKU0pQWG5UtGcfWA,4611
15
+ pyloid/thread_pool.py,sha256=6ohTRbQqIuLL6OVGo70qvAPZnq-V-bSVuawLFN0yMiY,12591
16
+ pyloid/timer.py,sha256=YNxQn2HVMKBk417YDiz8WwhTmSAkbnGUyFGV2biUEPg,7821
17
+ pyloid/tray.py,sha256=yHWsOMPpEjZa3W-T-O8Wrwo1GphCV-9adodLdxU0_mA,1673
18
+ pyloid/url_interceptor.py,sha256=lA-i5Raw-GDRDMKHRO361N6igLfN9_mIANCXwZ_FZT8,771
19
+ pyloid/utils.py,sha256=x7PGkgreV3l4K-Tke9W06t_VEtq0mH0AYWK695IR-mo,6416
20
+ pyloid-0.26.5.dist-info/LICENSE,sha256=F96EzotgWhhpnQTW2TcdoqrMDir1jyEo6H915tGQ-QE,11524
21
+ pyloid-0.26.5.dist-info/METADATA,sha256=vRjpHU_PHJpGOV4mHTHFet15IXYVcubHQXMNKu3yheU,2298
22
+ pyloid-0.26.5.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
23
+ pyloid-0.26.5.dist-info/RECORD,,