Diagnose a mutable default argument

Problem

In default_argument_report, predict the returned value and identity booleans. Then rewrite record so calls that omit bucket receive a new list while callers may still supply an existing list.

Reveal answer or reference solution

The default list is created once, so first, second, and third alias the same list, which ends as ["A", "B", "D"]. The explicit list used for "C" is separate. The safe version uses None as the default and creates a list inside the function only when the argument is None.

def default_argument_report() -> tuple[object, ...]:
    def record(tag: str, bucket: list[str] = []) -> list[str]:
        bucket.append(tag)
        return bucket
 
    first = record("A")
    second = record("B")
    separate = record("C", [])
    third = record("D")
    return (
        first.copy(),
        second.copy(),
        separate.copy(),
        third.copy(),
        first is second,
        second is third,
    )
 
def safe_record(
    tag: str, bucket: list[str] | None = None
) -> list[str]:
    if bucket is None:
        bucket = []
    bucket.append(tag)
    return bucket

Public tests

  • default_argument_report() → (['A', 'B', 'D'], ['A', 'B', 'D'], ['C'], ['A', 'B', 'D'], True, True)
  • safe_record("X") → ['X']
  • safe_record("Y") → ['Y']
Outcome

Previous attempts

Loading attempts saved in this browser…

    Review Screening Results