Exceptions handlers (except:) are evaluated in the order they are written. Once a match is found, the evaluation stops.

In some contexts an except block is dead code as it will never catch any exception:

This rule raises an issue when an except block catches every exception before a later except block could catch it.

Noncompliant Code Example

def foo():
    try:
        raise FloatingPointError()
    except (ArithmeticError, RuntimeError) as e:
        print(e)
    except FloatingPointError as e: # Noncompliant. FloatingPointError is a subclass of ArithmeticError
        print("Never executed")
    except OverflowError as e: # Noncompliant. OverflowError is a subclass of ArithmeticError
        print("Never executed")

    try:
        raise TypeError()
    except TypeError as e:
        print(e)
    except TypeError as e: # Noncompliant. Duplicate Except.
        print("Never executed")

    try:
        raise ValueError()
    except BaseException as e:
        print(e)
    except: # Noncompliant. This is equivalent to "except BaseException" block
        print("Never executed")

Compliant Solution

def foo():
    try:
        raise FloatingPointError()
    except FloatingPointError as e:
        print("Executed")
    except OverflowError as e:
        print("Executed")
    except (ArithmeticError, RuntimeError) as e:
        print(e)

    try:
        raise TypeError()
    except TypeError as e:
        print(e)

    try:
        raise ValueError()
    except BaseException as e:
        print(e)

See