From: <pj...@us...> - 2009-05-13 02:49:13
|
Revision: 6345 http://jython.svn.sourceforge.net/jython/?rev=6345&view=rev Author: pjenvey Date: 2009-05-13 02:48:53 +0000 (Wed, 13 May 2009) Log Message: ----------- from: http://svn.python.org/projects/python/branches/release25-maint/Lib/tempfile.py@60728 http://svn.python.org/projects/python/branches/release25-maint/Lib/test/test_tempfile.py@60728 Modified Paths: -------------- trunk/jython/Lib/tempfile.py trunk/jython/Lib/test/test_tempfile.py Modified: trunk/jython/Lib/tempfile.py =================================================================== --- trunk/jython/Lib/tempfile.py 2009-05-12 01:51:08 UTC (rev 6344) +++ trunk/jython/Lib/tempfile.py 2009-05-13 02:48:53 UTC (rev 6345) @@ -377,30 +377,32 @@ self.name = name self.close_called = False - # XXX: CPython assigns unlink as a class var but this would - # rebind Jython's os.unlink (to be a classmethod) because it's - # not a built-in function (unfortunately built-in functions act - # differently when binding: - # http://mail.python.org/pipermail/python-dev/2003-April/034749.html) - - # 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 - # name TemporaryFileWrapper may also get None'd out before - # __del__ is called. - self.unlink = _os.unlink - 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): 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 + # name TemporaryFileWrapper may also get None'd out before + # __del__ is called. + unlink = _os.unlink def close(self): if not self.close_called: @@ -411,6 +413,14 @@ 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', bufsize=-1, suffix="", prefix=template, dir=None): """Create and return a temporary file. Modified: trunk/jython/Lib/test/test_tempfile.py =================================================================== --- trunk/jython/Lib/test/test_tempfile.py 2009-05-12 01:51:08 UTC (rev 6344) +++ trunk/jython/Lib/test/test_tempfile.py 2009-05-13 02:48:53 UTC (rev 6345) @@ -1,6 +1,5 @@ -# From Python 2.5.1 # tempfile.py unit tests. - +from __future__ import with_statement import tempfile import os import sys @@ -208,32 +207,21 @@ class mkstemped: _bflags = tempfile._bin_openflags _tflags = tempfile._text_openflags + _close = os.close + _unlink = os.unlink def __init__(self, dir, pre, suf, bin): if bin: flags = self._bflags else: flags = self._tflags - # XXX: CPython assigns _close/_unlink as class vars but this - # would rebind Jython's close/unlink (to be classmethods) - # because they're not built-in functions (unfortunately - # built-in functions act differently when binding: - # http://mail.python.org/pipermail/python-dev/2003-April/034749.html) - self._close = os.close - self._unlink = os.unlink (self.fd, self.name) = tempfile._mkstemp_inner(dir, pre, suf, flags) def write(self, str): os.write(self.fd, str) - # XXX: self.test_choose_directory expects the file to have been deleted - # (via __del__) by the time it's called, which is CPython specific - # garbage collection behavior. We need to delete it now in Jython - self._close(self.fd) - self._unlink(self.name) def __del__(self): self._close(self.fd) - if os.path.exists(self.name): - self._unlink(self.name) + self._unlink(self.name) def do_create(self, dir=None, pre="", suf="", bin=1): if dir is None: @@ -259,10 +247,6 @@ extant = range(TEST_FILES) for i in extant: extant[i] = self.do_create(pre="aa") - # XXX: Ensure mkstemped files are deleted (can't rely on Java's - # GC) - for i in extant: - i.__del__() def test_choose_directory(self): # _mkstemp_inner can create files in a user-selected directory @@ -272,8 +256,7 @@ finally: os.rmdir(dir) - # XXX: Jython can't set the write mode yet - def _test_file_mode(self): + def test_file_mode(self): # _mkstemp_inner creates files with the proper mode if not has_stat: return # ugh, can't use TestSkipped. @@ -315,7 +298,7 @@ # On Windows a spawn* /path/ with embedded spaces shouldn't be quoted, # but an arg with embedded spaces should be decorated with double # quotes on each end - if sys.platform in ('win32'): + if sys.platform in ('win32',): decorated = '"%s"' % sys.executable tester = '"%s"' % tester else: @@ -494,9 +477,6 @@ # mkdtemp creates directories with the proper mode if not has_stat: return # ugh, can't use TestSkipped. - if os.name == 'java': - # Java doesn't support stating files for permissions - return dir = self.do_create() try: @@ -529,25 +509,18 @@ self.dir = None class mktemped: + _unlink = os.unlink _bflags = tempfile._bin_openflags def __init__(self, dir, pre, suf): - # XXX: Assign _unlink here, instead of as a class var. See - # mkstemped.__init__ for an explanation - self._unlink = os.unlink - self.name = tempfile.mktemp(dir=dir, prefix=pre, suffix=suf) # Create the file. This will raise an exception if it's # mysteriously appeared in the meanwhile. os.close(os.open(self.name, self._bflags, 0600)) - # XXX: test_mktemp.tearDown expects the file to have been deleted - # (via __del__) by the time it's called, which is CPython specific - # garbage collection behavior. We need to delete it now in Jython + + def __del__(self): self._unlink(self.name) - #def __del__(self): - # self._unlink(self.name) - def do_create(self, pre="", suf=""): try: file = self.mktemped(self.dir, pre, suf) @@ -628,7 +601,6 @@ def test_multiple_close(self): # A NamedTemporaryFile can be closed many times without error - f = tempfile.NamedTemporaryFile() f.write('abc\n') f.close() @@ -638,6 +610,16 @@ except: self.failOnException("close") + def test_context_manager(self): + # A NamedTemporaryFile can be used as a context manager + with tempfile.NamedTemporaryFile() as f: + self.failUnless(os.path.exists(f.name)) + self.failIf(os.path.exists(f.name)) + def use_closed(): + with f: + pass + self.failUnlessRaises(ValueError, use_closed) + # How to test the mode and bufsize parameters? test_classes.append(test_NamedTemporaryFile) @@ -693,7 +675,3 @@ if __name__ == "__main__": test_main() - # XXX: Nudge Java's GC in an attempt to trigger any temp file's - # __del__ (cause them to be deleted) that hasn't been called - from java.lang import System - System.gc() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |