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)
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)
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
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)
def name(self): # type: () -> Optional[str] if self.req is None: return None return six.ensure_str(pkg_resources.safe_name(self.req.name))