Exemplo n.º 1
0
    def _build_paths(self, name, spec_path_lists, exists):
        """
        Given an environment variable name and specified paths,
        return a pathsep-separated string of paths containing
        unique, extant, directories from those paths and from
        the environment variable. Raise an error if no paths
        are resolved.

        Parameters
        ----------
        name: str
            Environment variable name
        spec_path_lists: list of str
            Paths
        exists: bool
            It True, only return existing paths.

        Return
        ------
        str
            Pathsep-separated paths
        """
        # flatten spec_path_lists
        spec_paths = itertools.chain.from_iterable(spec_path_lists)
        env_paths = environ.get(name, '').split(pathsep)
        paths = itertools.chain(spec_paths, env_paths)
        extant_paths = list(filter(isdir, paths)) if exists else paths
        if not extant_paths:
            msg = "%s environment variable is empty" % name.upper()
            raise distutils.errors.DistutilsPlatformError(msg)
        unique_paths = unique_everseen(extant_paths)
        return pathsep.join(unique_paths)
Exemplo n.º 2
0
def find_packages(
    *,
    namespaces=True,
    fill_package_dir: Optional[Dict[str, str]] = None,
    root_dir: Optional[_Path] = None,
    **kwargs
) -> List[str]:
    """Works similarly to :func:`setuptools.find_packages`, but with all
    arguments given as keyword arguments. Moreover, ``where`` can be given
    as a list (the results will be simply concatenated).

    When the additional keyword argument ``namespaces`` is ``True``, it will
    behave like :func:`setuptools.find_namespace_packages`` (i.e. include
    implicit namespaces as per :pep:`420`).

    The ``where`` argument will be considered relative to ``root_dir`` (or the current
    working directory when ``root_dir`` is not given).

    If the ``fill_package_dir`` argument is passed, this function will consider it as a
    similar data structure to the ``package_dir`` configuration parameter add fill-in
    any missing package location.

    :rtype: list
    """
    from setuptools.discovery import construct_package_dir
    from setuptools.extern.more_itertools import unique_everseen, always_iterable

    if namespaces:
        from setuptools.discovery import PEP420PackageFinder as PackageFinder
    else:
        from setuptools.discovery import PackageFinder  # type: ignore

    root_dir = root_dir or os.curdir
    where = kwargs.pop('where', ['.'])
    packages: List[str] = []
    fill_package_dir = {} if fill_package_dir is None else fill_package_dir
    search = list(unique_everseen(always_iterable(where)))

    if len(search) == 1 and all(not _same_path(search[0], x) for x in (".", root_dir)):
        fill_package_dir.setdefault("", search[0])

    for path in search:
        package_path = _nest_path(root_dir, path)
        pkgs = PackageFinder.find(package_path, **kwargs)
        packages.extend(pkgs)
        if pkgs and not (
            fill_package_dir.get("") == path
            or os.path.samefile(package_path, root_dir)
        ):
            fill_package_dir.update(construct_package_dir(pkgs, path))

    return packages
Exemplo n.º 3
0
 def exclude_data_files(self, package, src_dir, files):
     """Filter filenames for package's data files in 'src_dir'"""
     files = list(files)
     patterns = self._get_platform_patterns(
         self.exclude_package_data,
         package,
         src_dir,
     )
     match_groups = (fnmatch.filter(files, pattern) for pattern in patterns)
     # flatten the groups of matches into an iterable of matches
     matches = itertools.chain.from_iterable(match_groups)
     bad = set(matches)
     keepers = (fn for fn in files if fn not in bad)
     # ditch dupes
     return list(unique_everseen(keepers))
Exemplo n.º 4
0
    def _finalize_license_files(self):
        """Compute names of all license files which should be included."""
        license_files: Optional[List[str]] = self.metadata.license_files
        patterns: List[str] = license_files if license_files else []

        license_file: Optional[str] = self.metadata.license_file
        if license_file and license_file not in patterns:
            patterns.append(license_file)

        if license_files is None and license_file is None:
            # Default patterns match the ones wheel uses
            # See https://wheel.readthedocs.io/en/stable/user_guide.html
            # -> 'Including license files in the generated wheel file'
            patterns = ('LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*')

        self.metadata.license_files = list(
            unique_everseen(self._expand_patterns(patterns)))
Exemplo n.º 5
0
    def paths_on_pythonpath(paths):
        """
        Add the indicated paths to the head of the PYTHONPATH environment
        variable so that subprocesses will also see the packages at
        these paths.

        Do this in a context that restores the value on exit.
        """
        nothing = object()
        orig_pythonpath = os.environ.get('PYTHONPATH', nothing)
        current_pythonpath = os.environ.get('PYTHONPATH', '')
        try:
            prefix = os.pathsep.join(unique_everseen(paths))
            to_join = filter(None, [prefix, current_pythonpath])
            new_path = os.pathsep.join(to_join)
            if new_path:
                os.environ['PYTHONPATH'] = new_path
            yield
        finally:
            if orig_pythonpath is nothing:
                os.environ.pop('PYTHONPATH', None)
            else:
                os.environ['PYTHONPATH'] = orig_pythonpath
 def wrapper(*args, **kwargs):
     return unique_everseen(func(*args, **kwargs))