예제 #1
0
    def get_package_paths(cls, sitedir,
                          name):  # type: (Path, str) -> Set[Path]
        """
        Process a .pth file within the site-packages directory, and return any valid
        paths. We skip executable .pth files as there is no reliable means to do this
        without side-effects to current run-time. Mo check is made that the item refers
        to a directory rather than a file, however, in order to maintain backwards
        compatibility, we allow non-existing paths to be discovered. The latter
        behaviour is different to how Python's site-specific hook configuration works.

        Reference: https://docs.python.org/3.8/library/site.html

        :param sitedir: The site-packages directory to search for .pth file.
        :param name: The name of the package to search .pth file for.
        :return: A `Set` of valid `Path` objects.
        """
        paths = set()

        pth_file = sitedir.joinpath("{}.pth".format(name))
        if pth_file.exists():
            with pth_file.open() as f:
                for line in f:
                    line = line.strip()
                    if line and not line.startswith(
                        ("#", "import ", "import\t")):
                        path = Path(line)
                        if not path.is_absolute():
                            path = sitedir.joinpath(path)
                        paths.add(path)

        return paths
예제 #2
0
    def get_package_paths(cls, env, name):  # type: (Env, str) -> Set[Path]
        """
        Process a .pth file within the site-packages directories, and return any valid
        paths. We skip executable .pth files as there is no reliable means to do this
        without side-effects to current run-time. Mo check is made that the item refers
        to a directory rather than a file, however, in order to maintain backwards
        compatibility, we allow non-existing paths to be discovered. The latter
        behaviour is different to how Python's site-specific hook configuration works.

        Reference: https://docs.python.org/3.8/library/site.html

        :param env: The environment to search for the .pth file in.
        :param name: The name of the package to search .pth file for.
        :return: A `Set` of valid `Path` objects.
        """
        paths = set()

        # we identify the candidate pth files to check, this is done so to handle cases
        # where the pth file for foo-bar might have been installed as either foo-bar.pth or
        # foo_bar.pth (expected) in either pure or platform lib directories.
        candidates = itertools.product(
            {env.purelib, env.platlib},
            {name, module_name(name)},
        )

        for lib, module in candidates:
            pth_file = lib.joinpath(module).with_suffix(".pth")
            if not pth_file.exists():
                continue

            with pth_file.open() as f:
                for line in f:
                    line = line.strip()
                    if line and not line.startswith(
                        ("#", "import ", "import\t")):
                        path = Path(line)
                        if not path.is_absolute():
                            try:
                                path = lib.joinpath(path).resolve()
                            except FileNotFoundError:
                                # this is required to handle pathlib oddity on win32 python==3.5
                                path = lib.joinpath(path)
                        paths.add(path)
        return paths