コード例 #1
0
ファイル: test_req.py プロジェクト: jaraco/pip
 def test_unexisting_path(self):
     with pytest.raises(InstallationError) as e:
         install_req_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
コード例 #2
0
ファイル: test_req.py プロジェクト: jaraco/pip
 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:
         install_req_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
コード例 #3
0
ファイル: test_req.py プロジェクト: jaraco/pip
def test_exclusive_environment_markers():
    """Make sure RequirementSet accepts several excluding env markers"""
    eq26 = install_req_from_line(
        "Django>=1.6.10,<1.7 ; python_version == '2.6'")
    eq26.is_direct = True
    ne26 = install_req_from_line(
        "Django>=1.6.10,<1.8 ; python_version != '2.6'")
    ne26.is_direct = True

    req_set = RequirementSet()
    req_set.add_requirement(eq26)
    req_set.add_requirement(ne26)
    assert req_set.has_requirement('Django')
コード例 #4
0
ファイル: test_req.py プロジェクト: jaraco/pip
    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 = install_req_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 = install_req_from_line(line)
        assert req.link.url == line, req.url
        assert req.markers is None
コード例 #5
0
ファイル: test_finder.py プロジェクト: jaraco/pip
def test_no_mpkg(data):
    """Finder skips zipfiles with "macosx10" in the name."""
    finder = PackageFinder([data.find_links], [], session=PipSession())
    req = install_req_from_line("pkgwithmpkg")
    found = finder.find_requirement(req, False)

    assert found.url.endswith("pkgwithmpkg-1.0.tar.gz"), found
コード例 #6
0
ファイル: test_finder.py プロジェクト: jaraco/pip
def test_no_partial_name_match(data):
    """Finder requires the full project name to match, not just beginning."""
    finder = PackageFinder([data.find_links], [], session=PipSession())
    req = install_req_from_line("gmpy")
    found = finder.find_requirement(req, False)

    assert found.url.endswith("gmpy-1.15.tar.gz"), found
コード例 #7
0
ファイル: test_finder.py プロジェクト: jaraco/pip
def test_finder_priority_nonegg_over_eggfragments():
    """Test PackageFinder prefers non-egg links over "#egg=" links"""
    req = install_req_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_candidates(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_candidates(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')
コード例 #8
0
ファイル: test_finder.py プロジェクト: jaraco/pip
def test_finder_only_installs_stable_releases(data):
    """
    Test PackageFinder only accepts stable versioned releases by default.
    """

    req = install_req_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"
コード例 #9
0
ファイル: test_req_file.py プロジェクト: techtonik/pip
 def test_yield_line_requirement_with_spaces_in_specifier(self):
     line = 'SomeProject >= 2'
     filename = 'filename'
     comes_from = '-r %s (line %s)' % (filename, 1)
     req = install_req_from_line(line, comes_from=comes_from)
     assert repr(list(process_line(line, filename, 1))[0]) == repr(req)
     assert str(req.req.specifier) == '>=2'
コード例 #10
0
ファイル: test_req.py プロジェクト: jaraco/pip
 def test_get_dist(self, path):
     req = install_req_from_line('foo')
     req._egg_info_path = path
     dist = req.get_dist()
     assert isinstance(dist, pkg_resources.Distribution)
     assert dist.project_name == 'foo'
     assert dist.location == '/path/to'.replace('/', os.path.sep)
コード例 #11
0
ファイル: test_req.py プロジェクト: jaraco/pip
 def test_extras_for_line_url_requirement(self):
     line = 'git+https://url#egg=SomeProject[ex1,ex2]'
     filename = 'filename'
     comes_from = '-r %s (line %s)' % (filename, 1)
     req = install_req_from_line(line, comes_from=comes_from)
     assert len(req.extras) == 2
     assert req.extras == {'ex1', 'ex2'}
コード例 #12
0
    def run(self, options, args):
        with self._build_session(options) as session:
            reqs_to_uninstall = {}
            for name in args:
                req = install_req_from_line(
                    name, isolated=options.isolated_mode,
                )
                if req.name:
                    reqs_to_uninstall[canonicalize_name(req.name)] = req
            for filename in options.requirements:
                for req in parse_requirements(
                        filename,
                        options=options,
                        session=session):
                    if req.name:
                        reqs_to_uninstall[canonicalize_name(req.name)] = req
            if not reqs_to_uninstall:
                raise InstallationError(
                    'You must give at least one requirement to %(name)s (see '
                    '"pip help %(name)s")' % dict(name=self.name)
                )

            protect_pip_from_modification_on_windows(
                modifying_pip="pip" in reqs_to_uninstall
            )

            for req in reqs_to_uninstall.values():
                uninstall_pathset = req.uninstall(
                    auto_confirm=options.yes, verbose=self.verbosity > 0,
                )
                if uninstall_pathset:
                    uninstall_pathset.commit()
コード例 #13
0
ファイル: test_finder.py プロジェクト: jaraco/pip
def test_tilde():
    """Finder can accept a path with ~ in it and will normalize it."""
    session = PipSession()
    with patch('pip._internal.index.os.path.exists', return_value=True):
        finder = PackageFinder(['~/python-pkgs'], [], session=session)
    req = install_req_from_line("gmpy")
    with pytest.raises(DistributionNotFound):
        finder.find_requirement(req, False)
コード例 #14
0
ファイル: test_finder.py プロジェクト: jaraco/pip
def test_get_index_urls_locations():
    """Check that the canonical name is on all indexes"""
    finder = PackageFinder(
        [], ['file://index1/', 'file://index2'], session=PipSession())
    locations = finder._get_index_urls_locations(
        install_req_from_line('Complex_Name').name)
    assert locations == ['file://index1/complex-name/',
                         'file://index2/complex-name/']
コード例 #15
0
ファイル: test_req_file.py プロジェクト: techtonik/pip
 def test_yield_line_constraint(self):
     line = 'SomeProject'
     filename = 'filename'
     comes_from = '-c %s (line %s)' % (filename, 1)
     req = install_req_from_line(
         line, comes_from=comes_from, constraint=True)
     found_req = list(process_line(line, filename, 1, constraint=True))[0]
     assert repr(found_req) == repr(req)
     assert found_req.constraint is True
コード例 #16
0
    def populate_requirement_set(requirement_set, args, options, finder,
                                 session, name, wheel_cache):
        """
        Marshal cmd line args into a requirement set.
        """
        # NOTE: As a side-effect, options.require_hashes and
        #       requirement_set.require_hashes may be updated

        for filename in options.constraints:
            for req_to_add in parse_requirements(
                    filename,
                    constraint=True, finder=finder, options=options,
                    session=session, wheel_cache=wheel_cache):
                req_to_add.is_direct = True
                requirement_set.add_requirement(req_to_add)

        for req in args:
            req_to_add = install_req_from_line(
                req, None, isolated=options.isolated_mode,
                wheel_cache=wheel_cache
            )
            req_to_add.is_direct = True
            requirement_set.add_requirement(req_to_add)

        for req in options.editables:
            req_to_add = install_req_from_editable(
                req,
                isolated=options.isolated_mode,
                wheel_cache=wheel_cache
            )
            req_to_add.is_direct = True
            requirement_set.add_requirement(req_to_add)

        for filename in options.requirements:
            for req_to_add in parse_requirements(
                    filename,
                    finder=finder, options=options, session=session,
                    wheel_cache=wheel_cache):
                req_to_add.is_direct = True
                requirement_set.add_requirement(req_to_add)
        # 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 options.requirements):
            opts = {'name': name}
            if options.find_links:
                raise CommandError(
                    '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:
                raise CommandError(
                    'You must give at least one requirement to %(name)s '
                    '(see "pip help %(name)s")' % opts)
コード例 #17
0
ファイル: test_req.py プロジェクト: jaraco/pip
    def test_unsupported_wheel_link_requirement_raises(self):
        reqset = RequirementSet()
        req = install_req_from_line(
            'https://whatever.com/peppercorn-0.4-py2.py3-bogus-any.whl',
        )
        assert req.link is not None
        assert req.link.is_wheel
        assert req.link.scheme == "https"

        with pytest.raises(InstallationError):
            reqset.add_requirement(req)
コード例 #18
0
ファイル: test_req.py プロジェクト: jaraco/pip
    def test_unsupported_wheel_local_file_requirement_raises(self, data):
        reqset = RequirementSet()
        req = install_req_from_line(
            data.packages.join('simple.dist-0.1-py1-none-invalid.whl'),
        )
        assert req.link is not None
        assert req.link.is_wheel
        assert req.link.scheme == "file"

        with pytest.raises(InstallationError):
            reqset.add_requirement(req)
コード例 #19
0
ファイル: test_req.py プロジェクト: jaraco/pip
    def test_markers_match(self):
        # match
        for markers in (
            'python_version >= "1.0"',
            'sys_platform == %r' % sys.platform,
        ):
            line = 'name; ' + markers
            req = install_req_from_line(line, comes_from='')
            assert str(req.markers) == str(Marker(markers))
            assert req.match_markers()

        # don't match
        for markers in (
            'python_version >= "5.0"',
            'sys_platform != %r' % sys.platform,
        ):
            line = 'name; ' + markers
            req = install_req_from_line(line, comes_from='')
            assert str(req.markers) == str(Marker(markers))
            assert not req.match_markers()
コード例 #20
0
ファイル: test_finder.py プロジェクト: jaraco/pip
def test_duplicates_sort_ok(data):
    """Finder successfully finds one of a set of duplicates in different
    locations"""
    finder = PackageFinder(
        [data.find_links, data.find_links2],
        [],
        session=PipSession(),
    )
    req = install_req_from_line("duplicate")
    found = finder.find_requirement(req, False)

    assert found.url.endswith("duplicate-1.0.tar.gz"), found
コード例 #21
0
ファイル: test_req_file.py プロジェクト: techtonik/pip
    def test_nested_constraints_file(self, monkeypatch):
        line = '-c another_file'
        req = install_req_from_line('SomeProject')
        import pip._internal.req.req_file

        def stub_parse_requirements(req_url, finder, comes_from, options,
                                    session, wheel_cache, constraint):
            return [(req, constraint)]
        parse_requirements_stub = stub(call=stub_parse_requirements)
        monkeypatch.setattr(pip._internal.req.req_file, 'parse_requirements',
                            parse_requirements_stub.call)
        assert list(process_line(line, 'filename', 1)) == [(req, True)]
コード例 #22
0
ファイル: test_finder.py プロジェクト: jaraco/pip
 def test_wheel_over_sdist_priority(self, data):
     """
     Test wheels have priority over sdists.
     `test_link_sorting` also covers this at lower level
     """
     req = install_req_from_line("priority")
     finder = PackageFinder(
         [data.find_links],
         [],
         session=PipSession(),
     )
     found = finder.find_requirement(req, True)
     assert found.url.endswith("priority-1.0-py2.py3-none-any.whl"), found
コード例 #23
0
ファイル: test_req.py プロジェクト: jaraco/pip
 def test_markers(self):
     for line in (
         # recommended syntax
         'mock3; python_version >= "3"',
         # with more spaces
         'mock3 ; python_version >= "3" ',
         # without spaces
         'mock3;python_version >= "3"',
     ):
         req = install_req_from_line(line)
         assert req.req.name == 'mock3'
         assert str(req.req.specifier) == ''
         assert str(req.markers) == 'python_version >= "3"'
コード例 #24
0
ファイル: test_req_install.py プロジェクト: akaihola/pip
    def test_forward_slash_results_in_a_link(self, tmpdir):
        install_dir = tmpdir / "foo" / "bar"

        # Just create a file for letting the logic work
        setup_py_path = install_dir / "setup.py"
        os.makedirs(str(install_dir))
        with open(setup_py_path, 'w') as f:
            f.write('')

        requirement = install_req_from_line(
            str(install_dir).replace(os.sep, os.altsep or os.sep)
        )

        assert requirement.link is not None
コード例 #25
0
ファイル: test_finder.py プロジェクト: jaraco/pip
def test_finder_installs_dev_releases(data):
    """
    Test PackageFinder finds dev releases if asked to.
    """

    req = install_req_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
コード例 #26
0
ファイル: test_finder.py プロジェクト: jaraco/pip
def test_finder_detects_latest_already_satisfied_find_links(data):
    """Test PackageFinder detects latest already satisfied using find-links"""
    req = install_req_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)
コード例 #27
0
ファイル: test_finder.py プロジェクト: jaraco/pip
def test_finder_priority_file_over_page(data):
    """Test PackageFinder prefers file links over equivalent page links"""
    req = install_req_from_line('gmpy==1.15', None)
    finder = PackageFinder(
        [data.find_links],
        ["http://pypi.org/simple/"],
        session=PipSession(),
    )
    all_versions = finder.find_all_candidates(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://")
コード例 #28
0
ファイル: test_finder.py プロジェクト: jaraco/pip
def test_finder_deplink():
    """
    Test PackageFinder with dependency links only
    """
    req = install_req_from_line('gmpy==1.15', None)
    finder = PackageFinder(
        [],
        [],
        process_dependency_links=True,
        session=PipSession(),
    )
    finder.add_dependency_links(
        ['https://files.pythonhosted.org/packages/source/g/gmpy/gmpy-1.15.zip']
    )
    link = finder.find_requirement(req, False)
    assert link.url.startswith("https://files.pythonhosted.org/"), link
コード例 #29
0
ファイル: test_finder.py プロジェクト: jaraco/pip
def test_finder_installs_pre_releases_with_version_spec():
    """
    Test PackageFinder only accepts stable versioned releases by default.
    """
    req = install_req_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, [], session=PipSession())

    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, [], session=PipSession())

    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"
コード例 #30
0
ファイル: test_finder.py プロジェクト: jaraco/pip
def test_finder_detects_latest_already_satisfied_pypi_links():
    """Test PackageFinder detects latest already satisfied using pypi links"""
    req = install_req_from_line('initools', None)
    # the latest initools on PyPI is 0.3.1
    latest_version = "0.3.1"
    satisfied_by = Mock(
        location="/path",
        parsed_version=parse_version(latest_version),
        version=latest_version,
    )
    req.satisfied_by = satisfied_by
    finder = PackageFinder(
        [],
        ["http://pypi.org/simple/"],
        session=PipSession(),
    )

    with pytest.raises(BestVersionAlreadyInstalled):
        finder.find_requirement(req, True)
コード例 #31
0
def bootstrap(tmpdir=None):
    # Import pip so we can use it to install pip and maybe setuptools too
    from pip._internal.cli.main import main as pip_entry_point
    from pip._internal.commands.install import InstallCommand
    from pip._internal.req.constructors import install_req_from_line

    # Wrapper to provide default certificate with the lowest priority
    # Due to pip._internal.commands.commands_dict structure, a monkeypatch
    # seems the simplest workaround.
    install_parse_args = InstallCommand.parse_args

    def cert_parse_args(self, args):
        # If cert isn't specified in config or environment, we provide our
        # own certificate through defaults.
        # This allows user to specify custom cert anywhere one likes:
        # config, environment variable or argv.
        if not self.parser.get_default_values().cert:
            self.parser.defaults["cert"] = cert_path  # calculated below
        return install_parse_args(self, args)

    InstallCommand.parse_args = cert_parse_args

    implicit_pip = True
    implicit_setuptools = True
    implicit_wheel = True

    # Check if the user has requested us not to install setuptools
    if "--no-setuptools" in sys.argv or os.environ.get("PIP_NO_SETUPTOOLS"):
        args = [x for x in sys.argv[1:] if x != "--no-setuptools"]
        implicit_setuptools = False
    else:
        args = sys.argv[1:]

    # Check if the user has requested us not to install wheel
    if "--no-wheel" in args or os.environ.get("PIP_NO_WHEEL"):
        args = [x for x in args if x != "--no-wheel"]
        implicit_wheel = False

    # We only want to implicitly install setuptools and wheel if they don't
    # already exist on the target platform.
    if implicit_setuptools:
        try:
            import setuptools  # noqa
            implicit_setuptools = False
        except ImportError:
            pass
    if implicit_wheel:
        try:
            import wheel  # noqa
            implicit_wheel = False
        except ImportError:
            pass

    # We want to support people passing things like 'pip<8' to get-pip.py which
    # will let them install a specific version. However because of the dreaded
    # DoubleRequirement error if any of the args look like they might be a
    # specific for one of our packages, then we'll turn off the implicit
    # install of them.
    for arg in args:
        try:
            req = install_req_from_line(arg)
        except Exception:
            continue

        if implicit_pip and req.name == "pip":
            implicit_pip = False
        elif implicit_setuptools and req.name == "setuptools":
            implicit_setuptools = False
        elif implicit_wheel and req.name == "wheel":
            implicit_wheel = False

    # Add any implicit installations to the end of our args
    if implicit_pip:
        args += ["pip{pip_version}"]
    if implicit_setuptools:
        args += ["setuptools{setuptools_version}"]
    if implicit_wheel:
        args += ["wheel{wheel_version}"]

    # Add our default arguments
    args = ["install", "--upgrade", "--force-reinstall"] + args

    delete_tmpdir = False
    try:
        # Create a temporary directory to act as a working directory if we were
        # not given one.
        if tmpdir is None:
            tmpdir = tempfile.mkdtemp()
            delete_tmpdir = True

        # We need to extract the SSL certificates from requests so that they
        # can be passed to --cert
        cert_path = os.path.join(tmpdir, "cacert.pem")
        with open(cert_path, "wb") as cert:
            cert.write(pkgutil.get_data("pip._vendor.certifi", "cacert.pem"))

        # Execute the included pip and use it to install the latest pip and
        # setuptools from PyPI
        sys.exit(pip_entry_point(args))
    finally:
        # Remove our temporary directory
        if delete_tmpdir and tmpdir:
            shutil.rmtree(tmpdir, ignore_errors=True)
コード例 #32
0
ファイル: test_req.py プロジェクト: wai123999/pip
 def test_url_preserved_line_req(self):
     """Confirm the url is preserved in a non-editable requirement"""
     url = 'git+http://foo.com@ref#egg=foo'
     req = install_req_from_line(url)
     assert req.link.url == url
コード例 #33
0
def test_finder_detects_latest_find_links(data):
    """Test PackageFinder detects latest using find-links"""
    req = install_req_from_line('simple', None)
    finder = PackageFinder([data.find_links], [], session=PipSession())
    link = finder.find_requirement(req, False)
    assert link.url.endswith("simple-3.0.tar.gz")
コード例 #34
0
def freeze(requirement=None,
           find_links=None,
           local_only=None,
           user_only=None,
           skip_regex=None,
           isolated=False,
           wheel_cache=None,
           exclude_editable=False,
           skip=()):
    find_links = find_links or []
    skip_match = None

    if skip_regex:
        skip_match = re.compile(skip_regex).search

    dependency_links = []

    for dist in pkg_resources.working_set:
        if dist.has_metadata('dependency_links.txt'):
            dependency_links.extend(
                dist.get_metadata_lines('dependency_links.txt'))
    for link in find_links:
        if '#egg=' in link:
            dependency_links.append(link)
    for link in find_links:
        yield '-f %s' % link
    installations = {}
    for dist in get_installed_distributions(local_only=local_only,
                                            skip=(),
                                            user_only=user_only):
        try:
            req = FrozenRequirement.from_dist(dist, dependency_links)
        except RequirementParseError:
            logger.warning("Could not parse requirement: %s",
                           dist.project_name)
            continue
        if exclude_editable and req.editable:
            continue
        installations[req.name] = req

    if requirement:
        # the options that don't get turned into an InstallRequirement
        # should only be emitted once, even if the same option is in multiple
        # requirements files, so we need to keep track of what has been emitted
        # so that we don't emit it again if it's seen again
        emitted_options = set()
        # keep track of which files a requirement is in so that we can
        # give an accurate warning if a requirement appears multiple times.
        req_files = collections.defaultdict(list)
        for req_file_path in requirement:
            with open(req_file_path) as req_file:
                for line in req_file:
                    if (not line.strip() or line.strip().startswith('#')
                            or (skip_match and skip_match(line))
                            or line.startswith(
                                ('-r', '--requirement', '-Z', '--always-unzip',
                                 '-f', '--find-links', '-i', '--index-url',
                                 '--pre', '--trusted-host',
                                 '--process-dependency-links',
                                 '--extra-index-url'))):
                        line = line.rstrip()
                        if line not in emitted_options:
                            emitted_options.add(line)
                            yield line
                        continue

                    if line.startswith('-e') or line.startswith('--editable'):
                        if line.startswith('-e'):
                            line = line[2:].strip()
                        else:
                            line = line[len('--editable'):].strip().lstrip('=')
                        line_req = install_req_from_editable(
                            line,
                            isolated=isolated,
                            wheel_cache=wheel_cache,
                        )
                    else:
                        line_req = install_req_from_line(
                            COMMENT_RE.sub('', line).strip(),
                            isolated=isolated,
                            wheel_cache=wheel_cache,
                        )

                    if not line_req.name:
                        logger.info(
                            "Skipping line in requirement file [%s] because "
                            "it's not clear what it would install: %s",
                            req_file_path,
                            line.strip(),
                        )
                        logger.info(
                            "  (add #egg=PackageName to the URL to avoid"
                            " this warning)")
                    elif line_req.name not in installations:
                        # either it's not installed, or it is installed
                        # but has been processed already
                        if not req_files[line_req.name]:
                            logger.warning(
                                "Requirement file [%s] contains %s, but that "
                                "package is not installed",
                                req_file_path,
                                COMMENT_RE.sub('', line).strip(),
                            )
                        else:
                            req_files[line_req.name].append(req_file_path)
                    else:
                        yield str(installations[line_req.name]).rstrip()
                        del installations[line_req.name]
                        req_files[line_req.name].append(req_file_path)

        # Warn about requirements that were included multiple times (in a
        # single requirements file or in different requirements files).
        for name, files in six.iteritems(req_files):
            if len(files) > 1:
                logger.warning("Requirement %s included multiple times [%s]",
                               name, ', '.join(sorted(set(files))))

        yield ('## The following requirements were added by ' 'pip freeze:')
    for installation in sorted(installations.values(),
                               key=lambda x: x.name.lower()):
        if canonicalize_name(installation.name) not in skip:
            yield str(installation).rstrip()
コード例 #35
0
ファイル: freeze.py プロジェクト: Kanyandula/BlogPost
def freeze(
    requirement: Optional[List[str]] = None,
    local_only: bool = False,
    user_only: bool = False,
    paths: Optional[List[str]] = None,
    isolated: bool = False,
    exclude_editable: bool = False,
    skip: Container[str] = (),
) -> Generator[str, None, None]:
    installations: Dict[str, FrozenRequirement] = {}

    dists = get_environment(paths).iter_installed_distributions(
        local_only=local_only,
        skip=(),
        user_only=user_only,
    )
    for dist in dists:
        req = FrozenRequirement.from_dist(dist)
        if exclude_editable and req.editable:
            continue
        installations[req.canonical_name] = req

    if requirement:
        # the options that don't get turned into an InstallRequirement
        # should only be emitted once, even if the same option is in multiple
        # requirements files, so we need to keep track of what has been emitted
        # so that we don't emit it again if it's seen again
        emitted_options: Set[str] = set()
        # keep track of which files a requirement is in so that we can
        # give an accurate warning if a requirement appears multiple times.
        req_files: Dict[str, List[str]] = collections.defaultdict(list)
        for req_file_path in requirement:
            with open(req_file_path) as req_file:
                for line in req_file:
                    if (
                        not line.strip()
                        or line.strip().startswith("#")
                        or line.startswith(
                            (
                                "-r",
                                "--requirement",
                                "-f",
                                "--find-links",
                                "-i",
                                "--index-url",
                                "--pre",
                                "--trusted-host",
                                "--process-dependency-links",
                                "--extra-index-url",
                                "--use-feature",
                            )
                        )
                    ):
                        line = line.rstrip()
                        if line not in emitted_options:
                            emitted_options.add(line)
                            yield line
                        continue

                    if line.startswith("-e") or line.startswith("--editable"):
                        if line.startswith("-e"):
                            line = line[2:].strip()
                        else:
                            line = line[len("--editable") :].strip().lstrip("=")
                        line_req = install_req_from_editable(
                            line,
                            isolated=isolated,
                        )
                    else:
                        line_req = install_req_from_line(
                            COMMENT_RE.sub("", line).strip(),
                            isolated=isolated,
                        )

                    if not line_req.name:
                        logger.info(
                            "Skipping line in requirement file [%s] because "
                            "it's not clear what it would install: %s",
                            req_file_path,
                            line.strip(),
                        )
                        logger.info(
                            "  (add #egg=PackageName to the URL to avoid"
                            " this warning)"
                        )
                    else:
                        line_req_canonical_name = canonicalize_name(line_req.name)
                        if line_req_canonical_name not in installations:
                            # either it's not installed, or it is installed
                            # but has been processed already
                            if not req_files[line_req.name]:
                                logger.warning(
                                    "Requirement file [%s] contains %s, but "
                                    "package %r is not installed",
                                    req_file_path,
                                    COMMENT_RE.sub("", line).strip(),
                                    line_req.name,
                                )
                            else:
                                req_files[line_req.name].append(req_file_path)
                        else:
                            yield str(installations[line_req_canonical_name]).rstrip()
                            del installations[line_req_canonical_name]
                            req_files[line_req.name].append(req_file_path)

        # Warn about requirements that were included multiple times (in a
        # single requirements file or in different requirements files).
        for name, files in req_files.items():
            if len(files) > 1:
                logger.warning(
                    "Requirement %s included multiple times [%s]",
                    name,
                    ", ".join(sorted(set(files))),
                )

        yield ("## The following requirements were added by pip freeze:")
    for installation in sorted(installations.values(), key=lambda x: x.name.lower()):
        if installation.canonical_name not in skip:
            yield str(installation).rstrip()
コード例 #36
0
ファイル: test_req.py プロジェクト: wai123999/pip
 def test_repr(self):
     req = install_req_from_line('simple==0.1')
     assert repr(req) == (
         '<InstallRequirement object: simple==0.1 editable=False>')
コード例 #37
0
ファイル: test_req_file.py プロジェクト: vharsh/pip
 def test_yield_pep440_line_requirement(self):
     line = 'SomeProject @ https://url/SomeProject-py2-py3-none-any.whl'
     filename = 'filename'
     comes_from = '-r %s (line %s)' % (filename, 1)
     req = install_req_from_line(line, comes_from=comes_from)
     assert repr(list(process_line(line, filename, 1))[0]) == repr(req)
コード例 #38
0
ファイル: test_req.py プロジェクト: wai123999/pip
 def test_single_equal_sign(self):
     with pytest.raises(InstallationError) as e:
         install_req_from_line('toto=42')
     err_msg = e.value.args[0]
     assert "Invalid requirement" in err_msg
     assert "= is not a valid operator. Did you mean == ?" in err_msg
コード例 #39
0
ファイル: test_req_file.py プロジェクト: ysora/pip
 def test_yield_pep440_line_requirement(self, line_processor):
     line = 'SomeProject @ https://url/SomeProject-py2-py3-none-any.whl'
     filename = 'filename'
     comes_from = '-r {} (line {})'.format(filename, 1)
     req = install_req_from_line(line, comes_from=comes_from)
     assert repr(line_processor(line, filename, 1)[0]) == repr(req)
コード例 #40
0
ファイル: req_command.py プロジェクト: realxwx/leetcode-solve
    def populate_requirement_set(
            self,
            requirement_set,  # type: RequirementSet
            args,  # type: List[str]
            options,  # type: Values
            finder,  # type: PackageFinder
            session,  # type: PipSession
            wheel_cache,  # type: Optional[WheelCache]
    ):
        # type: (...) -> None
        """
        Marshal cmd line args into a requirement set.
        """
        for filename in options.constraints:
            for req_to_add in parse_requirements(filename,
                                                 constraint=True,
                                                 finder=finder,
                                                 options=options,
                                                 session=session,
                                                 wheel_cache=wheel_cache):
                req_to_add.is_direct = True
                requirement_set.add_requirement(req_to_add)

        for req in args:
            req_to_add = install_req_from_line(req,
                                               None,
                                               isolated=options.isolated_mode,
                                               use_pep517=options.use_pep517,
                                               wheel_cache=wheel_cache)
            req_to_add.is_direct = True
            requirement_set.add_requirement(req_to_add)

        for req in options.editables:
            req_to_add = install_req_from_editable(
                req,
                isolated=options.isolated_mode,
                use_pep517=options.use_pep517,
                wheel_cache=wheel_cache)
            req_to_add.is_direct = True
            requirement_set.add_requirement(req_to_add)

        # NOTE: options.require_hashes may be set if --require-hashes is True
        for filename in options.requirements:
            for req_to_add in parse_requirements(
                    filename,
                    finder=finder,
                    options=options,
                    session=session,
                    wheel_cache=wheel_cache,
                    use_pep517=options.use_pep517):
                req_to_add.is_direct = True
                requirement_set.add_requirement(req_to_add)

        # If any requirement has hash options, enable hash checking.
        requirements = (requirement_set.unnamed_requirements +
                        list(requirement_set.requirements.values()))
        if any(req.has_hash_options for req in requirements):
            options.require_hashes = True

        if not (args or options.editables or options.requirements):
            opts = {'name': self.name}
            if options.find_links:
                raise CommandError(
                    '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:
                raise CommandError(
                    'You must give at least one requirement to %(name)s '
                    '(see "pip help %(name)s")' % opts)
コード例 #41
0
 def test_yield_line_requirement(self):
     line = 'SomeProject'
     filename = 'filename'
     comes_from = '-r %s (line %s)' % (filename, 1)
     req = install_req_from_line(line, comes_from=comes_from)
     assert repr(list(process_line(line, filename, 1))[0]) == repr(req)
コード例 #42
0
ファイル: base_command.py プロジェクト: tysonclugg/pip
    def populate_requirement_set(
            requirement_set,  # type: RequirementSet
            args,  # type: List[str]
            options,  # type: Values
            finder,  # type: PackageFinder
            session,  # type: PipSession
            name,  # type: str
            wheel_cache  # type: Optional[WheelCache]
    ):
        # type: (...) -> None
        """
        Marshal cmd line args into a requirement set.
        """
        # NOTE: As a side-effect, options.require_hashes and
        #       requirement_set.require_hashes may be updated

        for filename in options.constraints:
            for req_to_add in parse_requirements(filename,
                                                 constraint=True,
                                                 finder=finder,
                                                 options=options,
                                                 session=session,
                                                 wheel_cache=wheel_cache):
                req_to_add.is_direct = True
                requirement_set.add_requirement(req_to_add)

        for req in args:
            req_to_add = install_req_from_line(req,
                                               None,
                                               isolated=options.isolated_mode,
                                               use_pep517=options.use_pep517,
                                               wheel_cache=wheel_cache)
            req_to_add.is_direct = True
            requirement_set.add_requirement(req_to_add)

        for req in options.editables:
            req_to_add = install_req_from_editable(
                req,
                isolated=options.isolated_mode,
                use_pep517=options.use_pep517,
                wheel_cache=wheel_cache)
            req_to_add.is_direct = True
            requirement_set.add_requirement(req_to_add)

        for filename in options.requirements:
            for req_to_add in parse_requirements(
                    filename,
                    finder=finder,
                    options=options,
                    session=session,
                    wheel_cache=wheel_cache,
                    use_pep517=options.use_pep517):
                req_to_add.is_direct = True
                requirement_set.add_requirement(req_to_add)
        # 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 options.requirements):
            opts = {'name': name}
            if options.find_links:
                raise CommandError(
                    '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:
                raise CommandError(
                    'You must give at least one requirement to %(name)s '
                    '(see "pip help %(name)s")' % opts)
コード例 #43
0
def cli(
    ctx,
    verbose,
    quiet,
    dry_run,
    pre,
    rebuild,
    find_links,
    index_url,
    extra_index_url,
    cert,
    client_cert,
    trusted_host,
    header,
    index,
    emit_trusted_host,
    annotate,
    upgrade,
    upgrade_packages,
    output_file,
    allow_unsafe,
    generate_hashes,
    src_files,
    max_rounds,
    build_isolation,
    emit_find_links,
    cache_dir,
):
    """Compiles requirements.txt from requirements.in specs."""
    log.verbosity = verbose - quiet

    if len(src_files) == 0:
        if os.path.exists(DEFAULT_REQUIREMENTS_FILE):
            src_files = (DEFAULT_REQUIREMENTS_FILE, )
        elif os.path.exists("setup.py"):
            src_files = ("setup.py", )
        else:
            raise click.BadParameter(("If you do not specify an input file, "
                                      "the default is {} or setup.py"
                                      ).format(DEFAULT_REQUIREMENTS_FILE))

    if not output_file:
        # An output file must be provided for stdin
        if src_files == ("-", ):
            raise click.BadParameter(
                "--output-file is required if input is from stdin")
        # Use default requirements output file if there is a setup.py the source file
        elif src_files == ("setup.py", ):
            file_name = DEFAULT_REQUIREMENTS_OUTPUT_FILE
        # An output file must be provided if there are multiple source files
        elif len(src_files) > 1:
            raise click.BadParameter(
                "--output-file is required if two or more input files are given."
            )
        # Otherwise derive the output file from the source file
        else:
            base_name = src_files[0].rsplit(".", 1)[0]
            file_name = base_name + ".txt"

        output_file = click.open_file(file_name, "w+b", atomic=True, lazy=True)

        # Close the file at the end of the context execution
        ctx.call_on_close(safecall(output_file.close_intelligently))

    ###
    # Setup
    ###

    pip_args = []
    if find_links:
        for link in find_links:
            pip_args.extend(["-f", link])
    if index_url:
        pip_args.extend(["-i", index_url])
    if extra_index_url:
        for extra_index in extra_index_url:
            pip_args.extend(["--extra-index-url", extra_index])
    if cert:
        pip_args.extend(["--cert", cert])
    if client_cert:
        pip_args.extend(["--client-cert", client_cert])
    if pre:
        pip_args.extend(["--pre"])
    if trusted_host:
        for host in trusted_host:
            pip_args.extend(["--trusted-host", host])

    repository = PyPIRepository(pip_args,
                                build_isolation=build_isolation,
                                cache_dir=cache_dir)

    # Parse all constraints coming from --upgrade-package/-P
    upgrade_reqs_gen = (install_req_from_line(pkg) for pkg in upgrade_packages)
    upgrade_install_reqs = {
        key_from_ireq(install_req): install_req
        for install_req in upgrade_reqs_gen
    }

    existing_pins_to_upgrade = set()

    # Proxy with a LocalRequirementsRepository if --upgrade is not specified
    # (= default invocation)
    if not upgrade and os.path.exists(output_file.name):
        # Use a temporary repository to ensure outdated(removed) options from
        # existing requirements.txt wouldn't get into the current repository.
        tmp_repository = PyPIRepository(pip_args,
                                        build_isolation=build_isolation,
                                        cache_dir=cache_dir)
        ireqs = parse_requirements(
            output_file.name,
            finder=tmp_repository.finder,
            session=tmp_repository.session,
            options=tmp_repository.options,
        )

        # Exclude packages from --upgrade-package/-P from the existing
        # constraints, and separately gather pins to be upgraded
        existing_pins = {}
        for ireq in filter(is_pinned_requirement, ireqs):
            key = key_from_ireq(ireq)
            if key in upgrade_install_reqs:
                existing_pins_to_upgrade.add(key)
            else:
                existing_pins[key] = ireq
        repository = LocalRequirementsRepository(existing_pins, repository)

    ###
    # Parsing/collecting initial requirements
    ###

    constraints = []
    for src_file in src_files:
        is_setup_file = os.path.basename(src_file) == "setup.py"
        if is_setup_file or src_file == "-":
            # pip requires filenames and not files. Since we want to support
            # piping from stdin, we need to briefly save the input from stdin
            # to a temporary file and have pip read that.  also used for
            # reading requirements from install_requires in setup.py.
            tmpfile = tempfile.NamedTemporaryFile(mode="wt", delete=False)
            if is_setup_file:
                from distutils.core import run_setup

                dist = run_setup(src_file)
                tmpfile.write("\n".join(dist.install_requires))
                comes_from = "{name} ({filename})".format(name=dist.get_name(),
                                                          filename=src_file)
            else:
                tmpfile.write(sys.stdin.read())
                comes_from = "-r -"
            tmpfile.flush()
            reqs = list(
                parse_requirements(
                    tmpfile.name,
                    finder=repository.finder,
                    session=repository.session,
                    options=repository.options,
                ))
            for req in reqs:
                req.comes_from = comes_from
            constraints.extend(reqs)
        else:
            constraints.extend(
                parse_requirements(
                    src_file,
                    finder=repository.finder,
                    session=repository.session,
                    options=repository.options,
                ))

    primary_packages = {
        key_from_ireq(ireq)
        for ireq in constraints if not ireq.constraint
    }

    allowed_upgrades = primary_packages | existing_pins_to_upgrade
    constraints.extend(ireq for key, ireq in upgrade_install_reqs.items()
                       if key in allowed_upgrades)

    # Filter out pip environment markers which do not match (PEP496)
    constraints = [
        req for req in constraints
        if req.markers is None or req.markers.evaluate()
    ]

    log.debug("Using indexes:")
    for index_url in dedup(repository.finder.index_urls):
        log.debug("  {}".format(index_url))

    if repository.finder.find_links:
        log.debug("")
        log.debug("Configuration:")
        for find_link in dedup(repository.finder.find_links):
            log.debug("  -f {}".format(find_link))

    try:
        resolver = Resolver(
            constraints,
            repository,
            prereleases=repository.finder.allow_all_prereleases or pre,
            cache=DependencyCache(cache_dir),
            clear_caches=rebuild,
            allow_unsafe=allow_unsafe,
        )
        results = resolver.resolve(max_rounds=max_rounds)
        if generate_hashes:
            hashes = resolver.resolve_hashes(results)
        else:
            hashes = None
    except PipToolsError as e:
        log.error(str(e))
        sys.exit(2)

    log.debug("")

    ##
    # Output
    ##

    writer = OutputWriter(
        src_files,
        output_file,
        click_ctx=ctx,
        dry_run=dry_run,
        emit_header=header,
        emit_index=index,
        emit_trusted_host=emit_trusted_host,
        annotate=annotate,
        generate_hashes=generate_hashes,
        default_index_url=repository.DEFAULT_INDEX_URL,
        index_urls=repository.finder.index_urls,
        trusted_hosts=repository.finder.trusted_hosts,
        format_control=repository.finder.format_control,
        allow_unsafe=allow_unsafe,
        find_links=repository.finder.find_links,
        emit_find_links=emit_find_links,
    )
    writer.write(
        results=results,
        unsafe_requirements=resolver.unsafe_constraints,
        markers={
            key_from_ireq(ireq): ireq.markers
            for ireq in constraints if ireq.markers
        },
        hashes=hashes,
    )

    if dry_run:
        log.info("Dry-run, so nothing updated.")
コード例 #44
0
ファイル: test_req.py プロジェクト: wai123999/pip
 def test_unidentifiable_name(self):
     test_name = '-'
     with pytest.raises(InstallationError) as e:
         install_req_from_line(test_name)
     err_msg = e.value.args[0]
     assert f"Invalid requirement: '{test_name}'" == err_msg
コード例 #45
0
ファイル: test_req.py プロジェクト: wai123999/pip
 def test_wheel_requirement_sets_req_attribute(self):
     req = install_req_from_line('simple-0.1-py2.py3-none-any.whl')
     assert isinstance(req.req, Requirement)
     assert str(req.req) == 'simple==0.1'
コード例 #46
0
ファイル: test_req.py プロジェクト: wai123999/pip
 def test_url_with_query(self):
     """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 = install_req_from_line(url + fragment)
     assert req.link.url == url + fragment, req.link
コード例 #47
0
ファイル: test_req_file.py プロジェクト: ysora/pip
 def test_yield_line_requirement(self, line_processor):
     line = 'SomeProject'
     filename = 'filename'
     comes_from = '-r {} (line {})'.format(filename, 1)
     req = install_req_from_line(line, comes_from=comes_from)
     assert repr(line_processor(line, filename, 1)[0]) == repr(req)
コード例 #48
0
ファイル: req_command.py プロジェクト: AndrewChuma/hw1
    def get_requirements(
        self,
        args,  # type: List[str]
        options,  # type: Values
        finder,  # type: PackageFinder
        session,  # type: PipSession
    ):
        # type: (...) -> List[InstallRequirement]
        """
        Parse command-line arguments into the corresponding requirements.
        """
        requirements = []  # type: List[InstallRequirement]
        for filename in options.constraints:
            for parsed_req in parse_requirements(
                filename,
                constraint=True,
                finder=finder,
                options=options,
                session=session,
            ):
                req_to_add = install_req_from_parsed_requirement(
                    parsed_req, isolated=options.isolated_mode, user_supplied=False
                )
                requirements.append(req_to_add)

        for req in args:
            req_to_add = install_req_from_line(
                req,
                None,
                isolated=options.isolated_mode,
                use_pep517=options.use_pep517,
                user_supplied=True,
            )
            requirements.append(req_to_add)

        for req in options.editables:
            req_to_add = install_req_from_editable(
                req,
                user_supplied=True,
                isolated=options.isolated_mode,
                use_pep517=options.use_pep517,
            )
            requirements.append(req_to_add)

        # NOTE: options.require_hashes may be set if --require-hashes is True
        for filename in options.requirements:
            for parsed_req in parse_requirements(
                filename, finder=finder, options=options, session=session
            ):
                req_to_add = install_req_from_parsed_requirement(
                    parsed_req,
                    isolated=options.isolated_mode,
                    use_pep517=options.use_pep517,
                    user_supplied=True,
                )
                requirements.append(req_to_add)

        # If any requirement has hash options, enable hash checking.
        if any(req.has_hash_options for req in requirements):
            options.require_hashes = True

        if not (args or options.editables or options.requirements):
            opts = {"name": self.name}
            if options.find_links:
                raise CommandError(
                    "You must give at least one requirement to {name} "
                    '(maybe you meant "pip {name} {links}"?)'.format(
                        **dict(opts, links=" ".join(options.find_links))
                    )
                )
            else:
                raise CommandError(
                    "You must give at least one requirement to {name} "
                    '(see "pip help {name}")'.format(**opts)
                )

        return requirements
コード例 #49
0
ファイル: test_req.py プロジェクト: wai123999/pip
 def test_invalid_wheel_requirement_raises(self):
     with pytest.raises(InvalidWheelFilename):
         install_req_from_line('invalid.whl')
コード例 #50
0
ファイル: test_req.py プロジェクト: vigneshragul/pip
 def test_traceback(self):
     with pytest.raises(InstallationError) as e:
         install_req_from_line('toto 42')
     err_msg = e.value.args[0]
     assert "Invalid requirement" in err_msg
     assert "\nTraceback " in err_msg
コード例 #51
0
ファイル: test_req.py プロジェクト: wai123999/pip
 def test_str(self):
     req = install_req_from_line('simple==0.1')
     assert str(req) == 'simple==0.1'
コード例 #52
0
ファイル: req_file.py プロジェクト: xuhdev/pip
def handle_line(
        line,  # type: ParsedLine
        finder=None,  # type: Optional[PackageFinder]
        options=None,  # type: Optional[optparse.Values]
        session=None,  # type: Optional[PipSession]
        wheel_cache=None,  # type: Optional[WheelCache]
        use_pep517=None,  # type: Optional[bool]
):
    # type: (...) -> Optional[InstallRequirement]
    """Handle a single parsed requirements line; This can result in
    creating/yielding requirements, or updating the finder.

    For lines that contain requirements, the only options that have an effect
    are from SUPPORTED_OPTIONS_REQ, and they are scoped to the
    requirement. Other options from SUPPORTED_OPTIONS may be present, but are
    ignored.

    For lines that do not contain requirements, the only options that have an
    effect are from SUPPORTED_OPTIONS. Options from SUPPORTED_OPTIONS_REQ may
    be present, but are ignored. These lines may contain multiple options
    (although our docs imply only one is supported), and all our parsed and
    affect the finder.
    """

    # preserve for the nested code path
    line_comes_from = '%s %s (line %s)' % (
        '-c' if line.constraint else '-r',
        line.filename,
        line.lineno,
    )

    # return a line requirement
    if line.args:
        isolated = options.isolated_mode if options else False
        if options:
            cmdoptions.check_install_build_global(options, line.opts)
        # get the options that apply to requirements
        req_options = {}
        for dest in SUPPORTED_OPTIONS_REQ_DEST:
            if dest in line.opts.__dict__ and line.opts.__dict__[dest]:
                req_options[dest] = line.opts.__dict__[dest]
        line_source = 'line {} of {}'.format(line.lineno, line.filename)
        return install_req_from_line(
            line.args,
            comes_from=line_comes_from,
            use_pep517=use_pep517,
            isolated=isolated,
            options=req_options,
            wheel_cache=wheel_cache,
            constraint=line.constraint,
            line_source=line_source,
        )

    # return an editable requirement
    elif line.opts.editables:
        isolated = options.isolated_mode if options else False
        return install_req_from_editable(line.opts.editables[0],
                                         comes_from=line_comes_from,
                                         use_pep517=use_pep517,
                                         constraint=line.constraint,
                                         isolated=isolated,
                                         wheel_cache=wheel_cache)

    # percolate hash-checking option upward
    elif line.opts.require_hashes:
        options.require_hashes = line.opts.require_hashes

    # set finder options
    elif finder:
        find_links = finder.find_links
        index_urls = finder.index_urls
        if line.opts.index_url:
            index_urls = [line.opts.index_url]
        if line.opts.no_index is True:
            index_urls = []
        if line.opts.extra_index_urls:
            index_urls.extend(line.opts.extra_index_urls)
        if line.opts.find_links:
            # FIXME: it would be nice to keep track of the source
            # of the find_links: support a find-links local path
            # relative to a requirements file.
            value = line.opts.find_links[0]
            req_dir = os.path.dirname(os.path.abspath(line.filename))
            relative_to_reqs_file = os.path.join(req_dir, value)
            if os.path.exists(relative_to_reqs_file):
                value = relative_to_reqs_file
            find_links.append(value)

        search_scope = SearchScope(
            find_links=find_links,
            index_urls=index_urls,
        )
        finder.search_scope = search_scope

        if line.opts.pre:
            finder.set_allow_all_prereleases()

        if session:
            for host in line.opts.trusted_hosts or []:
                source = 'line {} of {}'.format(line.lineno, line.filename)
                session.add_trusted_host(host, source=source)

    return None
コード例 #53
0
ファイル: test_req.py プロジェクト: wai123999/pip
 def test_installed_version_not_installed(self):
     req = install_req_from_line('simple-0.1-py2.py3-none-any.whl')
     assert req.installed_version is None
コード例 #54
0
ファイル: test_req.py プロジェクト: wai123999/pip
 def test_markers_semicolon(self):
     # check that the markers can contain a semicolon
     req = install_req_from_line('semicolon; os_name == "a; b"')
     assert req.req.name == 'semicolon'
     assert str(req.req.specifier) == ''
     assert str(req.markers) == 'os_name == "a; b"'
コード例 #55
0
def process_line(
        line,  # type: Text
        filename,  # type: str
        line_number,  # type: int
        finder=None,  # type: Optional[PackageFinder]
        comes_from=None,  # type: Optional[str]
        options=None,  # type: Optional[optparse.Values]
        session=None,  # type: Optional[PipSession]
        wheel_cache=None,  # type: Optional[WheelCache]
        use_pep517=None,  # type: Optional[bool]
        constraint=False  # type: bool
):
    # type: (...) -> Iterator[InstallRequirement]
    """Process a single requirements line; This can result in creating/yielding
    requirements, or updating the finder.

    For lines that contain requirements, the only options that have an effect
    are from SUPPORTED_OPTIONS_REQ, and they are scoped to the
    requirement. Other options from SUPPORTED_OPTIONS may be present, but are
    ignored.

    For lines that do not contain requirements, the only options that have an
    effect are from SUPPORTED_OPTIONS. Options from SUPPORTED_OPTIONS_REQ may
    be present, but are ignored. These lines may contain multiple options
    (although our docs imply only one is supported), and all our parsed and
    affect the finder.

    :param constraint: If True, parsing a constraints file.
    :param options: OptionParser options that we may update
    """
    parser = build_parser(line)
    defaults = parser.get_default_values()
    defaults.index_url = None
    if finder:
        defaults.format_control = finder.format_control
    args_str, options_str = break_args_options(line)
    # Prior to 2.7.3, shlex cannot deal with unicode entries
    if sys.version_info < (2, 7, 3):
        # https://github.com/python/mypy/issues/1174
        options_str = options_str.encode('utf8')  # type: ignore
    # https://github.com/python/mypy/issues/1174
    opts, _ = parser.parse_args(shlex.split(options_str),
                                defaults)  # type: ignore

    # preserve for the nested code path
    line_comes_from = '%s %s (line %s)' % (
        '-c' if constraint else '-r',
        filename,
        line_number,
    )

    # yield a line requirement
    if args_str:
        isolated = options.isolated_mode if options else False
        if options:
            cmdoptions.check_install_build_global(options, opts)
        # get the options that apply to requirements
        req_options = {}
        for dest in SUPPORTED_OPTIONS_REQ_DEST:
            if dest in opts.__dict__ and opts.__dict__[dest]:
                req_options[dest] = opts.__dict__[dest]
        yield install_req_from_line(args_str,
                                    line_comes_from,
                                    constraint=constraint,
                                    use_pep517=use_pep517,
                                    isolated=isolated,
                                    options=req_options,
                                    wheel_cache=wheel_cache)

    # yield an editable requirement
    elif opts.editables:
        isolated = options.isolated_mode if options else False
        yield install_req_from_editable(opts.editables[0],
                                        comes_from=line_comes_from,
                                        use_pep517=use_pep517,
                                        constraint=constraint,
                                        isolated=isolated,
                                        wheel_cache=wheel_cache)

    # parse a nested requirements file
    elif opts.requirements or opts.constraints:
        if opts.requirements:
            req_path = opts.requirements[0]
            nested_constraint = False
        else:
            req_path = opts.constraints[0]
            nested_constraint = True
        # original file is over http
        if SCHEME_RE.search(filename):
            # do a url join so relative paths work
            req_path = urllib_parse.urljoin(filename, req_path)
        # original file and nested file are paths
        elif not SCHEME_RE.search(req_path):
            # do a join so relative paths work
            req_path = os.path.join(os.path.dirname(filename), req_path)
        # TODO: Why not use `comes_from='-r {} (line {})'` here as well?
        parsed_reqs = parse_requirements(req_path,
                                         finder,
                                         comes_from,
                                         options,
                                         session,
                                         constraint=nested_constraint,
                                         wheel_cache=wheel_cache)
        for req in parsed_reqs:
            yield req

    # percolate hash-checking option upward
    elif opts.require_hashes:
        options.require_hashes = opts.require_hashes

    # set finder options
    elif finder:
        if opts.index_url:
            finder.index_urls = [opts.index_url]
        if opts.no_index is True:
            finder.index_urls = []
        if opts.extra_index_urls:
            finder.index_urls.extend(opts.extra_index_urls)
        if opts.find_links:
            # FIXME: it would be nice to keep track of the source
            # of the find_links: support a find-links local path
            # relative to a requirements file.
            value = opts.find_links[0]
            req_dir = os.path.dirname(os.path.abspath(filename))
            relative_to_reqs_file = os.path.join(req_dir, value)
            if os.path.exists(relative_to_reqs_file):
                value = relative_to_reqs_file
            finder.find_links.append(value)
        if opts.pre:
            finder.allow_all_prereleases = True
        if opts.trusted_hosts:
            finder.secure_origins.extend(
                ("*", host, "*") for host in opts.trusted_hosts)
コード例 #56
0
    def get_requirements(
            self,
            args,  # type: List[str]
            options,  # type: Values
            finder,  # type: PackageFinder
            session,  # type: PipSession
            wheel_cache,  # type: Optional[WheelCache]
            check_supported_wheels=True,  # type: bool
    ):
        # type: (...) -> List[InstallRequirement]
        """
        Parse command-line arguments into the corresponding requirements.
        """
        requirement_set = RequirementSet(
            check_supported_wheels=check_supported_wheels)
        for filename in options.constraints:
            for req_to_add in parse_requirements(filename,
                                                 constraint=True,
                                                 finder=finder,
                                                 options=options,
                                                 session=session,
                                                 wheel_cache=wheel_cache):
                req_to_add.is_direct = True
                requirement_set.add_requirement(req_to_add)

        for req in args:
            req_to_add = install_req_from_line(req,
                                               None,
                                               isolated=options.isolated_mode,
                                               use_pep517=options.use_pep517,
                                               wheel_cache=wheel_cache)
            req_to_add.is_direct = True
            requirement_set.add_requirement(req_to_add)

        for req in options.editables:
            req_to_add = install_req_from_editable(
                req,
                isolated=options.isolated_mode,
                use_pep517=options.use_pep517,
                wheel_cache=wheel_cache)
            req_to_add.is_direct = True
            requirement_set.add_requirement(req_to_add)

        # NOTE: options.require_hashes may be set if --require-hashes is True
        for filename in options.requirements:
            for req_to_add in parse_requirements(
                    filename,
                    finder=finder,
                    options=options,
                    session=session,
                    wheel_cache=wheel_cache,
                    use_pep517=options.use_pep517):
                req_to_add.is_direct = True
                requirement_set.add_requirement(req_to_add)

        # If any requirement has hash options, enable hash checking.
        requirements = requirement_set.all_requirements
        if any(req.has_hash_options for req in requirements):
            options.require_hashes = True

        if not (args or options.editables or options.requirements):
            opts = {'name': self.name}
            if options.find_links:
                raise CommandError(
                    '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:
                raise CommandError(
                    'You must give at least one requirement to %(name)s '
                    '(see "pip help %(name)s")' % opts)

        return requirements
コード例 #57
0
def test_incorrect_case_file_index(data):
    """Test PackageFinder detects latest using wrong case"""
    req = install_req_from_line('dinner', None)
    finder = PackageFinder([], [data.find_links3], session=PipSession())
    link = finder.find_requirement(req, False)
    assert link.url.endswith("Dinner-2.0.tar.gz")
コード例 #58
0
ファイル: test_finder.py プロジェクト: cjc7373/pip
def test_incorrect_case_file_index(data):
    """Test PackageFinder detects latest using wrong case"""
    req = install_req_from_line('dinner', None)
    finder = make_test_finder(index_urls=[data.find_links3])
    found = finder.find_requirement(req, False)
    assert found.link.url.endswith("Dinner-2.0.tar.gz")
コード例 #59
0
ファイル: freeze.py プロジェクト: SteveMHill/phenocube-py
def freeze(
    requirement=None,  # type: Optional[List[str]]
    find_links=None,  # type: Optional[List[str]]
    local_only=None,  # type: Optional[bool]
    user_only=None,  # type: Optional[bool]
    paths=None,  # type: Optional[List[str]]
    isolated=False,  # type: bool
    wheel_cache=None,  # type: Optional[WheelCache]
    exclude_editable=False,  # type: bool
    skip=(),  # type: Container[str]
):
    # type: (...) -> Iterator[str]
    find_links = find_links or []

    for link in find_links:
        yield "-f {}".format(link)
    installations = {}  # type: Dict[str, FrozenRequirement]
    for dist in get_installed_distributions(
        local_only=local_only, skip=(), user_only=user_only, paths=paths
    ):
        try:
            req = FrozenRequirement.from_dist(dist)
        except RequirementParseError as exc:
            # We include dist rather than dist.project_name because the
            # dist string includes more information, like the version and
            # location. We also include the exception message to aid
            # troubleshooting.
            logger.warning(
                "Could not generate requirement for distribution %r: %s", dist, exc
            )
            continue
        if exclude_editable and req.editable:
            continue
        installations[req.canonical_name] = req

    if requirement:
        # the options that don't get turned into an InstallRequirement
        # should only be emitted once, even if the same option is in multiple
        # requirements files, so we need to keep track of what has been emitted
        # so that we don't emit it again if it's seen again
        emitted_options = set()  # type: Set[str]
        # keep track of which files a requirement is in so that we can
        # give an accurate warning if a requirement appears multiple times.
        req_files = collections.defaultdict(list)  # type: Dict[str, List[str]]
        for req_file_path in requirement:
            with open(req_file_path) as req_file:
                for line in req_file:
                    if (
                        not line.strip()
                        or line.strip().startswith("#")
                        or line.startswith(
                            (
                                "-r",
                                "--requirement",
                                "-Z",
                                "--always-unzip",
                                "-f",
                                "--find-links",
                                "-i",
                                "--index-url",
                                "--pre",
                                "--trusted-host",
                                "--process-dependency-links",
                                "--extra-index-url",
                            )
                        )
                    ):
                        line = line.rstrip()
                        if line not in emitted_options:
                            emitted_options.add(line)
                            yield line
                        continue

                    if line.startswith("-e") or line.startswith("--editable"):
                        if line.startswith("-e"):
                            line = line[2:].strip()
                        else:
                            line = line[len("--editable") :].strip().lstrip("=")
                        line_req = install_req_from_editable(
                            line,
                            isolated=isolated,
                        )
                    else:
                        line_req = install_req_from_line(
                            COMMENT_RE.sub("", line).strip(),
                            isolated=isolated,
                        )

                    if not line_req.name:
                        logger.info(
                            "Skipping line in requirement file [%s] because "
                            "it's not clear what it would install: %s",
                            req_file_path,
                            line.strip(),
                        )
                        logger.info(
                            "  (add #egg=PackageName to the URL to avoid"
                            " this warning)"
                        )
                    else:
                        line_req_canonical_name = canonicalize_name(line_req.name)
                        if line_req_canonical_name not in installations:
                            # either it's not installed, or it is installed
                            # but has been processed already
                            if not req_files[line_req.name]:
                                logger.warning(
                                    "Requirement file [%s] contains %s, but "
                                    "package %r is not installed",
                                    req_file_path,
                                    COMMENT_RE.sub("", line).strip(),
                                    line_req.name,
                                )
                            else:
                                req_files[line_req.name].append(req_file_path)
                        else:
                            yield str(installations[line_req_canonical_name]).rstrip()
                            del installations[line_req_canonical_name]
                            req_files[line_req.name].append(req_file_path)

        # Warn about requirements that were included multiple times (in a
        # single requirements file or in different requirements files).
        for name, files in six.iteritems(req_files):
            if len(files) > 1:
                logger.warning(
                    "Requirement %s included multiple times [%s]",
                    name,
                    ", ".join(sorted(set(files))),
                )

        yield ("## The following requirements were added by " "pip freeze:")
    for installation in sorted(installations.values(), key=lambda x: x.name.lower()):
        if installation.canonical_name not in skip:
            yield str(installation).rstrip()
コード例 #60
0
ファイル: test_finder.py プロジェクト: cjc7373/pip
def test_finder_detects_latest_find_links(data):
    """Test PackageFinder detects latest using find-links"""
    req = install_req_from_line('simple', None)
    finder = make_test_finder(find_links=[data.find_links])
    found = finder.find_requirement(req, False)
    assert found.link.url.endswith("simple-3.0.tar.gz")