Python 'raise' without arguments: what is "the last exception that was active in the current scope"?

The Python 2 behavior is not so much a bug as a design flaw. It was addressed in Python 3.0 by adding the exception chaining features. The closest thing to documentation of this change can be found in PEP 3134 -- Exception Chaining and Embedded Tracebacks motivation:

During the handling of one exception (exception A), it is possible that another exception (exception B) may occur. In today's Python (version 2.4), if this happens, exception B is propagated outward and exception A is lost.

This is exactly what you're seeing in 2.7: EXPECTED (A) was lost because UNEXPECTED (B) appeared and overwrote it. With the newer exception chaining features in Python 3, the full context of both errors can be preserved via __cause__ and __context__ attributes on exception instances.

For a more direct cross-compatible workaround, I would encourage you to keep the references manually, explicitly show which error is being re-raised, and as usual avoid bare except statements (which are always too broad):

try:
    raise Exception('EXPECTED')
except Exception as err_expected:
    try:
        raise Exception('UNEXPECTED')
    except Exception as err_unexpected:
        pass
    raise err_expected

Should you wish to suppress the exception-chaining feature in a cross-compatible way, you can do that by setting err_expected.__cause__ = None before re-raising.