From f775e60bc02d2cbc0c6c24500750f7e7768aface Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 22 May 2021 18:54:37 -0400 Subject: [PATCH] Replace for/if/add/extend with generator on patterns. Use unique_everseen to dedupe. --- setuptools/dist.py | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/setuptools/dist.py b/setuptools/dist.py index 5117681a53d..fb8a6ec4724 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -18,7 +18,7 @@ from glob import iglob import itertools import textwrap -from typing import List, Optional, Set, TYPE_CHECKING +from typing import List, Optional, TYPE_CHECKING from collections import defaultdict from email import message_from_file @@ -573,7 +573,6 @@ def _clean_req(self, req): def _finalize_license_files(self): """Compute names of all license files which should be included.""" - files: List[str] = [] license_files: Optional[List[str]] = self.metadata.license_files patterns: List[str] = license_files if license_files else [] @@ -587,16 +586,18 @@ def _finalize_license_files(self): # -> 'Including license files in the generated wheel file' patterns = ('LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*') - for pattern in patterns: - files_pattern: Set[str] = set() - for path in iglob(pattern): - if path.endswith('~'): - continue - if path not in files and os.path.isfile(path): - files_pattern.add(path) - files.extend(sorted(files_pattern)) + self.metadata.license_files = list( + unique_everseen(self._expand_patterns(patterns))) - self.metadata.license_files = files + @staticmethod + def _expand_patterns(patterns): + return ( + path + for pattern in patterns + for path in iglob(pattern) + if not path.endswith('~') + and os.path.isfile(path) + ) # FIXME: 'Distribution._parse_config_files' is too complex (14) def _parse_config_files(self, filenames=None): # noqa: C901 @@ -1103,3 +1104,21 @@ def handle_display_options(self, option_order): class DistDeprecationWarning(SetuptoolsDeprecationWarning): """Class for warning about deprecations in dist in setuptools. Not ignored by default, unlike DeprecationWarning.""" + + +def unique_everseen(iterable, key=None): + "List unique elements, preserving order. Remember all elements ever seen." + # unique_everseen('AAAABBBCCDAABBB') --> A B C D + # unique_everseen('ABBCcAD', str.lower) --> A B C D + seen = set() + seen_add = seen.add + if key is None: + for element in itertools.filterfalse(seen.__contains__, iterable): + seen_add(element) + yield element + else: + for element in iterable: + k = key(element) + if k not in seen: + seen_add(k) + yield element