Index: configure.in =================================================================== --- configure.in (revision 72786) +++ configure.in (working copy) @@ -956,6 +956,7 @@ elif test "$UNIVERSAL_ARCHS" = "64-bit" ; then UNIVERSAL_ARCH_FLAGS="-arch ppc64 -arch x86_64" + ARCH_RUN_32BIT="true" elif test "$UNIVERSAL_ARCHS" = "all" ; then UNIVERSAL_ARCH_FLAGS="-arch i386 -arch ppc -arch ppc64 -arch x86_64" Index: Doc/library/zipfile.rst =================================================================== --- Doc/library/zipfile.rst (revision 72786) +++ Doc/library/zipfile.rst (working copy) @@ -270,7 +270,7 @@ byte, the name of the file in the archive will be truncated at the null byte. -.. method:: ZipFile.writestr(zinfo_or_arcname, bytes) +.. method:: ZipFile.writestr(zinfo_or_arcname, bytes[, compress_type]) Write the string *bytes* to the archive; *zinfo_or_arcname* is either the file name it will be given in the archive, or a :class:`ZipInfo` instance. If it's @@ -280,6 +280,10 @@ created with mode ``'r'`` will raise a :exc:`RuntimeError`. Calling :meth:`writestr` on a closed ZipFile will raise a :exc:`RuntimeError`. + If given, *compress_type* overrides the value given for the *compression* + parameter to the constructor for the new entry, or in the *zinfo_or_arcname* + (if that is a :class:`ZipInfo` instance). + .. note:: When passing a :class:`ZipInfo` instance as the *zinfo_or_acrname* parameter, Index: Lib/zipfile.py =================================================================== --- Lib/zipfile.py (revision 72786) +++ Lib/zipfile.py (working copy) @@ -1086,13 +1086,14 @@ self.filelist.append(zinfo) self.NameToInfo[zinfo.filename] = zinfo - def writestr(self, zinfo_or_arcname, bytes): + def writestr(self, zinfo_or_arcname, bytes, compress_type=None): """Write a file into the archive. The contents is the string 'bytes'. 'zinfo_or_arcname' is either a ZipInfo instance or the name of the file in the archive.""" if not isinstance(zinfo_or_arcname, ZipInfo): zinfo = ZipInfo(filename=zinfo_or_arcname, date_time=time.localtime(time.time())[:6]) + zinfo.compress_type = self.compression zinfo.external_attr = 0600 << 16 else: @@ -1102,6 +1103,9 @@ raise RuntimeError( "Attempt to write to ZIP archive that was already closed") + if compress_type is not None: + zinfo.compress_type = compress_type + zinfo.file_size = len(bytes) # Uncompressed size zinfo.header_offset = self.fp.tell() # Start of header bytes self._writecheck(zinfo) Index: Lib/test/test_zipfile.py =================================================================== --- Lib/test/test_zipfile.py (revision 72786) +++ Lib/test/test_zipfile.py (working copy) @@ -373,6 +373,20 @@ # remove the test file subdirectories shutil.rmtree(os.path.join(os.getcwd(), 'ziptest2dir')) + def test_writestr_compression(self): + zipfp = zipfile.ZipFile(TESTFN2, "w") + zipfp.writestr("a.txt", "hello world", compress_type=zipfile.ZIP_STORED) + if zlib: + zipfp.writestr("b.txt", "hello world", compress_type=zipfile.ZIP_DEFLATED) + + info = zipfp.getinfo('a.txt') + self.assertEqual(info.compress_type, zipfile.ZIP_STORED) + + if zlib: + info = zipfp.getinfo('b.txt') + self.assertEqual(info.compress_type, zipfile.ZIP_DEFLATED) + + def zip_test_writestr_permissions(self, f, compression): # Make sure that writestr creates files with mode 0600, # when it is passed a name rather than a ZipInfo instance.