Syllabus Lesson 69 of 141 · APIs nobody can misuse
APIs nobody can misuse

No boolean traps

Why it matters copy(src, dst, True, False) cannot be read without opening the function. Swap the two flags and a dry run becomes a real overwrite. Named options make every call say what it does.

A data team has a helper that copies records between two stores: copy_records(src, dst, overwrite, dry_run). Last month someone called it as copy_records(a, b, False, True) meaning "dry run, do not overwrite", got the order wrong, and overwrote a production table. You are replacing it.

Boolean trap: an argument that is only True or False, so the call site does not say what it means and is easy to swap.

copy_records(src, dst, on_conflict="keep", mode="dry_run")
Your turn

Write copy_records(src, dst, *, on_conflict, mode). src and dst are dicts. For each key in src: if it is not in dst, copy it; if it is, on_conflict decides: "keep" (leave dst's value), "overwrite" (use src's), or "fail" (raise ValueError and change nothing at all). mode is "apply" (change dst) or "dry_run" (change nothing). Return the sorted list of keys written (or that would be).

Hidden misuse scripts will try each of these; each must raise TypeError or ValueError and leave dst unchanged: passing the options by position, leaving either option out (no defaults: the caller must choose), any value that is not exactly one of the named strings (typos, other capitals, True, False, None), and the old overwrite= keyword.

Spotted a problem in this lesson? Report it · Ask about this lesson

This exercise opens soon

Finish the lesson before it and this one unlocks. The whole course is free, no account needed, and you can read this lesson right now.