(prepep) Preventing future issues with warnings as errors

Here’s a code block with all the syntax warnings (slightly edited):

So, what’s literally always incorrect here?

  • Literal divided by zero (currently not a warning):
    1 / 0
    
    Equivalent to:
    raise ZeroDivisionError("division by zero")
    
  • Return that’s overwritten in a finally block (warning in a different place):
    try:
        return 1 # <- warn here
    finally:
        return 2 # <- not here
    
    Equivalent to:
    try:
        pass
    finally:
        return 2
    
  • Assert with parentheses:
    assert (x, "msg")
    
    Equivalent to:
    pass
    
  • Invalid operations on displays:
    {}()
    {1}[1]
    "a"["b"]
    
    Equivalent to:
    raise TypeError("'dict' object is not callable")
    raise TypeError("'set' object is not subscriptable")
    raise TypeError("string indices must be integers, not 'str'")
    

What should display a warning anyway?

  • Ambiguous syntax:
    x = [y + 0x1for y in [1]]
    
    Equivalent to:
    x = [y + 0x1f or y in [1]]
    
  • Strict equality (only works with small numbers):
    x = y is 1
    
    Equivalent to:
    x = y == 1 and isinstance(y, int)
    
  • Single backslashes (only works with invalid escape sequences):
    x = "\99"
    x = f"\{1}"
    
    Equivalent to:
    x = "\\99"
    x = f"\\{1}"
    

And what’s more controversial:

  • Supressing exceptions in finally:
    try:
        input() # Ctrl+C
    finally:
        return 1
    
    Equivalent to:
    try:
        input() # Ctrl+C
    except:
        pass
    return 1