def test_unsupported_hashes(self, data): """VCS and dir links should raise errors when --require-hashes is on. In addition, complaints about the type of requirement (VCS or dir) should trump the presence or absence of a hash. """ reqset = self.basic_reqset(require_hashes=True) reqset.add_requirement( list( process_line( 'git+git://github.com/pypa/pip-test-package --hash=sha256:123', 'file', 1))[0]) dir_path = data.packages.join('FSPkg') reqset.add_requirement( list(process_line('file://%s' % (dir_path, ), 'file', 2))[0]) finder = PackageFinder([data.find_links], [], session=PipSession()) resolver = self._basic_resolver(finder) sep = os.path.sep if sep == '\\': sep = '\\\\' # This needs to be escaped for the regex assert_raises_regexp( HashErrors, r"Can't verify hashes for these requirements because we don't " r"have a way to hash version control repositories:\n" r" git\+git://github\.com/pypa/pip-test-package \(from -r file " r"\(line 1\)\)\n" r"Can't verify hashes for these file:// requirements because they " r"point to directories:\n" r" file://.*{sep}data{sep}packages{sep}FSPkg " r"\(from -r file \(line 2\)\)".format(sep=sep), resolver.resolve, reqset)
def test_unpinned_hash_checking(self, data): """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_requirement( get_processed_req_from_line( 'simple --hash=sha256:a90427ae31f5d1d0d7ec06ee97d9fcf2d0fc9a786985' '250c1c83fd68df5911dd', lineno=1, )) # Test that the operator must be ==: reqset.add_requirement( get_processed_req_from_line( 'simple2>1.0 --hash=sha256:3ad45e1e9aa48b4462af0' '123f6a7e44a9115db1ef945d4d92c123dfe21815a06', lineno=2, )) finder = make_test_finder(find_links=[data.find_links]) resolver = self._basic_resolver(finder) assert_raises_regexp( HashErrors, # Make sure all failing requirements are listed: 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)
def test_unpinned_hash_checking(self, data): """Make sure prepare_files() raises an error when a requirement is not version-pinned in hash-checking mode. """ reqset = self.basic_reqset() # Test that there must be exactly 1 specifier: reqset.add_requirement( list(process_line('simple --hash=sha256:a90427ae31f5d1d0d7ec06ee97' 'd9fcf2d0fc9a786985250c1c83fd68df5911dd', 'file', 1))[0]) # Test that the operator must be ==: reqset.add_requirement(list(process_line( 'simple2>1.0 --hash=sha256:3ad45e1e9aa48b4462af0' '123f6a7e44a9115db1ef945d4d92c123dfe21815a06', 'file', 2))[0]) finder = PackageFinder([data.find_links], [], session=PipSession()) assert_raises_regexp( HashErrors, # Make sure all failing requirements are listed: 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\)\)', reqset.prepare_files, finder)
def test_fails_with_no_cert_returning(self, mock_getpeercert): """ Test get ValueError if pypi returns no cert. """ mock_getpeercert.return_value = None o = urlopen.get_opener(scheme='https') assert_raises_regexp(ValueError, 'empty or no certificate', o.open, pypi_https)
def test_bad_pem_fails(self): """ Test ssl verification fails with bad pem file. Also confirms alternate --cert-path option works """ bad_cert = os.path.join(tests_data, 'packages', 'README.txt') os.environ['PIP_CERT'] = bad_cert o = urlopen.get_opener(scheme='https') assert_raises_regexp(URLError, '[sS][sS][lL]', o.open, pypi_https)
def test_finder_raises_error(self, monkeypatch): """ Test the PackageFinder raises an error when wheel is not supported """ monkeypatch.delattr('pkg_resources.DistInfoDistribution') # on initialization assert_raises_regexp(InstallationError, 'wheel support', PackageFinder, [], [], use_wheel=True) # when setting property later p = PackageFinder([], [], use_wheel=False) assert_raises_regexp(InstallationError, 'wheel support', self.set_use_wheel_true, p)
def test_missing_hash_with_require_hashes(self, data): """Setting --require-hashes explicitly should raise errors if hashes are missing. """ reqset = self.basic_reqset(require_hashes=True) reqset.add_requirement(list(process_line('simple==1.0', 'file', 1))[0]) finder = PackageFinder([data.find_links], [], session=PipSession()) assert_raises_regexp( HashErrors, r'Hashes are required in --require-hashes mode, but they are ' r'missing .*\n' r' simple==1.0 --hash=sha256:393043e672415891885c9a2a0929b1af95' r'fb866d6ca016b42d2e6ce53619b653$', reqset.prepare_files, finder)
def test_hash_mismatch(self, data): """A hash mismatch should raise an error.""" file_url = path_to_url((data.packages / 'simple-1.0.tar.gz').abspath) reqset = self.basic_reqset(require_hashes=True) reqset.add_requirement( list(process_line('%s --hash=sha256:badbad' % file_url, 'file', 1))[0]) finder = PackageFinder([data.find_links], [], session=PipSession()) assert_raises_regexp( HashErrors, r'THESE PACKAGES DO NOT MATCH THE HASHES.*\n' r' file:///.*/data/packages/simple-1\.0\.tar\.gz .*:\n' r' Expected sha256 badbad\n' r' Got 393043e672415891885c9a2a0929b1af95fb866d' r'6ca016b42d2e6ce53619b653$', reqset.prepare_files, finder)
def test_finder_raises_error(self, mock_get_distribution): """ Test the PackageFinder raises an error when wheel is not supported """ mock_get_distribution.side_effect = self.raise_not_found # on initialization assert_raises_regexp(InstallationError, 'wheel support', PackageFinder, [], [], use_wheel=True) # when setting property later p = PackageFinder([], []) assert_raises_regexp(InstallationError, 'wheel support', self.set_use_wheel_true, p)
def test_no_reuse_existing_build_dir(self, data): """Test prepare_files raise exception with previous build dir""" build_dir = os.path.join(self.tempdir, 'build', 'simple') os.makedirs(build_dir) open(os.path.join(build_dir, "setup.py"), 'w') reqset = self.basic_reqset() req = InstallRequirement.from_line('simple') reqset.add_requirement(req) finder = PackageFinder([data.find_links], []) assert_raises_regexp( PreviousBuildDirError, "pip can't proceed with [\s\S]*%s[\s\S]*%s" % (req, build_dir.replace('\\', '\\\\')), reqset.prepare_files, finder)
def test_missing_hash_checking(self): """Make sure prepare_files() raises an error when a requirement has no hash in implicit hash-checking mode. """ reqset = RequirementSet() # No flags here. This tests that detection of later flags nonetheless # requires earlier packages to have hashes: reqset.add_requirement( get_processed_req_from_line('blessings==1.0', lineno=1)) # This flag activates --require-hashes mode: reqset.add_requirement( get_processed_req_from_line( 'tracefront==0.1 --hash=sha256:somehash', lineno=2, )) # This hash should be accepted because it came from the reqs file, not # from the internet: reqset.add_requirement( get_processed_req_from_line( 'https://files.pythonhosted.org/packages/source/m/more-itertools/' 'more-itertools-1.0.tar.gz#md5=b21850c3cfa7efbb70fd662ab5413bdd', lineno=3, )) # The error text should list this as a URL and not `peep==3.1.1`: reqset.add_requirement( get_processed_req_from_line( 'https://files.pythonhosted.org/' 'packages/source/p/peep/peep-3.1.1.tar.gz', lineno=4, )) finder = PackageFinder( [], ['https://pypi.org/simple/'], session=PipSession(), ) resolver = self._basic_resolver(finder) assert_raises_regexp( HashErrors, r'Hashes are required in --require-hashes mode, but they are ' r'missing .*\n' r' https://files\.pythonhosted\.org/packages/source/p/peep/peep' r'-3\.1\.1\.tar\.gz --hash=sha256:[0-9a-f]+\n' r' blessings==1.0 --hash=sha256:[0-9a-f]+\n' r'THESE PACKAGES DO NOT MATCH THE HASHES.*\n' r' tracefront==0.1 .*:\n' r' Expected sha256 somehash\n' r' Got [0-9a-f]+$', resolver.resolve, reqset)
def test_missing_hash_with_require_hashes(self, data): """Setting --require-hashes explicitly should raise errors if hashes are missing. """ reqset = RequirementSet(require_hashes=True) reqset.add_requirement( get_processed_req_from_line('simple==1.0', lineno=1)) finder = PackageFinder([data.find_links], [], session=PipSession()) resolver = self._basic_resolver(finder) assert_raises_regexp( HashErrors, r'Hashes are required in --require-hashes mode, but they are ' r'missing .*\n' r' simple==1.0 --hash=sha256:393043e672415891885c9a2a0929b1af95' r'fb866d6ca016b42d2e6ce53619b653$', resolver.resolve, reqset)
def test_unhashed_deps_on_require_hashes(self, data): """Make sure unhashed, unpinned, or otherwise unrepeatable dependencies get complained about when --require-hashes is on.""" reqset = RequirementSet() finder = PackageFinder([data.find_links], [], session=PipSession()) resolver = self._basic_resolver(finder) reqset.add_requirement( get_processed_req_from_line( 'TopoRequires2==0.0.1 ' # requires TopoRequires '--hash=sha256:eaf9a01242c9f2f42cf2bd82a6a848cd' 'e3591d14f7896bdbefcf48543720c970', lineno=1)) assert_raises_regexp( HashErrors, r'In --require-hashes mode, all requirements must have their ' r'versions pinned.*\n' r' TopoRequires from .*$', resolver.resolve, reqset)
def test_hash_mismatch(self, data): """A hash mismatch should raise an error.""" file_url = path_to_url((data.packages / 'simple-1.0.tar.gz').abspath) reqset = RequirementSet(require_hashes=True) reqset.add_requirement( get_processed_req_from_line( '%s --hash=sha256:badbad' % file_url, lineno=1, )) finder = make_test_finder(find_links=[data.find_links]) resolver = self._basic_resolver(finder) assert_raises_regexp( HashErrors, r'THESE PACKAGES DO NOT MATCH THE HASHES.*\n' r' file:///.*/data/packages/simple-1\.0\.tar\.gz .*:\n' r' Expected sha256 badbad\n' r' Got 393043e672415891885c9a2a0929b1af95fb866d' r'6ca016b42d2e6ce53619b653$', resolver.resolve, reqset)
def test_no_reuse_existing_build_dir(self, data): """Test prepare_files raise exception with previous build dir""" build_dir = os.path.join(self.tempdir, 'build', 'simple') os.makedirs(build_dir) with open(os.path.join(build_dir, "setup.py"), 'w'): pass reqset = RequirementSet() req = install_req_from_line('simple') req.is_direct = True reqset.add_requirement(req) finder = PackageFinder([data.find_links], [], session=PipSession()) resolver = self._basic_resolver(finder) assert_raises_regexp( PreviousBuildDirError, r"pip can't proceed with [\s\S]*%s[\s\S]*%s" % (req, build_dir.replace('\\', '\\\\')), resolver.resolve, reqset, )
def test_unsupported_hashes(self, data): """VCS and dir links should raise errors when --require-hashes is on. In addition, complaints about the type of requirement (VCS or dir) should trump the presence or absence of a hash. """ reqset = RequirementSet() reqset.add_requirement( get_processed_req_from_line( 'git+git://github.com/pypa/pip-test-package --hash=sha256:123', lineno=1, )) dir_path = data.packages.joinpath('FSPkg') reqset.add_requirement( get_processed_req_from_line( 'file://{dir_path}'.format(**locals()), lineno=2, )) finder = make_test_finder(find_links=[data.find_links]) sep = os.path.sep if sep == '\\': sep = '\\\\' # This needs to be escaped for the regex with self._basic_resolver(finder, require_hashes=True) as resolver: assert_raises_regexp( HashErrors, r"Can't verify hashes for these requirements because we don't " r"have a way to hash version control repositories:\n" r" git\+git://github\.com/pypa/pip-test-package \(from -r " r"file \(line 1\)\)\n" r"Can't verify hashes for these file:// requirements because " r"they point to directories:\n" r" file://.*{sep}data{sep}packages{sep}FSPkg " r"\(from -r file \(line 2\)\)".format(sep=sep), resolver.resolve, reqset.all_requirements, True, )
def test_no_reuse_existing_build_dir(self, data): """Test prepare_files raise exception with previous build dir""" build_dir = os.path.join(self.tempdir, 'build', 'simple') os.makedirs(build_dir) 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_requirement(req) finder = make_test_finder(find_links=[data.find_links]) with self._basic_resolver(finder) as resolver: assert_raises_regexp( PreviousBuildDirError, 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_missing_hash_with_require_hashes(self, data): """Setting --require-hashes explicitly should raise errors if hashes are missing. """ reqset = RequirementSet() reqset.add_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: assert_raises_regexp( HashErrors, 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, )