|
|
71084d |
diff --git a/Lib/shutil.py b/Lib/shutil.py
|
|
|
71084d |
index 420802f..d0ff2ef 100644
|
|
|
71084d |
--- a/Lib/shutil.py
|
|
|
71084d |
+++ b/Lib/shutil.py
|
|
|
71084d |
@@ -446,17 +446,24 @@ def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None):
|
|
|
71084d |
zip_filename, base_dir)
|
|
|
71084d |
|
|
|
71084d |
if not dry_run:
|
|
|
71084d |
- zip = zipfile.ZipFile(zip_filename, "w",
|
|
|
71084d |
- compression=zipfile.ZIP_DEFLATED)
|
|
|
71084d |
-
|
|
|
71084d |
- for dirpath, dirnames, filenames in os.walk(base_dir):
|
|
|
71084d |
- for name in filenames:
|
|
|
71084d |
- path = os.path.normpath(os.path.join(dirpath, name))
|
|
|
71084d |
- if os.path.isfile(path):
|
|
|
71084d |
- zip.write(path, path)
|
|
|
71084d |
+ with zipfile.ZipFile(zip_filename, "w",
|
|
|
71084d |
+ compression=zipfile.ZIP_DEFLATED) as zf:
|
|
|
71084d |
+ path = os.path.normpath(base_dir)
|
|
|
71084d |
+ zf.write(path, path)
|
|
|
71084d |
+ if logger is not None:
|
|
|
71084d |
+ logger.info("adding '%s'", path)
|
|
|
71084d |
+ for dirpath, dirnames, filenames in os.walk(base_dir):
|
|
|
71084d |
+ for name in sorted(dirnames):
|
|
|
71084d |
+ path = os.path.normpath(os.path.join(dirpath, name))
|
|
|
71084d |
+ zf.write(path, path)
|
|
|
71084d |
if logger is not None:
|
|
|
71084d |
logger.info("adding '%s'", path)
|
|
|
71084d |
- zip.close()
|
|
|
71084d |
+ for name in filenames:
|
|
|
71084d |
+ path = os.path.normpath(os.path.join(dirpath, name))
|
|
|
71084d |
+ if os.path.isfile(path):
|
|
|
71084d |
+ zf.write(path, path)
|
|
|
71084d |
+ if logger is not None:
|
|
|
71084d |
+ logger.info("adding '%s'", path)
|
|
|
71084d |
|
|
|
71084d |
return zip_filename
|
|
|
71084d |
|
|
|
71084d |
diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py
|
|
|
71084d |
index 9bdb724..9238489 100644
|
|
|
71084d |
--- a/Lib/test/test_shutil.py
|
|
|
71084d |
+++ b/Lib/test/test_shutil.py
|
|
|
71084d |
@@ -10,13 +10,13 @@ import os.path
|
|
|
71084d |
import errno
|
|
|
71084d |
from os.path import splitdrive
|
|
|
71084d |
from distutils.spawn import find_executable, spawn
|
|
|
71084d |
-from shutil import (_make_tarball, _make_zipfile, make_archive,
|
|
|
71084d |
+from shutil import (make_archive,
|
|
|
71084d |
register_archive_format, unregister_archive_format,
|
|
|
71084d |
get_archive_formats)
|
|
|
71084d |
import tarfile
|
|
|
71084d |
import warnings
|
|
|
71084d |
|
|
|
71084d |
-from test import test_support
|
|
|
71084d |
+from test import test_support as support
|
|
|
71084d |
from test.test_support import TESTFN, check_warnings, captured_stdout
|
|
|
71084d |
|
|
|
71084d |
TESTFN2 = TESTFN + "2"
|
|
|
71084d |
@@ -372,139 +372,135 @@ class TestShutil(unittest.TestCase):
|
|
|
71084d |
@unittest.skipUnless(zlib, "requires zlib")
|
|
|
71084d |
def test_make_tarball(self):
|
|
|
71084d |
# creating something to tar
|
|
|
71084d |
- tmpdir = self.mkdtemp()
|
|
|
71084d |
- self.write_file([tmpdir, 'file1'], 'xxx')
|
|
|
71084d |
- self.write_file([tmpdir, 'file2'], 'xxx')
|
|
|
71084d |
- os.mkdir(os.path.join(tmpdir, 'sub'))
|
|
|
71084d |
- self.write_file([tmpdir, 'sub', 'file3'], 'xxx')
|
|
|
71084d |
+ root_dir, base_dir = self._create_files('')
|
|
|
71084d |
|
|
|
71084d |
tmpdir2 = self.mkdtemp()
|
|
|
71084d |
# force shutil to create the directory
|
|
|
71084d |
os.rmdir(tmpdir2)
|
|
|
71084d |
- unittest.skipUnless(splitdrive(tmpdir)[0] == splitdrive(tmpdir2)[0],
|
|
|
71084d |
+ unittest.skipUnless(splitdrive(root_dir)[0] == splitdrive(tmpdir2)[0],
|
|
|
71084d |
"source and target should be on same drive")
|
|
|
71084d |
|
|
|
71084d |
base_name = os.path.join(tmpdir2, 'archive')
|
|
|
71084d |
|
|
|
71084d |
# working with relative paths to avoid tar warnings
|
|
|
71084d |
- old_dir = os.getcwd()
|
|
|
71084d |
- os.chdir(tmpdir)
|
|
|
71084d |
- try:
|
|
|
71084d |
- _make_tarball(splitdrive(base_name)[1], '.')
|
|
|
71084d |
- finally:
|
|
|
71084d |
- os.chdir(old_dir)
|
|
|
71084d |
+ make_archive(splitdrive(base_name)[1], 'gztar', root_dir, '.')
|
|
|
71084d |
|
|
|
71084d |
# check if the compressed tarball was created
|
|
|
71084d |
tarball = base_name + '.tar.gz'
|
|
|
71084d |
- self.assertTrue(os.path.exists(tarball))
|
|
|
71084d |
+ self.assertTrue(os.path.isfile(tarball))
|
|
|
71084d |
+ self.assertTrue(tarfile.is_tarfile(tarball))
|
|
|
71084d |
+ with tarfile.open(tarball, 'r:gz') as tf:
|
|
|
71084d |
+ self.assertEqual(sorted(tf.getnames()),
|
|
|
71084d |
+ ['.', './file1', './file2',
|
|
|
71084d |
+ './sub', './sub/file3', './sub2'])
|
|
|
71084d |
|
|
|
71084d |
# trying an uncompressed one
|
|
|
71084d |
base_name = os.path.join(tmpdir2, 'archive')
|
|
|
71084d |
- old_dir = os.getcwd()
|
|
|
71084d |
- os.chdir(tmpdir)
|
|
|
71084d |
- try:
|
|
|
71084d |
- _make_tarball(splitdrive(base_name)[1], '.', compress=None)
|
|
|
71084d |
- finally:
|
|
|
71084d |
- os.chdir(old_dir)
|
|
|
71084d |
+ make_archive(splitdrive(base_name)[1], 'tar', root_dir, '.')
|
|
|
71084d |
tarball = base_name + '.tar'
|
|
|
71084d |
- self.assertTrue(os.path.exists(tarball))
|
|
|
71084d |
+ self.assertTrue(os.path.isfile(tarball))
|
|
|
71084d |
+ self.assertTrue(tarfile.is_tarfile(tarball))
|
|
|
71084d |
+ with tarfile.open(tarball, 'r') as tf:
|
|
|
71084d |
+ self.assertEqual(sorted(tf.getnames()),
|
|
|
71084d |
+ ['.', './file1', './file2',
|
|
|
71084d |
+ './sub', './sub/file3', './sub2'])
|
|
|
71084d |
|
|
|
71084d |
def _tarinfo(self, path):
|
|
|
71084d |
- tar = tarfile.open(path)
|
|
|
71084d |
- try:
|
|
|
71084d |
+ with tarfile.open(path) as tar:
|
|
|
71084d |
names = tar.getnames()
|
|
|
71084d |
names.sort()
|
|
|
71084d |
return tuple(names)
|
|
|
71084d |
- finally:
|
|
|
71084d |
- tar.close()
|
|
|
71084d |
|
|
|
71084d |
- def _create_files(self):
|
|
|
71084d |
+ def _create_files(self, base_dir='dist'):
|
|
|
71084d |
# creating something to tar
|
|
|
71084d |
- tmpdir = self.mkdtemp()
|
|
|
71084d |
- dist = os.path.join(tmpdir, 'dist')
|
|
|
71084d |
- os.mkdir(dist)
|
|
|
71084d |
- self.write_file([dist, 'file1'], 'xxx')
|
|
|
71084d |
- self.write_file([dist, 'file2'], 'xxx')
|
|
|
71084d |
+ root_dir = self.mkdtemp()
|
|
|
71084d |
+ dist = os.path.join(root_dir, base_dir)
|
|
|
71084d |
+ if not os.path.isdir(dist):
|
|
|
71084d |
+ os.makedirs(dist)
|
|
|
71084d |
+ self.write_file((dist, 'file1'), 'xxx')
|
|
|
71084d |
+ self.write_file((dist, 'file2'), 'xxx')
|
|
|
71084d |
os.mkdir(os.path.join(dist, 'sub'))
|
|
|
71084d |
- self.write_file([dist, 'sub', 'file3'], 'xxx')
|
|
|
71084d |
+ self.write_file((dist, 'sub', 'file3'), 'xxx')
|
|
|
71084d |
os.mkdir(os.path.join(dist, 'sub2'))
|
|
|
71084d |
- tmpdir2 = self.mkdtemp()
|
|
|
71084d |
- base_name = os.path.join(tmpdir2, 'archive')
|
|
|
71084d |
- return tmpdir, tmpdir2, base_name
|
|
|
71084d |
+ if base_dir:
|
|
|
71084d |
+ self.write_file((root_dir, 'outer'), 'xxx')
|
|
|
71084d |
+ return root_dir, base_dir
|
|
|
71084d |
|
|
|
71084d |
@unittest.skipUnless(zlib, "Requires zlib")
|
|
|
71084d |
- @unittest.skipUnless(find_executable('tar') and find_executable('gzip'),
|
|
|
71084d |
+ @unittest.skipUnless(find_executable('tar'),
|
|
|
71084d |
'Need the tar command to run')
|
|
|
71084d |
def test_tarfile_vs_tar(self):
|
|
|
71084d |
- tmpdir, tmpdir2, base_name = self._create_files()
|
|
|
71084d |
- old_dir = os.getcwd()
|
|
|
71084d |
- os.chdir(tmpdir)
|
|
|
71084d |
- try:
|
|
|
71084d |
- _make_tarball(base_name, 'dist')
|
|
|
71084d |
- finally:
|
|
|
71084d |
- os.chdir(old_dir)
|
|
|
71084d |
+ root_dir, base_dir = self._create_files()
|
|
|
71084d |
+ base_name = os.path.join(self.mkdtemp(), 'archive')
|
|
|
71084d |
+ make_archive(base_name, 'gztar', root_dir, base_dir)
|
|
|
71084d |
|
|
|
71084d |
# check if the compressed tarball was created
|
|
|
71084d |
tarball = base_name + '.tar.gz'
|
|
|
71084d |
- self.assertTrue(os.path.exists(tarball))
|
|
|
71084d |
+ self.assertTrue(os.path.isfile(tarball))
|
|
|
71084d |
|
|
|
71084d |
# now create another tarball using `tar`
|
|
|
71084d |
- tarball2 = os.path.join(tmpdir, 'archive2.tar.gz')
|
|
|
71084d |
- tar_cmd = ['tar', '-cf', 'archive2.tar', 'dist']
|
|
|
71084d |
- gzip_cmd = ['gzip', '-f9', 'archive2.tar']
|
|
|
71084d |
- old_dir = os.getcwd()
|
|
|
71084d |
- os.chdir(tmpdir)
|
|
|
71084d |
- try:
|
|
|
71084d |
- with captured_stdout() as s:
|
|
|
71084d |
- spawn(tar_cmd)
|
|
|
71084d |
- spawn(gzip_cmd)
|
|
|
71084d |
- finally:
|
|
|
71084d |
- os.chdir(old_dir)
|
|
|
71084d |
+ tarball2 = os.path.join(root_dir, 'archive2.tar')
|
|
|
71084d |
+ tar_cmd = ['tar', '-cf', 'archive2.tar', base_dir]
|
|
|
71084d |
+ with support.change_cwd(root_dir), captured_stdout():
|
|
|
71084d |
+ spawn(tar_cmd)
|
|
|
71084d |
|
|
|
71084d |
- self.assertTrue(os.path.exists(tarball2))
|
|
|
71084d |
+ self.assertTrue(os.path.isfile(tarball2))
|
|
|
71084d |
# let's compare both tarballs
|
|
|
71084d |
self.assertEqual(self._tarinfo(tarball), self._tarinfo(tarball2))
|
|
|
71084d |
|
|
|
71084d |
# trying an uncompressed one
|
|
|
71084d |
- base_name = os.path.join(tmpdir2, 'archive')
|
|
|
71084d |
- old_dir = os.getcwd()
|
|
|
71084d |
- os.chdir(tmpdir)
|
|
|
71084d |
- try:
|
|
|
71084d |
- _make_tarball(base_name, 'dist', compress=None)
|
|
|
71084d |
- finally:
|
|
|
71084d |
- os.chdir(old_dir)
|
|
|
71084d |
+ make_archive(base_name, 'tar', root_dir, base_dir)
|
|
|
71084d |
tarball = base_name + '.tar'
|
|
|
71084d |
- self.assertTrue(os.path.exists(tarball))
|
|
|
71084d |
+ self.assertTrue(os.path.isfile(tarball))
|
|
|
71084d |
|
|
|
71084d |
# now for a dry_run
|
|
|
71084d |
- base_name = os.path.join(tmpdir2, 'archive')
|
|
|
71084d |
- old_dir = os.getcwd()
|
|
|
71084d |
- os.chdir(tmpdir)
|
|
|
71084d |
- try:
|
|
|
71084d |
- _make_tarball(base_name, 'dist', compress=None, dry_run=True)
|
|
|
71084d |
- finally:
|
|
|
71084d |
- os.chdir(old_dir)
|
|
|
71084d |
+ make_archive(base_name, 'tar', root_dir, base_dir, dry_run=True)
|
|
|
71084d |
tarball = base_name + '.tar'
|
|
|
71084d |
- self.assertTrue(os.path.exists(tarball))
|
|
|
71084d |
+ self.assertTrue(os.path.isfile(tarball))
|
|
|
71084d |
|
|
|
71084d |
@unittest.skipUnless(zlib, "Requires zlib")
|
|
|
71084d |
@unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run')
|
|
|
71084d |
def test_make_zipfile(self):
|
|
|
71084d |
- # creating something to tar
|
|
|
71084d |
- tmpdir = self.mkdtemp()
|
|
|
71084d |
- self.write_file([tmpdir, 'file1'], 'xxx')
|
|
|
71084d |
- self.write_file([tmpdir, 'file2'], 'xxx')
|
|
|
71084d |
+ # creating something to zip
|
|
|
71084d |
+ root_dir, base_dir = self._create_files()
|
|
|
71084d |
+ base_name = os.path.join(self.mkdtemp(), 'archive')
|
|
|
71084d |
|
|
|
71084d |
- tmpdir2 = self.mkdtemp()
|
|
|
71084d |
- # force shutil to create the directory
|
|
|
71084d |
- os.rmdir(tmpdir2)
|
|
|
71084d |
- base_name = os.path.join(tmpdir2, 'archive')
|
|
|
71084d |
- _make_zipfile(base_name, tmpdir)
|
|
|
71084d |
+ res = make_archive(base_name, 'zip', root_dir, base_dir)
|
|
|
71084d |
|
|
|
71084d |
- # check if the compressed tarball was created
|
|
|
71084d |
- tarball = base_name + '.zip'
|
|
|
71084d |
- self.assertTrue(os.path.exists(tarball))
|
|
|
71084d |
+ self.assertEqual(res, base_name + '.zip')
|
|
|
71084d |
+ self.assertTrue(os.path.isfile(res))
|
|
|
71084d |
+ self.assertTrue(zipfile.is_zipfile(res))
|
|
|
71084d |
+ with zipfile.ZipFile(res) as zf:
|
|
|
71084d |
+ self.assertEqual(sorted(zf.namelist()),
|
|
|
71084d |
+ ['dist/', 'dist/file1', 'dist/file2',
|
|
|
71084d |
+ 'dist/sub/', 'dist/sub/file3', 'dist/sub2/'])
|
|
|
71084d |
|
|
|
71084d |
+ @unittest.skipUnless(zlib, "Requires zlib")
|
|
|
71084d |
+ @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run')
|
|
|
71084d |
+ @unittest.skipUnless(find_executable('zip'),
|
|
|
71084d |
+ 'Need the zip command to run')
|
|
|
71084d |
+ def test_zipfile_vs_zip(self):
|
|
|
71084d |
+ root_dir, base_dir = self._create_files()
|
|
|
71084d |
+ base_name = os.path.join(self.mkdtemp(), 'archive')
|
|
|
71084d |
+ archive = make_archive(base_name, 'zip', root_dir, base_dir)
|
|
|
71084d |
+
|
|
|
71084d |
+ # check if ZIP file was created
|
|
|
71084d |
+ self.assertEqual(archive, base_name + '.zip')
|
|
|
71084d |
+ self.assertTrue(os.path.isfile(archive))
|
|
|
71084d |
+
|
|
|
71084d |
+ # now create another ZIP file using `zip`
|
|
|
71084d |
+ archive2 = os.path.join(root_dir, 'archive2.zip')
|
|
|
71084d |
+ zip_cmd = ['zip', '-q', '-r', 'archive2.zip', base_dir]
|
|
|
71084d |
+ with support.change_cwd(root_dir):
|
|
|
71084d |
+ spawn(zip_cmd)
|
|
|
71084d |
+
|
|
|
71084d |
+ self.assertTrue(os.path.isfile(archive2))
|
|
|
71084d |
+ # let's compare both ZIP files
|
|
|
71084d |
+ with zipfile.ZipFile(archive) as zf:
|
|
|
71084d |
+ names = zf.namelist()
|
|
|
71084d |
+ with zipfile.ZipFile(archive2) as zf:
|
|
|
71084d |
+ names2 = zf.namelist()
|
|
|
71084d |
+ self.assertEqual(sorted(names), sorted(names2))
|
|
|
71084d |
|
|
|
71084d |
def test_make_archive(self):
|
|
|
71084d |
tmpdir = self.mkdtemp()
|
|
|
71084d |
@@ -521,39 +517,36 @@ class TestShutil(unittest.TestCase):
|
|
|
71084d |
else:
|
|
|
71084d |
group = owner = 'root'
|
|
|
71084d |
|
|
|
71084d |
- base_dir, root_dir, base_name = self._create_files()
|
|
|
71084d |
- base_name = os.path.join(self.mkdtemp() , 'archive')
|
|
|
71084d |
+ root_dir, base_dir = self._create_files()
|
|
|
71084d |
+ base_name = os.path.join(self.mkdtemp(), 'archive')
|
|
|
71084d |
res = make_archive(base_name, 'zip', root_dir, base_dir, owner=owner,
|
|
|
71084d |
group=group)
|
|
|
71084d |
- self.assertTrue(os.path.exists(res))
|
|
|
71084d |
+ self.assertTrue(os.path.isfile(res))
|
|
|
71084d |
|
|
|
71084d |
res = make_archive(base_name, 'zip', root_dir, base_dir)
|
|
|
71084d |
- self.assertTrue(os.path.exists(res))
|
|
|
71084d |
+ self.assertTrue(os.path.isfile(res))
|
|
|
71084d |
|
|
|
71084d |
res = make_archive(base_name, 'tar', root_dir, base_dir,
|
|
|
71084d |
owner=owner, group=group)
|
|
|
71084d |
- self.assertTrue(os.path.exists(res))
|
|
|
71084d |
+ self.assertTrue(os.path.isfile(res))
|
|
|
71084d |
|
|
|
71084d |
res = make_archive(base_name, 'tar', root_dir, base_dir,
|
|
|
71084d |
owner='kjhkjhkjg', group='oihohoh')
|
|
|
71084d |
- self.assertTrue(os.path.exists(res))
|
|
|
71084d |
+ self.assertTrue(os.path.isfile(res))
|
|
|
71084d |
|
|
|
71084d |
@unittest.skipUnless(zlib, "Requires zlib")
|
|
|
71084d |
@unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support")
|
|
|
71084d |
def test_tarfile_root_owner(self):
|
|
|
71084d |
- tmpdir, tmpdir2, base_name = self._create_files()
|
|
|
71084d |
- old_dir = os.getcwd()
|
|
|
71084d |
- os.chdir(tmpdir)
|
|
|
71084d |
+ root_dir, base_dir = self._create_files()
|
|
|
71084d |
+ base_name = os.path.join(self.mkdtemp(), 'archive')
|
|
|
71084d |
group = grp.getgrgid(0)[0]
|
|
|
71084d |
owner = pwd.getpwuid(0)[0]
|
|
|
71084d |
- try:
|
|
|
71084d |
- archive_name = _make_tarball(base_name, 'dist', compress=None,
|
|
|
71084d |
- owner=owner, group=group)
|
|
|
71084d |
- finally:
|
|
|
71084d |
- os.chdir(old_dir)
|
|
|
71084d |
+ with support.change_cwd(root_dir):
|
|
|
71084d |
+ archive_name = make_archive(base_name, 'gztar', root_dir, 'dist',
|
|
|
71084d |
+ owner=owner, group=group)
|
|
|
71084d |
|
|
|
71084d |
# check if the compressed tarball was created
|
|
|
71084d |
- self.assertTrue(os.path.exists(archive_name))
|
|
|
71084d |
+ self.assertTrue(os.path.isfile(archive_name))
|
|
|
71084d |
|
|
|
71084d |
# now checks the rights
|
|
|
71084d |
archive = tarfile.open(archive_name)
|
|
|
71084d |
@@ -859,7 +852,7 @@ class TestCopyFile(unittest.TestCase):
|
|
|
71084d |
|
|
|
71084d |
|
|
|
71084d |
def test_main():
|
|
|
71084d |
- test_support.run_unittest(TestShutil, TestMove, TestCopyFile)
|
|
|
71084d |
+ support.run_unittest(TestShutil, TestMove, TestCopyFile)
|
|
|
71084d |
|
|
|
71084d |
if __name__ == '__main__':
|
|
|
71084d |
test_main()
|
|
|
71084d |
diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py
|
|
|
71084d |
index 42c1b4d..98a9275 100644
|
|
|
71084d |
--- a/Lib/test/test_support.py
|
|
|
71084d |
+++ b/Lib/test/test_support.py
|
|
|
71084d |
@@ -491,6 +491,33 @@ TESTFN = "{}_{}_tmp".format(TESTFN, os.getpid())
|
|
|
71084d |
SAVEDCWD = os.getcwd()
|
|
|
71084d |
|
|
|
71084d |
@contextlib.contextmanager
|
|
|
71084d |
+def change_cwd(path, quiet=False):
|
|
|
71084d |
+ """Return a context manager that changes the current working directory.
|
|
|
71084d |
+
|
|
|
71084d |
+ Arguments:
|
|
|
71084d |
+
|
|
|
71084d |
+ path: the directory to use as the temporary current working directory.
|
|
|
71084d |
+
|
|
|
71084d |
+ quiet: if False (the default), the context manager raises an exception
|
|
|
71084d |
+ on error. Otherwise, it issues only a warning and keeps the current
|
|
|
71084d |
+ working directory the same.
|
|
|
71084d |
+
|
|
|
71084d |
+ """
|
|
|
71084d |
+ saved_dir = os.getcwd()
|
|
|
71084d |
+ try:
|
|
|
71084d |
+ os.chdir(path)
|
|
|
71084d |
+ except OSError:
|
|
|
71084d |
+ if not quiet:
|
|
|
71084d |
+ raise
|
|
|
71084d |
+ warnings.warn('tests may fail, unable to change CWD to: ' + path,
|
|
|
71084d |
+ RuntimeWarning, stacklevel=3)
|
|
|
71084d |
+ try:
|
|
|
71084d |
+ yield os.getcwd()
|
|
|
71084d |
+ finally:
|
|
|
71084d |
+ os.chdir(saved_dir)
|
|
|
71084d |
+
|
|
|
71084d |
+
|
|
|
71084d |
+@contextlib.contextmanager
|
|
|
71084d |
def temp_cwd(name='tempcwd', quiet=False):
|
|
|
71084d |
"""
|
|
|
71084d |
Context manager that creates a temporary directory and set it as CWD.
|