Author: christian.heimes Date: Sat Feb 9 21:51:34 2008 New Revision: 60698
Modified: python/branches/py3k/ (props changed) python/branches/py3k/Doc/library/tempfile.rst python/branches/py3k/Lib/io.py python/branches/py3k/Lib/tempfile.py python/branches/py3k/Lib/test/test_sys.py python/branches/py3k/Lib/test/test_tempfile.py python/branches/py3k/Modules/_collectionsmodule.c Log: 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://[EMAIL PROTECTED]/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) ........ Modified: python/branches/py3k/Doc/library/tempfile.rst ============================================================================== --- python/branches/py3k/Doc/library/tempfile.rst (original) +++ python/branches/py3k/Doc/library/tempfile.rst Sat Feb 9 21:51:34 2008 @@ -51,7 +51,8 @@ The returned object is a true file object on POSIX platforms. On other platforms, it is a file-like object whose :attr:`file` attribute is the - underlying true file object. + underlying true file object. This file-like object can be used in a :keyword:`with` + statement, just like a normal file. .. function:: NamedTemporaryFile([mode='w+b'[, bufsize=-1[, suffix[, prefix[, dir[, delete]]]]]]) @@ -64,7 +65,8 @@ across platforms (it can be so used on Unix; it cannot on Windows NT or later). If *delete* is true (the default), the file is deleted as soon as it is closed. The returned object is always a file-like object whose :attr:`file` attribute - is the underlying true file object. + is the underlying true file object. This file-like object can be used in a :keyword:`with` + statement, just like a normal file. .. function:: SpooledTemporaryFile([max_size=0, [mode='w+b'[, bufsize=-1[, suffix[, prefix[, dir]]]]]]) @@ -79,7 +81,8 @@ The returned object is a file-like object whose :attr:`_file` attribute is either a :class:`StringIO` object or a true file object, depending on - whether :func:`rollover` has been called. + whether :func:`rollover` has been called. This file-like object can be used in a + :keyword:`with` statement, just like a normal file. .. function:: mkstemp([suffix[, prefix[, dir[, text]]]]) Modified: python/branches/py3k/Lib/io.py ============================================================================== --- python/branches/py3k/Lib/io.py (original) +++ python/branches/py3k/Lib/io.py Sat Feb 9 21:51:34 2008 @@ -365,6 +365,7 @@ def __enter__(self) -> "IOBase": # That's a forward reference """Context management protocol. Returns self.""" + self._checkClosed() return self def __exit__(self, *args) -> None: Modified: python/branches/py3k/Lib/tempfile.py ============================================================================== --- python/branches/py3k/Lib/tempfile.py (original) +++ python/branches/py3k/Lib/tempfile.py Sat Feb 9 21:51:34 2008 @@ -363,6 +363,7 @@ raise IOError(_errno.EEXIST, "No usable temporary filename found") + class _TemporaryFileWrapper: """Temporary file wrapper @@ -378,17 +379,25 @@ 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 @@ 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 @@ 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__() Modified: python/branches/py3k/Lib/test/test_sys.py ============================================================================== --- python/branches/py3k/Lib/test/test_sys.py (original) +++ python/branches/py3k/Lib/test/test_sys.py Sat Feb 9 21:51:34 2008 @@ -336,17 +336,17 @@ def test_compact_freelists(self): sys._compact_freelists() r = sys._compact_freelists() - # freed blocks shouldn't change - self.assertEqual(r[0][2], 0) - # fill freelists - ints = list(range(10000)) - floats = [float(i) for i in ints] - del ints - del floats - # should free more than 100 blocks - r = sys._compact_freelists() - self.assert_(r[0][1] > 100, r[0][1]) - self.assert_(r[0][2] > 100, r[0][2]) + ## freed blocks shouldn't change + #self.assertEqual(r[0][2], 0) + ## fill freelists + #ints = list(range(10000)) + #floats = [float(i) for i in ints] + #del ints + #del floats + ## should free more than 100 blocks + #r = sys._compact_freelists() + #self.assert_(r[0][1] > 100, r[0][1]) + #self.assert_(r[0][2] > 100, r[0][2]) def test_main(): test.test_support.run_unittest(SysModuleTest) Modified: python/branches/py3k/Lib/test/test_tempfile.py ============================================================================== --- python/branches/py3k/Lib/test/test_tempfile.py (original) +++ python/branches/py3k/Lib/test/test_tempfile.py Sat Feb 9 21:51:34 2008 @@ -1,5 +1,4 @@ # tempfile.py unit tests. - import tempfile import os import sys @@ -619,7 +618,6 @@ def test_multiple_close(self): # A NamedTemporaryFile can be closed many times without error - f = tempfile.NamedTemporaryFile() f.write(b'abc\n') f.close() @@ -629,6 +627,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) @@ -707,10 +715,23 @@ self.failUnless(f.fileno() > 0) self.failUnless(f._rolled) - def test_multiple_close(self): + def test_multiple_close_before_rollover(self): # A SpooledTemporaryFile can be closed many times without error f = tempfile.SpooledTemporaryFile() f.write(b'abc\n') + self.failIf(f._rolled) + f.close() + try: + f.close() + f.close() + except: + self.failOnException("close") + + def test_multiple_close_after_rollover(self): + # A SpooledTemporaryFile can be closed many times without error + f = tempfile.SpooledTemporaryFile(max_size=1) + f.write(b'abc\n') + self.failUnless(f._rolled) f.close() try: f.close() @@ -759,6 +780,46 @@ self.assertEqual(f.read(), "\u039B\r\n" + ("\u039B" * 20) + "\r\n") self.failUnless(f._rolled) + def test_context_manager_before_rollover(self): + # A SpooledTemporaryFile can be used as a context manager + with tempfile.SpooledTemporaryFile(max_size=1) as f: + self.failIf(f._rolled) + self.failIf(f.closed) + self.failUnless(f.closed) + def use_closed(): + with f: + pass + self.failUnlessRaises(ValueError, use_closed) + + def test_context_manager_during_rollover(self): + # A SpooledTemporaryFile can be used as a context manager + with tempfile.SpooledTemporaryFile(max_size=1) as f: + self.failIf(f._rolled) + f.write(b'abc\n') + f.flush() + self.failUnless(f._rolled) + self.failIf(f.closed) + self.failUnless(f.closed) + def use_closed(): + with f: + pass + self.failUnlessRaises(ValueError, use_closed) + + def test_context_manager_after_rollover(self): + # A SpooledTemporaryFile can be used as a context manager + f = tempfile.SpooledTemporaryFile(max_size=1) + f.write(b'abc\n') + f.flush() + self.failUnless(f._rolled) + with f: + self.failIf(f.closed) + self.failUnless(f.closed) + def use_closed(): + with f: + pass + self.failUnlessRaises(ValueError, use_closed) + + test_classes.append(test_SpooledTemporaryFile) Modified: python/branches/py3k/Modules/_collectionsmodule.c ============================================================================== --- python/branches/py3k/Modules/_collectionsmodule.c (original) +++ python/branches/py3k/Modules/_collectionsmodule.c Sat Feb 9 21:51:34 2008 @@ -1127,7 +1127,7 @@ { /* This calls the object's class. That only works for subclasses whose class constructor has the same signature. Subclasses that - define a different constructor signature must override copy(). + define a different constructor signature must override __copy__(). */ return PyObject_CallFunctionObjArgs((PyObject*)Py_TYPE(dd), dd->default_factory, dd, NULL); @@ -1182,8 +1182,6 @@ static PyMethodDef defdict_methods[] = { {"__missing__", (PyCFunction)defdict_missing, METH_O, defdict_missing_doc}, - {"copy", (PyCFunction)defdict_copy, METH_NOARGS, - defdict_copy_doc}, {"__copy__", (PyCFunction)defdict_copy, METH_NOARGS, defdict_copy_doc}, {"__reduce__", (PyCFunction)defdict_reduce, METH_NOARGS, _______________________________________________ Python-3000-checkins mailing list Python-3000-checkins@python.org http://mail.python.org/mailman/listinfo/python-3000-checkins