'Different File Paths in Python ZipFile Depending on .write() vs .writestr()

I just wanted to ask quickly if the behavior I'm seeing in Python's zipfile module is expected... I wanted to put together a zip archive. For reasons I don't think I need to get into, I was adding some files using zipfile.writestr() and others using .write(). I was writing some files to zip subdirectory called /scripts and others to a zip subdirectory called /data.

For /data, I originally did this:

for root, _, filenames in os.walk(tmpdirname):
    for root_name in filenames:
        print(f"Handle zip of {root_name}")
        name = os.path.join(root, root_name)
        name = os.path.normpath(name)
        zipFile.write(name, f'/data/{root_name}')

This worked fine and produced a working archive that I could extract. So far, so good. To write text files to the /script subdirectory, I used:

zipFile.writestr(f'/script/{scriptname}', fileBytes)

Again, so far so good.

Now it gets odd... I wanted to extract files in /data/. So I looked for paths in zipFile.namelist() starting with /data. My code kept missing the files in /data/, however. Doing some more digging, I noticed that the files written using .writestr had a slash at the start of the zipfile path like this: "/scripts/myscript.py". The files written using .write did not have a slash at the start of the path, so the data file paths looked like this: "data/mydata.pickle".

I changed my code to use .writestr() for the data files:

for root, _, filenames in os.walk(tmpdirname):
    for root_name in filenames:
        print(f"Handle zip of {root_name}")
        name = os.path.join(root, root_name)
        name = os.path.normpath(name)
        with open(name, mode='rb') as extracted_file:
            zipFile.writestr(f'/data/{root_name}', extracted_file.read())

Voila, the data files now have slashes at the start of the path. I'm not sure why, however, as I'm providing the same file path either way, and I wouldn't expect using one method versus another would change the paths.

Is this supposed to work this way? Am I missing something obvious here?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source