Iterating over two iterables
There is no (general) way of telling the difference between an infinite and a finite iterator.

types might be a generator that stops yielding after a million items have been yielded.  The only fool-proof way of telling would be to consume the generator up to the point where it stops yielding items.  Of course, even if we've consumed a billion items and it hasn't stopped, we can't be sure it wouldn't stop at a later point.

This is why I recommend you change the specification for your function.  The new version will yield items until values have been up.  If there are too few types, it raises ValueError.

def serialize(types, values):
    types_iter = iter(types)
    for value in values:
        try:
            type = next(types_iter)
        except StopIteration:
            raise ValueError("Too few types.")
        yield type.dump(value)


If you really want to, you can check with len() that the lengths of types and values are the same, but as you have said, this will only work for some iterables.

def serialize(types, values):
    try:
        len_types, len_values = len(types), len(values)
    except TypeError:
        pass
    else:
        if len_values &gt; len_types:
            raise ValueError("Too many values.")
        if len_values &lt; len_types:
            raise ValueError('Too few values.')

        for type, value in itertools.izip(types, values):
            yield type.dump(value)
        return

    types_iter = iter(types)
    for value in values:
        try:
            type = next(types_iter)
        except StopIteration:
            raise ValueError("Too many values.")
        yield type.dump(value)