itertools.combinations(iterable, r)这个函数到底是如何定义的

我在看python内建模块itertools时,想要看看itertools.combinations(iterable, r)这个函数到底是如何定义的,代码的其他地方都看懂了,唯独代码的第18行,那个i为什么不会报未定义的错误,这点看不懂。能给我详细说一下吗

代码的第18行是:indices[i] += 1
具体代码如下:

def combinations(iterable, r):
    # combinations('ABCD', 2) --> AB AC AD BC BD CD
    # combinations(range(4), 3) --> 012 013 023 123
    pool = tuple(iterable)
    n = len(pool)
    if r > n:
        return
    indices = list(range(r))
    # 为什么第9行,第11行,第16行的i共用相同的内存地址,都是indices中对应元素的地址
    yield tuple(pool[i] for i in indices)
    while True:
        # 下面这个for循环是干嘛的,为什么是(n-r)+i  -> 当indices的每一项分别代表iterable的最后几项时,说明全部遍历完了
        for i in reversed(range(r)):
            if indices[i] != (n - r) + i:
                break
        else:
            return
        indices[i] += 1  # 这里的i为什么不会报未定义的错误   代码的第18行----------------------------------
        # 下面for循环作用是:固定前两位,遍历第三位,此时第三位遍历完了,那么第二位就需要前进一位,而第三位需要回到第二位的下一位
        for j in range(i+1, r):
            indices[j] = indices[j-1] + 1
        yield tuple(pool[i] for i in indices)

a = 'abcde'
print(list(combinations(a,3)))

这个indices[i] += 1,应该是return的,是for循环的i