13
13
import unittest
14
14
import unittest .mock as mock
15
15
import zipfile
16
+ import functools
16
17
17
18
18
19
from tempfile import TemporaryFile
@@ -2836,6 +2837,20 @@ def build_alpharep_fixture():
2836
2837
return zf
2837
2838
2838
2839
2840
+ def pass_alpharep (meth ):
2841
+ """
2842
+ Given a method, wrap it in a for loop that invokes method
2843
+ with each subtest.
2844
+ """
2845
+
2846
+ @functools .wraps (meth )
2847
+ def wrapper (self ):
2848
+ for alpharep in self .zipfile_alpharep ():
2849
+ meth (self , alpharep = alpharep )
2850
+
2851
+ return wrapper
2852
+
2853
+
2839
2854
class TestPath (unittest .TestCase ):
2840
2855
def setUp (self ):
2841
2856
self .fixtures = contextlib .ExitStack ()
@@ -2847,47 +2862,58 @@ def zipfile_alpharep(self):
2847
2862
with self .subTest ():
2848
2863
yield add_dirs (build_alpharep_fixture ())
2849
2864
2850
- def zipfile_ondisk (self ):
2865
+ def zipfile_ondisk (self , alpharep ):
2851
2866
tmpdir = pathlib .Path (self .fixtures .enter_context (temp_dir ()))
2852
- for alpharep in self .zipfile_alpharep ():
2853
- buffer = alpharep .fp
2854
- alpharep .close ()
2855
- path = tmpdir / alpharep .filename
2856
- with path .open ("wb" ) as strm :
2857
- strm .write (buffer .getvalue ())
2858
- yield path
2859
-
2860
- def test_iterdir_and_types (self ):
2861
- for alpharep in self .zipfile_alpharep ():
2862
- root = zipfile .Path (alpharep )
2863
- assert root .is_dir ()
2864
- a , b , g = root .iterdir ()
2865
- assert a .is_file ()
2866
- assert b .is_dir ()
2867
- assert g .is_dir ()
2868
- c , f , d = b .iterdir ()
2869
- assert c .is_file () and f .is_file ()
2870
- e , = d .iterdir ()
2871
- assert e .is_file ()
2872
- h , = g .iterdir ()
2873
- i , = h .iterdir ()
2874
- assert i .is_file ()
2875
-
2876
- def test_subdir_is_dir (self ):
2877
- for alpharep in self .zipfile_alpharep ():
2878
- root = zipfile .Path (alpharep )
2879
- assert (root / 'b' ).is_dir ()
2880
- assert (root / 'b/' ).is_dir ()
2881
- assert (root / 'g' ).is_dir ()
2882
- assert (root / 'g/' ).is_dir ()
2883
-
2884
- def test_open (self ):
2885
- for alpharep in self .zipfile_alpharep ():
2886
- root = zipfile .Path (alpharep )
2887
- a , b , g = root .iterdir ()
2888
- with a .open () as strm :
2889
- data = strm .read ()
2890
- assert data == "content of a"
2867
+ buffer = alpharep .fp
2868
+ alpharep .close ()
2869
+ path = tmpdir / alpharep .filename
2870
+ with path .open ("wb" ) as strm :
2871
+ strm .write (buffer .getvalue ())
2872
+ return path
2873
+
2874
+ @pass_alpharep
2875
+ def test_iterdir_and_types (self , alpharep ):
2876
+ root = zipfile .Path (alpharep )
2877
+ assert root .is_dir ()
2878
+ a , b , g = root .iterdir ()
2879
+ assert a .is_file ()
2880
+ assert b .is_dir ()
2881
+ assert g .is_dir ()
2882
+ c , f , d = b .iterdir ()
2883
+ assert c .is_file () and f .is_file ()
2884
+ (e ,) = d .iterdir ()
2885
+ assert e .is_file ()
2886
+ (h ,) = g .iterdir ()
2887
+ (i ,) = h .iterdir ()
2888
+ assert i .is_file ()
2889
+
2890
+ @pass_alpharep
2891
+ def test_is_file_missing (self , alpharep ):
2892
+ root = zipfile .Path (alpharep )
2893
+ assert not root .joinpath ('missing.txt' ).is_file ()
2894
+
2895
+ @pass_alpharep
2896
+ def test_iterdir_on_file (self , alpharep ):
2897
+ root = zipfile .Path (alpharep )
2898
+ a , b , g = root .iterdir ()
2899
+ with self .assertRaises (ValueError ):
2900
+ a .iterdir ()
2901
+
2902
+ @pass_alpharep
2903
+ def test_subdir_is_dir (self , alpharep ):
2904
+ root = zipfile .Path (alpharep )
2905
+ assert (root / 'b' ).is_dir ()
2906
+ assert (root / 'b/' ).is_dir ()
2907
+ assert (root / 'g' ).is_dir ()
2908
+ assert (root / 'g/' ).is_dir ()
2909
+
2910
+ @pass_alpharep
2911
+ def test_open (self , alpharep ):
2912
+ root = zipfile .Path (alpharep )
2913
+ a , b , g = root .iterdir ()
2914
+ with a .open () as strm :
2915
+ data = strm .read ()
2916
+ assert data == "content of a"
2891
2917
2892
2918
def test_open_write (self ):
2893
2919
"""
@@ -2908,6 +2934,14 @@ def test_open_extant_directory(self):
2908
2934
with self .assertRaises (IsADirectoryError ):
2909
2935
zf .joinpath ('b' ).open ()
2910
2936
2937
+ @pass_alpharep
2938
+ def test_open_binary_invalid_args (self , alpharep ):
2939
+ root = zipfile .Path (alpharep )
2940
+ with self .assertRaises (ValueError ):
2941
+ root .joinpath ('a.txt' ).open ('rb' , encoding = 'utf-8' )
2942
+ with self .assertRaises (ValueError ):
2943
+ root .joinpath ('a.txt' ).open ('rb' , 'utf-8' )
2944
+
2911
2945
def test_open_missing_directory (self ):
2912
2946
"""
2913
2947
Attempting to open a missing directory raises FileNotFoundError.
@@ -2916,75 +2950,87 @@ def test_open_missing_directory(self):
2916
2950
with self .assertRaises (FileNotFoundError ):
2917
2951
zf .joinpath ('z' ).open ()
2918
2952
2919
- def test_read (self ):
2920
- for alpharep in self .zipfile_alpharep ():
2921
- root = zipfile .Path (alpharep )
2922
- a , b , g = root .iterdir ()
2923
- assert a .read_text () == "content of a"
2924
- assert a .read_bytes () == b"content of a"
2925
-
2926
- def test_joinpath (self ):
2927
- for alpharep in self .zipfile_alpharep ():
2928
- root = zipfile .Path (alpharep )
2929
- a = root .joinpath ("a" )
2930
- assert a .is_file ()
2931
- e = root .joinpath ("b" ).joinpath ("d" ).joinpath ("e.txt" )
2932
- assert e .read_text () == "content of e"
2933
-
2934
- def test_traverse_truediv (self ):
2935
- for alpharep in self .zipfile_alpharep ():
2936
- root = zipfile .Path (alpharep )
2937
- a = root / "a"
2938
- assert a .is_file ()
2939
- e = root / "b" / "d" / "e.txt"
2940
- assert e .read_text () == "content of e"
2953
+ @pass_alpharep
2954
+ def test_read (self , alpharep ):
2955
+ root = zipfile .Path (alpharep )
2956
+ a , b , g = root .iterdir ()
2957
+ assert a .read_text () == "content of a"
2958
+ assert a .read_bytes () == b"content of a"
2959
+
2960
+ @pass_alpharep
2961
+ def test_joinpath (self , alpharep ):
2962
+ root = zipfile .Path (alpharep )
2963
+ a = root .joinpath ("a.txt" )
2964
+ assert a .is_file ()
2965
+ e = root .joinpath ("b" ).joinpath ("d" ).joinpath ("e.txt" )
2966
+ assert e .read_text () == "content of e"
2967
+
2968
+ @pass_alpharep
2969
+ def test_traverse_truediv (self , alpharep ):
2970
+ root = zipfile .Path (alpharep )
2971
+ a = root / "a.txt"
2972
+ assert a .is_file ()
2973
+ e = root / "b" / "d" / "e.txt"
2974
+ assert e .read_text () == "content of e"
2975
+
2976
+ @pass_alpharep
2977
+ def test_traverse_simplediv (self , alpharep ):
2978
+ """
2979
+ Disable the __future__.division when testing traversal.
2980
+ """
2981
+ code = compile (
2982
+ source = "zipfile.Path(alpharep) / 'a'" ,
2983
+ filename = "(test)" ,
2984
+ mode = "eval" ,
2985
+ dont_inherit = True ,
2986
+ )
2987
+ eval (code )
2941
2988
2942
- def test_pathlike_construction (self ):
2989
+ @pass_alpharep
2990
+ def test_pathlike_construction (self , alpharep ):
2943
2991
"""
2944
2992
zipfile.Path should be constructable from a path-like object
2945
2993
"""
2946
- for zipfile_ondisk in self .zipfile_ondisk ():
2947
- pathlike = pathlib .Path (str (zipfile_ondisk ))
2948
- zipfile .Path (pathlike )
2949
-
2950
- def test_traverse_pathlike (self ):
2951
- for alpharep in self .zipfile_alpharep ():
2952
- root = zipfile .Path (alpharep )
2953
- root / pathlib .Path ("a" )
2954
-
2955
- def test_parent (self ):
2956
- for alpharep in self .zipfile_alpharep ():
2957
- root = zipfile .Path (alpharep )
2958
- assert (root / 'a' ).parent .at == ''
2959
- assert (root / 'a' / 'b' ).parent .at == 'a/'
2960
-
2961
- def test_dir_parent (self ):
2962
- for alpharep in self .zipfile_alpharep ():
2963
- root = zipfile .Path (alpharep )
2964
- assert (root / 'b' ).parent .at == ''
2965
- assert (root / 'b/' ).parent .at == ''
2966
-
2967
- def test_missing_dir_parent (self ):
2968
- for alpharep in self .zipfile_alpharep ():
2969
- root = zipfile .Path (alpharep )
2970
- assert (root / 'missing dir/' ).parent .at == ''
2971
-
2972
- def test_mutability (self ):
2994
+ zipfile_ondisk = self .zipfile_ondisk (alpharep )
2995
+ pathlike = pathlib .Path (str (zipfile_ondisk ))
2996
+ zipfile .Path (pathlike )
2997
+
2998
+ @pass_alpharep
2999
+ def test_traverse_pathlike (self , alpharep ):
3000
+ root = zipfile .Path (alpharep )
3001
+ root / pathlib .Path ("a" )
3002
+
3003
+ @pass_alpharep
3004
+ def test_parent (self , alpharep ):
3005
+ root = zipfile .Path (alpharep )
3006
+ assert (root / 'a' ).parent .at == ''
3007
+ assert (root / 'a' / 'b' ).parent .at == 'a/'
3008
+
3009
+ @pass_alpharep
3010
+ def test_dir_parent (self , alpharep ):
3011
+ root = zipfile .Path (alpharep )
3012
+ assert (root / 'b' ).parent .at == ''
3013
+ assert (root / 'b/' ).parent .at == ''
3014
+
3015
+ @pass_alpharep
3016
+ def test_missing_dir_parent (self , alpharep ):
3017
+ root = zipfile .Path (alpharep )
3018
+ assert (root / 'missing dir/' ).parent .at == ''
3019
+
3020
+ @pass_alpharep
3021
+ def test_mutability (self , alpharep ):
2973
3022
"""
2974
3023
If the underlying zipfile is changed, the Path object should
2975
3024
reflect that change.
2976
3025
"""
2977
- for alpharep in self .zipfile_alpharep ():
2978
- root = zipfile .Path (alpharep )
2979
- a , b , g = root .iterdir ()
2980
- alpharep .writestr ('foo.txt' , 'foo' )
2981
- alpharep .writestr ('bar/baz.txt' , 'baz' )
2982
- assert any (
2983
- child .name == 'foo.txt'
2984
- for child in root .iterdir ())
2985
- assert (root / 'foo.txt' ).read_text () == 'foo'
2986
- baz , = (root / 'bar' ).iterdir ()
2987
- assert baz .read_text () == 'baz'
3026
+ root = zipfile .Path (alpharep )
3027
+ a , b , g = root .iterdir ()
3028
+ alpharep .writestr ('foo.txt' , 'foo' )
3029
+ alpharep .writestr ('bar/baz.txt' , 'baz' )
3030
+ assert any (child .name == 'foo.txt' for child in root .iterdir ())
3031
+ assert (root / 'foo.txt' ).read_text () == 'foo'
3032
+ (baz ,) = (root / 'bar' ).iterdir ()
3033
+ assert baz .read_text () == 'baz'
2988
3034
2989
3035
HUGE_ZIPFILE_NUM_ENTRIES = 2 ** 13
2990
3036
@@ -3013,11 +3059,65 @@ def test_implied_dirs_performance(self):
3013
3059
data = ['/' .join (string .ascii_lowercase + str (n )) for n in range (10000 )]
3014
3060
zipfile .CompleteDirs ._implied_dirs (data )
3015
3061
3016
- def test_read_does_not_close (self ):
3017
- for alpharep in self .zipfile_ondisk ():
3018
- with zipfile .ZipFile (alpharep ) as file :
3019
- for rep in range (2 ):
3020
- zipfile .Path (file , 'a.txt' ).read_text ()
3062
+ @pass_alpharep
3063
+ def test_read_does_not_close (self , alpharep ):
3064
+ alpharep = self .zipfile_ondisk (alpharep )
3065
+ with zipfile .ZipFile (alpharep ) as file :
3066
+ for rep in range (2 ):
3067
+ zipfile .Path (file , 'a.txt' ).read_text ()
3068
+
3069
+ @pass_alpharep
3070
+ def test_subclass (self , alpharep ):
3071
+ class Subclass (zipfile .Path ):
3072
+ pass
3073
+
3074
+ root = Subclass (alpharep )
3075
+ assert isinstance (root / 'b' , Subclass )
3076
+
3077
+ @pass_alpharep
3078
+ def test_filename (self , alpharep ):
3079
+ root = zipfile .Path (alpharep )
3080
+ assert root .filename == pathlib .Path ('alpharep.zip' )
3081
+
3082
+ @pass_alpharep
3083
+ def test_root_name (self , alpharep ):
3084
+ """
3085
+ The name of the root should be the name of the zipfile
3086
+ """
3087
+ root = zipfile .Path (alpharep )
3088
+ assert root .name == 'alpharep.zip' == root .filename .name
3089
+
3090
+ @pass_alpharep
3091
+ def test_root_parent (self , alpharep ):
3092
+ root = zipfile .Path (alpharep )
3093
+ assert root .parent == pathlib .Path ('.' )
3094
+ root .root .filename = 'foo/bar.zip'
3095
+ assert root .parent == pathlib .Path ('foo' )
3096
+
3097
+ @pass_alpharep
3098
+ def test_root_unnamed (self , alpharep ):
3099
+ """
3100
+ It is an error to attempt to get the name
3101
+ or parent of an unnamed zipfile.
3102
+ """
3103
+ alpharep .filename = None
3104
+ root = zipfile .Path (alpharep )
3105
+ with self .assertRaises (TypeError ):
3106
+ root .name
3107
+ with self .assertRaises (TypeError ):
3108
+ root .parent
3109
+
3110
+ # .name and .parent should still work on subs
3111
+ sub = root / "b"
3112
+ assert sub .name == "b"
3113
+ assert sub .parent
3114
+
3115
+ @pass_alpharep
3116
+ def test_inheritance (self , alpharep ):
3117
+ cls = type ('PathChild' , (zipfile .Path ,), {})
3118
+ for alpharep in self .zipfile_alpharep ():
3119
+ file = cls (alpharep ).joinpath ('some dir' ).parent
3120
+ assert isinstance (file , cls )
3021
3121
3022
3122
3023
3123
if __name__ == "__main__" :
0 commit comments