summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2001-06-23 20:45:43 (GMT)
committerTim Peters <tim.peters@gmail.com>2001-06-23 20:45:43 (GMT)
commit6ba5f79674bded76c1d8011fbbb9b5e6caa5afb5 (patch)
tree7de367b7e9e90e03b64be43b290c87e594788fb6
parent1def351b4560e6261dbf1c7c0f7794ea1b693163 (diff)
downloadcpython-6ba5f79674bded76c1d8011fbbb9b5e6caa5afb5.zip
cpython-6ba5f79674bded76c1d8011fbbb9b5e6caa5afb5.tar.gz
cpython-6ba5f79674bded76c1d8011fbbb9b5e6caa5afb5.tar.bz2
Add all the examples from PEP 255, and a few email examples.
-rw-r--r--Lib/test/test_generators.py185
1 files changed, 183 insertions, 2 deletions
diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py
index 28d27f7..9889588 100644
--- a/Lib/test/test_generators.py
+++ b/Lib/test/test_generators.py
@@ -1,4 +1,4 @@
-simple_tests = """
+tutorial_tests = """
Let's try a simple generator:
>>> def f():
@@ -124,7 +124,188 @@ Generators can call other generators:
"""
-__test__ = {"simple": simple_tests}
+# The examples from PEP 255.
+
+pep_tests = """
+
+Specification: Return
+
+ Note that return isn't always equivalent to raising StopIteration: the
+ difference lies in how enclosing try/except constructs are treated.
+ For example,
+
+ >>> def f1():
+ ... try:
+ ... return
+ ... except:
+ ... yield 1
+ >>> print list(f1())
+ []
+
+ because, as in any function, return simply exits, but
+
+ >>> def f2():
+ ... try:
+ ... raise StopIteration
+ ... except:
+ ... yield 42
+ >>> print list(f2())
+ [42]
+
+ because StopIteration is captured by a bare "except", as is any
+ exception.
+
+Specification: Generators and Exception Propagation
+
+ >>> def f():
+ ... return 1/0
+ >>> def g():
+ ... yield f() # the zero division exception propagates
+ ... yield 42 # and we'll never get here
+ >>> k = g()
+ >>> k.next()
+ Traceback (most recent call last):
+ File "<stdin>", line 1, in ?
+ File "<stdin>", line 2, in g
+ File "<stdin>", line 2, in f
+ ZeroDivisionError: integer division or modulo by zero
+ >>> k.next() # and the generator cannot be resumed
+ Traceback (most recent call last):
+ File "<stdin>", line 1, in ?
+ StopIteration
+ >>>
+
+Specification: Try/Except/Finally
+
+ >>> def f():
+ ... try:
+ ... yield 1
+ ... try:
+ ... yield 2
+ ... 1/0
+ ... yield 3 # never get here
+ ... except ZeroDivisionError:
+ ... yield 4
+ ... yield 5
+ ... raise
+ ... except:
+ ... yield 6
+ ... yield 7 # the "raise" above stops this
+ ... except:
+ ... yield 8
+ ... yield 9
+ ... try:
+ ... x = 12
+ ... finally:
+ ... yield 10
+ ... yield 11
+ >>> print list(f())
+ [1, 2, 4, 5, 8, 9, 10, 11]
+ >>>
+
+
+Guido's binary tree example.
+
+ >>> # A binary tree class.
+ >>> class Tree:
+ ...
+ ... def __init__(self, label, left=None, right=None):
+ ... self.label = label
+ ... self.left = left
+ ... self.right = right
+ ...
+ ... def __repr__(self, level=0, indent=" "):
+ ... s = level*indent + `self.label`
+ ... if self.left:
+ ... s = s + "\\n" + self.left.__repr__(level+1, indent)
+ ... if self.right:
+ ... s = s + "\\n" + self.right.__repr__(level+1, indent)
+ ... return s
+ ...
+ ... def __iter__(self):
+ ... return inorder(self)
+
+ >>> # Create a Tree from a list.
+ >>> def tree(list):
+ ... n = len(list)
+ ... if n == 0:
+ ... return []
+ ... i = n / 2
+ ... return Tree(list[i], tree(list[:i]), tree(list[i+1:]))
+
+ >>> # Show it off: create a tree.
+ >>> t = tree("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
+
+ >>> # A recursive generator that generates Tree leaves in in-order.
+ >>> def inorder(t):
+ ... if t:
+ ... for x in inorder(t.left):
+ ... yield x
+ ... yield t.label
+ ... for x in inorder(t.right):
+ ... yield x
+
+ >>> # Show it off: create a tree.
+ ... t = tree("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
+ ... # Print the nodes of the tree in in-order.
+ ... for x in t:
+ ... print x,
+ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
+
+ >>> # A non-recursive generator.
+ >>> def inorder(node):
+ ... stack = []
+ ... while node:
+ ... while node.left:
+ ... stack.append(node)
+ ... node = node.left
+ ... yield node.label
+ ... while not node.right:
+ ... try:
+ ... node = stack.pop()
+ ... except IndexError:
+ ... return
+ ... yield node.label
+ ... node = node.right
+
+ >>> # Exercise the non-recursive generator.
+ >>> for x in t:
+ ... print x,
+ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
+
+"""
+
+# A few examples from Iterator-List and Python-Dev email.
+
+email_tests = """
+
+The difference between yielding None and returning it.
+
+>>> def g():
+... for i in range(3):
+... yield None
+... yield None
+... return
+>>> list(g())
+[None, None, None, None]
+
+Ensure that explicitly raising StopIteration acts like any other exception
+in try/except, not like a return.
+
+>>> def g():
+... yield 1
+... try:
+... raise StopIteration
+... except:
+... yield 2
+... yield 3
+>>> list(g())
+[1, 2, 3]
+"""
+
+__test__ = {"tut": tutorial_tests,
+ "pep": pep_tests,
+ "zemail": email_tests}
# Magic test name that regrtest.py invokes *after* importing this module.
# This worms around a bootstrap problem.