def load_order(path):
"""Read one order from disk. Raises if the file is missing or malformed."""
try:
with open(path) as handle:
return json.load(handle)
except Exception:
log.exception("could not read %s", path)
return {}
The docstring says this function raises an exception, but the code catches the exception and returns an empty dictionary instead. This deliberately broken function comes from the example order service.
Check the comment against the code
First set up the example project, then save this rule in perch.yaml:
- name: comments-match-behavior
where: "**/*.{py,js,ts}"
each: method
ensure: >-
The method's leading comment accurately describes its
return values, errors, and side effects. Promising an
exception that is swallowed, an unchanged input that is
mutated, or a return type the body does not produce
breaks this rule. A method without a leading comment
satisfies this rule.
perch check storage.py::load_order --rules comments-match-behavior
The fix depends on which behavior the callers need. If they rely on the exception, remove the catch or re-raise after logging. If a missing file should return an empty value, change the docstring to say so, and keep parse errors distinguishable where callers need to tell them apart.
TypeScript example
The same rule catches a comment that promises not to modify its input when the code does. Save this illustrative function as sort.ts:
/** Return sorted IDs without modifying the caller's array. */
export function sortedIds(ids: number[]): number[] {
return ids.sort((a, b) => a - b);
}
perch check sort.ts::sortedIds --rules comments-match-behavior
sort changes the caller’s array in place. Sorting a copy with [...ids].sort((a, b) => a - b) does what the comment says. Add a test that checks both the returned order and the original array.
Useful comments
A second rule checks whether a comment tells the reader anything the code does not:
- name: comments-add-information
where: "src/**/*.{py,js,ts}"
each: method
ensure: >-
If the method has a leading comment, it explains a caller
contract, a constraint, or a reason for a non-obvious
choice. Only restating the method name or narrating the
next statement breaks this rule. A simple method with no
leading comment satisfies this rule.
perch scan --filter type=docs asks the built-in questions about method documentation. For requirements specific to your codebase, write your own lint rules. Neither one expects a comment on every trivial function.