|
60 | 60 | from codeflash.context import code_context_extractor
|
61 | 61 | from codeflash.context.unused_definition_remover import detect_unused_helper_functions, revert_unused_helper_functions
|
62 | 62 | from codeflash.discovery.functions_to_optimize import was_function_previously_optimized
|
63 |
| -from codeflash.either import Failure, Success, is_successful |
| 63 | +from codeflash.either import CodeflashError, Failure, Success, is_successful |
| 64 | +from codeflash.errors.errors import ( |
| 65 | + baseline_establishment_failed_error, |
| 66 | + behavioral_test_failure_error, |
| 67 | + code_context_extraction_failed_error, |
| 68 | + coverage_threshold_not_met_error, |
| 69 | + function_optimization_attempted_error, |
| 70 | + no_best_optimization_found_error, |
| 71 | + no_optimizations_generated_error, |
| 72 | + no_tests_generated_error, |
| 73 | + test_confidence_threshold_not_met_error, |
| 74 | + test_result_didnt_match_error, |
| 75 | +) |
64 | 76 | from codeflash.models.ExperimentMetadata import ExperimentMetadata
|
65 | 77 | from codeflash.models.models import (
|
66 | 78 | BestOptimization,
|
@@ -252,14 +264,18 @@ def can_be_optimized(self) -> Result[tuple[bool, CodeOptimizationContext, dict[P
|
252 | 264 | has_any_async_functions(code_string.code) for code_string in code_context.read_writable_code.code_strings
|
253 | 265 | )
|
254 | 266 | if async_code:
|
255 |
| - return Failure("Codeflash does not support async functions in the code to optimize.") |
| 267 | + return Failure( |
| 268 | + CodeflashError( |
| 269 | + "ASYNC_CODE_ERROR", "Codeflash does not support async functions in the code to optimize." |
| 270 | + ) |
| 271 | + ) |
256 | 272 | # Random here means that we still attempt optimization with a fractional chance to see if
|
257 | 273 | # last time we could not find an optimization, maybe this time we do.
|
258 | 274 | # Random is before as a performance optimization, swapping the two 'and' statements has the same effect
|
259 | 275 | if random.random() > REPEAT_OPTIMIZATION_PROBABILITY and was_function_previously_optimized( # noqa: S311
|
260 | 276 | self.function_to_optimize, code_context, self.args
|
261 | 277 | ):
|
262 |
| - return Failure("Function optimization previously attempted, skipping.") |
| 278 | + return Failure(function_optimization_attempted_error()) |
263 | 279 |
|
264 | 280 | return Success((should_run_experiment, code_context, original_helper_code))
|
265 | 281 |
|
@@ -430,7 +446,7 @@ def optimize_function(self) -> Result[BestOptimization, str]:
|
430 | 446 | if self.args.override_fixtures:
|
431 | 447 | restore_conftest(original_conftest_content)
|
432 | 448 | if not best_optimization:
|
433 |
| - return Failure(f"No best optimizations found for function {self.function_to_optimize.qualified_name}") |
| 449 | + return Failure(no_best_optimization_found_error(self.function_to_optimize.qualified_name)) |
434 | 450 | return Success(best_optimization)
|
435 | 451 |
|
436 | 452 | def determine_best_candidate(
|
@@ -852,7 +868,7 @@ def get_code_optimization_context(self) -> Result[CodeOptimizationContext, str]:
|
852 | 868 | self.function_to_optimize, self.project_root
|
853 | 869 | )
|
854 | 870 | except ValueError as e:
|
855 |
| - return Failure(str(e)) |
| 871 | + return Failure(code_context_extraction_failed_error(str(e))) |
856 | 872 |
|
857 | 873 | return Success(
|
858 | 874 | CodeOptimizationContext(
|
@@ -1012,7 +1028,7 @@ def generate_tests_and_optimizations(
|
1012 | 1028 | # Retrieve results
|
1013 | 1029 | candidates: list[OptimizedCandidate] = future_optimization_candidates.result()
|
1014 | 1030 | if not candidates:
|
1015 |
| - return Failure(f"/!\\ NO OPTIMIZATIONS GENERATED for {self.function_to_optimize.function_name}") |
| 1031 | + return Failure(no_optimizations_generated_error(self.function_to_optimize.function_name)) |
1016 | 1032 |
|
1017 | 1033 | candidates_experiment = future_candidates_exp.result() if future_candidates_exp else None
|
1018 | 1034 |
|
@@ -1040,7 +1056,7 @@ def generate_tests_and_optimizations(
|
1040 | 1056 | )
|
1041 | 1057 | if not tests:
|
1042 | 1058 | logger.warning(f"Failed to generate and instrument tests for {self.function_to_optimize.function_name}")
|
1043 |
| - return Failure(f"/!\\ NO TESTS GENERATED for {self.function_to_optimize.function_name}") |
| 1059 | + return Failure(no_tests_generated_error(self.function_to_optimize.function_name)) |
1044 | 1060 | function_to_concolic_tests, concolic_test_str = future_concolic_tests.result()
|
1045 | 1061 | logger.info(f"Generated {len(tests)} tests for {self.function_to_optimize.function_name}")
|
1046 | 1062 | console.rule()
|
@@ -1100,14 +1116,21 @@ def setup_and_establish_baseline(
|
1100 | 1116 | return Failure(baseline_result.failure())
|
1101 | 1117 |
|
1102 | 1118 | original_code_baseline, test_functions_to_remove = baseline_result.unwrap()
|
1103 |
| - if isinstance(original_code_baseline, OriginalCodeBaseline) and ( |
1104 |
| - not coverage_critic(original_code_baseline.coverage_results, self.args.test_framework) |
1105 |
| - or not quantity_of_tests_critic(original_code_baseline) |
1106 |
| - ): |
1107 |
| - if self.args.override_fixtures: |
1108 |
| - restore_conftest(original_conftest_content) |
1109 |
| - cleanup_paths(paths_to_cleanup) |
1110 |
| - return Failure("The threshold for test confidence was not met.") |
| 1119 | + if isinstance(original_code_baseline, OriginalCodeBaseline): |
| 1120 | + error = None |
| 1121 | + sufficent_coverage = coverage_critic(original_code_baseline.coverage_results, self.args.test_framework) |
| 1122 | + sufficent_tests = quantity_of_tests_critic(original_code_baseline) |
| 1123 | + |
| 1124 | + if not sufficent_coverage: |
| 1125 | + error = coverage_threshold_not_met_error() |
| 1126 | + elif not sufficent_tests: |
| 1127 | + error = test_confidence_threshold_not_met_error() |
| 1128 | + |
| 1129 | + if error: |
| 1130 | + if self.args.override_fixtures: |
| 1131 | + restore_conftest(original_conftest_content) |
| 1132 | + cleanup_paths(paths_to_cleanup) |
| 1133 | + return Failure(error) |
1111 | 1134 |
|
1112 | 1135 | return Success(
|
1113 | 1136 | (
|
@@ -1394,9 +1417,9 @@ def establish_original_code_baseline(
|
1394 | 1417 | f"Couldn't run any tests for original function {self.function_to_optimize.function_name}. SKIPPING OPTIMIZING THIS FUNCTION."
|
1395 | 1418 | )
|
1396 | 1419 | console.rule()
|
1397 |
| - return Failure("Failed to establish a baseline for the original code - bevhavioral tests failed.") |
| 1420 | + return Failure(behavioral_test_failure_error()) |
1398 | 1421 | if not coverage_critic(coverage_results, self.args.test_framework):
|
1399 |
| - return Failure("The threshold for test coverage was not met.") |
| 1422 | + return Failure(coverage_threshold_not_met_error()) |
1400 | 1423 | if test_framework == "pytest":
|
1401 | 1424 | line_profile_results = self.line_profiler_step(
|
1402 | 1425 | code_context=code_context, original_helper_code=original_helper_code, candidate_index=0
|
@@ -1456,7 +1479,7 @@ def establish_original_code_baseline(
|
1456 | 1479 | console.rule()
|
1457 | 1480 | success = False
|
1458 | 1481 | if not success:
|
1459 |
| - return Failure("Failed to establish a baseline for the original code.") |
| 1482 | + return Failure(baseline_establishment_failed_error()) |
1460 | 1483 |
|
1461 | 1484 | loop_count = max([int(result.loop_index) for result in benchmarking_results.test_results])
|
1462 | 1485 | logger.info(
|
@@ -1540,7 +1563,7 @@ def run_optimized_candidate(
|
1540 | 1563 | else:
|
1541 | 1564 | logger.info("Test results did not match the test results of the original code.")
|
1542 | 1565 | console.rule()
|
1543 |
| - return Failure("Test results did not match the test results of the original code.") |
| 1566 | + return Failure(test_result_didnt_match_error()) |
1544 | 1567 |
|
1545 | 1568 | if test_framework == "pytest":
|
1546 | 1569 | candidate_benchmarking_results, _ = self.run_and_parse_tests(
|
|
0 commit comments