From the docs:
Exception OverflowError
Raised when the result of an arithmetic operation is too large to be represented. This cannot occur for long integers (which would rather raise MemoryError than give up) and for most operations with plain integers, which return a long integer instead. Because of the lack of standardization of floating point exception handling in C, most floating point operations also aren’t checked.
Exception MemoryError
Raised when an operation runs out of memory but the situation may still be rescued (by deleting some objects). The associated value is a string indicating what kind of (internal) operation ran out of memory. Note that because of the underlying memory management architecture (C’s malloc() function), the interpreter may not always be able to completely recover from this situation; it nevertheless raises an exception so that a stack traceback can be printed, in case a run-away program was the cause.
In Python 2, range(1000000000) produces a list with 1000000000 elements, with causes you to run out of memory. If you replace range with xrange, the problem goes away because you are using a generator instead.
In the second example, 1000000000 is actually a long. If you use xrange, you get:
>>> (i for i in xrange(10000000000))
OverflowError: long int too large to convert to int