arxo-codegen 0.4.0__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.
- arxo_codegen/__init__.py +5 -0
- arxo_codegen/__main__.py +7 -0
- arxo_codegen/active-outcomes.json +6837 -0
- arxo_codegen/check.py +158 -0
- arxo_codegen/check_active_canaries.py +262 -0
- arxo_codegen/check_api.py +76 -0
- arxo_codegen/check_conformance.py +414 -0
- arxo_codegen/check_matrix.py +131 -0
- arxo_codegen/check_packages.py +281 -0
- arxo_codegen/check_semantic_probes.py +293 -0
- arxo_codegen/check_xlsx.py +320 -0
- arxo_codegen/consumer_runner.py +316 -0
- arxo_codegen/core_support.py +203 -0
- arxo_codegen/coverage.py +341 -0
- arxo_codegen/deliver.py +180 -0
- arxo_codegen/examples/xlsx/pricing.lawir.json +409 -0
- arxo_codegen/examples/xlsx/pricing.xlsx.json +52 -0
- arxo_codegen/excel_plan.py +602 -0
- arxo_codegen/harness/verify/ci/gates/backends/check_backends.py +1248 -0
- arxo_codegen/harness/verify/ci/gates/backends/l1_fixtures.py +463 -0
- arxo_codegen/inert-nodes.json +62 -0
- arxo_codegen/inert.py +91 -0
- arxo_codegen/inputs.py +59 -0
- arxo_codegen/package.py +565 -0
- arxo_codegen/plan.py +4053 -0
- arxo_codegen/recertify_registry.py +100 -0
- arxo_codegen/runtime-cert.json +5259 -0
- arxo_codegen/runtime_cert.py +233 -0
- arxo_codegen/survey.py +272 -0
- arxo_codegen/target_runner.py +101 -0
- arxo_codegen/targets/bsl/cert.bsl +113 -0
- arxo_codegen/targets/bsl/emit.py +356 -0
- arxo_codegen/targets/bsl/json.bsl +243 -0
- arxo_codegen/targets/bsl/runner.bsl +210 -0
- arxo_codegen/targets/bsl/runtime.bsl +858 -0
- arxo_codegen/targets/cs/Cert.cs +90 -0
- arxo_codegen/targets/cs/Runner.cs +154 -0
- arxo_codegen/targets/cs/Runtime.cs +243 -0
- arxo_codegen/targets/cs/emit.py +223 -0
- arxo_codegen/targets/dart/cert.dart +99 -0
- arxo_codegen/targets/dart/emit.py +206 -0
- arxo_codegen/targets/dart/json.dart +166 -0
- arxo_codegen/targets/dart/runner.dart +154 -0
- arxo_codegen/targets/dart/runtime.dart +293 -0
- arxo_codegen/targets/erl/cert.erl +64 -0
- arxo_codegen/targets/erl/emit.py +216 -0
- arxo_codegen/targets/erl/rt.erl +238 -0
- arxo_codegen/targets/erl/runner.erl +130 -0
- arxo_codegen/targets/ex/cert.exs +62 -0
- arxo_codegen/targets/ex/emit.py +204 -0
- arxo_codegen/targets/ex/runner.exs +124 -0
- arxo_codegen/targets/ex/runtime.ex +227 -0
- arxo_codegen/targets/go/apiBase.go +483 -0
- arxo_codegen/targets/go/apicheck.go +97 -0
- arxo_codegen/targets/go/cert.go +218 -0
- arxo_codegen/targets/go/emit.py +1806 -0
- arxo_codegen/targets/go/evaluate.go +1826 -0
- arxo_codegen/targets/go/runner.go +38 -0
- arxo_codegen/targets/go/runtime.go +2612 -0
- arxo_codegen/targets/java/Cert.java +91 -0
- arxo_codegen/targets/java/Json.java +148 -0
- arxo_codegen/targets/java/Runner.java +151 -0
- arxo_codegen/targets/java/Runtime.java +243 -0
- arxo_codegen/targets/java/emit.py +198 -0
- arxo_codegen/targets/kt/Cert.kt +67 -0
- arxo_codegen/targets/kt/Json.kt +103 -0
- arxo_codegen/targets/kt/Runner.kt +126 -0
- arxo_codegen/targets/kt/Runtime.kt +196 -0
- arxo_codegen/targets/kt/emit.py +195 -0
- arxo_codegen/targets/lua/cert.lua +82 -0
- arxo_codegen/targets/lua/emit.py +250 -0
- arxo_codegen/targets/lua/json.lua +133 -0
- arxo_codegen/targets/lua/runner.lua +167 -0
- arxo_codegen/targets/lua/runtime.lua +541 -0
- arxo_codegen/targets/php/cert.php +84 -0
- arxo_codegen/targets/php/emit.py +229 -0
- arxo_codegen/targets/php/json.php +144 -0
- arxo_codegen/targets/php/runner.php +189 -0
- arxo_codegen/targets/php/runtime.php +660 -0
- arxo_codegen/targets/py/api_base.py +334 -0
- arxo_codegen/targets/py/apicheck.py +51 -0
- arxo_codegen/targets/py/cert.py +140 -0
- arxo_codegen/targets/py/emit.py +1140 -0
- arxo_codegen/targets/py/evaluate.py +980 -0
- arxo_codegen/targets/py/runner.py +38 -0
- arxo_codegen/targets/py/runtime.py +1634 -0
- arxo_codegen/targets/rb/cert.rb +73 -0
- arxo_codegen/targets/rb/emit.py +203 -0
- arxo_codegen/targets/rb/runner.rb +130 -0
- arxo_codegen/targets/rb/runtime.rb +255 -0
- arxo_codegen/targets/rs/Cargo.lock +142 -0
- arxo_codegen/targets/rs/Cargo.toml +16 -0
- arxo_codegen/targets/rs/cert.rs +106 -0
- arxo_codegen/targets/rs/emit.py +233 -0
- arxo_codegen/targets/rs/prefetch.rs +1 -0
- arxo_codegen/targets/rs/runner.rs +181 -0
- arxo_codegen/targets/rs/runtime.rs +448 -0
- arxo_codegen/targets/scala/Cert.scala +77 -0
- arxo_codegen/targets/scala/Json.scala +140 -0
- arxo_codegen/targets/scala/Runner.scala +121 -0
- arxo_codegen/targets/scala/Runtime.scala +269 -0
- arxo_codegen/targets/scala/emit.py +193 -0
- arxo_codegen/targets/swift/cert.swift +105 -0
- arxo_codegen/targets/swift/emit.py +231 -0
- arxo_codegen/targets/swift/json.swift +208 -0
- arxo_codegen/targets/swift/runner.swift +133 -0
- arxo_codegen/targets/swift/runtime.swift +528 -0
- arxo_codegen/targets/ts/apiBase.ts +250 -0
- arxo_codegen/targets/ts/apicheck.ts +37 -0
- arxo_codegen/targets/ts/cert.ts +96 -0
- arxo_codegen/targets/ts/emit.py +1214 -0
- arxo_codegen/targets/ts/evaluate.ts +894 -0
- arxo_codegen/targets/ts/package-lock.json +45 -0
- arxo_codegen/targets/ts/package.json +9 -0
- arxo_codegen/targets/ts/runner.ts +31 -0
- arxo_codegen/targets/ts/runtime.ts +1369 -0
- arxo_codegen/targets/xlsx/README.ru.md +176 -0
- arxo_codegen/targets/xlsx/emit.py +198 -0
- arxo_codegen/temporal.py +59 -0
- arxo_codegen/test_alias_types.py +171 -0
- arxo_codegen/test_api_contract.py +89 -0
- arxo_codegen/test_calendar_policy.py +48 -0
- arxo_codegen/test_check.py +49 -0
- arxo_codegen/test_check_active_canaries.py +96 -0
- arxo_codegen/test_check_conformance.py +132 -0
- arxo_codegen/test_check_semantic_probes.py +85 -0
- arxo_codegen/test_check_xlsx.py +52 -0
- arxo_codegen/test_consumer_runner.py +175 -0
- arxo_codegen/test_core_support.py +80 -0
- arxo_codegen/test_e0212_decision_time.py +63 -0
- arxo_codegen/test_head_aggregate.py +71 -0
- arxo_codegen/test_inert.py +143 -0
- arxo_codegen/test_instant_types.py +113 -0
- arxo_codegen/test_key_conflict_scope.py +92 -0
- arxo_codegen/test_key_conflict_targets.py +17 -0
- arxo_codegen/test_package_layout.py +163 -0
- arxo_codegen/test_plan_language_version.py +44 -0
- arxo_codegen/test_positions_refusal.py +43 -0
- arxo_codegen/test_recertify_registry.py +77 -0
- arxo_codegen/test_ruby_target.py +41 -0
- arxo_codegen/test_runtime_cert.py +83 -0
- arxo_codegen/test_secondary_key_conflict_scope.py +17 -0
- arxo_codegen/test_stage_r.py +108 -0
- arxo_codegen/test_standalone_inputs.py +71 -0
- arxo_codegen/test_support.py +150 -0
- arxo_codegen/test_survey_inputs.py +115 -0
- arxo_codegen-0.4.0.dist-info/LICENSE +202 -0
- arxo_codegen-0.4.0.dist-info/METADATA +1673 -0
- arxo_codegen-0.4.0.dist-info/RECORD +152 -0
- arxo_codegen-0.4.0.dist-info/WHEEL +5 -0
- arxo_codegen-0.4.0.dist-info/entry_points.txt +13 -0
- arxo_codegen-0.4.0.dist-info/top_level.txt +1 -0
arxo_codegen/inert.py
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""Манифест инертных конструкций среза (CODEGEN-COVERAGE-PLAN §1.1, W1).
|
|
2
|
+
|
|
3
|
+
Статус «инертна»: конструкция присутствует в пакете, но на ответ поддержанных
|
|
4
|
+
видов вопросов не влияет; план её пропускает, а не отвергает. Пропуск
|
|
5
|
+
закрепляется строкой манифеста `inert-nodes.json` и ДОКАЗЫВАЕТСЯ парой
|
|
6
|
+
векторов: половина с конструкцией (`witness`) и половина без неё (`bare`)
|
|
7
|
+
над одной программой, делом и вопросом дают у оракула один документ по
|
|
8
|
+
`results`, `positions`, `issues`, `conflicts`, `proofGraph`; `manifest` и
|
|
9
|
+
`resultHash` различаются по построению (§209 покрывает конверт, §208 —
|
|
10
|
+
manifest). Ворота conformance требуют: обе половины экспортированы, половина
|
|
11
|
+
с конструкцией совпала с голденом на каждой активной цели, голдены половин
|
|
12
|
+
совпадают по перечисленным ключам. Строка без такого свидетеля — отказ ворот.
|
|
13
|
+
"""
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import json
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
HERE = Path(__file__).resolve().parent
|
|
20
|
+
MANIFEST = HERE / "inert-nodes.json"
|
|
21
|
+
FORMAT = "law.codegen-inert-nodes/0.1"
|
|
22
|
+
#: Ключи evaluation-документа, по которым половины пары обязаны совпасть.
|
|
23
|
+
DOCUMENT_KEYS = ("results", "positions", "issues", "conflicts", "proofGraph")
|
|
24
|
+
FAMILIES = ("node:", "rulefield:")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def load(path: Path = MANIFEST) -> dict:
|
|
28
|
+
manifest = json.loads(path.read_text(encoding="utf-8"))
|
|
29
|
+
if manifest.get("format") != FORMAT or not isinstance(manifest.get("constructs"), dict):
|
|
30
|
+
raise ValueError(f"манифест инертности не {FORMAT}: {path}")
|
|
31
|
+
for construct, row in manifest["constructs"].items():
|
|
32
|
+
if not construct.startswith(FAMILIES):
|
|
33
|
+
raise ValueError(f"манифест инертности: конструкция вне семейств {FAMILIES}: {construct}")
|
|
34
|
+
if not isinstance(row, dict) or not all(isinstance(row.get(k), str) and row[k] for k in ("witness", "bare")):
|
|
35
|
+
raise ValueError(f"манифест инертности: {construct} без пары witness/bare")
|
|
36
|
+
if row["witness"] == row["bare"]:
|
|
37
|
+
raise ValueError(f"манифест инертности: {construct} — одна половина названа дважды")
|
|
38
|
+
return manifest
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def constructs(path: Path = MANIFEST) -> dict[str, dict]:
|
|
42
|
+
return load(path)["constructs"]
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def node_kinds(manifest: dict) -> frozenset[str]:
|
|
46
|
+
return frozenset(c.removeprefix("node:") for c in manifest["constructs"] if c.startswith("node:"))
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def rule_fields(manifest: dict) -> frozenset[str]:
|
|
50
|
+
return frozenset(c.removeprefix("rulefield:") for c in manifest["constructs"] if c.startswith("rulefield:"))
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _document(vectors: Path, ident: str, index: dict[str, Path]) -> dict | None:
|
|
54
|
+
directory = index.get(ident)
|
|
55
|
+
if directory is None:
|
|
56
|
+
return None
|
|
57
|
+
golden = directory / "expected.json"
|
|
58
|
+
if not golden.is_file():
|
|
59
|
+
return None
|
|
60
|
+
return json.loads(golden.read_text(encoding="utf-8"))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def witness_failures(manifest: dict, rows: list[dict], vectors: Path) -> tuple[list[dict], list[str]]:
|
|
64
|
+
"""Свидетели каждой строки манифеста против отчёта conformance.
|
|
65
|
+
|
|
66
|
+
`rows` — строки `report["vectors"]` (`id`, `actual`), `vectors` — каталог
|
|
67
|
+
экспортированных векторов. Возвращает таблицу свидетелей и список отказов.
|
|
68
|
+
"""
|
|
69
|
+
actual = {row["id"]: row.get("actual") for row in rows}
|
|
70
|
+
index = {d.name: d for d in vectors.rglob("*") if d.is_dir() and (d / "expected.json").is_file()}
|
|
71
|
+
table, failures = [], []
|
|
72
|
+
for construct, row in sorted(manifest["constructs"].items()):
|
|
73
|
+
witness, bare = row["witness"], row["bare"]
|
|
74
|
+
entry = {"construct": construct, "witness": witness, "bare": bare,
|
|
75
|
+
"witnessOutcome": actual.get(witness), "bareOutcome": actual.get(bare)}
|
|
76
|
+
for ident in (witness, bare):
|
|
77
|
+
if ident not in actual:
|
|
78
|
+
failures.append(f"{construct}: свидетель {ident} не среди активных векторов")
|
|
79
|
+
elif actual[ident] != "match":
|
|
80
|
+
failures.append(f"{construct}: свидетель {ident} — «{actual[ident]}», а не совпадение")
|
|
81
|
+
docs = (_document(vectors, witness, index), _document(vectors, bare, index))
|
|
82
|
+
if None in docs:
|
|
83
|
+
failures.append(f"{construct}: у половины пары нет голдена expected.json")
|
|
84
|
+
entry["documentsAgree"] = None
|
|
85
|
+
else:
|
|
86
|
+
differing = [k for k in DOCUMENT_KEYS if docs[0].get(k) != docs[1].get(k)]
|
|
87
|
+
entry["documentsAgree"] = not differing
|
|
88
|
+
if differing:
|
|
89
|
+
failures.append(f"{construct}: половины пары расходятся по {', '.join(differing)} — конструкция не инертна")
|
|
90
|
+
table.append(entry)
|
|
91
|
+
return table, failures
|
arxo_codegen/inputs.py
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""Explicit inputs for standalone code generation; no repository discovery."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import hashlib
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from plan import Refused
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def dependency_index(documents: list[dict]) -> dict[str, dict]:
|
|
12
|
+
result = {}
|
|
13
|
+
for document in documents:
|
|
14
|
+
name = (document.get("package") or {}).get("name")
|
|
15
|
+
if not isinstance(name, str) or not name:
|
|
16
|
+
raise Refused("зависимость CLIR без имени пакета")
|
|
17
|
+
if name in result:
|
|
18
|
+
raise Refused(f"неоднозначная зависимость CLIR: {name}")
|
|
19
|
+
result[name] = document
|
|
20
|
+
return result
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def load_resources(manifest: Path) -> dict[str, bytes]:
|
|
24
|
+
root = manifest.resolve().parent
|
|
25
|
+
entries = json.loads(manifest.read_text(encoding="utf-8"))
|
|
26
|
+
if not isinstance(entries, dict):
|
|
27
|
+
raise Refused("ресурсы: ожидается объект URI → {path, sha256}")
|
|
28
|
+
resources = {}
|
|
29
|
+
for uri, entry in entries.items():
|
|
30
|
+
if (not isinstance(entry, dict) or set(entry) != {"path", "sha256"}
|
|
31
|
+
or not isinstance(entry["path"], str) or not isinstance(entry["sha256"], str)):
|
|
32
|
+
raise Refused(f"ресурсы: некорректная запись {uri}")
|
|
33
|
+
path = (root / entry["path"]).resolve()
|
|
34
|
+
if not path.is_relative_to(root):
|
|
35
|
+
raise Refused(f"ресурсы: путь вне комплекта {uri}")
|
|
36
|
+
if not path.is_file():
|
|
37
|
+
raise Refused(f"ресурсы: нет файла {uri}")
|
|
38
|
+
data = path.read_bytes()
|
|
39
|
+
if "sha256:" + hashlib.sha256(data).hexdigest() != entry["sha256"]:
|
|
40
|
+
raise Refused(f"ресурсы: неверный хэш {uri}")
|
|
41
|
+
resources[uri] = data
|
|
42
|
+
return resources
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def corpus_resources(documents: list[dict], root: Path) -> dict[str, bytes]:
|
|
46
|
+
"""Read only declared artifact resources beneath an explicitly selected root."""
|
|
47
|
+
root = Path(root).resolve()
|
|
48
|
+
resources = {}
|
|
49
|
+
for document in documents:
|
|
50
|
+
for node in document.get("nodes", []):
|
|
51
|
+
uri = node.get("resourceUri", "")
|
|
52
|
+
if node.get("kind") != "calendar_snapshot" or not isinstance(uri, str) or not uri.startswith("artifact:"):
|
|
53
|
+
continue
|
|
54
|
+
path = (root / uri[len("artifact:"):]).resolve()
|
|
55
|
+
if not path.is_relative_to(root):
|
|
56
|
+
raise Refused("resource artifact escapes explicit corpus root")
|
|
57
|
+
if path.is_file():
|
|
58
|
+
resources[uri] = path.read_bytes()
|
|
59
|
+
return resources
|