Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is exit code zero ("good") when I fail to handle an exception?

Consider the following code snippets and the resulting printouts from the console:

Snippet 1

Behaves just fine. Everything is hunkydory.

Code

try:
    raise ValueError()
finally:
    print(3)

Console Output

Traceback (most recent call last):
  File "D:/FILE_MGMT_PYTHON/fbzdfbhedrh.py", line 5, in <module>
    raise ValueError()
ValueError
3

Snippet 2

Also behaves just fine. Everything is hunkydory.

Code

try:
    raise ValueError()
except type("", (Exception,), dict()):
    print("this is not supposed to print")
finally:
    print(3)

Console Output

3
Traceback (most recent call last):
  File "D:/FILE_MGMT_PYTHON/fbzdfbhedrh.py", line 14, in <module>
    raise ValueError()
ValueError

Snippet 3

I don't understand why the following does not result in an unhandled exception being printed to the console:

Code

def e():
    try:
        raise ValueError()
        x = y + z
        L = [1, 2, 3]
        print(L[9999999999999999999999999999])
    except type("", (Exception,), dict()) as exc:
        print("this is not supposed to print")
        return "strawberries   " + src(exc)
    finally:
        return "finally"

print(e())

Console Output

finally

Process finished with exit code 0

Build:

------------------
System Information
------------------
      Time of this report: 10/25/2019, 07:22:01
             Machine name: DESKTOP-U5M46TJ
               Machine Id: {403D9006-3BF1-4C4B-AAF5-2AD795E00738}
         Operating System: Windows 10 Pro 64-bit (10.0, Build 18362) (18362.19h1_release.190318-1202)
                 Language: English (Regional Setting: English)
      System Manufacturer: System manufacturer
             System Model: System Product Name
                     BIOS: BIOS Date: 10/31/12 20:41:07 Ver: 36.02 (type: BIOS)
                Processor: Intel(R) Core(TM) i5-2500K CPU @ 3.30GHz (4 CPUs), ~3.3GHz
                   Memory: 4096MB RAM
      Available OS Memory: 4064MB RAM
                Page File: 12606MB used, 3744MB available
              Windows Dir: C:\Windows
          DirectX Version: DirectX 12
      DX Setup Parameters: Not found
         User DPI Setting: 96 DPI (100 percent)
       System DPI Setting: 144 DPI (150 percent)
          DWM DPI Scaling: UnKnown
                 Miracast: Available, with HDCP
Microsoft Graphics Hybrid: Not Supported
 DirectX Database Version: Unknown
           DxDiag Version: 10.00.18362.0387 64bit Unicode

------------------
IDE Information
------------------
PyCharm 2019.1.3 (Community Edition)
Build #PC-191.7479.30, built on May 29, 2019
JRE: 11.0.2+9-b159.60 amd64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0

------------------
Python Information
------------------
print(sys.version)
print(sys.version_info)
print(sys.hexversion)

3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:21:23) [MSC v.1916 32 bit (Intel)]
sys.version_info(major=3, minor=8, micro=0, releaselevel='final', serial=0)
50856176
like image 582
Toothpick Anemone Avatar asked Jan 01 '23 13:01

Toothpick Anemone


1 Answers

Returning from a finally block discards the exception. The function can't return and raise the exception, and you're telling it that you want it to return.

The exception is going to be thrown, but before the try statement can be exited, the finally block needs to be run. Your finally block says "regardless of whatever you thought you were doing, I want to return". So the exception is discarded.

Similary, if you were returning from a try block, and the finally block raised an exception, the return value would be discarded.

See Defining Clean-up Actions in the Python docs:

  • If an exception occurs during execution of the try clause, the exception may be handled by an except clause. If the exception is not handled by an except clause, the exception is re-raised after the finally clause has been executed.
    ...
  • If a finally clause includes a return statement, the finally clause’s return statement will execute before, and instead of, the return statement in a try clause.
like image 150
khelwood Avatar answered Feb 09 '23 03:02

khelwood