Skip to content

Commit e27c133

Browse files
authored
Merge pull request #779 from codeflash-ai/codeflash/optimize-pr769-2025-09-27T01.33.17
⚡️ Speed up function `remove_functions_from_generated_tests` by 23% in PR #769 (`clean-async-branch`)
2 parents 6116fc6 + 7a6a432 commit e27c133

File tree

1 file changed

+33
-15
lines changed

1 file changed

+33
-15
lines changed

codeflash/code_utils/edit_generated_tests.py

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -207,23 +207,41 @@ def add_runtime_comments_to_generated_tests(
207207
def remove_functions_from_generated_tests(
208208
generated_tests: GeneratedTestsList, test_functions_to_remove: list[str]
209209
) -> GeneratedTestsList:
210+
# Pre-compile patterns for all function names to remove
211+
function_patterns = _compile_function_patterns(test_functions_to_remove)
210212
new_generated_tests = []
211-
for generated_test in generated_tests.generated_tests:
212-
for test_function in test_functions_to_remove:
213-
function_pattern = re.compile(
214-
rf"(@pytest\.mark\.parametrize\(.*?\)\s*)?(async\s+)?def\s+{re.escape(test_function)}\(.*?\):.*?(?=\n(async\s+)?def\s|$)",
215-
re.DOTALL,
216-
)
217-
218-
match = function_pattern.search(generated_test.generated_original_test_source)
219-
220-
if match is None or "@pytest.mark.parametrize" in match.group(0):
221-
continue
222-
223-
generated_test.generated_original_test_source = function_pattern.sub(
224-
"", generated_test.generated_original_test_source
225-
)
226213

214+
for generated_test in generated_tests.generated_tests:
215+
source = generated_test.generated_original_test_source
216+
217+
# Apply all patterns without redundant searches
218+
for pattern in function_patterns:
219+
# Use finditer and sub only if necessary to avoid unnecessary .search()/.sub() calls
220+
for match in pattern.finditer(source):
221+
# Skip if "@pytest.mark.parametrize" present
222+
# Only the matched function's code is targeted
223+
if "@pytest.mark.parametrize" in match.group(0):
224+
continue
225+
# Remove function from source
226+
# If match, remove the function by substitution in the source
227+
# Replace using start/end indices for efficiency
228+
start, end = match.span()
229+
source = source[:start] + source[end:]
230+
# After removal, break since .finditer() is from left to right, and only one match expected per function in source
231+
break
232+
233+
generated_test.generated_original_test_source = source
227234
new_generated_tests.append(generated_test)
228235

229236
return GeneratedTestsList(generated_tests=new_generated_tests)
237+
238+
239+
# Pre-compile all function removal regexes upfront for efficiency.
240+
def _compile_function_patterns(test_functions_to_remove: list[str]) -> list[re.Pattern[str]]:
241+
return [
242+
re.compile(
243+
rf"(@pytest\.mark\.parametrize\(.*?\)\s*)?(async\s+)?def\s+{re.escape(func)}\(.*?\):.*?(?=\n(async\s+)?def\s|$)",
244+
re.DOTALL,
245+
)
246+
for func in test_functions_to_remove
247+
]

0 commit comments

Comments
 (0)