1#[derive(Clone, Copy, Debug, Eq, PartialEq)]
5pub struct PythonFidelity {
6 pub syntax: &'static str,
8 pub lowering: &'static str,
10 pub direct_evaluation: &'static str,
12 pub object_control: &'static str,
14 pub module_library: &'static str,
16 pub boundedness: &'static str,
18 pub expected_gaps: &'static [&'static str],
20}
21
22#[derive(Clone, Copy, Debug, Eq, PartialEq)]
24pub struct PythonEvidenceCase {
25 pub name: &'static str,
27 pub dimension: &'static str,
29 pub source: &'static str,
31 pub expected: &'static str,
33 pub external_oracle: bool,
35}
36
37pub const PYTHON_EXTERNAL_ORACLE: &str = "CPython 3.14.6 (offline expected-value oracle only)";
40
41pub const PYTHON_FIDELITY: PythonFidelity = PythonFidelity {
43 syntax: "bounded lossless Python 3.14.6 concrete syntax; admission is not execution support",
44 lowering: "stable python/module, python/statement, and python/token expressions",
45 direct_evaluation: "bounded tree-walking scalar expressions and assignments over lowered forms",
46 object_control: "checked classes/descriptors, exceptions, generators, matching, and managed cycles through shared organs",
47 module_library: "matrix-listed core plus caller-supplied Dir imports; no pip, host path, or ambient standard library",
48 boundedness: "codec budgets, evaluator step limits, managed-heap limits, and explicit capabilities",
49 expected_gaps: &[
50 "not a CPython replacement",
51 "no bytecode, compiler IR, optimizer, or foreign VM",
52 "no asyncio event loop, pip, ambient IO, or host import search",
53 "syntax coverage does not imply direct-evaluation coverage",
54 ],
55};
56
57pub const PYTHON_EVIDENCE_CASES: &[PythonEvidenceCase] = &[
59 PythonEvidenceCase {
60 name: "call",
61 dimension: "direct-evaluation",
62 source: "f = lambda x: x + 2\nf(40)\n",
63 expected: "42",
64 external_oracle: true,
65 },
66 PythonEvidenceCase {
67 name: "cyclic-value",
68 dimension: "object/control",
69 source: "value = []\nvalue.append(value)\nvalue is value[0]\n",
70 expected: "true; shared bounded heap",
71 external_oracle: true,
72 },
73 PythonEvidenceCase {
74 name: "exception",
75 dimension: "object/control",
76 source: "try:\n raise ValueError('x')\nexcept ValueError:\n answer = 42\n",
77 expected: "42",
78 external_oracle: true,
79 },
80 PythonEvidenceCase {
81 name: "generator",
82 dimension: "object/control",
83 source: "def g():\n yield 40\n yield 2\nsum(g())\n",
84 expected: "42",
85 external_oracle: true,
86 },
87 PythonEvidenceCase {
88 name: "matching",
89 dimension: "object/control",
90 source: "match [40, 2]:\n case [a, b]: answer = a + b\n",
91 expected: "42",
92 external_oracle: true,
93 },
94 PythonEvidenceCase {
95 name: "supplied-import",
96 dimension: "module/library",
97 source: "from supplied import answer\nanswer\n",
98 expected: "42 from caller-supplied Dir only",
99 external_oracle: false,
100 },
101 PythonEvidenceCase {
102 name: "ambient-import-refusal",
103 dimension: "module/library",
104 source: "import os\n",
105 expected: "refused without a supplied module root",
106 external_oracle: false,
107 },
108 PythonEvidenceCase {
109 name: "eval-capability-refusal",
110 dimension: "boundedness",
111 source: "eval('40 + 2')\n",
112 expected: "refused without read-eval and diminished capabilities",
113 external_oracle: false,
114 },
115 PythonEvidenceCase {
116 name: "exec-capability-refusal",
117 dimension: "boundedness",
118 source: "exec('answer = 42')\n",
119 expected: "refused without read-eval and diminished capabilities",
120 external_oracle: false,
121 },
122];
123
124#[cfg(test)]
125mod tests {
126 use super::*;
127 use std::{collections::BTreeSet, fs, path::Path};
128
129 #[test]
130 fn evidence_covers_every_required_regression_family() {
131 let names = PYTHON_EVIDENCE_CASES
132 .iter()
133 .map(|case| case.name)
134 .collect::<BTreeSet<_>>();
135 for required in [
136 "call",
137 "cyclic-value",
138 "exception",
139 "generator",
140 "matching",
141 "supplied-import",
142 "ambient-import-refusal",
143 "eval-capability-refusal",
144 "exec-capability-refusal",
145 ] {
146 assert!(
147 names.contains(required),
148 "missing Python evidence case {required}"
149 );
150 }
151 assert!(
152 PYTHON_EVIDENCE_CASES
153 .iter()
154 .any(|case| case.external_oracle)
155 );
156 assert!(
157 PYTHON_EVIDENCE_CASES
158 .iter()
159 .any(|case| !case.external_oracle)
160 );
161 }
162
163 #[test]
164 fn crate_has_no_foreign_python_or_compiler_dependency_or_artifact() {
165 let root = Path::new(env!("CARGO_MANIFEST_DIR"));
166 let manifest = fs::read_to_string(root.join("Cargo.toml"))
167 .unwrap()
168 .to_ascii_lowercase();
169 for forbidden in ["pyo3", "cpython =", "python3-sys", "python27-sys"] {
170 assert!(
171 !manifest.contains(forbidden),
172 "foreign Python dependency {forbidden}"
173 );
174 }
175 fn scan(path: &Path) {
176 for entry in fs::read_dir(path).unwrap() {
177 let path = entry.unwrap().path();
178 if path.is_dir() {
179 scan(&path);
180 continue;
181 }
182 let extension = path
183 .extension()
184 .and_then(|value| value.to_str())
185 .unwrap_or("");
186 assert!(
187 !matches!(extension, "pyc" | "pyo" | "pickle"),
188 "foreign Python artifact {}",
189 path.display()
190 );
191 }
192 }
193 scan(root);
194 let runtime = fs::read_to_string(root.join("src/runtime.rs")).unwrap();
195 for forbidden in [
196 "Py_CompileString",
197 "PyEval_",
198 "Command::new(\"python\"",
199 "Command::new(\"python3\"",
200 ] {
201 assert!(
202 !runtime.contains(forbidden),
203 "compiler/VM fallback marker {forbidden}"
204 );
205 }
206 }
207}