m-labs / artiq

A leading-edge control system for quantum information experiments
https://m-labs.hk/artiq
GNU Lesser General Public License v3.0
437 stars 201 forks source link

Fix nested outer `finally` blocks not running with nested `try`/`catch` #2620

Closed SquidDev closed 2 days ago

SquidDev commented 3 days ago

ARTIQ Pull Request

Description of Changes

If a function has a try/catch block nested inside a try/finally, then the finally clause will not be run if the inner block throws an exception without catching it.

For instance, the following code does not run print Cleanup.

try:
  try:
      raise RuntimeError("Error")
  except ValueError:
    print("ValueError")
finally:
  print("Cleanup")

We've seen this behaviour in the wild with ndscan, which has several functions with nested try statements.

This occurs because we skip adding the cleanup block to the landing pad if the try block does not have an exception. This patch changes the logic to only skip cleanup if we have no other try blocks in scope.

I've an alternative (though slightly more complex) patch that tracks whether we have any finally blocks in scope, and uses that instead — happy to submit that if preferred.

Type of Changes

Type
:bug: Bug fix

Steps (Choose relevant, delete irrelevant before submitting)

All Pull Requests

Code Changes

Documentation Changes

Git Logistics

Licensing

See copyright & licensing for more info. ARTIQ files that do not contain a license header are copyrighted by M-Labs Limited and are licensed under LGPLv3+.