From 236dc50ab24ee205498083f6cdd8d3c341805f96 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 31 Dec 2024 11:48:20 +0100 Subject: [PATCH 1/9] Apply ruff/ flake8-comprehensions rule C400 C400 Unnecessary generator (rewrite as a `list` comprehension) --- setuptools/command/build_ext.py | 2 +- setuptools/tests/test_bdist_egg.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setuptools/command/build_ext.py b/setuptools/command/build_ext.py index dbb956db8d..6c9e8990fd 100644 --- a/setuptools/command/build_ext.py +++ b/setuptools/command/build_ext.py @@ -335,7 +335,7 @@ def __get_stubs_outputs(self): ) # pair each base with the extension pairs = itertools.product(ns_ext_bases, self.__get_output_extensions()) - return list(base + fnext for base, fnext in pairs) + return [base + fnext for base, fnext in pairs] def __get_output_extensions(self): yield '.py' diff --git a/setuptools/tests/test_bdist_egg.py b/setuptools/tests/test_bdist_egg.py index 036167dd95..5a97c31831 100644 --- a/setuptools/tests/test_bdist_egg.py +++ b/setuptools/tests/test_bdist_egg.py @@ -68,6 +68,6 @@ def test_exclude_source_files(self): [dist_name] = os.listdir('dist') dist_filename = os.path.join('dist', dist_name) zip = zipfile.ZipFile(dist_filename) - names = list(zi.filename for zi in zip.filelist) + names = [zi.filename for zi in zip.filelist] assert 'hi.pyc' in names assert 'hi.py' not in names From 076dfb1a56cf39ccfb8f23d07cb7613f328c4410 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 31 Dec 2024 11:49:19 +0100 Subject: [PATCH 2/9] Apply ruff/flake8-comprehensions rule C401 C401 Unnecessary generator (rewrite as a `set` comprehension) --- setuptools/_discovery.py | 4 ++-- setuptools/wheel.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/setuptools/_discovery.py b/setuptools/_discovery.py index d1b4a0ee03..d48c870a56 100644 --- a/setuptools/_discovery.py +++ b/setuptools/_discovery.py @@ -10,11 +10,11 @@ def extras_from_dep(dep): markers = packaging.requirements.Requirement(dep).marker._markers except AttributeError: markers = () - return set( + return { marker[2].value for marker in markers if isinstance(marker, tuple) and marker[0].value == 'extra' - ) + } def extras_from_deps(deps): diff --git a/setuptools/wheel.py b/setuptools/wheel.py index 9366303154..24d8d1130e 100644 --- a/setuptools/wheel.py +++ b/setuptools/wheel.py @@ -196,11 +196,11 @@ def for_extra(req): markers = req.marker._markers except AttributeError: markers = () - return set( + return { marker[2].value for marker in markers if isinstance(marker, tuple) and marker[0].value == 'extra' - ) + } install_requires = list( map(raw_req, filter(eval, itertools.filterfalse(for_extra, reqs))) From e8d5bbe9a65fe996dce7fe8400cb3d705094e630 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 31 Dec 2024 11:49:54 +0100 Subject: [PATCH 3/9] Apply ruff/flake8-comprehensions rule C402 C402 Unnecessary generator (rewrite as a `dict` comprehension) --- setuptools/command/_requirestxt.py | 6 +++--- setuptools/tests/contexts.py | 2 +- setuptools/tests/test_egg_info.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/setuptools/command/_requirestxt.py b/setuptools/command/_requirestxt.py index 9029b12514..9e3619099b 100644 --- a/setuptools/command/_requirestxt.py +++ b/setuptools/command/_requirestxt.py @@ -77,11 +77,11 @@ def _move_install_requirements_markers( for r in complex_reqs: extras_require[':' + str(r.marker)].setdefault(r) - expanded_extras = dict( + expanded_extras = { # list(dict.fromkeys(...)) ensures a list of unique strings - (k, list(dict.fromkeys(str(r) for r in map(_clean_req, v)))) + k: list(dict.fromkeys(str(r) for r in map(_clean_req, v))) for k, v in extras_require.items() - ) + } return simple_install_requires, expanded_extras diff --git a/setuptools/tests/contexts.py b/setuptools/tests/contexts.py index 3c931bbd4f..6979b01eb0 100644 --- a/setuptools/tests/contexts.py +++ b/setuptools/tests/contexts.py @@ -27,7 +27,7 @@ def environment(**replacements): In a context, patch the environment with replacements. Pass None values to clear the values. """ - saved = dict((key, os.environ[key]) for key in replacements if key in os.environ) + saved = {key: os.environ[key] for key in replacements if key in os.environ} # remove values that are null remove = (key for (key, value) in replacements.items() if value is None) diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py index 3653be096f..1b57d493ba 100644 --- a/setuptools/tests/test_egg_info.py +++ b/setuptools/tests/test_egg_info.py @@ -31,7 +31,7 @@ def env(): env = Environment(env_dir) os.chmod(env_dir, stat.S_IRWXU) subs = 'home', 'lib', 'scripts', 'data', 'egg-base' - env.paths = dict((dirname, os.path.join(env_dir, dirname)) for dirname in subs) + env.paths = {dirname: os.path.join(env_dir, dirname) for dirname in subs} list(map(os.mkdir, env.paths.values())) path.build({ env.paths['home']: { From 091659df1d66bd1a39b06b19fb7751f4f06aa26f Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 31 Dec 2024 11:50:37 +0100 Subject: [PATCH 4/9] Apply ruff/flake8-comprehensions rule C405 C408 Unnecessary `dict()` call (rewrite as a literal) C405 Unnecessary `list` literal (rewrite as a `set` literal) --- ruff.toml | 3 +++ setuptools/command/build_clib.py | 6 +++--- setuptools/msvc.py | 2 +- setuptools/tests/config/test_setupcfg.py | 10 ++++----- setuptools/tests/environment.py | 2 +- setuptools/tests/test_manifest.py | 26 ++++++++++++------------ 6 files changed, 26 insertions(+), 23 deletions(-) diff --git a/ruff.toml b/ruff.toml index 567074d50a..7cb9c5a152 100644 --- a/ruff.toml +++ b/ruff.toml @@ -89,6 +89,9 @@ sections.delayed = ["distutils"] [lint.flake8-annotations] ignore-fully-untyped = true +[lint.flake8-comprehensions] +allow-dict-calls-with-keyword-arguments = true + [format] # Enable preview to get hugged parenthesis unwrapping and other nice surprises # See https://github.com/jaraco/skeleton/pull/133#issuecomment-2239538373 diff --git a/setuptools/command/build_clib.py b/setuptools/command/build_clib.py index f376f4ce4d..de8211c247 100644 --- a/setuptools/command/build_clib.py +++ b/setuptools/command/build_clib.py @@ -40,7 +40,7 @@ def build_libraries(self, libraries) -> None: # Make sure everything is the correct type. # obj_deps should be a dictionary of keys as sources # and a list/tuple of files that are its dependencies. - obj_deps = build_info.get('obj_deps', dict()) + obj_deps = build_info.get('obj_deps', {}) if not isinstance(obj_deps, dict): raise DistutilsSetupError( f"in 'libraries' option (library '{lib_name}'), " @@ -51,7 +51,7 @@ def build_libraries(self, libraries) -> None: # Get the global dependencies that are specified by the '' key. # These will go into every source's dependency list. - global_deps = obj_deps.get('', list()) + global_deps = obj_deps.get('', []) if not isinstance(global_deps, (list, tuple)): raise DistutilsSetupError( f"in 'libraries' option (library '{lib_name}'), " @@ -64,7 +64,7 @@ def build_libraries(self, libraries) -> None: for source in sources: src_deps = [source] src_deps.extend(global_deps) - extra_deps = obj_deps.get(source, list()) + extra_deps = obj_deps.get(source, []) if not isinstance(extra_deps, (list, tuple)): raise DistutilsSetupError( f"in 'libraries' option (library '{lib_name}'), " diff --git a/setuptools/msvc.py b/setuptools/msvc.py index f506c8222d..ff9868382f 100644 --- a/setuptools/msvc.py +++ b/setuptools/msvc.py @@ -38,7 +38,7 @@ class winreg: HKEY_LOCAL_MACHINE = None HKEY_CLASSES_ROOT = None - environ: dict[str, str] = dict() + environ: dict[str, str] = {} class PlatformInfo: diff --git a/setuptools/tests/config/test_setupcfg.py b/setuptools/tests/config/test_setupcfg.py index 495337a9a5..cb147388a0 100644 --- a/setuptools/tests/config/test_setupcfg.py +++ b/setuptools/tests/config/test_setupcfg.py @@ -357,11 +357,11 @@ def test_usupported_section(self, tmpdir): dist.parse_config_files() def test_classifiers(self, tmpdir): - expected = set([ + expected = { 'Framework :: Django', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.5', - ]) + } # From file. _, config = fake_env(tmpdir, '[metadata]\nclassifiers = file: classifiers\n') @@ -605,11 +605,11 @@ def test_find_directive(self, tmpdir): make_package_dir('sub_two', dir_package) with get_dist(tmpdir) as dist: - assert set(dist.packages) == set([ + assert set(dist.packages) == { 'fake_package', 'fake_package.sub_two', 'fake_package.sub_one', - ]) + } config.write( '[options]\n' @@ -633,7 +633,7 @@ def test_find_directive(self, tmpdir): ' fake_package.sub_one\n' ) with get_dist(tmpdir) as dist: - assert set(dist.packages) == set(['fake_package', 'fake_package.sub_two']) + assert set(dist.packages) == {'fake_package', 'fake_package.sub_two'} def test_find_namespace_directive(self, tmpdir): dir_package, config = fake_env( diff --git a/setuptools/tests/environment.py b/setuptools/tests/environment.py index ed5499ef7d..17e1e37a3f 100644 --- a/setuptools/tests/environment.py +++ b/setuptools/tests/environment.py @@ -49,7 +49,7 @@ def run_setup_py(cmd, pypath=None, path=None, data_stream=0, env=None): code directly to prevent accidental behavior issues """ if env is None: - env = dict() + env = {} for envname in os.environ: env[envname] = os.environ[envname] diff --git a/setuptools/tests/test_manifest.py b/setuptools/tests/test_manifest.py index 903a528db0..1fd8efda35 100644 --- a/setuptools/tests/test_manifest.py +++ b/setuptools/tests/test_manifest.py @@ -227,7 +227,7 @@ def get_files(self): def test_no_manifest(self): """Check a missing MANIFEST.in includes only the standard files.""" - assert (default_files - set(['MANIFEST.in'])) == self.get_files() + assert (default_files - {'MANIFEST.in'}) == self.get_files() def test_empty_files(self): """Check an empty MANIFEST.in includes only the standard files.""" @@ -237,7 +237,7 @@ def test_empty_files(self): def test_include(self): """Include extra rst files in the project root.""" self.make_manifest("include *.rst") - files = default_files | set(['testing.rst', '.hidden.rst']) + files = default_files | {'testing.rst', '.hidden.rst'} assert files == self.get_files() def test_exclude(self): @@ -249,45 +249,45 @@ def test_exclude(self): exclude app/*.txt """ ) - files = default_files | set([ml('app/c.rst')]) + files = default_files | {ml('app/c.rst')} assert files == self.get_files() def test_include_multiple(self): """Include with multiple patterns.""" ml = make_local_path self.make_manifest("include app/*.txt app/static/*") - files = default_files | set([ + files = default_files | { ml('app/a.txt'), ml('app/b.txt'), ml('app/static/app.js'), ml('app/static/app.js.map'), ml('app/static/app.css'), ml('app/static/app.css.map'), - ]) + } assert files == self.get_files() def test_graft(self): """Include the whole app/static/ directory.""" ml = make_local_path self.make_manifest("graft app/static") - files = default_files | set([ + files = default_files | { ml('app/static/app.js'), ml('app/static/app.js.map'), ml('app/static/app.css'), ml('app/static/app.css.map'), - ]) + } assert files == self.get_files() def test_graft_glob_syntax(self): """Include the whole app/static/ directory.""" ml = make_local_path self.make_manifest("graft */static") - files = default_files | set([ + files = default_files | { ml('app/static/app.js'), ml('app/static/app.js.map'), ml('app/static/app.css'), ml('app/static/app.css.map'), - ]) + } assert files == self.get_files() def test_graft_global_exclude(self): @@ -299,7 +299,7 @@ def test_graft_global_exclude(self): global-exclude *.map """ ) - files = default_files | set([ml('app/static/app.js'), ml('app/static/app.css')]) + files = default_files | {ml('app/static/app.js'), ml('app/static/app.css')} assert files == self.get_files() def test_global_include(self): @@ -310,13 +310,13 @@ def test_global_include(self): global-include *.rst *.js *.css """ ) - files = default_files | set([ + files = default_files | { '.hidden.rst', 'testing.rst', ml('app/c.rst'), ml('app/static/app.js'), ml('app/static/app.css'), - ]) + } assert files == self.get_files() def test_graft_prune(self): @@ -328,7 +328,7 @@ def test_graft_prune(self): prune app/static """ ) - files = default_files | set([ml('app/a.txt'), ml('app/b.txt'), ml('app/c.rst')]) + files = default_files | {ml('app/a.txt'), ml('app/b.txt'), ml('app/c.rst')} assert files == self.get_files() From caf023112e91f9b1f27170a4cde15a7d96cb35ce Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 31 Dec 2024 11:53:10 +0100 Subject: [PATCH 5/9] Apply ruff/flake8-comprehensions rule C413 C413 Unnecessary `list` call around `sorted()` --- setuptools/tests/test_glob.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/tests/test_glob.py b/setuptools/tests/test_glob.py index 8d225a4461..0cb87092a2 100644 --- a/setuptools/tests/test_glob.py +++ b/setuptools/tests/test_glob.py @@ -42,4 +42,4 @@ def test_glob(monkeypatch, tmpdir, tree, pattern, matches): monkeypatch.chdir(tmpdir) path.build({name: '' for name in tree.split()}) - assert list(sorted(glob(pattern))) == list(sorted(matches)) + assert sorted(glob(pattern)) == sorted(matches) From e2f15aa17f77ffe18c349f2c6434ca3f2a9f0b84 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 31 Dec 2024 11:53:46 +0100 Subject: [PATCH 6/9] Apply ruff/flake8-comprehensions rule C414 C414 Unnecessary `list` call within `sorted()` --- setuptools/command/build_clib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/command/build_clib.py b/setuptools/command/build_clib.py index de8211c247..92a58f7828 100644 --- a/setuptools/command/build_clib.py +++ b/setuptools/command/build_clib.py @@ -33,7 +33,7 @@ def build_libraries(self, libraries) -> None: "'sources' must be present and must be " "a list of source filenames" ) - sources = sorted(list(sources)) + sources = sorted(sources) log.info("building '%s' library", lib_name) From 553e4d56deea61b8660c72ede81ca3d20f88db47 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 31 Dec 2024 11:54:31 +0100 Subject: [PATCH 7/9] Apply ruff/flake8-comprehensions rule C417 C417 Unnecessary `map` usage (rewrite using a generator expression) --- setuptools/dist.py | 2 +- setuptools/tests/test_build_py.py | 2 +- setuptools/tests/test_sdist.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/setuptools/dist.py b/setuptools/dist.py index a224b3ee44..88c636c500 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -785,7 +785,7 @@ def by_order(hook): defined = metadata.entry_points(group=group) filtered = itertools.filterfalse(self._removed, defined) - loaded = map(lambda e: e.load(), filtered) + loaded = (e.load() for e in filtered) for ep in sorted(loaded, key=by_order): ep(self) diff --git a/setuptools/tests/test_build_py.py b/setuptools/tests/test_build_py.py index 78848f7182..9da5797f2a 100644 --- a/setuptools/tests/test_build_py.py +++ b/setuptools/tests/test_build_py.py @@ -252,7 +252,7 @@ def test_existing_egg_info(tmpdir_cwd, monkeypatch): assert build_py.data_files # Make sure the list of outputs is actually OK - outputs = map(lambda x: x.replace(os.sep, "/"), build_py.get_outputs()) + outputs = (x.replace(os.sep, "/") for x in build_py.get_outputs()) assert outputs example = str(Path(build_py.build_lib, "mypkg/__init__.py")).replace(os.sep, "/") assert example in outputs diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 5b435fe111..b19ccb42c9 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -415,7 +415,7 @@ def test_defaults_case_sensitivity(self, source_dir): # lowercase all names so we can test in a # case-insensitive way to make sure the files # are not included. - manifest = map(lambda x: x.lower(), cmd.filelist.files) + manifest = (x.lower() for x in cmd.filelist.files) assert 'readme.rst' not in manifest, manifest assert 'setup.py' not in manifest, manifest assert 'setup.cfg' not in manifest, manifest From 385f265132288a1128c9bb77aee3bb56107590af Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 31 Dec 2024 11:55:01 +0100 Subject: [PATCH 8/9] Apply ruff/flake8-comprehensions rule C420 C420 Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead --- setuptools/tests/config/test_expand.py | 6 +++--- setuptools/tests/test_glob.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/setuptools/tests/config/test_expand.py b/setuptools/tests/config/test_expand.py index c5710ec63d..71046d1c1f 100644 --- a/setuptools/tests/config/test_expand.py +++ b/setuptools/tests/config/test_expand.py @@ -29,7 +29,7 @@ def test_glob_relative(tmp_path, monkeypatch): "dir1/dir2/a.ini", } - write_files({k: "" for k in files}, tmp_path) + write_files(dict.fromkeys(files, ""), tmp_path) patterns = ["**/*.txt", "[ab].*", "**/[ac].ini"] monkeypatch.chdir(tmp_path) assert set(expand.glob_relative(patterns)) == files @@ -198,7 +198,7 @@ def test_find_packages(tmp_path, args, pkgs): "other/__init__.py", "dir1/dir2/__init__.py", } - write_files({k: "" for k in files}, tmp_path) + write_files(dict.fromkeys(files, ""), tmp_path) package_dir = {} kwargs = {"root_dir": tmp_path, "fill_package_dir": package_dir, **args} @@ -237,7 +237,7 @@ def test_find_packages(tmp_path, args, pkgs): ], ) def test_fill_package_dir(tmp_path, files, where, expected_package_dir): - write_files({k: "" for k in files}, tmp_path) + write_files(dict.fromkeys(files, ""), tmp_path) pkg_dir = {} kwargs = {"root_dir": tmp_path, "fill_package_dir": pkg_dir, "namespaces": False} pkgs = expand.find_packages(where=where, **kwargs) diff --git a/setuptools/tests/test_glob.py b/setuptools/tests/test_glob.py index 0cb87092a2..8805e2f663 100644 --- a/setuptools/tests/test_glob.py +++ b/setuptools/tests/test_glob.py @@ -41,5 +41,5 @@ ) def test_glob(monkeypatch, tmpdir, tree, pattern, matches): monkeypatch.chdir(tmpdir) - path.build({name: '' for name in tree.split()}) + path.build(dict.fromkeys(tree.split(), '')) assert sorted(glob(pattern)) == sorted(matches) From e71437931072f7b92beec06674e098d1395d6869 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 31 Dec 2024 11:57:32 +0100 Subject: [PATCH 9/9] Enforce ruff/flake8-comprehensions rules (C4) --- ruff.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/ruff.toml b/ruff.toml index 7cb9c5a152..2cc84caf36 100644 --- a/ruff.toml +++ b/ruff.toml @@ -26,6 +26,7 @@ extend-select = [ # local "ANN2", # missing-return-type-* + "C4", # flake8-comprehensions "ISC", # flake8-implicit-str-concat "FURB", # refurb "PERF", # Perflint