PyXR

c:\python24\lib \ test \ test_genexps.py



0001 doctests = """
0002 
0003 Test simple loop with conditional
0004 
0005     >>> sum(i*i for i in range(100) if i&1 == 1)
0006     166650
0007 
0008 Test simple nesting
0009 
0010     >>> list((i,j) for i in range(3) for j in range(4) )
0011     [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]
0012 
0013 Test nesting with the inner expression dependent on the outer
0014 
0015     >>> list((i,j) for i in range(4) for j in range(i) )
0016     [(1, 0), (2, 0), (2, 1), (3, 0), (3, 1), (3, 2)]
0017 
0018 Make sure the induction variable is not exposed
0019 
0020     >>> i = 20
0021     >>> sum(i*i for i in range(100))
0022     328350
0023     >>> i
0024     20
0025 
0026 Test first class
0027 
0028     >>> g = (i*i for i in range(4))
0029     >>> type(g)
0030     <type 'generator'>
0031     >>> list(g)
0032     [0, 1, 4, 9]
0033 
0034 Test direct calls to next()
0035 
0036     >>> g = (i*i for i in range(3))
0037     >>> g.next()
0038     0
0039     >>> g.next()
0040     1
0041     >>> g.next()
0042     4
0043     >>> g.next()
0044     Traceback (most recent call last):
0045       File "<pyshell#21>", line 1, in -toplevel-
0046         g.next()
0047     StopIteration
0048 
0049 Does it stay stopped?
0050 
0051     >>> g.next()
0052     Traceback (most recent call last):
0053       File "<pyshell#21>", line 1, in -toplevel-
0054         g.next()
0055     StopIteration
0056     >>> list(g)
0057     []
0058 
0059 Test running gen when defining function is out of scope
0060 
0061     >>> def f(n):
0062     ...     return (i*i for i in xrange(n))
0063     >>> list(f(10))
0064     [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
0065 
0066     >>> def f(n):
0067     ...     return ((i,j) for i in xrange(3) for j in xrange(n))
0068     >>> list(f(4))
0069     [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]
0070     >>> def f(n):
0071     ...     return ((i,j) for i in xrange(3) for j in xrange(4) if j in xrange(n))
0072     >>> list(f(4))
0073     [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]
0074     >>> list(f(2))
0075     [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]
0076 
0077 Verify that parenthesis are required in a statement
0078 
0079     >>> def f(n):
0080     ...     return i*i for i in xrange(n)
0081     Traceback (most recent call last):
0082        ...
0083     SyntaxError: invalid syntax
0084 
0085 Verify early binding for the outermost for-expression
0086 
0087     >>> x=10
0088     >>> g = (i*i for i in range(x))
0089     >>> x = 5
0090     >>> list(g)
0091     [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
0092 
0093 Verify that the outermost for-expression makes an immediate check
0094 for iterability
0095 
0096     >>> (i for i in 6)
0097     Traceback (most recent call last):
0098       File "<pyshell#4>", line 1, in -toplevel-
0099         (i for i in 6)
0100     TypeError: iteration over non-sequence
0101 
0102 Verify late binding for the outermost if-expression
0103 
0104     >>> include = (2,4,6,8)
0105     >>> g = (i*i for i in range(10) if i in include)
0106     >>> include = (1,3,5,7,9)
0107     >>> list(g)
0108     [1, 9, 25, 49, 81]
0109 
0110 Verify late binding for the innermost for-expression
0111 
0112     >>> g = ((i,j) for i in range(3) for j in range(x))
0113     >>> x = 4
0114     >>> list(g)
0115     [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]
0116 
0117 Verify re-use of tuples (a side benefit of using genexps over listcomps)
0118 
0119     >>> tupleids = map(id, ((i,i) for i in xrange(10)))
0120     >>> max(tupleids) - min(tupleids)
0121     0
0122 
0123 Verify that syntax error's are raised for genexps used as lvalues
0124 
0125     >>> (y for y in (1,2)) = 10
0126     Traceback (most recent call last):
0127        ...
0128     SyntaxError: assign to generator expression not possible
0129 
0130     >>> (y for y in (1,2)) += 10
0131     Traceback (most recent call last):
0132        ...
0133     SyntaxError: augmented assign to tuple literal or generator expression not possible
0134 
0135 
0136 
0137 ########### Tests borrowed from or inspired by test_generators.py ############
0138 
0139 Make a generator that acts like range()
0140 
0141     >>> yrange = lambda n:  (i for i in xrange(n))
0142     >>> list(yrange(10))
0143     [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
0144 
0145 Generators always return to the most recent caller:
0146 
0147     >>> def creator():
0148     ...     r = yrange(5)
0149     ...     print "creator", r.next()
0150     ...     return r
0151     >>> def caller():
0152     ...     r = creator()
0153     ...     for i in r:
0154     ...             print "caller", i
0155     >>> caller()
0156     creator 0
0157     caller 1
0158     caller 2
0159     caller 3
0160     caller 4
0161 
0162 Generators can call other generators:
0163 
0164     >>> def zrange(n):
0165     ...     for i in yrange(n):
0166     ...         yield i
0167     >>> list(zrange(5))
0168     [0, 1, 2, 3, 4]
0169 
0170 
0171 Verify that a gen exp cannot be resumed while it is actively running:
0172 
0173     >>> g = (me.next() for i in xrange(10))
0174     >>> me = g
0175     >>> me.next()
0176     Traceback (most recent call last):
0177       File "<pyshell#30>", line 1, in -toplevel-
0178         me.next()
0179       File "<pyshell#28>", line 1, in <generator expression>
0180         g = (me.next() for i in xrange(10))
0181     ValueError: generator already executing
0182 
0183 Verify exception propagation
0184 
0185     >>> g = (10 // i for i in (5, 0, 2))
0186     >>> g.next()
0187     2
0188     >>> g.next()
0189     Traceback (most recent call last):
0190       File "<pyshell#37>", line 1, in -toplevel-
0191         g.next()
0192       File "<pyshell#35>", line 1, in <generator expression>
0193         g = (10 // i for i in (5, 0, 2))
0194     ZeroDivisionError: integer division or modulo by zero
0195     >>> g.next()
0196     Traceback (most recent call last):
0197       File "<pyshell#38>", line 1, in -toplevel-
0198         g.next()
0199     StopIteration
0200 
0201 Make sure that None is a valid return value
0202 
0203     >>> list(None for i in xrange(10))
0204     [None, None, None, None, None, None, None, None, None, None]
0205 
0206 Check that generator attributes are present
0207 
0208     >>> g = (i*i for i in range(3))
0209     >>> expected = set(['gi_frame', 'gi_running', 'next'])
0210     >>> set(attr for attr in dir(g) if not attr.startswith('__')) >= expected
0211     True
0212 
0213     >>> print g.next.__doc__
0214     x.next() -> the next value, or raise StopIteration
0215     >>> import types
0216     >>> isinstance(g, types.GeneratorType)
0217     True
0218 
0219 Check the __iter__ slot is defined to return self
0220 
0221     >>> iter(g) is g
0222     True
0223 
0224 Verify that the running flag is set properly
0225 
0226     >>> g = (me.gi_running for i in (0,1))
0227     >>> me = g
0228     >>> me.gi_running
0229     0
0230     >>> me.next()
0231     1
0232     >>> me.gi_running
0233     0
0234 
0235 Verify that genexps are weakly referencable
0236 
0237     >>> import weakref
0238     >>> g = (i*i for i in range(4))
0239     >>> wr = weakref.ref(g)
0240     >>> wr() is g
0241     True
0242     >>> p = weakref.proxy(g)
0243     >>> list(p)
0244     [0, 1, 4, 9]
0245 
0246 
0247 """
0248 
0249 
0250 __test__ = {'doctests' : doctests}
0251 
0252 def test_main(verbose=None):
0253     import sys
0254     from test import test_support
0255     from test import test_genexps
0256     test_support.run_doctest(test_genexps, verbose)
0257 
0258     # verify reference counting
0259     if verbose and hasattr(sys, "gettotalrefcount"):
0260         import gc
0261         counts = [None] * 5
0262         for i in xrange(len(counts)):
0263             test_support.run_doctest(test_genexps, verbose)
0264             gc.collect()
0265             counts[i] = sys.gettotalrefcount()
0266         print counts
0267 
0268 if __name__ == "__main__":
0269     test_main(verbose=True)
0270 

Generated by PyXR 0.9.4
SourceForge.net Logo