11"""The vendored, typed_ast-free scalpel slice: it must import and compute SSA
22with no external scalpel / typed_ast / graphviz, and never pull in typeinfer."""
3+ import ast
34import sys
45
6+ import pytest
7+
58
69def test_vendored_scalpel_imports_and_computes_ssa_typed_ast_free ():
710 # No external scalpel shadowing the vendored copy.
@@ -25,9 +28,6 @@ def test_vendored_scalpel_imports_and_computes_ssa_typed_ast_free():
2528 assert not any ("typeinfer" in m for m in loaded ), f"typeinfer leaked: { loaded } "
2629
2730
28- import ast
29-
30-
3131def test_make_alias_oracle_defaults_to_scalpel_without_typed_ast ():
3232 import sys
3333 assert "typed_ast" not in sys .modules
@@ -51,3 +51,34 @@ def test_make_alias_oracle_is_deterministic():
5151 o2 = make_alias_oracle (None , _ast .parse (src ).body [0 ], {})
5252 pairs = [("a" , "b" ), ("b" , "c" ), ("a" , "c" ), ("b" , "b" )]
5353 assert [o1 .may_alias (x , y ) for x , y in pairs ] == [o2 .may_alias (x , y ) for x , y in pairs ]
54+
55+
56+ def _pip_scalpel_available ():
57+ try :
58+ import importlib .util
59+ # the EXTERNAL package, not our vendored copy
60+ return importlib .util .find_spec ("scalpel" ) is not None and \
61+ not importlib .util .find_spec ("scalpel" ).origin .endswith (
62+ "codeanalyzer/dataflow/scalpel/__init__.py" )
63+ except Exception :
64+ return False
65+
66+
67+ @pytest .mark .skipif (not _pip_scalpel_available (),
68+ reason = "upstream python-scalpel not installed (3.12+ can't build typed_ast)" )
69+ def test_vendored_ssa_matches_upstream ():
70+ """On a Python where pip python-scalpel installs (<=3.11), the vendored copy
71+ must produce identical SSA const_dict keys as upstream on the same source."""
72+ import scalpel .SSA .const as up_ssa
73+ import scalpel .cfg as up_cfg
74+ from codeanalyzer .dataflow .scalpel .SSA .const import SSA as VSSA
75+ from codeanalyzer .dataflow .scalpel .cfg import CFGBuilder as VCFG
76+
77+ src = "def f(a):\n b = a\n if a:\n b = 2\n return b\n "
78+ up_c = up_cfg .CFGBuilder ().build_from_src ("m" , src )
79+ v_c = VCFG ().build_from_src ("m" , src )
80+ up_fn = list (up_c .functioncfgs .values ())[0 ]
81+ v_fn = list (v_c .functioncfgs .values ())[0 ]
82+ _ , up_const = up_ssa .SSA ().compute_SSA (up_fn )
83+ _ , v_const = VSSA ().compute_SSA (v_fn )
84+ assert sorted (map (str , up_const )) == sorted (map (str , v_const ))
0 commit comments