| import io |
| import os |
| import tarfile |
| import zipfile |
| |
| from .distribution import Distribution |
| |
| class SDist(Distribution): |
| |
| def __init__(self, filename, metadata_version=None): |
| self.filename = filename |
| self.metadata_version = metadata_version |
| self.extractMetadata() |
| |
| @classmethod |
| def _get_archive(cls, fqn): |
| if not os.path.exists(fqn): |
| raise ValueError('No such file: %s' % fqn) |
| |
| if fqn.endswith('.zip'): |
| archive = zipfile.ZipFile(fqn) |
| names = archive.namelist() |
| def read_file(name): |
| return archive.read(name) |
| elif fqn.endswith('gz') or fqn.endswith('bz2'): |
| archive = tarfile.TarFile.open(fqn) |
| names = archive.getnames() |
| def read_file(name): |
| return archive.extractfile(name).read() |
| else: |
| raise ValueError('Not a known archive format: %s' % fqn) |
| |
| return archive, names, read_file |
| |
| |
| def read(self): |
| fqn = os.path.abspath( |
| os.path.normpath(self.filename)) |
| |
| archive, names, read_file = self._get_archive(fqn) |
| |
| try: |
| tuples = [x.split('/') for x in names if 'PKG-INFO' in x] |
| schwarz = sorted([(len(x), x) for x in tuples]) |
| for path in [x[1] for x in schwarz]: |
| candidate = '/'.join(path) |
| data = read_file(candidate) |
| if b'Metadata-Version' in data: |
| return data |
| finally: |
| archive.close() |
| |
| raise ValueError('No PKG-INFO in archive: %s' % fqn) |
| |
| |
| class UnpackedSDist(SDist): |
| def __init__(self, filename, metadata_version=None): |
| if os.path.isdir(filename): |
| pass |
| elif os.path.isfile(filename): |
| filename = os.path.dirname(filename) |
| else: |
| raise ValueError('No such file: %s' % filename) |
| |
| super(UnpackedSDist, self).__init__( |
| filename, metadata_version=metadata_version) |
| |
| def read(self): |
| try: |
| pkg_info = os.path.join(self.filename, 'PKG-INFO') |
| with io.open(pkg_info, errors='ignore') as f: |
| return f.read() |
| except Exception as e: |
| raise ValueError('Could not load %s as an unpacked sdist: %s' |
| % (self.filename, e)) |