Enables CodeFlash to use existing unit tests as both a source of function
invocations (for replay test generation) and as the performance baseline
(for end-to-end speedup reporting). Traces top-15 ranked functions via
unit tests, optimizes with high effort, and measures per-function speedup.
These files were unrelated to the PR and got swept in during a
stash/pop operation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Consolidate _parse_replay_metadata to call parse_replay_test_metadata
instead of duplicating the parsing logic
- Replace hardcoded fallback java command with a clear error message
when no java command is provided
- Filter empty strings from function_names split (\"".split(\",\")
returns [\"\"] which is truthy)
- Fix import ordering in tracer.py (ruff I001)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
get_git_diff now uses all registered extensions instead of filtering
by current language, so update tests to reflect the new behavior.
Co-authored-by: Sarthak Agarwal <undefined@users.noreply.github.com>
The optimization precomputes all frame-to-key conversions for a stack trace once (into a `keys` list) instead of calling `_frame_to_key` repeatedly inside the caller-callee loop, cutting per-frame extraction from ~3.3 µs to ~0.19 µs (83% reduction) and lifting `_frame_to_key` from 20.8% of total time to 43.2% (the loop cost is now dominated by the upfront list comprehension rather than repeated calls). A local `matches_packages_cached` closure memoizes package-filter results to avoid re-checking the same method keys across caller relationships, reducing `_matches_packages` overhead from 12.6% to 0.8% of total time; profiler data shows `_matches_packages` hits dropped from 18,364 to 1,500. The timestamp-duration calculation switched from accumulating a list then calling `max()`/`min()` to inline min/max tracking, removing intermediate allocations; combined, these changes yield a 42% overall speedup (46.4 ms → 32.6 ms).
- Import Language from codeflash.languages (exported) not codeflash.languages.base
- Fix _detect_non_python_language return type: object | None -> Language | None
- Fix bare dict type annotations: dict -> dict[str, Any] in jfr_parser.py and function_ranker.py
- Fix pytest_splits/test_paths type narrowing by separating assignment from None check
Co-authored-by: Saurabh Misra <undefined@users.noreply.github.com>
- Read --timeout from both config.timeout and config.tracer_timeout
- Handle multi-line /* */ block comments in package detection (aerospike
source files start with license block comments before package declaration)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The original code performed a linear scan over `self._ranking` on every call to `get_function_addressable_time`, which `rank_functions` invokes repeatedly (once per function to filter, plus once per function to sort). The optimized version builds a hash map `_ranking_by_name` during `__init__`, replacing the O(n) loop with an O(1) dictionary lookup. Line profiler confirms the loop and comparison accounted for 94.7% of original runtime. When `rank_functions` calls `get_function_addressable_time` dozens or hundreds of times across a 1000-method ranking (as in `test_large_number_of_methods_and_repeated_queries_perf_and_correctness`), the lookup cost drops from ~293 µs to ~10 µs per call, yielding the 1244% overall speedup. The optimization also consolidates the two calls to `get_addressable_time_ns` in `get_function_stats_summary` into a single call, stored in a local variable, eliminating redundant work.
- Unwrap logger.info call in tracer.py that fits within 120-char limit
- Revert auto-generated dev version string in version.py back to 0.20.3
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Git doesn't track empty directories, so src/test/java must be created
before process_pyproject_config validates tests-root exists.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use `uv run -m codeflash.main` instead of direct file path
- Remove redundant --no-pr (already hardcoded in _run_java_tracer)
- Clean up leftover replay tests between retry attempts
- Add error logging for subprocess output
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Triage now classifies PRs as TRIVIAL/SMALL/LARGE based on lines changed
- SMALL PRs: focused correctness check, quick duplicate scan, skip coverage
- LARGE PRs: full review with design checks, deep duplicate detection, coverage
- Optimization PRs: concise correctness verdict instead of long essays
- Added explicit scope rules: only read files in the diff, don't explore broadly
The conftest.py autouse fixture already resets _current_language before/after
each test, making per-test try/finally cleanup unnecessary.
Co-authored-by: Kevin Turcios <KRRT7@users.noreply.github.com>
test_parse_line_profile_results_non_python_java_json set Language.JAVA
but never reset it, causing test_java_diff_ignored_when_language_is_python
to fail when tests ran in this order.
Co-authored-by: Kevin Turcios <KRRT7@users.noreply.github.com>
The optimization eliminates redundant iterations through `node.body` by adding a `break` statement immediately after finding and decorating the `__init__` method (when `has_init=True`). The profiler shows the outer body loop dropped from 392 hits to 376 hits (~4% fewer), and the inner decorator-list loop dropped from 18 hits to 18 hits but now exits cleanly via `break` instead of continuing to scan remaining body items. Additionally, the `if not has_init:` branch now consolidates dataclass/attrs/NamedTuple checks in a single decorator loop instead of three separate passes, reducing `_expr_name` calls from 471 total hits to 263 (~44% fewer) and cutting that function's time from 391 µs to 218 µs. Runtime improved from 405 µs to 367 µs (10% faster) with no correctness regressions across all test cases.
The optimization pre-parses the `codeflash_capture` import statement once in `__init__` and stores it in `self._import_stmt`, eliminating the repeated `ast.parse` call inside `visit_Module`. Line profiler confirms the original code spent ~186 µs (1% of runtime) parsing the import on every module visit (11 hits × 16.9 µs each), which is now reduced to a one-time ~8 µs insertion cost. This reduces total `visit_Module` time by ~2.6% (17.87 ms → 17.41 ms) with no correctness trade-offs, preserving all AST structure and behavior across diverse test scenarios including large modules with 100+ classes.
- Fix bug: skip attrs classes with init=False (no __init__ to patch)
- Deduplicate attrs namespace/name sets into shared constants
- Fix _get_attrs_config to resolve import aliases properly
- Add test for init=False case with exact expected output
The optimization pre-allocates reusable AST node fragments in `__init__` (such as `ast.Load()`, `ast.Store()`, `ast.Name(id="self")`, and `ast.Starred`) that previously were reconstructed on every call to `_build_attrs_patch_block`. Because AST nodes are immutable value objects that Python interns, referencing the same instances avoids repeated allocation overhead—profiler data shows lines constructing `ast.Name`, `ast.arg`, and `ast.Starred` nodes dropped from ~1–3 µs each to ~0.1–0.4 µs. Across 2868 invocations (per profiler), this yields the observed 40% runtime reduction from 22.7 ms to 16.2 ms with no correctness regressions.
Instead of skipping attrs classes entirely (previous approach), emit a
module-level patch block immediately after the class definition:
_codeflash_orig_ClassName_init = ClassName.__init__
def _codeflash_patched_ClassName_init(self, *args, **kwargs):
return _codeflash_orig_ClassName_init(self, *args, **kwargs)
ClassName.__init__ = codeflash_capture(...)(_codeflash_patched_ClassName_init)
This sidesteps the __class__ cell TypeError that attrs(slots=True) triggers
when a synthetic super().__init__() body is injected into the original class,
because the patched wrapper is a plain module-level function with no __class__
cell.
Changes:
- InitDecorator.__init__: add _attrs_classes_to_patch dict
- visit_ClassDef: for attrs classes, record (name -> decorator) instead of
returning immediately; set inserted_decorator=True
- visit_Module: splice patch block statements after each attrs ClassDef
- _build_attrs_patch_block: new helper that builds the 3-statement AST block
- Tests: rename *_no_init_skipped -> *_patched_via_module_wrapper and update
expected strings to assert the exact generated patch block
Co-Authored-By: Oz <oz-agent@warp.dev>
- instrument_codeflash_capture: detect @attrs.define / @attr.s / etc. in the
'no explicit __init__' branch and return early, same as dataclass/NamedTuple.
Prevents a TypeError caused by attrs(slots=True) creating a new class whose
__class__ cell no longer matches the injected super().__init__ wrapper.
- code_context_extractor: add _get_attrs_config() helper; update
_collect_synthetic_constructor_type_names, _build_synthetic_init_stub, and
_extract_synthetic_init_parameters to handle attrs field conventions
(factory= keyword, init=False, kw_only).
- tests: add 3 exact-output tests for instrumentation skip behaviour and
3 exact-output tests for attrs stub generation.
Co-Authored-By: Oz <oz-agent@warp.dev>