Skip to content

Vendored typed_ast-free Scalpel slice as the default L4 alias oracle #113

Description

@rahlk

Tracking issue for the approved design "Vendored, typed_ast-free Scalpel as the default L4 oracle" (2026-07-22). Implemented on feat/vendor-scalpel-default-oracle.

Why

python-scalpel is the primary L4 may-alias oracle but hard-depends on typed_ast, abandoned at 1.5.5 with no wheel for Python 3.12+ and no source build on modern compilers. So on 3.12/3.13/3.14 the [scalpel] extra cannot install and L4 silently degrades to the coarser TypeBasedAliasOracle. Scalpel should be the shipping default everywhere.

Design (approved)

  • Vendor the exact 9-module closure the oracle loads — scalpel/__init__, SSA/{__init__,const}, cfg/{__init__,builder,model}, core/{__init__,func_call_visitor,vars_visitor} — verbatim from python-scalpel 1.0b0 (Apache-2.0, LICENSE copied, NOTICE entry added) as codeanalyzer/dataflow/scalpel/. typeinfer (the sole typed_ast importer) is deliberately excluded; verified the slice imports and computes SSA without typed_ast.
  • One patch only: cfg/model.py's module-load import graphviz becomes a lazy import inside the unused build_visual() — drops graphviz as a runtime dep. All analysis code paths byte-identical to upstream.
  • Dependencies: add astor>=0.8.1,<0.9 (runtime dep of SSA/const.py); remove the [project.optional-dependencies].scalpel extra; requires-python unchanged (>=3.9).
  • Oracle rewiring: ScalpelAliasOracle.from_function imports the vendored path; make_alias_oracle's ImportError branch is dead and removed. The per-callable build-failure and per-query unresolved-path fallbacks to TypeBasedAliasOracle stay — the total, never-raises may_alias contract is preserved; the type-based oracle is now a runtime safety net only.
  • Behavior change (intended): on 3.12+ (and anywhere the extra was absent) L4's prov:["points-to"] DDG edges become scalpel-precise instead of the type-based over-approximation. prov:["ssa"] is untouched, so the L3 ⊆ L4 monotonicity invariant holds. No schema change; no prov vocabulary change.
  • Tests: import-hygiene (no typeinfer/typed_ast/graphviz in sys.modules after oracle build), a typed_ast-free property gate, vendored-fidelity vs pip scalpel (skipif ≥3.12), the existing L4/SDG/defuse suites now exercising the scalpel path by default, and an L4 determinism run.
  • Rollback: single revert — delete the vendored package, restore the extra + ImportError branch, drop astor. No schema/id changes to unwind.

Out of scope: replacing astor.to_source with ast.unparse; a scalpel-installed CI lane; vendoring typeinfer.

Ships in 1.1.0 (minor: default L4 alias-oracle behavior change on 3.12+, [scalpel] extra removed).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions