Beispiel #1
0
    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("\\/")),
        )
Beispiel #2
0
    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,
        )
Beispiel #3
0
    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,
        )
Beispiel #4
0
    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)
Beispiel #5
0
 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
Beispiel #6
0
 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
Beispiel #7
0
 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
Beispiel #8
0
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()
Beispiel #9
0
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()
Beispiel #10
0
 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)