def test_format_specifier(): ireq = Requirement.from_line('foo').as_ireq() assert utils.format_specifier(ireq) == '<any>' ireq = Requirement.from_line('foo==1.2').as_ireq() assert utils.format_specifier(ireq) == '==1.2' ireq = Requirement.from_line('foo>1.2,~=1.1,<1.5').as_ireq() assert utils.format_specifier(ireq) == '~=1.1,>1.2,<1.5' ireq = Requirement.from_line('foo~=1.1,<1.5,>1.2').as_ireq() assert utils.format_specifier(ireq) == '~=1.1,>1.2,<1.5'
def test_format_specifier(): ireq = Requirement.from_line("foo").as_ireq() assert utils.format_specifier(ireq) == "<any>" ireq = Requirement.from_line("foo==1.2").as_ireq() assert utils.format_specifier(ireq) == "==1.2" ireq = Requirement.from_line("foo>1.2,~=1.1,<1.5").as_ireq() assert utils.format_specifier(ireq) == "~=1.1,>1.2,<1.5" ireq = Requirement.from_line("foo~=1.1,<1.5,>1.2").as_ireq() assert utils.format_specifier(ireq) == "~=1.1,>1.2,<1.5"
def test_convert_from_pip_fail_if_no_egg(): """Parsing should fail without `#egg=`. """ dep = "git+https://github.com/kennethreitz/requests.git" with pytest.raises(ValueError) as e: dep = Requirement.from_line(dep).as_pipfile() assert "pipenv requires an #egg fragment for vcs" in str(e)
def test_remote_req(url_line, name, requires): r = Requirement.from_line(url_line) assert r.name == name setup_dict = r.req.setup_info.as_dict() if "typing" in requires and not sys.version_info < (3, 5): requires.remove("typing") assert sorted(list(setup_dict.get("requires").keys())) == sorted(requires)
def test_no_duplicate_egg_info(): """When the package has 'src' directory, do not write egg-info in base dir.""" base_dir = vistir.compat.Path(os.path.abspath(os.getcwd())).as_posix() r = Requirement.from_line("-e {}".format(base_dir)) egg_info_name = "{}.egg-info".format(r.name.replace("-", "_")) distinfo_name = "{0}.dist-info".format(r.name.replace("-", "_")) def find_metadata(path): metadata_names = [ os.path.join(path, name) for name in (egg_info_name, distinfo_name) ] if not os.path.isdir(path): return None pth = next(iter(pth for pth in metadata_names if os.path.isdir(pth)), None) if not pth: pth = next( iter(pth for pth in os.listdir(path) if any( pth.endswith(md_ending) for md_ending in [".egg-info", ".dist-info", ".whl"])), None, ) return pth assert not find_metadata(base_dir) assert not find_metadata(os.path.join(base_dir, "src", "reqlib-metadata")) assert r.req.setup_info and os.path.isdir(r.req.setup_info.egg_base) setup_info = r.req.setup_info setup_info.get_info() assert (find_metadata(setup_info.egg_base) or find_metadata(setup_info.extra_kwargs["build_dir"]) or setup_info.get_egg_metadata())
def test_get_dependencies(): r = Requirement.from_line("requests==2.19.1") deps = r.get_dependencies() assert len(deps) > 0 deps_from_ireq = get_dependencies(r.as_ireq()) assert len(deps_from_ireq) > 0 assert sorted(set(deps_from_ireq)) == sorted(set(deps))
def test_stdout_is_suppressed(capsys, tmpdir): r = Requirement.from_line( "git+https://github.com/benjaminp/six.git@master#egg=six") r.req.get_vcs_repo(src_dir=tmpdir.strpath) out, err = capsys.readouterr() assert out.strip() == "", out assert err.strip() == "", err
def test_no_duplicate_egg_info(): """When the package has 'src' directory, do not write egg-info in base dir.""" base_dir = os.path.abspath(os.getcwd()) r = Requirement.from_line("-e {}".format(base_dir)) egg_info_name = "{}.egg-info".format(r.name.replace("-", "_")) assert os.path.isdir(os.path.join(base_dir, "src", egg_info_name)) assert not os.path.isdir(os.path.join(base_dir, egg_info_name))
def test_convert_non_installable_dir_fail(pathlib_tmpdir): """Convert a non-installable directory link should fail without deleting the directory.""" dep = "-e file://{}".format(pathlib_tmpdir.as_posix()) with pytest.raises(RequirementError): req = Requirement.from_line(dep) assert pathlib_tmpdir.exists()
def test_local_req(test_artifact): r = Requirement.from_line(test_artifact.as_posix()) assert r.name == "environ-config" setup_dict = r.req.setup_info.as_dict() assert sorted(list(setup_dict.get("requires").keys())) == [ "attrs", ]
def test_ast_parser_handles_repeated_assignments(setup_py_dir): target = (setup_py_dir.joinpath( "package_with_repeated_assignments").absolute().as_posix()) r = Requirement.from_line(target) setup_dict = r.req.setup_info.as_dict() assert setup_dict["name"] == "test-package-with-repeated-assignments" assert sorted(setup_dict["requires"]) == ["six"]
def test_without_extras(pathlib_tmpdir): """Tests a setup.py or setup.cfg parse when extras returns None for some files.""" setup_dir = pathlib_tmpdir.joinpath("sanitized-package") setup_dir.mkdir() assert setup_dir.is_dir() setup_py = setup_dir.joinpath("setup.py") setup_py.write_text(""" # -*- coding: utf-8 -*- from setuptools import setup setup( name="sanitized-package", version="0.0.1", install_requires=["raven==5.32.0"], extras_require={ 'PDF': ["socks"] } ) """.strip()) setup_dict = None with vistir.contextmanagers.cd(setup_dir.as_posix()): pipfile_entry = { "path": os.path.abspath(os.curdir), "editable": True, "extras": ["socks"], } r = Requirement.from_pipfile("e1839a8", pipfile_entry) r.run_requires() setup_dict = r.req.setup_info.as_dict() assert sorted(list(setup_dict.get("requires").keys())) == ["raven"]
def test_parse_function_call_as_name(setup_py_dir, pathlib_tmpdir): package_dir = pathlib_tmpdir.joinpath( "package_with_function_call_as_name").as_posix() setup_dir = setup_py_dir.joinpath( "package_with_function_call_as_name").as_posix() shutil.copytree(setup_dir, package_dir) req = Requirement.from_line("-e {}".format(package_dir)) assert req.name == "package-with-function-call-as-name"
def test_get_ref(artifact_dir): req_uri = (artifact_dir.joinpath("git/shellingham").as_uri().replace( "file:/", "file:///")) git_uri = "-e git+{0}@1.2.1#egg=shellingham".format(req_uri) r = Requirement.from_line(git_uri) # "-e git+https://github.com/sarugaku/[email protected]#egg=shellingham" # ) assert r.commit_hash == "9abe7464dab5cc362fe08361619d3fb15f2e16ab"
def test_local_editable_ref(monkeypatch): with monkeypatch.context() as m: m.setattr(pip_shims.shims, "unpack_url", mock_unpack) path = Path(ARTIFACTS_DIR) / "git/requests" req = Requirement.from_pipfile( "requests", {"editable": True, "git": path.as_uri(), "ref": "2.18.4"} ) assert req.as_line() == "-e git+{0}@2.18.4#egg=requests".format(path.as_uri())
def test_format_requirement_editable(monkeypatch): with monkeypatch.context() as m: m.setattr(SetupInfo, "get_info", mock_run_requires) m.setattr(Requirement, "run_requires", mock_run_requires) m.setattr(pip_shims.shims, "unpack_url", mock_unpack) ireq = Requirement.from_line( "-e git+git://fake.org/x/y.git#egg=y").as_ireq() assert utils.format_requirement( ireq) == "-e git+git://fake.org/x/y.git#egg=y"
def test_named_requirement_selected_over_non_installable_path( monkeypatch, pathlib_tmpdir): with monkeypatch.context() as m: m.chdir(pathlib_tmpdir.as_posix()) pathlib_tmpdir.joinpath("alembic").write_text(u"") r = Requirement.from_line("alembic") assert isinstance(r.req, NamedRequirement) assert r.as_line() == "alembic" assert r.line_instance.is_named is True
def test_convert_from_pip_git_uri_normalize(monkeypatch): """Pip does not parse this correctly, but we can (by converting to ssh://). """ with monkeypatch.context() as m: m.setattr(Requirement, "run_requires", mock_run_requires) m.setattr(SetupInfo, "get_info", mock_run_requires) m.setattr(pip_shims.shims, "unpack_url", mock_unpack) dep = "git+git@host:user/repo.git#egg=myname" dep = Requirement.from_line(dep).as_pipfile() assert dep == {"myname": {"git": "git@host:user/repo.git"}}
def get_abstract_deps(): r = Requirement.from_line("requests") deps = [InstallRequirement.from_line(d) for d in r.get_dependencies()] abstract_deps = r.get_abstract_dependencies() req_abstract_dep = AbstractDependency.from_requirement(r) assert r.abstract_dep == req_abstract_dep assert len(abstract_deps) > 0 deps_from_ireqs = get_abstract_dependencies(deps, parent=r) assert len(deps_from_ireqs) > 0 assert sorted(set(deps_from_ireqs)) == sorted(set(abstract_deps))
def test_extras(pathlib_tmpdir): """Test named extras as a dependency""" setup_dir = pathlib_tmpdir.joinpath("test_package") setup_dir.mkdir() assert setup_dir.is_dir() setup_py = setup_dir.joinpath("setup.py") setup_py.write_text(u""" import os from setuptools import setup, find_packages thisdir = os.path.abspath(os.path.dirname(__file__)) version = "1.0.0" testing_extras = [ 'coverage', 'flaky', ] setup( name='test_package', version=version, description="The Backend HTTP Server", long_description="This is a package", install_requires=[ 'six', ], tests_require=testing_extras, extras_require={ 'testing': testing_extras, }, package_dir={"": "src"}, packages=['test_package'], include_package_data=True, zip_safe=False, ) """.strip()) src_dir = setup_dir.joinpath("src") src_dir.mkdir() pkg_dir = src_dir.joinpath("test_package") pkg_dir.mkdir() pkg_dir.joinpath("__init__.py").write_text(u"") pipfile_entry = { "path": "./{0}".format(setup_dir.name), "extras": ["testing"], "editable": True } setup_dict = None with vistir.contextmanagers.cd(pathlib_tmpdir.as_posix()): r = Requirement.from_pipfile("test-package", pipfile_entry) assert r.name == "test-package" r.req.setup_info.get_info() setup_dict = r.req.setup_info.as_dict() assert sorted(list(setup_dict.get("requires").keys())) == [ "coverage", "flaky", "six" ], setup_dict
def test_convert_from_pipfile_vcs(monkeypatch): """ssh VCS links should be converted correctly""" with monkeypatch.context() as m: m.setattr(pip_shims.shims, "unpack_url", mock_unpack) pkg_name = "shellingham" pkg_pipfile = {"editable": True, "git": "[email protected]:sarugaku/shellingham.git"} req = Requirement.from_pipfile(pkg_name, pkg_pipfile) assert ( req.req.link.url == "git+ssh://[email protected]/sarugaku/shellingham.git#egg=shellingham" )
def test_convert_from_pipfile(monkeypatch, requirement, expected): with monkeypatch.context() as m: m.setattr(pip_shims.shims, "unpack_url", mock_unpack) m.setattr(SetupInfo, "get_info", mock_run_requires) m.setattr(Requirement, "run_requires", mock_run_requires) pkg_name = first(requirement.keys()) pkg_pipfile = requirement[pkg_name] req = Requirement.from_pipfile(pkg_name, pkg_pipfile) if " (" in expected and expected.endswith(")"): # To strip out plette[validation] (>=0.1.1) expected = expected.replace(" (", "").rstrip(")") assert req.as_line() == expected.lower() if "://" not in expected else expected
def test_get_local_ref(tmpdir): # TODO: add this as a git submodule and don't clone it from the internet all the time six_dir = tmpdir.join("six") import vistir c = vistir.misc.run( ["git", "clone", "https://github.com/benjaminp/six.git", six_dir.strpath], return_object=True, nospin=True, ) assert c.returncode == 0 r = Requirement.from_line("git+{0}#egg=six".format(Path(six_dir.strpath).as_uri())) assert r.commit_hash
def test_vcs_requirement_with_env_vars(): with temp_environ(): os.environ["GIT_URL"] = "github.com" r = Requirement.from_pipfile("click", { "git": "https://${GIT_URL}/pallets/click.git", "ref": "6.7" }) assert (r.as_ireq().link.url_without_fragment == "git+https://github.com/pallets/[email protected]") assert r.as_line( ) == "git+https://${GIT_URL}/pallets/[email protected]#egg=click" assert r.as_pipfile( )["click"]["git"] == "https://${GIT_URL}/pallets/click.git" assert r.commit_hash == "df0e37dd890d36fc997986ae6d2b6c255f3ed1dc"
def test_as_tuple(): ireq = Requirement.from_line("foo==1.1").as_ireq() name, version, extras = utils.as_tuple(ireq) assert name == "foo" assert version == "1.1" assert extras == () ireq = Requirement.from_line("foo[extra1,extra2]==1.1").as_ireq() name, version, extras = utils.as_tuple(ireq) assert name == "foo" assert version == "1.1" assert extras == ("extra1", "extra2") # Non-pinned versions aren't accepted should_be_rejected = [ "foo==1.*", "foo~=1.1,<1.5,>1.2", "foo", ] for spec in should_be_rejected: ireq = Requirement.from_line(spec).as_ireq() with pytest.raises(TypeError): utils.as_tuple(ireq)
def test_pep_508(): r = Requirement.from_line( "tablib@ https://codeload.github.com/jazzband/tablib/zip/v0.12.1") assert r.specifiers == "==0.12.1" assert ( r.req.link.url == "https://codeload.github.com/jazzband/tablib/zip/v0.12.1#egg=tablib") assert r.req.req.name == "tablib" assert r.req.req.url == "https://codeload.github.com/jazzband/tablib/zip/v0.12.1" requires, setup_requires, build_requires = r.req.dependencies assert all(dep in requires for dep in ["openpyxl", "odfpy", "xlrd"]) assert r.as_pipfile() == { "tablib": { "file": "https://codeload.github.com/jazzband/tablib/zip/v0.12.1" } }
def test_file_url_with_percent_encoding(): r = Requirement.from_pipfile( "torch", { "file": "https://download.pytorch.org/whl/cpu/torch-1.7.0%2Bcpu-cp38-cp38-linux_x86_64.whl#egg=torch" }, ) assert ( r.req.uri == "https://download.pytorch.org/whl/cpu/torch-1.7.0%2Bcpu-cp38-cp38-linux_x86_64.whl" ) assert ( r.as_line() == "https://download.pytorch.org/whl/cpu/torch-1.7.0%2Bcpu-cp38-cp38-linux_x86_64.whl#egg=torch" )
def test_convert_from_pip(monkeypatch, expected, requirement): with monkeypatch.context() as m: m.setattr(Requirement, "run_requires", mock_run_requires) m.setattr(SetupInfo, "get_info", mock_run_requires) m.setattr(Line, "get_setup_info", mock_run_requires) m.setattr(pip_shims.shims, "unpack_url", mock_unpack) pkg_name = next(iter(expected.keys())) pkg_pipfile = expected[pkg_name] line = Line(requirement) if (hasattr(pkg_pipfile, "keys") and "editable" in pkg_pipfile and not pkg_pipfile["editable"]): del expected[pkg_name]["editable"] req = Requirement.from_line(requirement) assert req.as_pipfile() == expected assert line.line_with_prefix == req.as_line(include_hashes=False) assert hash(Line(line.line_with_prefix)) == hash( Line(line.line_with_prefix))
def test_extras(pathlib_tmpdir, setup_py_dir, setup_py_name, extras, dependencies): """Test named extras as a dependency.""" setup_dir = pathlib_tmpdir.joinpath("test_package") shutil.copytree(setup_py_dir.joinpath(setup_py_name).as_posix(), setup_dir.as_posix()) assert setup_dir.is_dir() pipfile_entry = { "path": "./{0}".format(setup_dir.name), "extras": extras, "editable": True, } setup_dict = None with vistir.contextmanagers.cd(pathlib_tmpdir.as_posix()): r = Requirement.from_pipfile("test-package", pipfile_entry) assert r.name == "test-package" r.req.setup_info.get_info() setup_dict = r.req.setup_info.as_dict() assert sorted(list(setup_dict.get("requires").keys())) == dependencies
def test_remote_requirement_with_env_vars(): with temp_environ(): os.environ["USERNAME"] = "******" os.environ["PASSWORD"] = "******" r = Requirement.from_line( "https://${USERNAME}:${PASSWORD}@codeload.github.com/jazzband/tablib/zip/v0.12.1#egg=tablib" ) assert ( r.as_ireq().link.url_without_fragment == "https://*****:*****@codeload.github.com/jazzband/tablib/zip/v0.12.1") assert ( r.as_line() == "https://${USERNAME}:${PASSWORD}@codeload.github.com/jazzband/tablib/zip/v0.12.1#egg=tablib" ) assert ( r.as_pipfile()["tablib"]["file"] == "https://${USERNAME}:${PASSWORD}@codeload.github.com/jazzband/tablib/zip/v0.12.1" )