I was working on Magic Wormhole during a Pycon 2016 sprint and noticed that zipfiles don't preserve file permissions. I'm not the only one who's noticed this (some posts go back over five years) but it still doesn't appear to be fixed.
Anyhow, here's how I did it…
During creation of the zipfile
import zipfile
with zipfile.ZipFile("outzip.zip", "w", zipfile.ZIP_DEFLATED) as zf:
zf.write( "somefile" )
the file permissions are stored so the problem lies in the extraction. The easy way just defaults
all files to 644
(or whatever your umask
is).
with zipfile.ZipFile("outzip.zip", "r") as zf:
zf.extractall()
so we need to get a little fancy
def extract_file( zf, info, extract_dir ):
zf.extract( info.filename, path=extract_dir )
out_path = os.path.join( extract_dir, info.filename )
perm = info.external_attr >> 16L
os.chmod( out_path, perm )
with zipfile.ZipFile(zipname, 'r') as zf:
for info in zf.infolist():
extract_file( zf, info, extract_dir )
So there you have it.