1414from contextlib import ExitStack
1515from os .path import splitdrive
1616from distutils .spawn import find_executable , spawn
17- from shutil import (_make_tarball , _make_zipfile , make_archive ,
17+ from shutil import (make_archive ,
1818 register_archive_format , unregister_archive_format ,
1919 get_archive_formats , Error , unpack_archive ,
2020 register_unpack_format , RegistryError ,
@@ -86,6 +86,18 @@ def read_file(path, binary=False):
8686 with open (path , 'rb' if binary else 'r' ) as fp :
8787 return fp .read ()
8888
89+ def rlistdir (path ):
90+ res = []
91+ for name in sorted (os .listdir (path )):
92+ p = os .path .join (path , name )
93+ if os .path .isdir (p ) and not os .path .islink (p ):
94+ res .append (name + '/' )
95+ for n in rlistdir (p ):
96+ res .append (name + '/' + n )
97+ else :
98+ res .append (name )
99+ return res
100+
89101
90102class TestShutil (unittest .TestCase ):
91103
@@ -951,114 +963,105 @@ def test_copy2(self):
951963 @requires_zlib
952964 def test_make_tarball (self ):
953965 # creating something to tar
954- tmpdir = self .mkdtemp ()
955- write_file ((tmpdir , 'file1' ), 'xxx' )
956- write_file ((tmpdir , 'file2' ), 'xxx' )
957- os .mkdir (os .path .join (tmpdir , 'sub' ))
958- write_file ((tmpdir , 'sub' , 'file3' ), 'xxx' )
966+ root_dir , base_dir = self ._create_files ('' )
959967
960968 tmpdir2 = self .mkdtemp ()
961969 # force shutil to create the directory
962970 os .rmdir (tmpdir2 )
963- unittest .skipUnless (splitdrive (tmpdir )[0 ] == splitdrive (tmpdir2 )[0 ],
971+ unittest .skipUnless (splitdrive (root_dir )[0 ] == splitdrive (tmpdir2 )[0 ],
964972 "source and target should be on same drive" )
965973
966974 base_name = os .path .join (tmpdir2 , 'archive' )
967975
968976 # working with relative paths to avoid tar warnings
969- with support .change_cwd (tmpdir ):
970- _make_tarball (splitdrive (base_name )[1 ], '.' )
977+ make_archive (splitdrive (base_name )[1 ], 'gztar' , root_dir , '.' )
971978
972979 # check if the compressed tarball was created
973980 tarball = base_name + '.tar.gz'
974- self .assertTrue (os .path .exists (tarball ))
981+ self .assertTrue (os .path .isfile (tarball ))
982+ self .assertTrue (tarfile .is_tarfile (tarball ))
983+ with tarfile .open (tarball , 'r:gz' ) as tf :
984+ self .assertCountEqual (tf .getnames (),
985+ ['.' , './sub' , './sub2' ,
986+ './file1' , './file2' , './sub/file3' ])
975987
976988 # trying an uncompressed one
977989 base_name = os .path .join (tmpdir2 , 'archive' )
978- with support .change_cwd (tmpdir ):
979- _make_tarball (splitdrive (base_name )[1 ], '.' , compress = None )
990+ make_archive (splitdrive (base_name )[1 ], 'tar' , root_dir , '.' )
980991 tarball = base_name + '.tar'
981- self .assertTrue (os .path .exists (tarball ))
992+ self .assertTrue (os .path .isfile (tarball ))
993+ self .assertTrue (tarfile .is_tarfile (tarball ))
994+ with tarfile .open (tarball , 'r' ) as tf :
995+ self .assertCountEqual (tf .getnames (),
996+ ['.' , './sub' , './sub2' ,
997+ './file1' , './file2' , './sub/file3' ])
982998
983999 def _tarinfo (self , path ):
984- tar = tarfile .open (path )
985- try :
1000+ with tarfile .open (path ) as tar :
9861001 names = tar .getnames ()
9871002 names .sort ()
9881003 return tuple (names )
989- finally :
990- tar .close ()
9911004
992- def _create_files (self ):
1005+ def _create_files (self , base_dir = 'dist' ):
9931006 # creating something to tar
994- tmpdir = self .mkdtemp ()
995- dist = os .path .join (tmpdir , 'dist' )
996- os .mkdir (dist )
1007+ root_dir = self .mkdtemp ()
1008+ dist = os .path .join (root_dir , base_dir )
1009+ os .makedirs (dist , exist_ok = True )
9971010 write_file ((dist , 'file1' ), 'xxx' )
9981011 write_file ((dist , 'file2' ), 'xxx' )
9991012 os .mkdir (os .path .join (dist , 'sub' ))
10001013 write_file ((dist , 'sub' , 'file3' ), 'xxx' )
10011014 os .mkdir (os .path .join (dist , 'sub2' ))
1002- tmpdir2 = self . mkdtemp ()
1003- base_name = os . path . join ( tmpdir2 , 'archive ' )
1004- return tmpdir , tmpdir2 , base_name
1015+ if base_dir :
1016+ write_file (( root_dir , 'outer' ), 'xxx ' )
1017+ return root_dir , base_dir
10051018
10061019 @requires_zlib
1007- @unittest .skipUnless (find_executable ('tar' ) and find_executable ( 'gzip' ) ,
1020+ @unittest .skipUnless (find_executable ('tar' ),
10081021 'Need the tar command to run' )
10091022 def test_tarfile_vs_tar (self ):
1010- tmpdir , tmpdir2 , base_name = self ._create_files ()
1011- with support . change_cwd ( tmpdir ):
1012- _make_tarball (base_name , 'dist' )
1023+ root_dir , base_dir = self ._create_files ()
1024+ base_name = os . path . join ( self . mkdtemp (), 'archive' )
1025+ make_archive (base_name , 'gztar' , root_dir , base_dir )
10131026
10141027 # check if the compressed tarball was created
10151028 tarball = base_name + '.tar.gz'
1016- self .assertTrue (os .path .exists (tarball ))
1029+ self .assertTrue (os .path .isfile (tarball ))
10171030
10181031 # now create another tarball using `tar`
1019- tarball2 = os .path .join (tmpdir , 'archive2.tar.gz' )
1020- tar_cmd = ['tar' , '-cf' , 'archive2.tar' , 'dist' ]
1021- gzip_cmd = ['gzip' , '-f9' , 'archive2.tar' ]
1022- with support .change_cwd (tmpdir ):
1023- with captured_stdout () as s :
1024- spawn (tar_cmd )
1025- spawn (gzip_cmd )
1026-
1027- self .assertTrue (os .path .exists (tarball2 ))
1032+ tarball2 = os .path .join (root_dir , 'archive2.tar' )
1033+ tar_cmd = ['tar' , '-cf' , 'archive2.tar' , base_dir ]
1034+ with support .change_cwd (root_dir ), captured_stdout ():
1035+ spawn (tar_cmd )
1036+
1037+ self .assertTrue (os .path .isfile (tarball2 ))
10281038 # let's compare both tarballs
10291039 self .assertEqual (self ._tarinfo (tarball ), self ._tarinfo (tarball2 ))
10301040
10311041 # trying an uncompressed one
1032- base_name = os .path .join (tmpdir2 , 'archive' )
1033- with support .change_cwd (tmpdir ):
1034- _make_tarball (base_name , 'dist' , compress = None )
1042+ make_archive (base_name , 'tar' , root_dir , base_dir )
10351043 tarball = base_name + '.tar'
1036- self .assertTrue (os .path .exists (tarball ))
1044+ self .assertTrue (os .path .isfile (tarball ))
10371045
10381046 # now for a dry_run
1039- base_name = os .path .join (tmpdir2 , 'archive' )
1040- with support .change_cwd (tmpdir ):
1041- _make_tarball (base_name , 'dist' , compress = None , dry_run = True )
1047+ make_archive (base_name , 'tar' , root_dir , base_dir , dry_run = True )
10421048 tarball = base_name + '.tar'
1043- self .assertTrue (os .path .exists (tarball ))
1049+ self .assertTrue (os .path .isfile (tarball ))
10441050
10451051 @requires_zlib
10461052 @unittest .skipUnless (ZIP_SUPPORT , 'Need zip support to run' )
10471053 def test_make_zipfile (self ):
1048- # creating something to tar
1049- tmpdir = self .mkdtemp ()
1050- write_file ((tmpdir , 'file1' ), 'xxx' )
1051- write_file ((tmpdir , 'file2' ), 'xxx' )
1052-
1053- tmpdir2 = self .mkdtemp ()
1054- # force shutil to create the directory
1055- os .rmdir (tmpdir2 )
1056- base_name = os .path .join (tmpdir2 , 'archive' )
1057- _make_zipfile (base_name , tmpdir )
1054+ # creating something to zip
1055+ root_dir , base_dir = self ._create_files ()
1056+ base_name = os .path .join (self .mkdtemp (), 'archive' )
1057+ res = make_archive (base_name , 'zip' , root_dir , 'dist' )
10581058
1059- # check if the compressed tarball was created
1060- tarball = base_name + '.zip'
1061- self .assertTrue (os .path .exists (tarball ))
1059+ self .assertEqual (res , base_name + '.zip' )
1060+ self .assertTrue (os .path .isfile (res ))
1061+ self .assertTrue (zipfile .is_zipfile (res ))
1062+ with zipfile .ZipFile (res ) as zf :
1063+ self .assertCountEqual (zf .namelist (),
1064+ ['dist/file1' , 'dist/file2' , 'dist/sub/file3' ])
10621065
10631066
10641067 def test_make_archive (self ):
@@ -1076,36 +1079,37 @@ def test_make_archive_owner_group(self):
10761079 else :
10771080 group = owner = 'root'
10781081
1079- base_dir , root_dir , base_name = self ._create_files ()
1080- base_name = os .path .join (self .mkdtemp () , 'archive' )
1082+ root_dir , base_dir = self ._create_files ()
1083+ base_name = os .path .join (self .mkdtemp (), 'archive' )
10811084 res = make_archive (base_name , 'zip' , root_dir , base_dir , owner = owner ,
10821085 group = group )
1083- self .assertTrue (os .path .exists (res ))
1086+ self .assertTrue (os .path .isfile (res ))
10841087
10851088 res = make_archive (base_name , 'zip' , root_dir , base_dir )
1086- self .assertTrue (os .path .exists (res ))
1089+ self .assertTrue (os .path .isfile (res ))
10871090
10881091 res = make_archive (base_name , 'tar' , root_dir , base_dir ,
10891092 owner = owner , group = group )
1090- self .assertTrue (os .path .exists (res ))
1093+ self .assertTrue (os .path .isfile (res ))
10911094
10921095 res = make_archive (base_name , 'tar' , root_dir , base_dir ,
10931096 owner = 'kjhkjhkjg' , group = 'oihohoh' )
1094- self .assertTrue (os .path .exists (res ))
1097+ self .assertTrue (os .path .isfile (res ))
10951098
10961099
10971100 @requires_zlib
10981101 @unittest .skipUnless (UID_GID_SUPPORT , "Requires grp and pwd support" )
10991102 def test_tarfile_root_owner (self ):
1100- tmpdir , tmpdir2 , base_name = self ._create_files ()
1103+ root_dir , base_dir = self ._create_files ()
1104+ base_name = os .path .join (self .mkdtemp (), 'archive' )
11011105 group = grp .getgrgid (0 )[0 ]
11021106 owner = pwd .getpwuid (0 )[0 ]
1103- with support .change_cwd (tmpdir ):
1104- archive_name = _make_tarball (base_name , 'dist ' , compress = None ,
1105- owner = owner , group = group )
1107+ with support .change_cwd (root_dir ):
1108+ archive_name = make_archive (base_name , 'gztar ' , root_dir , 'dist' ,
1109+ owner = owner , group = group )
11061110
11071111 # check if the compressed tarball was created
1108- self .assertTrue (os .path .exists (archive_name ))
1112+ self .assertTrue (os .path .isfile (archive_name ))
11091113
11101114 # now checks the rights
11111115 archive = tarfile .open (archive_name )
@@ -1162,40 +1166,30 @@ def test_register_archive_format(self):
11621166 formats = [name for name , params in get_archive_formats ()]
11631167 self .assertNotIn ('xxx' , formats )
11641168
1165- def _compare_dirs (self , dir1 , dir2 ):
1166- # check that dir1 and dir2 are equivalent,
1167- # return the diff
1168- diff = []
1169- for root , dirs , files in os .walk (dir1 ):
1170- for file_ in files :
1171- path = os .path .join (root , file_ )
1172- target_path = os .path .join (dir2 , os .path .split (path )[- 1 ])
1173- if not os .path .exists (target_path ):
1174- diff .append (file_ )
1175- return diff
1176-
11771169 @requires_zlib
11781170 def test_unpack_archive (self ):
11791171 formats = ['tar' , 'gztar' , 'zip' ]
11801172 if BZ2_SUPPORTED :
11811173 formats .append ('bztar' )
11821174
1175+ root_dir , base_dir = self ._create_files ()
11831176 for format in formats :
1184- tmpdir = self .mkdtemp ()
1185- base_dir , root_dir , base_name = self ._create_files ()
1186- tmpdir2 = self .mkdtemp ()
1177+ expected = rlistdir (root_dir )
1178+ expected .remove ('outer' )
1179+ if format == 'zip' :
1180+ expected .remove ('dist/sub2/' )
1181+ base_name = os .path .join (self .mkdtemp (), 'archive' )
11871182 filename = make_archive (base_name , format , root_dir , base_dir )
11881183
11891184 # let's try to unpack it now
1185+ tmpdir2 = self .mkdtemp ()
11901186 unpack_archive (filename , tmpdir2 )
1191- diff = self ._compare_dirs (tmpdir , tmpdir2 )
1192- self .assertEqual (diff , [])
1187+ self .assertEqual (rlistdir (tmpdir2 ), expected )
11931188
11941189 # and again, this time with the format specified
11951190 tmpdir3 = self .mkdtemp ()
11961191 unpack_archive (filename , tmpdir3 , format = format )
1197- diff = self ._compare_dirs (tmpdir , tmpdir3 )
1198- self .assertEqual (diff , [])
1192+ self .assertEqual (rlistdir (tmpdir3 ), expected )
11991193 self .assertRaises (shutil .ReadError , unpack_archive , TESTFN )
12001194 self .assertRaises (ValueError , unpack_archive , TESTFN , format = 'xxx' )
12011195
0 commit comments