44import pathlib
55import pickle
66import string
7- from test . support . script_helper import assert_python_ok
7+ import sys
88import unittest
99import zipfile
1010
11- from ._test_params import parameterize , Invoked
1211from ._functools import compose
12+ from ._itertools import Counter
1313
14+ from ._test_params import parameterize , Invoked
15+ from ._func_timeout_compat import set_timeout
1416
1517from test .support .os_helper import temp_dir
1618
1719
18- # Poor man's technique to consume a (smallish) iterable.
19- consume = tuple
20-
21-
22- # from jaraco.itertools 5.0
2320class jaraco :
2421 class itertools :
25- class Counter :
26- def __init__ (self , i ):
27- self .count = 0
28- self ._orig_iter = iter (i )
22+ Counter = Counter
2923
30- def __iter__ (self ):
31- return self
3224
33- def __next__ (self ):
34- result = next (self ._orig_iter )
35- self .count += 1
36- return result
25+ consume = tuple
3726
3827
3928def add_dirs (zf ):
@@ -161,10 +150,10 @@ def test_open_encoding_utf16(self):
161150 u16 = path .joinpath ("16.txt" )
162151 with u16 .open ('r' , "utf-16" ) as strm :
163152 data = strm .read ()
164- self . assertEqual ( data , "This was utf-16" )
153+ assert data == "This was utf-16"
165154 with u16 .open (encoding = "utf-16" ) as strm :
166155 data = strm .read ()
167- self . assertEqual ( data , "This was utf-16" )
156+ assert data == "This was utf-16"
168157
169158 def test_open_encoding_errors (self ):
170159 in_memory_file = io .BytesIO ()
@@ -177,9 +166,9 @@ def test_open_encoding_errors(self):
177166
178167 # encoding= as a positional argument for gh-101144.
179168 data = u16 .read_text ("utf-8" , errors = "ignore" )
180- self . assertEqual ( data , "invalid utf-8: ." )
169+ assert data == "invalid utf-8: ."
181170 with u16 .open ("r" , "utf-8" , errors = "surrogateescape" ) as f :
182- self . assertEqual ( f .read (), "invalid utf-8: \udcff \udcff ." )
171+ assert f .read () == "invalid utf-8: \udcff \udcff ."
183172
184173 # encoding= both positional and keyword is an error; gh-101144.
185174 with self .assertRaisesRegex (TypeError , "encoding" ):
@@ -191,24 +180,21 @@ def test_open_encoding_errors(self):
191180 with self .assertRaises (UnicodeDecodeError ):
192181 f .read ()
193182
194- def test_encoding_warnings (self ):
183+ @unittest .skipIf (
184+ not getattr (sys .flags , 'warn_default_encoding' , 0 ),
185+ "Requires warn_default_encoding" ,
186+ )
187+ @pass_alpharep
188+ def test_encoding_warnings (self , alpharep ):
195189 """EncodingWarning must blame the read_text and open calls."""
196- code = '''\
197- import io, zipfile
198- with zipfile.ZipFile(io.BytesIO(), "w") as zf:
199- zf.filename = '<test_encoding_warnings in memory zip file>'
200- zf.writestr("path/file.txt", b"Spanish Inquisition")
201- root = zipfile.Path(zf)
202- (path,) = root.iterdir()
203- file_path = path.joinpath("file.txt")
204- unused = file_path.read_text() # should warn
205- file_path.open("r").close() # should warn
206- '''
207- proc = assert_python_ok ('-X' , 'warn_default_encoding' , '-c' , code )
208- warnings = proc .err .splitlines ()
209- self .assertEqual (len (warnings ), 2 , proc .err )
210- self .assertRegex (warnings [0 ], rb"^<string>:8: EncodingWarning:" )
211- self .assertRegex (warnings [1 ], rb"^<string>:9: EncodingWarning:" )
190+ assert sys .flags .warn_default_encoding
191+ root = zipfile .Path (alpharep )
192+ with self .assertWarns (EncodingWarning ) as wc :
193+ root .joinpath ("a.txt" ).read_text ()
194+ assert __file__ == wc .filename
195+ with self .assertWarns (EncodingWarning ) as wc :
196+ root .joinpath ("a.txt" ).open ("r" ).close ()
197+ assert __file__ == wc .filename
212198
213199 def test_open_write (self ):
214200 """
@@ -250,7 +236,8 @@ def test_read(self, alpharep):
250236 root = zipfile .Path (alpharep )
251237 a , b , g = root .iterdir ()
252238 assert a .read_text (encoding = "utf-8" ) == "content of a"
253- a .read_text ("utf-8" ) # No positional arg TypeError per gh-101144.
239+ # Also check positional encoding arg (gh-101144).
240+ assert a .read_text ("utf-8" ) == "content of a"
254241 assert a .read_bytes () == b"content of a"
255242
256243 @pass_alpharep
@@ -275,19 +262,6 @@ def test_traverse_truediv(self, alpharep):
275262 e = root / "b" / "d" / "e.txt"
276263 assert e .read_text (encoding = "utf-8" ) == "content of e"
277264
278- @pass_alpharep
279- def test_traverse_simplediv (self , alpharep ):
280- """
281- Disable the __future__.division when testing traversal.
282- """
283- code = compile (
284- source = "zipfile.Path(alpharep) / 'a'" ,
285- filename = "(test)" ,
286- mode = "eval" ,
287- dont_inherit = True ,
288- )
289- eval (code )
290-
291265 @pass_alpharep
292266 def test_pathlike_construction (self , alpharep ):
293267 """
@@ -356,7 +330,7 @@ def test_joinpath_constant_time(self):
356330 # Check the file iterated all items
357331 assert entries .count == self .HUGE_ZIPFILE_NUM_ENTRIES
358332
359- # @func_timeout.func_set_timeout (3)
333+ @ set_timeout (3 )
360334 def test_implied_dirs_performance (self ):
361335 data = ['/' .join (string .ascii_lowercase + str (n )) for n in range (10000 )]
362336 zipfile .CompleteDirs ._implied_dirs (data )
@@ -472,6 +446,52 @@ def test_root_unnamed(self, alpharep):
472446 assert sub .name == "b"
473447 assert sub .parent
474448
449+ @pass_alpharep
450+ def test_match_and_glob (self , alpharep ):
451+ root = zipfile .Path (alpharep )
452+ assert not root .match ("*.txt" )
453+
454+ assert list (root .glob ("b/c.*" )) == [zipfile .Path (alpharep , "b/c.txt" )]
455+
456+ files = root .glob ("**/*.txt" )
457+ assert all (each .match ("*.txt" ) for each in files )
458+
459+ assert list (root .glob ("**/*.txt" )) == list (root .rglob ("*.txt" ))
460+
461+ def test_glob_empty (self ):
462+ root = zipfile .Path (zipfile .ZipFile (io .BytesIO (), 'w' ))
463+ with self .assertRaises (ValueError ):
464+ root .glob ('' )
465+
466+ @pass_alpharep
467+ def test_eq_hash (self , alpharep ):
468+ root = zipfile .Path (alpharep )
469+ assert root == zipfile .Path (alpharep )
470+
471+ assert root != (root / "a.txt" )
472+ assert (root / "a.txt" ) == (root / "a.txt" )
473+
474+ root = zipfile .Path (alpharep )
475+ assert root in {root }
476+
477+ @pass_alpharep
478+ def test_is_symlink (self , alpharep ):
479+ """
480+ See python/cpython#82102 for symlink support beyond this object.
481+ """
482+
483+ root = zipfile .Path (alpharep )
484+ assert not root .is_symlink ()
485+
486+ @pass_alpharep
487+ def test_relative_to (self , alpharep ):
488+ root = zipfile .Path (alpharep )
489+ relative = root .joinpath ("b" , "c.txt" ).relative_to (root / "b" )
490+ assert str (relative ) == "c.txt"
491+
492+ relative = root .joinpath ("b" , "d" , "e.txt" ).relative_to (root / "b" )
493+ assert str (relative ) == "d/e.txt"
494+
475495 @pass_alpharep
476496 def test_inheritance (self , alpharep ):
477497 cls = type ('PathChild' , (zipfile .Path ,), {})
@@ -493,3 +513,14 @@ def test_pickle(self, alpharep, path_type, subpath):
493513 restored_1 = pickle .loads (saved_1 )
494514 first , * rest = restored_1 .iterdir ()
495515 assert first .read_text ().startswith ('content of ' )
516+
517+ @pass_alpharep
518+ def test_extract_orig_with_implied_dirs (self , alpharep ):
519+ """
520+ A zip file wrapped in a Path should extract even with implied dirs.
521+ """
522+ source_path = self .zipfile_ondisk (alpharep )
523+ zf = zipfile .ZipFile (source_path )
524+ # wrap the zipfile for its side effect
525+ zipfile .Path (zf )
526+ zf .extractall (source_path .parent )
0 commit comments