Use self.default_file_extension in format_code and a treesitter_language
property in validate_syntax so TypeScriptSupport inherits both methods
from JavaScriptSupport instead of duplicating them.
Protocol methods with default bodies on a Protocol class are not
inherited by implementations. Add explicit detect_module_system and
adjust_test_config_for_discovery to PythonSupport.
Add JAVA enum value, is_java() helper, registry import guard, and Java
test frameworks (junit5/junit4/testng) as zero-behavior-change scaffolding.
Add 6 new LanguageSupport protocol methods/properties
(default_language_version, valid_test_frameworks,
test_result_serialization_format, load_coverage,
adjust_test_config_for_discovery, detect_module_system,
process_generated_test_strings) and implement them in PythonSupport and
JavaScriptSupport.
Replace 12 is_python()/is_javascript() guards across aiservice.py (5),
parse_test_output.py (4), verifier.py (2), and discover_unit_tests.py (1)
with protocol dispatch, moving ~40 lines of JS instrumentation logic from
verifier.py into JavaScriptSupport.
Also add imported_type_skeletons field to CodeContext and
JAVA_TESTCASE_TIMEOUT constant for upcoming Java support.
- Add JS optimizer, normalizer, and support files to architecture tree
- Update key entry points table for per-function optimization and test execution
- Add protocol dispatch preference to language-patterns rules
- Fix stale context path in optimization-patterns
- Add explicit utf-8 encoding rule scoped to new/changed code
- Update discover_functions calls to new (source, file_path) signature
- Use language-specific FunctionOptimizer subclasses in tests
- Add explicit utf-8 encoding to read_text()/write_text() for Windows
- Fix pytest fixture in TestTsJestSkipsConversion (was __init__)
- Update nonexistent file tests for source-based discover_functions
- Remove unused imports
- Extract JavaScriptFunctionOptimizer subclass with JS-specific overrides
for code context, candidate comparison, line profiling, and code replacement
- Replace is_python()/is_javascript() guards with LanguageSupport protocol
dispatch across optimizer, verification, and utility layers
- Move generate_concolic_tests into LanguageSupport (default no-op, Python
overrides with CrossHair)
- Collapse normalizer infrastructure: delete CodeNormalizer ABC and registry,
move implementations into language directories
- Unify discover_functions to source-based signature (source, file_path)
- Flatten function discovery indirection, making git-diff discovery work
for JS/TS
- Extract language-agnostic code replacer to languages/code_replacer.py
- Deduplicate error constants and function grouping logic into shared locations
- Restore pytest_cmd support in PythonSupport test runners
- Add empty-code guard in language-agnostic code replacer
- Fix tmpdir_path cleanup, self.args crash, UnboundLocalError in finally block
The return statement was outside the inner if-not block, causing all TestResults
(even populated ones) to return an empty dict.
Co-authored-by: Kevin Turcios <KRRT7@users.noreply.github.com>
Log "Discovered N existing unit test files" after counting tests, and
"Instrumented N existing unit test files" after injecting profiling.
Python E2E harness matches "Discovered", JS harness matches "Instrumented".
The refactoring changed the log message from 'Discovered' to 'Instrumented',
breaking the E2E test regex in end_to_end_test_utilities.py:225.
Co-authored-by: Kevin Turcios <KRRT7@users.noreply.github.com>
Add languages/python/function_optimizer.py and languages/python/optimizer.py
to the directory tree and Key Entry Points table.
Co-authored-by: Kevin Turcios <KRRT7@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add clarifying comment on shared replace_function_definitions_in_module import
- Remove misleading alias in test_unused_helper_revert.py, use PythonFunctionOptimizer directly
- Align base line_profiler_step return type to dict[str, Any]
- Fix latent bug: handle non-empty TestResults in line_profiler_step
The factory method was resolving the function AST from original_module_ast
before constructing PythonFunctionOptimizer, duplicating the _resolve_function_ast
hook. Now the hook handles resolution and the factory checks the result post-construction.
Replace 2 is_python() guard sites around coverage_critic() calls with a
should_check_coverage() hook, defaulting to False in the base class and
True in PythonFunctionOptimizer.
PythonSupport.instrument_existing_test() already delegates to
inject_profiling_into_existing_test(), so the base class handles
Python correctly through the language_support abstraction.
Move async decorator instrumentation (4 sites) and codeflash capture
instrumentation (2 sites) into overridable hooks. Base class no-ops;
PythonFunctionOptimizer provides the implementations.
Move the Python-specific test instrumentation branch (~80 lines using
inject_profiling_into_existing_test) to the subclass. Base class keeps
the JS/TS branch using language_support.instrument_existing_test as the
default.
- Base class keeps the language-routing replacement logic (used by both
Python and JS); Python subclass adds unused-helper revert on top via super()
- Tests that exercise Python-specific replace+revert use PythonFunctionOptimizer
- Move `ast` to TYPE_CHECKING in optimizer.py (fixes prek)
Move 6 Python-specific methods into PythonFunctionOptimizer in
languages/python/function_optimizer.py. Base class gets no-op defaults;
Optimizer.create_function_optimizer dispatches to the subclass when
is_python().
Handle itertools.cycle on Python 3.14 where __reduce__ was removed by
falling back to element-by-element sampling. Add version guards for
pairwise (3.10+) and batched (3.12+) tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a catch-all handler for itertools iterators (chain, islice, product,
permutations, combinations, starmap, accumulate, compress, dropwhile,
takewhile, filterfalse, zip_longest, groupby, pairwise, batched, tee).
Uses module check (type.__module__ == "itertools") so it automatically
covers any itertools type without version-specific enumeration. groupby
gets special handling to also materialize its group iterators.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
itertools.repeat uses repr() comparison (same approach as count).
itertools.cycle uses __reduce__() to extract internal state (saved items,
remaining items, and first-pass flag) since repr() only shows a memory
address. The __reduce__ approach is deprecated in 3.14 but is the only
way to access cycle state without consuming elements.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The comparator had no handler for itertools.count (an infinite iterator),
causing it to fall through all type checks and return False even for
equal objects. Use repr() comparison which reliably reflects internal
state and avoids the __reduce__ deprecation coming in Python 3.14.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Nested functions are now skipped by FunctionVisitor, and
discover_functions no longer swallows parse/IO errors — callers
handle them. Update test expectations accordingly.
Remove the AST-based discovery path for Python, routing all languages
through the unified CST-based `_find_all_functions_via_language_support`.
Delete dead code: `find_functions_with_return_statement`,
`_find_all_functions_in_python_file`, `function_has_return_statement`,
`function_is_a_property`, and associated constants. Fix FunctionVisitor
to skip nested functions and exclude @property/@cached_property, and let
parse errors propagate for correct empty-dict behavior on invalid files.
Keep file_name as a plain str throughout the per-call path. Path is only
constructed once per unique function in the first-time-seen branch where
filter_files_optimized and FunctionModules need it.
Replace per-call Path.is_relative_to() and Path.exists() (stat syscall)
with a single cached lookup per unique co_filename. Use os.path.realpath
and str.startswith instead of pathlib to avoid object allocation on the
hot path. Profile showed these pathlib ops at ~15% self-time.