Deep audit fixes: consolidate macros, harden C-API bridging, fix Python version hardcoding, add CI & tests - #3
Merged
Conversation
Copilot created this pull request from a session on behalf of
jagtesh
July 3, 2026 23:51
View session
jagtesh
marked this pull request as ready for review
July 3, 2026 23:53
jagtesh
reviewed
Jul 3, 2026
| /// This avoids hardcoding a single Python version that may not be | ||
| /// installed on the host machine. | ||
| private func detectPythonExecutable() throws -> String { | ||
| let candidates = ["python3", "python3.13", "python3.12", "python3.11", "python3.10", "python3.9"] |
Owner
There was a problem hiding this comment.
Add the newer python versions, 3.14 and 3.15
Contributor
Author
There was a problem hiding this comment.
Added python3.14 and python3.15 to the probe list in e28b19b.
Contributor
Author
jagtesh
approved these changes
Jul 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The ApplePy deep audit flagged critical and high-severity bugs across the macro implementations and CPython bridging layer: a stale duplicate macro target, hardcoded
python3.13that breaks the build on any other version, unchecked C-API return values that silently corrupt collections, force-unwraps that crash the interpreter, and zero CI/test coverage for most macros. This PR addresses the critical/high findings and several medium ones.Macro consolidation
Sources/ApplePyMacroCore— a stale duplicate ofSources/ApplePyMacrosthat had drifted (different error handling) and was never referenced inPackage.swift.ApplePyMacrosis now the single source of truth.Python version hardcoding
module.modulemaphardcodedlink "python3.13", breaking any install without that exact version. SwitchedApplePyFFI's pkg-config module topython3-embed(correct for an embedding host process) and dropped the hardcoded link.ApplePyBundleplugin now probespython3,python3.13...python3.9instead of assumingpython3is on PATH.Examples/*/build.sh) had the same hardcoded version plus a macOS-only linker flag; fixed both and verified the examples build/run on Linux.C-API bridging hardening
Collections.swift: check return codes onPyList_SetItem,PyDict_SetItem,PySet_Add,PyTuple_SetItem, and*_Size()instead of ignoring failures.PyErr_Occurred()checks afterPyIter_Next/PyDict_Nextloops — both APIs return NULL/0 for "done" and "errored", so a real exception mid-iteration was being silently swallowed.swiftPtrin generated_getSwiftValueandPyBridge.load/loadBoxwithnil-returning failure paths instead of crashing the whole interpreter on a corrupted Swift/Python pairing.PyEnumMacro-generated registration code on failure paths (e.g.baseBases/variantClassleaked when a later step failed).Macro-time diagnostics
@PyFunctionnow rejectsasyncfunctions, generic functions, andinoutparameters instead of silently generating broken wrappers.@PyClassrejects generic structs/classes.@PyPropertyrejects computed properties.@PyEnumvalidates case names and parameter labels are valid, non-keyword Python identifiers (previously a param named e.g.classwould generate syntactically invalid Python via raw string interpolation).@PyModulenow reuses the correctMETH_NOARGS/METH_VARARGSflag computed by@PyFunctionper function, instead of hardcodingMETH_VARARGSfor every function regardless of arity.CI and testing
swift testGitHub Actions workflow (macOS + Linux matrix) — previously only a docs-publishing workflow existed.assertMacroExpansion(fromSwiftSyntaxMacrosTestSupport) reports failures viaXCTFail, which is silently swallowed when called from Swift Testing@Testfunctions — every macro-expansion test was passing regardless of actual output. Switched to the framework-agnosticSwiftSyntaxMacrosGenericTestSupportAPI with a custom failure handler wired toIssue.record, so these tests now genuinely validate expansion. This surfaced a real bug in@PyUnion(emitting broken empty conformance extensions when misapplied to a non-enum), now fixed.Set<T>,PyTuple2,PyTuple3, bytes/bytearray conversion, and the new macro diagnostics (18 → 36 tests).Other medium-priority fixes
@unchecked Sendablesafety invariant (GIL-serialized access) onPyObjectBoxandPyExceptionType.BufferBridge.bytesFromPythonnow type-checks withPyBytes_Check/PyByteArray_Checkbefore extracting (also adds previously-unsupportedbytearrayhandling) and guards negative size results.Int64→Inttruncation inPrimitives.swift; documentedFloat/Doubleprecision loss.swift-syntaxto600.0.0..<700.0.0instead of an open-endedfrom:range; pinned GitHub Actions by SHA.Known gap (pre-existing, not introduced here)
@PyClassdoesn't currently wire up codegen for@PyMethodinstance methods,@PyPropertygetters/setters, or@PyStaticMethod— these attributes validate correctly but aren't read by@PyClass's member generation. Flagging for a follow-up since it's a larger change than this audit pass.