voicerender 0.1.1__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.
- voicerender/__init__.py +127 -0
- voicerender/__main__.py +3 -0
- voicerender/_version.py +24 -0
- voicerender/capacity.py +678 -0
- voicerender/cli.py +345 -0
- voicerender/engines/__init__.py +68 -0
- voicerender/engines/api_probe.py +495 -0
- voicerender/engines/base.py +425 -0
- voicerender/engines/catalog.py +83 -0
- voicerender/engines/inflectsynth.py +920 -0
- voicerender/engines/kittensynth.py +511 -0
- voicerender/engines/kokoro.py +725 -0
- voicerender/engines/metadata.py +58 -0
- voicerender/engines/piper.py +173 -0
- voicerender/engines/pipersynth.py +570 -0
- voicerender/engines/pocket.py +169 -0
- voicerender/engines/pocketsynth.py +1234 -0
- voicerender/engines/registry.py +320 -0
- voicerender/engines/selection.py +61 -0
- voicerender/engines/supertonicsynth.py +707 -0
- voicerender/errors.py +161 -0
- voicerender/events.py +43 -0
- voicerender/handoff.py +62 -0
- voicerender/inputs/__init__.py +21 -0
- voicerender/inputs/utterplan_v5.py +897 -0
- voicerender/lexicons.py +42 -0
- voicerender/manifest.py +750 -0
- voicerender/models.py +499 -0
- voicerender/py.typed +0 -0
- voicerender/render.py +365 -0
- voicerender/render_v5.py +1193 -0
- voicerender/schemas/render-manifest-v2.schema.json +415 -0
- voicerender/storage.py +113 -0
- voicerender-0.1.1.dist-info/METADATA +254 -0
- voicerender-0.1.1.dist-info/RECORD +39 -0
- voicerender-0.1.1.dist-info/WHEEL +5 -0
- voicerender-0.1.1.dist-info/entry_points.txt +2 -0
- voicerender-0.1.1.dist-info/licenses/LICENSE +201 -0
- voicerender-0.1.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
"""Structured diagnostics for public synthesis-engine API compatibility."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import importlib
|
|
6
|
+
import importlib.metadata
|
|
7
|
+
import json
|
|
8
|
+
import logging
|
|
9
|
+
from collections.abc import Mapping
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
from typing import Any, Literal
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
SUPPORTED_REQUEST_API_VERSION = 1
|
|
15
|
+
|
|
16
|
+
EngineApiStatus = Literal[
|
|
17
|
+
"ready",
|
|
18
|
+
"package_missing",
|
|
19
|
+
"api_incompatible",
|
|
20
|
+
"api_version_incompatible",
|
|
21
|
+
"api_probe_failed",
|
|
22
|
+
]
|
|
23
|
+
ContractSource = Literal["explicit", "legacy_symbols"]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass(frozen=True, slots=True)
|
|
27
|
+
class EngineApiProbe:
|
|
28
|
+
"""Serializable result of checking one engine's documented public API."""
|
|
29
|
+
|
|
30
|
+
engine: str
|
|
31
|
+
package: str
|
|
32
|
+
compatible: bool
|
|
33
|
+
status: EngineApiStatus
|
|
34
|
+
distribution_version: str | None = None
|
|
35
|
+
module_version: str | None = None
|
|
36
|
+
module_path: str | None = None
|
|
37
|
+
expected_api_version: int | None = None
|
|
38
|
+
api_version: int | None = None
|
|
39
|
+
contract_source: ContractSource | None = None
|
|
40
|
+
missing_symbols: tuple[str, ...] = ()
|
|
41
|
+
missing_methods: tuple[str, ...] = ()
|
|
42
|
+
failed_stage: str | None = None
|
|
43
|
+
failed_symbol: str | None = None
|
|
44
|
+
error_type: str | None = None
|
|
45
|
+
error_message: str | None = None
|
|
46
|
+
warnings: tuple[str, ...] = ()
|
|
47
|
+
details: Mapping[str, Any] = field(default_factory=dict)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _probe_public_api(
|
|
51
|
+
*,
|
|
52
|
+
engine: str,
|
|
53
|
+
package: str,
|
|
54
|
+
required_symbols: tuple[str, ...],
|
|
55
|
+
required_methods: Mapping[str, tuple[str, ...]],
|
|
56
|
+
expected_api_version: int | None = None,
|
|
57
|
+
require_explicit_contract: bool = False,
|
|
58
|
+
contract_required_symbols: tuple[str, ...] = (),
|
|
59
|
+
contract_required_methods: Mapping[str, tuple[str, ...]] | None = None,
|
|
60
|
+
legacy_required_methods: Mapping[str, tuple[str, ...]] | None = None,
|
|
61
|
+
) -> EngineApiProbe:
|
|
62
|
+
"""Probe a package root and concrete public entry points without opening a runtime."""
|
|
63
|
+
metadata_warning: str | None = None
|
|
64
|
+
try:
|
|
65
|
+
distribution_version = importlib.metadata.version(package)
|
|
66
|
+
except importlib.metadata.PackageNotFoundError:
|
|
67
|
+
distribution_version = None
|
|
68
|
+
except Exception as exc:
|
|
69
|
+
logger.debug(
|
|
70
|
+
"Engine %s distribution metadata probe failed", engine, exc_info=True
|
|
71
|
+
)
|
|
72
|
+
distribution_version = None
|
|
73
|
+
metadata_warning = (
|
|
74
|
+
f"Distribution metadata could not be read: {type(exc).__name__}: {exc}"
|
|
75
|
+
)
|
|
76
|
+
else:
|
|
77
|
+
metadata_warning = None
|
|
78
|
+
|
|
79
|
+
common: dict[str, Any] = {
|
|
80
|
+
"engine": engine,
|
|
81
|
+
"package": package,
|
|
82
|
+
"expected_api_version": expected_api_version,
|
|
83
|
+
"distribution_version": distribution_version,
|
|
84
|
+
}
|
|
85
|
+
warnings: list[str] = []
|
|
86
|
+
if metadata_warning is not None:
|
|
87
|
+
warnings.append(metadata_warning)
|
|
88
|
+
|
|
89
|
+
try:
|
|
90
|
+
module = importlib.import_module(package)
|
|
91
|
+
except ModuleNotFoundError as exc:
|
|
92
|
+
logger.debug("Engine %s package import failed", engine, exc_info=True)
|
|
93
|
+
if exc.name == package:
|
|
94
|
+
return EngineApiProbe(
|
|
95
|
+
**common,
|
|
96
|
+
compatible=False,
|
|
97
|
+
status="package_missing",
|
|
98
|
+
failed_stage="module_import",
|
|
99
|
+
error_type=type(exc).__name__,
|
|
100
|
+
error_message=str(exc),
|
|
101
|
+
warnings=tuple(warnings),
|
|
102
|
+
)
|
|
103
|
+
return _probe_failed(
|
|
104
|
+
common,
|
|
105
|
+
warnings,
|
|
106
|
+
stage="module_import",
|
|
107
|
+
error=exc,
|
|
108
|
+
)
|
|
109
|
+
except Exception as exc:
|
|
110
|
+
logger.debug("Engine %s package import failed", engine, exc_info=True)
|
|
111
|
+
return _probe_failed(common, warnings, stage="module_import", error=exc)
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
module_version_value = getattr(module, "__version__", None)
|
|
115
|
+
module_path_value = getattr(module, "__file__", None)
|
|
116
|
+
module_version = (
|
|
117
|
+
str(module_version_value) if module_version_value is not None else None
|
|
118
|
+
)
|
|
119
|
+
module_path = str(module_path_value) if module_path_value is not None else None
|
|
120
|
+
except Exception as exc:
|
|
121
|
+
logger.debug(
|
|
122
|
+
"Engine %s module metadata resolution failed", engine, exc_info=True
|
|
123
|
+
)
|
|
124
|
+
return _probe_failed(
|
|
125
|
+
common,
|
|
126
|
+
warnings,
|
|
127
|
+
stage="module_metadata",
|
|
128
|
+
error=exc,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
if (
|
|
132
|
+
distribution_version is not None
|
|
133
|
+
and module_version is not None
|
|
134
|
+
and distribution_version != module_version
|
|
135
|
+
):
|
|
136
|
+
warnings.append("Imported module version differs from distribution metadata.")
|
|
137
|
+
|
|
138
|
+
common.update(module_version=module_version, module_path=module_path)
|
|
139
|
+
resolved: dict[str, Any] = {}
|
|
140
|
+
missing_symbols: list[str] = []
|
|
141
|
+
for name in required_symbols:
|
|
142
|
+
try:
|
|
143
|
+
resolved[name] = getattr(module, name)
|
|
144
|
+
except AttributeError:
|
|
145
|
+
missing_symbols.append(name)
|
|
146
|
+
except Exception as exc:
|
|
147
|
+
logger.debug(
|
|
148
|
+
"Engine %s public symbol %s resolution failed",
|
|
149
|
+
engine,
|
|
150
|
+
name,
|
|
151
|
+
exc_info=True,
|
|
152
|
+
)
|
|
153
|
+
return _probe_failed(
|
|
154
|
+
common,
|
|
155
|
+
warnings,
|
|
156
|
+
stage="symbol_resolution",
|
|
157
|
+
error=exc,
|
|
158
|
+
failed_symbol=name,
|
|
159
|
+
missing_symbols=tuple(missing_symbols),
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
missing_methods: list[str] = []
|
|
163
|
+
for owner_name, methods in required_methods.items():
|
|
164
|
+
owner = (
|
|
165
|
+
module
|
|
166
|
+
if owner_name in {"__module__", "module"}
|
|
167
|
+
else resolved.get(owner_name)
|
|
168
|
+
)
|
|
169
|
+
if (
|
|
170
|
+
owner is None
|
|
171
|
+
and owner_name not in {"__module__", "module"}
|
|
172
|
+
and owner_name not in resolved
|
|
173
|
+
):
|
|
174
|
+
# A missing class is already reported as a missing public symbol.
|
|
175
|
+
continue
|
|
176
|
+
for method_name in methods:
|
|
177
|
+
qualified_name = (
|
|
178
|
+
method_name
|
|
179
|
+
if owner_name in {"__module__", "module"}
|
|
180
|
+
else f"{owner_name}.{method_name}"
|
|
181
|
+
)
|
|
182
|
+
try:
|
|
183
|
+
method = getattr(owner, method_name)
|
|
184
|
+
except AttributeError:
|
|
185
|
+
missing_methods.append(qualified_name)
|
|
186
|
+
continue
|
|
187
|
+
except Exception as exc:
|
|
188
|
+
logger.debug(
|
|
189
|
+
"Engine %s public method %s resolution failed",
|
|
190
|
+
engine,
|
|
191
|
+
qualified_name,
|
|
192
|
+
exc_info=True,
|
|
193
|
+
)
|
|
194
|
+
return _probe_failed(
|
|
195
|
+
common,
|
|
196
|
+
warnings,
|
|
197
|
+
stage="method_resolution",
|
|
198
|
+
error=exc,
|
|
199
|
+
failed_symbol=qualified_name,
|
|
200
|
+
missing_symbols=tuple(missing_symbols),
|
|
201
|
+
missing_methods=tuple(missing_methods),
|
|
202
|
+
)
|
|
203
|
+
if not callable(method):
|
|
204
|
+
missing_methods.append(qualified_name)
|
|
205
|
+
|
|
206
|
+
api_version: int | None = None
|
|
207
|
+
contract_source: ContractSource | None = None
|
|
208
|
+
contract_names = ("REQUEST_API_VERSION", "request_api_contract")
|
|
209
|
+
contract_values: dict[str, Any] = {}
|
|
210
|
+
for name in contract_names:
|
|
211
|
+
try:
|
|
212
|
+
contract_values[name] = getattr(module, name)
|
|
213
|
+
except AttributeError:
|
|
214
|
+
continue
|
|
215
|
+
except Exception as exc:
|
|
216
|
+
logger.debug(
|
|
217
|
+
"Engine %s request API marker %s resolution failed",
|
|
218
|
+
engine,
|
|
219
|
+
name,
|
|
220
|
+
exc_info=True,
|
|
221
|
+
)
|
|
222
|
+
return _probe_failed(
|
|
223
|
+
common,
|
|
224
|
+
warnings,
|
|
225
|
+
stage="contract_resolution",
|
|
226
|
+
error=exc,
|
|
227
|
+
failed_symbol=name,
|
|
228
|
+
missing_symbols=tuple(missing_symbols),
|
|
229
|
+
missing_methods=tuple(missing_methods),
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
has_version = "REQUEST_API_VERSION" in contract_values
|
|
233
|
+
has_contract = "request_api_contract" in contract_values
|
|
234
|
+
if has_version and has_contract:
|
|
235
|
+
contract_source = "explicit"
|
|
236
|
+
version_value = contract_values["REQUEST_API_VERSION"]
|
|
237
|
+
if isinstance(version_value, bool) or not isinstance(version_value, int):
|
|
238
|
+
error = TypeError("REQUEST_API_VERSION must be an integer")
|
|
239
|
+
logger.debug("Engine %s request API version is invalid: %s", engine, error)
|
|
240
|
+
return _probe_failed(
|
|
241
|
+
common,
|
|
242
|
+
warnings,
|
|
243
|
+
stage="contract_version",
|
|
244
|
+
error=error,
|
|
245
|
+
failed_symbol="REQUEST_API_VERSION",
|
|
246
|
+
missing_symbols=tuple(missing_symbols),
|
|
247
|
+
missing_methods=tuple(missing_methods),
|
|
248
|
+
)
|
|
249
|
+
api_version = version_value
|
|
250
|
+
contract_function = contract_values["request_api_contract"]
|
|
251
|
+
if not callable(contract_function):
|
|
252
|
+
error = TypeError("request_api_contract is not callable")
|
|
253
|
+
logger.debug("Engine %s request API contract is invalid: %s", engine, error)
|
|
254
|
+
return _probe_failed(
|
|
255
|
+
common,
|
|
256
|
+
warnings,
|
|
257
|
+
stage="contract_inspection",
|
|
258
|
+
error=error,
|
|
259
|
+
failed_symbol="request_api_contract",
|
|
260
|
+
missing_symbols=tuple(missing_symbols),
|
|
261
|
+
missing_methods=tuple(missing_methods),
|
|
262
|
+
)
|
|
263
|
+
try:
|
|
264
|
+
contract_function()
|
|
265
|
+
except Exception as exc:
|
|
266
|
+
logger.debug(
|
|
267
|
+
"Engine %s request API contract inspection failed",
|
|
268
|
+
engine,
|
|
269
|
+
exc_info=True,
|
|
270
|
+
)
|
|
271
|
+
return _probe_failed(
|
|
272
|
+
common,
|
|
273
|
+
warnings,
|
|
274
|
+
stage="contract_inspection",
|
|
275
|
+
error=exc,
|
|
276
|
+
failed_symbol="request_api_contract",
|
|
277
|
+
missing_symbols=tuple(missing_symbols),
|
|
278
|
+
missing_methods=tuple(missing_methods),
|
|
279
|
+
api_version=api_version,
|
|
280
|
+
contract_source=contract_source,
|
|
281
|
+
)
|
|
282
|
+
elif has_version or has_contract:
|
|
283
|
+
if require_explicit_contract:
|
|
284
|
+
contract_source = "explicit"
|
|
285
|
+
absent_name = (
|
|
286
|
+
"request_api_contract" if has_version else "REQUEST_API_VERSION"
|
|
287
|
+
)
|
|
288
|
+
missing_symbols.append(absent_name)
|
|
289
|
+
else:
|
|
290
|
+
contract_source = "legacy_symbols"
|
|
291
|
+
warnings.append(
|
|
292
|
+
"Incomplete explicit request API contract; using legacy symbol checks."
|
|
293
|
+
)
|
|
294
|
+
elif required_symbols or required_methods:
|
|
295
|
+
if require_explicit_contract:
|
|
296
|
+
contract_source = "explicit"
|
|
297
|
+
missing_symbols.extend(contract_names)
|
|
298
|
+
else:
|
|
299
|
+
contract_source = "legacy_symbols"
|
|
300
|
+
|
|
301
|
+
common.update(api_version=api_version, contract_source=contract_source)
|
|
302
|
+
|
|
303
|
+
conditional_symbols = (
|
|
304
|
+
contract_required_symbols if contract_source == "explicit" else ()
|
|
305
|
+
)
|
|
306
|
+
conditional_methods = (
|
|
307
|
+
contract_required_methods or {}
|
|
308
|
+
if contract_source == "explicit"
|
|
309
|
+
else legacy_required_methods or {}
|
|
310
|
+
)
|
|
311
|
+
for name in conditional_symbols:
|
|
312
|
+
if name in resolved:
|
|
313
|
+
continue
|
|
314
|
+
try:
|
|
315
|
+
resolved[name] = getattr(module, name)
|
|
316
|
+
except AttributeError:
|
|
317
|
+
missing_symbols.append(name)
|
|
318
|
+
except Exception as exc:
|
|
319
|
+
logger.debug(
|
|
320
|
+
"Engine %s public symbol %s resolution failed",
|
|
321
|
+
engine,
|
|
322
|
+
name,
|
|
323
|
+
exc_info=True,
|
|
324
|
+
)
|
|
325
|
+
return _probe_failed(
|
|
326
|
+
common,
|
|
327
|
+
warnings,
|
|
328
|
+
stage="symbol_resolution",
|
|
329
|
+
error=exc,
|
|
330
|
+
failed_symbol=name,
|
|
331
|
+
missing_symbols=tuple(missing_symbols),
|
|
332
|
+
missing_methods=tuple(missing_methods),
|
|
333
|
+
api_version=api_version,
|
|
334
|
+
contract_source=contract_source,
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
for owner_name, methods in conditional_methods.items():
|
|
338
|
+
owner = (
|
|
339
|
+
module
|
|
340
|
+
if owner_name in {"__module__", "module"}
|
|
341
|
+
else resolved.get(owner_name)
|
|
342
|
+
)
|
|
343
|
+
if (
|
|
344
|
+
owner is None
|
|
345
|
+
and owner_name not in {"__module__", "module"}
|
|
346
|
+
and owner_name not in resolved
|
|
347
|
+
):
|
|
348
|
+
continue
|
|
349
|
+
for method_name in methods:
|
|
350
|
+
qualified_name = (
|
|
351
|
+
method_name
|
|
352
|
+
if owner_name in {"__module__", "module"}
|
|
353
|
+
else f"{owner_name}.{method_name}"
|
|
354
|
+
)
|
|
355
|
+
try:
|
|
356
|
+
method = getattr(owner, method_name)
|
|
357
|
+
except AttributeError:
|
|
358
|
+
missing_methods.append(qualified_name)
|
|
359
|
+
except Exception as exc:
|
|
360
|
+
logger.debug(
|
|
361
|
+
"Engine %s public method %s resolution failed",
|
|
362
|
+
engine,
|
|
363
|
+
qualified_name,
|
|
364
|
+
exc_info=True,
|
|
365
|
+
)
|
|
366
|
+
return _probe_failed(
|
|
367
|
+
common,
|
|
368
|
+
warnings,
|
|
369
|
+
stage="method_resolution",
|
|
370
|
+
error=exc,
|
|
371
|
+
failed_symbol=qualified_name,
|
|
372
|
+
missing_symbols=tuple(missing_symbols),
|
|
373
|
+
missing_methods=tuple(missing_methods),
|
|
374
|
+
api_version=api_version,
|
|
375
|
+
contract_source=contract_source,
|
|
376
|
+
)
|
|
377
|
+
else:
|
|
378
|
+
if not callable(method):
|
|
379
|
+
missing_methods.append(qualified_name)
|
|
380
|
+
|
|
381
|
+
if (
|
|
382
|
+
api_version is not None
|
|
383
|
+
and expected_api_version is not None
|
|
384
|
+
and api_version != expected_api_version
|
|
385
|
+
):
|
|
386
|
+
return EngineApiProbe(
|
|
387
|
+
**common,
|
|
388
|
+
compatible=False,
|
|
389
|
+
status="api_version_incompatible",
|
|
390
|
+
missing_symbols=tuple(dict.fromkeys(missing_symbols)),
|
|
391
|
+
missing_methods=tuple(dict.fromkeys(missing_methods)),
|
|
392
|
+
warnings=tuple(warnings),
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
if missing_symbols or missing_methods:
|
|
396
|
+
return EngineApiProbe(
|
|
397
|
+
**common,
|
|
398
|
+
compatible=False,
|
|
399
|
+
status="api_incompatible",
|
|
400
|
+
missing_symbols=tuple(dict.fromkeys(missing_symbols)),
|
|
401
|
+
missing_methods=tuple(dict.fromkeys(missing_methods)),
|
|
402
|
+
warnings=tuple(warnings),
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
return EngineApiProbe(
|
|
406
|
+
**common,
|
|
407
|
+
compatible=True,
|
|
408
|
+
status="ready",
|
|
409
|
+
warnings=tuple(warnings),
|
|
410
|
+
)
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
def probe_public_api(
|
|
414
|
+
*,
|
|
415
|
+
engine: str,
|
|
416
|
+
package: str,
|
|
417
|
+
required_symbols: tuple[str, ...],
|
|
418
|
+
required_methods: Mapping[str, tuple[str, ...]],
|
|
419
|
+
expected_api_version: int | None = None,
|
|
420
|
+
require_explicit_contract: bool = False,
|
|
421
|
+
contract_required_symbols: tuple[str, ...] = (),
|
|
422
|
+
contract_required_methods: Mapping[str, tuple[str, ...]] | None = None,
|
|
423
|
+
legacy_required_methods: Mapping[str, tuple[str, ...]] | None = None,
|
|
424
|
+
) -> EngineApiProbe:
|
|
425
|
+
"""Probe a public package API and emit one compact structured debug event."""
|
|
426
|
+
probe = _probe_public_api(
|
|
427
|
+
engine=engine,
|
|
428
|
+
package=package,
|
|
429
|
+
required_symbols=required_symbols,
|
|
430
|
+
required_methods=required_methods,
|
|
431
|
+
expected_api_version=expected_api_version,
|
|
432
|
+
require_explicit_contract=require_explicit_contract,
|
|
433
|
+
contract_required_symbols=contract_required_symbols,
|
|
434
|
+
contract_required_methods=contract_required_methods,
|
|
435
|
+
legacy_required_methods=legacy_required_methods,
|
|
436
|
+
)
|
|
437
|
+
event = {
|
|
438
|
+
"engine": probe.engine,
|
|
439
|
+
"package": probe.package,
|
|
440
|
+
"distribution_version": probe.distribution_version,
|
|
441
|
+
"module_version": probe.module_version,
|
|
442
|
+
"module_path": probe.module_path,
|
|
443
|
+
"api_version": probe.api_version,
|
|
444
|
+
"expected_api_version": probe.expected_api_version,
|
|
445
|
+
"contract_source": probe.contract_source,
|
|
446
|
+
"compatible": probe.compatible,
|
|
447
|
+
"status": probe.status,
|
|
448
|
+
"missing_symbols": probe.missing_symbols,
|
|
449
|
+
"missing_methods": probe.missing_methods,
|
|
450
|
+
"failed_stage": probe.failed_stage,
|
|
451
|
+
"failed_symbol": probe.failed_symbol,
|
|
452
|
+
"error_type": probe.error_type,
|
|
453
|
+
"error_message": probe.error_message,
|
|
454
|
+
"warnings": probe.warnings,
|
|
455
|
+
}
|
|
456
|
+
logger.debug(
|
|
457
|
+
"engine.api_probe %s", json.dumps(event, sort_keys=True, separators=(",", ":"))
|
|
458
|
+
)
|
|
459
|
+
return probe
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
def _probe_failed(
|
|
463
|
+
common: Mapping[str, Any],
|
|
464
|
+
warnings: list[str],
|
|
465
|
+
*,
|
|
466
|
+
stage: str,
|
|
467
|
+
error: Exception,
|
|
468
|
+
failed_symbol: str | None = None,
|
|
469
|
+
missing_symbols: tuple[str, ...] = (),
|
|
470
|
+
missing_methods: tuple[str, ...] = (),
|
|
471
|
+
api_version: int | None = None,
|
|
472
|
+
contract_source: ContractSource | None = None,
|
|
473
|
+
) -> EngineApiProbe:
|
|
474
|
+
return EngineApiProbe(
|
|
475
|
+
**common,
|
|
476
|
+
compatible=False,
|
|
477
|
+
status="api_probe_failed",
|
|
478
|
+
api_version=api_version,
|
|
479
|
+
contract_source=contract_source,
|
|
480
|
+
missing_symbols=missing_symbols,
|
|
481
|
+
missing_methods=missing_methods,
|
|
482
|
+
failed_stage=stage,
|
|
483
|
+
failed_symbol=failed_symbol,
|
|
484
|
+
error_type=type(error).__name__,
|
|
485
|
+
error_message=str(error),
|
|
486
|
+
warnings=tuple(warnings),
|
|
487
|
+
)
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
__all__ = [
|
|
491
|
+
"ContractSource",
|
|
492
|
+
"EngineApiProbe",
|
|
493
|
+
"EngineApiStatus",
|
|
494
|
+
"probe_public_api",
|
|
495
|
+
]
|