Index: Doc/library/tarfile.rst =================================================================== --- Doc/library/tarfile.rst (revision 78510) +++ Doc/library/tarfile.rst (working copy) @@ -650,6 +650,14 @@ tar.add(name) tar.close() +The same example using :func:`tarfile.open` as a context manager +(see :ref:`typecontextmanager`):: + + import tarfile + with tarfile.open("sample.tar", "w") as tar: + for name in ["foo", "bar", "quux"]: + tar.add(name) + How to read a gzip compressed tar archive and display some member information:: import tarfile Index: Lib/tarfile.py =================================================================== --- Lib/tarfile.py (revision 78510) +++ Lib/tarfile.py (working copy) @@ -2411,6 +2411,18 @@ """ if level <= self.debug: print >> sys.stderr, msg + + def __enter__(self): + """Enter the runtime context for this tarfile, if the tarfile + is in a valid state. Otherwise, an IOError is raised. + """ + self._check() + return self + + def __exit__(self, type, value, traceback): + """Exit the runtime context without supressing any exceptions. + """ + self.close() # class TarFile class TarIter: Index: Lib/test/test_tarfile.py =================================================================== --- Lib/test/test_tarfile.py (revision 78510) +++ Lib/test/test_tarfile.py (working copy) @@ -327,7 +327,34 @@ finally: os.remove(empty) + def test_context_manager(self): + with tarfile.open(tarname) as tar: + self.assertFalse(tar.closed, "closed inside runtime context") + self.assertTrue(tar.closed, "context manager failed") + def test_context_manager_closed(self): + tar = tarfile.open(tarname) + tar.close() + with self.assertRaises(IOError): + with tar: + pass + + def test_context_manager_exception(self): + # Create a unique exception type so that we + # can guarantee the exception source. + class TarfileTestException(Exception): pass + + try: + with tarfile.open(tarname) as tar: + raise TarfileTestException + except TarfileTestException: + self.assertTrue(tar.closed, "context manager failed") + except: + self.fail("wrong exception raised in context manager") + else: + self.fail("exception not reraised in context manager") + + class StreamReadTest(CommonReadTest): mode="r|"