def get_wheel_deps(wheel_dir): from wheel.pkginfo import read_pkg_info_bytes from wheel.wheelfile import WheelFile requires_dist_re = re.compile(r"""^(?P<name>\S+)(\s\((?P<spec>.+)\))?$""") packages = {} dependencies = {} for whl_path in locate_wheels(wheel_dir): try: with WheelFile(whl_path) as whl: pkg_info = read_pkg_info_bytes(whl.read(whl.dist_info_path + '/METADATA')) lib_name = pkg_info.get('Name') if should_skip_lib(lib_name): continue packages[lib_name] = { 'version': pkg_info.get('Version'), 'source': whl_path } requires = pkg_info.get_all('Requires-Dist') for req in requires: parsed = requires_dist_re.match(req.split(';')[0].strip()) req_name, spec = parsed.group('name', 'spec') spec = ','.join(sorted(spec.split(','))) if spec else '' if not req_name in dependencies: dependencies[req_name] = {} if not spec in dependencies[req_name]: dependencies[req_name][spec] = [] dependencies[req_name][spec].append(lib_name) except: print('Failed to parse METADATA from %s' % (whl_path)) return packages, dependencies
def get_wheel_deps(wheel_dir): from wheel.pkginfo import read_pkg_info_bytes from wheel.wheelfile import WheelFile packages = {} dependencies = {} for whl_path in locate_wheels(wheel_dir): try: with WheelFile(whl_path) as whl: pkg_info = read_pkg_info_bytes(whl.read(whl.dist_info_path + '/METADATA')) lib_name = pkg_info.get('Name') packages[lib_name] = { 'version': pkg_info.get('Version'), 'source': whl_path, 'deps': [] } requires = pkg_info.get_all('Requires-Dist') for req in requires: req = req.split(';')[0] # Extras conditions appear after a semicolon req = re.sub(r'[\s\(\)]', '', req) # Version specifiers appear in parentheses req_name, spec = parse_req(req) packages[lib_name]['deps'].append({ 'name': req_name, 'version': spec }) if not report_should_skip_lib(lib_name): record_dep(dependencies, req_name, spec, lib_name) except: print('Failed to parse METADATA from %s' % (whl_path)) return packages, dependencies
def parse_to_db(session, pkg_infos): pkginfo_insert = PKGINFO.__table__.insert() i = 0 for file in pkg_infos: try: pkginfo = read_pkg_info_bytes(file.contents) except Exception as e: # doesn't happen session.execute(pkginfo_insert, { 'file_id': file.id, 'key': 'error', 'value': repr(e) }) continue # XXX delete old values (or purge entire table) for key, value in pkginfo.items(): if key.lower() == 'description': continue key = key.title() try: key = key.decode('latin1') value = value.decode('utf-8') except UnicodeDecodeError: value = value.decode('latin1') session.execute(pkginfo_insert, { 'file_id': file.id, 'key': key, 'value': value }) i += 1 if (i % 10000) == 0: print i
def test_success(project, requirements): subprocess.check_call( ['pip', 'wheel', '--no-build-isolation', '--no-deps', '.'], cwd=project) meta = _get_wheel_metadata(project) info = pkginfo.read_pkg_info_bytes(meta) assert info.get_all('Requires-Dist') == ['flask'] + requirements
def build_wheel(self, wheel_directory, config_settings=None, metadata_directory=None): requirements_path = Path('requirements.txt') if not requirements_path.exists(): raise ValueError('"requirements.txt" file must be present when using setup_requirements build backend') result_basename = super().build_wheel( wheel_directory, config_settings=config_settings, metadata_directory=metadata_directory ) wheel_file = Path(wheel_directory) / result_basename with zipfile.ZipFile(wheel_file) as zf: metas = [f for f in zf.infolist() if os.path.basename(f.filename) == 'METADATA'] assert len(metas) == 1, 'METADATA file not found in final wheel file' meta = metas[0] info = pkginfo.read_pkg_info_bytes(zf.read(meta)) for requirement in parse_requirements(requirements_path.read_text()): info['Requires-Dist'] = str(requirement) with tempfile.NamedTemporaryFile() as tmp: pkginfo.write_pkg_info(tmp.name, info) tmp.seek(0) new_meta = tmp.read() zip_overwrite(wheel_file, meta, new_meta) return result_basename
def get_wheel_deps(wheel_dir): from wheel.pkginfo import read_pkg_info_bytes from wheel.wheelfile import WheelFile requires_dist_re = re.compile(r"""^(?P<name>\S+)(\s\((?P<spec>.+)\))?$""") packages = {} dependencies = {} for whl_path in locate_wheels(wheel_dir): try: with WheelFile(whl_path) as whl: pkg_info = read_pkg_info_bytes( whl.read(whl.dist_info_path + '/METADATA')) lib_name = pkg_info.get('Name') if should_skip_lib(lib_name): continue packages[lib_name] = { 'version': pkg_info.get('Version'), 'source': whl_path } requires = pkg_info.get_all('Requires-Dist') for req in requires: parsed = requires_dist_re.match(req.split(';')[0].strip()) req_name, spec = parsed.group('name', 'spec') spec = ','.join(sorted(spec.split(','))) if spec else '' if not req_name in dependencies: dependencies[req_name] = {} if not spec in dependencies[req_name]: dependencies[req_name][spec] = [] dependencies[req_name][spec].append(lib_name) except: print('Failed to parse METADATA from %s' % (whl_path)) return packages, dependencies
def get_info(wheelfile): # Work round wheel API changes try: return wheelfile.parsed_wheel_info except AttributeError: pass # Wheel 0.32.0 from wheel.pkginfo import read_pkg_info_bytes info_name = _get_wheelinfo_name(wheelfile) return read_pkg_info_bytes(wheelfile.read(info_name))
def _collect_tags(self, wheel_metadata): pyver, abi, plat = set(), set(), set() pkginfo = read_pkg_info_bytes(wheel_metadata) tags = pkginfo.get_all("tag") for tag in tags: t_pyver, t_abi, t_plat = tag.split("-") pyver.add(t_pyver) abi.add(t_abi) plat.add(t_plat) return "%s-%s-%s" % tuple([ ".".join(sorted(tag)) for tag in (pyver, abi, plat)])
def _collect_tags(self, wheel_metadata): pyver, abi, plat = set(), set(), set() pkginfo = read_pkg_info_bytes(wheel_metadata) tags = pkginfo.get_all("tag") for tag in tags: t_pyver, t_abi, t_plat = tag.split("-") pyver.add(t_pyver) abi.add(t_abi) plat.add(t_plat) return "%s-%s-%s" % tuple( [".".join(sorted(tag)) for tag in (pyver, abi, plat)])
def get_package_info(package): package = str(package) name, description, long_description = '', '', '' if package.endswith('.whl'): wf = wheelfile.WheelFile(package) ef = wf.open(posixpath.join(wf.dist_info_path, 'METADATA')) pkg_info = pkginfo.read_pkg_info_bytes(ef.read()) name = pkg_info['Name'] description = pkg_info['Summary'] long_description = pkg_info.get_payload() ef.close() wf.close() if package.endswith('.egg'): with zipfile.ZipFile(package) as zf: with zf.open(posixpath.join('EGG-INFO', 'PKG-INFO')) as fp: value = fp.read().decode('utf-8') pkg_info = email.parser.Parser().parsestr(value) name = pkg_info['Name'] description = pkg_info['Summary'] long_description = pkg_info['Description'] long_description = '\n'.join((line.strip() for line in StringIO(long_description))) return name, description, long_description
def parsed_wheel_info(self): """Parse wheel metadata (the .data/WHEEL file)""" return read_pkg_info_bytes(self.zipfile.read(self.wheelinfo_name))
def is_purelib(self): """Returns True if the Wheel is a purelib.""" wheel_info = pkginfo.read_pkg_info_bytes( self.distribution.get_metadata(self.WHEEL_INFO).encode("utf-8") ) return wheel_info["Root-Is-Purelib"] == "true"