summaryrefslogtreecommitdiffstats
path: root/Lib/tempfile.py
diff options
context:
space:
mode:
authorChristian Heimes <christian@cheimes.de>2008-02-09 20:51:34 (GMT)
committerChristian Heimes <christian@cheimes.de>2008-02-09 20:51:34 (GMT)
commit3ecfea71ffec6cb51c5d57f8d750dbac78092659 (patch)
tree4bdbb63aa0d3c00b6592e2e9a76e54598c176c15 /Lib/tempfile.py
parentbfd061218b153f1d30b6bd344e947b4ae0fd49a5 (diff)
downloadcpython-3ecfea71ffec6cb51c5d57f8d750dbac78092659.zip
cpython-3ecfea71ffec6cb51c5d57f8d750dbac78092659.tar.gz
cpython-3ecfea71ffec6cb51c5d57f8d750dbac78092659.tar.bz2
Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678-60695 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r60679 | raymond.hettinger | 2008-02-09 02:18:42 +0100 (Sat, 09 Feb 2008) | 1 line Make ABC containers inherit as documented. ........ r60684 | raymond.hettinger | 2008-02-09 04:34:52 +0100 (Sat, 09 Feb 2008) | 1 line Merge with r60683. ........ r60687 | raymond.hettinger | 2008-02-09 05:37:49 +0100 (Sat, 09 Feb 2008) | 1 line Add -3 warnings that set.copy(), dict.copy(), and defaultdict.copy() will go away in Py3.x ........ r60689 | raymond.hettinger | 2008-02-09 11:04:19 +0100 (Sat, 09 Feb 2008) | 1 line Metaclass declaration is inherited ........ r60691 | raymond.hettinger | 2008-02-09 11:06:20 +0100 (Sat, 09 Feb 2008) | 1 line Temporarily disable this test. It's been broken for a week. ........ r60695 | nick.coghlan | 2008-02-09 16:28:09 +0100 (Sat, 09 Feb 2008) | 1 line Issue 2021: Allow NamedTemporaryFile and SpooledTemporaryFile to be used as context managers. (The NamedTemporaryFile fix should be considered for backporting to 2.5) ........
Diffstat (limited to 'Lib/tempfile.py')
-rw-r--r--Lib/tempfile.py35
1 files changed, 33 insertions, 2 deletions
diff --git a/Lib/tempfile.py b/Lib/tempfile.py
index d725a9d..4f27f61 100644
--- a/Lib/tempfile.py
+++ b/Lib/tempfile.py
@@ -363,6 +363,7 @@ def mktemp(suffix="", prefix=template, dir=None):
raise IOError(_errno.EEXIST, "No usable temporary filename found")
+
class _TemporaryFileWrapper:
"""Temporary file wrapper
@@ -378,17 +379,25 @@ class _TemporaryFileWrapper:
self.delete = delete
def __getattr__(self, name):
+ # Attribute lookups are delegated to the underlying file
+ # and cached for non-numeric results
+ # (i.e. methods are cached, closed and friends are not)
file = self.__dict__['file']
a = getattr(file, name)
- if type(a) != type(0):
+ if not isinstance(a, int):
setattr(self, name, a)
return a
+ # The underlying __enter__ method returns the wrong object
+ # (self.file) so override it to return the wrapper
+ def __enter__(self):
+ self.file.__enter__()
+ return self
+
# NT provides delete-on-close as a primitive, so we don't need
# the wrapper to do anything special. We still use it so that
# file.name is useful (i.e. not "(fdopen)") with NamedTemporaryFile.
if _os.name != 'nt':
-
# Cache the unlinker so we don't get spurious errors at
# shutdown when the module-level "os" is None'd out. Note
# that this must be referenced as self.unlink, because the
@@ -406,6 +415,14 @@ class _TemporaryFileWrapper:
def __del__(self):
self.close()
+ # Need to trap __exit__ as well to ensure the file gets
+ # deleted when used in a with statement
+ def __exit__(self, exc, value, tb):
+ result = self.file.__exit__(exc, value, tb)
+ self.close()
+ return result
+
+
def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None,
newline=None, suffix="", prefix=template,
dir=None, delete=True):
@@ -523,6 +540,20 @@ class SpooledTemporaryFile:
self._rolled = True
+ # The method caching trick from NamedTemporaryFile
+ # won't work here, because _file may change from a
+ # _StringIO instance to a real file. So we list
+ # all the methods directly.
+
+ # Context management protocol
+ def __enter__(self):
+ if self._file.closed:
+ raise ValueError("Cannot enter context with closed file")
+ return self
+
+ def __exit__(self, exc, value, tb):
+ self._file.close()
+
# file protocol
def __iter__(self):
return self._file.__iter__()