##// END OF EJS Templates
Merge pull request #10228 from srinivasreddy/patch-1...
Thomas Kluyver -
r23290:e8341164 merge
parent child Browse files
Show More
@@ -1,144 +1,60 b''
1 """TemporaryDirectory class, copied from Python 3.2.
1 """ This module contains classes - NamedFileInTemporaryDirectory, TemporaryWorkingDirectory.
2
2
3 This is copied from the stdlib and will be standard in Python 3.2 and onwards.
3 These classes add extra features such as creating a named file in temporary directory and
4 creating a context manager for the working directory which is also temporary.
4 """
5 """
5
6
6 import os as _os
7 import os as _os
7 import warnings as _warnings
8 import warnings as _warnings
8 import sys as _sys
9 import sys as _sys
9
10
10 # This code should only be used in Python versions < 3.2, since after that we
11 # can rely on the stdlib itself.
12 try:
13 from tempfile import TemporaryDirectory
11 from tempfile import TemporaryDirectory
14
12
15 except ImportError:
16 from tempfile import mkdtemp, template
17
18 class TemporaryDirectory(object):
19 """Create and return a temporary directory. This has the same
20 behavior as mkdtemp but can be used as a context manager. For
21 example:
22
23 with TemporaryDirectory() as tmpdir:
24 ...
25
26 Upon exiting the context, the directory and everthing contained
27 in it are removed.
28 """
29
30 def __init__(self, suffix="", prefix=template, dir=None):
31 self.name = mkdtemp(suffix, prefix, dir)
32 self._closed = False
33
34 def __enter__(self):
35 return self.name
36
37 def cleanup(self, _warn=False):
38 if self.name and not self._closed:
39 try:
40 self._rmtree(self.name)
41 except (TypeError, AttributeError) as ex:
42 # Issue #10188: Emit a warning on stderr
43 # if the directory could not be cleaned
44 # up due to missing globals
45 if "None" not in str(ex):
46 raise
47 print("ERROR: {!r} while cleaning up {!r}".format(ex, self,),
48 file=_sys.stderr)
49 return
50 self._closed = True
51 if _warn:
52 self._warn("Implicitly cleaning up {!r}".format(self),
53 Warning)
54
55 def __exit__(self, exc, value, tb):
56 self.cleanup()
57
58 def __del__(self):
59 # Issue a ResourceWarning if implicit cleanup needed
60 self.cleanup(_warn=True)
61
62
63 # XXX (ncoghlan): The following code attempts to make
64 # this class tolerant of the module nulling out process
65 # that happens during CPython interpreter shutdown
66 # Alas, it doesn't actually manage it. See issue #10188
67 _listdir = staticmethod(_os.listdir)
68 _path_join = staticmethod(_os.path.join)
69 _isdir = staticmethod(_os.path.isdir)
70 _remove = staticmethod(_os.remove)
71 _rmdir = staticmethod(_os.rmdir)
72 _os_error = _os.error
73 _warn = _warnings.warn
74
75 def _rmtree(self, path):
76 # Essentially a stripped down version of shutil.rmtree. We can't
77 # use globals because they may be None'ed out at shutdown.
78 for name in self._listdir(path):
79 fullname = self._path_join(path, name)
80 try:
81 isdir = self._isdir(fullname)
82 except self._os_error:
83 isdir = False
84 if isdir:
85 self._rmtree(fullname)
86 else:
87 try:
88 self._remove(fullname)
89 except self._os_error:
90 pass
91 try:
92 self._rmdir(path)
93 except self._os_error:
94 pass
95
96
97 class NamedFileInTemporaryDirectory(object):
13 class NamedFileInTemporaryDirectory(object):
98
14
99 def __init__(self, filename, mode='w+b', bufsize=-1, **kwds):
15 def __init__(self, filename, mode='w+b', bufsize=-1, **kwds):
100 """
16 """
101 Open a file named `filename` in a temporary directory.
17 Open a file named `filename` in a temporary directory.
102
18
103 This context manager is preferred over `NamedTemporaryFile` in
19 This context manager is preferred over `NamedTemporaryFile` in
104 stdlib `tempfile` when one needs to reopen the file.
20 stdlib `tempfile` when one needs to reopen the file.
105
21
106 Arguments `mode` and `bufsize` are passed to `open`.
22 Arguments `mode` and `bufsize` are passed to `open`.
107 Rest of the arguments are passed to `TemporaryDirectory`.
23 Rest of the arguments are passed to `TemporaryDirectory`.
108
24
109 """
25 """
110 self._tmpdir = TemporaryDirectory(**kwds)
26 self._tmpdir = TemporaryDirectory(**kwds)
111 path = _os.path.join(self._tmpdir.name, filename)
27 path = _os.path.join(self._tmpdir.name, filename)
112 self.file = open(path, mode, bufsize)
28 self.file = open(path, mode, bufsize)
113
29
114 def cleanup(self):
30 def cleanup(self):
115 self.file.close()
31 self.file.close()
116 self._tmpdir.cleanup()
32 self._tmpdir.cleanup()
117
33
118 __del__ = cleanup
34 __del__ = cleanup
119
35
120 def __enter__(self):
36 def __enter__(self):
121 return self.file
37 return self.file
122
38
123 def __exit__(self, type, value, traceback):
39 def __exit__(self, type, value, traceback):
124 self.cleanup()
40 self.cleanup()
125
41
126
42
127 class TemporaryWorkingDirectory(TemporaryDirectory):
43 class TemporaryWorkingDirectory(TemporaryDirectory):
128 """
44 """
129 Creates a temporary directory and sets the cwd to that directory.
45 Creates a temporary directory and sets the cwd to that directory.
130 Automatically reverts to previous cwd upon cleanup.
46 Automatically reverts to previous cwd upon cleanup.
131 Usage example:
47 Usage example:
132
48
133 with TemporaryWorkingDirectory() as tmpdir:
49 with TemporaryWorkingDirectory() as tmpdir:
134 ...
50 ...
135 """
51 """
136 def __enter__(self):
52 def __enter__(self):
137 self.old_wd = _os.getcwd()
53 self.old_wd = _os.getcwd()
138 _os.chdir(self.name)
54 _os.chdir(self.name)
139 return super(TemporaryWorkingDirectory, self).__enter__()
55 return super(TemporaryWorkingDirectory, self).__enter__()
140
56
141 def __exit__(self, exc, value, tb):
57 def __exit__(self, exc, value, tb):
142 _os.chdir(self.old_wd)
58 _os.chdir(self.old_wd)
143 return super(TemporaryWorkingDirectory, self).__exit__(exc, value, tb)
59 return super(TemporaryWorkingDirectory, self).__exit__(exc, value, tb)
144
60
General Comments 0
You need to be logged in to leave comments. Login now