def __init__(self, src_dir: str | Path, environment: Environment) -> None: self._env = environment self.executable = self._env.interpreter.executable self.src_dir = src_dir logger.debug("Preparing isolated env for PEP 517 build...") try: with open(os.path.join(src_dir, "pyproject.toml"), "rb") as f: spec = tomli.load(f) except FileNotFoundError: spec = {} except Exception as e: raise BuildError(e) from e build_system = spec.get("build-system", self.DEFAULT_BACKEND) if "build-backend" not in build_system: build_system["build-backend"] = self.DEFAULT_BACKEND[ "build-backend"] if "requires" not in build_system: raise BuildError( "Missing 'build-system.requires' in pyproject.toml") self.init_build_system(build_system) self._prefix = _Prefix( self.executable, shared=self.get_shared_env(hash(frozenset(self._requires))), overlay=self.get_overlay_env( os.path.normcase(self.src_dir).rstrip("\\/")), )
def __init__(self, src_dir: str | Path, environment: Environment) -> None: self._env = environment self._path = self.get_env_path(src_dir) self.executable = self._env.interpreter.executable self.src_dir = src_dir self._prefix = _Prefix(self.executable, self._path) logger.debug("Preparing isolated env for PEP 517 build...") try: with open(os.path.join(src_dir, "pyproject.toml"), encoding="utf8") as f: spec = toml.load(f) except FileNotFoundError: spec = {} except Exception as e: raise BuildError(e) from e self._build_system = spec.get("build-system", self.DEFAULT_BACKEND) if "build-backend" not in self._build_system: self._build_system["build-backend"] = self.DEFAULT_BACKEND[ "build-backend"] if "requires" not in self._build_system: raise BuildError( "Missing 'build-system.requires' in pyproject.toml") self._backend = self._build_system["build-backend"] self._hook = Pep517HookCaller( src_dir, self._backend, backend_path=self._build_system.get("backend-path"), runner=self.subprocess_runner, python_executable=self.executable, )
def __init__(self, src_dir: os.PathLike, environment: Environment) -> None: self._env = environment self._path: Optional[str] = None self._saved_env = None self.executable = self._env.python_executable self.src_dir = src_dir try: with open(os.path.join(src_dir, "pyproject.toml"), encoding="utf8") as f: spec = toml.load(f) except FileNotFoundError: spec = {} except Exception as e: raise BuildError(e) from e self._build_system = spec.get("build-system", self.DEFAULT_BACKEND) if "build-backend" not in self._build_system: self._build_system["build-backend"] = self.DEFAULT_BACKEND[ "build-backend"] if "requires" not in self._build_system: raise BuildError( "Missing 'build-system.requires' in pyproject.toml") self._backend = self._build_system["build-backend"] self._hook = Pep517HookCaller( src_dir, self._backend, backend_path=self._build_system.get("backend-path"), runner=self.subprocess_runner, python_executable=self.executable, )
def __init__(self, src_dir: str | Path, environment: Environment) -> None: """If isolated is True(default), the builder will set up a *clean* environment. Otherwise, the environment of the host Python will be used. """ self._env = environment self.executable = self._env.interpreter.executable.as_posix() self.src_dir = src_dir self.isolated = environment.project.config["build_isolation"] logger.debug("Preparing isolated env for PEP 517 build...") try: with open(os.path.join(src_dir, "pyproject.toml"), "rb") as f: spec = tomli.load(f) except FileNotFoundError: spec = {} except Exception as e: raise BuildError(e) from e build_system = spec.get("build-system", self.DEFAULT_BACKEND) if "build-backend" not in build_system: build_system["build-backend"] = self.DEFAULT_BACKEND[ "build-backend"] if "requires" not in build_system: raise BuildError( "Missing 'build-system.requires' in pyproject.toml") self.init_build_system(build_system)
def _find_egg_info(directory: str) -> str: filename = next( (f for f in os.listdir(directory) if f.endswith(".egg-info")), None, ) if not filename: raise BuildError("No egg info is generated.") return filename
def check_requirements(self, reqs: Iterable[str]) -> Iterable[str]: missing = set() conflicting = set() if reqs: ws = WorkingSet(self._prefix.lib_dirs) for req in reqs: try: if ws.find(Requirement.parse(req)) is None: missing.add(req) except VersionConflict: conflicting.add(req) if conflicting: raise BuildError(f"Conflicting requirements: {', '.join(conflicting)}") return missing
def check_requirements(self, reqs: Iterable[str]) -> Iterable[str]: missing = set() conflicting = set() if reqs: ws = WorkingSet(self._prefix.lib_dirs) for req in reqs: parsed_req = parse_requirement(req) if parsed_req.identify() not in ws: missing.add(req) elif parsed_req.specifier and not parsed_req.specifier.contains( ws[parsed_req.identify()].version, prereleases=True): conflicting.add(req) if conflicting: raise BuildError( f"Conflicting requirements: {', '.join(conflicting)}") return missing
def log_subprocessor(cmd, cwd=None, extra_environ=None): env = os.environ.copy() if extra_environ: env.update(extra_environ) outstream = LoggerWrapper(stream.logger, logging.DEBUG) try: subprocess.check_call( cmd, cwd=cwd, env=env, stdout=outstream, stderr=subprocess.STDOUT, ) except subprocess.CalledProcessError: raise BuildError(f"Call command {cmd} return non-zero status.") finally: outstream.stop()
def log_subprocessor( cmd: list[str], cwd: str | Path | None = None, extra_environ: dict[str, str] | None = None, ) -> None: env = os.environ.copy() if extra_environ: env.update(extra_environ) outstream = LoggerWrapper(logger, logging.DEBUG) try: subprocess.check_call( cmd, cwd=cwd, env=env, stdout=outstream.fileno(), stderr=subprocess.STDOUT, ) except subprocess.CalledProcessError: raise BuildError(f"Call command {cmd} return non-zero status.") finally: outstream.stop()
def _download_pip_wheel(self, path: os.PathLike): dirname = Path(tempfile.mkdtemp(prefix="pip-download-")) try: subprocess.check_call( [ getattr(sys, "_original_executable", sys.executable), "-m", "pip", "download", "--only-binary=:all:", "-d", str(dirname), "pip<21", # pip>=21 drops the support of py27 ], ) wheel_file = next(dirname.glob("pip-*.whl")) shutil.move(str(wheel_file), path) except subprocess.CalledProcessError: raise BuildError("Failed to download pip for the given interpreter") finally: shutil.rmtree(dirname, ignore_errors=True)