[Distutils] Using Wheel with zipimport

Vinay Sajip vinay_sajip at yahoo.co.uk
Wed Jan 29 16:00:05 CET 2014


--------------------------------------------
On Wed, 29/1/14, Donald Stufft <donald at stufft.io> wrote:

> It’s hard to pin down because the failure modes of zipped
> eggs are nebulous themselves.
 
> For instance take pip. I just recently redid the get-pip.py
> installer to use a zip file (not a Wheel or Egg) that contained pip
> and add that zip file straight to sys.path instead of unzipping it.
> One of the failure modes was that it was suddenly unable to validate
> TLS certificates. The reason why, was because it bundles it’s
> own cacerts.pem which it passes to the ssl library to validate the
> connection. In this case it’s impossible as far as I can tell to use
> pkgutil.get_data directly because the ssl library does not directly
> support pkgutil.get_data nor does it support passing the certificates
> as a string or other in memory.
 
> That’s really the biggest problem with strictly pure python Zipped Eggs.

If that's all, I'm not overly worried as long as there's a mountability flag on
wheels. I looked at running pip from a zip a while ago, the cacerts thing
was easy to diagnose and fix - a five-or-ten-minute job. (I'm not trying to
come across as a show-off.) Here's the code I added as a fix in
pip/locations.py (no doubt it could be improved):

    def _check_for_zip():
        import zipimport
        global default_cert_path
        try:
            if isinstance(__loader__, zipimport.zipimporter):
                # running from a zip file. Save data to a handy location.
                data = __loader__.get_data(default_cert_path)
                destdir = os.path.expanduser('~/.pip')
                if not os.path.isdir(destdir):
                    os.mkdir(destdir)
                default_cert_path = os.path.join(destdir, 'cacert.pem')
                with open(default_cert_path, 'wb') as f:
                    f.write(data)
        except NameError:
            # __loader__ not defined, so not in zip
            pass

    _check_for_zip()
    del _check_for_zip

Of course, pip wasn't originally designed to run from zip, so one would
expect to find these kinds of issues. OTOH, if importable zips were more
commonplace, then presumably people would think about these kinds of
issues more when writing their code. Of course, in the above case, using
pkgutil wouldn't have worked, and there are bound to be other similar cases,
but I still don't see any real reason to fear the consequences of importable
wheels.

Regards,

Vinay Sajip


More information about the Distutils-SIG mailing list