My understanding of how contextlib.contextmanager works was incorrect -- I thought it handled exceptions, but it doesn't . If an exception occurs during the @contextmanager-using function's yield statement (i.e. inside the with statement using it), the code after the yield won't get run.
This is easily fixed by using try/finally on our end.
EDIT: looks like this actually came up and was fixed for settings() already, as it correctly handles this.
Clean up hide/show if exceptions occur.