somewhat less horrid hack <wink>: if a module does
from __future__ import X
then the module dict D is left in a state such that (viewing X as a
string)
D[X] is getattr(__future__, X)
So by examining D for all the names of future features, and making that
test for each, we can make a darned good guess as to which future-features
were imported by the module. The appropriate flags are then sucked out
of the __future__ module, and passed on to compile()'s new optional
arguments (PEP 264).
Also gave doctest a meaningful __all__, removed the history of changes
(CVS serves that purpose now), and removed the __version__ vrbl (similarly;
before CVS, it was a reasonable clue, but not anymore).
that 'yield' is a keyword. This doesn't help test_generators at all! I
don't know why not. These things do work now (and didn't before this
patch):
1. "from __future__ import generators" now works in a native shell.
2. Similarly "python -i xxx.py" now has generators enabled in the
shell if xxx.py had them enabled.
3. This program (which was my doctest proxy) works fine:
from __future__ import generators
source = """\
def f():
yield 1
"""
exec compile(source, "", "single") in globals()
print type(f())
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.
This makes verbose-mode output easier to dig thru, and removes an accidental
dependence on the order of dict.items() (made visible by recent changes to
dictobject.c).
newline at the end if there isn't one already. Expected output has no
way to indicate that a trailing newline was not expected, and in the
interpreter shell *Python* supplies the trailing newline before printing
the next prompt.