예제 #1
0
def pkg_resources_distribution_for_wheel(wheel_zip, name, location):
    # type: (ZipFile, str, str) -> Distribution
    """Get a pkg_resources distribution given a wheel.

    :raises UnsupportedWheel: on any errors
    """
    info_dir, _ = parse_wheel(wheel_zip, name)

    metadata_files = [
        p for p in wheel_zip.namelist() if p.startswith("{}/".format(info_dir))
    ]

    metadata_text = {}  # type: Dict[str, bytes]
    for path in metadata_files:
        # If a flag is set, namelist entries may be unicode in Python 2.
        # We coerce them to native str type to match the types used in the rest
        # of the code. This cannot fail because unicode can always be encoded
        # with UTF-8.
        full_path = ensure_str(path)
        _, metadata_name = full_path.split("/", 1)

        try:
            metadata_text[metadata_name] = read_wheel_metadata_file(
                wheel_zip, full_path)
        except UnsupportedWheel as e:
            raise UnsupportedWheel("{} has an invalid wheel, {}".format(
                name, str(e)))

    metadata = WheelMetadata(metadata_text, location)

    return DistInfoDistribution(location=location,
                                metadata=metadata,
                                project_name=name)
예제 #2
0
def wheel_dist_info_dir(source, name):
    # type: (ZipFile, str) -> str
    """Returns the name of the contained .dist-info directory.

    Raises AssertionError or UnsupportedWheel if not found, >1 found, or
    it doesn't match the provided name.
    """
    # Zip file path separators must be /
    subdirs = list(set(p.split("/")[0] for p in source.namelist()))

    info_dirs = [s for s in subdirs if s.endswith('.dist-info')]

    if not info_dirs:
        raise UnsupportedWheel(".dist-info directory not found")

    if len(info_dirs) > 1:
        raise UnsupportedWheel(
            "multiple .dist-info directories found: {}".format(
                ", ".join(info_dirs)))

    info_dir = info_dirs[0]

    info_dir_name = canonicalize_name(info_dir)
    canonical_name = canonicalize_name(name)
    if not info_dir_name.startswith(canonical_name):
        raise UnsupportedWheel(
            ".dist-info directory {!r} does not start with {!r}".format(
                info_dir, canonical_name))

    # Zip file paths can be unicode or str depending on the zip entry flags,
    # so normalize it.
    return ensure_str(info_dir)
예제 #3
0
 def get_metadata(self, name):
     # type: (str) -> str
     try:
         return ensure_str(self._metadata[name])
     except UnicodeDecodeError as e:
         # Mirrors handling done in pkg_resources.NullProvider.
         e.reason += " in {} file".format(name)
         raise
예제 #4
0
def wheel_metadata(source, dist_info_dir):
    # type: (ZipFile, str) -> Message
    """Return the WHEEL metadata of an extracted wheel, if possible.
    Otherwise, raise UnsupportedWheel.
    """
    path = "{}/WHEEL".format(dist_info_dir)
    # Zip file path separators must be /
    wheel_contents = read_wheel_metadata_file(source, path)

    try:
        wheel_text = ensure_str(wheel_contents)
    except UnicodeDecodeError as e:
        raise UnsupportedWheel("error decoding {!r}: {!r}".format(path, e))

    # FeedParser (used by Parser) does not raise any exceptions. The returned
    # message may have .defects populated, but for backwards-compatibility we
    # currently ignore them.
    return Parser().parsestr(wheel_text)
예제 #5
0
 def name(self):
     # type: () -> Optional[str]
     if self.req is None:
         return None
     return six.ensure_str(pkg_resources.safe_name(self.req.name))