def _setup_build(self) -> None: builder = SdistBuilder(self._poetry) setup = self._path / "setup.py" has_setup = setup.exists() if has_setup: self._io.write_error_line( "<warning>A setup.py file already exists. Using it.</warning>") else: with setup.open("w", encoding="utf-8") as f: f.write(decode(builder.build_setup())) try: if self._env.pip_version < Version.from_parts(19, 0): pip_install(self._path, self._env, upgrade=True, editable=True) else: # Temporarily rename pyproject.toml shutil.move(str(self._poetry.file), str(self._poetry.file.with_suffix(".tmp"))) try: pip_install(self._path, self._env, upgrade=True, editable=True) finally: shutil.move( str(self._poetry.file.with_suffix(".tmp")), str(self._poetry.file), ) finally: if not has_setup: os.remove(str(setup))
def install_directory(self, package: "Package") -> Union[str, int]: from cleo.io.null_io import NullIO from poetry.factory import Factory req: Path if package.root_dir: req = (package.root_dir / package.source_url).as_posix() else: req = Path(package.source_url).resolve(strict=False) pyproject = PyProjectTOML(os.path.join(req, "pyproject.toml")) if pyproject.is_poetry_project(): # Even if there is a build system specified # some versions of pip (< 19.0.0) don't understand it # so we need to check the version of pip to know # if we can rely on the build system legacy_pip = self._env.pip_version < self._env.pip_version.__class__( 19, 0, 0) package_poetry = Factory().create_poetry( pyproject.file.path.parent) if package.develop and not package_poetry.package.build_script: from poetry.masonry.builders.editable import EditableBuilder # This is a Poetry package in editable mode # we can use the EditableBuilder without going through pip # to install it, unless it has a build script. builder = EditableBuilder(package_poetry, self._env, NullIO()) builder.build() return 0 elif legacy_pip or package_poetry.package.build_script: from poetry.core.masonry.builders.sdist import SdistBuilder # We need to rely on creating a temporary setup.py # file since the version of pip does not support # build-systems # We also need it for non-PEP-517 packages builder = SdistBuilder(package_poetry) with builder.setup_py(): if package.develop: return pip_editable_install(directory=req, environment=self._env) return pip_install(path=req, environment=self._env, deps=False, upgrade=True) if package.develop: return pip_editable_install(directory=req, environment=self._env) return pip_install(path=req, environment=self._env, deps=False, upgrade=True)
def test_pip_install_with_keyboard_interrupt( tmp_dir: str, tmp_venv: VirtualEnv, fixture_dir: FixtureDirGetter, mocker: MockerFixture, ): file_path = fixture_dir("distributions/demo-0.1.0-py2.py3-none-any.whl") mocker.patch("subprocess.run", side_effect=KeyboardInterrupt()) with pytest.raises(KeyboardInterrupt): pip_install(file_path, tmp_venv) subprocess.run.assert_called_once()
def pip_install(self, req: Path | Link, upgrade: bool = False, editable: bool = False) -> int: try: pip_install(req, self._env, upgrade=upgrade, editable=editable) except EnvCommandError as e: output = decode(e.e.output) if ("KeyboardInterrupt" in output or "ERROR: Operation cancelled by user" in output): return -2 raise return 0
def test_pip_install_link(tmp_dir, tmp_venv, fixture_dir): file_path = Link( path_to_url(fixture_dir("distributions/demo-0.1.0-py2.py3-none-any.whl")) ) result = pip_install(file_path, tmp_venv) assert "Successfully installed demo-0.1.0" in result
def test_pip_install_successful( tmp_dir: str, tmp_venv: VirtualEnv, fixture_dir: FixtureDirGetter ): file_path = fixture_dir("distributions/demo-0.1.0-py2.py3-none-any.whl") result = pip_install(file_path, tmp_venv) assert "Successfully installed demo-0.1.0" in result