Skip to content

Instantly share code, notes, and snippets.

@nitori
Last active September 3, 2024 22:12
Show Gist options
  • Save nitori/1abf820684c114d03137c2416c238b6e to your computer and use it in GitHub Desktop.
Save nitori/1abf820684c114d03137c2416c238b6e to your computer and use it in GitHub Desktop.
Simple rollback on error with contextlib.ExitStack
import os
import shutil
from contextlib import ExitStack
def create_folder(stack: ExitStack, path):
try:
os.mkdir(path)
except FileExistsError:
pass
if not os.path.isdir(path):
raise NotADirectoryError(repr(path))
stack.callback(lambda: os.rmdir(path))
def copy_file(stack: ExitStack, src, dst):
shutil.copyfile(src, dst)
stack.callback(lambda: os.unlink(dst))
def main():
with ExitStack() as stack:
create_folder(stack, './foobar')
copy_file(stack, './foo.json', './foobar/spam.json')
copy_file(stack, './foo.json', './foobar/spam1.json')
copy_file(stack, './foo.json', './foobar/spam2.json')
copy_file(stack, './foo.json', './foobar/spam3.json')
copy_file(stack, './foo.json', './foobar/spam4')
create_folder(stack,'./foobar/spam4') # Error!
create_folder(stack, './foobar/spam5')
stack.pop_all() # on success, clear exit stack, so the files/folders stay.
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment