• Tim Peters's avatar
    Clear the copy of the globs dict after running examples. This helps to · d4ad59e1
    Tim Peters authored
    break cycles, which are a special problem when running generator tests
    that provoke exceptions by invoking the .next() method of a named
    generator-iterator:  then the iterator is named in globs, and the
    iterator's frame gets a tracekback object pointing back to globs, and
    gc doesn't chase these types so the cycle leaks.
    
    Also changed _run_examples() to make a copy of globs itself, so its
    callers (direct and indirect) don't have to (and changed the callers
    to stop making their own copies); *that* much is a change I've been
    meaning to make for a long time (it's more robust the new way).
    
    Here's a way to provoke the symptom without doctest; it leaks at a
    prodigious rate; if the last two "source" lines are replaced with
        g().next()
    the iterator isn't named and then there's no leak:
    
    source = """\
    def g():
        yield 1/0
    
    k = g()
    k.next()
    """
    
    code = compile(source, "<source>", "exec")
    
    def f(globs):
        try:
            exec code in globs
        except ZeroDivisionError:
            pass
    
    while 1:
        f(globals().copy())
    
    After this change, running test_generators in an infinite loop still leaks,
    but reduced from a flood to a trickle.
    d4ad59e1
doctest.py 36.2 KB