Example #1
0
File: base.py Project: pi-dal/pdm
    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,
        )
Example #2
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)
Example #3
0
File: base.py Project: pawamoy/pdm
    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("\\/")),
        )
Example #4
0
 def get_shared_env(cls, key: int) -> str:
     if key in cls._shared_envs:
         logger.debug("Reusing shared build env: %s", cls._shared_envs[key])
         return cls._shared_envs[key]
     # We don't save the cache here, instead it will be done after the installation
     # finished.
     return create_tracked_tempdir("-shared", "pdm-build-env-")
Example #5
0
def install_wheel_with_cache(wheel: str,
                             environment: Environment,
                             direct_url: dict[str, Any] | None = None) -> None:
    """Only create .pth files referring to the cached package.
    If the cache doesn't exist, create one.
    """
    wheel_stem = Path(wheel).stem
    cache_path = environment.project.cache("packages") / wheel_stem
    package_cache = CachedPackage(cache_path)
    interpreter = environment.interpreter.executable
    script_kind = _get_kind(environment)
    if not cache_path.is_dir():
        logger.debug("Installing wheel into cached location %s", cache_path)
        cache_path.mkdir(exist_ok=True)
        _install_wheel(
            wheel=wheel,
            interpreter=interpreter,
            script_kind=script_kind,
            scheme_dict=package_cache.scheme(),
        )

    additional_metadata = {"REFER_TO": package_cache.path.as_posix().encode()}

    if direct_url is not None:
        additional_metadata["direct_url.json"] = json.dumps(direct_url,
                                                            indent=2).encode()

    def skip_files(scheme: Scheme, path: str) -> bool:
        return not (scheme == "scripts"
                    or path.split("/")[0].endswith(".dist-info")
                    or path.endswith(".pth"))

    filename = wheel_stem.split("-")[0] + ".pth"
    lib_path = package_cache.scheme()["purelib"]

    dist_info_dir = _install_wheel(
        wheel=wheel,
        interpreter=interpreter,
        script_kind=script_kind,
        scheme_dict=environment.get_paths(),
        excludes=skip_files,
        additional_files=[(None, filename,
                           io.BytesIO(f"{lib_path}\n".encode()))],
        additional_metadata=additional_metadata,
    )
    package_cache.add_referrer(dist_info_dir)
Example #6
0
 def __enter__(self) -> EnvBuilder:
     self._path = tempfile.mkdtemp(prefix="pdm-build-env-")
     paths = get_sys_config_paths(self.executable,
                                  vars={
                                      "base": self._path,
                                      "platbase": self._path
                                  })
     old_path = os.getenv("PATH")
     self._saved_env = {
         "PYTHONPATH":
         paths["purelib"],
         "PATH":
         paths["scripts"]
         if not old_path else os.pathsep.join([paths["scripts"], old_path]),
         "PYTHONNOUSERSITE":
         "1",
         "PDM_PYTHON_PEP582":
         "0",
     }
     logger.debug("Preparing isolated env for PEP 517 build...")
     return self
Example #7
0
File: base.py Project: pawamoy/pdm
 def get_shared_env(cls, key: int) -> str:
     if key in cls._shared_envs:
         logger.debug("Reusing shared build env: %s", cls._shared_envs[key])
         return cls._shared_envs[key]
     # Postpone the cache after installation is done
     return create_tracked_tempdir("-shared", "pdm-build-env-")
Example #8
0
def install_wheel_with_cache(wheel: str,
                             environment: Environment,
                             direct_url: dict[str, Any] | None = None) -> None:
    """Only create .pth files referring to the cached package.
    If the cache doesn't exist, create one.
    """
    wheel_stem = Path(wheel).stem
    cache_path = environment.project.cache("packages") / wheel_stem
    package_cache = CachedPackage(cache_path)
    interpreter = str(environment.interpreter.executable)
    script_kind = _get_kind(environment)
    supports_symlink = (environment.project.config["install.cache_method"]
                        == "symlink" and fs_supports_symlink())
    if not cache_path.is_dir():
        logger.debug("Installing wheel into cached location %s", cache_path)
        cache_path.mkdir(exist_ok=True)
        destination = InstallDestination(
            scheme_dict=package_cache.scheme(),
            interpreter=interpreter,
            script_kind=script_kind,
        )
        _install_wheel(wheel=wheel, destination=destination)

    additional_metadata = {"REFER_TO": package_cache.path.as_posix().encode()}

    if direct_url is not None:
        additional_metadata["direct_url.json"] = json.dumps(direct_url,
                                                            indent=2).encode()

    def skip_files(source: WheelFile, element: WheelContentElement) -> bool:
        root_scheme = _process_WHEEL_file(source)
        scheme, path = _determine_scheme(element[0][0], source, root_scheme)
        return not (
            scheme not in ("purelib", "platlib")
            or path.split("/")[0].endswith(".dist-info")
            # We need to skip the *-nspkg.pth files generated by setuptools'
            # namespace_packages merchanism. See issue#623 for details
            or not supports_symlink and path.endswith(".pth")
            and not path.endswith("-nspkg.pth"))

    additional_contents: list[WheelContentElement] = []
    lib_path = package_cache.scheme()["purelib"]
    if not supports_symlink:
        # HACK: Prefix with aaa_ to make it processed as early as possible
        filename = "aaa_" + wheel_stem.split("-")[0] + ".pth"
        stream = io.BytesIO(f"{lib_path}\n".encode())
        additional_contents.append(
            ((filename, "", str(len(stream.getvalue()))), stream, False))

    destination = InstallDestination(
        scheme_dict=environment.get_paths(),
        interpreter=interpreter,
        script_kind=script_kind,
        symlink_to=lib_path if supports_symlink else None,
    )

    dist_info_dir = _install_wheel(
        wheel=wheel,
        destination=destination,
        excludes=skip_files,
        additional_contents=additional_contents,
        additional_metadata=additional_metadata,
    )
    package_cache.add_referrer(dist_info_dir)