def test_unpinned_hash_checking(self, data: TestData) -> None: """Make sure prepare_files() raises an error when a requirement is not version-pinned in hash-checking mode. """ reqset = RequirementSet() # Test that there must be exactly 1 specifier: reqset.add_named_requirement( get_processed_req_from_line( "simple --hash=sha256:a90427ae31f5d1d0d7ec06ee97d9fcf2d0fc9a786985" "250c1c83fd68df5911dd", lineno=1, )) # Test that the operator must be ==: reqset.add_named_requirement( get_processed_req_from_line( "simple2>1.0 --hash=sha256:3ad45e1e9aa48b4462af0" "123f6a7e44a9115db1ef945d4d92c123dfe21815a06", lineno=2, )) finder = make_test_finder(find_links=[data.find_links]) with self._basic_resolver(finder, require_hashes=True) as resolver: with pytest.raises( HashErrors, # Make sure all failing requirements are listed: match=(r"versions pinned with ==. These do not:\n" r" simple .* \(from -r file \(line 1\)\)\n" r" simple2>1.0 .* \(from -r file \(line 2\)\)"), ): resolver.resolve(reqset.all_requirements, True)
def resolve_reqs( self, download_dir: Optional[str], ireq: InstallRequirement, wheel_cache: WheelCache, ) -> Set[InstallationCandidate]: with get_build_tracker() as build_tracker, TempDirectory( kind="resolver" ) as temp_dir, indent_log(): preparer_kwargs = { "temp_build_dir": temp_dir, "options": self.options, "session": self.session, "finder": self.finder, "use_user_site": False, "download_dir": download_dir, } if PIP_VERSION[:2] <= (22, 0): preparer_kwargs["req_tracker"] = build_tracker else: preparer_kwargs["build_tracker"] = build_tracker preparer = self.command.make_requirement_preparer(**preparer_kwargs) reqset = RequirementSet() ireq.user_supplied = True if PIP_VERSION[:3] < (22, 1, 1): reqset.add_requirement(ireq) elif getattr(ireq, "name", None): reqset.add_named_requirement(ireq) else: reqset.add_unnamed_requirement(ireq) resolver = self.command.make_resolver( preparer=preparer, finder=self.finder, options=self.options, wheel_cache=wheel_cache, use_user_site=False, ignore_installed=True, ignore_requires_python=False, force_reinstall=False, upgrade_strategy="to-satisfy-only", ) results = resolver._resolve_one(reqset, ireq) if not ireq.prepared: # If still not prepared, e.g. a constraint, do enough to assign # the ireq a name: resolver._get_dist_for(ireq) return set(results)
def test_missing_hash_with_require_hashes(self, data: TestData) -> None: """Setting --require-hashes explicitly should raise errors if hashes are missing. """ reqset = RequirementSet() reqset.add_named_requirement( get_processed_req_from_line("simple==1.0", lineno=1)) finder = make_test_finder(find_links=[data.find_links]) with self._basic_resolver(finder, require_hashes=True) as resolver: with pytest.raises( HashErrors, match= (r"Hashes are required in --require-hashes mode, but they are " r"missing .*\n" r" simple==1.0 --hash=sha256:393043e672415891885c9a2a0929b1" r"af95fb866d6ca016b42d2e6ce53619b653$"), ): resolver.resolve(reqset.all_requirements, True)
def test_no_reuse_existing_build_dir(self, data: TestData) -> None: """Test prepare_files raise exception with previous build dir""" build_dir = os.path.join(self.tempdir, "build", "simple") os.makedirs(build_dir) with open(os.path.join(build_dir, "setup.py"), "w"): pass reqset = RequirementSet() req = install_req_from_line("simple") req.user_supplied = True reqset.add_named_requirement(req) finder = make_test_finder(find_links=[data.find_links]) with self._basic_resolver(finder) as resolver: with pytest.raises( PreviousBuildDirError, match= (r"pip can't proceed with [\s\S]*{req}[\s\S]*{build_dir_esc}". format(build_dir_esc=build_dir.replace("\\", "\\\\"), req=req)), ): resolver.resolve(reqset.all_requirements, True)
def test_unhashed_deps_on_require_hashes(self, data: TestData) -> None: """Make sure unhashed, unpinned, or otherwise unrepeatable dependencies get complained about when --require-hashes is on.""" reqset = RequirementSet() finder = make_test_finder(find_links=[data.find_links]) reqset.add_named_requirement( get_processed_req_from_line( "TopoRequires2==0.0.1 " # requires TopoRequires "--hash=sha256:eaf9a01242c9f2f42cf2bd82a6a848cd" "e3591d14f7896bdbefcf48543720c970", lineno=1, )) with self._basic_resolver(finder, require_hashes=True) as resolver: with pytest.raises( HashErrors, match= (r"In --require-hashes mode, all requirements must have their " r"versions pinned.*\n" r" TopoRequires from .*$"), ): resolver.resolve(reqset.all_requirements, True)
def test_hashed_deps_on_require_hashes(self) -> None: """Make sure hashed dependencies get installed when --require-hashes is on. (We actually just check that no "not all dependencies are hashed!" error gets raised while preparing; there is no reason to expect installation to then fail, as the code paths are the same as ever.) """ reqset = RequirementSet() reqset.add_named_requirement( get_processed_req_from_line( "TopoRequires2==0.0.1 " # requires TopoRequires "--hash=sha256:eaf9a01242c9f2f42cf2bd82a6a848cd" "e3591d14f7896bdbefcf48543720c970", lineno=1, )) reqset.add_named_requirement( get_processed_req_from_line( "TopoRequires==0.0.1 " "--hash=sha256:d6dd1e22e60df512fdcf3640ced3039b3b02a56ab2cee81ebcb" "3d0a6d4e8bfa6", lineno=2, ))