Example #1
0
def add_to_requirements_lockfile(reqs, filename):
    # click.echo("Adding module to requirements")

    new_reqs = []
    for req in reqs:
        if req.editable:
            install_req = InstallRequirement.from_editable(
                req.line.replace("-e ", ""))
        else:
            install_req = InstallRequirement.from_line(req.line)
        new_reqs.append(install_req)

    with open(filename + ".tmp", "w") as file:
        # click.echo(file.name)
        for package in new_reqs:
            # click.echo("Adding package {0}".format(package))
            if package.name not in IGNORED_PACKAGES:
                if package.link is not None:
                    package_string = ('-e {0}'.format(package.link) if
                                      package.editable else str(package.link))
                    # project.add_package_to_pipfile(package_string)
                    # requirements.append(package_string)
                    file.write(package_string + "\n")
                else:
                    file.write(str(package.req) + "\n")
                    # requirements.append(packa)
        file.close()
        # project.recase_pipfile()

    os.remove(filename)
    os.rename(filename + ".tmp", filename)
    return
Example #2
0
def add_to_requirements_file(req, filename):
    # click.echo("Adding module to requirements")
    old_reqs = [r for r in parse_requirements(filename, session='')]

    if req.editable:
        install_req = InstallRequirement.from_editable(
            req.line.replace("-e ", ""))
    else:
        install_req = InstallRequirement.from_line(req.line)

    reqs = []
    replaced = False
    for old_req in old_reqs:
        # click.echo(old_req)
        if old_req.name.lower() == install_req.name.lower():
            replaced = True
            reqs.append(install_req)
            # click.echo(install_req)
        else:
            reqs.append(old_req)
            # click.echo(old_req)

    if not replaced:
        reqs.append(install_req)

    if not replaced:
        reqs.append(install_req)

    # requirements = []

    # click.echo("List of requirements: {0}".format(reqs))

    with open(filename + ".tmp", "w") as file:
        # click.echo(file.name)
        for package in reqs:
            # click.echo("Adding package {0}".format(package))
            if package.name not in IGNORED_PACKAGES:
                if package.link is not None:
                    package_string = ('-e {0}'.format(package.link) if
                                      package.editable else str(package.link))
                    # project.add_package_to_pipfile(package_string)
                    # requirements.append(package_string)
                    file.write(package_string + "\n")
                else:
                    file.write(str(package.req) + "\n")
                    # requirements.append(packa)
        file.close()
        # project.recase_pipfile()

    os.remove(filename)
    os.rename(filename + ".tmp", filename)
    return
Example #3
0
def test_update_with_new_packages(mocker):
    sub = mocker.patch('subprocess.check_output')
    resolve = mocker.patch('piptools.resolver.Resolver.resolve')
    get_hashes = mocker.patch('piptools.resolver.Resolver.resolve_hashes')
    reverse_dependencies = mocker.patch('piptools.resolver.Resolver.reverse_dependencies')
    reverse_dependencies.return_value = {'requests': set()}
    write_lock = mocker.patch('poet.installer.Installer._write_lock')
    pendulum_req = InstallRequirement.from_line('pendulum==1.3.0')
    pytest_req = InstallRequirement.from_line('pytest==3.5.0')
    requests_req = InstallRequirement.from_line('requests==2.13.0')
    resolve.return_value = [
        pendulum_req,
        pytest_req,
        requests_req
    ]
    get_hashes.return_value = {
        pendulum_req: set([
            "sha256:a97e3ed9557ac0c5c3742f21fa4d852d7a050dd9b1b517e993aebef2dd2eea52",
            "sha256:641140a05f959b37a177866e263f6f53a53b711fae6355336ee832ec1a59da8a"
        ]),
        pytest_req: set([
            "sha256:66f332ae62593b874a648b10a8cb106bfdacd2c6288ed7dec3713c3a808a6017",
            "sha256:b70696ebd1a5e6b627e7e3ac1365a4bc60aaf3495e843c1e70448966c5224cab"
        ]),
        requests_req: set([
            "sha256:5722cd09762faa01276230270ff16af7acf7c5c45d623868d9ba116f15791ce8",
            "sha256:1a720e8862a41aa22e339373b526f508ef0c8988baf48b84d3fc891a8e237efb"
        ])
    }
    app = Application()
    app.add(UpdateCommand())

    command = app.find('update')
    command_tester = CommandTester(command)
    command_tester.execute([('command', command.name), ('--no-progress', True)])

    assert sub.call_count == 3
    write_lock.assert_called_once()

    output = command_tester.get_display()
    expected = """
Updating dependencies

 - Resolving dependencies
 - Summary: 2 updates, 1 installations
 - Updating pendulum (1.2.0 -> 1.3.0)
 - Updating pytest (3.0.7 -> 3.5.0)
 - Installing requests (2.13.0)
"""

    assert output == expected
Example #4
0
 def test_tmp_build_directory(self):
     # when req is None, we can produce a temporary directory
     # Make sure we're handling it correctly with real path.
     requirement = InstallRequirement(None, None)
     tmp_dir = tempfile.mkdtemp('-build', 'pip-')
     tmp_build_dir = requirement.build_location(tmp_dir)
     assert (os.path.dirname(tmp_build_dir) == os.path.realpath(
         os.path.dirname(tmp_dir)))
     # are we on a system where /tmp is a symlink
     if os.path.realpath(tmp_dir) != os.path.abspath(tmp_dir):
         assert os.path.dirname(tmp_build_dir) != os.path.dirname(tmp_dir)
     else:
         assert os.path.dirname(tmp_build_dir) == os.path.dirname(tmp_dir)
     os.rmdir(tmp_dir)
     assert not os.path.exists(tmp_dir)
Example #5
0
 def test_yield_line_requirement_with_spaces_in_specifier(self):
     line = 'SomeProject >= 2'
     filename = 'filename'
     comes_from = '-r %s (line %s)' % (filename, 1)
     req = InstallRequirement.from_line(line, comes_from=comes_from)
     assert repr(list(process_line(line, filename, 1))[0]) == repr(req)
     assert str(req.req.specifier) == '>=2'
    def _pip_compile(*args):
        """
        Performs pip-compile (from piptools) with a twist.

        We force editable requirements to use GIT repository (parameter obtain=True) so we have setuptools_scm working on
        them (axado.runner uses setuptools_scm).
        """
        from contextlib import contextmanager

        @contextmanager
        def replaced_argv(args):
            import sys
            argv = sys.argv
            sys.argv = [''] + list(args)
            yield
            sys.argv = argv

        from pip.req.req_install import InstallRequirement
        try:
            InstallRequirement.update_editable_
        except AttributeError:
            InstallRequirement.update_editable_ = InstallRequirement.update_editable
            InstallRequirement.update_editable = lambda s, _o: InstallRequirement.update_editable_(
                s, True)

        with replaced_argv(args):
            from piptools.scripts.compile import cli
            try:
                cli()
            except SystemExit as e:
                return e.code
Example #7
0
 def test_yield_editable_requirement(self):
     url = 'git+https://url#egg=SomeProject'
     line = '-e %s' % url
     filename = 'filename'
     comes_from = '-r %s (line %s)' % (filename, 1)
     req = InstallRequirement.from_editable(url, comes_from=comes_from)
     assert repr(list(process_line(line, filename, 1))[0]) == repr(req)
Example #8
0
 def test_yield_editable_requirement(self):
     url = 'git+https://url#egg=SomeProject'
     line = '-e %s' % url
     filename = 'filename'
     comes_from = '-r %s (line %s)' % (filename, 1)
     req = InstallRequirement.from_editable(url, comes_from=comes_from)
     assert repr(list(process_line(line, filename, 1))[0]) == repr(req)
    def compile(self,
                dst_file,
                src_files,
                upgrade=False,
                rebuild=False,
                new_code=False):
        """
        Performs pip-compile (from piptools) with a twist.

        We force editable requirements to use GIT repository (parameter obtain=True) so we have setuptools_scm working on
        them (we use setuptools_scm). Not sure this is working with piptools 2.X.
        """
        from pip.req.req_install import InstallRequirement

        try:
            InstallRequirement.update_editable_
        except AttributeError:
            InstallRequirement.update_editable_ = InstallRequirement.update_editable
            InstallRequirement.update_editable = lambda s, _o: InstallRequirement.update_editable_(
                s, True)

        from piptools.scripts.compile import cli
        return self.__click_context.invoke(
            cli,
            output_file=dst_file,
            src_files=src_files,
            upgrade=upgrade,
            rebuild=rebuild,
            emit_trusted_host=False,
            header=False,
            index=False,
        )
Example #10
0
 def test_yield_line_requirement_with_spaces_in_specifier(self):
     line = 'SomeProject >= 2'
     filename = 'filename'
     comes_from = '-r %s (line %s)' % (filename, 1)
     req = InstallRequirement.from_line(line, comes_from=comes_from)
     assert repr(list(process_line(line, filename, 1))[0]) == repr(req)
     assert req.req.specs == [('>=', '2')]
Example #11
0
def test_install_default(mocker, check_output):
    resolve = mocker.patch('piptools.resolver.Resolver.resolve')
    reverse_dependencies = mocker.patch(
        'piptools.resolver.Resolver.reverse_dependencies')
    resolve.return_value = [InstallRequirement.from_line('pendulum==1.2.0')]
    reverse_dependencies.return_value = {}
    app = Application()
    app.add(InstallCommand())

    command = app.find('install')
    command_tester = CommandTester(command)
    command_tester.execute([('command', command.name),
                            ('--no-progress', True)])

    assert os.path.exists(DUMMY_LOCK)
    os.remove(DUMMY_LOCK)

    check_output.assert_called_once()

    output = command_tester.get_display()
    expected = """
Locking dependencies to poetry.lock

 - Resolving dependencies
 - Writing dependencies

Installing dependencies

 - Installing pendulum (1.2.0)
"""

    assert output == expected
Example #12
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[0] == 'ex1'
     assert req.extras[1] == 'ex2'
Example #13
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[0] == 'ex1'
     assert req.extras[1] == 'ex2'
Example #14
0
 def add_req(subreq):
     sub_install_req = InstallRequirement(
         str(subreq),
         req_to_install,
         isolated=self.isolated,
     )
     more_reqs.extend(
         self.add_requirement(sub_install_req, req_to_install.name))
Example #15
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[0] == 'ex1'
     assert req.extras[1] == 'ex2'
Example #16
0
 def test_tmp_build_directory(self):
     # when req is None, we can produce a temporary directory
     # Make sure we're handling it correctly with real path.
     requirement = InstallRequirement(None, None)
     tmp_dir = tempfile.mkdtemp('-build', 'pip-')
     tmp_build_dir = requirement.build_location(tmp_dir)
     assert (
         os.path.dirname(tmp_build_dir) ==
         os.path.realpath(os.path.dirname(tmp_dir))
     )
     # are we on a system where /tmp is a symlink
     if os.path.realpath(tmp_dir) != os.path.abspath(tmp_dir):
         assert os.path.dirname(tmp_build_dir) != os.path.dirname(tmp_dir)
     else:
         assert os.path.dirname(tmp_build_dir) == os.path.dirname(tmp_dir)
     os.rmdir(tmp_dir)
     assert not os.path.exists(tmp_dir)
Example #17
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[0] == 'ex1'
     assert req.extras[1] == '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[0] == 'ex1'
     assert req.extras[1] == 'ex2'
Example #19
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[0] == 'ex1'
     assert req.extras[1] == 'ex2'
Example #20
0
def requirement_install(self, config, install_options, *args, **kwargs):
    '''
    Package installation method wrapper that applies custom install options if
    provided
    '''
    if config:
        install_options = config.get('install_options', install_options)
    return InstallRequirement.install(self, install_options, *args, **kwargs)
Example #21
0
def requirement_install(self, config, install_options, *args, **kwargs):
    '''
    Package installation method wrapper that applies custom install options if
    provided
    '''
    if config:
        install_options = config.get('install_options', install_options)
    return InstallRequirement.install(self, install_options, *args, **kwargs)
Example #22
0
 def test_yield_line_constraint(self):
     line = 'SomeProject'
     filename = 'filename'
     comes_from = '-c %s (line %s)' % (filename, 1)
     req = InstallRequirement.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
Example #23
0
def test_update_only_update(mocker):
    sub = mocker.patch('subprocess.check_output')
    resolve = mocker.patch('piptools.resolver.Resolver.resolve')
    get_hashes = mocker.patch('piptools.resolver.Resolver.resolve_hashes')
    reverse_dependencies = mocker.patch('piptools.resolver.Resolver.reverse_dependencies')
    reverse_dependencies.return_value = {}
    write_lock = mocker.patch('poet.installer.Installer._write_lock')
    pendulum_req = InstallRequirement.from_line('pendulum==1.3.0')
    pytest_req = InstallRequirement.from_line('pytest==3.5.0')
    resolve.return_value = [
        pendulum_req,
        pytest_req
    ]
    get_hashes.return_value = {
        pendulum_req: set([
            "sha256:a97e3ed9557ac0c5c3742f21fa4d852d7a050dd9b1b517e993aebef2dd2eea52",
            "sha256:641140a05f959b37a177866e263f6f53a53b711fae6355336ee832ec1a59da8a"
        ]),
        pytest_req: set([
            "sha256:66f332ae62593b874a648b10a8cb106bfdacd2c6288ed7dec3713c3a808a6017",
            "sha256:b70696ebd1a5e6b627e7e3ac1365a4bc60aaf3495e843c1e70448966c5224cab"
        ])
    }
    app = Application()
    app.add(UpdateCommand())

    command = app.find('update')
    command_tester = CommandTester(command)
    command_tester.execute([('command', command.name), ('--no-progress', True)])

    assert sub.call_count == 2
    write_lock.assert_called_once()

    output = command_tester.get_display()
    expected = """
Updating dependencies

 - Resolving dependencies
 - Summary: 2 updates
 - Updating pendulum (1.2.0 -> 1.3.0)
 - Updating pytest (3.0.7 -> 3.5.0)
"""

    assert output == expected
Example #24
0
 def add_req(subreq, extras_requested):
     sub_install_req = InstallRequirement(
         str(subreq),
         req_to_install,
         isolated=self.isolated,
         wheel_cache=self._wheel_cache,
     )
     more_reqs.extend(self.add_requirement(
         sub_install_req, req_to_install.name,
         extras_requested=extras_requested))
Example #25
0
 def test_yield_editable_constraint(self):
     url = 'git+https://url#egg=SomeProject'
     line = '-e %s' % url
     filename = 'filename'
     comes_from = '-c %s (line %s)' % (filename, 1)
     req = InstallRequirement.from_editable(
         url, 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
Example #26
0
 def add_req(subreq, extras_requested):
     sub_install_req = InstallRequirement.from_req(
         str(subreq),
         req_to_install,
         isolated=self.isolated,
         wheel_cache=self._wheel_cache,
     )
     more_reqs.extend(self.add_requirement(
         sub_install_req, req_to_install.name,
         extras_requested=extras_requested))
Example #27
0
    def test_nested_constraints_file(self, monkeypatch):
        line = '-c another_file'
        req = InstallRequirement.from_line('SomeProject')
        import pip.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.req.req_file, 'parse_requirements',
                            parse_requirements_stub.call)
        assert list(process_line(line, 'filename', 1)) == [(req, True)]
Example #28
0
    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 = InstallRequirement.from_line(
            str(install_dir).replace(os.sep, os.altsep or os.sep)
        )

        assert requirement.link is not None
Example #29
0
def get_link(dist_name, index_url=DEFAULT_INDEX):
    req = pkg_resources.Requirement.parse(dist_name)
    install_req = InstallRequirement(req=req, comes_from=None)
    with PipSession(retries=5) as session:
        finder = pip.index.PackageFinder(find_links=(),
                                         index_urls=[index_url],
                                         session=session)
        result = finder.find_requirement(install_req, upgrade=True)
    url, sep, checksum = result.url.partition('#')
    assert url == result.url_without_fragment
    data = {
        'url': url,
        'checksum': checksum or None,  # hashtype=srchash
    }
    return data
Example #30
0
    def _install_build_reqs(self, reqs, prefix):
        # Local import to avoid circular import (wheel <-> req_install)
        from pip.req.req_install import InstallRequirement
        from pip.index import FormatControl
        # Ignore the --no-binary option when installing the build system, so
        # we don't recurse trying to build a self-hosting build system.
        finder = copy.copy(self.finder)
        finder.format_control = FormatControl(set(), set())
        urls = [finder.find_requirement(InstallRequirement.from_line(r),
                                        upgrade=False).url
                for r in reqs]

        args = [sys.executable, '-m', 'pip', 'install', '--ignore-installed',
                '--prefix', prefix] + list(urls)
        with open_spinner("Installing build dependencies") as spinner:
            call_subprocess(args, show_stdout=False, spinner=spinner)
Example #31
0
    def _install_build_reqs(self, reqs, prefix):
        # Local import to avoid circular import (wheel <-> req_install)
        from pip.req.req_install import InstallRequirement
        from pip.index import FormatControl
        # Ignore the --no-binary option when installing the build system, so
        # we don't recurse trying to build a self-hosting build system.
        finder = copy.copy(self.finder)
        finder.format_control = FormatControl(set(), set())
        urls = [finder.find_requirement(InstallRequirement.from_line(r),
                                        upgrade=False).url
                for r in reqs]

        args = [sys.executable, '-m', 'pip', 'install', '--ignore-installed',
                '--prefix', prefix] + list(urls)
        with open_spinner("Installing build dependencies") as spinner:
            call_subprocess(args, show_stdout=False, spinner=spinner)
Example #32
0
 def get_dep_links_ireqs(dist):
     # pylint: disable=protected-access
     dependency_links = list(dist._get_metadata('dependency_links.txt'))
     dependency_links = [append_egg_hash_to_url_if_need_be(url) for url in dependency_links]
     dependency_links = [url for url in dependency_links if url]
     dep_links_ireqs = set(InstallRequirement.from_line(url) for url in dependency_links)
     # We cache those dependency_links so that they can be accessed from CustomResolver._iter_dependencies, self.find_all_candidates and at the end of _pip_compile
     for dep_ireq in dep_links_ireqs:
         dep_ireq.remove_temporary_source()
         dependency_links_requirements[str(dep_ireq.req)] = dep_ireq
         if str(dep_ireq.req).lower() != str(dep_ireq.req):
             # This is required for dependencies with a version like X.Y.Z-SNAPSHOT (notice the uppercase).
             # They need to exist BOTH as key in this dict, otherwise:
             # * if only the lowercase is there, `get_dependencies` raise a pip.exceptions.DistributionNotFound
             # * if only the uppercase is there, an erroneous "version-locked" pkg version gets out of this module, and we get a:
             # requests.exceptions.HTTPError: 404 Client Error: Not Found (no releases) for url: https://pypi.python.org/pypi/$pkg/json
             dependency_links_requirements[str(dep_ireq.req).lower()] = dep_ireq
     return dep_links_ireqs
Example #33
0
 def parse_requirement(req):
     install_req = InstallRequirement.from_line(req)
     if install_req.original_link:
         return
     if install_req.is_pinned:
         version = next(iter(install_req.specifier)).version
     else:
         version = None
     setup_packages.append({
         "name":
         install_req.req.name,
         "version":
         version,
         "file":
         "setup.py",
         "requirement":
         str(install_req.specifier) or None
     })
Example #34
0
 def setup(*args, **kwargs):
     for arg in ['install_requires', 'tests_require']:
         if not kwargs.get(arg):
             continue
         for req in kwargs.get(arg):
             install_req = InstallRequirement.from_line(req)
             if install_req.original_link:
                 continue
             if install_req.is_pinned:
                 version = next(iter(install_req.specifier)).version
             else:
                 version = None
             setup_packages.append({
                 "name":
                 install_req.req.name,
                 "version":
                 version,
                 "file":
                 "setup.py",
                 "requirement":
                 str(install_req.specifier) or None
             })
Example #35
0
def test_command(app, mocker, tmp_dir):
    poetry_file = os.path.join(tmp_dir, 'poetry.toml')
    readme = os.path.join(tmp_dir, 'README.rst')
    fixtures = os.path.join(os.path.dirname(__file__), '..', 'fixtures')
    shutil.copy(os.path.join(fixtures, 'poetry.toml'), poetry_file)
    shutil.copy(os.path.join(fixtures, 'README.rst'), readme)
    requirements_file = os.path.join(tmp_dir, 'requirements.txt')

    resolve = mocker.patch('piptools.resolver.Resolver.resolve')
    reverse_dependencies = mocker.patch(
        'piptools.resolver.Resolver.reverse_dependencies')
    resolve.return_value = [InstallRequirement.from_line('pendulum==1.2.0')]
    reverse_dependencies.return_value = {}
    poet = Poet(poetry_file)
    poet_prop = mocker.patch('poet.console.commands.command.Command.poet',
                             poet)
    poet_prop.return_value = poet

    command = app.find('make:requirements')
    tester = CommandTester(command)
    tester.execute([('command', command.name)])

    expected = """
 - Resolving dependencies
 - Created requirements.txt file
"""

    output = tester.get_display()

    assert expected == output

    assert os.path.exists(requirements_file)

    content = """pendulum==1.2.0
"""

    with open(requirements_file) as f:
        assert content == f.read()
Example #36
0
    def prepare_files(self, finder):
        """
        Prepare process. Create temp directories, download and/or unpack files.
        """
        from pip.index import Link

        unnamed = list(self.unnamed_requirements)
        reqs = list(self.requirements.values())
        while reqs or unnamed:
            if unnamed:
                req_to_install = unnamed.pop(0)
            else:
                req_to_install = reqs.pop(0)
            install = True
            best_installed = False
            not_found = None

            # ############################################# #
            # # Search for archive to fulfill requirement # #
            # ############################################# #

            if not self.ignore_installed and not req_to_install.editable:
                req_to_install.check_if_exists()
                if req_to_install.satisfied_by:
                    if self.upgrade:
                        if not self.force_reinstall and not req_to_install.url:
                            try:
                                url = finder.find_requirement(
                                    req_to_install, self.upgrade)
                            except BestVersionAlreadyInstalled:
                                best_installed = True
                                install = False
                            except DistributionNotFound as exc:
                                not_found = exc
                            else:
                                # Avoid the need to call find_requirement again
                                req_to_install.url = url.url

                        if not best_installed:
                            # don't uninstall conflict if user install and
                            # conflict is not user install
                            if not (self.use_user_site
                                    and not dist_in_usersite(
                                        req_to_install.satisfied_by
                                    )):
                                req_to_install.conflicts_with = \
                                    req_to_install.satisfied_by
                            req_to_install.satisfied_by = None
                    else:
                        install = False
                if req_to_install.satisfied_by:
                    if best_installed:
                        logger.info(
                            'Requirement already up-to-date: %s',
                            req_to_install,
                        )
                    else:
                        logger.info(
                            'Requirement already satisfied (use --upgrade to '
                            'upgrade): %s',
                            req_to_install,
                        )
            if req_to_install.editable:
                logger.info('Obtaining %s', req_to_install)
            elif install:
                if (req_to_install.url
                        and req_to_install.url.lower().startswith('file:')):
                    path = url_to_path(req_to_install.url)
                    logger.info('Processing %s', display_path(path))
                else:
                    logger.info('Collecting %s', req_to_install)

            with indent_log():
                # ################################ #
                # # vcs update or unpack archive # #
                # ################################ #

                is_wheel = False
                if req_to_install.editable:
                    if req_to_install.source_dir is None:
                        location = req_to_install.build_location(self.src_dir)
                        req_to_install.source_dir = location
                    else:
                        location = req_to_install.source_dir
                    if not os.path.exists(self.build_dir):
                        _make_build_dir(self.build_dir)
                    req_to_install.update_editable(not self.is_download)
                    if self.is_download:
                        req_to_install.run_egg_info()
                        req_to_install.archive(self.download_dir)
                    else:
                        req_to_install.run_egg_info()
                elif install:
                    # @@ if filesystem packages are not marked
                    # editable in a req, a non deterministic error
                    # occurs when the script attempts to unpack the
                    # build directory

                    # NB: This call can result in the creation of a temporary
                    # build directory
                    location = req_to_install.build_location(
                        self.build_dir,
                    )
                    unpack = True
                    url = None

                    # If a checkout exists, it's unwise to keep going.  version
                    # inconsistencies are logged later, but do not fail the
                    # installation.
                    if os.path.exists(os.path.join(location, 'setup.py')):
                        raise PreviousBuildDirError(
                            "pip can't proceed with requirements '%s' due to a"
                            " pre-existing build directory (%s). This is "
                            "likely due to a previous installation that failed"
                            ". pip is being responsible and not assuming it "
                            "can delete this. Please delete it and try again."
                            % (req_to_install, location)
                        )
                    else:
                        # FIXME: this won't upgrade when there's an existing
                        # package unpacked in `location`
                        if req_to_install.url is None:
                            if not_found:
                                raise not_found
                            url = finder.find_requirement(
                                req_to_install,
                                upgrade=self.upgrade,
                            )
                        else:
                            # FIXME: should req_to_install.url already be a
                            # link?
                            url = Link(req_to_install.url)
                            assert url
                        if url:
                            try:

                                if (
                                    url.filename.endswith(wheel_ext)
                                    and self.wheel_download_dir
                                ):
                                    # when doing 'pip wheel`
                                    download_dir = self.wheel_download_dir
                                    do_download = True
                                else:
                                    download_dir = self.download_dir
                                    do_download = self.is_download
                                unpack_url(
                                    url, location, download_dir,
                                    do_download, session=self.session,
                                )
                            except requests.HTTPError as exc:
                                logger.critical(
                                    'Could not install requirement %s because '
                                    'of error %s',
                                    req_to_install,
                                    exc,
                                )
                                raise InstallationError(
                                    'Could not install requirement %s because '
                                    'of HTTP error %s for URL %s' %
                                    (req_to_install, exc, url)
                                )
                        else:
                            unpack = False
                    if unpack:
                        is_wheel = url and url.filename.endswith(wheel_ext)
                        if self.is_download:
                            req_to_install.source_dir = location
                            if not is_wheel:
                                # FIXME:https://github.com/pypa/pip/issues/1112
                                req_to_install.run_egg_info()
                            if url and url.scheme in vcs.all_schemes:
                                req_to_install.archive(self.download_dir)
                        elif is_wheel:
                            req_to_install.source_dir = location
                            req_to_install.url = url.url
                        else:
                            req_to_install.source_dir = location
                            req_to_install.run_egg_info()
                            req_to_install.assert_source_matches_version()
                        # req_to_install.req is only avail after unpack for URL
                        # pkgs repeat check_if_exists to uninstall-on-upgrade
                        # (#14)
                        if not self.ignore_installed:
                            req_to_install.check_if_exists()
                        if req_to_install.satisfied_by:
                            if self.upgrade or self.ignore_installed:
                                # don't uninstall conflict if user install and
                                # conflict is not user install
                                if not (self.use_user_site
                                        and not dist_in_usersite(
                                            req_to_install.satisfied_by)):
                                    req_to_install.conflicts_with = \
                                        req_to_install.satisfied_by
                                req_to_install.satisfied_by = None
                            else:
                                logger.info(
                                    'Requirement already satisfied (use '
                                    '--upgrade to upgrade): %s',
                                    req_to_install,
                                )
                                install = False

                # ###################### #
                # # parse dependencies # #
                # ###################### #
                if (req_to_install.extras):
                    logger.debug(
                        "Installing extra requirements: %r",
                        ','.join(req_to_install.extras),
                    )

                if is_wheel:
                    dist = list(
                        pkg_resources.find_distributions(location)
                    )[0]
                else:  # sdists
                    if req_to_install.satisfied_by:
                        dist = req_to_install.satisfied_by
                    else:
                        dist = req_to_install.get_dist()
                    # FIXME: shouldn't be globally added:
                    if dist.has_metadata('dependency_links.txt'):
                        finder.add_dependency_links(
                            dist.get_metadata_lines('dependency_links.txt')
                        )

                if not self.ignore_dependencies:
                    for subreq in dist.requires(
                            req_to_install.extras):
                        if self.has_requirement(
                                subreq.project_name):
                            # FIXME: check for conflict
                            continue
                        subreq = InstallRequirement(
                            str(subreq),
                            req_to_install,
                            isolated=self.isolated,
                        )
                        reqs.append(subreq)
                        self.add_requirement(subreq)

                if not self.has_requirement(req_to_install.name):
                    # 'unnamed' requirements will get added here
                    self.add_requirement(req_to_install)

                # cleanup tmp src
                if (self.is_download or
                        req_to_install._temp_build_dir is not None):
                    self.reqs_to_cleanup.append(req_to_install)

                if install:
                    self.successfully_downloaded.append(req_to_install)
Example #37
0
            line = _remove_prefix(line, '--allow-unverified')
=======
            line = line[len("--allow-insecure"):].strip().lstrip("=")
            if finder:
                finder.allow_unverified |= set([normalize_name(line).lower()])
        elif line.startswith("--allow-unverified"):
            line = line[len("--allow-unverified"):].strip().lstrip("=")
>>>>>>> bde4533e29dfedadf6bcf9d451baa615bc828a59
            if finder:
                finder.allow_unverified |= set([normalize_name(line).lower()])
        else:
            comes_from = '-r %s (line %s)' % (filename, line_number)
<<<<<<< HEAD
            if line.startswith(('-e', '--editable')):
                editable = _remove_prefixes(line, '-e', '--editable')
                req = InstallRequirement.from_editable(
                    editable,
=======
            if line.startswith('-e') or line.startswith('--editable'):
                if line.startswith('-e'):
                    line = line[2:].strip()
                else:
                    line = line[len('--editable'):].strip().lstrip('=')
                req = InstallRequirement.from_editable(
                    line,
>>>>>>> bde4533e29dfedadf6bcf9d451baa615bc828a59
                    comes_from=comes_from,
                    default_vcs=options.default_vcs if options else None,
                    isolated=options.isolated_mode if options else False,
                )
            else:
                req = InstallRequirement.from_line(
Example #38
0
def parse_requirements(filename, finder=None, comes_from=None, options=None,
                       session=None):
    if session is None:
        raise TypeError(
            "parse_requirements() missing 1 required keyword argument: "
            "'session'"
        )

    skip_match = None
    skip_regex = options.skip_requirements_regex if options else None
    if skip_regex:
        skip_match = re.compile(skip_regex)
    reqs_file_dir = os.path.dirname(os.path.abspath(filename))
    filename, content = get_file_content(
        filename,
        comes_from=comes_from,
        session=session,
    )
    for line_number, line in enumerate(content.splitlines(), 1):
        line = line.strip()

        # Remove comments from file and all spaces before it
        line = re.sub(r"(^|\s)+#.*$", "", line)

        if not line:
            continue
        if skip_match and skip_match.search(line):
            continue
        if line.startswith(('-r', '--requirement')):
            req_url = _remove_prefixes(line, '-r', '--requirement')
            if _scheme_re.search(filename):
                # Relative to a URL
                req_url = urllib_parse.urljoin(filename, req_url)
            elif not _scheme_re.search(req_url):
                req_url = os.path.join(os.path.dirname(filename), req_url)
            for item in parse_requirements(
                    req_url, finder,
                    comes_from=filename,
                    options=options,
                    session=session):
                yield item
        elif line.startswith(('-Z', '--always-unzip')):
            # No longer used, but previously these were used in
            # requirement files, so we'll ignore.
            pass
        elif line.startswith(('-f', '--find-links')):
            find_links = _remove_prefixes(line, '-f', '--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
            relative_to_reqs_file = os.path.join(reqs_file_dir, find_links)
            if os.path.exists(relative_to_reqs_file):
                find_links = relative_to_reqs_file
            if finder:
                finder.find_links.append(find_links)
        elif line.startswith(('-i', '--index-url')):
            index_url = _remove_prefixes(line, '-i', '--index-url')
            if finder:
                finder.index_urls = [index_url]
        elif line.startswith('--extra-index-url'):
            line = _remove_prefix(line, '--extra-index-url')
            if finder:
                finder.index_urls.append(line)
        elif line.startswith('--use-wheel'):
            # Default in 1.5
            pass
        elif line.startswith('--no-use-wheel'):
            if finder:
                finder.use_wheel = False
        elif line.startswith('--no-index'):
            if finder:
                finder.index_urls = []
        elif line.startswith("--allow-external"):
            line = _remove_prefix(line, '--allow-external')
            if finder:
                finder.allow_external |= set([normalize_name(line).lower()])
        elif line.startswith("--allow-all-external"):
            if finder:
                finder.allow_all_external = True
        # Remove in 7.0
        elif line.startswith("--no-allow-external"):
            pass
        # Remove in 7.0
        elif line.startswith("--no-allow-insecure"):
            pass
        # Remove after 7.0
        elif line.startswith("--allow-insecure"):
            line = _remove_prefix(line, '--allow-insecure')
            if finder:
                finder.allow_unverified |= set([normalize_name(line).lower()])
        elif line.startswith("--allow-unverified"):
            line = _remove_prefix(line, '--allow-unverified')
            if finder:
                finder.allow_unverified |= set([normalize_name(line).lower()])
        else:
            comes_from = '-r %s (line %s)' % (filename, line_number)
            if line.startswith(('-e', '--editable')):
                editable = _remove_prefixes(line, '-e', '--editable')
                req = InstallRequirement.from_editable(
                    editable,
                    comes_from=comes_from,
                    default_vcs=options.default_vcs if options else None,
                    isolated=options.isolated_mode if options else False,
                )
            else:
                req = InstallRequirement.from_line(
                    line,
                    comes_from,
                    isolated=options.isolated_mode if options else False,
                )
            yield req
Example #39
0
def parse_requirements(filename,
                       finder=None,
                       comes_from=None,
                       options=None,
                       session=None):
    if session is None:
        raise TypeError(
            "parse_requirements() missing 1 required keyword argument: "
            "'session'")

    skip_match = None
    skip_regex = options.skip_requirements_regex if options else None
    if skip_regex:
        skip_match = re.compile(skip_regex)
    reqs_file_dir = os.path.dirname(os.path.abspath(filename))
    filename, content = get_file_content(
        filename,
        comes_from=comes_from,
        session=session,
    )
    for line_number, line in enumerate(content.splitlines(), 1):
        line = line.strip()

        # Remove comments from file
        line = re.sub(r"(^|\s)#.*$", "", line)

        if not line or line.startswith('#'):
            continue
        if skip_match and skip_match.search(line):
            continue
        if line.startswith('-r') or line.startswith('--requirement'):
            if line.startswith('-r'):
                req_url = line[2:].strip()
            else:
                req_url = line[len('--requirement'):].strip().strip('=')
            if _scheme_re.search(filename):
                # Relative to a URL
                req_url = urllib_parse.urljoin(filename, req_url)
            elif not _scheme_re.search(req_url):
                req_url = os.path.join(os.path.dirname(filename), req_url)
            for item in parse_requirements(req_url,
                                           finder,
                                           comes_from=filename,
                                           options=options,
                                           session=session):
                yield item
        elif line.startswith('-Z') or line.startswith('--always-unzip'):
            # No longer used, but previously these were used in
            # requirement files, so we'll ignore.
            pass
        elif line.startswith('-f') or line.startswith('--find-links'):
            if line.startswith('-f'):
                line = line[2:].strip()
            else:
                line = line[len('--find-links'):].strip().lstrip('=')
            # 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
            relative_to_reqs_file = os.path.join(reqs_file_dir, line)
            if os.path.exists(relative_to_reqs_file):
                line = relative_to_reqs_file
            if finder:
                finder.find_links.append(line)
        elif line.startswith('-i') or line.startswith('--index-url'):
            if line.startswith('-i'):
                line = line[2:].strip()
            else:
                line = line[len('--index-url'):].strip().lstrip('=')
            if finder:
                finder.index_urls = [line]
        elif line.startswith('--extra-index-url'):
            line = line[len('--extra-index-url'):].strip().lstrip('=')
            if finder:
                finder.index_urls.append(line)
        elif line.startswith('--use-wheel'):
            # Default in 1.5
            pass
        elif line.startswith('--no-use-wheel'):
            if finder:
                finder.use_wheel = False
        elif line.startswith('--no-index'):
            if finder:
                finder.index_urls = []
        elif line.startswith("--allow-external"):
            line = line[len("--allow-external"):].strip().lstrip("=")
            if finder:
                finder.allow_external |= set([normalize_name(line).lower()])
        elif line.startswith("--allow-all-external"):
            if finder:
                finder.allow_all_external = True
        # Remove in 7.0
        elif line.startswith("--no-allow-external"):
            pass
        # Remove in 7.0
        elif line.startswith("--no-allow-insecure"):
            pass
        # Remove after 7.0
        elif line.startswith("--allow-insecure"):
            line = line[len("--allow-insecure"):].strip().lstrip("=")
            if finder:
                finder.allow_unverified |= set([normalize_name(line).lower()])
        elif line.startswith("--allow-unverified"):
            line = line[len("--allow-unverified"):].strip().lstrip("=")
            if finder:
                finder.allow_unverified |= set([normalize_name(line).lower()])
        else:
            comes_from = '-r %s (line %s)' % (filename, line_number)
            if line.startswith('-e') or line.startswith('--editable'):
                if line.startswith('-e'):
                    line = line[2:].strip()
                else:
                    line = line[len('--editable'):].strip().lstrip('=')
                req = InstallRequirement.from_editable(
                    line,
                    comes_from=comes_from,
                    default_vcs=options.default_vcs if options else None,
                    isolated=options.isolated_mode if options else False,
                )
            else:
                req = InstallRequirement.from_line(
                    line,
                    comes_from,
                    isolated=options.isolated_mode if options else False,
                )
            yield req
Example #40
0
def process_line(line,
                 filename,
                 line_number,
                 finder=None,
                 comes_from=None,
                 options=None,
                 session=None,
                 wheel_cache=None,
                 constraint=False):
    """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()
    defaults = parser.get_default_values()
    defaults.index_url = None
    if finder:
        # `finder.format_control` will be updated during parsing
        defaults.format_control = finder.format_control
    args_str, options_str = break_args_options(line)
    if sys.version_info < (2, 7, 3):
        # Priori to 2.7.3, shlex can not deal with unicode entries
        options_str = options_str.encode('utf8')
    opts, _ = parser.parse_args(shlex.split(options_str), defaults)

    # 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 InstallRequirement.from_line(args_str,
                                           line_comes_from,
                                           constraint=constraint,
                                           isolated=isolated,
                                           options=req_options,
                                           wheel_cache=wheel_cache)

    # yield an editable requirement
    elif opts.editables:
        isolated = options.isolated_mode if options else False
        default_vcs = options.default_vcs if options else None
        yield InstallRequirement.from_editable(opts.editables[0],
                                               comes_from=line_comes_from,
                                               constraint=constraint,
                                               default_vcs=default_vcs,
                                               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?
        parser = parse_requirements(req_path,
                                    finder,
                                    comes_from,
                                    options,
                                    session,
                                    constraint=nested_constraint,
                                    wheel_cache=wheel_cache)
        for req in parser:
            yield req

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

    # set finder options
    elif finder:
        if opts.allow_external:
            warnings.warn(
                "--allow-external has been deprecated and will be removed in "
                "the future. Due to changes in the repository protocol, it no "
                "longer has any effect.",
                RemovedInPip10Warning,
            )

        if opts.allow_all_external:
            warnings.warn(
                "--allow-all-external has been deprecated and will be removed "
                "in the future. Due to changes in the repository protocol, it "
                "no longer has any effect.",
                RemovedInPip10Warning,
            )

        if opts.allow_unverified:
            warnings.warn(
                "--allow-unverified has been deprecated and will be removed "
                "in the future. Due to changes in the repository protocol, it "
                "no longer has any effect.",
                RemovedInPip10Warning,
            )

        if opts.index_url:
            finder.index_urls = [opts.index_url]
        if opts.use_wheel is False:
            finder.use_wheel = False
            pip.index.fmt_ctl_no_use_wheel(finder.format_control)
        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.process_dependency_links:
            finder.process_dependency_links = True
        if opts.trusted_hosts:
            finder.secure_origins.extend(
                ("*", host, "*") for host in opts.trusted_hosts)
Example #41
0
def process_line(line, filename, line_number, finder=None, comes_from=None,
                 options=None, session=None, wheel_cache=None,
                 constraint=False):
    """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()
    defaults = parser.get_default_values()
    defaults.index_url = None
    if finder:
        # `finder.format_control` will be updated during parsing
        defaults.format_control = finder.format_control
    args_str, options_str = break_args_options(line)
    if sys.version_info < (2, 7, 3):
        # Prior to 2.7.3, shlex cannot deal with unicode entries
        options_str = options_str.encode('utf8')
    opts, _ = parser.parse_args(shlex.split(options_str), defaults)

    # 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 InstallRequirement.from_line(
            args_str, line_comes_from, constraint=constraint,
            isolated=isolated, options=req_options, wheel_cache=wheel_cache
        )

    # yield an editable requirement
    elif opts.editables:
        isolated = options.isolated_mode if options else False
        default_vcs = options.default_vcs if options else None
        yield InstallRequirement.from_editable(
            opts.editables[0], comes_from=line_comes_from,
            constraint=constraint, default_vcs=default_vcs, 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?
        parser = parse_requirements(
            req_path, finder, comes_from, options, session,
            constraint=nested_constraint, wheel_cache=wheel_cache
        )
        for req in parser:
            yield req

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

    # set finder options
    elif finder:
        if opts.allow_external:
            warnings.warn(
                "--allow-external has been deprecated and will be removed in "
                "the future. Due to changes in the repository protocol, it no "
                "longer has any effect.",
                RemovedInPip10Warning,
            )

        if opts.allow_all_external:
            warnings.warn(
                "--allow-all-external has been deprecated and will be removed "
                "in the future. Due to changes in the repository protocol, it "
                "no longer has any effect.",
                RemovedInPip10Warning,
            )

        if opts.allow_unverified:
            warnings.warn(
                "--allow-unverified has been deprecated and will be removed "
                "in the future. Due to changes in the repository protocol, it "
                "no longer has any effect.",
                RemovedInPip10Warning,
            )

        if opts.index_url:
            finder.index_urls = [opts.index_url]
        if opts.use_wheel is False:
            finder.use_wheel = False
            pip.index.fmt_ctl_no_use_wheel(finder.format_control)
        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.process_dependency_links:
            finder.process_dependency_links = True
        if opts.trusted_hosts:
            finder.secure_origins.extend(
                ("*", host, "*") for host in opts.trusted_hosts)
Example #42
0
def parse_requirements(filename, finder=None, comes_from=None, options=None,
                       session=None):
    if session is None:
        session = PipSession()

    skip_match = None
    skip_regex = options.skip_requirements_regex if options else None
    if skip_regex:
        skip_match = re.compile(skip_regex)
    reqs_file_dir = os.path.dirname(os.path.abspath(filename))
    filename, content = get_file_content(
        filename,
        comes_from=comes_from,
        session=session,
    )
    for line_number, line in enumerate(content.splitlines()):
        line_number += 1
        line = line.strip()

        # Remove comments from file
        line = re.sub(r"(^|\s)#.*$", "", line)

        if not line or line.startswith('#'):
            continue
        if skip_match and skip_match.search(line):
            continue
        if line.startswith('-r') or line.startswith('--requirement'):
            if line.startswith('-r'):
                req_url = line[2:].strip()
            else:
                req_url = line[len('--requirement'):].strip().strip('=')
            if _scheme_re.search(filename):
                # Relative to a URL
                req_url = urlparse.urljoin(filename, req_url)
            elif not _scheme_re.search(req_url):
                req_url = os.path.join(os.path.dirname(filename), req_url)
            for item in parse_requirements(
                    req_url, finder,
                    comes_from=filename,
                    options=options,
                    session=session):
                yield item
        elif line.startswith('-Z') or line.startswith('--always-unzip'):
            # No longer used, but previously these were used in
            # requirement files, so we'll ignore.
            pass
        elif line.startswith('-f') or line.startswith('--find-links'):
            if line.startswith('-f'):
                line = line[2:].strip()
            else:
                line = line[len('--find-links'):].strip().lstrip('=')
            ## 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
            relative_to_reqs_file = os.path.join(reqs_file_dir, line)
            if os.path.exists(relative_to_reqs_file):
                line = relative_to_reqs_file
            if finder:
                finder.find_links.append(line)
        elif line.startswith('-i') or line.startswith('--index-url'):
            if line.startswith('-i'):
                line = line[2:].strip()
            else:
                line = line[len('--index-url'):].strip().lstrip('=')
            if finder:
                finder.index_urls = [line]
        elif line.startswith('--extra-index-url'):
            line = line[len('--extra-index-url'):].strip().lstrip('=')
            if finder:
                finder.index_urls.append(line)
        elif line.startswith('--use-wheel'):
            finder.use_wheel = True
        elif line.startswith('--no-index'):
            finder.index_urls = []
        elif line.startswith("--allow-external"):
            line = line[len("--allow-external"):].strip().lstrip("=")
            finder.allow_external |= set([normalize_name(line).lower()])
        elif line.startswith("--allow-all-external"):
            finder.allow_all_external = True
        # Remove in 1.7
        elif line.startswith("--no-allow-external"):
            pass
        # Remove in 1.7
        elif line.startswith("--no-allow-insecure"):
            pass
        # Remove after 1.7
        elif line.startswith("--allow-insecure"):
            line = line[len("--allow-insecure"):].strip().lstrip("=")
            finder.allow_unverified |= set([normalize_name(line).lower()])
        elif line.startswith("--allow-unverified"):
            line = line[len("--allow-unverified"):].strip().lstrip("=")
            finder.allow_unverified |= set([normalize_name(line).lower()])
        else:
            comes_from = '-r %s (line %s)' % (filename, line_number)
            if line.startswith('-e') or line.startswith('--editable'):
                if line.startswith('-e'):
                    line = line[2:].strip()
                else:
                    line = line[len('--editable'):].strip().lstrip('=')
                req = InstallRequirement.from_editable(
                    line,
                    comes_from=comes_from,
                    default_vcs=options.default_vcs if options else None
                )
            else:
                req = InstallRequirement.from_line(
                    line,
                    comes_from,
                    prereleases=getattr(options, "pre", None)
                )
            yield req
Example #43
0
 def test_yield_line_requirement(self):
     line = 'SomeProject'
     filename = 'filename'
     comes_from = '-r %s (line %s)' % (filename, 1)
     req = InstallRequirement.from_line(line, comes_from=comes_from)
     assert repr(list(process_line(line, filename, 1))[0]) == repr(req)
Example #44
0
    session = PipSession()
    options = {}

    print('# AUTOGENERATED by {}\n# DO NOT EDIT\n#\n'.format(sys.argv[0]))

    if os.path.exists('setup.cfg'):
        options = read_configuration('setup.cfg').get('options', {})

    install_requires = options.get('install_requires', [])
    extras_require = options.get('extras_require', {})

    if install_requires:
        fname = 'setup.cfg:options.install_requires'
        print_file(
            fname,
            (InstallRequirement.from_line(l, fname)
             for l in sorted(install_requires)),
        )

    for extra, requires in sorted(extras_require.items()):
        if extra in args.extras:
            fname = 'setup.cfg:options.extras_require:' + extra
            print_file(
                fname,
                (InstallRequirement.from_line(l, fname)
                 for l in sorted(requires)),
            )

    for filename in args.requirements:
        print_file(filename, parse_requirements(filename, session=session))
Example #45
0
def process_line(line,
                 filename,
                 line_number,
                 finder=None,
                 comes_from=None,
                 options=None,
                 session=None,
                 wheel_cache=None,
                 constraint=False):
    """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.
    """
    parser = build_parser()
    defaults = parser.get_default_values()
    defaults.index_url = None
    if finder:
        # `finder.format_control` will be updated during parsing
        defaults.format_control = finder.format_control
    args_str, options_str = break_args_options(line)
    opts, _ = parser.parse_args(shlex.split(options_str), defaults)

    # 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 InstallRequirement.from_line(args_str,
                                           line_comes_from,
                                           constraint=constraint,
                                           isolated=isolated,
                                           options=req_options,
                                           wheel_cache=wheel_cache)

    # yield an editable requirement
    elif opts.editables:
        isolated = options.isolated_mode if options else False
        default_vcs = options.default_vcs if options else None
        yield InstallRequirement.from_editable(opts.editables[0],
                                               comes_from=line_comes_from,
                                               constraint=constraint,
                                               default_vcs=default_vcs,
                                               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_dir = os.path.dirname(filename)
            req_path = os.path.join(os.path.dirname(filename), req_path)
        # TODO: Why not use `comes_from='-r {} (line {})'` here as well?
        parser = parse_requirements(req_path,
                                    finder,
                                    comes_from,
                                    options,
                                    session,
                                    constraint=nested_constraint,
                                    wheel_cache=wheel_cache)
        for req in parser:
            yield req

    # set finder options
    elif finder:
        if opts.index_url:
            finder.index_urls = [opts.index_url]
        if opts.use_wheel is False:
            finder.use_wheel = False
            pip.index.fmt_ctl_no_use_wheel(finder.format_control)
        if opts.no_index is True:
            finder.index_urls = []
        if opts.allow_all_external:
            finder.allow_all_external = opts.allow_all_external
        if opts.extra_index_urls:
            finder.index_urls.extend(opts.extra_index_urls)
        if opts.allow_external:
            finder.allow_external |= set(
                [normalize_name(v).lower() for v in opts.allow_external])
        if opts.allow_unverified:
            # Remove after 7.0
            finder.allow_unverified |= set(
                [normalize_name(v).lower() for v in opts.allow_unverified])
        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)
Example #46
0
def process_line(line, filename, line_number, finder=None, comes_from=None,
                 options=None, session=None, wheel_cache=None,
                 constraint=False):
    """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.
    """
    parser = build_parser()
    defaults = parser.get_default_values()
    defaults.index_url = None
    if finder:
        # `finder.format_control` will be updated during parsing
        defaults.format_control = finder.format_control
    args_str, options_str = break_args_options(line)
    opts, _ = parser.parse_args(shlex.split(options_str), defaults)

    # 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 InstallRequirement.from_line(
            args_str, line_comes_from, constraint=constraint,
            isolated=isolated, options=req_options, wheel_cache=wheel_cache
        )

    # yield an editable requirement
    elif opts.editables:
        isolated = options.isolated_mode if options else False
        default_vcs = options.default_vcs if options else None
        yield InstallRequirement.from_editable(
            opts.editables[0], comes_from=line_comes_from,
            constraint=constraint, default_vcs=default_vcs, 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_dir = os.path.dirname(filename)
            req_path = os.path.join(os.path.dirname(filename), req_path)
        # TODO: Why not use `comes_from='-r {} (line {})'` here as well?
        parser = parse_requirements(
            req_path, finder, comes_from, options, session,
            constraint=nested_constraint, wheel_cache=wheel_cache
        )
        for req in parser:
            yield req

    # set finder options
    elif finder:
        if opts.index_url:
            finder.index_urls = [opts.index_url]
        if opts.use_wheel is False:
            finder.use_wheel = False
            pip.index.fmt_ctl_no_use_wheel(finder.format_control)
        if opts.no_index is True:
            finder.index_urls = []
        if opts.allow_all_external:
            finder.allow_all_external = opts.allow_all_external
        if opts.extra_index_urls:
            finder.index_urls.extend(opts.extra_index_urls)
        if opts.allow_external:
            finder.allow_external |= set(
                [normalize_name(v).lower() for v in opts.allow_external])
        if opts.allow_unverified:
            # Remove after 7.0
            finder.allow_unverified |= set(
                [normalize_name(v).lower() for v in opts.allow_unverified])
        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)