Example #1
0
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
Example #2
0
    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)
Example #3
0
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
Example #4
0
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)
Example #5
0
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
Example #6
0
    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'),
        )
Example #7
0
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
Example #8
0
    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,
        )
Example #9
0
    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')
Example #10
0
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)
Example #11
0
 def distribution(self):
     return Distribution(project_name=self.interpreter,
                         version=self.version_str)
Example #12
0
 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'