pythonaro.com

Pythonaro blog

07 June 2009

The pains of backward-compatibility

Problem:
  • you have several ZIP and TAR archives
  • you have to replace ONE FILE in each of them
  • you only have Python 2.5

From what I see, the only solution in this situation is to completely branch off the two cases, because the relevant Python modules (tarfile and zipfile) have such a completely different interface.

None of them can simply replace or delete one single file, so you have to unpack the entire archive, edit the file, repack. Inefficient, but consistent approach.
Then ZipFile object will read bytes, whereas TarFile objects will extract files.
Finally, ZipFile doesn't feature a method to extract all files in one go, like TarFile has. To be honest, zipfile sucks in pre-2.6 VMs.
This means that what you can really do (more or less) in the same way (with some essential metaprogramming) is opening/closing archives, listing the contained files, and adding new files.

Things are much, much better in 2.6 and 3.0, where both interfaces are almost the same, but if you are stuck with 2.5 (like me) then you'll have to do with inelegant solutions. And if you are reading this, maybe you'll waste less time.

(Memo to self: always, ALWAYS do the easiest thing that could possibly work, no matter how inelegant it is. Premature optimization really is the root of all evil.)

Labels: , , ,

posted by GiacomoL @ 7:54 PM   2 comments links to this post

30 April 2009

zipfile quirk

In Python 2.6.0, a bug in the zipfile module makes the newly-acquired extractall() method basically useless. The function is supposed to extract all members of a zipfile, "no questions asked", like Windows would do with a right-click "Extract All..."; unfortunately, the original implementation makes it fail when the zipfile contains subdirectories. The behaviour was corrected in one of the 2.6.x maintenance releases (and 3.0.x, and 2.7), but if you have the misfortune to be stuck with 2.6.0, here's the banal workaround:
zf = zipfile.ZipFile(zpath)
zlist = zf.namelist()
for filename in zlist:
 if filename.endswith("/"):
  destpath = os.path.join(path_to_extract,filename[:-1])
  if not os.path.exists(destpath): os.makedirs(destpath)
 else:
  zf.extract(filename,path_to_extract)

Labels: , ,

posted by GiacomoL @ 9:22 AM   0 comments links to this post