Write a docstring
Documentation that states the units, timezone, and edge cases the type signature cannot — so the function reads correctly from autocomplete alone.
When to use it
Documenting a shared function whose signature hides something — units, a timezone assumption, an edge case — that a caller needs and cannot see.
What it prevents
The docstring that restates the signature. “Returns a dict” is already in the type annotation; what the caller cannot see is that the keys are hours in UTC. Directing the model at the units, assumptions, and empty-input behaviour is what makes the docstring earn its place.
The prompt
Write a docstring for the function below. ### Context Python, part of a shared library other teams import. Readers see the docstring in autocomplete and rarely open the source, so it has to stand alone. ### Requirements - Output format: A single triple-quoted docstring in Google style — one-line summary, Args, Returns, Raises. - State the units and the timezone assumption, which the signature does not reveal. - Describe the behaviour on the empty-input case explicitly. - Do not restate the parameter types; the annotations already show them. - Avoid: narrating the implementation line by line. ### Function """ def bucket_by_hour(events: list[Event], tz: str) -> dict[int, int]: ... """
Instant checks
States a concrete task
PassedAvoids vague language
PassedSpecifies an output format
PassedGives context or audience
PassedAvoids dangling references
PassedAvoids over-aggressive phrasing
PassedDefines what a good answer looks like
Passed
Why each part is there
Every section of that prompt exists because a specific failure happens without it. These are the checks it passes, and what each one is protecting you from:
- States a concrete task — why this matters
- Avoids vague language — why this matters
- Specifies an output format — why this matters
- Gives context or audience — why this matters
- Avoids dangling references — why this matters
- Avoids over-aggressive phrasing — why this matters
- Defines what a good answer looks like — why this matters
How to adapt this one
Point it at your function and name the invisible assumptions explicitly — the ones a reader would get wrong from the signature alone. Keep the “do not restate the types” rule, or you get a docstring that duplicates the annotations and adds nothing. The empty-input clause generalises: whatever your function's surprising edge case is, name it and make the docstring cover it.
The mistake this prompt avoids
Letting the model narrate the implementation. The default docstring walks through what the code does, which the code already shows. A docstring is for the caller, who wants the contract — inputs, outputs, units, failure modes — not a tour of the internals they will never read.
A variation
Documenting a whole module or public API rather than one function? Ask for a short module-level overview first — what it is for, the one concept a newcomer must grasp, and the entry point to start from — before any per-function detail. Callers orient at the module level; a pile of good function docstrings with no map is still hard to enter.
Check your version
Once you have adapted it, run it through the checker. The same nine checks that graded this page will grade yours, free and in your browser — paste it in, or build one from scratch by answering a few questions.