From b59882e1fbf70b602da1046f83d93776dd32033a Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Wed, 4 Feb 2026 16:48:15 +0000 Subject: [PATCH 1/4] prevent pytest fail with non unicode chars --- codeflash/code_utils/shell_utils.py | 4 ++++ codeflash/languages/javascript/find_references.py | 4 ++-- codeflash/languages/javascript/parse.py | 7 +------ codeflash/languages/javascript/vitest_runner.py | 3 +-- codeflash/languages/treesitter_utils.py | 4 ++-- codeflash/optimization/function_optimizer.py | 6 +++--- codeflash/verification/parse_test_output.py | 8 +++----- 7 files changed, 16 insertions(+), 20 deletions(-) diff --git a/codeflash/code_utils/shell_utils.py b/codeflash/code_utils/shell_utils.py index df2cff2d6..61dc9f2fd 100644 --- a/codeflash/code_utils/shell_utils.py +++ b/codeflash/code_utils/shell_utils.py @@ -247,6 +247,10 @@ def get_cross_platform_subprocess_run_args( capture_output: bool = True, ) -> dict[str, str]: run_args = {"cwd": cwd, "env": env, "text": text, "timeout": timeout, "check": check} + # When text=True, use errors='replace' to handle non-UTF-8 bytes gracefully + # instead of raising UnicodeDecodeError + if text: + run_args["errors"] = "replace" if sys.platform == "win32": creationflags = subprocess.CREATE_NEW_PROCESS_GROUP run_args["creationflags"] = creationflags diff --git a/codeflash/languages/javascript/find_references.py b/codeflash/languages/javascript/find_references.py index 16b93cfca..3b48761dd 100644 --- a/codeflash/languages/javascript/find_references.py +++ b/codeflash/languages/javascript/find_references.py @@ -213,7 +213,7 @@ def find_references( trigger_check = True if import_info: context.visited_files.add(file_path) - import_name, original_import = import_info + import_name, original_import = import_info # noqa: RUF059 file_refs = self._find_references_in_file( file_path, file_code, reexport_name, import_name, file_analyzer, include_self=True ) @@ -404,7 +404,7 @@ def _find_identifier_references( name_node = node.child_by_field_name("name") if name_node: new_current_function = source_bytes[name_node.start_byte : name_node.end_byte].decode("utf8") - elif node.type in ("variable_declarator",): + elif node.type in ("variable_declarator",): # noqa: FURB171 # Arrow function or function expression assigned to variable name_node = node.child_by_field_name("name") value_node = node.child_by_field_name("value") diff --git a/codeflash/languages/javascript/parse.py b/codeflash/languages/javascript/parse.py index bc24013d9..d6b43feae 100644 --- a/codeflash/languages/javascript/parse.py +++ b/codeflash/languages/javascript/parse.py @@ -16,12 +16,7 @@ from junitparser.xunit2 import JUnitXml from codeflash.cli_cmds.console import logger -from codeflash.models.models import ( - FunctionTestInvocation, - InvocationId, - TestResults, - TestType, -) +from codeflash.models.models import FunctionTestInvocation, InvocationId, TestResults, TestType if TYPE_CHECKING: import subprocess diff --git a/codeflash/languages/javascript/vitest_runner.py b/codeflash/languages/javascript/vitest_runner.py index a5f6552d3..f622d7384 100644 --- a/codeflash/languages/javascript/vitest_runner.py +++ b/codeflash/languages/javascript/vitest_runner.py @@ -288,8 +288,7 @@ def run_vitest_behavioral_tests( logger.debug(f"Vitest JUnit XML created: {result_file_path} ({file_size} bytes)") if file_size < 200: # Suspiciously small - likely empty or just headers logger.warning( - f"Vitest JUnit XML is very small ({file_size} bytes). " - f"Content: {result_file_path.read_text()[:500]}" + f"Vitest JUnit XML is very small ({file_size} bytes). Content: {result_file_path.read_text()[:500]}" ) else: logger.warning( diff --git a/codeflash/languages/treesitter_utils.py b/codeflash/languages/treesitter_utils.py index f4b7ead43..8125161c1 100644 --- a/codeflash/languages/treesitter_utils.py +++ b/codeflash/languages/treesitter_utils.py @@ -1580,9 +1580,9 @@ def get_analyzer_for_file(file_path: Path) -> TreeSitterAnalyzer: """ suffix = file_path.suffix.lower() - if suffix in (".ts",): + if suffix in (".ts",): # noqa: FURB171 return TreeSitterAnalyzer(TreeSitterLanguage.TYPESCRIPT) - if suffix in (".tsx",): + if suffix in (".tsx",): # noqa: FURB171 return TreeSitterAnalyzer(TreeSitterLanguage.TSX) # Default to JavaScript for .js, .jsx, .mjs, .cjs return TreeSitterAnalyzer(TreeSitterLanguage.JAVASCRIPT) diff --git a/codeflash/optimization/function_optimizer.py b/codeflash/optimization/function_optimizer.py index ad39557c1..89b19d02c 100644 --- a/codeflash/optimization/function_optimizer.py +++ b/codeflash/optimization/function_optimizer.py @@ -315,7 +315,7 @@ def _handle_empty_queue(self) -> CandidateNode | None: self.future_all_code_repair, "Repairing {0} candidates", "Added {0} candidates from repair, total candidates now: {1}", - lambda: self.future_all_code_repair.clear(), + lambda: self.future_all_code_repair.clear(), # noqa: PLW0108 ) if self.line_profiler_done and not self.refinement_done: return self._process_candidates( @@ -330,7 +330,7 @@ def _handle_empty_queue(self) -> CandidateNode | None: self.future_adaptive_optimizations, "Applying adaptive optimizations to {0} candidates", "Added {0} candidates from adaptive optimization, total candidates now: {1}", - lambda: self.future_adaptive_optimizations.clear(), + lambda: self.future_adaptive_optimizations.clear(), # noqa: PLW0108 ) return None # All done @@ -2093,7 +2093,7 @@ def process_review( formatted_generated_test = format_generated_code(concolic_test_str, self.args.formatter_cmds) generated_tests_str += f"```{code_lang}\n{formatted_generated_test}\n```\n\n" - existing_tests, replay_tests, concolic_tests = existing_tests_source_for( + existing_tests, replay_tests, concolic_tests = existing_tests_source_for( # noqa: RUF059 self.function_to_optimize.qualified_name_with_modules_from_root(self.project_root), function_to_all_tests, test_cfg=self.test_cfg, diff --git a/codeflash/verification/parse_test_output.py b/codeflash/verification/parse_test_output.py index c80a287e5..4c2c809eb 100644 --- a/codeflash/verification/parse_test_output.py +++ b/codeflash/verification/parse_test_output.py @@ -1,6 +1,5 @@ from __future__ import annotations -import contextlib import os import re import sqlite3 @@ -22,6 +21,9 @@ ) from codeflash.discovery.discover_unit_tests import discover_parameters_unittest from codeflash.languages import is_javascript + +# Import Jest-specific parsing from the JavaScript language module +from codeflash.languages.javascript.parse import parse_jest_test_xml as _parse_jest_test_xml from codeflash.models.models import ( ConcurrencyMetrics, FunctionTestInvocation, @@ -32,10 +34,6 @@ ) from codeflash.verification.coverage_utils import CoverageUtils, JestCoverageUtils -# Import Jest-specific parsing from the JavaScript language module -from codeflash.languages.javascript.parse import jest_end_pattern, jest_start_pattern -from codeflash.languages.javascript.parse import parse_jest_test_xml as _parse_jest_test_xml - if TYPE_CHECKING: import subprocess From 8be10e24ba7e8ca54e7f68791ce3cd2728d36f77 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 17:01:46 +0000 Subject: [PATCH 2/4] fix: re-export jest patterns for backward compatibility --- codeflash/verification/parse_test_output.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/codeflash/verification/parse_test_output.py b/codeflash/verification/parse_test_output.py index 4c2c809eb..bd6511334 100644 --- a/codeflash/verification/parse_test_output.py +++ b/codeflash/verification/parse_test_output.py @@ -23,7 +23,11 @@ from codeflash.languages import is_javascript # Import Jest-specific parsing from the JavaScript language module -from codeflash.languages.javascript.parse import parse_jest_test_xml as _parse_jest_test_xml +from codeflash.languages.javascript.parse import ( + jest_end_pattern, + jest_start_pattern, + parse_jest_test_xml as _parse_jest_test_xml, +) from codeflash.models.models import ( ConcurrencyMetrics, FunctionTestInvocation, From 1a0bb05bb85179c6063b7de48c0eb06a80ce75a2 Mon Sep 17 00:00:00 2001 From: aseembits93 Date: Wed, 4 Feb 2026 09:19:47 -0800 Subject: [PATCH 3/4] undo non relevant changes --- codeflash/verification/parse_test_output.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/codeflash/verification/parse_test_output.py b/codeflash/verification/parse_test_output.py index bd6511334..c80a287e5 100644 --- a/codeflash/verification/parse_test_output.py +++ b/codeflash/verification/parse_test_output.py @@ -1,5 +1,6 @@ from __future__ import annotations +import contextlib import os import re import sqlite3 @@ -21,13 +22,6 @@ ) from codeflash.discovery.discover_unit_tests import discover_parameters_unittest from codeflash.languages import is_javascript - -# Import Jest-specific parsing from the JavaScript language module -from codeflash.languages.javascript.parse import ( - jest_end_pattern, - jest_start_pattern, - parse_jest_test_xml as _parse_jest_test_xml, -) from codeflash.models.models import ( ConcurrencyMetrics, FunctionTestInvocation, @@ -38,6 +32,10 @@ ) from codeflash.verification.coverage_utils import CoverageUtils, JestCoverageUtils +# Import Jest-specific parsing from the JavaScript language module +from codeflash.languages.javascript.parse import jest_end_pattern, jest_start_pattern +from codeflash.languages.javascript.parse import parse_jest_test_xml as _parse_jest_test_xml + if TYPE_CHECKING: import subprocess From ff4c36599ba33e0bba7a30946c0f9dc491629c37 Mon Sep 17 00:00:00 2001 From: aseembits93 Date: Wed, 4 Feb 2026 10:13:11 -0800 Subject: [PATCH 4/4] mypy fix --- codeflash/github/PrComment.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/codeflash/github/PrComment.py b/codeflash/github/PrComment.py index 7416329bb..7ea94ba93 100644 --- a/codeflash/github/PrComment.py +++ b/codeflash/github/PrComment.py @@ -31,7 +31,7 @@ def to_json(self) -> dict[str, Union[str, int, dict[str, dict[str, int]], list[B if name: report_table[name] = result - result: dict[str, Union[str, int, dict[str, dict[str, int]], list[BenchmarkDetail], None]] = { + result: dict[str, Union[str, int, dict[str, dict[str, int]], list[BenchmarkDetail], None]] = { # type: ignore[no-redef] "optimization_explanation": self.optimization_explanation, "best_runtime": humanize_runtime(self.best_runtime), "original_runtime": humanize_runtime(self.original_runtime), @@ -45,10 +45,10 @@ def to_json(self) -> dict[str, Union[str, int, dict[str, dict[str, int]], list[B } if self.original_async_throughput is not None and self.best_async_throughput is not None: - result["original_async_throughput"] = str(self.original_async_throughput) - result["best_async_throughput"] = str(self.best_async_throughput) + result["original_async_throughput"] = str(self.original_async_throughput) # type: ignore[assignment] + result["best_async_throughput"] = str(self.best_async_throughput) # type: ignore[assignment] - return result + return result # type: ignore[return-value] class FileDiffContent(BaseModel):