def _factory( name=None, dependencies=None, dev_dependencies=None, pyproject_content=None, poetry_lock_content=None, install_deps=True, ): project_dir = workspace / "poetry-fixture-{}".format(name) dependencies = dependencies or {} dev_dependencies = dev_dependencies or {} if pyproject_content: project_dir.mkdir(parents=True, exist_ok=True) with project_dir.joinpath("pyproject.toml").open( "w", encoding="utf-8") as f: f.write(pyproject_content) else: layout("src")( name, "0.1.0", author="PyTest Tester <*****@*****.**>", readme_format="md", python=default_python, dependencies=dependencies, dev_dependencies=dev_dependencies, ).create(project_dir, with_tests=False) if poetry_lock_content: lock_file = project_dir / "poetry.lock" lock_file.write_text(data=poetry_lock_content, encoding="utf-8") poetry = Factory().create_poetry(project_dir) locker = TestLocker(poetry.locker.lock.path, poetry.locker._local_config) # noqa locker.write() poetry.set_locker(locker) poetry.set_config(config) pool = Pool() pool.add_repository(repo) poetry.set_pool(pool) if install_deps: for deps in [dependencies, dev_dependencies]: for name, version in deps.items(): pkg = get_package(name, version) repo.add_package(pkg) installed.add_package(pkg) return poetry
def poetry(self) -> "Poetry": from pathlib import Path from poetry.factory import Factory if self._poetry is not None: return self._poetry self._poetry = Factory().create_poetry(Path.cwd()) return self._poetry
def test_uploader_registers_for_appropriate_400_errors(mocker, http): register = mocker.patch("poetry.masonry.publishing.uploader.Uploader._register") http.register_uri( http.POST, "https://foo.com", status=400, body="No package was ever registered" ) uploader = Uploader(Factory().create_poetry(project("simple_project")), NullIO()) with pytest.raises(UploadError): uploader.upload("https://foo.com") assert 1 == register.call_count
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 test_create_poetry_with_plugins(mocker: "MockerFixture"): mocker.patch( "entrypoints.get_group_all", return_value=[ EntryPoint("my-plugin", "tests.test_factory", "MyPlugin") ], ) poetry = Factory().create_poetry(fixtures_dir / "sample_project") assert poetry.package.version.text == "9.9.9"
def test_create_poetry_with_plugins(mocker: MockerFixture): mocker.patch( "entrypoints.get_group_all", return_value=[ EntryPoint("my-plugin", "tests.test_factory", "MyPlugin") ], ) poetry = Factory().create_poetry(fixtures_dir / "sample_project") assert poetry.package.readmes == ("README.md", )
def test_metadata_homepage_default(): builder = Builder( Factory().create_poetry( Path(__file__).parent / "fixtures" / "simple_version"), NullEnv(), NullIO(), ) metadata = Parser().parsestr(builder.get_metadata_content()) assert metadata["Home-page"] is None
def test_create_poetry_fails_on_invalid_configuration(): with pytest.raises(RuntimeError) as e: Factory().create_poetry( Path(__file__).parent / "fixtures" / "invalid_pyproject" / "pyproject.toml") expected = """\ The Poetry configuration is invalid: - 'description' is a required property """ assert expected == str(e.value)
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
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_wheel_package(): module_path = fixtures_dir / "complete" WheelBuilder.make(Factory().create_poetry(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_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 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_uploader_properly_handles_403_errors(http): http.register_uri(http.POST, "https://foo.com", status=403, body="Unauthorized") uploader = Uploader(Factory().create_poetry(project("simple_project")), NullIO()) with pytest.raises(UploadError) as e: uploader.upload("https://foo.com") assert "HTTP Error 403: Forbidden" == str(e.value)
def test_wheel_localversionlabel(): module_path = fixtures_dir / "localversionlabel" WheelBuilder.make(Factory().create_poetry(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_publish_raises_error_for_undefined_repository( fixture_dir: FixtureDirGetter, config: Config ): poetry = Factory().create_poetry(fixture_dir("sample_project")) poetry._config = config poetry.config.merge( {"http-basic": {"my-repo": {"username": "******", "password": "******"}}} ) publisher = Publisher(poetry, NullIO()) with pytest.raises(RuntimeError): publisher.publish("my-repo", None, None)
def test_display_single_local_setting( command_tester_factory: CommandTesterFactory, fixture_dir: FixtureDirGetter): tester = command_tester_factory("config", poetry=Factory().create_poetry( fixture_dir("with_local_config"))) tester.execute("virtualenvs.create") expected = """false """ assert tester.io.fetch_output() == expected
def poetry(self) -> "Poetry": from pathlib import Path from poetry.factory import Factory if self._poetry is not None: return self._poetry self._poetry = Factory().create_poetry( Path.cwd(), io=self._io, disable_plugins=self._disable_plugins) return self._poetry
def test_poetry_with_non_default_source(with_simple_keyring: None): poetry = Factory().create_poetry(fixtures_dir / "with_non_default_source") assert len(poetry.pool.repositories) == 2 assert not poetry.pool.has_default() assert poetry.pool.repositories[0].name == "foo" assert isinstance(poetry.pool.repositories[0], LegacyRepository) assert poetry.pool.repositories[1].name == "PyPI" assert isinstance(poetry.pool.repositories[1], PyPiRepository)
def test_module(): poetry = Factory().create_poetry(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()
def test_package(): poetry = Factory().create_poetry(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 install_directory(self, package): from poetry.masonry.builder import SdistBuilder from poetry.factory import Factory 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( Factory().create_poetry(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) try: return self.run(*args) finally: if not has_setup and os.path.exists(setup): os.remove(setup)
def test_metadata_with_vcs_dependencies(): builder = Builder( Factory().create_poetry( Path(__file__).parent / "fixtures" / "with_vcs_dependency"), NullEnv(), NullIO(), ) metadata = Parser().parsestr(builder.get_metadata_content()) requires_dist = metadata["Requires-Dist"] assert "cleo @ git+https://github.com/sdispater/cleo.git@master" == requires_dist
def test_builder_find_invalid_case_sensitive_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" / "invalid_case_sensitive_exclusions"), NullEnv(), NullIO(), ) assert {"my_package/Bar/foo/bar/Foo.py"} == builder.find_excluded_files()
def test_wheel_excluded_data(): module_path = fixtures_dir / "default_with_excluded_data_toml" WheelBuilder.make(Factory().create_poetry(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/__init__.py" in z.namelist() assert "my_package/data/sub_data/data2.txt" in z.namelist() assert "my_package/data/sub_data/data3.txt" in z.namelist() assert "my_package/data/data1.txt" not in z.namelist()
def test_excluded_subpackage(): poetry = Factory().create_poetry(project("excluded_subpackage")) 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"] == ["example"]
def test_uploader_properly_handles_301_redirects(http): http.register_uri(http.POST, "https://foo.com", status=301, body="Redirect") uploader = Uploader(Factory().create_poetry(project("simple_project")), NullIO()) with pytest.raises(UploadError) as e: uploader.upload("https://foo.com") assert "Redirects are not supported. Is the URL missing a trailing slash?" == str( e.value)
def test_with_c_extensions_src_layout(): poetry = Factory().create_poetry(project("src_extended")) builder = SdistBuilder(poetry, NullEnv(), NullIO()) builder.build() sdist = fixtures_dir / "src_extended" / "dist" / "extended-0.1.tar.gz" assert sdist.exists() with tarfile.open(str(sdist), "r") as tar: assert "extended-0.1/build.py" in tar.getnames() assert "extended-0.1/src/extended/extended.c" in tar.getnames()
def test_display_single_local_setting(app, config, fixture_dir): poetry = Factory().create_poetry(fixture_dir("with_local_config")) app._poetry = poetry command = app.find("config") tester = CommandTester(command) tester.execute("virtualenvs.create") expected = """false """ assert expected == tester.io.fetch_output()
def build_packages() -> List[Package]: poetry = Factory().create_poetry(Path.cwd()) env = NullEnv() io = NullIO() with TemporaryDirectory() as temp_dir_str: temp_dir = Path(temp_dir_str) wheel_pkg_name = WheelBuilder.make_in(poetry, env, io, temp_dir) pkg_path = temp_dir / wheel_pkg_name pkg_bytes = pkg_path.read_bytes() pkgs = [Package(wheel_pkg_name, pkg_bytes)] return pkgs