~jaraco/pkginfo/relative-imports

« back to all changes in this revision

Viewing changes to pkginfo/wheel.py

  • Committer: Tres Seaver
  • Date: 2013-11-27 22:09:41 UTC
  • Revision ID: tseaver@agendaless.com-20131127220941-doh1v0vd1x4otwzf
Add support for the "wheel" distribution format

Also includes minimal metadata 2.0 support (not including new PEP 426
JSON properties).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
from io import StringIO
 
2
import os
 
3
import zipfile
 
4
 
 
5
 
 
6
from .distribution import Distribution
 
7
from .distribution import must_decode
 
8
from .distribution import parse
 
9
 
 
10
 
 
11
class Wheel(Distribution):
 
12
 
 
13
    def __init__(self, filename, metadata_version=None):
 
14
        self.filename = filename
 
15
        self.metadata_version = metadata_version
 
16
        self.extractMetadata()
 
17
 
 
18
    def read(self):
 
19
        fqn = os.path.abspath(os.path.normpath(self.filename))
 
20
        if not os.path.exists(fqn):
 
21
            raise ValueError('No such file: %s' % fqn)
 
22
 
 
23
        if fqn.endswith('.whl'):
 
24
            archive = zipfile.ZipFile(fqn)
 
25
            names = archive.namelist()
 
26
 
 
27
            def read_file(name):
 
28
                return archive.read(name)
 
29
        else:
 
30
            raise ValueError('Not a known archive format: %s' % fqn)
 
31
 
 
32
        try:
 
33
            tuples = [x.split('/') for x in names if 'METADATA' in x]
 
34
            schwarz = sorted([(len(x), x) for x in tuples])
 
35
            for path in [x[1] for x in schwarz]:
 
36
                candidate = '/'.join(path)
 
37
                data = read_file(candidate)
 
38
                if b'Metadata-Version' in data:
 
39
                    return data
 
40
        finally:
 
41
            archive.close()
 
42
 
 
43
        raise ValueError('No METADATA in archive: %s' % fqn)
 
44
 
 
45
    def parse(self, data):
 
46
        super(Wheel, self).parse(data)
 
47
        fp = StringIO(must_decode(data))
 
48
        msg = parse(fp)
 
49
        self.description = msg.get_payload()