()
| 140 | } |
| 141 | |
| 142 | async function validatePython(): Promise<ValidationResult[]> { |
| 143 | const results: ValidationResult[] = []; |
| 144 | const pyDir = path.join(VALIDATION_DIR, "python"); |
| 145 | const manifest = loadManifest(); |
| 146 | |
| 147 | if (!fs.existsSync(pyDir)) { |
| 148 | console.log(" No Python files to validate"); |
| 149 | return results; |
| 150 | } |
| 151 | |
| 152 | const files = await glob("*.py", { cwd: pyDir }); |
| 153 | |
| 154 | for (const file of files) { |
| 155 | const fullPath = path.join(pyDir, file); |
| 156 | const block = manifest.blocks.find( |
| 157 | (b) => b.outputFile === `python/${file}`, |
| 158 | ); |
| 159 | const errors: string[] = []; |
| 160 | |
| 161 | // Syntax check with py_compile |
| 162 | try { |
| 163 | execFileSync("python3", ["-m", "py_compile", fullPath], { |
| 164 | encoding: "utf-8", |
| 165 | }); |
| 166 | } catch (err: any) { |
| 167 | errors.push(err.stdout || err.stderr || err.message || "Syntax error"); |
| 168 | } |
| 169 | |
| 170 | // Type check with mypy (if available) |
| 171 | if (errors.length === 0) { |
| 172 | try { |
| 173 | execFileSync( |
| 174 | "python3", |
| 175 | [ |
| 176 | "-m", |
| 177 | "mypy", |
| 178 | fullPath, |
| 179 | "--ignore-missing-imports", |
| 180 | "--no-error-summary", |
| 181 | ], |
| 182 | { encoding: "utf-8" }, |
| 183 | ); |
| 184 | } catch (err: any) { |
| 185 | const output = err.stdout || err.stderr || err.message || ""; |
| 186 | // Filter out "Success" messages and notes |
| 187 | const typeErrors = output |
| 188 | .split("\n") |
| 189 | .filter( |
| 190 | (l: string) => |
| 191 | l.includes(": error:") && |
| 192 | !l.includes("Cannot find implementation"), |
| 193 | ); |
| 194 | if (typeErrors.length > 0) { |
| 195 | errors.push(...typeErrors); |
| 196 | } |
| 197 | } |
| 198 | } |
| 199 |
nothing calls this directly
no test coverage detected
searching dependent graphs…