Utility Classes :: YieldSeq
Overview
YieldSeq() was dreamed up as a solution to the problem of wanting your generator to return objects of different types on sequential yields. Without YieldSeq(), nasty, imprecise workarounds are required:
@yields(IsOneOf(int, float)) def foo(): yield 5 yield 5.0 yield 6 yield 6.0
Where IsOneOf() is the IsOneOf utility class.
With the YieldSeq() utility class in hand, however, you can express this in a much more type-safe way:
@yields(YieldSeq(int, float, int, float)) def foo(): yield 5 yield 5.0 yield 6 yield 6.0
This approach is better because it retains a higher degree of precision as opposed to the IsOneOf()-based approach.
Details
-
The
YieldSeq()constructor requires at least one argument; an invocation likeYieldSeq()
will raise a
TypeErrorexception. -
YieldSeqinstances will compare equal (==) only if they have the same sequence of types. AllYieldSeqinstances that compare equal will hash to the same value. -
If the typechecked generator yields more values than the
YieldSeqinstance is prepared for, a_TC_YieldCountErrorexception will be raised with the number of expected yields.It is expected that this exception will be caught and converted to a
TypeCheckErrorbefore it reaches the user. -
As can be deduced from the examples given above, the
YieldSeqinstance will check sequential conditions against sequential yields. This sequence will not be interrupted if a particular yielded value fails to typecheck; the following code, for example, will examine all values yielded by the generator:@yields(YieldSeq(int, float, int, float)) def gen_foo(): yield 5 yield 5.0 yield "6" yield 6.0 gen = gen_foo() while True: try: print gen.next() except StopIteration: break except TypeCheckError: pass
Even though
"6"clearly fails its typecheck and will raise aTypeCheckError, the values 5, 5.0 and 6.0 will still be printed.