| from __future__ import division, print_function, unicode_literals | |
| from contextlib import contextmanager | |
| import os | |
| import shutil | |
| from tempfile import mkdtemp, NamedTemporaryFile | |
| def ignore_missing_file(filename=None): | |
| try: | |
| yield | |
| except OSError as e: | |
| if e.errno != 2 or filename and e.filename != filename: | |
| raise | |
| def in_dir(dirpath): | |
| # WARNING not thread-safe | |
| prev = os.path.abspath(os.getcwd()) | |
| os.chdir(dirpath) | |
| try: | |
| yield | |
| finally: | |
| os.chdir(prev) | |
| def TempDir(**kw): | |
| """mkdtemp wrapper that automatically deletes the directory | |
| """ | |
| d = mkdtemp(**kw) | |
| try: | |
| yield d | |
| finally: | |
| with ignore_missing_file(d): | |
| shutil.rmtree(d) | |
| def TempFile(**kw): | |
| """NamedTemporaryFile wrapper that doesn't fail if you (re)move the file | |
| """ | |
| f = NamedTemporaryFile(**kw) | |
| try: | |
| yield f | |
| finally: | |
| with ignore_missing_file(): | |
| f.__exit__(None, None, None) | |
| def force_link(source, link_name): | |
| # WARNING not atomic | |
| with ignore_missing_file(): | |
| os.remove(link_name) | |
| os.link(source, link_name) | |