def test_find_packages(): poetry = Poetry.create(project("complete")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) base = project("complete") include = PackageInclude(base, "my_package") pkg_dir, packages, pkg_data = builder.find_packages(include) assert pkg_dir is None assert packages == [ "my_package", "my_package.sub_pkg1", "my_package.sub_pkg2" ] assert pkg_data == { "": ["*"], "my_package": ["data1/*"], "my_package.sub_pkg2": ["data2/*"], } poetry = Poetry.create(project("source_package")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) base = project("source_package") include = PackageInclude(base, "package_src", "src") pkg_dir, packages, pkg_data = builder.find_packages(include) assert pkg_dir == str(base / "src") assert packages == ["package_src"] assert pkg_data == {"": ["*"]}
def test_install_with_trusted_host(config: Config): config.merge({"certificates": {"default": {"cert": False}}}) default = LegacyRepository("default", "https://foo.bar") pool = Pool() pool.add_repository(default, default=True) null_env = NullEnv() installer = PipInstaller(null_env, NullIO(), pool) foo = Package( "foo", "0.0.0", source_type="legacy", source_reference=default.name, source_url=default.url, ) installer.install(foo) assert len(null_env.executed) == 1 cmd = null_env.executed[0] assert "--trusted-host" in cmd cert_index = cmd.index("--trusted-host") assert cmd[cert_index + 1] == "foo.bar"
def test_package_src(): module_path = fixtures_dir / "source_package" builder = CompleteBuilder( Poetry.create(module_path), NullEnv(execute=True), NullIO() ) builder.build() sdist = module_path / "dist" / "package-src-0.1.tar.gz" assert sdist.exists() with tarfile.open(str(sdist), "r") as tar: assert "package-src-0.1/src/package_src/module.py" in tar.getnames() whl = module_path / "dist" / "package_src-0.1-py2.py3-none-any.whl" assert whl.exists() zip = zipfile.ZipFile(str(whl)) try: assert "package_src/__init__.py" in zip.namelist() assert "package_src/module.py" in zip.namelist() finally: zip.close()
def test_install_with_client_cert(): client_path = "path/to/client.pem" pool = Pool() default = LegacyRepository("default", "https://foo.bar", client_cert=Path(client_path)) pool.add_repository(default, default=True) null_env = NullEnv() installer = PipInstaller(null_env, NullIO(), pool) foo = Package( "foo", "0.0.0", source_type="legacy", source_reference=default.name, source_url=default.url, ) installer.install(foo) assert len(null_env.executed) == 1 cmd = null_env.executed[0] assert "--client-cert" in cmd cert_index = cmd.index("--client-cert") # Need to do the str(Path()) bit because Windows paths get modified by Path assert cmd[cert_index + 1] == str(Path(client_path))
def test_install_with_certs(mocker: MockerFixture, key: str, option: str): client_path = "path/to/client.pem" mocker.patch( "poetry.utils.authenticator.Authenticator.get_certs_for_url", return_value={key: client_path}, ) default = LegacyRepository("default", "https://foo.bar") pool = Pool() pool.add_repository(default, default=True) null_env = NullEnv() installer = PipInstaller(null_env, NullIO(), pool) foo = Package( "foo", "0.0.0", source_type="legacy", source_reference=default.name, source_url=default.url, ) installer.install(foo) assert len(null_env.executed) == 1 cmd = null_env.executed[0] assert f"--{option}" in cmd cert_index = cmd.index(f"--{option}") # Need to do the str(Path()) bit because Windows paths get modified by Path assert cmd[cert_index + 1] == str(Path(client_path))
def test_package_with_include(mocker): # Patch git module to return specific excluded files p = mocker.patch("poetry.vcs.git.Git.get_ignored_files") p.return_value = [ str( Path(__file__).parent / "fixtures" / "with-include" / "extra_dir" / "vcs_excluded.txt"), str( Path(__file__).parent / "fixtures" / "with-include" / "extra_dir" / "sub_pkg" / "vcs_excluded.txt"), ] module_path = fixtures_dir / "with-include" WheelBuilder.make(Poetry.create(str(module_path)), NullEnv(), NullIO()) whl = module_path / "dist" / "with_include-1.2.3-py3-none-any.whl" assert whl.exists() with zipfile.ZipFile(str(whl)) as z: names = z.namelist() assert len(names) == len(set(names)) assert "with_include-1.2.3.dist-info/LICENSE" in names assert "extra_dir/__init__.py" in names assert "extra_dir/vcs_excluded.txt" in names assert "extra_dir/sub_pkg/__init__.py" in names assert "extra_dir/sub_pkg/vcs_excluded.txt" not in names assert "my_module.py" in names assert "notes.txt" in names assert "package_with_include/__init__.py" in names
def test_make_setup(): poetry = Poetry.create(project("complete")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) setup = builder.build_setup() setup_ast = ast.parse(setup) setup_ast.body = [n for n in setup_ast.body if isinstance(n, ast.Assign)] ns = {} exec(compile(setup_ast, filename="setup.py", mode="exec"), ns) assert ns["packages"] == [ "my_package", "my_package.sub_pkg1", "my_package.sub_pkg2", ] assert ns["install_requires"] == [ "cachy[msgpack]>=0.2.0,<0.3.0", "cleo>=0.6,<0.7" ] assert ns["entry_points"] == { "console_scripts": [ "extra-script = my_package.extra:main[time]", "my-2nd-script = my_package:main2", "my-script = my_package:main", ] } assert ns["extras_require"] == {"time": ["pendulum>=1.4,<2.0"]}
def test_src_excluded_nested_data(): module_path = fixtures_dir / "exclude_nested_data_toml" poetry = Factory().create_poetry(module_path) builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder.build() sdist = module_path / "dist" / "my-package-1.2.3.tar.gz" assert sdist.exists() with tarfile.open(str(sdist), "r") as tar: names = tar.getnames() assert len(names) == len(set(names)) assert "my-package-1.2.3/LICENSE" in names assert "my-package-1.2.3/README.rst" in names assert "my-package-1.2.3/pyproject.toml" in names assert "my-package-1.2.3/setup.py" in names assert "my-package-1.2.3/PKG-INFO" in names assert "my-package-1.2.3/my_package/__init__.py" in names assert "my-package-1.2.3/my_package/data/sub_data/data2.txt" not in names assert "my-package-1.2.3/my_package/data/sub_data/data3.txt" not in names assert "my-package-1.2.3/my_package/data/data1.txt" not in names assert "my-package-1.2.3/my_package/puplic/publicdata.txt" in names assert "my-package-1.2.3/my_package/public/item1/itemdata1.txt" not in names assert ( "my-package-1.2.3/my_package/public/item1/subitem/subitemdata.txt" not in names ) assert "my-package-1.2.3/my_package/public/item2/itemdata2.txt" not in names
def test_wheel_prerelease(): module_path = fixtures_dir / "prerelease" WheelBuilder.make(Poetry.create(str(module_path)), NullEnv(), NullIO()) whl = module_path / "dist" / "prerelease-0.1b1-py2.py3-none-any.whl" assert whl.exists()
def test_make_pkg_info_any_python(): poetry = Poetry.create(project("module1")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) pkg_info = builder.build_pkg_info() p = Parser() parsed = p.parsestr(to_str(pkg_info)) assert "Requires-Python" not in parsed
def test_package_with_include(mocker): # Patch git module to return specific excluded files p = mocker.patch("poetry.vcs.git.Git.get_ignored_files") p.return_value = [ str( Path(__file__).parent / "fixtures" / "with-include" / "extra_dir" / "vcs_excluded.txt" ), str( Path(__file__).parent / "fixtures" / "with-include" / "extra_dir" / "sub_pkg" / "vcs_excluded.txt" ), ] poetry = Poetry.create(project("with-include")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) # Check setup.py setup = builder.build_setup() setup_ast = ast.parse(setup) setup_ast.body = [n for n in setup_ast.body if isinstance(n, ast.Assign)] ns = {} exec(compile(setup_ast, filename="setup.py", mode="exec"), ns) assert "package_dir" not in ns assert ns["packages"] == ["extra_dir", "extra_dir.sub_pkg", "package_with_include"] assert ns["package_data"] == {"": ["*"]} assert ns["modules"] == ["my_module"] builder.build() sdist = fixtures_dir / "with-include" / "dist" / "with-include-1.2.3.tar.gz" assert sdist.exists() with tarfile.open(str(sdist), "r") as tar: names = tar.getnames() assert len(names) == len(set(names)) assert "with-include-1.2.3/LICENSE" in names assert "with-include-1.2.3/README.rst" in names assert "with-include-1.2.3/extra_dir/__init__.py" in names assert "with-include-1.2.3/extra_dir/vcs_excluded.txt" in names assert "with-include-1.2.3/extra_dir/sub_pkg/__init__.py" in names assert "with-include-1.2.3/extra_dir/sub_pkg/vcs_excluded.txt" not in names assert "with-include-1.2.3/my_module.py" in names assert "with-include-1.2.3/notes.txt" in names assert "with-include-1.2.3/package_with_include/__init__.py" in names assert "with-include-1.2.3/pyproject.toml" in names assert "with-include-1.2.3/setup.py" in names assert "with-include-1.2.3/PKG-INFO" in names
def test_prelease(): poetry = Poetry.create(project("prerelease")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder.build() sdist = fixtures_dir / "prerelease" / "dist" / "prerelease-0.1b1.tar.gz" assert sdist.exists()
def test_proper_python_requires_if_two_digits_precision_version_specified(): poetry = Factory().create_poetry(project("simple_version")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) pkg_info = builder.build_pkg_info() p = Parser() parsed = p.parsestr(to_str(pkg_info)) assert parsed["Requires-Python"] == ">=3.6,<3.7"
def test_default_with_excluded_data(mocker): # Patch git module to return specific excluded files p = mocker.patch("poetry.vcs.git.Git.get_ignored_files") p.return_value = [ ( ( Path(__file__).parent / "fixtures" / "default_with_excluded_data" / "my_package" / "data" / "sub_data" / "data2.txt" ) .relative_to(project("default_with_excluded_data")) .as_posix() ) ] poetry = Factory().create_poetry(project("default_with_excluded_data")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) # Check setup.py setup = builder.build_setup() setup_ast = ast.parse(setup) setup_ast.body = [n for n in setup_ast.body if isinstance(n, ast.Assign)] ns = {} exec(compile(setup_ast, filename="setup.py", mode="exec"), ns) assert "package_dir" not in ns assert ns["packages"] == ["my_package"] assert ns["package_data"] == { "": ["*"], "my_package": ["data/*", "data/sub_data/data3.txt"], } builder.build() sdist = ( fixtures_dir / "default_with_excluded_data" / "dist" / "my-package-1.2.3.tar.gz" ) assert sdist.exists() with tarfile.open(str(sdist), "r") as tar: names = tar.getnames() assert len(names) == len(set(names)) assert "my-package-1.2.3/LICENSE" in names assert "my-package-1.2.3/README.rst" in names assert "my-package-1.2.3/my_package/__init__.py" in names assert "my-package-1.2.3/my_package/data/data1.txt" in names assert "my-package-1.2.3/pyproject.toml" in names assert "my-package-1.2.3/setup.py" in names assert "my-package-1.2.3/PKG-INFO" in names # all last modified times should be set to a valid timestamp for tarinfo in tar.getmembers(): assert 0 < tarinfo.mtime
def test_proper_python_requires_if_three_digits_precision_version_specified(): poetry = Poetry.create(project("single_python")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) pkg_info = builder.build_pkg_info() p = Parser() parsed = p.parsestr(to_str(pkg_info)) assert parsed["Requires-Python"] == "==2.7.15"
def test_make_pkg_info(mocker): get_metadata_content = mocker.patch( "poetry.masonry.builders.builder.Builder.get_metadata_content") poetry = Poetry.create(project("complete")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder.build_pkg_info() assert get_metadata_content.called
def test_wheel_package(): module_path = fixtures_dir / "complete" WheelBuilder.make(Poetry.create(str(module_path)), NullEnv(), NullIO()) whl = module_path / "dist" / "my_package-1.2.3-py3-none-any.whl" assert whl.exists() with zipfile.ZipFile(str(whl)) as z: assert "my_package/sub_pkg1/__init__.py" in z.namelist()
def test_metadata_homepage_default(): builder = Builder( Poetry.create(Path(__file__).parent / "fixtures" / "simple_version"), NullEnv(), NullIO(), ) metadata = Parser().parsestr(builder.get_metadata_content()) assert metadata["Home-page"] is None
def test_wheel_package_pep_561_stub_only_includes_typed_marker(): root = fixtures_dir / "pep_561_stub_only_partial" WheelBuilder.make(Factory().create_poetry(root), NullEnv(), NullIO()) whl = root / "dist" / "pep_561_stubs-0.1-py3-none-any.whl" assert whl.exists() with zipfile.ZipFile(str(whl)) as z: assert "pkg-stubs/py.typed" in z.namelist()
def test_wheel_localversionlabel(): module_path = fixtures_dir / "localversionlabel" WheelBuilder.make(Poetry.create(str(module_path)), NullEnv(), NullIO()) local_version_string = "localversionlabel-0.1b1+gitbranch.buildno.1" whl = module_path / "dist" / (local_version_string + "-py2.py3-none-any.whl") assert whl.exists() with zipfile.ZipFile(str(whl)) as z: assert local_version_string + ".dist-info/METADATA" in z.namelist()
def test_wheel_module_src(): module_path = fixtures_dir / "source_file" WheelBuilder.make(Poetry.create(str(module_path)), NullEnv(), NullIO()) whl = module_path / "dist" / "module_src-0.1-py2.py3-none-any.whl" assert whl.exists() with zipfile.ZipFile(str(whl)) as z: assert "module_src.py" in z.namelist()
def test_wheel_module(): module_path = fixtures_dir / "module1" WheelBuilder.make(Factory().create_poetry(module_path), NullEnv(), NullIO()) whl = module_path / "dist" / "module1-0.1-py2.py3-none-any.whl" assert whl.exists() with zipfile.ZipFile(str(whl)) as z: assert "module1.py" in z.namelist()
def install_directory(self, package): from poetry.io import NullIO from poetry.masonry.builder import SdistBuilder from poetry.poetry import Poetry from poetry.utils._compat import decode from poetry.utils.env import NullEnv from poetry.utils.toml_file import TomlFile if package.root_dir: req = os.path.join(package.root_dir, package.source_url) else: req = os.path.realpath(package.source_url) args = ["install", "--no-deps", "-U"] pyproject = TomlFile(os.path.join(req, "pyproject.toml")) has_poetry = False has_build_system = False if pyproject.exists(): pyproject_content = pyproject.read() has_poetry = ("tool" in pyproject_content and "poetry" in pyproject_content["tool"]) # Even if there is a build system specified # pip as of right now does not support it fully # TODO: Check for pip version when proper PEP-517 support lands # has_build_system = ("build-system" in pyproject_content) setup = os.path.join(req, "setup.py") has_setup = os.path.exists(setup) if not has_setup and has_poetry and (package.develop or not has_build_system): # We actually need to rely on creating a temporary setup.py # file since pip, as of this comment, does not support # build-system for editable packages # We also need it for non-PEP-517 packages builder = SdistBuilder(Poetry.create(pyproject.parent), NullEnv(), NullIO()) with open(setup, "w", encoding="utf-8") as f: f.write(decode(builder.build_setup())) if package.develop: args.append("-e") args.append(req) if self._vendor_path: args += ["-t", self._vendor_path] try: return self.run(*args) finally: if not has_setup and os.path.exists(setup): os.remove(setup)
def test_requirement_source_type_url(): installer = PipInstaller(NullEnv(), NullIO(), Pool()) foo = Package("foo", "0.0.0") foo.source_type = "url" foo.source_url = "https://somehwere.com/releases/foo-1.0.0.tar.gz" result = installer.requirement(foo, formatted=True) expected = "{}#egg={}".format(foo.source_url, foo.name) assert expected == result
def test_wheel_package_src(): module_path = fixtures_dir / "source_package" WheelBuilder.make(Factory().create_poetry(module_path), NullEnv(), NullIO()) whl = module_path / "dist" / "package_src-0.1-py2.py3-none-any.whl" assert whl.exists() with zipfile.ZipFile(str(whl)) as z: assert "package_src/__init__.py" in z.namelist() assert "package_src/module.py" in z.namelist()
def handle(self): from poetry.installation import Installer from poetry.io import NullIO from poetry.masonry.builders import SdistBuilder from poetry.utils._compat import decode from poetry.utils.env import NullEnv installer = Installer( self.output, self.env, self.poetry.package, self.poetry.locker, self.poetry.pool, ) extras = [] for extra in self.option("extras"): if " " in extra: extras += [e.strip() for e in extra.split(" ")] else: extras.append(extra) installer.extras(extras) installer.dev_mode(not self.option("no-dev")) installer.develop(self.option("develop")) installer.dry_run(self.option("dry-run")) installer.verbose(self.option("verbose")) return_code = installer.run() if return_code != 0: return return_code setup = self.poetry.file.parent / "setup.py" has_setup = setup.exists() if has_setup: self.line( "<warning>A setup.py file already exists. Using it.</warning>") else: builder = SdistBuilder(self.poetry, NullEnv(), NullIO()) with setup.open("w") as f: f.write(decode(builder.build_setup())) self.line("Installing <info>{}</info> (<comment>{}</comment>)".format( self.poetry.package.pretty_name, self.poetry.package.pretty_version)) try: self.env.run("pip", "install", "-e", str(setup.parent), "--no-deps") finally: if not has_setup: os.remove(str(setup))
def test_builder_find_excluded_files(mocker): p = mocker.patch("poetry.vcs.git.Git.get_ignored_files") p.return_value = [] builder = Builder( Factory().create_poetry(Path(__file__).parent / "fixtures" / "complete"), NullEnv(), NullIO(), ) assert builder.find_excluded_files() == {"my_package/sub_pkg1/extra_file.xml"}
def test_package(): poetry = Poetry.create(project("complete")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder.build() sdist = fixtures_dir / "complete" / "dist" / "my-package-1.2.3.tar.gz" assert sdist.exists() with tarfile.open(str(sdist), "r") as tar: assert "my-package-1.2.3/LICENSE" in tar.getnames()
def test_wheel_package_pep_561_stub_only(package): root = fixtures_dir / package WheelBuilder.make(Factory().create_poetry(root), NullEnv(), NullIO()) whl = root / "dist" / "pep_561_stubs-0.1-py3-none-any.whl" assert whl.exists() with zipfile.ZipFile(str(whl)) as z: assert "pkg-stubs/__init__.pyi" in z.namelist() assert "pkg-stubs/module.pyi" in z.namelist() assert "pkg-stubs/subpkg/__init__.pyi" in z.namelist()
def test_module(): poetry = Poetry.create(project("module1")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder.build() sdist = fixtures_dir / "module1" / "dist" / "module1-0.1.tar.gz" assert sdist.exists() with tarfile.open(str(sdist), "r") as tar: assert "module1-0.1/module1.py" in tar.getnames()