From 074e49f52d88106a9e20ef05bf20a06910bbfd7b Mon Sep 17 00:00:00 2001 From: Kevin Turcios Date: Sun, 23 Nov 2025 15:54:45 -0500 Subject: [PATCH 1/4] remove --async --- codeflash/cli_cmds/cli.py | 15 --------------- codeflash/discovery/functions_to_optimize.py | 15 --------------- codeflash/optimization/optimizer.py | 1 - tests/scripts/end_to_end_test_async.py | 1 - tests/scripts/end_to_end_test_utilities.py | 3 --- tests/test_async_function_discovery.py | 13 +++++++------ 6 files changed, 7 insertions(+), 41 deletions(-) diff --git a/codeflash/cli_cmds/cli.py b/codeflash/cli_cmds/cli.py index 847abe1eb..fbefdc08b 100644 --- a/codeflash/cli_cmds/cli.py +++ b/codeflash/cli_cmds/cli.py @@ -1,4 +1,3 @@ -import importlib.util import logging import sys from argparse import SUPPRESS, ArgumentParser, Namespace @@ -100,12 +99,6 @@ def parse_args() -> Namespace: ) parser.add_argument("--no-draft", default=False, action="store_true", help="Skip optimization for draft PRs") parser.add_argument("--worktree", default=False, action="store_true", help="Use worktree for optimization") - parser.add_argument( - "--async", - default=False, - action="store_true", - help="Enable optimization of async functions. By default, async functions are excluded from optimization.", - ) args, unknown_args = parser.parse_known_args() sys.argv[:] = [sys.argv[0], *unknown_args] @@ -155,14 +148,6 @@ def process_and_validate_cmd_args(args: Namespace) -> Namespace: if env_utils.is_ci(): args.no_pr = True - if getattr(args, "async", False) and importlib.util.find_spec("pytest_asyncio") is None: - logger.warning( - "Warning: The --async flag requires pytest-asyncio to be installed.\n" - "Please install it using:\n" - ' pip install "codeflash[asyncio]"' - ) - raise SystemExit(1) - return args diff --git a/codeflash/discovery/functions_to_optimize.py b/codeflash/discovery/functions_to_optimize.py index e2727224e..ee54e14e2 100644 --- a/codeflash/discovery/functions_to_optimize.py +++ b/codeflash/discovery/functions_to_optimize.py @@ -179,8 +179,6 @@ def get_functions_to_optimize( project_root: Path, module_root: Path, previous_checkpoint_functions: dict[str, dict[str, str]] | None = None, - *, - enable_async: bool = False, ) -> tuple[dict[Path, list[FunctionToOptimize]], int, Path | None]: assert sum([bool(optimize_all), bool(replay_test), bool(file)]) <= 1, ( "Only one of optimize_all, replay_test, or file should be provided" @@ -248,7 +246,6 @@ def get_functions_to_optimize( project_root, module_root, previous_checkpoint_functions, - enable_async=enable_async, ) logger.info(f"!lsp|Found {functions_count} function{'s' if functions_count > 1 else ''} to optimize") @@ -658,7 +655,6 @@ def filter_functions( previous_checkpoint_functions: dict[Path, dict[str, Any]] | None = None, *, disable_logs: bool = False, - enable_async: bool = False, ) -> tuple[dict[Path, list[FunctionToOptimize]], int]: filtered_modified_functions: dict[str, list[FunctionToOptimize]] = {} blocklist_funcs = get_blocklisted_functions() @@ -678,7 +674,6 @@ def filter_functions( submodule_ignored_paths_count: int = 0 blocklist_funcs_removed_count: int = 0 previous_checkpoint_functions_removed_count: int = 0 - async_functions_removed_count: int = 0 tests_root_str = str(tests_root) module_root_str = str(module_root) @@ -734,15 +729,6 @@ def filter_functions( functions_tmp.append(function) _functions = functions_tmp - if not enable_async: - functions_tmp = [] - for function in _functions: - if function.is_async: - async_functions_removed_count += 1 - continue - functions_tmp.append(function) - _functions = functions_tmp - filtered_modified_functions[file_path] = _functions functions_count += len(_functions) @@ -756,7 +742,6 @@ def filter_functions( "Files from ignored submodules": (submodule_ignored_paths_count, "bright_black"), "Blocklisted functions removed": (blocklist_funcs_removed_count, "bright_red"), "Functions skipped from checkpoint": (previous_checkpoint_functions_removed_count, "green"), - "Async functions removed": (async_functions_removed_count, "bright_magenta"), } tree = Tree(Text("Ignored functions and files", style="bold")) for label, (count, color) in log_info.items(): diff --git a/codeflash/optimization/optimizer.py b/codeflash/optimization/optimizer.py index 38b7f0d37..ddbb894d1 100644 --- a/codeflash/optimization/optimizer.py +++ b/codeflash/optimization/optimizer.py @@ -134,7 +134,6 @@ def get_optimizable_functions(self) -> tuple[dict[Path, list[FunctionToOptimize] project_root=self.args.project_root, module_root=self.args.module_root, previous_checkpoint_functions=self.args.previous_checkpoint_functions, - enable_async=getattr(self.args, "async", False), ) def create_function_optimizer( diff --git a/tests/scripts/end_to_end_test_async.py b/tests/scripts/end_to_end_test_async.py index 09bcd2bb7..8cdf050ed 100644 --- a/tests/scripts/end_to_end_test_async.py +++ b/tests/scripts/end_to_end_test_async.py @@ -8,7 +8,6 @@ def run_test(expected_improvement_pct: int) -> bool: config = TestConfig( file_path="main.py", min_improvement_x=0.1, - enable_async=True, coverage_expectations=[ CoverageExpectation( function_name="retry_with_backoff", diff --git a/tests/scripts/end_to_end_test_utilities.py b/tests/scripts/end_to_end_test_utilities.py index ede7c3a49..8ab1a4f8d 100644 --- a/tests/scripts/end_to_end_test_utilities.py +++ b/tests/scripts/end_to_end_test_utilities.py @@ -27,7 +27,6 @@ class TestConfig: trace_mode: bool = False coverage_expectations: list[CoverageExpectation] = field(default_factory=list) benchmarks_root: Optional[pathlib.Path] = None - enable_async: bool = False use_worktree: bool = False @@ -136,8 +135,6 @@ def build_command( ) if benchmarks_root: base_command.extend(["--benchmark", "--benchmarks-root", str(benchmarks_root)]) - if config.enable_async: - base_command.append("--async") if config.use_worktree: base_command.append("--worktree") return base_command diff --git a/tests/test_async_function_discovery.py b/tests/test_async_function_discovery.py index 16f4c0d45..0cb0d23f4 100644 --- a/tests/test_async_function_discovery.py +++ b/tests/test_async_function_discovery.py @@ -244,7 +244,6 @@ def sync_method(self): ignore_paths=[], project_root=file_path.parent, module_root=file_path.parent, - enable_async=True, ) assert functions_count == 4 @@ -259,7 +258,8 @@ def sync_method(self): @pytest.mark.skipif(sys.platform == "win32", reason="pending support for asyncio on windows") -def test_no_async_functions_finding(temp_dir): +def test_async_functions_always_included(temp_dir): + """Test that async functions are always included now (no longer filtered out).""" mixed_code = """ async def async_func_one(): return await operation_one() @@ -297,16 +297,17 @@ def sync_method(self): ignore_paths=[], project_root=file_path.parent, module_root=file_path.parent, - enable_async=False, ) - assert functions_count == 2 + # Now async functions are always included, so we expect 4 functions (not 2) + assert functions_count == 4 function_names = [fn.function_name for fn in functions[file_path]] assert "sync_func_one" in function_names assert "sync_method" in function_names - assert "async_func_one" not in function_names - assert "async_method" not in function_names + # Async functions are now included by default + assert "async_func_one" in function_names + assert "async_method" in function_names @pytest.mark.skipif(sys.platform == "win32", reason="pending support for asyncio on windows") From 313e957b3d3f8cac3b29762a48f3ff195448bd13 Mon Sep 17 00:00:00 2001 From: Kevin Turcios Date: Sun, 23 Nov 2025 15:56:17 -0500 Subject: [PATCH 2/4] include it by default --- pyproject.toml | 8 +------- uv.lock | 21 ++++----------------- 2 files changed, 5 insertions(+), 24 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9473a0811..ef036c321 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,6 +44,7 @@ dependencies = [ "pygls>=2.0.0,<3.0.0", "codeflash-benchmark", "filelock", + "pytest-asyncio>=1.2.0", ] [project.urls] @@ -53,13 +54,9 @@ Homepage = "https://codeflash.ai" codeflash = "codeflash.main:main" [project.optional-dependencies] -asyncio = [ - "pytest-asyncio>=1.2.0", -] [dependency-groups] dev = [ - {include-group = "asyncio"}, "ipython>=8.12.0", "mypy>=1.13", "ruff>=0.7.0", @@ -82,9 +79,6 @@ dev = [ "uv>=0.6.2", "pre-commit>=4.2.0,<5", ] -asyncio = [ - "pytest-asyncio>=1.2.0", -] tests = [ "black>=25.9.0", "jax>=0.4.30", diff --git a/uv.lock b/uv.lock index 1177e7333..a75782117 100644 --- a/uv.lock +++ b/uv.lock @@ -335,6 +335,8 @@ dependencies = [ { name = "pygls" }, { name = "pytest", version = "8.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "pytest", version = "9.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "pytest-asyncio", version = "1.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "pytest-asyncio", version = "1.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, { name = "pytest-timeout" }, { name = "rich" }, { name = "sentry-sdk" }, @@ -344,17 +346,7 @@ dependencies = [ { name = "unittest-xml-reporting" }, ] -[package.optional-dependencies] -asyncio = [ - { name = "pytest-asyncio", version = "1.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "pytest-asyncio", version = "1.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, -] - [package.dev-dependencies] -asyncio = [ - { name = "pytest-asyncio", version = "1.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "pytest-asyncio", version = "1.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, -] dev = [ { name = "ipython", version = "8.18.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "ipython", version = "8.37.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" }, @@ -365,8 +357,6 @@ dev = [ { name = "pandas-stubs", version = "2.2.2.240909", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, { name = "pre-commit", version = "4.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "pre-commit", version = "4.4.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, - { name = "pytest-asyncio", version = "1.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "pytest-asyncio", version = "1.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, { name = "ruff" }, { name = "types-cffi" }, { name = "types-colorama" }, @@ -428,7 +418,7 @@ requires-dist = [ { name = "pydantic", specifier = ">=1.10.1" }, { name = "pygls", specifier = ">=2.0.0,<3.0.0" }, { name = "pytest", specifier = ">=7.0.0" }, - { name = "pytest-asyncio", marker = "extra == 'asyncio'", specifier = ">=1.2.0" }, + { name = "pytest-asyncio", specifier = ">=1.2.0" }, { name = "pytest-timeout", specifier = ">=2.1.0" }, { name = "rich", specifier = ">=13.8.1" }, { name = "sentry-sdk", specifier = ">=1.40.6,<3.0.0" }, @@ -437,17 +427,14 @@ requires-dist = [ { name = "unidiff", specifier = ">=0.7.4" }, { name = "unittest-xml-reporting", specifier = ">=3.2.0" }, ] -provides-extras = ["asyncio"] [package.metadata.requires-dev] -asyncio = [{ name = "pytest-asyncio", specifier = ">=1.2.0" }] dev = [ { name = "ipython", specifier = ">=8.12.0" }, { name = "lxml-stubs", specifier = ">=0.5.1" }, { name = "mypy", specifier = ">=1.13" }, { name = "pandas-stubs", specifier = ">=2.2.2.240807,<2.2.3.241009" }, { name = "pre-commit", specifier = ">=4.2.0,<5" }, - { name = "pytest-asyncio", specifier = ">=1.2.0" }, { name = "ruff", specifier = ">=0.7.0" }, { name = "types-cffi", specifier = ">=1.16.0.20240331" }, { name = "types-colorama", specifier = ">=0.4.15.20240311" }, @@ -841,7 +828,7 @@ name = "exceptiongroup" version = "1.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } wheels = [ From 5513a0079373e19e31e4385c2c67e18ebbb6c84b Mon Sep 17 00:00:00 2001 From: Kevin Turcios Date: Sun, 23 Nov 2025 15:58:41 -0500 Subject: [PATCH 3/4] don't crash for --async --- codeflash/cli_cmds/cli.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/codeflash/cli_cmds/cli.py b/codeflash/cli_cmds/cli.py index fbefdc08b..5ae0eee60 100644 --- a/codeflash/cli_cmds/cli.py +++ b/codeflash/cli_cmds/cli.py @@ -99,6 +99,12 @@ def parse_args() -> Namespace: ) parser.add_argument("--no-draft", default=False, action="store_true", help="Skip optimization for draft PRs") parser.add_argument("--worktree", default=False, action="store_true", help="Use worktree for optimization") + parser.add_argument( + "--async", + default=False, + action="store_true", + help="(Deprecated) Async function optimization is now enabled by default. This flag is ignored.", + ) args, unknown_args = parser.parse_known_args() sys.argv[:] = [sys.argv[0], *unknown_args] @@ -148,6 +154,12 @@ def process_and_validate_cmd_args(args: Namespace) -> Namespace: if env_utils.is_ci(): args.no_pr = True + if getattr(args, "async", False): + logger.warning( + "The --async flag is deprecated and will be removed in a future version. " + "Async function optimization is now enabled by default." + ) + return args From 7fd58892ab311ad290f44a1d06289eed4d6c88bf Mon Sep 17 00:00:00 2001 From: Kevin Turcios Date: Sun, 23 Nov 2025 15:59:21 -0500 Subject: [PATCH 4/4] pre-commit --- codeflash/discovery/functions_to_optimize.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/codeflash/discovery/functions_to_optimize.py b/codeflash/discovery/functions_to_optimize.py index ee54e14e2..b8cf895e1 100644 --- a/codeflash/discovery/functions_to_optimize.py +++ b/codeflash/discovery/functions_to_optimize.py @@ -240,12 +240,7 @@ def get_functions_to_optimize( ph("cli-optimizing-git-diff") functions = get_functions_within_git_diff(uncommitted_changes=False) filtered_modified_functions, functions_count = filter_functions( - functions, - test_cfg.tests_root, - ignore_paths, - project_root, - module_root, - previous_checkpoint_functions, + functions, test_cfg.tests_root, ignore_paths, project_root, module_root, previous_checkpoint_functions ) logger.info(f"!lsp|Found {functions_count} function{'s' if functions_count > 1 else ''} to optimize")