Private
Public Access
feat(scripts): Heuristic A - Result-returning recovery = INTERNAL_COMPLIANT
Phase 11.2. Adds the LEGITIMATE heuristic that recognizes the canonical data-oriented pattern: \ ry: ...; except: return Result(data=..., errors=[...])\ is the convention's canonical recovery pattern. Detection: - New _returns_result(stmts) helper on ExceptionVisitor - New step 0 in _classify_except (BEFORE BOUNDARY_CONVERSION check) - Classifies as INTERNAL_COMPLIANT with a hint that names the pattern The function-name-not-ending-in-_result is documented as a smell (rename to xxx_result for canonical naming), but the pattern itself is compliant. Tests: - 2 new tests in test_audit_exception_handling_heuristics.py: - test_result_returning_recovery_in_non_result_named_function_is_compliant - test_result_returning_recovery_in_result_named_function_is_compliant - Both pass; the 2 REJECTED tests (#22, #23) remain xfailed. Per conductor/tracks/result_migration_small_files_20260617/plan.md section 11.2.
This commit is contained in:
@@ -337,3 +337,61 @@ def test_narrow_except_uses_error_inline_is_compliant():
|
||||
assert excepts[0]["category"] == "INTERNAL_COMPLIANT", (
|
||||
f"narrow except using error inline should be INTERNAL_COMPLIANT, got {excepts[0]['category']}"
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Heuristic A: Result-returning recovery in non-*_result function (Phase 11.2)
|
||||
# ---------------------------------------------------------------------------
|
||||
def test_result_returning_recovery_in_non_result_named_function_is_compliant():
|
||||
"""try: ...; except SpecificError: return Result(data=..., errors=[ErrorInfo(...)]) is compliant.
|
||||
|
||||
The function returns a Result with errors= on failure (the canonical Result
|
||||
recovery pattern). The convention requires Result[T] for try/except sites
|
||||
that can fail; this pattern satisfies the requirement. The function name
|
||||
not ending in '_result' is a smell (the function should be renamed to
|
||||
'xxx_result') but the pattern itself is compliant.
|
||||
This is the pattern used by src/hot_reloader.py:reload(),
|
||||
src/warmup.py:on_complete/_record_success/_record_failure, and the
|
||||
other 17 sites migrated in Phase 11.3.
|
||||
"""
|
||||
src = '''
|
||||
from src.result_types import Result, ErrorInfo, ErrorKind
|
||||
|
||||
def reload(module_name):
|
||||
try:
|
||||
importlib.reload(sys.modules[module_name])
|
||||
return Result(data=True)
|
||||
except (ImportError, ModuleNotFoundError) as e:
|
||||
return Result(data=False, errors=[ErrorInfo(kind=ErrorKind.INTERNAL, message=str(e), source="hot_reloader.reload", original=e)])
|
||||
'''
|
||||
data = _run_audit_on_fixture(src)
|
||||
findings = _classifications_for_file(data, "audit_heuristic_fixture.py")
|
||||
excepts = [f for f in findings if f["kind"] == "EXCEPT"]
|
||||
assert len(excepts) == 1
|
||||
assert excepts[0]["category"] == "INTERNAL_COMPLIANT", (
|
||||
f"Result-returning recovery in non-*_result function should be INTERNAL_COMPLIANT, got {excepts[0]['category']}"
|
||||
)
|
||||
|
||||
|
||||
def test_result_returning_recovery_in_result_named_function_is_compliant():
|
||||
"""Same pattern but with a function name ending in '_result' is also compliant (and ideal).
|
||||
|
||||
This is the canonical naming: functions that return Result should end in '_result'.
|
||||
"""
|
||||
src = '''
|
||||
from src.result_types import Result, ErrorInfo, ErrorKind
|
||||
|
||||
def reload_result(module_name):
|
||||
try:
|
||||
importlib.reload(sys.modules[module_name])
|
||||
return Result(data=True)
|
||||
except (ImportError, ModuleNotFoundError) as e:
|
||||
return Result(data=False, errors=[ErrorInfo(kind=ErrorKind.INTERNAL, message=str(e), source="hot_reloader.reload_result", original=e)])
|
||||
'''
|
||||
data = _run_audit_on_fixture(src)
|
||||
findings = _classifications_for_file(data, "audit_heuristic_fixture.py")
|
||||
excepts = [f for f in findings if f["kind"] == "EXCEPT"]
|
||||
assert len(excepts) == 1
|
||||
assert excepts[0]["category"] == "INTERNAL_COMPLIANT", (
|
||||
f"Result-returning recovery in *_result function should be INTERNAL_COMPLIANT, got {excepts[0]['category']}"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user