From 5c3903ee86e6ca7d3905f4763ea2056c9a7db5c5 Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Mon, 19 May 2025 23:04:45 -0400 Subject: [PATCH 01/19] will exit the cli if user doesn't have the formatter installed while running codeflash AFTER init --- codeflash/main.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/codeflash/main.py b/codeflash/main.py index 02b13d5aa..e81301a38 100644 --- a/codeflash/main.py +++ b/codeflash/main.py @@ -1,8 +1,11 @@ """Thanks for being curious about how codeflash works! If you might want to work with us on finally making performance a solved problem, please reach out to us at careers@codeflash.ai. We're hiring! """ - +import subprocess from pathlib import Path +import sys + +import click from codeflash.cli_cmds.cli import parse_args, process_pyproject_config from codeflash.cli_cmds.cmd_init import CODEFLASH_LOGO, ask_run_end_to_end_test @@ -36,6 +39,14 @@ def main() -> None: ask_run_end_to_end_test(args) else: args = process_pyproject_config(args) + if args.formatter_cmds[0].startswith("black") or args.formatter_cmds[0].startswith("uv"): + formatter = args.formatter_cmds[0].split(" ")[0] + try: + subprocess.run([formatter], capture_output=True, check=False) + except (FileNotFoundError, NotADirectoryError): + click.echo(f"⚠️ Formatter not found: {formatter}, please ensure it is installed") + sys.exit(1) + args.previous_checkpoint_functions = ask_should_use_checkpoint_get_functions(args) init_sentry(not args.disable_telemetry, exclude_errors=True) posthog_cf.initialize_posthog(not args.disable_telemetry) From 3766ab422384589fb86d673fbbbcd6cb55c21aca Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Mon, 19 May 2025 23:15:39 -0400 Subject: [PATCH 02/19] moving things around --- codeflash/main.py | 12 ------------ codeflash/optimization/optimizer.py | 15 +++++++++++++-- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/codeflash/main.py b/codeflash/main.py index e81301a38..82bb44a07 100644 --- a/codeflash/main.py +++ b/codeflash/main.py @@ -1,11 +1,7 @@ """Thanks for being curious about how codeflash works! If you might want to work with us on finally making performance a solved problem, please reach out to us at careers@codeflash.ai. We're hiring! """ -import subprocess from pathlib import Path -import sys - -import click from codeflash.cli_cmds.cli import parse_args, process_pyproject_config from codeflash.cli_cmds.cmd_init import CODEFLASH_LOGO, ask_run_end_to_end_test @@ -39,14 +35,6 @@ def main() -> None: ask_run_end_to_end_test(args) else: args = process_pyproject_config(args) - if args.formatter_cmds[0].startswith("black") or args.formatter_cmds[0].startswith("uv"): - formatter = args.formatter_cmds[0].split(" ")[0] - try: - subprocess.run([formatter], capture_output=True, check=False) - except (FileNotFoundError, NotADirectoryError): - click.echo(f"⚠️ Formatter not found: {formatter}, please ensure it is installed") - sys.exit(1) - args.previous_checkpoint_functions = ask_should_use_checkpoint_get_functions(args) init_sentry(not args.disable_telemetry, exclude_errors=True) posthog_cf.initialize_posthog(not args.disable_telemetry) diff --git a/codeflash/optimization/optimizer.py b/codeflash/optimization/optimizer.py index de2cc1740..7e84a7c54 100644 --- a/codeflash/optimization/optimizer.py +++ b/codeflash/optimization/optimizer.py @@ -2,12 +2,15 @@ import ast import os +import sys import tempfile import time from collections import defaultdict from pathlib import Path from typing import TYPE_CHECKING +import click + from codeflash.api.aiservice import AiServiceClient, LocalAiServiceClient from codeflash.benchmarking.instrument_codeflash_trace import instrument_codeflash_trace_decorator from codeflash.benchmarking.plugin.plugin import CodeFlashBenchmarkPlugin @@ -18,14 +21,14 @@ from codeflash.code_utils import env_utils from codeflash.code_utils.checkpoint import CodeflashRunCheckpoint from codeflash.code_utils.code_replacer import normalize_code, normalize_node -from codeflash.code_utils.code_utils import cleanup_paths, get_run_tmp_file from codeflash.code_utils.static_analysis import analyze_imported_modules, get_first_top_level_function_or_method_ast from codeflash.discovery.discover_unit_tests import discover_unit_tests from codeflash.discovery.functions_to_optimize import get_functions_to_optimize from codeflash.either import is_successful -from codeflash.models.models import BenchmarkKey, TestType, ValidCode +from codeflash.models.models import BenchmarkKey, ValidCode from codeflash.optimization.function_optimizer import FunctionOptimizer from codeflash.telemetry.posthog_cf import ph +from codeflash.verification.test_runner import execute_test_subprocess from codeflash.verification.verification_utils import TestConfig if TYPE_CHECKING: @@ -77,6 +80,14 @@ def create_function_optimizer( ) def run(self) -> None: + if self.args.formatter_cmds[0].startswith("black") or self.args.formatter_cmds[0].startswith("uv"): + formatter = self.args.formatter_cmds[0].split(" ")[0] + try: + execute_test_subprocess([formatter]) + except (FileNotFoundError, NotADirectoryError): + click.echo(f"⚠️ Formatter not found: {formatter}, please ensure it is installed") + sys.exit(1) + ph("cli-optimize-run-start") logger.info("Running optimizer.") console.rule() From 022d59b507f7932a406718a88e2ce10411dc34cf Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Mon, 19 May 2025 23:16:54 -0400 Subject: [PATCH 03/19] typo --- codeflash/main.py | 1 + codeflash/optimization/optimizer.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/codeflash/main.py b/codeflash/main.py index 82bb44a07..02b13d5aa 100644 --- a/codeflash/main.py +++ b/codeflash/main.py @@ -1,6 +1,7 @@ """Thanks for being curious about how codeflash works! If you might want to work with us on finally making performance a solved problem, please reach out to us at careers@codeflash.ai. We're hiring! """ + from pathlib import Path from codeflash.cli_cmds.cli import parse_args, process_pyproject_config diff --git a/codeflash/optimization/optimizer.py b/codeflash/optimization/optimizer.py index 7e84a7c54..4bb580a8b 100644 --- a/codeflash/optimization/optimizer.py +++ b/codeflash/optimization/optimizer.py @@ -80,7 +80,7 @@ def create_function_optimizer( ) def run(self) -> None: - if self.args.formatter_cmds[0].startswith("black") or self.args.formatter_cmds[0].startswith("uv"): + if self.args.formatter_cmds[0].startswith("black") or self.args.formatter_cmds[0].startswith("ruff"): formatter = self.args.formatter_cmds[0].split(" ")[0] try: execute_test_subprocess([formatter]) From cf57fb1ca2adf7acaa6525b3133e127cea76cef5 Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Mon, 19 May 2025 23:18:17 -0400 Subject: [PATCH 04/19] ruff --- codeflash/optimization/function_optimizer.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/codeflash/optimization/function_optimizer.py b/codeflash/optimization/function_optimizer.py index 6d49e8546..6b9996e97 100644 --- a/codeflash/optimization/function_optimizer.py +++ b/codeflash/optimization/function_optimizer.py @@ -3,7 +3,6 @@ import ast import concurrent.futures import os -import shutil import subprocess import time import uuid @@ -405,7 +404,7 @@ def determine_best_candidate( future_line_profile_results = None try: candidate = candidates.popleft() - except IndexError as e: + except IndexError: if done: break continue From 4619f69ec23f17cb29b26fe22896436a7e1a2a82 Mon Sep 17 00:00:00 2001 From: Saurabh Misra Date: Mon, 19 May 2025 20:28:09 -0700 Subject: [PATCH 05/19] Update codeflash/optimization/optimizer.py --- codeflash/optimization/optimizer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codeflash/optimization/optimizer.py b/codeflash/optimization/optimizer.py index 4bb580a8b..381d2db34 100644 --- a/codeflash/optimization/optimizer.py +++ b/codeflash/optimization/optimizer.py @@ -85,7 +85,7 @@ def run(self) -> None: try: execute_test_subprocess([formatter]) except (FileNotFoundError, NotADirectoryError): - click.echo(f"⚠️ Formatter not found: {formatter}, please ensure it is installed") + click.echo(f"⚠️ Formatter not found: {formatter}, please ensure it is installed. Exiting...") sys.exit(1) ph("cli-optimize-run-start") From 1def2b4fa159ca3280e01e01dfc327de94477f60 Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Mon, 19 May 2025 23:38:58 -0400 Subject: [PATCH 06/19] refactoring --- codeflash/code_utils/env_utils.py | 14 ++++++++++++++ codeflash/optimization/optimizer.py | 9 +++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/codeflash/code_utils/env_utils.py b/codeflash/code_utils/env_utils.py index 9f303a4f6..d13413a40 100644 --- a/codeflash/code_utils/env_utils.py +++ b/codeflash/code_utils/env_utils.py @@ -2,9 +2,23 @@ from functools import lru_cache from typing import Optional +import click + from codeflash.cli_cmds.console import logger from codeflash.code_utils.shell_utils import read_api_key_from_shell_config +from codeflash.verification.test_runner import execute_test_subprocess + +def check_formatter_installed(formatter_cmds: list[str]) -> bool: + cmd_parts = formatter_cmds[0].split(" ") + if "black" in cmd_parts or "ruff" in cmd_parts: + formatter = cmd_parts[0] + try: + execute_test_subprocess([formatter]) + except (FileNotFoundError, NotADirectoryError): + click.echo(f"⚠️ Formatter not found: {formatter}, please ensure it is installed") + return False + return True @lru_cache(maxsize=1) def get_codeflash_api_key() -> str: diff --git a/codeflash/optimization/optimizer.py b/codeflash/optimization/optimizer.py index 381d2db34..e1d554fbb 100644 --- a/codeflash/optimization/optimizer.py +++ b/codeflash/optimization/optimizer.py @@ -2,15 +2,12 @@ import ast import os -import sys import tempfile import time from collections import defaultdict from pathlib import Path from typing import TYPE_CHECKING -import click - from codeflash.api.aiservice import AiServiceClient, LocalAiServiceClient from codeflash.benchmarking.instrument_codeflash_trace import instrument_codeflash_trace_decorator from codeflash.benchmarking.plugin.plugin import CodeFlashBenchmarkPlugin @@ -28,7 +25,6 @@ from codeflash.models.models import BenchmarkKey, ValidCode from codeflash.optimization.function_optimizer import FunctionOptimizer from codeflash.telemetry.posthog_cf import ph -from codeflash.verification.test_runner import execute_test_subprocess from codeflash.verification.verification_utils import TestConfig if TYPE_CHECKING: @@ -80,6 +76,7 @@ def create_function_optimizer( ) def run(self) -> None: +<<<<<<< Updated upstream if self.args.formatter_cmds[0].startswith("black") or self.args.formatter_cmds[0].startswith("ruff"): formatter = self.args.formatter_cmds[0].split(" ")[0] try: @@ -88,11 +85,15 @@ def run(self) -> None: click.echo(f"⚠️ Formatter not found: {formatter}, please ensure it is installed. Exiting...") sys.exit(1) +======= +>>>>>>> Stashed changes ph("cli-optimize-run-start") logger.info("Running optimizer.") console.rule() if not env_utils.ensure_codeflash_api_key(): return + if not env_utils.check_formatter_installed(): + return function_optimizer = None file_to_funcs_to_optimize: dict[Path, list[FunctionToOptimize]] num_optimizable_functions: int From 7ba496d5665381734131f1994ede0fe179d3cc3a Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Mon, 19 May 2025 23:40:46 -0400 Subject: [PATCH 07/19] stash didnt work as expected --- codeflash/optimization/optimizer.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/codeflash/optimization/optimizer.py b/codeflash/optimization/optimizer.py index e1d554fbb..8984d8b3a 100644 --- a/codeflash/optimization/optimizer.py +++ b/codeflash/optimization/optimizer.py @@ -76,17 +76,6 @@ def create_function_optimizer( ) def run(self) -> None: -<<<<<<< Updated upstream - if self.args.formatter_cmds[0].startswith("black") or self.args.formatter_cmds[0].startswith("ruff"): - formatter = self.args.formatter_cmds[0].split(" ")[0] - try: - execute_test_subprocess([formatter]) - except (FileNotFoundError, NotADirectoryError): - click.echo(f"⚠️ Formatter not found: {formatter}, please ensure it is installed. Exiting...") - sys.exit(1) - -======= ->>>>>>> Stashed changes ph("cli-optimize-run-start") logger.info("Running optimizer.") console.rule() From 72519d56f9af2f824c903955a7f09aefacf3805d Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Mon, 19 May 2025 20:44:54 -0700 Subject: [PATCH 08/19] Update env_utils.py --- codeflash/code_utils/env_utils.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/codeflash/code_utils/env_utils.py b/codeflash/code_utils/env_utils.py index d13413a40..7fdb664f0 100644 --- a/codeflash/code_utils/env_utils.py +++ b/codeflash/code_utils/env_utils.py @@ -1,9 +1,6 @@ import os from functools import lru_cache from typing import Optional - -import click - from codeflash.cli_cmds.console import logger from codeflash.code_utils.shell_utils import read_api_key_from_shell_config from codeflash.verification.test_runner import execute_test_subprocess @@ -16,7 +13,7 @@ def check_formatter_installed(formatter_cmds: list[str]) -> bool: try: execute_test_subprocess([formatter]) except (FileNotFoundError, NotADirectoryError): - click.echo(f"⚠️ Formatter not found: {formatter}, please ensure it is installed") + logger.error(f"⚠️ Formatter not found: {formatter}, please ensure it is installed") return False return True From 290f7b32f130190d0806a80a0923e0e74f3372fb Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Tue, 20 May 2025 00:03:45 -0400 Subject: [PATCH 09/19] circular depenencies --- codeflash/code_utils/env_utils.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/codeflash/code_utils/env_utils.py b/codeflash/code_utils/env_utils.py index 7fdb664f0..43cd5abde 100644 --- a/codeflash/code_utils/env_utils.py +++ b/codeflash/code_utils/env_utils.py @@ -1,9 +1,10 @@ import os +import subprocess from functools import lru_cache from typing import Optional + from codeflash.cli_cmds.console import logger from codeflash.code_utils.shell_utils import read_api_key_from_shell_config -from codeflash.verification.test_runner import execute_test_subprocess def check_formatter_installed(formatter_cmds: list[str]) -> bool: @@ -11,12 +12,13 @@ def check_formatter_installed(formatter_cmds: list[str]) -> bool: if "black" in cmd_parts or "ruff" in cmd_parts: formatter = cmd_parts[0] try: - execute_test_subprocess([formatter]) + subprocess.run([formatter], check=False) except (FileNotFoundError, NotADirectoryError): logger.error(f"⚠️ Formatter not found: {formatter}, please ensure it is installed") return False return True + @lru_cache(maxsize=1) def get_codeflash_api_key() -> str: api_key = os.environ.get("CODEFLASH_API_KEY") or read_api_key_from_shell_config() From ffbb167f5c53a75776ecb1a2b88a07bd85ae8741 Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Tue, 20 May 2025 00:07:15 -0400 Subject: [PATCH 10/19] minor fix --- codeflash/optimization/optimizer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codeflash/optimization/optimizer.py b/codeflash/optimization/optimizer.py index 8984d8b3a..399d41929 100644 --- a/codeflash/optimization/optimizer.py +++ b/codeflash/optimization/optimizer.py @@ -81,7 +81,7 @@ def run(self) -> None: console.rule() if not env_utils.ensure_codeflash_api_key(): return - if not env_utils.check_formatter_installed(): + if not env_utils.check_formatter_installed(self.args.formatter_cmds): return function_optimizer = None file_to_funcs_to_optimize: dict[Path, list[FunctionToOptimize]] From f484ff0679b9dbed41fbc1e2b70d39b1b02ba4d6 Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Tue, 20 May 2025 00:18:21 -0400 Subject: [PATCH 11/19] reduce duplication --- codeflash/cli_cmds/cmd_init.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/codeflash/cli_cmds/cmd_init.py b/codeflash/cli_cmds/cmd_init.py index 7e6d2cd57..e433e42a6 100644 --- a/codeflash/cli_cmds/cmd_init.py +++ b/codeflash/cli_cmds/cmd_init.py @@ -22,7 +22,7 @@ from codeflash.cli_cmds.console import console, logger from codeflash.code_utils.compat import LF from codeflash.code_utils.config_parser import parse_config_file -from codeflash.code_utils.env_utils import get_codeflash_api_key +from codeflash.code_utils.env_utils import check_formatter_installed, get_codeflash_api_key from codeflash.code_utils.git_utils import get_git_remotes, get_repo_owner_and_name from codeflash.code_utils.github_utils import get_github_secrets_page_url from codeflash.code_utils.shell_utils import get_shell_rc_path, save_api_key_to_rc @@ -239,7 +239,7 @@ def collect_setup_info() -> SetupInfo: else: apologize_and_exit() else: - tests_root = Path(curdir) / Path(cast(str, tests_root_answer)) + tests_root = Path(curdir) / Path(cast("str", tests_root_answer)) tests_root = tests_root.relative_to(curdir) ph("cli-tests-root-provided") @@ -302,7 +302,7 @@ def collect_setup_info() -> SetupInfo: elif benchmarks_answer == no_benchmarks_option: benchmarks_root = None else: - benchmarks_root = tests_root / Path(cast(str, benchmarks_answer)) + benchmarks_root = tests_root / Path(cast("str", benchmarks_answer)) # TODO: Implement other benchmark framework options # if benchmarks_root: @@ -354,9 +354,9 @@ def collect_setup_info() -> SetupInfo: module_root=str(module_root), tests_root=str(tests_root), benchmarks_root=str(benchmarks_root) if benchmarks_root else None, - test_framework=cast(str, test_framework), + test_framework=cast("str", test_framework), ignore_paths=ignore_paths, - formatter=cast(str, formatter), + formatter=cast("str", formatter), git_remote=str(git_remote), ) @@ -466,7 +466,7 @@ def check_for_toml_or_setup_file() -> str | None: click.echo("⏩️ Skipping pyproject.toml creation.") apologize_and_exit() click.echo() - return cast(str, project_name) + return cast("str", project_name) def install_github_actions(override_formatter_check: bool = False) -> None: @@ -717,11 +717,7 @@ def configure_pyproject_toml(setup_info: SetupInfo) -> None: ) elif formatter == "don't use a formatter": formatter_cmds.append("disabled") - if formatter in ["black", "ruff"]: - try: - subprocess.run([formatter], capture_output=True, check=False) - except (FileNotFoundError, NotADirectoryError): - click.echo(f"⚠️ Formatter not found: {formatter}, please ensure it is installed") + check_formatter_installed(formatter_cmds) codeflash_section["formatter-cmds"] = formatter_cmds # Add the 'codeflash' section, ensuring 'tool' section exists tool_section = pyproject_data.get("tool", tomlkit.table()) From cd63955794b00f727389ce327bc69143df1f9348 Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Tue, 20 May 2025 15:46:35 -0400 Subject: [PATCH 12/19] more pythonic --- codeflash/code_utils/env_utils.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/codeflash/code_utils/env_utils.py b/codeflash/code_utils/env_utils.py index 43cd5abde..3e207be1b 100644 --- a/codeflash/code_utils/env_utils.py +++ b/codeflash/code_utils/env_utils.py @@ -1,4 +1,5 @@ import os +import shlex import subprocess from functools import lru_cache from typing import Optional @@ -8,9 +9,9 @@ def check_formatter_installed(formatter_cmds: list[str]) -> bool: - cmd_parts = formatter_cmds[0].split(" ") - if "black" in cmd_parts or "ruff" in cmd_parts: - formatter = cmd_parts[0] + cmd_parts = shlex.split(formatter_cmds[0]," ") + formatter = "black" if "black" in cmd_parts else "ruff" if "ruff" in cmd_parts else None + if not formatter: try: subprocess.run([formatter], check=False) except (FileNotFoundError, NotADirectoryError): From dfc5177461f870f7c046c762a88c4fa353f0f995 Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Tue, 20 May 2025 16:03:19 -0400 Subject: [PATCH 13/19] covering cases where uv or uvx is used --- codeflash/code_utils/env_utils.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/codeflash/code_utils/env_utils.py b/codeflash/code_utils/env_utils.py index 3e207be1b..fe983da83 100644 --- a/codeflash/code_utils/env_utils.py +++ b/codeflash/code_utils/env_utils.py @@ -9,8 +9,9 @@ def check_formatter_installed(formatter_cmds: list[str]) -> bool: - cmd_parts = shlex.split(formatter_cmds[0]," ") - formatter = "black" if "black" in cmd_parts else "ruff" if "ruff" in cmd_parts else None + clean_cmd = formatter_cmds[0].replace("uvx ","").replace("uv ","").replace("tool ","").replace("run ","") + clean_cmd_parts = shlex.split(clean_cmd," ") + formatter = "black" if "black" in clean_cmd_parts else "ruff" if "ruff" in clean_cmd_parts else clean_cmd_parts[0] if not formatter: try: subprocess.run([formatter], check=False) From ac0894a1af51e901820af716c984ffbbfb98d9b1 Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Tue, 20 May 2025 16:35:05 -0400 Subject: [PATCH 14/19] running all commands in list to ensure all run --- codeflash/code_utils/env_utils.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/codeflash/code_utils/env_utils.py b/codeflash/code_utils/env_utils.py index fe983da83..8d952a120 100644 --- a/codeflash/code_utils/env_utils.py +++ b/codeflash/code_utils/env_utils.py @@ -1,6 +1,7 @@ import os import shlex import subprocess +import tempfile from functools import lru_cache from typing import Optional @@ -9,16 +10,21 @@ def check_formatter_installed(formatter_cmds: list[str]) -> bool: - clean_cmd = formatter_cmds[0].replace("uvx ","").replace("uv ","").replace("tool ","").replace("run ","") - clean_cmd_parts = shlex.split(clean_cmd," ") - formatter = "black" if "black" in clean_cmd_parts else "ruff" if "ruff" in clean_cmd_parts else clean_cmd_parts[0] - if not formatter: - try: - subprocess.run([formatter], check=False) - except (FileNotFoundError, NotADirectoryError): - logger.error(f"⚠️ Formatter not found: {formatter}, please ensure it is installed") - return False - return True + return_code = True + if formatter_cmds[0] == "disabled": + return return_code + tmp_code = """print("hello world")""" + tmp_file = tempfile.NamedTemporaryFile(suffix=".py").write_text(tmp_code, encoding="utf8") + file_token = "$file" # noqa: S105 + for command in set(formatter_cmds): + formatter_cmd_list = shlex.split(command, posix=os.name != "nt") + formatter_cmd_list = [tmp_file.as_posix() if chunk == file_token else chunk for chunk in formatter_cmd_list] + result = subprocess.run(formatter_cmd_list, capture_output=True, check=False) + if result.returncode: + return_code = False + break + tmp_file.unlink(missing_ok=True) + return return_code @lru_cache(maxsize=1) From 6b27835c8a50ff9e6ec6df82e0a21620231012db Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Tue, 20 May 2025 16:41:46 -0400 Subject: [PATCH 15/19] minor fixes --- codeflash/code_utils/env_utils.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/codeflash/code_utils/env_utils.py b/codeflash/code_utils/env_utils.py index 8d952a120..e0beb24a1 100644 --- a/codeflash/code_utils/env_utils.py +++ b/codeflash/code_utils/env_utils.py @@ -3,6 +3,7 @@ import subprocess import tempfile from functools import lru_cache +from pathlib import Path from typing import Optional from codeflash.cli_cmds.console import logger @@ -14,7 +15,8 @@ def check_formatter_installed(formatter_cmds: list[str]) -> bool: if formatter_cmds[0] == "disabled": return return_code tmp_code = """print("hello world")""" - tmp_file = tempfile.NamedTemporaryFile(suffix=".py").write_text(tmp_code, encoding="utf8") + tmp_file = tempfile.NamedTemporaryFile(suffix=".py") + Path(tmp_file.name).write_text(tmp_code, encoding="utf8") file_token = "$file" # noqa: S105 for command in set(formatter_cmds): formatter_cmd_list = shlex.split(command, posix=os.name != "nt") @@ -23,6 +25,7 @@ def check_formatter_installed(formatter_cmds: list[str]) -> bool: if result.returncode: return_code = False break + tmp_file.close() tmp_file.unlink(missing_ok=True) return return_code From 7f0182305bdb08290f86e8823922ca245c69c3da Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Tue, 20 May 2025 18:38:12 -0400 Subject: [PATCH 16/19] bugfix --- codeflash/code_utils/env_utils.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/codeflash/code_utils/env_utils.py b/codeflash/code_utils/env_utils.py index e0beb24a1..e14d01295 100644 --- a/codeflash/code_utils/env_utils.py +++ b/codeflash/code_utils/env_utils.py @@ -15,18 +15,21 @@ def check_formatter_installed(formatter_cmds: list[str]) -> bool: if formatter_cmds[0] == "disabled": return return_code tmp_code = """print("hello world")""" - tmp_file = tempfile.NamedTemporaryFile(suffix=".py") - Path(tmp_file.name).write_text(tmp_code, encoding="utf8") - file_token = "$file" # noqa: S105 - for command in set(formatter_cmds): - formatter_cmd_list = shlex.split(command, posix=os.name != "nt") - formatter_cmd_list = [tmp_file.as_posix() if chunk == file_token else chunk for chunk in formatter_cmd_list] - result = subprocess.run(formatter_cmd_list, capture_output=True, check=False) - if result.returncode: - return_code = False - break - tmp_file.close() + with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", suffix=".py") as f: + f.write(tmp_code) + f.flush() + tmp_file = Path(f.name) + file_token = "$file" # noqa: S105 + for command in set(formatter_cmds): + formatter_cmd_list = shlex.split(command, posix=os.name != "nt") + formatter_cmd_list = [tmp_file.as_posix() if chunk == file_token else chunk for chunk in formatter_cmd_list] + result = subprocess.run(formatter_cmd_list, capture_output=True, check=False) + if result.returncode: + return_code = False + break tmp_file.unlink(missing_ok=True) + if not return_code: + raise logger.error(f"Error running formatter command: {command}") return return_code From bc31a6174274eab99d91ac8321233117b0170db7 Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Tue, 20 May 2025 21:53:04 -0400 Subject: [PATCH 17/19] handle more exceptions --- codeflash/code_utils/env_utils.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/codeflash/code_utils/env_utils.py b/codeflash/code_utils/env_utils.py index e14d01295..5e5251cc2 100644 --- a/codeflash/code_utils/env_utils.py +++ b/codeflash/code_utils/env_utils.py @@ -23,13 +23,18 @@ def check_formatter_installed(formatter_cmds: list[str]) -> bool: for command in set(formatter_cmds): formatter_cmd_list = shlex.split(command, posix=os.name != "nt") formatter_cmd_list = [tmp_file.as_posix() if chunk == file_token else chunk for chunk in formatter_cmd_list] - result = subprocess.run(formatter_cmd_list, capture_output=True, check=False) + try: + result = subprocess.run(formatter_cmd_list, capture_output=True, check=False) + except (FileNotFoundError, NotADirectoryError): + return_code = False + break if result.returncode: return_code = False break tmp_file.unlink(missing_ok=True) if not return_code: - raise logger.error(f"Error running formatter command: {command}") + msg = f"Error running formatter command: {command}" + raise logger.error(msg) # type: ignore return return_code From dfaa1cbac44fa5885984ea2bc3fb3f9adcca20f0 Mon Sep 17 00:00:00 2001 From: Kevin Turcios Date: Tue, 20 May 2025 23:03:10 -0400 Subject: [PATCH 18/19] raise proper exception --- codeflash/cli_cmds/cmd_init.py | 8 ++++++++ codeflash/code_utils/env_utils.py | 8 +++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/codeflash/cli_cmds/cmd_init.py b/codeflash/cli_cmds/cmd_init.py index 3038e1c59..4527a1f3a 100644 --- a/codeflash/cli_cmds/cmd_init.py +++ b/codeflash/cli_cmds/cmd_init.py @@ -916,6 +916,14 @@ def test_sort(): def run_end_to_end_test(args: Namespace, bubble_sort_path: str, bubble_sort_test_path: str) -> None: + try: + check_formatter_installed(args.formatter_cmds) + except Exception: # noqa: BLE001 + logger.error( + "Formatter not found. Review the formatter_cmds in your pyproject.toml file and make sure the formatter is installed." + ) + return + command = ["codeflash", "--file", "bubble_sort.py", "--function", "sorter"] if args.no_pr: command.append("--no-pr") diff --git a/codeflash/code_utils/env_utils.py b/codeflash/code_utils/env_utils.py index 5e5251cc2..229e784b8 100644 --- a/codeflash/code_utils/env_utils.py +++ b/codeflash/code_utils/env_utils.py @@ -10,6 +10,12 @@ from codeflash.code_utils.shell_utils import read_api_key_from_shell_config +class FormatterNotFoundError(Exception): + """Exception raised when a formatter is not found.""" + + def __init__(self, formatter_cmd: str) -> None: + super().__init__(f"Formatter command not found: {formatter_cmd}") + def check_formatter_installed(formatter_cmds: list[str]) -> bool: return_code = True if formatter_cmds[0] == "disabled": @@ -34,7 +40,7 @@ def check_formatter_installed(formatter_cmds: list[str]) -> bool: tmp_file.unlink(missing_ok=True) if not return_code: msg = f"Error running formatter command: {command}" - raise logger.error(msg) # type: ignore + raise FormatterNotFoundError(msg) return return_code From baa747ad40e724fd86eb3c14e1ce546aa0d4b491 Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Wed, 21 May 2025 16:12:58 -0400 Subject: [PATCH 19/19] precommit fix --- codeflash/cli_cmds/cmd_init.py | 2 +- codeflash/code_utils/env_utils.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/codeflash/cli_cmds/cmd_init.py b/codeflash/cli_cmds/cmd_init.py index 7870e1e89..6804ccc86 100644 --- a/codeflash/cli_cmds/cmd_init.py +++ b/codeflash/cli_cmds/cmd_init.py @@ -922,7 +922,7 @@ def test_sort(): def run_end_to_end_test(args: Namespace, bubble_sort_path: str, bubble_sort_test_path: str) -> None: try: check_formatter_installed(args.formatter_cmds) - except Exception: # noqa: BLE001 + except Exception: logger.error( "Formatter not found. Review the formatter_cmds in your pyproject.toml file and make sure the formatter is installed." ) diff --git a/codeflash/code_utils/env_utils.py b/codeflash/code_utils/env_utils.py index 71a2807e9..ee18cfa00 100644 --- a/codeflash/code_utils/env_utils.py +++ b/codeflash/code_utils/env_utils.py @@ -18,6 +18,7 @@ class FormatterNotFoundError(Exception): def __init__(self, formatter_cmd: str) -> None: super().__init__(f"Formatter command not found: {formatter_cmd}") + def check_formatter_installed(formatter_cmds: list[str]) -> bool: return_code = True if formatter_cmds[0] == "disabled":