Concepts / Reading Python Tracebacks

Reading Python Tracebacks

An AssertionError is raised when an assert statement's condition is False, and it appears in the traceback with the file name and line number where the assertion failed.

  • Programming
Interactive lab

Try it: A Retry Decorator, Step by Step

What a decorator does: @retry(max_attempts) turns a function into a wrapper that calls the original. When the original's assertion fails, the wrapper catches the AssertionError, logs the attempt and runs the WHOLE function again (repeating its side effect) until it succeeds or runs out of attempts, then re-raises (with a traceback whose deepest frame is the assert) or returns a default.

How it works

  1. @retry(max_attempts=3) is evaluated first: retry(3) returns decorate; decorate(save_reading) returns wrapper; the name save_reading is bound to the wrapper.
  2. Calling save_reading(42) runs the wrapper, which loops over attempts and calls the original function inside try.
  3. A false assert raises AssertionError immediately; the original stops and the exception moves up to the wrapper's except block.
  4. The wrapper logs the failed attempt and starts a new, complete execution of the original: side effects before the assert (saved.append) happen again.
  5. After the last allowed attempt the wrapper's design decides: raise last_error (the traceback's deepest frame is the assert line; the wrapper frames only caught and re-raised it) or return None.

Default run (36 steps): Line 1: def retry(max_attempts): creates the decorator factory and binds the name retry. Nothing inside it runs yet. … The program finished: the wrapper returned 'saved' from attempt 3. The side effect ran 3 times for one reading: a retried function should be idempotent.

Simplified: One fixed program; you choose the per-attempt sensor results, max_attempts (1-5), whether the write comes before or after the check, and raise vs return None. Your settings are never executed: the lab's model reproduces CPython 3.12's line-by-line execution, printed output and traceback text for all 640 possible programs (checked against real runs). The "database" is a Python list.

Educational simulation

Loading the simulation…

The Failure Path

When an assert statement evaluates a condition as False, Python raises an AssertionError immediately. The current function stops at that point, and the exception moves up through the call stack unless an exception handler catches it. A traceback records this path so you can investigate both the function that failed and the calls that led to it.

What do you think happens?

A decorated function reaches a false assertion on its first attempt, and the decorator is configured to retry failures. What happens next?

  • The assertion is ignored and the function continues

  • The decorator catches the exception, logs the failed attempt, and re-executes the function

  • Only the failed assertion line is executed again

  • The caller always receives the exception immediately

Reveal answer
Answer:

The decorator catches the exception, logs the failed attempt, and re-executes the function.

A retry decorator intercepts the wrapped function's execution. It can catch AssertionError, record the attempt, and execute the entire wrapped function again, up to its maximum number of attempts.

Decorator Interception

A decorator places a wrapper between the caller and the original function. The caller starts the wrapped operation, the wrapper invokes the original function, and the original function either completes or raises an exception. If an exception occurs, the wrapper's exception handler can catch it before it reaches the caller. A retry decorator then decides whether to log the failure, retry the operation, or propagate the exception.

CallerRetry wrapperexception handlerWrapped functionassert statementAssertionErrorRetry decisionCaller receivesresult or errorcallsinvokesraisescaught byevaluatesretryfinish or propagate
What happens to control flow when a decorated function is called, its assertion fails, and the decorator handles the exception?

Retrying the Whole Operation

A retry mechanism does not jump back to only the assertion line. It re-executes the entire wrapped function. The decorator catches the exception, logs the failure with the attempt number, and starts the function again. This process continues until the function succeeds or the maximum number of attempts is reached.

Attempt 1function executesAssertionErrorassertion is falseFailure logattempt numberRetry decisionmaximum not reachedAttempt 2entire function re-executesFinal outcomesuccess or last exceptionraisescaught and recordedcontinue evaluationretrystop retryingcomplete or fail again
After an AssertionError, how does the retry mechanism catch it, decide whether to retry, and re-execute the function?
Worked example

First Attempt Fails, Second Attempt Proceeds

Trace a decorated function that fails with an exception on its first attempt and is then re-executed by a retry decorator.

  1. 1
    Call enters the wrapper

    The caller invokes the decorated function, so execution first passes through the decorator's wrapper.

  2. 2
    Original function runs

    The wrapper invokes the original function. The function performs its work and reaches an assertion.

  3. 3
    Assertion fails

    Because the assertion condition is False, Python raises an AssertionError and stops the current function.

  4. 4
    Wrapper catches the exception

    The retry decorator catches the exception, logs the failure with the attempt number, and checks whether another attempt is allowed.

  5. 5
    Function runs again

    The decorator re-executes the entire wrapped function rather than resuming at the failed assertion line.

  6. 6
    Process ends

    If a later attempt succeeds, execution continues. If attempts continue to fail until the limit is reached, the decorator may raise the last exception or return a default value, depending on its design.

Result

The wrapper controls the transition from failure to retry. The original function is started again from the beginning of its wrapped execution.

Reading the Call Stack

Caller framestarted the callDecorator frameintercepted executionFunction framecontains assertionAssertionErrororiginates herecallsinvokesraises
Which function calls led to the failure, and how do the traceback frames connect the decorated wrapper to the original function?

Read traceback frames as a path through the program. Earlier frames show calls that led to the failure. A decorator frame explains why the wrapper was involved, but the deepest frame, listed last, identifies where the exception originated. For an AssertionError, inspect that final relevant frame for the file name, line number, function, and assertion that evaluated to False.

File namesource fileLine numberlocationFunctionexecution contextassert statementcondition was FalseAssertionErrorfailurenarrows towithincontainsraises
How do the traceback's file name and line number identify the exact assert statement whose condition evaluated to False?
  1. 1
    Start with the final traceback frame rather than the decorator frame.
  2. 2
    Read the file name to identify the source file.
  3. 3
    Read the line number to locate the relevant source line.
  4. 4
    Confirm that the line contains the assertion whose condition evaluated to False.
  5. 5
    Read earlier frames to understand which caller and wrapper led to the failure.
  6. 6
    Check retry logs to determine whether the decorator caught the exception and started another attempt.

Mistakes in Traceback Reading

  • Common mistake

    Treating the decorator frame as the failure location

    What it looks like

    The traceback includes a retry wrapper, so the wrapper is assumed to contain the faulty assertion.

    Why it fails

    The wrapper is part of the call stack and may catch the exception, but the deepest frame listed last shows where the exception actually originated.

    Do this instead

    Inspect the final relevant frame and use its file name and line number to locate the failed assertion.

  • Common mistake

    Assuming a retry resumes at the failed line

    What it looks like

    After an assertion fails, only that assertion is expected to run again.

    Why it fails

    A retry decorator re-executes the entire wrapped function.

    Do this instead

    Trace the next attempt from the beginning of the wrapped function and account for repeated side effects.

  • Common mistake

    Assuming every caught failure reaches the caller immediately

    What it looks like

    An AssertionError appears during the first attempt, so the caller is expected to receive it at once.

    Why it fails

    The decorator can catch the exception, log the attempt, and retry before deciding what the caller receives.

    Do this instead

    Look for the decorator's retry decision and maximum-attempt behavior.

  • Common mistake

    Ignoring the line number

    What it looks like

    The function name is used to search the whole file without checking the traceback location.

    Why it fails

    The traceback supplies a file name and line number that pinpoint the failed assertion.

    Do this instead

    Open the named source file at the reported line and inspect the assertion condition.

Best practice

Read the traceback in two passes. First, locate the origin of the exception by finding the deepest frame and its source location. Second, reconstruct the route to that frame by reading the earlier caller and decorator frames. This separates the question “Where did it fail?” from the question “Why was this function running?”

Traceback Practice

MEDIUM

A traceback lists a caller frame, a decorator frame, and a final frame inside the original function. The final frame identifies a source file and line containing an assert statement. The decorator log says the first attempt failed and another attempt began. Explain where the AssertionError originated, what the decorator did, and what code must be considered when checking for repeated side effects.

Hints
  • Use the deepest frame to identify the origin.
  • Separate catching the exception from creating the exception.
  • A retry starts the entire wrapped function again.
Worked example

Practice Solution

Interpret the traceback and retry information from the practice situation.

  1. 1
    Locate the origin

    The AssertionError originated in the deepest frame, inside the original function at the reported file and line number.

  2. 2
    Interpret the decorator frame

    The decorator frame shows that a wrapper intercepted the call and handled the exception; it is not necessarily where the assertion failed.

  3. 3
    Interpret the retry log

    The first attempt failed, the decorator logged that attempt, and the retry mechanism started another execution.

  4. 4
    Check repeated work

    Because the whole wrapped function runs again, any side effects performed before the assertion can occur again on the retry.

Result

The traceback identifies the failed assertion, while the decorator frames and logs explain how the failure was handled and why another full execution occurred.

Key Takeaways

  1. 1
    An AssertionError is raised immediately when an assert condition is False.
  2. 2
    The deepest traceback frame, listed last, identifies where the exception originated; decorator frames show the surrounding call path.
  3. 3
    A retry decorator can catch the exception, log the attempt, and re-execute the entire wrapped function up to a maximum number of attempts.
  4. 4
    Use the traceback's file name and line number to locate the failed assertion in source code.
  5. 5
    Because retries repeat the whole function, side effects can happen again on each attempt.

At a glance

  • Find the deepest traceback frame to locate the actual AssertionError origin.
  • Use the file name and line number to inspect the assertion whose condition evaluated to False.
  • Remember that a decorator can catch the exception before it reaches the caller.
  • A retry re-executes the complete wrapped function, not only the failed line.
  • Inspect repeated side effects and retry logs when diagnosing decorated failures.

Related concepts

More concepts starting with R