Most of what a test configures on a patch holds until the test changes it. Retry logic is the classic case where that is not enough: the code under test keeps calling, and the test needs the behaviour to change on its own as it does. Fail twice and then succeed. Hand out a sequence of canned responses. Run the real thing until it breaks and then fail fast. unittest.mock handles the first two of those with a list passed as side_effect, consumed one entry per call. wrapture models the same idea as phases, and this post is about what that buys you beyond the list.

The code under test

A client that fetches a URL, and a function that retries on a timeout:

class Client:

def fetch(self, url):