provide-foundation 0.0.0.dev1__py3-none-any.whl → 0.0.0.dev3__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.
Files changed (163) hide show
  1. provide/foundation/__init__.py +36 -10
  2. provide/foundation/archive/__init__.py +1 -1
  3. provide/foundation/archive/base.py +15 -14
  4. provide/foundation/archive/bzip2.py +40 -40
  5. provide/foundation/archive/gzip.py +42 -42
  6. provide/foundation/archive/operations.py +93 -96
  7. provide/foundation/archive/tar.py +33 -31
  8. provide/foundation/archive/zip.py +52 -50
  9. provide/foundation/asynctools/__init__.py +20 -0
  10. provide/foundation/asynctools/core.py +126 -0
  11. provide/foundation/cli/__init__.py +2 -2
  12. provide/foundation/cli/commands/deps.py +15 -9
  13. provide/foundation/cli/commands/logs/__init__.py +3 -3
  14. provide/foundation/cli/commands/logs/generate.py +2 -2
  15. provide/foundation/cli/commands/logs/query.py +4 -4
  16. provide/foundation/cli/commands/logs/send.py +3 -3
  17. provide/foundation/cli/commands/logs/tail.py +3 -3
  18. provide/foundation/cli/decorators.py +11 -11
  19. provide/foundation/cli/main.py +1 -1
  20. provide/foundation/cli/testing.py +2 -40
  21. provide/foundation/cli/utils.py +21 -18
  22. provide/foundation/config/__init__.py +35 -2
  23. provide/foundation/config/base.py +2 -2
  24. provide/foundation/config/converters.py +477 -0
  25. provide/foundation/config/defaults.py +67 -0
  26. provide/foundation/config/env.py +6 -20
  27. provide/foundation/config/loader.py +10 -4
  28. provide/foundation/config/sync.py +8 -6
  29. provide/foundation/config/types.py +5 -5
  30. provide/foundation/config/validators.py +4 -4
  31. provide/foundation/console/input.py +5 -5
  32. provide/foundation/console/output.py +36 -14
  33. provide/foundation/context/__init__.py +8 -4
  34. provide/foundation/context/core.py +88 -110
  35. provide/foundation/crypto/certificates/__init__.py +9 -5
  36. provide/foundation/crypto/certificates/base.py +2 -2
  37. provide/foundation/crypto/certificates/certificate.py +48 -19
  38. provide/foundation/crypto/certificates/factory.py +26 -18
  39. provide/foundation/crypto/certificates/generator.py +24 -23
  40. provide/foundation/crypto/certificates/loader.py +24 -16
  41. provide/foundation/crypto/certificates/operations.py +17 -10
  42. provide/foundation/crypto/certificates/trust.py +21 -21
  43. provide/foundation/env/__init__.py +28 -0
  44. provide/foundation/env/core.py +218 -0
  45. provide/foundation/errors/__init__.py +3 -3
  46. provide/foundation/errors/decorators.py +0 -234
  47. provide/foundation/errors/types.py +0 -98
  48. provide/foundation/eventsets/display.py +13 -14
  49. provide/foundation/eventsets/registry.py +61 -31
  50. provide/foundation/eventsets/resolver.py +50 -46
  51. provide/foundation/eventsets/sets/das.py +8 -8
  52. provide/foundation/eventsets/sets/database.py +14 -14
  53. provide/foundation/eventsets/sets/http.py +21 -21
  54. provide/foundation/eventsets/sets/llm.py +16 -16
  55. provide/foundation/eventsets/sets/task_queue.py +13 -13
  56. provide/foundation/eventsets/types.py +7 -7
  57. provide/foundation/file/directory.py +14 -23
  58. provide/foundation/file/lock.py +4 -3
  59. provide/foundation/hub/components.py +75 -389
  60. provide/foundation/hub/config.py +157 -0
  61. provide/foundation/hub/discovery.py +63 -0
  62. provide/foundation/hub/handlers.py +89 -0
  63. provide/foundation/hub/lifecycle.py +195 -0
  64. provide/foundation/hub/manager.py +7 -4
  65. provide/foundation/hub/processors.py +49 -0
  66. provide/foundation/integrations/__init__.py +11 -0
  67. provide/foundation/{observability → integrations}/openobserve/__init__.py +10 -7
  68. provide/foundation/{observability → integrations}/openobserve/auth.py +1 -1
  69. provide/foundation/{observability → integrations}/openobserve/client.py +14 -14
  70. provide/foundation/{observability → integrations}/openobserve/commands.py +12 -12
  71. provide/foundation/integrations/openobserve/config.py +37 -0
  72. provide/foundation/{observability → integrations}/openobserve/formatters.py +1 -1
  73. provide/foundation/{observability → integrations}/openobserve/otlp.py +2 -2
  74. provide/foundation/{observability → integrations}/openobserve/search.py +2 -3
  75. provide/foundation/{observability → integrations}/openobserve/streaming.py +5 -5
  76. provide/foundation/logger/__init__.py +0 -1
  77. provide/foundation/logger/config/base.py +1 -1
  78. provide/foundation/logger/config/logging.py +69 -299
  79. provide/foundation/logger/config/telemetry.py +39 -121
  80. provide/foundation/logger/factories.py +2 -2
  81. provide/foundation/logger/processors/main.py +12 -10
  82. provide/foundation/logger/ratelimit/limiters.py +4 -4
  83. provide/foundation/logger/ratelimit/processor.py +1 -1
  84. provide/foundation/logger/setup/coordinator.py +39 -25
  85. provide/foundation/logger/setup/processors.py +3 -3
  86. provide/foundation/logger/setup/testing.py +14 -0
  87. provide/foundation/logger/trace.py +5 -5
  88. provide/foundation/metrics/__init__.py +1 -1
  89. provide/foundation/metrics/otel.py +3 -1
  90. provide/foundation/observability/__init__.py +3 -3
  91. provide/foundation/process/__init__.py +9 -0
  92. provide/foundation/process/exit.py +48 -0
  93. provide/foundation/process/lifecycle.py +69 -46
  94. provide/foundation/resilience/__init__.py +36 -0
  95. provide/foundation/resilience/circuit.py +166 -0
  96. provide/foundation/resilience/decorators.py +236 -0
  97. provide/foundation/resilience/fallback.py +208 -0
  98. provide/foundation/resilience/retry.py +327 -0
  99. provide/foundation/serialization/__init__.py +16 -0
  100. provide/foundation/serialization/core.py +70 -0
  101. provide/foundation/streams/config.py +78 -0
  102. provide/foundation/streams/console.py +4 -5
  103. provide/foundation/streams/core.py +5 -2
  104. provide/foundation/streams/file.py +12 -2
  105. provide/foundation/testing/__init__.py +29 -9
  106. provide/foundation/testing/archive/__init__.py +7 -7
  107. provide/foundation/testing/archive/fixtures.py +58 -54
  108. provide/foundation/testing/cli.py +30 -20
  109. provide/foundation/testing/common/__init__.py +13 -15
  110. provide/foundation/testing/common/fixtures.py +27 -57
  111. provide/foundation/testing/file/__init__.py +15 -15
  112. provide/foundation/testing/file/content_fixtures.py +289 -0
  113. provide/foundation/testing/file/directory_fixtures.py +107 -0
  114. provide/foundation/testing/file/fixtures.py +42 -516
  115. provide/foundation/testing/file/special_fixtures.py +145 -0
  116. provide/foundation/testing/logger.py +89 -8
  117. provide/foundation/testing/mocking/__init__.py +21 -21
  118. provide/foundation/testing/mocking/fixtures.py +80 -67
  119. provide/foundation/testing/process/__init__.py +23 -23
  120. provide/foundation/testing/process/async_fixtures.py +414 -0
  121. provide/foundation/testing/process/fixtures.py +48 -571
  122. provide/foundation/testing/process/subprocess_fixtures.py +210 -0
  123. provide/foundation/testing/threading/__init__.py +17 -17
  124. provide/foundation/testing/threading/basic_fixtures.py +105 -0
  125. provide/foundation/testing/threading/data_fixtures.py +101 -0
  126. provide/foundation/testing/threading/execution_fixtures.py +278 -0
  127. provide/foundation/testing/threading/fixtures.py +32 -502
  128. provide/foundation/testing/threading/sync_fixtures.py +100 -0
  129. provide/foundation/testing/time/__init__.py +11 -11
  130. provide/foundation/testing/time/fixtures.py +95 -83
  131. provide/foundation/testing/transport/__init__.py +9 -9
  132. provide/foundation/testing/transport/fixtures.py +54 -54
  133. provide/foundation/time/__init__.py +18 -0
  134. provide/foundation/time/core.py +63 -0
  135. provide/foundation/tools/__init__.py +2 -2
  136. provide/foundation/tools/base.py +68 -67
  137. provide/foundation/tools/cache.py +69 -74
  138. provide/foundation/tools/downloader.py +68 -62
  139. provide/foundation/tools/installer.py +51 -57
  140. provide/foundation/tools/registry.py +38 -45
  141. provide/foundation/tools/resolver.py +70 -68
  142. provide/foundation/tools/verifier.py +39 -50
  143. provide/foundation/tracer/spans.py +2 -14
  144. provide/foundation/transport/__init__.py +26 -33
  145. provide/foundation/transport/base.py +32 -30
  146. provide/foundation/transport/client.py +44 -49
  147. provide/foundation/transport/config.py +36 -107
  148. provide/foundation/transport/errors.py +13 -27
  149. provide/foundation/transport/http.py +69 -55
  150. provide/foundation/transport/middleware.py +113 -114
  151. provide/foundation/transport/registry.py +29 -27
  152. provide/foundation/transport/types.py +6 -6
  153. provide/foundation/utils/deps.py +17 -14
  154. provide/foundation/utils/parsing.py +49 -4
  155. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/METADATA +2 -2
  156. provide_foundation-0.0.0.dev3.dist-info/RECORD +233 -0
  157. provide_foundation-0.0.0.dev1.dist-info/RECORD +0 -200
  158. /provide/foundation/{observability → integrations}/openobserve/exceptions.py +0 -0
  159. /provide/foundation/{observability → integrations}/openobserve/models.py +0 -0
  160. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/WHEEL +0 -0
  161. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/entry_points.txt +0 -0
  162. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/licenses/LICENSE +0 -0
  163. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,210 @@
1
+ """
2
+ Subprocess-specific test fixtures for process testing.
3
+
4
+ Provides fixtures for mocking and testing subprocess operations,
5
+ stream handling, and process communication.
6
+ """
7
+
8
+ from unittest.mock import AsyncMock, Mock
9
+
10
+ import pytest
11
+
12
+
13
+ @pytest.fixture
14
+ def mock_async_process() -> AsyncMock:
15
+ """
16
+ Mock async subprocess for testing.
17
+
18
+ Returns:
19
+ AsyncMock configured as a subprocess with common attributes.
20
+ """
21
+ mock_process = AsyncMock()
22
+ mock_process.communicate = AsyncMock(return_value=(b"output", b""))
23
+ mock_process.returncode = 0
24
+ mock_process.pid = 12345
25
+ mock_process.stdin = AsyncMock()
26
+ mock_process.stdout = AsyncMock()
27
+ mock_process.stderr = AsyncMock()
28
+ mock_process.wait = AsyncMock(return_value=0)
29
+ mock_process.kill = Mock()
30
+ mock_process.terminate = Mock()
31
+
32
+ return mock_process
33
+
34
+
35
+ @pytest.fixture
36
+ async def async_stream_reader() -> AsyncMock:
37
+ """
38
+ Mock async stream reader for subprocess stdout/stderr.
39
+
40
+ Returns:
41
+ AsyncMock configured as a stream reader.
42
+ """
43
+ reader = AsyncMock()
44
+
45
+ # Simulate reading lines
46
+ async def readline_side_effect():
47
+ for line in [b"line1\n", b"line2\n", b""]:
48
+ yield line
49
+
50
+ reader.readline = AsyncMock(side_effect=readline_side_effect().__anext__)
51
+ reader.read = AsyncMock(return_value=b"full content")
52
+ reader.at_eof = Mock(side_effect=[False, False, True])
53
+
54
+ return reader
55
+
56
+
57
+ @pytest.fixture
58
+ def async_subprocess():
59
+ """
60
+ Create mock async subprocess for testing.
61
+
62
+ Returns:
63
+ Function that creates mock subprocess with configurable behavior.
64
+ """
65
+
66
+ def _create_subprocess(
67
+ returncode: int = 0, stdout: bytes = b"", stderr: bytes = b"", pid: int = 12345
68
+ ) -> AsyncMock:
69
+ """
70
+ Create a mock async subprocess.
71
+
72
+ Args:
73
+ returncode: Process return code
74
+ stdout: Process stdout output
75
+ stderr: Process stderr output
76
+ pid: Process ID
77
+
78
+ Returns:
79
+ AsyncMock configured as subprocess
80
+ """
81
+ process = AsyncMock()
82
+ process.returncode = returncode
83
+ process.pid = pid
84
+ process.communicate = AsyncMock(return_value=(stdout, stderr))
85
+ process.wait = AsyncMock(return_value=returncode)
86
+ process.kill = Mock()
87
+ process.terminate = Mock()
88
+ process.send_signal = Mock()
89
+
90
+ # Add stdout/stderr as async stream readers
91
+ process.stdout = AsyncMock()
92
+ process.stdout.read = AsyncMock(return_value=stdout)
93
+ process.stdout.readline = AsyncMock(side_effect=[stdout, b""])
94
+ process.stdout.at_eof = Mock(side_effect=[False, True])
95
+
96
+ process.stderr = AsyncMock()
97
+ process.stderr.read = AsyncMock(return_value=stderr)
98
+ process.stderr.readline = AsyncMock(side_effect=[stderr, b""])
99
+ process.stderr.at_eof = Mock(side_effect=[False, True])
100
+
101
+ process.stdin = AsyncMock()
102
+ process.stdin.write = AsyncMock()
103
+ process.stdin.drain = AsyncMock()
104
+ process.stdin.close = Mock()
105
+
106
+ return process
107
+
108
+ return _create_subprocess
109
+
110
+
111
+ @pytest.fixture
112
+ def async_mock_server():
113
+ """
114
+ Create a mock async server for testing.
115
+
116
+ Returns:
117
+ Mock server with async methods.
118
+ """
119
+
120
+ class AsyncMockServer:
121
+ def __init__(self):
122
+ self.started = False
123
+ self.connections = []
124
+ self.requests = []
125
+
126
+ async def start(self, host: str = "localhost", port: int = 8080):
127
+ """Start the mock server."""
128
+ self.started = True
129
+ self.host = host
130
+ self.port = port
131
+
132
+ async def stop(self):
133
+ """Stop the mock server."""
134
+ self.started = False
135
+ for conn in self.connections:
136
+ await conn.close()
137
+
138
+ async def handle_connection(self, reader, writer):
139
+ """Mock connection handler."""
140
+ conn = {"reader": reader, "writer": writer}
141
+ self.connections.append(conn)
142
+
143
+ # Mock reading request
144
+ data = await reader.read(1024)
145
+ self.requests.append(data)
146
+
147
+ # Mock sending response
148
+ writer.write(b"HTTP/1.1 200 OK\r\n\r\nOK")
149
+ await writer.drain()
150
+
151
+ writer.close()
152
+ await writer.wait_closed()
153
+
154
+ def get_url(self) -> str:
155
+ """Get server URL."""
156
+ return f"http://{self.host}:{self.port}"
157
+
158
+ return AsyncMockServer()
159
+
160
+
161
+ @pytest.fixture
162
+ def async_test_client():
163
+ """
164
+ Create an async HTTP test client.
165
+
166
+ Returns:
167
+ Mock async HTTP client for testing.
168
+ """
169
+
170
+ class AsyncTestClient:
171
+ def __init__(self):
172
+ self.responses = {}
173
+ self.requests = []
174
+
175
+ def set_response(self, url: str, response: dict):
176
+ """Set a mock response for a URL."""
177
+ self.responses[url] = response
178
+
179
+ async def get(self, url: str, **kwargs) -> dict:
180
+ """Mock GET request."""
181
+ self.requests.append({"method": "GET", "url": url, "kwargs": kwargs})
182
+ return self.responses.get(url, {"status": 404, "body": "Not Found"})
183
+
184
+ async def post(self, url: str, data=None, **kwargs) -> dict:
185
+ """Mock POST request."""
186
+ self.requests.append(
187
+ {"method": "POST", "url": url, "data": data, "kwargs": kwargs}
188
+ )
189
+ return self.responses.get(url, {"status": 200, "body": "OK"})
190
+
191
+ async def close(self):
192
+ """Close the client."""
193
+ pass
194
+
195
+ async def __aenter__(self):
196
+ return self
197
+
198
+ async def __aexit__(self, *args):
199
+ await self.close()
200
+
201
+ return AsyncTestClient()
202
+
203
+
204
+ __all__ = [
205
+ "async_mock_server",
206
+ "async_stream_reader",
207
+ "async_subprocess",
208
+ "async_test_client",
209
+ "mock_async_process",
210
+ ]
@@ -6,33 +6,33 @@ and concurrent operations across any project that depends on provide.foundation.
6
6
  """
7
7
 
8
8
  from provide.foundation.testing.threading.fixtures import (
9
+ concurrent_executor,
10
+ deadlock_detector,
11
+ mock_thread,
9
12
  test_thread,
10
- thread_pool,
11
13
  thread_barrier,
12
- thread_safe_list,
13
- thread_safe_counter,
14
- thread_event,
15
14
  thread_condition,
16
- mock_thread,
15
+ thread_event,
16
+ thread_exception_handler,
17
17
  thread_local_storage,
18
- concurrent_executor,
18
+ thread_pool,
19
+ thread_safe_counter,
20
+ thread_safe_list,
19
21
  thread_synchronizer,
20
- deadlock_detector,
21
- thread_exception_handler,
22
22
  )
23
23
 
24
24
  __all__ = [
25
+ "concurrent_executor",
26
+ "deadlock_detector",
27
+ "mock_thread",
25
28
  "test_thread",
26
- "thread_pool",
27
29
  "thread_barrier",
28
- "thread_safe_list",
29
- "thread_safe_counter",
30
- "thread_event",
31
30
  "thread_condition",
32
- "mock_thread",
31
+ "thread_event",
32
+ "thread_exception_handler",
33
33
  "thread_local_storage",
34
- "concurrent_executor",
34
+ "thread_pool",
35
+ "thread_safe_counter",
36
+ "thread_safe_list",
35
37
  "thread_synchronizer",
36
- "deadlock_detector",
37
- "thread_exception_handler",
38
- ]
38
+ ]
@@ -0,0 +1,105 @@
1
+ """
2
+ Basic threading test fixtures.
3
+
4
+ Core fixtures for creating threads, thread pools, mocks, and thread-local storage.
5
+ """
6
+
7
+ from concurrent.futures import ThreadPoolExecutor
8
+ import threading
9
+ from typing import Callable
10
+ from unittest.mock import Mock
11
+
12
+ import pytest
13
+
14
+
15
+ @pytest.fixture
16
+ def test_thread():
17
+ """
18
+ Create a test thread with automatic cleanup.
19
+
20
+ Returns:
21
+ Function to create and manage test threads.
22
+ """
23
+ threads = []
24
+
25
+ def _create_thread(
26
+ target: Callable, args: tuple = (), kwargs: dict = None, daemon: bool = True
27
+ ) -> threading.Thread:
28
+ """
29
+ Create a test thread.
30
+
31
+ Args:
32
+ target: Function to run in thread
33
+ args: Positional arguments for target
34
+ kwargs: Keyword arguments for target
35
+ daemon: Whether thread should be daemon
36
+
37
+ Returns:
38
+ Started thread instance
39
+ """
40
+ kwargs = kwargs or {}
41
+ thread = threading.Thread(
42
+ target=target, args=args, kwargs=kwargs, daemon=daemon
43
+ )
44
+ threads.append(thread)
45
+ thread.start()
46
+ return thread
47
+
48
+ yield _create_thread
49
+
50
+ # Cleanup: wait for all threads to complete
51
+ for thread in threads:
52
+ if thread.is_alive():
53
+ thread.join(timeout=1.0)
54
+
55
+
56
+ @pytest.fixture
57
+ def thread_pool():
58
+ """
59
+ Create a thread pool executor for testing.
60
+
61
+ Returns:
62
+ ThreadPoolExecutor instance with automatic cleanup.
63
+ """
64
+ executor = ThreadPoolExecutor(max_workers=4)
65
+ yield executor
66
+ executor.shutdown(wait=True, cancel_futures=True)
67
+
68
+
69
+ @pytest.fixture
70
+ def mock_thread():
71
+ """
72
+ Create a mock thread for testing without actual threading.
73
+
74
+ Returns:
75
+ Mock thread object.
76
+ """
77
+ mock = Mock(spec=threading.Thread)
78
+ mock.is_alive.return_value = False
79
+ mock.daemon = False
80
+ mock.name = "MockThread"
81
+ mock.ident = 12345
82
+ mock.start = Mock()
83
+ mock.join = Mock()
84
+ mock.run = Mock()
85
+
86
+ return mock
87
+
88
+
89
+ @pytest.fixture
90
+ def thread_local_storage():
91
+ """
92
+ Create thread-local storage for testing.
93
+
94
+ Returns:
95
+ Thread-local storage object.
96
+ """
97
+ return threading.local()
98
+
99
+
100
+ __all__ = [
101
+ "mock_thread",
102
+ "test_thread",
103
+ "thread_local_storage",
104
+ "thread_pool",
105
+ ]
@@ -0,0 +1,101 @@
1
+ """
2
+ Thread-safe data structure test fixtures.
3
+
4
+ Fixtures for thread-safe lists, counters, and other data structures for testing.
5
+ """
6
+
7
+ import threading
8
+ from typing import Any
9
+
10
+ import pytest
11
+
12
+
13
+ @pytest.fixture
14
+ def thread_safe_list():
15
+ """
16
+ Create a thread-safe list for collecting results.
17
+
18
+ Returns:
19
+ Thread-safe list implementation.
20
+ """
21
+
22
+ class ThreadSafeList:
23
+ def __init__(self):
24
+ self._list = []
25
+ self._lock = threading.Lock()
26
+
27
+ def append(self, item: Any):
28
+ """Thread-safe append."""
29
+ with self._lock:
30
+ self._list.append(item)
31
+
32
+ def extend(self, items):
33
+ """Thread-safe extend."""
34
+ with self._lock:
35
+ self._list.extend(items)
36
+
37
+ def get_all(self) -> list:
38
+ """Get copy of all items."""
39
+ with self._lock:
40
+ return self._list.copy()
41
+
42
+ def clear(self):
43
+ """Clear the list."""
44
+ with self._lock:
45
+ self._list.clear()
46
+
47
+ def __len__(self) -> int:
48
+ with self._lock:
49
+ return len(self._list)
50
+
51
+ def __getitem__(self, index):
52
+ with self._lock:
53
+ return self._list[index]
54
+
55
+ return ThreadSafeList()
56
+
57
+
58
+ @pytest.fixture
59
+ def thread_safe_counter():
60
+ """
61
+ Create a thread-safe counter.
62
+
63
+ Returns:
64
+ Thread-safe counter implementation.
65
+ """
66
+
67
+ class ThreadSafeCounter:
68
+ def __init__(self, initial: int = 0):
69
+ self._value = initial
70
+ self._lock = threading.Lock()
71
+
72
+ def increment(self, amount: int = 1) -> int:
73
+ """Thread-safe increment."""
74
+ with self._lock:
75
+ self._value += amount
76
+ return self._value
77
+
78
+ def decrement(self, amount: int = 1) -> int:
79
+ """Thread-safe decrement."""
80
+ with self._lock:
81
+ self._value -= amount
82
+ return self._value
83
+
84
+ @property
85
+ def value(self) -> int:
86
+ """Get current value."""
87
+ with self._lock:
88
+ return self._value
89
+
90
+ def reset(self, value: int = 0):
91
+ """Reset counter."""
92
+ with self._lock:
93
+ self._value = value
94
+
95
+ return ThreadSafeCounter()
96
+
97
+
98
+ __all__ = [
99
+ "thread_safe_counter",
100
+ "thread_safe_list",
101
+ ]