Skip to content

Commit 321640c

Browse files
authored
CF-900 allow async optimizations by default (#938)
* remove --async * include it by default * don't crash for --async * pre-commit
1 parent f7d97b2 commit 321640c

File tree

8 files changed

+17
-63
lines changed

8 files changed

+17
-63
lines changed

codeflash/cli_cmds/cli.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import importlib.util
21
import logging
32
import sys
43
from argparse import SUPPRESS, ArgumentParser, Namespace
@@ -104,7 +103,7 @@ def parse_args() -> Namespace:
104103
"--async",
105104
default=False,
106105
action="store_true",
107-
help="Enable optimization of async functions. By default, async functions are excluded from optimization.",
106+
help="(Deprecated) Async function optimization is now enabled by default. This flag is ignored.",
108107
)
109108

110109
args, unknown_args = parser.parse_known_args()
@@ -155,13 +154,11 @@ def process_and_validate_cmd_args(args: Namespace) -> Namespace:
155154
if env_utils.is_ci():
156155
args.no_pr = True
157156

158-
if getattr(args, "async", False) and importlib.util.find_spec("pytest_asyncio") is None:
157+
if getattr(args, "async", False):
159158
logger.warning(
160-
"Warning: The --async flag requires pytest-asyncio to be installed.\n"
161-
"Please install it using:\n"
162-
' pip install "codeflash[asyncio]"'
159+
"The --async flag is deprecated and will be removed in a future version. "
160+
"Async function optimization is now enabled by default."
163161
)
164-
raise SystemExit(1)
165162

166163
return args
167164

codeflash/discovery/functions_to_optimize.py

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,6 @@ def get_functions_to_optimize(
179179
project_root: Path,
180180
module_root: Path,
181181
previous_checkpoint_functions: dict[str, dict[str, str]] | None = None,
182-
*,
183-
enable_async: bool = False,
184182
) -> tuple[dict[Path, list[FunctionToOptimize]], int, Path | None]:
185183
assert sum([bool(optimize_all), bool(replay_test), bool(file)]) <= 1, (
186184
"Only one of optimize_all, replay_test, or file should be provided"
@@ -242,13 +240,7 @@ def get_functions_to_optimize(
242240
ph("cli-optimizing-git-diff")
243241
functions = get_functions_within_git_diff(uncommitted_changes=False)
244242
filtered_modified_functions, functions_count = filter_functions(
245-
functions,
246-
test_cfg.tests_root,
247-
ignore_paths,
248-
project_root,
249-
module_root,
250-
previous_checkpoint_functions,
251-
enable_async=enable_async,
243+
functions, test_cfg.tests_root, ignore_paths, project_root, module_root, previous_checkpoint_functions
252244
)
253245

254246
logger.info(f"!lsp|Found {functions_count} function{'s' if functions_count > 1 else ''} to optimize")
@@ -658,7 +650,6 @@ def filter_functions(
658650
previous_checkpoint_functions: dict[Path, dict[str, Any]] | None = None,
659651
*,
660652
disable_logs: bool = False,
661-
enable_async: bool = False,
662653
) -> tuple[dict[Path, list[FunctionToOptimize]], int]:
663654
filtered_modified_functions: dict[str, list[FunctionToOptimize]] = {}
664655
blocklist_funcs = get_blocklisted_functions()
@@ -678,7 +669,6 @@ def filter_functions(
678669
submodule_ignored_paths_count: int = 0
679670
blocklist_funcs_removed_count: int = 0
680671
previous_checkpoint_functions_removed_count: int = 0
681-
async_functions_removed_count: int = 0
682672
tests_root_str = str(tests_root)
683673
module_root_str = str(module_root)
684674

@@ -734,15 +724,6 @@ def filter_functions(
734724
functions_tmp.append(function)
735725
_functions = functions_tmp
736726

737-
if not enable_async:
738-
functions_tmp = []
739-
for function in _functions:
740-
if function.is_async:
741-
async_functions_removed_count += 1
742-
continue
743-
functions_tmp.append(function)
744-
_functions = functions_tmp
745-
746727
filtered_modified_functions[file_path] = _functions
747728
functions_count += len(_functions)
748729

@@ -756,7 +737,6 @@ def filter_functions(
756737
"Files from ignored submodules": (submodule_ignored_paths_count, "bright_black"),
757738
"Blocklisted functions removed": (blocklist_funcs_removed_count, "bright_red"),
758739
"Functions skipped from checkpoint": (previous_checkpoint_functions_removed_count, "green"),
759-
"Async functions removed": (async_functions_removed_count, "bright_magenta"),
760740
}
761741
tree = Tree(Text("Ignored functions and files", style="bold"))
762742
for label, (count, color) in log_info.items():

codeflash/optimization/optimizer.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ def get_optimizable_functions(self) -> tuple[dict[Path, list[FunctionToOptimize]
134134
project_root=self.args.project_root,
135135
module_root=self.args.module_root,
136136
previous_checkpoint_functions=self.args.previous_checkpoint_functions,
137-
enable_async=getattr(self.args, "async", False),
138137
)
139138

140139
def create_function_optimizer(

pyproject.toml

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ dependencies = [
4444
"pygls>=2.0.0,<3.0.0",
4545
"codeflash-benchmark",
4646
"filelock",
47+
"pytest-asyncio>=1.2.0",
4748
]
4849

4950
[project.urls]
@@ -53,13 +54,9 @@ Homepage = "https://codeflash.ai"
5354
codeflash = "codeflash.main:main"
5455

5556
[project.optional-dependencies]
56-
asyncio = [
57-
"pytest-asyncio>=1.2.0",
58-
]
5957

6058
[dependency-groups]
6159
dev = [
62-
{include-group = "asyncio"},
6360
"ipython>=8.12.0",
6461
"mypy>=1.13",
6562
"ruff>=0.7.0",
@@ -82,9 +79,6 @@ dev = [
8279
"uv>=0.6.2",
8380
"pre-commit>=4.2.0,<5",
8481
]
85-
asyncio = [
86-
"pytest-asyncio>=1.2.0",
87-
]
8882
tests = [
8983
"black>=25.9.0",
9084
"jax>=0.4.30",

tests/scripts/end_to_end_test_async.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ def run_test(expected_improvement_pct: int) -> bool:
88
config = TestConfig(
99
file_path="main.py",
1010
min_improvement_x=0.1,
11-
enable_async=True,
1211
coverage_expectations=[
1312
CoverageExpectation(
1413
function_name="retry_with_backoff",

tests/scripts/end_to_end_test_utilities.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ class TestConfig:
2727
trace_mode: bool = False
2828
coverage_expectations: list[CoverageExpectation] = field(default_factory=list)
2929
benchmarks_root: Optional[pathlib.Path] = None
30-
enable_async: bool = False
3130
use_worktree: bool = False
3231

3332

@@ -136,8 +135,6 @@ def build_command(
136135
)
137136
if benchmarks_root:
138137
base_command.extend(["--benchmark", "--benchmarks-root", str(benchmarks_root)])
139-
if config.enable_async:
140-
base_command.append("--async")
141138
if config.use_worktree:
142139
base_command.append("--worktree")
143140
return base_command

tests/test_async_function_discovery.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,6 @@ def sync_method(self):
244244
ignore_paths=[],
245245
project_root=file_path.parent,
246246
module_root=file_path.parent,
247-
enable_async=True,
248247
)
249248

250249
assert functions_count == 4
@@ -259,7 +258,8 @@ def sync_method(self):
259258

260259

261260
@pytest.mark.skipif(sys.platform == "win32", reason="pending support for asyncio on windows")
262-
def test_no_async_functions_finding(temp_dir):
261+
def test_async_functions_always_included(temp_dir):
262+
"""Test that async functions are always included now (no longer filtered out)."""
263263
mixed_code = """
264264
async def async_func_one():
265265
return await operation_one()
@@ -297,16 +297,17 @@ def sync_method(self):
297297
ignore_paths=[],
298298
project_root=file_path.parent,
299299
module_root=file_path.parent,
300-
enable_async=False,
301300
)
302301

303-
assert functions_count == 2
302+
# Now async functions are always included, so we expect 4 functions (not 2)
303+
assert functions_count == 4
304304

305305
function_names = [fn.function_name for fn in functions[file_path]]
306306
assert "sync_func_one" in function_names
307307
assert "sync_method" in function_names
308-
assert "async_func_one" not in function_names
309-
assert "async_method" not in function_names
308+
# Async functions are now included by default
309+
assert "async_func_one" in function_names
310+
assert "async_method" in function_names
310311

311312

312313
@pytest.mark.skipif(sys.platform == "win32", reason="pending support for asyncio on windows")

uv.lock

Lines changed: 4 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)