Example #1
0
 def test_unexisting_path(self):
     with pytest.raises(InstallationError) as e:
         InstallRequirement.from_line(
             os.path.join('this', 'path', 'does', 'not', 'exist'))
     err_msg = e.value.args[0]
     assert "Invalid requirement" in err_msg
     assert "It looks like a path." in err_msg
Example #2
0
 def run(self, options, args):
     if not options.build_dir:
         options.build_dir = build_prefix
     if not options.src_dir:
         options.src_dir = src_prefix
     if options.download_dir:
         options.no_install = True
         options.ignore_installed = True
     options.build_dir = os.path.abspath(options.build_dir)
     options.src_dir = os.path.abspath(options.src_dir)
     install_options = options.install_options or []
     index_urls = [options.index_url] + options.extra_index_urls
     if options.no_index:
         logger.notify('Ignoring indexes: %s' % ','.join(index_urls))
         index_urls = []
     finder = PackageFinder(
         find_links=options.find_links,
         index_urls=index_urls)
     requirement_set = RequirementSet(
         build_dir=options.build_dir,
         src_dir=options.src_dir,
         download_dir=options.download_dir,
         download_cache=options.download_cache,
         upgrade=options.upgrade,
         ignore_installed=options.ignore_installed,
         ignore_dependencies=options.ignore_dependencies)
     for name in args:
         requirement_set.add_requirement(
             InstallRequirement.from_line(name, None))
     for name in options.editables:
         requirement_set.add_requirement(
             InstallRequirement.from_editable(name, default_vcs=options.default_vcs))
     for filename in options.requirements:
         for req in parse_requirements(filename, finder=finder, options=options):
             requirement_set.add_requirement(req)
     if not options.no_download:
         requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
     else:
         requirement_set.locate_files()
     if not options.no_install and not self.bundle:
         requirement_set.install(install_options)
         installed = ' '.join([req.name for req in
                               requirement_set.successfully_installed])
         if installed:
             logger.notify('Successfully installed %s' % installed)
     elif not self.bundle:
         downloaded = ' '.join([req.name for req in
                                requirement_set.successfully_downloaded])
         if downloaded:
             logger.notify('Successfully downloaded %s' % downloaded)
     elif self.bundle:
         requirement_set.create_bundle(self.bundle_filename)
         logger.notify('Created bundle in %s' % self.bundle_filename)
     # Clean up
     if not options.no_install:
         requirement_set.cleanup_files(bundle=self.bundle)
     return requirement_set
Example #3
0
def test_exclusive_environment_markers():
    """Make sure RequirementSet accepts several excluding env markers"""
    eq26 = InstallRequirement.from_line("Django>=1.6.10,<1.7 ; python_version == '2.6'")
    ne26 = InstallRequirement.from_line("Django>=1.6.10,<1.8 ; python_version != '2.6'")

    req_set = RequirementSet("", "", "", session=PipSession())
    req_set.add_requirement(eq26)
    req_set.add_requirement(ne26)
    assert req_set.has_requirement("Django")
Example #4
0
        def _find_cached_match(spec):
            #if spec.is_pinned:
                ## If this is a pinned spec, we can take a shortcut: if it is
                ## found in the dependency cache, we can safely assume it has
                ## been downloaded before, and thus must exist.  We can know
                ## this without every reaching out to PyPI and avoid the
                ## network overhead.
                #name, version = spec.name, first(spec.preds)[1]
                #if (name, version) in self._dep_cache:
                    #source = 'dependency cache'
                    #return version, source
            version = None
            overrides = self.overrides.get(spec.name)

            ## Try the link cache, and otherwise, try PyPI
            if (spec.no_extra, overrides) in self._link_cache:
                link, version = self._link_cache[(spec.no_extra, overrides)]
                source = 'link cache'
            else:
                try:
                    requirement = InstallRequirement.from_line(specline)
                    link = self.finder.find_requirement(requirement, False)
                except DistributionNotFound:
                    requirement = InstallRequirement.from_line(
                        specline, prereleases=True)
                    link = self.finder.find_requirement(requirement, False)

                link, version = self._link_hook(overrides, spec, link)

                # Hack to make pickle work
                link.comes_from = None
                source = 'PyPI'

                if link.egg_fragment:
                    version = link.egg_fragment.rsplit('-', 1)[1]
                    link = Link(
                        link.url_without_fragment + "#%s=%s" % self.get_hash(link)
                    )
                elif not version:
                    _, version = splitext(link.filename)[0].rsplit('-', 1)

                # It's more reliable to get version from pinned spec then filename
                if spec.is_pinned:
                    version = spec.pinned

                assert version, "Version must be set!"
                self._link_cache[(spec.no_extra, overrides)] = (link, version)

                # Take this moment to smartly insert the pinned variant of this
                # spec into the link_cache, too
                pinned_spec = Spec.from_pinned(spec.name, version)
                self._link_cache[pinned_spec.fullname] = (link, version)

            return version, source
Example #5
0
 def test_requirement_file(self):
     req_file_path = os.path.join(self.tempdir, 'test.txt')
     with open(req_file_path, 'w') as req_file:
         req_file.write('pip\nsetuptools')
     with pytest.raises(InstallationError) as e:
         InstallRequirement.from_line(req_file_path)
     err_msg = e.value.args[0]
     assert "Invalid requirement" in err_msg
     assert "It looks like a path. It does exist." in err_msg
     assert "appears to be a requirements file." in err_msg
     assert "If that is the case, use the '-r' flag to install" in err_msg
Example #6
0
    def populate_requirement_set(requirement_set, args, options, finder,
                                 session, name, wheel_cache):
        """
        Marshal cmd line args into a requirement set.
        """
        for filename in options.constraints:
            for req in parse_requirements(
                    filename,
                    constraint=True, finder=finder, options=options,
                    session=session, wheel_cache=wheel_cache):
                requirement_set.add_requirement(req)

        for req in args:
            requirement_set.add_requirement(
                InstallRequirement.from_line(
                    req, None, isolated=options.isolated_mode,
                    wheel_cache=wheel_cache
                )
            )

        for req in options.editables:
            requirement_set.add_requirement(
                InstallRequirement.from_editable(
                    req,
                    default_vcs=options.default_vcs,
                    isolated=options.isolated_mode,
                    wheel_cache=wheel_cache
                )
            )

        found_req_in_file = False
        for filename in options.requirements:
            for req in parse_requirements(
                    filename,
                    finder=finder, options=options, session=session,
                    wheel_cache=wheel_cache):
                found_req_in_file = True
                requirement_set.add_requirement(req)
        # If --require-hashes was a line in a requirements file, tell
        # RequirementSet about it:
        requirement_set.require_hashes = options.require_hashes

        if not (args or options.editables or found_req_in_file):
            opts = {'name': name}
            if options.find_links:
                msg = ('You must give at least one requirement to '
                       '%(name)s (maybe you meant "pip %(name)s '
                       '%(links)s"?)' %
                       dict(opts, links=' '.join(options.find_links)))
            else:
                msg = ('You must give at least one requirement '
                       'to %(name)s (see "pip help %(name)s")' % opts)
            logger.warning(msg)
Example #7
0
    def test_markers_match(self):
        # match
        for markers in ('python_version >= "1.0"', "sys_platform == %r" % sys.platform):
            line = "name; " + markers
            req = InstallRequirement.from_line(line)
            assert req.markers == markers
            assert req.match_markers()

        # don't match
        for markers in ('python_version >= "5.0"', "sys_platform != %r" % sys.platform):
            line = "name; " + markers
            req = InstallRequirement.from_line(line)
            assert req.markers == markers
            assert not req.match_markers()
Example #8
0
    def test_markers_url(self):
        # test "URL; markers" syntax
        url = 'http://foo.com/?p=bar.git;a=snapshot;h=v0.1;sf=tgz'
        line = '%s; python_version >= "3"' % url
        req = InstallRequirement.from_line(line)
        assert req.link.url == url, req.url
        assert str(req.markers) == 'python_version >= "3"'

        # without space, markers are part of the URL
        url = 'http://foo.com/?p=bar.git;a=snapshot;h=v0.1;sf=tgz'
        line = '%s;python_version >= "3"' % url
        req = InstallRequirement.from_line(line)
        assert req.link.url == line, req.url
        assert req.markers is None
Example #9
0
def make_install_requirement(name, version, extras, markers, constraint=False):
    # If no extras are specified, the extras string is blank
    extras_string = ""
    if extras:
        # Sort extras for stability
        extras_string = "[{}]".format(",".join(sorted(extras)))

    if not markers:
        return InstallRequirement.from_line(
            str('{}{}=={}'.format(name, extras_string, version)),
            constraint=constraint)
    else:
        return InstallRequirement.from_line(
            str('{}{}=={}; {}'.format(name, extras_string, version, str(markers))),
            constraint=constraint)
Example #10
0
    def handle(self, *args, **options):
        new_app_names = []
        new_package_names = []
        extra_settings = []
        default_templates = []
        for name in args:
            req = InstallRequirement.from_line(name)
            if not req.check_if_exists():
                result = subprocess.call(["pip", "install", name])
                if not result == 0:
                    raise Exception("Install error")
                req = InstallRequirement.from_line(name)
                if not req.check_if_exists():
                    raise Exception("Installed package not found")

            distribution = req.satisfied_by
            new_package_names.append(distribution.project_name)
            
            def _get_app_names(name):
                if HOOKS['APPNAMES'].has_key(name):
                    return HOOKS['APPNAMES'][name]
                    
                ## try real package names
                packages = os.listdir(distribution.location)
                candidates = difflib.get_close_matches(name, packages)
                if candidates:
                    return [candidates[0]]
                
                return name
            
            new_app_names += _get_app_names(distribution.project_name)
            if HOOKS['EXTRA_SETTINGS'].has_key(distribution.project_name):
                extra_settings += [HOOKS['EXTRA_SETTINGS'][distribution.project_name]]
            if HOOKS['TEMPLATES'].has_key(distribution.project_name):
                default_templates += [HOOKS['TEMPLATES'][distribution.project_name]]
                
        _add_to_requirements_txt(new_package_names)

        ## settings
        for d in extra_settings:
            for name, values in d.items():
                _settings_add_to_list(name, values)
                
        for d in default_templates:
            for name, content in d.items():
                _add_default_template(name, content)

        _add_to_installed_apps(new_app_names)
Example #11
0
    def get_dependencies(self, ireq):
        if ireq.editable:
            return self.editables[str(ireq.link)]

        name, version = as_name_version_tuple(ireq)
        dependencies = self.index[name][version]
        return [InstallRequirement.from_line(dep) for dep in dependencies]
Example #12
0
    def find_best_match(self, ireq, prereleases=False):
        if ireq.editable:
            return ireq

        versions = ireq.specifier.filter(self.index[ireq.req.key], prereleases=prereleases)
        best_version = max(versions, key=Version)
        return InstallRequirement.from_line('{}=={}'.format(ireq.req.key, best_version))
Example #13
0
def test_finder_installs_pre_releases(data):
    """
    Test PackageFinder finds pre-releases if asked to.
    """

    req = InstallRequirement.from_line("bar", None, prereleases=True)

    # using a local index (that has pre & dev releases)
    finder = PackageFinder([], [data.index_url("pre")])
    link = finder.find_requirement(req, False)
    assert link.url.endswith("bar-2.0b1.tar.gz"), link.url

    # using find-links
    links = ["https://foo/bar-1.0.tar.gz", "https://foo/bar-2.0b1.tar.gz"]
    finder = PackageFinder(links, [])

    with patch.object(finder, "_get_pages", lambda x, y: []):
        link = finder.find_requirement(req, False)
        assert link.url == "https://foo/bar-2.0b1.tar.gz"

    links.reverse()
    finder = PackageFinder(links, [])

    with patch.object(finder, "_get_pages", lambda x, y: []):
        link = finder.find_requirement(req, False)
        assert link.url == "https://foo/bar-2.0b1.tar.gz"
Example #14
0
def test_url_with_query():
    """InstallRequirement should strip the fragment, but not the query."""
    url = 'http://foo.com/?p=bar.git;a=snapshot;h=v0.1;sf=tgz'
    fragment = '#egg=bar'
    req = InstallRequirement.from_line(url + fragment)

    assert req.url == url, req.url
Example #15
0
def test_pypirepo_calls_reqset_with_str_paths():
    """
    Make sure that paths passed to RequirementSet init are str.

    Passing unicode paths on Python 2 could make pip fail later on
    unpack, if the package contains non-ASCII file names, because
    non-ASCII str and unicode paths cannot be combined.
    """
    with patch('piptools.repositories.pypi.RequirementSet') as mocked_init:
        repo = get_pypi_repository()
        ireq = InstallRequirement.from_line('ansible==2.4.0.0')

        # Setup a mock object to be returned from the RequirementSet call
        mocked_reqset = MagicMock()
        mocked_init.return_value = mocked_reqset

        # Do the call
        repo.get_dependencies(ireq)

        # Check that RequirementSet init is called with correct type arguments
        assert mocked_init.call_count == 1
        (init_call_args, init_call_kwargs) = mocked_init.call_args
        assert isinstance(init_call_args[0], str)
        assert isinstance(init_call_args[1], str)
        assert isinstance(init_call_kwargs.get('download_dir'), str)
        assert isinstance(init_call_kwargs.get('wheel_download_dir'), str)

        # Check that _prepare_file is called correctly
        assert mocked_reqset._prepare_file.call_count == 1
        (pf_call_args, pf_call_kwargs) = mocked_reqset._prepare_file.call_args
        (called_with_finder, called_with_ireq) = pf_call_args
        assert isinstance(called_with_finder, PackageFinder)
        assert called_with_ireq == ireq
        assert not pf_call_kwargs
Example #16
0
 def test_extras_for_editable_path_requirement(self):
     url = '.[ex1,ex2]'
     filename = 'filename'
     comes_from = '-r %s (line %s)' % (filename, 1)
     req = InstallRequirement.from_editable(url, comes_from=comes_from)
     assert len(req.extras) == 2
     assert req.extras == set(['ex1', 'ex2'])
Example #17
0
 def test_extras_for_line_path_requirement(self):
     line = 'SomeProject[ex1,ex2]'
     filename = 'filename'
     comes_from = '-r %s (line %s)' % (filename, 1)
     req = InstallRequirement.from_line(line, comes_from=comes_from)
     assert len(req.extras) == 2
     assert req.extras == set(['ex1', 'ex2'])
Example #18
0
 def test_extras_for_editable_url_requirement(self):
     url = 'git+https://url#egg=SomeProject[ex1,ex2]'
     filename = 'filename'
     comes_from = '-r %s (line %s)' % (filename, 1)
     req = InstallRequirement.from_editable(url, comes_from=comes_from)
     assert len(req.extras) == 2
     assert req.extras == set(['ex1', 'ex2'])
Example #19
0
    def _iter_dependencies(self, ireq):
        """
        Given a pinned or editable InstallRequirement, collects all the
        secondary dependencies for them, either by looking them up in a local
        cache, or by reaching out to the repository.

        Editable requirements will never be looked up, as they may have
        changed at any time.
        """
        if ireq.editable:
            for dependency in self.repository.get_dependencies(ireq):
                yield dependency
            return
        elif not is_pinned_requirement(ireq):
            raise TypeError("Expected pinned or editable requirement, got {}".format(ireq))

        # Now, either get the dependencies from the dependency cache (for
        # speed), or reach out to the external repository to
        # download and inspect the package version and get dependencies
        # from there
        if ireq not in self.dependency_cache:
            log.debug("  {} not in cache, need to check index".format(format_requirement(ireq)), fg="yellow")
            dependencies = self.repository.get_dependencies(ireq)
            self.dependency_cache[ireq] = sorted(str(ireq.req) for ireq in dependencies)

        # Example: ['Werkzeug>=0.9', 'Jinja2>=2.4']
        dependency_strings = self.dependency_cache[ireq]
        log.debug(
            "  {:25} requires {}".format(
                format_requirement(ireq), ", ".join(sorted(dependency_strings, key=lambda s: s.lower())) or "-"
            )
        )
        for dependency_string in dependency_strings:
            yield InstallRequirement.from_line(dependency_string)
Example #20
0
def test_finder_priority_page_over_deplink():
    """Test PackageFinder prefers page links over equivalent dependency links"""
    req = InstallRequirement.from_line('gmpy==1.15', None)
    finder = PackageFinder([], ["http://pypi.python.org/simple"])
    finder.add_dependency_links(['http://c.pypi.python.org/simple/gmpy/'])
    link = finder.find_requirement(req, False)
    assert link.url.startswith("http://pypi")
def install(name):
    """
    Try to install the package with 'name' into folder 'libs/python27'.
    """
    print "Installation directory:"
    print python27_dir()

    requirement_set = RequirementSet(build_dir=build_prefix,
                                     src_dir=src_prefix,
                                     download_dir=None)

    requirement_set.add_requirement(InstallRequirement.from_line(name, None))

    install_options = ["--prefix=%s" % python27_dir()]
    global_options = []
    finder = PackageFinder(find_links=[],
                           index_urls=["http://pypi.python.org/simple/"])

    try:
        requirement_set.prepare_files(finder,
                                      force_root_egg_info=False,
                                      bundle=False)

        requirement_set.install(install_options, global_options)

        print "\nSuccessfully installed\n=================================="
        for package in requirement_set.successfully_installed:
            print package.name
        print "\nDone.\n"

    except DistributionNotFound:
        print "No package found with name: %s" % name

    except Exception as e:
        print "Error:", e
Example #22
0
def test_finder_only_installs_stable_releases(data):
    """
    Test PackageFinder only accepts stable versioned releases by default.
    """

    req = InstallRequirement.from_line("bar", None)

    # using a local index (that has pre & dev releases)
    finder = PackageFinder([], [data.index_url("pre")], session=PipSession())
    link = finder.find_requirement(req, False)
    assert link.url.endswith("bar-1.0.tar.gz"), link.url

    # using find-links
    links = ["https://foo/bar-1.0.tar.gz", "https://foo/bar-2.0b1.tar.gz"]
    finder = PackageFinder(links, [], session=PipSession())

    with patch.object(finder, "_get_pages", lambda x, y: []):
        link = finder.find_requirement(req, False)
        assert link.url == "https://foo/bar-1.0.tar.gz"

    links.reverse()
    finder = PackageFinder(links, [], session=PipSession())

    with patch.object(finder, "_get_pages", lambda x, y: []):
        link = finder.find_requirement(req, False)
        assert link.url == "https://foo/bar-1.0.tar.gz"
Example #23
0
def test_finder_priority_nonegg_over_eggfragments():
    """Test PackageFinder prefers non-egg links over "#egg=" links"""
    req = InstallRequirement.from_line('bar==1.0', None)
    links = ['http://foo/bar.py#egg=bar-1.0', 'http://foo/bar-1.0.tar.gz']

    finder = PackageFinder(links, [], session=PipSession())

    with patch.object(finder, "_get_pages", lambda x, y: []):
        all_versions = finder._find_all_versions(req.name)
        assert all_versions[0].location.url.endswith('tar.gz')
        assert all_versions[1].location.url.endswith('#egg=bar-1.0')

        link = finder.find_requirement(req, False)

    assert link.url.endswith('tar.gz')

    links.reverse()
    finder = PackageFinder(links, [], session=PipSession())

    with patch.object(finder, "_get_pages", lambda x, y: []):
        all_versions = finder._find_all_versions(req.name)
        assert all_versions[0].location.url.endswith('tar.gz')
        assert all_versions[1].location.url.endswith('#egg=bar-1.0')
        link = finder.find_requirement(req, False)

    assert link.url.endswith('tar.gz')
Example #24
0
def test_no_partial_name_match():
    """Finder requires the full project name to match, not just beginning."""
    finder = PackageFinder([find_links], [])
    req = InstallRequirement.from_line("gmpy")
    found = finder.find_requirement(req, False)

    assert found.url.endswith("gmpy-1.15.tar.gz"), found
Example #25
0
def test_no_mpkg():
    """Finder skips zipfiles with "macosx10" in the name."""
    finder = PackageFinder([find_links], [])
    req = InstallRequirement.from_line("pkgwithmpkg")
    found = finder.find_requirement(req, False)

    assert found.url.endswith("pkgwithmpkg-1.0.tar.gz"), found
Example #26
0
 def run(self, options, args):
     with self._build_session(options) as session:
         format_control = pip.index.FormatControl(set(), set())
         wheel_cache = WheelCache(options.cache_dir, format_control)
         requirement_set = RequirementSet(
             build_dir=None,
             src_dir=None,
             download_dir=None,
             isolated=options.isolated_mode,
             session=session,
             wheel_cache=wheel_cache,
         )
         for name in args:
             requirement_set.add_requirement(
                 InstallRequirement.from_line(
                     name, isolated=options.isolated_mode,
                     wheel_cache=wheel_cache
                 )
             )
         for filename in options.requirements:
             for req in parse_requirements(
                     filename,
                     options=options,
                     session=session,
                     wheel_cache=wheel_cache):
                 requirement_set.add_requirement(req)
         if not requirement_set.has_requirements:
             raise InstallationError(
                 'You must give at least one requirement to %(name)s (see '
                 '"pip help %(name)s")' % dict(name=self.name)
             )
         requirement_set.uninstall(auto_confirm=options.yes)
Example #27
0
def pip_install(name, tmpdir):
    build_dir = os.path.join(tmpdir, 'build')
    src_dir = os.path.join(tmpdir, 'src')
    download_dir = os.path.join(tmpdir, 'download')

    os.mkdir(build_dir)
    os.mkdir(src_dir)
    os.mkdir(download_dir)

    finder = PackageFinder(
        find_links=[],
        index_urls=['https://pypi.python.org/simple/'],
        use_mirrors=False,
        allow_all_external=True,
        allow_all_insecure=True,
    )

    requirement_set = RequirementSet(
        build_dir=build_dir,
        src_dir=src_dir,
        download_dir=download_dir,
        ignore_installed=True,
        ignore_dependencies=True
    )
    requirement_set.add_requirement(InstallRequirement.from_line(name, None))
    requirement_set.prepare_files(finder)

    # should be exactly one
    filename = os.listdir(download_dir)[0]
    path = os.path.join(download_dir, filename)
    return path
Example #28
0
 def test_not_find_wheel_not_supported(self):
     """
     Test not finding an unsupported wheel.
     """
     req = InstallRequirement.from_line("simple.dist")
     finder = PackageFinder([find_links], [], use_wheel=True)
     assert_raises(DistributionNotFound, finder.find_requirement, req, True)
Example #29
0
def getDependencies(name, requirementSet=None, finder=None):
    """Get dependencies of a python project
    
    @param name: name of python project
    @param requirements: RequirementSet
    @param finder: PackageFinder
    """
    if requirementSet is None:
        requirementSet = RequirementSet(
            build_dir=os.path.abspath(build_prefix),
            src_dir=os.path.abspath(src_prefix),
            download_dir=None,
            download_cache=None,
            upgrade=False,
            ignore_installed=True,
            ignore_dependencies=False)
    if finder is None:
        finder = PackageFinder(find_links=[], 
                               index_urls=['http://pypi.python.org/simple'])

    # lead pip download all dependencies
    req = InstallRequirement.from_line(name, None)
    requirementSet.add_requirement(req)
    requirementSet.install_files(finder)
    
    # trace the dependencies relationships between projects
    dependencies = []
    traceDependencys(req, requirementSet, dependencies)
    return dependencies
Example #30
0
 def test_get_dist(self):
     req = InstallRequirement.from_line('foo')
     req.egg_info_path = Mock(return_value='/path/to/foo.egg-info')
     dist = req.get_dist()
     assert isinstance(dist, pkg_resources.Distribution)
     assert dist.project_name == 'foo'
     assert dist.location == '/path/to'
Example #31
0
    def get_dependencies(self, ireq):
        if ireq.editable:
            return self.editables[str(ireq.link)]

        name, version, extras = as_tuple(ireq)
        # Store non-extra dependencies under the empty string
        extras += ("", )
        dependencies = [
            dep for extra in extras for dep in self.index[name][version][extra]
        ]
        return [
            InstallRequirement.from_line(dep, constraint=ireq.constraint)
            for dep in dependencies
        ]
Example #32
0
 def test_wheel_over_sdist_priority(self, data):
     """
     Test wheels have priority over sdists.
     `test_link_sorting` also covers this at lower level
     """
     req = InstallRequirement.from_line("priority")
     finder = PackageFinder(
         [data.find_links],
         [],
         use_wheel=True,
         session=PipSession(),
     )
     found = finder.find_requirement(req, True)
     assert found.url.endswith("priority-1.0-py2.py3-none-any.whl"), found
Example #33
0
def test_finder_ignores_external_links(data):
    """
    Tests that PackageFinder ignores external links, with or without hashes.
    """
    req = InstallRequirement.from_line("bar", None)

    # using a local index
    finder = PackageFinder(
        [],
        [data.index_url("externals")],
        session=PipSession(),
    )
    link = finder.find_requirement(req, False)
    assert link.filename == "bar-1.0.tar.gz"
Example #34
0
def test_finder_finds_external_links_without_hashes_scraped_per_project():
    """
    Tests that PackageFinder finds externally scraped links
    """
    req = InstallRequirement.from_line("bar", None)

    # using a local index
    index_url = path_to_url(os.path.join(tests_data, "indexes", "externals"))
    finder = PackageFinder([], [index_url],
                allow_external=["bar"],
                allow_insecure=["bar"],
            )
    link = finder.find_requirement(req, False)
    assert link.filename == "bar-4.0.tar.gz"
Example #35
0
 def run(self, options, args):
     requirement_set = RequirementSet(build_dir=None,
                                      src_dir=None,
                                      download_dir=None)
     for name in args:
         requirement_set.add_requirement(InstallRequirement.from_line(name))
     for filename in options.requirements:
         for req in parse_requirements(filename, options=options):
             requirement_set.add_requirement(req)
     if not requirement_set.has_requirements:
         raise InstallationError('You must give at least one requirement '
                                 'to %(name)s (see "pip help %(name)s")' %
                                 dict(name=self.name))
     requirement_set.uninstall(auto_confirm=options.yes)
Example #36
0
def test_finder_priority_page_over_deplink():
    """
    Test PackageFinder prefers page links over equivalent dependency links
    """
    req = InstallRequirement.from_line('gmpy==1.15', None)
    finder = PackageFinder(
        [],
        ["https://pypi.python.org/simple"],
        process_dependency_links=True,
        session=PipSession(),
    )
    finder.add_dependency_links(['http://c.pypi.python.org/simple/gmpy/'])
    link = finder.find_requirement(req, False)
    assert link.url.startswith("https://pypi"), link
Example #37
0
def trace_requirements(requirements):
    """given an iterable of pip InstallRequirements,
    return the set of required packages, given their transitive requirements.
    """
    requirements = tuple(pretty_req(r) for r in requirements)
    working_set = fresh_working_set()

    # breadth-first traversal:
    from collections import deque
    queue = deque(requirements)
    queued = set([req.req for req in queue])
    errors = []
    result = []
    while queue:
        req = queue.popleft()

        logger.debug('tracing: %s', req)
        try:
            dist = working_set.find(req.req)
        except pkg_resources.VersionConflict as conflict:
            dist = conflict.args[0]
            errors.append('Error: version conflict: %s (%s) <-> %s' %
                          (dist, timid_relpath(dist.location), req))

        if dist is None:
            errors.append('Error: unmet dependency: %s' % req)
            continue

        result.append(dist_to_req(dist))

        for sub_req in sorted(dist.requires(), key=lambda req: req.key):
            from pip.req import InstallRequirement
            sub_req = InstallRequirement(sub_req, req)

            if req_cycle(sub_req):
                logger.warn('Circular dependency! %s', sub_req)
                continue
            elif sub_req.req in queued:
                logger.debug('already queued: %s', sub_req)
                continue
            else:
                logger.debug('adding sub-requirement %s', sub_req)
                queue.append(sub_req)
                queued.add(sub_req.req)

    if errors:
        raise InstallationError('\n'.join(errors))

    return result
Example #38
0
def trace_requirements(requirements):
    """given an iterable of pip InstallRequirements,
    return the set of required packages, given their transitive requirements.
    """
    requirements = tuple(pretty_req(r) for r in requirements)
    working_set = fresh_working_set()

    # breadth-first traversal:
    from collections import deque
    queue = deque(requirements)
    queued = {_package_req_to_pkg_resources_req(req.req) for req in queue}
    errors = []
    result = []
    while queue:
        req = queue.popleft()

        logger.debug('tracing: %s', req)
        try:
            dist = working_set.find_normalized(
                _package_req_to_pkg_resources_req(req.req))
        except pkg_resources.VersionConflict as conflict:
            dist = conflict.args[0]
            errors.append('Error: version conflict: %s (%s) <-> %s' %
                          (dist, timid_relpath(dist.location), req))

        assert dist is not None, 'Should be unreachable in pip8+'
        result.append(dist_to_req(dist))

        # TODO: pip does no validation of extras. should we?
        extras = [extra for extra in req.extras if extra in dist.extras]
        for sub_req in sorted(dist.requires(extras=extras),
                              key=lambda req: req.key):
            sub_req = InstallRequirement(sub_req, req)

            if req_cycle(sub_req):
                logger.warning('Circular dependency! %s', sub_req)
                continue
            elif sub_req.req in queued:
                logger.debug('already queued: %s', sub_req)
                continue
            else:
                logger.debug('adding sub-requirement %s', sub_req)
                queue.append(sub_req)
                queued.add(sub_req.req)

    if errors:
        raise InstallationError('\n'.join(errors))

    return result
Example #39
0
    def test_skip_invalid_wheel_link(self, caplog, data):
        """
        Test if PackageFinder skips invalid wheel filenames
        """
        req = InstallRequirement.from_line("invalid")
        # data.find_links contains "invalid.whl", which is an invalid wheel
        finder = PackageFinder(
            [data.find_links],
            [],
            session=PipSession(),
        )
        with pytest.raises(DistributionNotFound):
            finder.find_requirement(req, True)

        assert ("invalid.whl; invalid wheel filename" in caplog.text)
Example #40
0
def test_finder_finds_external_links_without_hashes_scraped_per_project(data):
    """
    Tests that PackageFinder finds externally scraped links
    """
    req = InstallRequirement.from_line("bar", None)

    # using a local index
    finder = PackageFinder(
        [],
        [data.index_url("externals")],
        allow_external=["bar"],
        allow_unverified=["bar"],
    )
    link = finder.find_requirement(req, False)
    assert link.filename == "bar-4.0.tar.gz"
Example #41
0
 def install_egg(self, egg_name):
     """ Install an egg into the egg directory """
     if not os.path.exists(self.egg_directory):
         os.makedirs(self.egg_directory)
     self.requirement_set.add_requirement(
         InstallRequirement.from_line(egg_name, None))
     try:
         self.requirement_set.prepare_files(self.finder,
                                            force_root_egg_info=False,
                                            bundle=False)
         self.requirement_set.install(self.install_options,
                                      self.global_options)
     except DistributionNotFound:
         self.requirement_set.requirements._keys.remove(egg_name)
         raise PipException()
Example #42
0
    def test_existing_over_wheel_priority(self, data):
        """
        Test existing install has priority over wheels.
        `test_link_sorting` also covers this at a lower level
        """
        req = InstallRequirement.from_line('priority', None)
        latest_version = "1.0"
        satisfied_by = Mock(location="/path",
                            parsed_version=parse_version(latest_version),
                            version=latest_version)
        req.satisfied_by = satisfied_by
        finder = PackageFinder([data.find_links], [], use_wheel=True)

        with pytest.raises(BestVersionAlreadyInstalled):
            finder.find_requirement(req, True)
Example #43
0
def test_finder_installs_dev_releases(data):
    """
    Test PackageFinder finds dev releases if asked to.
    """

    req = InstallRequirement.from_line("bar", None)

    # using a local index (that has dev releases)
    finder = PackageFinder(
        [], [data.index_url("dev")],
        allow_all_prereleases=True,
        session=PipSession(),
    )
    link = finder.find_requirement(req, False)
    assert link.url.endswith("bar-2.0.dev1.tar.gz"), link.url
Example #44
0
def test_finder_deplink():
    """
    Test PackageFinder with dependency links only
    """
    req = InstallRequirement.from_line('gmpy==1.15', None)
    finder = PackageFinder(
        [],
        [],
        process_dependency_links=True,
        session=PipSession(),
    )
    finder.add_dependency_links(
        ['https://pypi.python.org/packages/source/g/gmpy/gmpy-1.15.zip'])
    link = finder.find_requirement(req, False)
    assert link.url.startswith("https://pypi"), link
def _requirement_finder(finder, req_str):
    """
    First try to find the given requirement. If that fails, try several
    alternatives. If they all fail, raise the first exception caught.
    """
    err = None

    for req_name in _get_package_name_alternatives(req_str):
        req = InstallRequirement(req=req_name, comes_from=None)
        try:
            return finder.find_requirement(req=req, upgrade=True)
        except DistributionNotFound as e:
            if err is None:
                err = e
    raise err
Example #46
0
def test_finder_detects_latest_already_satisfied_find_links(data):
    """Test PackageFinder detects latest already satisfied using find-links"""
    req = InstallRequirement.from_line('simple', None)
    # the latest simple in local pkgs is 3.0
    latest_version = "3.0"
    satisfied_by = Mock(
        location="/path",
        parsed_version=parse_version(latest_version),
        version=latest_version
    )
    req.satisfied_by = satisfied_by
    finder = PackageFinder([data.find_links], [], session=PipSession())

    with pytest.raises(BestVersionAlreadyInstalled):
        finder.find_requirement(req, True)
Example #47
0
def test_finder_installs_pre_releases_with_version_spec():
    """
    Test PackageFinder only accepts stable versioned releases by default.
    """
    req = InstallRequirement.from_line("bar>=0.0.dev0", None)
    links = ["https://foo/bar-1.0.tar.gz", "https://foo/bar-2.0b1.tar.gz"]

    finder = PackageFinder(links, [])
    link = finder.find_requirement(req, False)
    assert link.url == "https://foo/bar-2.0b1.tar.gz"

    links.reverse()
    finder = PackageFinder(links, [])
    link = finder.find_requirement(req, False)
    assert link.url == "https://foo/bar-2.0b1.tar.gz"
Example #48
0
def test_finder_finds_external_links_without_hashes_all_all_insecure():
    """
    Tests that PackageFinder finds external links if they do not have a hash
    using the all external flag
    """
    req = InstallRequirement.from_line("bar==3.0", None)

    # using a local index
    index_url = path_to_url(os.path.join(tests_data, "indexes", "externals"))
    finder = PackageFinder([], [index_url],
                allow_all_external=True,
                allow_all_insecure=True,
            )
    link = finder.find_requirement(req, False)
    assert link.filename == "bar-3.0.tar.gz"
Example #49
0
def get_pinned_version(ireq):
    """
    Get pinned version of a requirement, if it is pinned.

    :type ireq: InstallRequirement|str
    :type ignore_editables: bool
    """
    if not isinstance(ireq, InstallRequirement):
        ireq = InstallRequirement(ireq, None)
    assert isinstance(ireq, InstallRequirement)

    if ireq.editable:
        return None

    return get_ireq_version(ireq)
Example #50
0
    def test_no_reuse_existing_build_dir(self, data):
        """Test prepare_files raise exception with previous build dir"""

        build_dir = os.path.join(self.tempdir, 'build', 'simple')
        os.makedirs(build_dir)
        open(os.path.join(build_dir, "setup.py"), 'w')
        reqset = self.basic_reqset()
        req = InstallRequirement.from_line('simple')
        reqset.add_requirement(req)
        finder = PackageFinder([data.find_links], [])
        assert_raises_regexp(
            PreviousBuildDirError,
            "pip can't proceed with [\s\S]*%s[\s\S]*%s" %
            (req, build_dir.replace('\\', '\\\\')), reqset.prepare_files,
            finder)
Example #51
0
    def _iter_dependencies(self, ireq):
        """
        Given a pinned or editable InstallRequirement, collects all the
        secondary dependencies for them, either by looking them up in a local
        cache, or by reaching out to the repository.

        Editable requirements will never be looked up, as they may have
        changed at any time.
        """
        if ireq.editable:
            for dependency in self.repository.get_dependencies(ireq):
                yield dependency
            return
        elif ireq.markers:
            for dependency in self.repository.get_dependencies(ireq):
                dependency.prepared = False
                yield dependency
            return
        elif ireq.extras:
            for dependency in self.repository.get_dependencies(ireq):
                dependency.prepared = False
                yield dependency
            return
        elif not is_pinned_requirement(ireq):
            raise TypeError(
                'Expected pinned or editable requirement, got {}'.format(ireq))

        # Now, either get the dependencies from the dependency cache (for
        # speed), or reach out to the external repository to
        # download and inspect the package version and get dependencies
        # from there
        if ireq not in self.dependency_cache:
            log.debug('  {} not in cache, need to check index'.format(
                format_requirement(ireq)),
                      fg='yellow')
            dependencies = self.repository.get_dependencies(ireq)
            self.dependency_cache[ireq] = sorted(
                str(ireq.req) for ireq in dependencies)

        # Example: ['Werkzeug>=0.9', 'Jinja2>=2.4']
        dependency_strings = self.dependency_cache[ireq]
        log.debug('  {:25} requires {}'.format(
            format_requirement(ireq),
            ', '.join(sorted(dependency_strings, key=lambda s: s.lower()))
            or '-'))
        for dependency_string in dependency_strings:
            yield InstallRequirement.from_line(dependency_string,
                                               constraint=ireq.constraint)
Example #52
0
    def get_legacy_dependencies(self, ireq):
        """
        Given a pinned or an editable InstallRequirement, returns a set of
        dependencies (also InstallRequirements, but not necessarily pinned).
        They indicate the secondary dependencies for the given requirement.
        """

        if not (ireq.editable or is_pinned_requirement(ireq)):
            raise TypeError(
                'Expected pinned or editable InstallRequirement, got {}'.
                format(ireq))

        if ireq not in self._dependencies_cache:
            if ireq.link and not ireq.link.is_artifact:
                # No download_dir for VCS sources.  This also works around pip
                # using git-checkout-index, which gets rid of the .git dir.
                download_dir = None
            else:
                download_dir = self._download_dir
                if not os.path.isdir(download_dir):
                    os.makedirs(download_dir)
            if not os.path.isdir(self._wheel_download_dir):
                os.makedirs(self._wheel_download_dir)

            reqset = RequirementSet(
                self.build_dir,
                self.source_dir,
                download_dir=download_dir,
                wheel_download_dir=self._wheel_download_dir,
                session=self.session,
                ignore_installed=True,
                ignore_requires_python=True)

            result = reqset._prepare_file(self.finder,
                                          ireq,
                                          ignore_requires_python=True)
            if not result:
                if reqset.requires_python:
                    from pip.req.req_install import InstallRequirement

                    marker = 'python_version=="{0}"'.format(
                        reqset.requires_python.replace(' ', ''))
                    new_req = InstallRequirement.from_line('{0}; {1}'.format(
                        str(ireq.req), marker))
                    result = [new_req]

            self._dependencies_cache[ireq] = result
        return set(self._dependencies_cache[ireq])
def test_finder_finds_external_links_with_hashes_all(data):
    """
    Tests that PackageFinder finds external links but only if they have a hash
    using the all externals flag.
    """
    req = InstallRequirement.from_line("bar", None)

    # using a local index
    finder = PackageFinder(
        [],
        [data.index_url("externals")],
        allow_all_external=True,
        session=PipSession(),
    )
    link = finder.find_requirement(req, False)
    assert link.filename == "bar-2.0.tar.gz"
Example #54
0
def test_finder_priority_file_over_page(data):
    """Test PackageFinder prefers file links over equivalent page links"""
    req = InstallRequirement.from_line('gmpy==1.15', None)
    finder = PackageFinder(
        [data.find_links],
        ["http://pypi.python.org/simple"],
        session=PipSession(),
    )
    all_versions = finder._find_all_versions(req.name)
    # 1 file InstallationCandidate followed by all https ones
    assert all_versions[0].location.scheme == 'file'
    assert all(version.location.scheme == 'https'
               for version in all_versions[1:]), all_versions

    link = finder.find_requirement(req, False)
    assert link.url.startswith("file://")
def test_finder_finds_external_links_without_hashes_per_project(data):
    """
    Tests that PackageFinder finds external links if they do not have a hash
    """
    req = InstallRequirement.from_line("bar==3.0", None)

    # using a local index
    finder = PackageFinder(
        [],
        [data.index_url("externals")],
        allow_external=["bar"],
        allow_unverified=["bar"],
        session=PipSession(),
    )
    link = finder.find_requirement(req, False)
    assert link.filename == "bar-3.0.tar.gz"
Example #56
0
 def test_environment_marker_extras(self, data):
     """
     Test that the environment marker extras are used with
     non-wheel installs.
     """
     reqset = self.basic_reqset()
     req = InstallRequirement.from_editable(
         data.packages.join("LocalEnvironMarker"))
     reqset.add_requirement(req)
     finder = PackageFinder([data.find_links], [], session=PipSession())
     reqset.prepare_files(finder)
     # This is hacky but does test both case in py2 and py3
     if sys.version_info[:2] in ((2, 7), (3, 4)):
         assert reqset.has_requirement('simple')
     else:
         assert not reqset.has_requirement('simple')
Example #57
0
def test_finder_finds_external_links_without_hashes_all_all_insecure(data):
    """
    Tests that PackageFinder finds external links if they do not have a hash
    using the all external flag
    """
    req = InstallRequirement.from_line("bar==3.0", None)

    # using a local index
    finder = PackageFinder(
        [],
        [data.index_url("externals")],
        allow_all_external=True,
        allow_unverified=["bar"],
    )
    link = finder.find_requirement(req, False)
    assert link.filename == "bar-3.0.tar.gz"
Example #58
0
    def make_install_req(ver=None):
        req = Mock()
        req.project_name = test_project_name
        if ver:
            req.url = url_template % str(ver)
            req.specs = [('==', ver)]
        else:
            req.url = url_template.replace('@', '') % ''
            req.specs = []

        install_requirement = InstallRequirement(req,
                                                 None,
                                                 editable=True,
                                                 url=req.url)

        return install_requirement
Example #59
0
def trace_requirements(requirements):
    """given an iterable of pip InstallRequirements,
    return the set of required packages, given their transitive requirements.
    """
    from collections import deque
    from pip import logger
    from pip.req import InstallRequirement
    from pip._vendor import pkg_resources

    working_set = fresh_working_set()

    # breadth-first traversal:
    errors = False
    queue = deque(requirements)
    result = []
    seen_warnings = set()
    while queue:
        req = queue.popleft()
        if req.req is None:
            # a file:/// requirement
            continue

        try:
            dist = working_set.find(req.req)
        except pkg_resources.VersionConflict as conflict:
            dist = conflict.args[0]
            if req.name not in seen_warnings:
                logger.error("Error: version conflict: %s <-> %s" %
                             (dist, req))
                errors = True
                seen_warnings.add(req.name)

        if dist is None:
            logger.error('Error: unmet dependency: %s' % req)
            errors = True
            continue

        result.append(dist_to_req(dist))

        for dist_req in sorted(dist.requires(), key=lambda req: req.key):
            # there really shouldn't be any circular dependencies...
            queue.append(InstallRequirement(dist_req, str(req)))

    if errors:
        exit(1)

    return result
def test_finder_finds_external_links_without_hashes_scraped_all(data):
    """
    Tests that PackageFinder finds externally scraped links using the all
    external flag.
    """
    req = InstallRequirement.from_line("bar", None)

    # using a local index
    finder = PackageFinder(
        [],
        [data.index_url("externals")],
        allow_all_external=True,
        allow_unverified=["bar"],
        session=PipSession(),
    )
    link = finder.find_requirement(req, False)
    assert link.filename == "bar-4.0.tar.gz"