Wrap a long string to an array of short-enough strings
Bug

You have a small bug. For text="abc \\n def" and max_width=10 the output is incorrectly ['abc', 'def'] instead of ['abc def'].

You can greatly simplify the handling of embedded whitespace characters by using re.split with a pattern r'\s+'.

Don't repeat yourself

This (or almost the same) piece of code appears in multiple places: " ".join((line, words[0])).
Look out for duplication like this and use helper functions to eliminate.

Overcomplicated string joins

Instead of " ".join((line, words[0])),
it would be a lot simpler to write line + " " + words[0].

Simplify the logic

Consider this alternative algorithm:


Create a word generator: from some text as input, extract the words one by one
For each word:


If the word is too long, raise an error
If the current line + word would be too long, then


Append the current line to the list of lines
Start a new line with the current word

If the current line + word is not too long, then append the word to the line

Append the current line to the list of lines


Implementation:

def wrap_text(text, font, max_width):
    def gen_words(text):
        yield from re.split(r'\s+', text)
        # or in older versions of Python:
        # for word in re.split(r'\s+', text):
        #     yield word

    def raise_word_too_long_error(word):
        raise ValueError("\"{}\" is too long to be wrapped.".format(word))

    def too_long(line):
        return font.size(line)[0] &gt; max_width

    words = gen_words(text)
    line = next(words)
    if too_long(line):
        raise_word_too_long_error(line)

    lines = []
    for word in words:
        if too_long(word):
            raise_word_too_long_error(word)

        if too_long(line + " " + word):
            lines.append(line)
            line = word
        else:
            line += " " + word

    lines.append(line)

    return lines


Some doctests to verify it works:

def _wrap_text_tester(text, max_width):
    """
    &gt;&gt;&gt; _wrap_text_tester("hello there", 7)
    ['hello', 'there']

    &gt;&gt;&gt; _wrap_text_tester("I am legend", 7)
    ['I am', 'legend']

    &gt;&gt;&gt; _wrap_text_tester("abc \\n def", 10)
    ['abc def']

    &gt;&gt;&gt; _wrap_text_tester("toobigtofit", 7)
    Traceback (most recent call last):
        ...
    ValueError: "toobigtofit" is too long to be wrapped.

    &gt;&gt;&gt; _wrap_text_tester("in the middle toobigtofit", 7)
    Traceback (most recent call last):
        ...
    ValueError: "toobigtofit" is too long to be wrapped.

    &gt;&gt;&gt; _wrap_text_tester("", 7)
    ['']

    """
    return wrap_text(text, font, max_width)