Skip to content

Enforce ruff/flake8-comprehensions rules (C4) #4785

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
2 changes: 1 addition & 1 deletion pkg_resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3173,7 +3173,7 @@ def __getattr__(self, attr: str):
def __dir__(self):
return list(
set(super().__dir__())
| set(attr for attr in self._provider.__dir__() if not attr.startswith('_'))
| {attr for attr in self._provider.__dir__() if not attr.startswith('_')}
)

@classmethod
Expand Down
2 changes: 1 addition & 1 deletion pkg_resources/tests/test_pkg_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ class Environment(str):
env = Environment(tmpdir)
tmpdir.chmod(stat.S_IRWXU)
subs = 'home', 'lib', 'scripts', 'data', 'egg-base'
env.paths = dict((dirname, str(tmpdir / dirname)) for dirname in subs)
env.paths = {dirname: str(tmpdir / dirname) for dirname in subs}
list(map(os.mkdir, env.paths.values()))
return env

Expand Down
7 changes: 3 additions & 4 deletions pkg_resources/tests/test_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,7 @@ def test_resolve_conflicts_with_prior(self):
with pytest.raises(VersionConflict) as vc:
ws.resolve(parse_requirements("Foo\nBar\n"))

msg = "Baz 1.0 is installed but Baz==2.0 is required by "
msg += repr(set(['Bar']))
msg = f"Baz 1.0 is installed but Baz==2.0 is required by { {'Bar'}!r}"
assert vc.value.report() == msg


Expand Down Expand Up @@ -561,8 +560,8 @@ def testOptionsAndHashing(self):
r1 = Requirement.parse("Twisted[foo,bar]>=1.2")
r2 = Requirement.parse("Twisted[bar,FOO]>=1.2")
assert r1 == r2
assert set(r1.extras) == set(("foo", "bar"))
assert set(r2.extras) == set(("foo", "bar"))
assert set(r1.extras) == {"foo", "bar"}
assert set(r2.extras) == {"foo", "bar"}
assert hash(r1) == hash(r2)
assert hash(r1) == hash((
"twisted",
Expand Down
4 changes: 4 additions & 0 deletions ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ extend-select = [

# local
"ANN2", # missing-return-type-*
"C4", # flake8-comprehensions
"PERF", # Perflint
"PGH", # pygrep-hooks (blanket-* rules)
"PT", # flake8-pytest-style
Expand Down Expand Up @@ -86,6 +87,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
Expand Down
4 changes: 2 additions & 2 deletions setuptools/_discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
6 changes: 3 additions & 3 deletions setuptools/command/_requirestxt.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
8 changes: 4 additions & 4 deletions setuptools/command/build_clib.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ 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)

# 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}'), "
Expand All @@ -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}'), "
Expand All @@ -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}'), "
Expand Down
2 changes: 1 addition & 1 deletion setuptools/command/build_ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,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'
Expand Down
2 changes: 1 addition & 1 deletion setuptools/dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,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)

Expand Down
2 changes: 1 addition & 1 deletion setuptools/msvc.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class winreg:
HKEY_LOCAL_MACHINE = None
HKEY_CLASSES_ROOT = None

environ: dict[str, str] = dict()
environ: dict[str, str] = {}


class PlatformInfo:
Expand Down
6 changes: 3 additions & 3 deletions setuptools/tests/config/test_expand.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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}
Expand Down Expand Up @@ -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)
Expand Down
10 changes: 5 additions & 5 deletions setuptools/tests/config/test_setupcfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,11 +354,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')
Expand Down Expand Up @@ -602,11 +602,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'
Expand All @@ -630,7 +630,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(
Expand Down
2 changes: 1 addition & 1 deletion setuptools/tests/contexts.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion setuptools/tests/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]

Expand Down
2 changes: 1 addition & 1 deletion setuptools/tests/test_bdist_egg.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion setuptools/tests/test_build_py.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion setuptools/tests/test_egg_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -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']: {
Expand Down
4 changes: 2 additions & 2 deletions setuptools/tests/test_glob.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,5 @@
)
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))
path.build(dict.fromkeys(tree.split(), ''))
assert sorted(glob(pattern)) == sorted(matches)
26 changes: 13 additions & 13 deletions setuptools/tests/test_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Expand All @@ -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):
Expand All @@ -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):
Expand All @@ -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):
Expand All @@ -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):
Expand All @@ -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()


Expand Down
2 changes: 1 addition & 1 deletion setuptools/tests/test_sdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,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
Expand Down
10 changes: 5 additions & 5 deletions setuptools/tests/test_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,11 @@ def build_wheel(extra_file_defs=None, **kwargs):


def tree_set(root):
contents = set()
for dirpath, dirnames, filenames in os.walk(root):
for filename in filenames:
contents.add(os.path.join(os.path.relpath(dirpath, root), filename))
return contents
return {
os.path.join(os.path.relpath(dirpath, root), filename)
for dirpath, dirnames, filenames in os.walk(root)
for filename in filenames
}


def flatten_tree(tree):
Expand Down
Loading
Loading