From 35c8d1409a84bd2d36b4cd64daa00c8b067654fa Mon Sep 17 00:00:00 2001 From: aseembits93 Date: Wed, 28 May 2025 17:38:02 -0700 Subject: [PATCH 01/18] edit pyproject to remove blacklisted plugin parameters --- codeflash/cli_cmds/cmd_init.py | 2 +- codeflash/code_utils/code_utils.py | 43 ++++++++++++++++++ codeflash/verification/test_runner.py | 64 ++++++++++++++------------- 3 files changed, 78 insertions(+), 31 deletions(-) diff --git a/codeflash/cli_cmds/cmd_init.py b/codeflash/cli_cmds/cmd_init.py index c1c235b8d..66ef8a14b 100644 --- a/codeflash/cli_cmds/cmd_init.py +++ b/codeflash/cli_cmds/cmd_init.py @@ -537,7 +537,7 @@ def install_github_actions(override_formatter_check: bool = False) -> None: # n existing_api_key = None click.prompt( f"Next, you'll need to add your CODEFLASH_API_KEY as a secret to your GitHub repo.{LF}" - f"Press Enter to open your repo's secrets page at {get_github_secrets_page_url(repo)}…{LF}" + f"Press Enter to open your repo's secrets page at {get_github_secrets_page_url(repo)} {LF}" f"Then, click 'New repository secret' to add your api key with the variable name CODEFLASH_API_KEY.{LF}" f"{'Here is your CODEFLASH_API_KEY: ' + existing_api_key + ' ' + LF}" if existing_api_key diff --git a/codeflash/code_utils/code_utils.py b/codeflash/code_utils/code_utils.py index 2a0ddc310..930237618 100644 --- a/codeflash/code_utils/code_utils.py +++ b/codeflash/code_utils/code_utils.py @@ -4,13 +4,56 @@ import os import shutil import site +from contextlib import contextmanager from functools import lru_cache from pathlib import Path from tempfile import TemporaryDirectory +import tomlkit + from codeflash.cli_cmds.console import logger +@contextmanager +def custom_addopts(pyproject_path: str = "pyproject.toml") -> None: + pyproject_file = Path(pyproject_path) + original_content = None + + try: + # Read original file + if pyproject_file.exists(): + with Path.open(pyproject_file, encoding="utf-8") as f: + original_content = f.read() + data = tomlkit.parse(original_content) + + # Backup original addopts + original_addopts = data.get("tool", {}).get("pytest", {}).get("ini_options", {}).get("addopts", "") + + # Set new addopts + if "tool" not in data: + data["tool"] = {} + if "pytest" not in data["tool"]: + data["tool"]["pytest"] = {} + if "ini_options" not in data["tool"]["pytest"]: + data["tool"]["pytest"]["ini_options"] = {} + + data["tool"]["pytest"]["ini_options"]["addopts"] = [ + x for x in original_addopts if x not in ["-n", "-n auto", "auto"] + ] + + # Write modified file + with Path.open(pyproject_file, "w", encoding="utf-8") as f: + f.write(tomlkit.dumps(data)) + + yield + + finally: + # Restore original file + if original_content and pyproject_file.exists(): + with Path.open(pyproject_file, "w", encoding="utf-8") as f: + f.write(original_content) + + def encoded_tokens_len(s: str) -> int: """Return the approximate length of the encoded tokens. diff --git a/codeflash/verification/test_runner.py b/codeflash/verification/test_runner.py index 58834d1c4..38ab5d23d 100644 --- a/codeflash/verification/test_runner.py +++ b/codeflash/verification/test_runner.py @@ -6,7 +6,7 @@ from typing import TYPE_CHECKING from codeflash.cli_cmds.console import logger -from codeflash.code_utils.code_utils import get_run_tmp_file +from codeflash.code_utils.code_utils import custom_addopts, get_run_tmp_file from codeflash.code_utils.compat import IS_POSIX, SAFE_SYS_EXECUTABLE from codeflash.code_utils.config_consts import TOTAL_LOOPING_TIME from codeflash.code_utils.coverage_utils import prepare_coverage_files @@ -97,24 +97,27 @@ def run_behavioral_tests( coverage_cmd.extend(shlex.split(pytest_cmd, posix=IS_POSIX)[1:]) blocklist_args = [f"-p no:{plugin}" for plugin in BEHAVIORAL_BLOCKLISTED_PLUGINS if plugin != "cov"] - results = execute_test_subprocess( - coverage_cmd + common_pytest_args + blocklist_args + result_args + test_files, - cwd=cwd, - env=pytest_test_env, - timeout=600, - ) + + with custom_addopts(): + results = execute_test_subprocess( + coverage_cmd + common_pytest_args + blocklist_args + result_args + test_files, + cwd=cwd, + env=pytest_test_env, + timeout=600, + ) logger.debug( f"Result return code: {results.returncode}, " f"{'Result stderr:' + str(results.stderr) if results.stderr else ''}" ) else: blocklist_args = [f"-p no:{plugin}" for plugin in BEHAVIORAL_BLOCKLISTED_PLUGINS] - results = execute_test_subprocess( - pytest_cmd_list + common_pytest_args + blocklist_args + result_args + test_files, - cwd=cwd, - env=pytest_test_env, - timeout=600, # TODO: Make this dynamic - ) + with custom_addopts(): + results = execute_test_subprocess( + pytest_cmd_list + common_pytest_args + blocklist_args + result_args + test_files, + cwd=cwd, + env=pytest_test_env, + timeout=600, # TODO: Make this dynamic + ) logger.debug( f"""Result return code: {results.returncode}, {"Result stderr:" + str(results.stderr) if results.stderr else ""}""" ) @@ -192,12 +195,13 @@ def run_line_profile_tests( pytest_test_env["PYTEST_PLUGINS"] = "codeflash.verification.pytest_plugin" blocklist_args = [f"-p no:{plugin}" for plugin in BENCHMARKING_BLOCKLISTED_PLUGINS] pytest_test_env["LINE_PROFILE"] = "1" - results = execute_test_subprocess( - pytest_cmd_list + pytest_args + blocklist_args + result_args + test_files, - cwd=cwd, - env=pytest_test_env, - timeout=600, # TODO: Make this dynamic - ) + with custom_addopts(): + results = execute_test_subprocess( + pytest_cmd_list + pytest_args + blocklist_args + result_args + test_files, + cwd=cwd, + env=pytest_test_env, + timeout=600, # TODO: Make this dynamic + ) else: msg = f"Unsupported test framework: {test_framework}" raise ValueError(msg) @@ -252,13 +256,13 @@ def run_benchmarking_tests( pytest_test_env = test_env.copy() pytest_test_env["PYTEST_PLUGINS"] = "codeflash.verification.pytest_plugin" blocklist_args = [f"-p no:{plugin}" for plugin in BENCHMARKING_BLOCKLISTED_PLUGINS] - - results = execute_test_subprocess( - pytest_cmd_list + pytest_args + blocklist_args + result_args + test_files, - cwd=cwd, - env=pytest_test_env, - timeout=600, # TODO: Make this dynamic - ) + with custom_addopts(): + results = execute_test_subprocess( + pytest_cmd_list + pytest_args + blocklist_args + result_args + test_files, + cwd=cwd, + env=pytest_test_env, + timeout=600, # TODO: Make this dynamic + ) elif test_framework == "unittest": test_files = [file.benchmarking_file_path for file in test_paths.test_files] result_file_path, results = run_unittest_tests( @@ -278,8 +282,8 @@ def run_unittest_tests( log_level = ["-v"] if verbose else [] files = [str(file) for file in test_file_paths] output_file = ["--output-file", str(result_file_path)] - - results = execute_test_subprocess( - unittest_cmd_list + log_level + files + output_file, cwd=cwd, env=test_env, timeout=600 - ) + with custom_addopts(): + results = execute_test_subprocess( + unittest_cmd_list + log_level + files + output_file, cwd=cwd, env=test_env, timeout=600 + ) return result_file_path, results From dcf92867707606a3716769bc874720c7e463fead Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Wed, 28 May 2025 20:04:12 -0700 Subject: [PATCH 02/18] precommit pass --- codeflash/code_utils/code_utils.py | 36 +++++++-------- codeflash/verification/test_runner.py | 64 +++++++++++++-------------- 2 files changed, 47 insertions(+), 53 deletions(-) diff --git a/codeflash/code_utils/code_utils.py b/codeflash/code_utils/code_utils.py index 930237618..2be33f3d2 100644 --- a/codeflash/code_utils/code_utils.py +++ b/codeflash/code_utils/code_utils.py @@ -2,6 +2,7 @@ import ast import os +import re import shutil import site from contextlib import contextmanager @@ -12,11 +13,12 @@ import tomlkit from codeflash.cli_cmds.console import logger +from codeflash.code_utils.config_parser import find_pyproject_toml @contextmanager -def custom_addopts(pyproject_path: str = "pyproject.toml") -> None: - pyproject_file = Path(pyproject_path) +def custom_addopts() -> None: + pyproject_file = find_pyproject_toml() original_content = None try: @@ -28,28 +30,24 @@ def custom_addopts(pyproject_path: str = "pyproject.toml") -> None: # Backup original addopts original_addopts = data.get("tool", {}).get("pytest", {}).get("ini_options", {}).get("addopts", "") - - # Set new addopts - if "tool" not in data: - data["tool"] = {} - if "pytest" not in data["tool"]: - data["tool"]["pytest"] = {} - if "ini_options" not in data["tool"]["pytest"]: - data["tool"]["pytest"]["ini_options"] = {} - - data["tool"]["pytest"]["ini_options"]["addopts"] = [ - x for x in original_addopts if x not in ["-n", "-n auto", "auto"] - ] - - # Write modified file - with Path.open(pyproject_file, "w", encoding="utf-8") as f: - f.write(tomlkit.dumps(data)) + # nothing to do if no addopts present + if original_addopts != "": + non_blacklist_plugin_args = re.sub(r"-n +\S+", "", " ".join(original_addopts)).split(" ") + if non_blacklist_plugin_args != original_addopts: + data["tool"]["pytest"]["ini_options"]["addopts"] = non_blacklist_plugin_args + # Write modified file + with Path.open(pyproject_file, "w", encoding="utf-8") as f: + f.write(tomlkit.dumps(data)) yield finally: # Restore original file - if original_content and pyproject_file.exists(): + if ( + original_content + and pyproject_file.exists() + and tuple(original_addopts) not in {(), tuple(non_blacklist_plugin_args)} + ): with Path.open(pyproject_file, "w", encoding="utf-8") as f: f.write(original_content) diff --git a/codeflash/verification/test_runner.py b/codeflash/verification/test_runner.py index 38ab5d23d..f0d1c01a5 100644 --- a/codeflash/verification/test_runner.py +++ b/codeflash/verification/test_runner.py @@ -23,8 +23,9 @@ def execute_test_subprocess( cmd_list: list[str], cwd: Path, env: dict[str, str] | None, timeout: int = 600 ) -> subprocess.CompletedProcess: """Execute a subprocess with the given command list, working directory, environment variables, and timeout.""" - logger.debug(f"executing test run with command: {' '.join(cmd_list)}") - return subprocess.run(cmd_list, capture_output=True, cwd=cwd, env=env, text=True, timeout=timeout, check=False) + with custom_addopts(): + logger.debug(f"executing test run with command: {' '.join(cmd_list)}") + return subprocess.run(cmd_list, capture_output=True, cwd=cwd, env=env, text=True, timeout=timeout, check=False) def run_behavioral_tests( @@ -98,26 +99,24 @@ def run_behavioral_tests( blocklist_args = [f"-p no:{plugin}" for plugin in BEHAVIORAL_BLOCKLISTED_PLUGINS if plugin != "cov"] - with custom_addopts(): - results = execute_test_subprocess( - coverage_cmd + common_pytest_args + blocklist_args + result_args + test_files, - cwd=cwd, - env=pytest_test_env, - timeout=600, - ) + results = execute_test_subprocess( + coverage_cmd + common_pytest_args + blocklist_args + result_args + test_files, + cwd=cwd, + env=pytest_test_env, + timeout=600, + ) logger.debug( f"Result return code: {results.returncode}, " f"{'Result stderr:' + str(results.stderr) if results.stderr else ''}" ) else: blocklist_args = [f"-p no:{plugin}" for plugin in BEHAVIORAL_BLOCKLISTED_PLUGINS] - with custom_addopts(): - results = execute_test_subprocess( - pytest_cmd_list + common_pytest_args + blocklist_args + result_args + test_files, - cwd=cwd, - env=pytest_test_env, - timeout=600, # TODO: Make this dynamic - ) + results = execute_test_subprocess( + pytest_cmd_list + common_pytest_args + blocklist_args + result_args + test_files, + cwd=cwd, + env=pytest_test_env, + timeout=600, # TODO: Make this dynamic + ) logger.debug( f"""Result return code: {results.returncode}, {"Result stderr:" + str(results.stderr) if results.stderr else ""}""" ) @@ -195,13 +194,12 @@ def run_line_profile_tests( pytest_test_env["PYTEST_PLUGINS"] = "codeflash.verification.pytest_plugin" blocklist_args = [f"-p no:{plugin}" for plugin in BENCHMARKING_BLOCKLISTED_PLUGINS] pytest_test_env["LINE_PROFILE"] = "1" - with custom_addopts(): - results = execute_test_subprocess( - pytest_cmd_list + pytest_args + blocklist_args + result_args + test_files, - cwd=cwd, - env=pytest_test_env, - timeout=600, # TODO: Make this dynamic - ) + results = execute_test_subprocess( + pytest_cmd_list + pytest_args + blocklist_args + result_args + test_files, + cwd=cwd, + env=pytest_test_env, + timeout=600, # TODO: Make this dynamic + ) else: msg = f"Unsupported test framework: {test_framework}" raise ValueError(msg) @@ -256,13 +254,12 @@ def run_benchmarking_tests( pytest_test_env = test_env.copy() pytest_test_env["PYTEST_PLUGINS"] = "codeflash.verification.pytest_plugin" blocklist_args = [f"-p no:{plugin}" for plugin in BENCHMARKING_BLOCKLISTED_PLUGINS] - with custom_addopts(): - results = execute_test_subprocess( - pytest_cmd_list + pytest_args + blocklist_args + result_args + test_files, - cwd=cwd, - env=pytest_test_env, - timeout=600, # TODO: Make this dynamic - ) + results = execute_test_subprocess( + pytest_cmd_list + pytest_args + blocklist_args + result_args + test_files, + cwd=cwd, + env=pytest_test_env, + timeout=600, # TODO: Make this dynamic + ) elif test_framework == "unittest": test_files = [file.benchmarking_file_path for file in test_paths.test_files] result_file_path, results = run_unittest_tests( @@ -282,8 +279,7 @@ def run_unittest_tests( log_level = ["-v"] if verbose else [] files = [str(file) for file in test_file_paths] output_file = ["--output-file", str(result_file_path)] - with custom_addopts(): - results = execute_test_subprocess( - unittest_cmd_list + log_level + files + output_file, cwd=cwd, env=test_env, timeout=600 - ) + results = execute_test_subprocess( + unittest_cmd_list + log_level + files + output_file, cwd=cwd, env=test_env, timeout=600 + ) return result_file_path, results From 5c53d92be3283cef4157525d3dbef62fc714f02c Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Wed, 28 May 2025 20:32:44 -0700 Subject: [PATCH 03/18] quicl fix --- codeflash/code_utils/code_utils.py | 1 + codeflash/version.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/codeflash/code_utils/code_utils.py b/codeflash/code_utils/code_utils.py index 2be33f3d2..86bd1eb8f 100644 --- a/codeflash/code_utils/code_utils.py +++ b/codeflash/code_utils/code_utils.py @@ -20,6 +20,7 @@ def custom_addopts() -> None: pyproject_file = find_pyproject_toml() original_content = None + non_blacklist_plugin_args = "" try: # Read original file diff --git a/codeflash/version.py b/codeflash/version.py index 16cb84c61..5346820c1 100644 --- a/codeflash/version.py +++ b/codeflash/version.py @@ -1,3 +1,3 @@ # These version placeholders will be replaced by poetry-dynamic-versioning during `poetry build`. -__version__ = "0.12.3" -__version_tuple__ = (0, 12, 3) +__version__ = "0.12.3.post54.dev0+dcf92867" +__version_tuple__ = (0, 12, 3, "post54", "dev0", "dcf92867") From c10981f9041048faa58cae4d0f12574cf41058c7 Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Wed, 28 May 2025 20:48:57 -0700 Subject: [PATCH 04/18] account for -n= situation --- codeflash/code_utils/code_utils.py | 2 +- codeflash/version.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/codeflash/code_utils/code_utils.py b/codeflash/code_utils/code_utils.py index 86bd1eb8f..cffa84a6e 100644 --- a/codeflash/code_utils/code_utils.py +++ b/codeflash/code_utils/code_utils.py @@ -33,7 +33,7 @@ def custom_addopts() -> None: original_addopts = data.get("tool", {}).get("pytest", {}).get("ini_options", {}).get("addopts", "") # nothing to do if no addopts present if original_addopts != "": - non_blacklist_plugin_args = re.sub(r"-n +\S+", "", " ".join(original_addopts)).split(" ") + non_blacklist_plugin_args = re.sub(r"-n(?: +|=)\S+", "", " ".join(original_addopts)).split(" ") if non_blacklist_plugin_args != original_addopts: data["tool"]["pytest"]["ini_options"]["addopts"] = non_blacklist_plugin_args # Write modified file diff --git a/codeflash/version.py b/codeflash/version.py index 5346820c1..16cb84c61 100644 --- a/codeflash/version.py +++ b/codeflash/version.py @@ -1,3 +1,3 @@ # These version placeholders will be replaced by poetry-dynamic-versioning during `poetry build`. -__version__ = "0.12.3.post54.dev0+dcf92867" -__version_tuple__ = (0, 12, 3, "post54", "dev0", "dcf92867") +__version__ = "0.12.3" +__version_tuple__ = (0, 12, 3) From b74509a49be4d46f140815cee8da9ed2efc37220 Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Wed, 28 May 2025 21:38:03 -0700 Subject: [PATCH 05/18] e2e test --- codeflash/code_utils/code_utils.py | 1 - ...nd_test_bubblesort_blacklist_arg_pytest.py | 44 +++++++++++++++++++ .../scripts/end_to_end_test_tracer_replay.py | 3 +- tests/scripts/end_to_end_test_utilities.py | 6 ++- 4 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 tests/scripts/end_to_end_test_bubblesort_blacklist_arg_pytest.py diff --git a/codeflash/code_utils/code_utils.py b/codeflash/code_utils/code_utils.py index cffa84a6e..11ab3566c 100644 --- a/codeflash/code_utils/code_utils.py +++ b/codeflash/code_utils/code_utils.py @@ -28,7 +28,6 @@ def custom_addopts() -> None: with Path.open(pyproject_file, encoding="utf-8") as f: original_content = f.read() data = tomlkit.parse(original_content) - # Backup original addopts original_addopts = data.get("tool", {}).get("pytest", {}).get("ini_options", {}).get("addopts", "") # nothing to do if no addopts present diff --git a/tests/scripts/end_to_end_test_bubblesort_blacklist_arg_pytest.py b/tests/scripts/end_to_end_test_bubblesort_blacklist_arg_pytest.py new file mode 100644 index 000000000..f96048908 --- /dev/null +++ b/tests/scripts/end_to_end_test_bubblesort_blacklist_arg_pytest.py @@ -0,0 +1,44 @@ +import os +from pathlib import Path + +from end_to_end_test_utilities import CoverageExpectation, TestConfig, run_codeflash_command, run_with_retries +import tomlkit + + +def run_test(expected_improvement_pct: int) -> bool: + try: + # Modify Pyproject file + with Path.open((Path(__file__).parent.parent.parent / "pyproject.toml").resolve(), encoding="utf-8") as f: + original_content = f.read() + data = tomlkit.parse(original_content) + data["tool"]["pytest"] = {} + data["tool"]["pytest"]["ini_options"] = {} + data["tool"]["pytest"]["ini_options"]["addopts"] = ["-n=auto", "-n", "1", "-n 1", "-n 1", "-n auto"] + with Path.open((Path(__file__).parent.parent.parent / "pyproject.toml").resolve(), "w", encoding="utf-8") as f: + f.write(tomlkit.dumps(data)) + + config = TestConfig( + file_path="bubble_sort.py", + function_name="sorter", + test_framework="pytest", + min_improvement_x=1.0, + coverage_expectations=[ + CoverageExpectation( + function_name="sorter", expected_coverage=100.0, expected_lines=[2, 3, 4, 5, 6, 7, 8, 9, 10] + ) + ], + ) + cwd = (Path(__file__).parent.parent.parent / "code_to_optimize").resolve() + return run_codeflash_command( + cwd, + config, + expected_improvement_pct, + ['print("codeflash stdout: Sorting list")', 'print(f"result: {arr}")'], + ) + finally: + with Path.open(Path("pyproject.toml"), "w", encoding="utf-8") as f: + f.write(original_content) + + +if __name__ == "__main__": + exit(run_with_retries(run_test, int(os.getenv("EXPECTED_IMPROVEMENT_PCT", 100)))) diff --git a/tests/scripts/end_to_end_test_tracer_replay.py b/tests/scripts/end_to_end_test_tracer_replay.py index 2af49999d..a2506fd99 100644 --- a/tests/scripts/end_to_end_test_tracer_replay.py +++ b/tests/scripts/end_to_end_test_tracer_replay.py @@ -10,7 +10,7 @@ def run_test(expected_improvement_pct: int) -> bool: min_improvement_x=0.1, expected_unit_tests=1, coverage_expectations=[ - CoverageExpectation(function_name="funcA", expected_coverage=100.0, expected_lines=[5, 6, 7, 8, 10, 13]), + CoverageExpectation(function_name="funcA", expected_coverage=100.0, expected_lines=[5, 6, 7, 8, 10, 13]) ], ) cwd = ( @@ -18,5 +18,6 @@ def run_test(expected_improvement_pct: int) -> bool: ).resolve() return run_codeflash_command(cwd, config, expected_improvement_pct) + if __name__ == "__main__": exit(run_with_retries(run_test, int(os.getenv("EXPECTED_IMPROVEMENT_PCT", 10)))) diff --git a/tests/scripts/end_to_end_test_utilities.py b/tests/scripts/end_to_end_test_utilities.py index d050f50e9..3645930b0 100644 --- a/tests/scripts/end_to_end_test_utilities.py +++ b/tests/scripts/end_to_end_test_utilities.py @@ -117,7 +117,9 @@ def run_codeflash_command( return validated -def build_command(cwd: pathlib.Path, config: TestConfig, test_root: pathlib.Path, benchmarks_root:pathlib.Path|None = None) -> list[str]: +def build_command( + cwd: pathlib.Path, config: TestConfig, test_root: pathlib.Path, benchmarks_root: pathlib.Path | None = None +) -> list[str]: python_path = "../../../codeflash/main.py" if "code_directories" in str(cwd) else "../codeflash/main.py" base_command = ["python", python_path, "--file", config.file_path, "--no-pr"] @@ -251,4 +253,4 @@ def run_with_retries(test_func, *args, **kwargs) -> bool: logging.error("Test failed after all retries") return 1 - return 1 \ No newline at end of file + return 1 From 1753e16b6e17b71c22d07069ae4dfe6d2bd22965 Mon Sep 17 00:00:00 2001 From: Aseem Saxena Date: Wed, 28 May 2025 21:55:36 -0700 Subject: [PATCH 06/18] e2e test --- ...ubblesort-blacklist-arg-pytest-no-git.yaml | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 .github/workflows/end-to-end-test-bubblesort-blacklist-arg-pytest-no-git.yaml diff --git a/.github/workflows/end-to-end-test-bubblesort-blacklist-arg-pytest-no-git.yaml b/.github/workflows/end-to-end-test-bubblesort-blacklist-arg-pytest-no-git.yaml new file mode 100644 index 000000000..972add520 --- /dev/null +++ b/.github/workflows/end-to-end-test-bubblesort-blacklist-arg-pytest-no-git.yaml @@ -0,0 +1,89 @@ +name: end-to-end-test-blacklist-arg + +on: + # Use pull_request_target for everything to ensure access to secrets + pull_request_target: + paths: + - '**' # Trigger for all paths + + workflow_dispatch: + +jobs: + end-to-end-test-blacklist-arg: + # Dynamically determine if environment is needed only when workflow files change and contributor is external + environment: ${{ (github.event_name == 'workflow_dispatch' || (contains(toJSON(github.event.pull_request.files.*.filename), '.github/workflows/') && github.event.pull_request.user.login != 'misrasaurabh1' && github.event.pull_request.user.login != 'KRRT7')) && 'external-trusted-contributors' || '' }} + + runs-on: ubuntu-latest + env: + CODEFLASH_AIS_SERVER: prod + POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }} + CODEFLASH_API_KEY: ${{ secrets.CODEFLASH_API_KEY }} + COLUMNS: 110 + MAX_RETRIES: 3 + RETRY_DELAY: 5 + EXPECTED_IMPROVEMENT_PCT: 300 + CODEFLASH_END_TO_END: 1 + steps: + - name: 🛎️ Checkout + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.ref }} + repository: ${{ github.event.pull_request.head.repo.full_name }} + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + - name: Validate PR + run: | + # Check for any workflow changes + if git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}" | grep -q "^.github/workflows/"; then + echo "⚠️ Workflow changes detected." + + # Get the PR author + AUTHOR="${{ github.event.pull_request.user.login }}" + echo "PR Author: $AUTHOR" + + # Allowlist check + if [[ "$AUTHOR" == "misrasaurabh1" || "$AUTHOR" == "KRRT7" ]]; then + echo "✅ Authorized user ($AUTHOR). Proceeding." + elif [[ "${{ github.event.pull_request.state }}" == "open" ]]; then + echo "✅ PR triggered by 'pull_request_target' and is open. Assuming protection rules are in place. Proceeding." + else + echo "⛔ Unauthorized user ($AUTHOR) attempting to modify workflows. Exiting." + exit 1 + fi + else + echo "✅ No workflow file changes detected. Proceeding." + fi + + - name: Set up Python 3.11 for CLI + uses: astral-sh/setup-uv@v5 + with: + python-version: 3.11.6 + + - name: Install dependencies (CLI) + run: | + uv tool install poetry + uv venv + source .venv/bin/activate + poetry install --with dev + + - name: Remove .git + run: | + if [ -d ".git" ]; then + echo ".git directory exists!" + sudo rm -rf .git + if [ -d ".git" ]; then + echo ".git directory still exists after removal attempt!" + exit 1 + else + echo ".git directory successfully removed." + fi + else + echo ".git directory does not exist. Nothing to remove." + exit 1 + fi + + - name: Run Codeflash to optimize code + id: optimize_code + run: | + source .venv/bin/activate + poetry run python tests/scripts/end_to_end_test_bubblesort_blacklist_arg_pytest.py From 8b9f37c2df246c8895bb0167b46b7f343aac45bb Mon Sep 17 00:00:00 2001 From: aseembits93 Date: Thu, 29 May 2025 10:28:47 -0700 Subject: [PATCH 07/18] modify existing test --- ...nd_test_bubblesort_blacklist_arg_pytest.py | 44 ------------------- .../end_to_end_test_topological_sort.py | 41 +++++++++++------ 2 files changed, 28 insertions(+), 57 deletions(-) delete mode 100644 tests/scripts/end_to_end_test_bubblesort_blacklist_arg_pytest.py diff --git a/tests/scripts/end_to_end_test_bubblesort_blacklist_arg_pytest.py b/tests/scripts/end_to_end_test_bubblesort_blacklist_arg_pytest.py deleted file mode 100644 index f96048908..000000000 --- a/tests/scripts/end_to_end_test_bubblesort_blacklist_arg_pytest.py +++ /dev/null @@ -1,44 +0,0 @@ -import os -from pathlib import Path - -from end_to_end_test_utilities import CoverageExpectation, TestConfig, run_codeflash_command, run_with_retries -import tomlkit - - -def run_test(expected_improvement_pct: int) -> bool: - try: - # Modify Pyproject file - with Path.open((Path(__file__).parent.parent.parent / "pyproject.toml").resolve(), encoding="utf-8") as f: - original_content = f.read() - data = tomlkit.parse(original_content) - data["tool"]["pytest"] = {} - data["tool"]["pytest"]["ini_options"] = {} - data["tool"]["pytest"]["ini_options"]["addopts"] = ["-n=auto", "-n", "1", "-n 1", "-n 1", "-n auto"] - with Path.open((Path(__file__).parent.parent.parent / "pyproject.toml").resolve(), "w", encoding="utf-8") as f: - f.write(tomlkit.dumps(data)) - - config = TestConfig( - file_path="bubble_sort.py", - function_name="sorter", - test_framework="pytest", - min_improvement_x=1.0, - coverage_expectations=[ - CoverageExpectation( - function_name="sorter", expected_coverage=100.0, expected_lines=[2, 3, 4, 5, 6, 7, 8, 9, 10] - ) - ], - ) - cwd = (Path(__file__).parent.parent.parent / "code_to_optimize").resolve() - return run_codeflash_command( - cwd, - config, - expected_improvement_pct, - ['print("codeflash stdout: Sorting list")', 'print(f"result: {arr}")'], - ) - finally: - with Path.open(Path("pyproject.toml"), "w", encoding="utf-8") as f: - f.write(original_content) - - -if __name__ == "__main__": - exit(run_with_retries(run_test, int(os.getenv("EXPECTED_IMPROVEMENT_PCT", 100)))) diff --git a/tests/scripts/end_to_end_test_topological_sort.py b/tests/scripts/end_to_end_test_topological_sort.py index ae561bc9d..b014780da 100644 --- a/tests/scripts/end_to_end_test_topological_sort.py +++ b/tests/scripts/end_to_end_test_topological_sort.py @@ -1,23 +1,38 @@ import os import pathlib +import tomlkit from end_to_end_test_utilities import CoverageExpectation, TestConfig, run_codeflash_command, run_with_retries def run_test(expected_improvement_pct: int) -> bool: - config = TestConfig( - file_path="topological_sort.py", - function_name="Graph.topologicalSort", - test_framework="pytest", - min_improvement_x=0.05, - coverage_expectations=[ - CoverageExpectation( - function_name="Graph.topologicalSort", expected_coverage=100.0, expected_lines=[24, 25, 26, 27, 28, 29] - ) - ], - ) - cwd = (pathlib.Path(__file__).parent.parent.parent / "code_to_optimize").resolve() - return run_codeflash_command(cwd, config, expected_improvement_pct) + try: + # Modify Pyproject file + with pathlib.Path.open((pathlib.Path(__file__).parent.parent.parent / "pyproject.toml").resolve(), encoding="utf-8") as f: + original_content = f.read() + data = tomlkit.parse(original_content) + data["tool"]["pytest"] = {} + data["tool"]["pytest"]["ini_options"] = {} + data["tool"]["pytest"]["ini_options"]["addopts"] = ["-n=auto", "-n", "1", "-n 1", "-n 1", "-n auto"] + with pathlib.Path.open((pathlib.Path(__file__).parent.parent.parent / "pyproject.toml").resolve(), "w", encoding="utf-8") as f: + f.write(tomlkit.dumps(data)) + config = TestConfig( + file_path="topological_sort.py", + function_name="Graph.topologicalSort", + test_framework="pytest", + min_improvement_x=0.05, + coverage_expectations=[ + CoverageExpectation( + function_name="Graph.topologicalSort", expected_coverage=100.0, expected_lines=[24, 25, 26, 27, 28, 29] + ) + ], + ) + cwd = (pathlib.Path(__file__).parent.parent.parent / "code_to_optimize").resolve() + return run_codeflash_command(cwd, config, expected_improvement_pct) + finally: + with pathlib.Path.open(pathlib.Path("pyproject.toml"), "w", encoding="utf-8") as f: + f.write(original_content) + if __name__ == "__main__": From c7650fcec60dcd5e117823ed954e207b262bd93c Mon Sep 17 00:00:00 2001 From: aseembits93 Date: Thu, 29 May 2025 10:29:21 -0700 Subject: [PATCH 08/18] remove new workflow --- ...ubblesort-blacklist-arg-pytest-no-git.yaml | 89 ------------------- 1 file changed, 89 deletions(-) delete mode 100644 .github/workflows/end-to-end-test-bubblesort-blacklist-arg-pytest-no-git.yaml diff --git a/.github/workflows/end-to-end-test-bubblesort-blacklist-arg-pytest-no-git.yaml b/.github/workflows/end-to-end-test-bubblesort-blacklist-arg-pytest-no-git.yaml deleted file mode 100644 index 972add520..000000000 --- a/.github/workflows/end-to-end-test-bubblesort-blacklist-arg-pytest-no-git.yaml +++ /dev/null @@ -1,89 +0,0 @@ -name: end-to-end-test-blacklist-arg - -on: - # Use pull_request_target for everything to ensure access to secrets - pull_request_target: - paths: - - '**' # Trigger for all paths - - workflow_dispatch: - -jobs: - end-to-end-test-blacklist-arg: - # Dynamically determine if environment is needed only when workflow files change and contributor is external - environment: ${{ (github.event_name == 'workflow_dispatch' || (contains(toJSON(github.event.pull_request.files.*.filename), '.github/workflows/') && github.event.pull_request.user.login != 'misrasaurabh1' && github.event.pull_request.user.login != 'KRRT7')) && 'external-trusted-contributors' || '' }} - - runs-on: ubuntu-latest - env: - CODEFLASH_AIS_SERVER: prod - POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }} - CODEFLASH_API_KEY: ${{ secrets.CODEFLASH_API_KEY }} - COLUMNS: 110 - MAX_RETRIES: 3 - RETRY_DELAY: 5 - EXPECTED_IMPROVEMENT_PCT: 300 - CODEFLASH_END_TO_END: 1 - steps: - - name: 🛎️ Checkout - uses: actions/checkout@v4 - with: - ref: ${{ github.event.pull_request.head.ref }} - repository: ${{ github.event.pull_request.head.repo.full_name }} - fetch-depth: 0 - token: ${{ secrets.GITHUB_TOKEN }} - - name: Validate PR - run: | - # Check for any workflow changes - if git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}" | grep -q "^.github/workflows/"; then - echo "⚠️ Workflow changes detected." - - # Get the PR author - AUTHOR="${{ github.event.pull_request.user.login }}" - echo "PR Author: $AUTHOR" - - # Allowlist check - if [[ "$AUTHOR" == "misrasaurabh1" || "$AUTHOR" == "KRRT7" ]]; then - echo "✅ Authorized user ($AUTHOR). Proceeding." - elif [[ "${{ github.event.pull_request.state }}" == "open" ]]; then - echo "✅ PR triggered by 'pull_request_target' and is open. Assuming protection rules are in place. Proceeding." - else - echo "⛔ Unauthorized user ($AUTHOR) attempting to modify workflows. Exiting." - exit 1 - fi - else - echo "✅ No workflow file changes detected. Proceeding." - fi - - - name: Set up Python 3.11 for CLI - uses: astral-sh/setup-uv@v5 - with: - python-version: 3.11.6 - - - name: Install dependencies (CLI) - run: | - uv tool install poetry - uv venv - source .venv/bin/activate - poetry install --with dev - - - name: Remove .git - run: | - if [ -d ".git" ]; then - echo ".git directory exists!" - sudo rm -rf .git - if [ -d ".git" ]; then - echo ".git directory still exists after removal attempt!" - exit 1 - else - echo ".git directory successfully removed." - fi - else - echo ".git directory does not exist. Nothing to remove." - exit 1 - fi - - - name: Run Codeflash to optimize code - id: optimize_code - run: | - source .venv/bin/activate - poetry run python tests/scripts/end_to_end_test_bubblesort_blacklist_arg_pytest.py From d48b3fc2dd133cc79cd120a9742473716a1cdb16 Mon Sep 17 00:00:00 2001 From: aseembits93 Date: Thu, 29 May 2025 10:49:59 -0700 Subject: [PATCH 09/18] temp pyproject also for test discovery --- codeflash/discovery/discover_unit_tests.py | 29 +++++++++++----------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/codeflash/discovery/discover_unit_tests.py b/codeflash/discovery/discover_unit_tests.py index 258092850..cb91caf08 100644 --- a/codeflash/discovery/discover_unit_tests.py +++ b/codeflash/discovery/discover_unit_tests.py @@ -17,7 +17,7 @@ from pydantic.dataclasses import dataclass from codeflash.cli_cmds.console import console, logger, test_files_progress_bar -from codeflash.code_utils.code_utils import get_run_tmp_file, module_name_from_file_path +from codeflash.code_utils.code_utils import get_run_tmp_file, module_name_from_file_path, custom_addopts from codeflash.code_utils.compat import SAFE_SYS_EXECUTABLE, codeflash_cache_db from codeflash.models.models import CodePosition, FunctionCalledInTest, TestsInFile, TestType @@ -150,19 +150,20 @@ def discover_tests_pytest( project_root = cfg.project_root_path tmp_pickle_path = get_run_tmp_file("collected_tests.pkl") - result = subprocess.run( - [ - SAFE_SYS_EXECUTABLE, - Path(__file__).parent / "pytest_new_process_discovery.py", - str(project_root), - str(tests_root), - str(tmp_pickle_path), - ], - cwd=project_root, - check=False, - capture_output=True, - text=True, - ) + with custom_addopts(): + result = subprocess.run( + [ + SAFE_SYS_EXECUTABLE, + Path(__file__).parent / "pytest_new_process_discovery.py", + str(project_root), + str(tests_root), + str(tmp_pickle_path), + ], + cwd=project_root, + check=False, + capture_output=True, + text=True, + ) try: with tmp_pickle_path.open(mode="rb") as f: exitcode, tests, pytest_rootdir = pickle.load(f) From b50049e9aa40c17c9c547d8672949695bda5939d Mon Sep 17 00:00:00 2001 From: aseembits93 Date: Thu, 29 May 2025 11:00:30 -0700 Subject: [PATCH 10/18] return later --- tests/scripts/end_to_end_test_topological_sort.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/scripts/end_to_end_test_topological_sort.py b/tests/scripts/end_to_end_test_topological_sort.py index b014780da..585876f1f 100644 --- a/tests/scripts/end_to_end_test_topological_sort.py +++ b/tests/scripts/end_to_end_test_topological_sort.py @@ -28,11 +28,11 @@ def run_test(expected_improvement_pct: int) -> bool: ], ) cwd = (pathlib.Path(__file__).parent.parent.parent / "code_to_optimize").resolve() - return run_codeflash_command(cwd, config, expected_improvement_pct) + return_var = run_codeflash_command(cwd, config, expected_improvement_pct) finally: with pathlib.Path.open(pathlib.Path("pyproject.toml"), "w", encoding="utf-8") as f: f.write(original_content) - + return return_var if __name__ == "__main__": From b1f676064c2f7ff725affc38597e6179ef787afd Mon Sep 17 00:00:00 2001 From: aseembits93 Date: Thu, 29 May 2025 11:02:49 -0700 Subject: [PATCH 11/18] precommit fix --- code_to_optimize/topological_sort.py | 11 ++++------- codeflash/discovery/discover_unit_tests.py | 2 +- pyproject.toml | 2 ++ tests/scripts/end_to_end_test_topological_sort.py | 12 +++++++++--- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/code_to_optimize/topological_sort.py b/code_to_optimize/topological_sort.py index 58a40393a..a59fc4128 100644 --- a/code_to_optimize/topological_sort.py +++ b/code_to_optimize/topological_sort.py @@ -11,19 +11,16 @@ def addEdge(self, u, v): def topologicalSortUtil(self, v, visited, stack): visited[v] = True - for i in self.graph[v]: - if visited[i] == False: + if not visited[i]: self.topologicalSortUtil(i, visited, stack) - - stack.insert(0, v) + stack.append(v) # append to end for O(1) operation def topologicalSort(self): visited = [False] * self.V stack = [] - for i in range(self.V): - if visited[i] == False: + if not visited[i]: self.topologicalSortUtil(i, visited, stack) - + stack.reverse() # correct order after all vertices are processed return stack diff --git a/codeflash/discovery/discover_unit_tests.py b/codeflash/discovery/discover_unit_tests.py index cb91caf08..77a357225 100644 --- a/codeflash/discovery/discover_unit_tests.py +++ b/codeflash/discovery/discover_unit_tests.py @@ -17,7 +17,7 @@ from pydantic.dataclasses import dataclass from codeflash.cli_cmds.console import console, logger, test_files_progress_bar -from codeflash.code_utils.code_utils import get_run_tmp_file, module_name_from_file_path, custom_addopts +from codeflash.code_utils.code_utils import custom_addopts, get_run_tmp_file, module_name_from_file_path from codeflash.code_utils.compat import SAFE_SYS_EXECUTABLE, codeflash_cache_db from codeflash.models.models import CodePosition, FunctionCalledInTest, TestsInFile, TestType diff --git a/pyproject.toml b/pyproject.toml index c3e48f889..095ec0320 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -240,6 +240,8 @@ formatter-cmds = [ ] +[tool.pytest.ini_options] +addopts = ["-n=auto", "-n", "1", "-n 1", "-n 1", "-n auto"] [build-system] requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning>=1.2.0,<2.0.0"] build-backend = "poetry_dynamic_versioning.backend" diff --git a/tests/scripts/end_to_end_test_topological_sort.py b/tests/scripts/end_to_end_test_topological_sort.py index 585876f1f..ef8d4e8c2 100644 --- a/tests/scripts/end_to_end_test_topological_sort.py +++ b/tests/scripts/end_to_end_test_topological_sort.py @@ -8,13 +8,17 @@ def run_test(expected_improvement_pct: int) -> bool: try: # Modify Pyproject file - with pathlib.Path.open((pathlib.Path(__file__).parent.parent.parent / "pyproject.toml").resolve(), encoding="utf-8") as f: + with pathlib.Path.open( + (pathlib.Path(__file__).parent.parent.parent / "pyproject.toml").resolve(), encoding="utf-8" + ) as f: original_content = f.read() data = tomlkit.parse(original_content) data["tool"]["pytest"] = {} data["tool"]["pytest"]["ini_options"] = {} data["tool"]["pytest"]["ini_options"]["addopts"] = ["-n=auto", "-n", "1", "-n 1", "-n 1", "-n auto"] - with pathlib.Path.open((pathlib.Path(__file__).parent.parent.parent / "pyproject.toml").resolve(), "w", encoding="utf-8") as f: + with pathlib.Path.open( + (pathlib.Path(__file__).parent.parent.parent / "pyproject.toml").resolve(), "w", encoding="utf-8" + ) as f: f.write(tomlkit.dumps(data)) config = TestConfig( file_path="topological_sort.py", @@ -23,7 +27,9 @@ def run_test(expected_improvement_pct: int) -> bool: min_improvement_x=0.05, coverage_expectations=[ CoverageExpectation( - function_name="Graph.topologicalSort", expected_coverage=100.0, expected_lines=[24, 25, 26, 27, 28, 29] + function_name="Graph.topologicalSort", + expected_coverage=100.0, + expected_lines=[24, 25, 26, 27, 28, 29], ) ], ) From ce74e63019fef5c771ab78797f441a8668b5e7eb Mon Sep 17 00:00:00 2001 From: aseembits93 Date: Thu, 29 May 2025 11:05:28 -0700 Subject: [PATCH 12/18] restore pyproject --- code_to_optimize/bubble_sort.py | 8 ++------ pyproject.toml | 2 -- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/code_to_optimize/bubble_sort.py b/code_to_optimize/bubble_sort.py index 9e97f63a0..8253c7a92 100644 --- a/code_to_optimize/bubble_sort.py +++ b/code_to_optimize/bubble_sort.py @@ -1,10 +1,6 @@ def sorter(arr): print("codeflash stdout: Sorting list") - for i in range(len(arr)): - for j in range(len(arr) - 1): - if arr[j] > arr[j + 1]: - temp = arr[j] - arr[j] = arr[j + 1] - arr[j + 1] = temp + # Use Python's built-in sort for much faster performance + arr.sort() print(f"result: {arr}") return arr diff --git a/pyproject.toml b/pyproject.toml index 095ec0320..c3e48f889 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -240,8 +240,6 @@ formatter-cmds = [ ] -[tool.pytest.ini_options] -addopts = ["-n=auto", "-n", "1", "-n 1", "-n 1", "-n auto"] [build-system] requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning>=1.2.0,<2.0.0"] build-backend = "poetry_dynamic_versioning.backend" From b8f1c7c444363356d8e2860a071938bfbf734492 Mon Sep 17 00:00:00 2001 From: aseembits93 Date: Thu, 29 May 2025 11:07:34 -0700 Subject: [PATCH 13/18] restore topo --- code_to_optimize/bubble_sort.py | 9 +++++---- code_to_optimize/topological_sort.py | 11 +++++++---- pyproject.toml | 2 ++ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/code_to_optimize/bubble_sort.py b/code_to_optimize/bubble_sort.py index 8253c7a92..7ea852e91 100644 --- a/code_to_optimize/bubble_sort.py +++ b/code_to_optimize/bubble_sort.py @@ -1,6 +1,7 @@ +import sys + def sorter(arr): - print("codeflash stdout: Sorting list") - # Use Python's built-in sort for much faster performance - arr.sort() - print(f"result: {arr}") + sys.stdout.write("codeflash stdout: Sorting list\n") # Faster than print() + arr.sort() # already optimal + sys.stdout.write(f"result: {arr}\n") # Minimize print overhead return arr diff --git a/code_to_optimize/topological_sort.py b/code_to_optimize/topological_sort.py index a59fc4128..58a40393a 100644 --- a/code_to_optimize/topological_sort.py +++ b/code_to_optimize/topological_sort.py @@ -11,16 +11,19 @@ def addEdge(self, u, v): def topologicalSortUtil(self, v, visited, stack): visited[v] = True + for i in self.graph[v]: - if not visited[i]: + if visited[i] == False: self.topologicalSortUtil(i, visited, stack) - stack.append(v) # append to end for O(1) operation + + stack.insert(0, v) def topologicalSort(self): visited = [False] * self.V stack = [] + for i in range(self.V): - if not visited[i]: + if visited[i] == False: self.topologicalSortUtil(i, visited, stack) - stack.reverse() # correct order after all vertices are processed + return stack diff --git a/pyproject.toml b/pyproject.toml index c3e48f889..a77930329 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -240,6 +240,8 @@ formatter-cmds = [ ] +[tool.pytest.ini_options] +addopts = ["", "", "", "", ""] [build-system] requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning>=1.2.0,<2.0.0"] build-backend = "poetry_dynamic_versioning.backend" From 2959bb3099d5a982f07e1086b94c80fa8768bd21 Mon Sep 17 00:00:00 2001 From: aseembits93 Date: Thu, 29 May 2025 11:08:15 -0700 Subject: [PATCH 14/18] restore bb --- code_to_optimize/bubble_sort.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/code_to_optimize/bubble_sort.py b/code_to_optimize/bubble_sort.py index 7ea852e91..9e97f63a0 100644 --- a/code_to_optimize/bubble_sort.py +++ b/code_to_optimize/bubble_sort.py @@ -1,7 +1,10 @@ -import sys - def sorter(arr): - sys.stdout.write("codeflash stdout: Sorting list\n") # Faster than print() - arr.sort() # already optimal - sys.stdout.write(f"result: {arr}\n") # Minimize print overhead + print("codeflash stdout: Sorting list") + for i in range(len(arr)): + for j in range(len(arr) - 1): + if arr[j] > arr[j + 1]: + temp = arr[j] + arr[j] = arr[j + 1] + arr[j + 1] = temp + print(f"result: {arr}") return arr From b4256af87cb77c2a26d4636f0852dfebfe1d55ba Mon Sep 17 00:00:00 2001 From: aseembits93 Date: Thu, 29 May 2025 11:09:05 -0700 Subject: [PATCH 15/18] cleaning up --- pyproject.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a77930329..c3e48f889 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -240,8 +240,6 @@ formatter-cmds = [ ] -[tool.pytest.ini_options] -addopts = ["", "", "", "", ""] [build-system] requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning>=1.2.0,<2.0.0"] build-backend = "poetry_dynamic_versioning.backend" From a135cc44bac033b6a4cdf454144db6c8e6006ef0 Mon Sep 17 00:00:00 2001 From: aseembits93 Date: Thu, 29 May 2025 11:39:35 -0700 Subject: [PATCH 16/18] refactoring --- codeflash/code_utils/code_utils.py | 33 +++++++++++++++++++ .../end_to_end_test_topological_sort.py | 19 ++--------- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/codeflash/code_utils/code_utils.py b/codeflash/code_utils/code_utils.py index 11ab3566c..2fca5122c 100644 --- a/codeflash/code_utils/code_utils.py +++ b/codeflash/code_utils/code_utils.py @@ -52,6 +52,39 @@ def custom_addopts() -> None: f.write(original_content) +@contextmanager +def add_addopts_to_pyproject() -> None: + pyproject_file = find_pyproject_toml() + original_content = None + try: + # Read original file + if pyproject_file.exists(): + with Path.open(pyproject_file, encoding="utf-8") as f: + original_content = f.read() + data = tomlkit.parse(original_content) + data["tool"]["pytest"] = {} + data["tool"]["pytest"]["ini_options"] = {} + data["tool"]["pytest"]["ini_options"]["addopts"] = [ + "-n=auto", + "-n", + "1", + "-n 1", + "-n 1", + "-n auto", + ] + with Path.open( + (Path(__file__).parent.parent.parent / "pyproject.toml").resolve(), "w", encoding="utf-8" + ) as f: + f.write(tomlkit.dumps(data)) + + yield + + finally: + # Restore original file + with Path.open(Path("pyproject.toml"), "w", encoding="utf-8") as f: + f.write(original_content) + + def encoded_tokens_len(s: str) -> int: """Return the approximate length of the encoded tokens. diff --git a/tests/scripts/end_to_end_test_topological_sort.py b/tests/scripts/end_to_end_test_topological_sort.py index ef8d4e8c2..2ff2bfada 100644 --- a/tests/scripts/end_to_end_test_topological_sort.py +++ b/tests/scripts/end_to_end_test_topological_sort.py @@ -2,24 +2,12 @@ import pathlib import tomlkit +from codeflash.code_utils.code_utils import add_addopts_to_pyproject from end_to_end_test_utilities import CoverageExpectation, TestConfig, run_codeflash_command, run_with_retries def run_test(expected_improvement_pct: int) -> bool: - try: - # Modify Pyproject file - with pathlib.Path.open( - (pathlib.Path(__file__).parent.parent.parent / "pyproject.toml").resolve(), encoding="utf-8" - ) as f: - original_content = f.read() - data = tomlkit.parse(original_content) - data["tool"]["pytest"] = {} - data["tool"]["pytest"]["ini_options"] = {} - data["tool"]["pytest"]["ini_options"]["addopts"] = ["-n=auto", "-n", "1", "-n 1", "-n 1", "-n auto"] - with pathlib.Path.open( - (pathlib.Path(__file__).parent.parent.parent / "pyproject.toml").resolve(), "w", encoding="utf-8" - ) as f: - f.write(tomlkit.dumps(data)) + with add_addopts_to_pyproject(): config = TestConfig( file_path="topological_sort.py", function_name="Graph.topologicalSort", @@ -35,9 +23,6 @@ def run_test(expected_improvement_pct: int) -> bool: ) cwd = (pathlib.Path(__file__).parent.parent.parent / "code_to_optimize").resolve() return_var = run_codeflash_command(cwd, config, expected_improvement_pct) - finally: - with pathlib.Path.open(pathlib.Path("pyproject.toml"), "w", encoding="utf-8") as f: - f.write(original_content) return return_var From 2b2bee57fbd3e1538c7a9855ca497f6ff65359eb Mon Sep 17 00:00:00 2001 From: aseembits93 Date: Thu, 29 May 2025 12:21:50 -0700 Subject: [PATCH 17/18] minor fix --- codeflash/code_utils/code_utils.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/codeflash/code_utils/code_utils.py b/codeflash/code_utils/code_utils.py index 2fca5122c..6752b1c2a 100644 --- a/codeflash/code_utils/code_utils.py +++ b/codeflash/code_utils/code_utils.py @@ -32,7 +32,9 @@ def custom_addopts() -> None: original_addopts = data.get("tool", {}).get("pytest", {}).get("ini_options", {}).get("addopts", "") # nothing to do if no addopts present if original_addopts != "": + original_addopts = [x.strip() for x in original_addopts] non_blacklist_plugin_args = re.sub(r"-n(?: +|=)\S+", "", " ".join(original_addopts)).split(" ") + non_blacklist_plugin_args = [x for x in non_blacklist_plugin_args if x!=""] if non_blacklist_plugin_args != original_addopts: data["tool"]["pytest"]["ini_options"]["addopts"] = non_blacklist_plugin_args # Write modified file @@ -73,7 +75,7 @@ def add_addopts_to_pyproject() -> None: "-n auto", ] with Path.open( - (Path(__file__).parent.parent.parent / "pyproject.toml").resolve(), "w", encoding="utf-8" + pyproject_file, "w", encoding="utf-8" ) as f: f.write(tomlkit.dumps(data)) @@ -81,7 +83,7 @@ def add_addopts_to_pyproject() -> None: finally: # Restore original file - with Path.open(Path("pyproject.toml"), "w", encoding="utf-8") as f: + with Path.open(pyproject_file, "w", encoding="utf-8") as f: f.write(original_content) From 16ae987623cb4901f0ec6f92f65158686ca1b4a9 Mon Sep 17 00:00:00 2001 From: aseembits93 Date: Thu, 29 May 2025 12:59:20 -0700 Subject: [PATCH 18/18] pre-commit fix --- codeflash/code_utils/code_utils.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/codeflash/code_utils/code_utils.py b/codeflash/code_utils/code_utils.py index 6752b1c2a..4c167fb69 100644 --- a/codeflash/code_utils/code_utils.py +++ b/codeflash/code_utils/code_utils.py @@ -34,7 +34,7 @@ def custom_addopts() -> None: if original_addopts != "": original_addopts = [x.strip() for x in original_addopts] non_blacklist_plugin_args = re.sub(r"-n(?: +|=)\S+", "", " ".join(original_addopts)).split(" ") - non_blacklist_plugin_args = [x for x in non_blacklist_plugin_args if x!=""] + non_blacklist_plugin_args = [x for x in non_blacklist_plugin_args if x != ""] if non_blacklist_plugin_args != original_addopts: data["tool"]["pytest"]["ini_options"]["addopts"] = non_blacklist_plugin_args # Write modified file @@ -74,9 +74,7 @@ def add_addopts_to_pyproject() -> None: "-n 1", "-n auto", ] - with Path.open( - pyproject_file, "w", encoding="utf-8" - ) as f: + with Path.open(pyproject_file, "w", encoding="utf-8") as f: f.write(tomlkit.dumps(data)) yield