def _get_info_from_wheel( self, url): # type: (str) -> Dict[str, Union[str, List, None]] self._log( "Downloading wheel: {}".format( urlparse.urlparse(url).path.rsplit("/")[-1]), level="debug", ) info = {"summary": "", "requires_python": None, "requires_dist": None} filename = os.path.basename( urlparse.urlparse(url).path.rsplit("/")[-1]) with temporary_directory() as temp_dir: filepath = os.path.join(temp_dir, filename) self._download(url, filepath) try: meta = pkginfo.Wheel(filepath) except ValueError: # Unable to determine dependencies # Assume none return info if meta.summary: info["summary"] = meta.summary or "" info["requires_python"] = meta.requires_python if meta.requires_dist: info["requires_dist"] = meta.requires_dist return info
def render_package_information(self, package_name: str): package = Package.find_by_name(package_name) if package is None: return abort(404, "package does not exist in repository") folder = self.package_folder.joinpath(package_name) payload = { "name": package_name, "packages": [], "use_prompt": package.private and not self.is_pip, } if self.is_pip and package.private and not package.is_valid_token( self.token): return render_template('package-info.html', **payload) for path in folder.iterdir(): filename = path.name if path.is_file() and (filename.endswith('.whl') or filename.endswith('.tar.gz')): filepath = path.as_posix() info = pkginfo.Wheel(filepath) if filename.endswith( '.whl') else pkginfo.SDist(filepath) payload["packages"].append({ "link": f"/simple/{package_name}/{path.name}", "title": path.name, "requires_python": info.requires_python }) return render_template('package-info.html', **payload)
def package_info(path): path = Path(path) if not path.exists(): raise FileNotFoundError("File not found") d = {'type': 'unknown', 'path': str(path), 'size': path.stat().st_size, 'modified': datetime.utcfromtimestamp(path.stat().st_mtime), 'filename': str(path.name)} pkg = None try: if path.suffix == '.whl': pkg = pkginfo.Wheel(path) d['type'] = 'wheel' elif path.suffix in ('.gz', '.bz2'): pkg = pkginfo.SDist(path) d['type'] = 'sdist' except ValueError as e: d['error'] = str(e) if pkg: d['metadata'] = {k: getattr(pkg, k, None) for k in pkg} return d
def inspect_wheel( self, file_path): # type: (Path) -> Dict[str, Union[str, List[str]]] info = { "name": "", "version": "", "summary": "", "requires_python": None, "requires_dist": [], } try: meta = pkginfo.Wheel(str(file_path)) except ValueError: # Unable to determine dependencies # Assume none return info if meta.name: info["name"] = meta.name if meta.version: info["version"] = meta.version if meta.summary: info["summary"] = meta.summary or "" info["requires_python"] = meta.requires_python if meta.requires_dist: info["requires_dist"] = meta.requires_dist return info
def test_ruamel_yaml_clib_whl(self): td = pkginfo.Wheel( TestData("ruamel_yaml_clib_0_2_0_whl/file/ruamel.yaml.clib-0.2.0-cp27-cp27m-manylinux1_x86_64.whl") ) self.assertEqual( set(whl.dependencies(td)), set([]) )
def __init__(self, path, # type: Path category='main', # type: str optional=False, # type: bool base=None # type: Path ): self._path = path self._base = base self._full_path = path if self._base and not self._path.is_absolute(): self._full_path = self._base / self._path if not self._full_path.exists(): raise ValueError('File {} does not exist'.format(self._path)) if self._full_path.is_dir(): raise ValueError( '{} is a directory, expected a file'.format(self._path) ) if self._path.suffix == '.whl': self._meta = pkginfo.Wheel(str(self._full_path)) else: # Assume sdist self._meta = pkginfo.SDist(str(self._full_path)) super(FileDependency, self).__init__( self._meta.name, self._meta.version, category=category, optional=optional, allows_prereleases=True )
def _get_info_from_wheel( self, url): # type: (str) -> Dict[str, Union[str, List, None]] info = { 'summary': '', 'requires_python': None, 'requires_dist': None, } filename = os.path.basename(urlparse.urlparse(url).path) with temporary_directory() as temp_dir: filepath = os.path.join(temp_dir, filename) self._download(url, filepath) try: meta = pkginfo.Wheel(filepath) except ValueError: # Unable to determine dependencies # Assume none return info if meta.summary: info['summary'] = meta.summary or '' info['requires_python'] = meta.requires_python if meta.requires_dist: info['requires_dist'] = meta.requires_dist return info
def get_metadata(self): from glob import glob metadata = {} ext_dir = self.path or get_extension_path(self.name) if not ext_dir or not os.path.isdir(ext_dir): return None # include *.egg-info and *.dist-info info_dirs = glob(os.path.join(ext_dir, self.name.replace('-', '_') + '*.*-info')) if not info_dirs: return None azext_metadata = WheelExtension.get_azext_metadata(ext_dir) if azext_metadata: metadata.update(azext_metadata) for dist_info_dirname in info_dirs: try: if dist_info_dirname.endswith('.egg-info'): ext_whl_metadata = pkginfo.Develop(dist_info_dirname) elif dist_info_dirname.endswith('.dist-info'): ext_whl_metadata = pkginfo.Wheel(dist_info_dirname) else: raise ValueError() if self.name == ext_whl_metadata.name: metadata.update(vars(ext_whl_metadata)) except ValueError: logger.warning('extension %s contains invalid metadata for Python Package', self.name) return metadata
def test_grpc_whl(self): td = pkginfo.Wheel( TestData("grpc_whl/file/grpcio-1.6.0-cp27-cp27m-manylinux1_i686.whl") ) self.assertEqual( set(whl.dependencies(td)), set(["enum34", "futures", "protobuf", "six"]) )
def from_metadata(cls, path): # type: (Path) -> Optional[PackageInfo] """ Helper method to parse package information from an unpacked metadata directory. :param path: The metadata directory to parse information from. """ if path.suffix in {".dist-info", ".egg-info"}: directories = [path] else: directories = cls._find_dist_info(path=path) for directory in directories: try: if directory.suffix == ".egg-info": dist = pkginfo.UnpackedSDist(directory.as_posix()) elif directory.suffix == ".dist-info": dist = pkginfo.Wheel(directory.as_posix()) else: continue break except ValueError: continue else: try: # handle PKG-INFO in unpacked sdist root dist = pkginfo.UnpackedSDist(path.as_posix()) except ValueError: return info = cls._from_distribution(dist=dist) if info: return info
def test_mock_whl_extras(self, *args): td = pkginfo.Wheel( TestData("mock_whl/file/mock-2.0.0-py2.py3-none-any.whl")) self.assertEqual(set(whl.dependencies(td, extra="docs")), set(["sphinx"])) self.assertEqual(set(whl.dependencies(td, extra="test")), set(["unittest2"]))
def get_package_from_file(cls, file_path): # type: (Path) -> Package if file_path.suffix == ".whl": meta = pkginfo.Wheel(str(file_path)) else: # Assume sdist meta = pkginfo.SDist(str(file_path)) package = Package(meta.name, meta.version) package.source_type = "file" package.source_url = file_path.as_posix() package.description = meta.summary for req in meta.requires_dist: dep = dependency_from_pep_508(req) for extra in dep.in_extras: if extra not in package.extras: package.extras[extra] = [] package.extras[extra].append(dep) if not dep.is_optional(): package.requires.append(dep) if meta.requires_python: package.python_versions = meta.requires_python return package
def _get_pkginfo(filename: str): try: if ".whl" in filename: return pkginfo.Wheel(filename) else: return pkginfo.SDist(filename) except Exception: return None
def test_google_cloud_language_whl_3_4(self, *args): td = pkginfo.Wheel( TestData("google_cloud_language_whl/file/" + "google_cloud_language-0.29.0-py2.py3-none-any.whl")) expected_deps = [ "google-gax", "google-cloud-core", "googleapis-common-protos[grpc]", ] self.assertEqual(set(whl.dependencies(td)), set(expected_deps))
def from_wheel(cls, path): # type: (Path) -> PackageInfo """ Gather package information from a wheel. :param path: Path to wheel. """ try: return cls._from_distribution(pkginfo.Wheel(str(path))) except ValueError: return PackageInfo()
def test_build_dist(tmpdir): dest_dir = tmpdir.mkdir("repo") repo_pth = clone_repo(code_plugin_url, dest_dir).working_tree_dir wheel_pth = build_dist(repo_pth, dest_dir) assert wheel_pth.endswith('.whl') wheel = pkginfo.Wheel(wheel_pth) assert isinstance(wheel, pkginfo.Wheel) assert wheel.name == 'napari-demo'
def test_pytest_flask_whl(self, *args): td = pkginfo.Wheel( TestData("pytest_flask_0_14_0_whl/file/" + "pytest_flask-0.14.0-py2.py3-none-any.whl")) expected_deps = [ 'pytest', 'Flask', 'Werkzeug', ] self.assertEqual(len(whl.dependencies(td)), len(expected_deps)) self.assertEqual(set(whl.dependencies(td)), set(expected_deps))
def __call__(self, ctx, dsp): src = ctx.src _log.info('Collecting metadata for %r.', src) with tempfile.TemporaryDirectory(prefix='pup-metadata-') as temp_dir: wheel_file = self._create_wheel(ctx.src, temp_dir, dsp) ctx.src_metadata = pkginfo.Wheel(wheel_file) for field in self._METADATA_FIELDS: _log.debug('%s=%r', field, getattr(ctx.src_metadata, field))
def metadata(self): # Extract the structured data from metadata.json in the WHL's dist-info # directory. with zipfile.ZipFile(self.path(), 'r') as whl: # first check for metadata.json try: with whl.open(self._dist_info() + '/metadata.json') as f: return json.loads(f.read().decode("utf-8")) except KeyError: pass # fall back to parsing using pkginfo return self._parse_with_pkginfo(pkginfo.Wheel(self.path()))
def install_package(pkg, directory, pip_args): """Downloads wheel for a package. Assumes python binary provided has pip and wheel package installed. Args: pkg: package name directory: destination directory to download the wheel file in python: python binary path used to run pip command pip_args: extra pip args sent to pip Returns: str: path to the wheel file """ pip_args = [ "--isolated", "--disable-pip-version-check", "--target", directory, "--no-deps", "--ignore-requires-python", "--use-deprecated=legacy-resolver", pkg, ] + pip_args cmd = create_command("install") cmd.main(pip_args) # need dist-info directory for pkg_resources to be able to find the packages dist_info = glob.glob(os.path.join(directory, "*.dist-info"))[0] # fix namespace packages by adding proper __init__.py files namespace_packages = os.path.join(dist_info, "namespace_packages.txt") if os.path.exists(namespace_packages): with open(namespace_packages) as nspkg: for line in nspkg.readlines(): namespace = line.strip().replace(".", os.sep) if namespace: _create_nspkg_init(os.path.join(directory, namespace)) # PEP 420 -- Implicit Namespace Packages if (sys.version_info[0], sys.version_info[1]) >= (3, 3): for dirpath, dirnames, filenames in os.walk(directory): # we are only interested in dirs with no init file if "__init__.py" in filenames: dirnames[:] = [] continue # remove bin and dist-info dirs for ignored in ("bin", os.path.basename(dist_info)): if ignored in dirnames: dirnames.remove(ignored) _create_nspkg_init(dirpath) return pkginfo.Wheel(dist_info)
def _get_requires_dist_from_wheel(self, url ): # type: (str) -> Union[list, None] filename = os.path.basename(urlparse.urlparse(url).path) with temporary_directory() as temp_dir: filepath = os.path.join(temp_dir, filename) self._download(url, filepath) try: meta = pkginfo.Wheel(filepath) except ValueError: # Unable to determine dependencies # Assume none return if meta.requires_dist: return meta.requires_dist
def search_for_file(self, dependency): # type: (FileDependency) -> List[Package] if dependency.path.suffix == ".whl": meta = pkginfo.Wheel(str(dependency.full_path)) else: # Assume sdist meta = pkginfo.SDist(str(dependency.full_path)) if dependency.name != meta.name: # For now, the dependency's name must match the actual package's name raise RuntimeError( "The dependency name for {} does not match the actual package's name: {}".format( dependency.name, meta.name ) ) package = Package(meta.name, meta.version) package.source_type = "file" package.source_url = dependency.path.as_posix() package.description = meta.summary for req in meta.requires_dist: dep = dependency_from_pep_508(req) for extra in dep.in_extras: if extra not in package.extras: package.extras[extra] = [] package.extras[extra].append(dep) if not dep.is_optional(): package.requires.append(dep) if meta.requires_python: package.python_versions = meta.requires_python package.hashes = [dependency.hash()] for extra in dependency.extras: if extra in package.extras: for dep in package.extras[extra]: dep.activate() package.requires += package.extras[extra] return [package]
def install_package(pkg, directory, python_version, pip_args): """Downloads wheel for a package. Assumes python binary provided has pip and wheel package installed. :param pkg: package name :param directory: destination directory to download the wheel file in :param python: python binary path used to run pip command :param pip_args: extra pip args sent to pip :returns: path to the wheel file :rtype: str """ pip_args = [ "--isolated", "--disable-pip-version-check", "--target", directory, "--no-deps", "--ignore-requires-python", "--python-version", python_version, pkg, ] + pip_args cmd = InstallCommand() cmd.run(*cmd.parse_args(pip_args)) # need dist-info directory for pkg_resources to be able to find the packages dist_info = glob.glob(os.path.join(directory, "*.dist-info"))[0] # fix namespace packages by adding proper __init__.py files namespace_packages = os.path.join(dist_info, "namespace_packages.txt") if os.path.exists(namespace_packages): with open(namespace_packages) as nspkg: for line in nspkg.readlines(): namespace = line.strip().replace(".", os.sep) if namespace: nspkg_init = os.path.join(directory, namespace, "__init__.py") with open(nspkg_init, "w") as nspkg: nspkg.write( "__path__ = __import__('pkgutil').extend_path(__path__, __name__)" ) return pkginfo.Wheel(dist_info)
def get_nni_meta(source): if not os.path.exists(source): print_error('{} does not exist'.format(source)) return None if os.path.isdir(source): if not os.path.exists(os.path.join(source, 'setup.py')): print_error('setup.py not found') return None pkg = pkginfo.Develop(source) else: if not source.endswith('.whl'): print_error('File name {} must ends with \'.whl\''.format(source)) return False pkg = pkginfo.Wheel(source) classifiers = pkg.classifiers meta = parse_classifiers(classifiers) meta['package_name'] = pkg.name return meta
def get_metadata(self): from glob import glob if not extension_exists(self.name): return None metadata = {} ext_dir = self.path or get_extension_path(self.name) info_dirs = glob(os.path.join(ext_dir, '*.*-info')) azext_metadata = WheelExtension.get_azext_metadata(ext_dir) if azext_metadata: metadata.update(azext_metadata) for dist_info_dirname in info_dirs: try: ext_whl_metadata = pkginfo.Wheel(dist_info_dirname) metadata.update(vars(ext_whl_metadata)) except ValueError: logger.warning( 'extension % contains invalid metadata for Python Package', self.name) return metadata
def get_pkginfo(f): fp, ext = os.path.splitext(f) #print(f) try: if ext == '.whl': return pkg.Wheel(f) elif ext == '.gz': return pkg.SDist(f) elif ext == '.zip': return pkg.SDist(f) elif ext == '.egg': return pkg.BDist(f) elif ext == '.bz2': return pkg.SDist(f) elif ext == '.tgz': return pkg.SDist(f) except ReadError: return None except ValueError: return None else: return None
def download_finished(self, *args, **kw): # print("HelpUI.download_finished", args, kw) finished = [] pending = [] for item in self._pending_downloads: if not item.isFinished(): pending.append(item) else: finished.append(item) self._pending_downloads = pending import pkginfo from chimerax.ui.ask import ask for item in finished: item.finished.disconnect() filename = item.path() try: w = pkginfo.Wheel(filename) except Exception as e: self.session.logger.info("Error parsing %s: %s" % (filename, str(e))) self.session.logger.info("File saved as %s" % filename) continue if not _installable(w, self.session.logger): self.session.logger.info("Bundle saved as %s" % filename) continue how = ask(self.session, "Install %s %s (file %s)?" % (w.name, w.version, filename), ["install", "cancel"], title="Toolshed") if how == "cancel": self.session.logger.info("Bundle installation canceled") continue self.session.toolshed.install_bundle(filename, self.session.logger, per_user=True, session=self.session)
def test_whl_with_METADATA_file(self): td = pkginfo.Wheel( TestData( "futures_2_2_0_whl/file/futures-2.2.0-py2.py3-none-any.whl")) self.assertEqual(set(whl.dependencies(td)), set())
def test_futures_whl(self): td = pkginfo.Wheel( TestData("futures_3_1_1_whl/file/futures-3.1.1-py2-none-any.whl")) self.assertEqual(set(whl.dependencies(td)), set())
def test_mock_whl_3_3(self, *args): td = pkginfo.Wheel( TestData("mock_whl/file/mock-2.0.0-py2.py3-none-any.whl")) self.assertEqual(set(whl.dependencies(td)), set(["pbr", "six"]))