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
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
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
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)
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
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, )
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')]
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
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'
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'
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))
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'
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)
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)
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
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
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))
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
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))
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)]
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
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
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)
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
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 })
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 })
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()
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)
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(
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
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
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)
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)
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
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)
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))
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)
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)