@@ -171,127 +171,59 @@ def discover_tests(
171171 # === Code Analysis ===
172172
173173 def extract_code_context (self , function : FunctionToOptimize , project_root : Path , module_root : Path ) -> CodeContext :
174- """Extract function code and its dependencies.
174+ """Extract function code and its dependencies via the canonical context pipeline."""
175+ from codeflash .languages .python .context .code_context_extractor import get_code_optimization_context
175176
176- Uses jedi and libcst for Python code analysis.
177-
178- Args:
179- function: The function to extract context for.
180- project_root: Root of the project.
181- module_root: Root of the module containing the function.
182-
183- Returns:
184- CodeContext with target code and dependencies.
185-
186- """
187177 try :
188- source = function . file_path . read_text ( )
178+ result = get_code_optimization_context ( function , project_root )
189179 except Exception as e :
190- logger .exception ("Failed to read %s: %s" , function .file_path , e )
180+ logger .warning ("Failed to extract code context for %s: %s" , function .function_name , e )
191181 return CodeContext (target_code = "" , target_file = function .file_path , language = Language .PYTHON )
192182
193- # Extract the function source
194- lines = source .splitlines (keepends = True )
195- if function .starting_line and function .ending_line :
196- target_lines = lines [function .starting_line - 1 : function .ending_line ]
197- target_code = "" .join (target_lines )
198- else :
199- target_code = ""
200-
201- # Find helper functions
202- helpers = self .find_helper_functions (function , project_root )
203-
204- # Extract imports
205- import_lines = []
206- for line in lines :
207- stripped = line .strip ()
208- if stripped .startswith (("import " , "from " )):
209- import_lines .append (stripped )
210- elif stripped and not stripped .startswith ("#" ):
211- # Stop at first non-import, non-comment line
212- break
183+ helpers = [
184+ HelperFunction (
185+ name = fs .only_function_name ,
186+ qualified_name = fs .qualified_name ,
187+ file_path = fs .file_path ,
188+ source_code = fs .source_code ,
189+ start_line = fs .jedi_definition .line if fs .jedi_definition else 1 ,
190+ end_line = fs .jedi_definition .line if fs .jedi_definition else 1 ,
191+ )
192+ for fs in result .helper_functions
193+ ]
213194
214195 return CodeContext (
215- target_code = target_code ,
196+ target_code = result . read_writable_code . markdown ,
216197 target_file = function .file_path ,
217198 helper_functions = helpers ,
218- read_only_context = "" ,
219- imports = import_lines ,
199+ read_only_context = result . read_only_context_code ,
200+ imports = [] ,
220201 language = Language .PYTHON ,
221202 )
222203
223204 def find_helper_functions (self , function : FunctionToOptimize , project_root : Path ) -> list [HelperFunction ]:
224- """Find helper functions called by the target function.
225-
226- Uses jedi for Python code analysis.
227-
228- Args:
229- function: The target function to analyze.
230- project_root: Root of the project.
231-
232- Returns:
233- List of HelperFunction objects.
234-
235- """
236- helpers : list [HelperFunction ] = []
205+ """Find helper functions called by the target function via the canonical jedi pipeline."""
206+ from codeflash .languages .python .context .code_context_extractor import get_function_sources_from_jedi
237207
238208 try :
239- import jedi
240-
241- from codeflash .code_utils .code_utils import get_qualified_name , path_belongs_to_site_packages
242- from codeflash .optimization .function_context import belongs_to_function_qualified
243-
244- script = jedi .Script (path = function .file_path , project = jedi .Project (path = project_root ))
245- file_refs = script .get_names (all_scopes = True , definitions = False , references = True )
246-
247- qualified_name = function .qualified_name
248-
249- for ref in file_refs :
250- if not ref .full_name or not belongs_to_function_qualified (ref , qualified_name ):
251- continue
252-
253- try :
254- definitions = ref .goto (follow_imports = True , follow_builtin_imports = False )
255- except Exception :
256- continue
257-
258- for definition in definitions :
259- definition_path = definition .module_path
260- if definition_path is None :
261- continue
262-
263- # Check if it's a valid helper (in project, not in target function)
264- is_valid = (
265- str (definition_path ).startswith (str (project_root ))
266- and not path_belongs_to_site_packages (definition_path )
267- and definition .full_name
268- and not belongs_to_function_qualified (definition , qualified_name )
269- and definition .type == "function"
270- )
271-
272- if is_valid :
273- helper_qualified_name = get_qualified_name (definition .module_name , definition .full_name )
274- # Get source code
275- try :
276- helper_source = definition .get_line_code ()
277- except Exception :
278- helper_source = ""
279-
280- helpers .append (
281- HelperFunction (
282- name = definition .name ,
283- qualified_name = helper_qualified_name ,
284- file_path = definition_path ,
285- source_code = helper_source ,
286- start_line = definition .line or 1 ,
287- end_line = definition .line or 1 ,
288- )
289- )
290-
209+ _dict , sources = get_function_sources_from_jedi (
210+ {function .file_path : {function .qualified_name }}, project_root
211+ )
291212 except Exception as e :
292213 logger .warning ("Failed to find helpers for %s: %s" , function .function_name , e )
214+ return []
293215
294- return helpers
216+ return [
217+ HelperFunction (
218+ name = fs .only_function_name ,
219+ qualified_name = fs .qualified_name ,
220+ file_path = fs .file_path ,
221+ source_code = fs .source_code ,
222+ start_line = fs .jedi_definition .line if fs .jedi_definition else 1 ,
223+ end_line = fs .jedi_definition .line if fs .jedi_definition else 1 ,
224+ )
225+ for fs in sources
226+ ]
295227
296228 def find_references (
297229 self , function : FunctionToOptimize , project_root : Path , tests_root : Path | None = None , max_files : int = 500
0 commit comments