def distros_for_location(location, basename, metadata=None): """Yield egg or source distribution objects based on basename""" if basename.endswith('.egg.zip'): basename = basename[:-4] # strip the .zip if basename.endswith('.egg') and '-' in basename: # only one, unambiguous interpretation return [Distribution.from_location(location, basename, metadata)] if basename.endswith('.whl') and '-' in basename: wheel = Wheel(basename) if not wheel.is_compatible(): return [] return [ Distribution( location=location, project_name=wheel.project_name, version=wheel.version, # Increase priority over eggs. precedence=EGG_DIST + 1, ) ] if basename.endswith('.exe'): win_base, py_ver, platform = parse_bdist_wininst(basename) if win_base is not None: return interpret_distro_name(location, win_base, metadata, py_ver, BINARY_DIST, platform) # Try source distro extensions (.zip, .tgz, etc.) # for ext in EXTENSIONS: if basename.endswith(ext): basename = basename[:-len(ext)] return interpret_distro_name(location, basename, metadata) return [] # no extension matched
def run(self): import pex.third_party.setuptools.command.easy_install as ei self.run_command("egg_info") if self.distribution.scripts: orig.install_scripts.run(self) # run first to set up self.outfiles else: self.outfiles = [] if self.no_ep: # don't install entry point scripts into .egg file! return ei_cmd = self.get_finalized_command("egg_info") dist = Distribution( ei_cmd.egg_base, PathMetadata(ei_cmd.egg_base, ei_cmd.egg_info), ei_cmd.egg_name, ei_cmd.egg_version, ) bs_cmd = self.get_finalized_command('build_scripts') exec_param = getattr(bs_cmd, 'executable', None) bw_cmd = self.get_finalized_command("bdist_wininst") is_wininst = getattr(bw_cmd, '_is_running', False) writer = ei.ScriptWriter if is_wininst: exec_param = "python.exe" writer = ei.WindowsScriptWriter if exec_param == sys.executable: # In case the path to the Python executable contains a space, wrap # it so it's not split up. exec_param = [exec_param] # resolve the writer to the environment writer = writer.best() cmd = writer.command_spec_class.best().from_param(exec_param) for args in writer.get_args(dist, cmd.as_header()): self.write_script(*args)
def test_can_add_handles_invalid_wheel_filename(python_35_interpreter): # type: (PythonInterpreter) -> None pex_environment = PEXEnvironment( pex="", pex_info=PexInfo.default(python_35_interpreter), interpreter=python_35_interpreter) assert pex_environment.can_add(Distribution("pep427-invalid.whl")) is False
def create_dist( location, # type: str version="1.0.0", # type: Optional[str] ): # type: (...) -> Distribution # N.B.: version must be set simply so that __hash__ / __eq__ work correctly in the # `pex.dist_metadata` module. return Distribution(location=location, version=version)
def test_can_add_handles_optional_build_tag_in_wheel( python_35_interpreter, wheel_filename, wheel_is_linux ): # type: (PythonInterpreter, str, bool) -> None pex_environment = PEXEnvironment( pex="", pex_info=PexInfo.default(python_35_interpreter), interpreter=python_35_interpreter ) native_wheel = IS_LINUX and wheel_is_linux assert pex_environment.can_add(Distribution(wheel_filename)) is native_wheel
def _convert_metadata(zf, destination_eggdir, dist_info, egg_info): def get_metadata(name): with zf.open(posixpath.join(dist_info, name)) as fp: value = fp.read().decode('utf-8') if PY3 else fp.read() return email.parser.Parser().parsestr(value) wheel_metadata = get_metadata('WHEEL') # Check wheel format version is supported. wheel_version = parse_version(wheel_metadata.get('Wheel-Version')) wheel_v1 = ( parse_version('1.0') <= wheel_version < parse_version('2.0dev0') ) if not wheel_v1: raise ValueError( 'unsupported wheel format version: %s' % wheel_version) # Extract to target directory. os.mkdir(destination_eggdir) zf.extractall(destination_eggdir) # Convert metadata. dist_info = os.path.join(destination_eggdir, dist_info) dist = Distribution.from_location( destination_eggdir, dist_info, metadata=PathMetadata(destination_eggdir, dist_info), ) # Note: Evaluate and strip markers now, # as it's difficult to convert back from the syntax: # foobar; "linux" in sys_platform and extra == 'test' def raw_req(req): req.marker = None return str(req) install_requires = list(sorted(map(raw_req, dist.requires()))) extras_require = { extra: sorted( req for req in map(raw_req, dist.requires((extra,))) if req not in install_requires ) for extra in dist.extras } os.rename(dist_info, egg_info) os.rename( os.path.join(egg_info, 'METADATA'), os.path.join(egg_info, 'PKG-INFO'), ) setup_dist = SetuptoolsDistribution( attrs=dict( install_requires=install_requires, extras_require=extras_require, ), ) write_requirements( setup_dist.get_command_obj('egg_info'), None, os.path.join(egg_info, 'requires.txt'), )
def matches_requirement(req, wheels): """List of wheels matching a requirement. :param req: The requirement to satisfy :param wheels: List of wheels to search. """ try: from pex.third_party.pkg_resources import Distribution, Requirement except ImportError: raise RuntimeError("Cannot use requirements without pkg_resources") req = Requirement.parse(req) selected = [] for wf in wheels: f = wf.parsed_filename dist = Distribution(project_name=f.group("name"), version=f.group("ver")) if dist in req: selected.append(wf) return selected
def finalize_options(self): ei = self.get_finalized_command("egg_info") if ei.broken_egg_info: template = "Please rename %r to %r before using 'develop'" args = ei.egg_info, ei.broken_egg_info raise DistutilsError(template % args) self.args = [ei.egg_name] easy_install.finalize_options(self) self.expand_basedirs() self.expand_dirs() # pick up setup-dir .egg files only: no .egg-info self.package_index.scan(glob.glob('*.egg')) egg_link_fn = ei.egg_name + '.egg-link' self.egg_link = os.path.join(self.install_dir, egg_link_fn) self.egg_base = ei.egg_base if self.egg_path is None: self.egg_path = os.path.abspath(ei.egg_base) target = normalize_path(self.egg_base) egg_path = normalize_path(os.path.join(self.install_dir, self.egg_path)) if egg_path != target: raise DistutilsOptionError( "--egg-path must be a relative path from the install" " directory to " + target) # Make a distribution for the package's source self.dist = Distribution(target, PathMetadata(target, os.path.abspath(ei.egg_info)), project_name=ei.egg_name) self.setup_path = self._resolve_setup_path( self.egg_base, self.install_dir, self.egg_path, )
def finalize_options(self): ei_cmd = self.ei_cmd = self.get_finalized_command("egg_info") self.egg_info = ei_cmd.egg_info if self.bdist_dir is None: bdist_base = self.get_finalized_command('bdist').bdist_base self.bdist_dir = os.path.join(bdist_base, 'egg') if self.plat_name is None: self.plat_name = get_build_platform() self.set_undefined_options('bdist', ('dist_dir', 'dist_dir')) if self.egg_output is None: # Compute filename of the output egg basename = Distribution( None, None, ei_cmd.egg_name, ei_cmd.egg_version, get_python_version(), self.distribution.has_ext_modules() and self.plat_name).egg_name() self.egg_output = os.path.join(self.dist_dir, basename + '.egg')
def interpret_distro_name(location, basename, metadata, py_version=None, precedence=SOURCE_DIST, platform=None): """Generate alternative interpretations of a source distro name Note: if `location` is a filesystem filename, you should call ``pkg_resources.normalize_path()`` on it before passing it to this routine! """ # Generate alternative interpretations of a source distro name # Because some packages are ambiguous as to name/versions split # e.g. "adns-python-1.1.0", "egenix-mx-commercial", etc. # So, we generate each possible interepretation (e.g. "adns, python-1.1.0" # "adns-python, 1.1.0", and "adns-python-1.1.0, no version"). In practice, # the spurious interpretations should be ignored, because in the event # there's also an "adns" package, the spurious "python-1.1.0" version will # compare lower than any numeric version number, and is therefore unlikely # to match a request for it. It's still a potential problem, though, and # in the long run PyPI and the distutils should go for "safe" names and # versions in distribution archive names (sdist and bdist). parts = basename.split('-') if not py_version and any(re.match(r'py\d\.\d$', p) for p in parts[2:]): # it is a bdist_dumb, not an sdist -- bail out return for p in range(1, len(parts) + 1): yield Distribution(location, metadata, '-'.join(parts[:p]), '-'.join(parts[p:]), py_version=py_version, precedence=precedence, platform=platform)
def distribution(self): return Distribution(project_name=self.interpreter, version=self.version_str)
def egg_name(self): return Distribution( project_name=self.project_name, version=self.version, platform=(None if self.platform == 'any' else get_platform()), ).egg_name() + '.egg'