When handling settings, parsed model outputs, and lookup results, assume values may be missing (None/empty), omitted, or of the wrong type. Prevent NoneType and KeyError crashes by applying a consistent null-safety pattern.
Standards: 1) Default missing configuration/flags
2) Defensive access to dict/list payloads
.get() for optional keys.3) Handle lookup failures explicitly
4) Guard against wrong types / absent fields
5) Avoid mutable default arguments
None defaults and create a new list inside the function.Example pattern:
def publish_inline_comment(payload: dict, settings: dict, diff_files: list):
# 1) Default optional config
default_status = settings.get("azure_devops", {}).get("default_comment_status") or "closed"
# 2) Defensive dict access
feedback = payload.get("PR Feedback") or {}
suggestions = feedback.get("Code suggestions") or []
for s in suggestions:
# 3) Validate required fields
relevant_file = (s.get("relevant file") or "").strip()
relevant_line = (s.get("relevant line in file") or "").strip()
content = s.get("suggestion content")
if not relevant_file or not relevant_line or content is None:
continue
# 4) Handle lookup failure
target_file = next((f for f in diff_files if f.filename.strip() == relevant_file), None)
if target_file is None:
# skip instead of crashing
continue
# proceed safely...
6) Tests