Skip to content

Instantly share code, notes, and snippets.

@lanfon72
Created September 14, 2017 14:17
Show Gist options
  • Save lanfon72/0e3641c6cef3a5de75196619658d8f5b to your computer and use it in GitHub Desktop.
Save lanfon72/0e3641c6cef3a5de75196619658d8f5b to your computer and use it in GitHub Desktop.
zipfile polyfill for async extract and extractall.
import os
import asyncio
from zipfile import ZipFile
__all__ = ("ZipFile", )
@asyncio.coroutine
def async_extract(self, member, path=None, pwd=None, loop=None):
loop = loop or asyncio.get_event_loop()
return loop.run_in_executor(None, self.extract, member, path, pwd)
@asyncio.coroutine
def async_extractall(self, path=None, members=None, pwd=None, loop=None):
members = members or self.namelist()
loop = loop or asyncio.get_event_loop()
path = path or os.getcwd()
fs = [self.async_extract(zipinfo, path, pwd) for zipinfo in members]
done = yield from asyncio.gather(*fs, loop=loop, return_exceptions=True)
# to resolve concurrent mkdirs
retries = set(members)
for p in done:
if not isinstance(p, OSError):
member = p.replace(path, '').replace(os.path.sep, '/').lstrip('/')
retries.discard(member)
coro = asyncio.gather(*[self.async_extract(m, path, pwd) for m in retries],
loop=loop)
yield from coro
ZipFile.async_extract = async_extract
ZipFile.async_extractall = async_extractall
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment