Skip to content

Commit 36defbc

Browse files
author
Adi Roiban
committed
Add tests.
1 parent a6d22b7 commit 36defbc

File tree

1 file changed

+102
-0
lines changed

1 file changed

+102
-0
lines changed

Lib/test/test_zipfile/test_core.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import io
66
import itertools
77
import os
8+
import pathlib
89
import posixpath
910
import stat
1011
import struct
@@ -485,6 +486,9 @@ def tearDown(self):
485486

486487
class StoredTestsWithSourceFile(AbstractTestsWithSourceFile,
487488
unittest.TestCase):
489+
"""
490+
Test in which the files inside the archive are not compressed.
491+
"""
488492
compression = zipfile.ZIP_STORED
489493
test_low_compression = None
490494

@@ -676,6 +680,104 @@ def test_add_file_after_2107(self):
676680
self.assertEqual(zinfo.date_time, (2107, 12, 31, 23, 59, 59))
677681

678682

683+
class CustomZipInfo(zipfile.ZipInfo):
684+
"""
685+
Support for testing extending and subclassing ZipFile.
686+
"""
687+
688+
class CustomZipExtFile(zipfile.ZipExtFile):
689+
"""
690+
Support for testing extending and subclassing ZipFile.
691+
"""
692+
693+
def test_read_custom_zipinfo_and_zipextfile(self):
694+
"""
695+
A subclass of ZipFile can be implemented to read and handle the
696+
archive content using custom ZipInfo and ZipExtFile implementations.
697+
"""
698+
# Create the file using the default Zipfile.
699+
source = io.BytesIO()
700+
with zipfile.ZipFile(source, 'w', zipfile.ZIP_STORED) as zipfp:
701+
zipfp.writestr('test.txt', 'some-text-content')
702+
703+
with zipfile.ZipFile(
704+
source, 'r',
705+
zipinfo_class=self.CustomZipInfo,
706+
zipextfile_class=self.CustomZipExtFile,
707+
) as zipfp:
708+
# Archive content returns the custom ZipInfo
709+
members = zipfp.infolist()
710+
self.assertEqual(1, len(members))
711+
self.assertIsInstance(members[0], self.CustomZipInfo)
712+
713+
# Archive members can be opened using the custom ZipInfo
714+
target_member = members[0]
715+
with zipfp.open(target_member, mode='r') as memberfp:
716+
self.assertIsInstance(memberfp, self.CustomZipExtFile)
717+
718+
def test_write_custom_zipinfo(self):
719+
"""
720+
A subclass of ZipFile can be implemented to write and handle the
721+
archive content using custom ZipInfo implementation.
722+
"""
723+
destination = io.BytesIO()
724+
with zipfile.ZipFile(
725+
destination, 'w', zipinfo_class=self.CustomZipInfo) as zipfp:
726+
# It can write using the specific custom classe.
727+
new_member = self.CustomZipInfo('new-member.txt')
728+
with zipfp.open(new_member, mode='w') as memberfp:
729+
self.assertIs(new_member, memberfp._zinfo)
730+
731+
# When creating a new member using just the name,
732+
# the custom ZipInfo is used internally.
733+
with zipfp.open('other-member.txt', mode='w') as memberfp:
734+
self.assertIsInstance(memberfp._zinfo, self.CustomZipInfo)
735+
self.assertIsInstance(
736+
zipfp.NameToInfo['other-member.txt'], self.CustomZipInfo)
737+
738+
# ZipFile.writestr can handle the custom class or just the
739+
# archive name as text.
740+
custom_member = self.CustomZipInfo('some-member.txt')
741+
zipfp.writestr(custom_member, b'some-new-content')
742+
zipfp.writestr('some-name.txt', b'other-content')
743+
self.assertIsInstance(
744+
zipfp.NameToInfo['some-name.txt'], self.CustomZipInfo)
745+
746+
# ZipFile.mkdir can handle the custom class or just text.
747+
custom_dir = self.CustomZipInfo('some-directory/')
748+
custom_dir.CRC = 0
749+
zipfp.mkdir(custom_dir)
750+
zipfp.mkdir('dir-as-text/')
751+
self.assertIsInstance(
752+
zipfp.NameToInfo['dir-as-text/'], self.CustomZipInfo)
753+
754+
# When writing from an external file, the file is created using
755+
# the custom ZipInfo
756+
with temp_dir() as source_dir:
757+
source_file = pathlib.Path(source_dir).joinpath('source.txt')
758+
with open(source_file, 'wb') as fp:
759+
fp.write(b'some-content')
760+
zipfp.write(source_file, arcname='newly-file.txt')
761+
self.assertIsInstance(
762+
zipfp.NameToInfo['newly-file.txt'], self.CustomZipInfo)
763+
764+
def test_extract_custom_zipinfo(self):
765+
"""
766+
A subclass of ZipFile can be implemented to extact the
767+
archive content using custom ZipInfo implementation.
768+
"""
769+
destination = io.BytesIO()
770+
with zipfile.ZipFile(
771+
destination, 'w', zipinfo_class=self.CustomZipInfo) as zipfp:
772+
zipfp.mkdir('dir-as-text/')
773+
dir_info = zipfp.NameToInfo['dir-as-text/']
774+
self.assertIsInstance(dir_info, self.CustomZipInfo)
775+
776+
with temp_dir() as extract_dir:
777+
zipfp.extract(dir_info, path=extract_dir)
778+
zipfp.extract('dir-as-text/', path=extract_dir)
779+
780+
679781
@requires_zlib()
680782
class DeflateTestsWithSourceFile(AbstractTestsWithSourceFile,
681783
unittest.TestCase):

0 commit comments

Comments
 (0)