From 0f08db8eaecb9ebcd5c6db7129e82f714ca4770f Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Wed, 22 Nov 2023 01:31:37 +0100 Subject: [PATCH 01/12] Add pyupgrade rules to ruff config --- ruff.toml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/ruff.toml b/ruff.toml index 795cca162a..791cfdc0a5 100644 --- a/ruff.toml +++ b/ruff.toml @@ -16,7 +16,25 @@ ignore = [ "ISC001", "ISC002", ] +extend-select = [ + "UP", # pyupgrade +] +extend-ignore = [ + "UP015", # redundant-open-modes, explicit is prefered + "UP030", # temporarily disabled + "UP031", # temporarily disabled + "UP032", # temporarily disabled + "UP036", # temporarily disabled +] +extend-exclude = [ + "**/_vendor", + "setuptools/_distutils", +] [format] +extend-exclude = [ + "**/_vendor", + "setuptools/_distutils", +] # https://docs.astral.sh/ruff/settings/#format-quote-style quote-style = "preserve" From ac3bf62dbca0d2284b990de7ae3cf02001f54542 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 20 Nov 2023 22:42:34 +0100 Subject: [PATCH 02/12] "yield from", instead of "yield" in a loop This is a suggestion from pyupgrade: https://github.com/asottile/pyupgrade#yield--yield-from --- setuptools/command/bdist_egg.py | 9 +++------ setuptools/command/easy_install.py | 6 ++---- setuptools/command/sdist.py | 3 +-- setuptools/dist.py | 6 ++---- setuptools/glob.py | 3 +-- setuptools/package_index.py | 8 +++----- 6 files changed, 12 insertions(+), 23 deletions(-) diff --git a/setuptools/command/bdist_egg.py b/setuptools/command/bdist_egg.py index e0947c6624..a4b683f66e 100644 --- a/setuptools/command/bdist_egg.py +++ b/setuptools/command/bdist_egg.py @@ -321,8 +321,7 @@ def walk_egg(egg_dir): if 'EGG-INFO' in dirs: dirs.remove('EGG-INFO') yield base, dirs, files - for bdf in walker: - yield bdf + yield from walker def analyze_egg(egg_dir, stubs): @@ -406,14 +405,12 @@ def scan_module(egg_dir, base, name, stubs): def iter_symbols(code): """Yield names and strings used by `code` and its nested code objects""" - for name in code.co_names: - yield name + yield from code.co_names for const in code.co_consts: if isinstance(const, str): yield const elif isinstance(const, CodeType): - for name in iter_symbols(const): - yield name + yield from iter_symbols(const) def can_scan(): diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 897ec6ad9b..3231650c5c 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1743,8 +1743,7 @@ class RewritePthDistributions(PthDistributions): @classmethod def _wrap_lines(cls, lines): yield cls.prelude - for line in lines: - yield line + yield from lines yield cls.postlude prelude = _one_liner( @@ -2180,8 +2179,7 @@ def get_args(cls, dist, header=None): cls._ensure_safe_name(name) script_text = cls.template % locals() args = cls._get_script_args(type_, name, header, script_text) - for res in args: - yield res + yield from args @staticmethod def _ensure_safe_name(name): diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py index 5f45fb5dee..95d325717a 100644 --- a/setuptools/command/sdist.py +++ b/setuptools/command/sdist.py @@ -14,8 +14,7 @@ def walk_revctrl(dirname=''): """Find all files under revision control""" for ep in metadata.entry_points(group='setuptools.file_finders'): - for item in ep.load()(dirname): - yield item + yield from ep.load()(dirname) class sdist(orig.sdist): diff --git a/setuptools/dist.py b/setuptools/dist.py index c9c8c77515..0d35583dbc 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -912,11 +912,9 @@ def get_cmdline_options(self): def iter_distribution_names(self): """Yield all packages, modules, and extension names in distribution""" - for pkg in self.packages or (): - yield pkg + yield from self.packages or () - for module in self.py_modules or (): - yield module + yield from self.py_modules or () for ext in self.ext_modules or (): if isinstance(ext, tuple): diff --git a/setuptools/glob.py b/setuptools/glob.py index 8dbf34972d..ac901d9253 100644 --- a/setuptools/glob.py +++ b/setuptools/glob.py @@ -113,8 +113,7 @@ def glob0(dirname, basename): def glob2(dirname, pattern): assert _isrecursive(pattern) yield pattern[:0] - for x in _rlistdir(dirname): - yield x + yield from _rlistdir(dirname) # Recursively yields relative pathnames inside a literal directory. diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 3cedd5105c..c491ddb3cc 100644 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -112,15 +112,13 @@ def egg_info_for_url(url): def distros_for_url(url, metadata=None): """Yield egg or source distribution objects that might be found at a URL""" base, fragment = egg_info_for_url(url) - for dist in distros_for_location(url, base, metadata): - yield dist + yield from distros_for_location(url, base, metadata) if fragment: match = EGG_FRAGMENT.match(fragment) if match: - for dist in interpret_distro_name( + yield from interpret_distro_name( url, match.group(1), metadata, precedence=CHECKOUT_DIST - ): - yield dist + ) def distros_for_location(location, basename, metadata=None): From af41360fab5256b7d59118fdcda9b3246e000d02 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 20 Nov 2023 22:44:03 +0100 Subject: [PATCH 03/12] =?UTF-8?q?io.open()=20=E2=86=92=20open()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In Python 3, io.open() is an alias for the builtin open() function. https://docs.python.org/3/library/io.html#io.open This is a suggestion from pyupgrade: https://github.com/asottile/pyupgrade#open-alias --- setuptools/msvc.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setuptools/msvc.py b/setuptools/msvc.py index be373d176e..aa69db5810 100644 --- a/setuptools/msvc.py +++ b/setuptools/msvc.py @@ -12,7 +12,6 @@ """ import json -from io import open from os import listdir, pathsep from os.path import join, isfile, isdir, dirname from subprocess import CalledProcessError From bba79a0a3f1dd450eca23192810acf12d0f758c0 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 20 Nov 2023 22:48:49 +0100 Subject: [PATCH 04/12] Simplify super() calls See PEP 3135: https://peps.python.org/pep-3135/ This is a suggestion from pyupgrade: https://github.com/asottile/pyupgrade#super-calls --- pkg_resources/__init__.py | 4 ++-- setuptools/build_meta.py | 2 +- setuptools/package_index.py | 2 +- setuptools/tests/test_build_meta.py | 4 ++-- setuptools/tests/test_manifest.py | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index ab6afe955d..9adc214676 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -2901,7 +2901,7 @@ def __getattr__(self, attr): def __dir__(self): return list( - set(super(Distribution, self).__dir__()) + set(super().__dir__()) | set(attr for attr in self._provider.__dir__() if not attr.startswith('_')) ) @@ -3168,7 +3168,7 @@ class RequirementParseError(packaging.requirements.InvalidRequirement): class Requirement(packaging.requirements.Requirement): def __init__(self, requirement_string): """DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!""" - super(Requirement, self).__init__(requirement_string) + super().__init__(requirement_string) self.unsafe_name = self.name project_name = safe_name(self.name) self.project_name, self.key = project_name, project_name.lower() diff --git a/setuptools/build_meta.py b/setuptools/build_meta.py index 80ccceff3c..18ebb75c24 100644 --- a/setuptools/build_meta.py +++ b/setuptools/build_meta.py @@ -477,7 +477,7 @@ def run_setup(self, setup_script='setup.py'): sys.argv[0] = setup_script try: - super(_BuildMetaLegacyBackend, self).run_setup(setup_script=setup_script) + super().run_setup(setup_script=setup_script) finally: # While PEP 517 frontends should be calling each hook in a fresh # subprocess according to the standard (and thus it should not be diff --git a/setuptools/package_index.py b/setuptools/package_index.py index c491ddb3cc..1e535bc747 100644 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -514,7 +514,7 @@ def obtain(self, requirement, installer=None): if dist in requirement: return dist self.debug("%s does not match %s", requirement, dist) - return super(PackageIndex, self).obtain(requirement, installer) + return super().obtain(requirement, installer) def check_hash(self, checker, filename, tfp): """ diff --git a/setuptools/tests/test_build_meta.py b/setuptools/tests/test_build_meta.py index 429533229d..1281eb52a2 100644 --- a/setuptools/tests/test_build_meta.py +++ b/setuptools/tests/test_build_meta.py @@ -40,7 +40,7 @@ class BuildBackend(BuildBackendBase): """PEP 517 Build Backend""" def __init__(self, *args, **kwargs): - super(BuildBackend, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self.pool = futures.ProcessPoolExecutor(max_workers=1) def __getattr__(self, name): @@ -73,7 +73,7 @@ def _kill(self, pid): class BuildBackendCaller(BuildBackendBase): def __init__(self, *args, **kwargs): - super(BuildBackendCaller, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) (self.backend_name, _, self.backend_obj) = self.backend_name.partition(':') diff --git a/setuptools/tests/test_manifest.py b/setuptools/tests/test_manifest.py index 33d3250893..fbd21b1976 100644 --- a/setuptools/tests/test_manifest.py +++ b/setuptools/tests/test_manifest.py @@ -171,7 +171,7 @@ def teardown_method(self, method): class TestManifestTest(TempDirTestCase): def setup_method(self, method): - super(TestManifestTest, self).setup_method(method) + super().setup_method(method) f = open(os.path.join(self.temp_dir, 'setup.py'), 'w') f.write(SETUP_PY) From 1ddffe4946be0f6f08ea3c73b4efc5ebea74ad4b Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Wed, 22 Nov 2023 01:39:47 +0100 Subject: [PATCH 05/12] Don't cast string literals with str() Fixed by running `ruff --select UP018 --fix .`: UP018 [*] Unnecessary `str` call (rewrite as a literal) Original suggestions from pyupgrade: https://github.com/asottile/pyupgrade#forced-strnative-literals --- setuptools/tests/test_dist.py | 4 +- setuptools/tests/test_easy_install.py | 70 +++++++++++++-------------- setuptools/tests/test_integration.py | 2 +- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/setuptools/tests/test_dist.py b/setuptools/tests/test_dist.py index 609932a9b3..99cd582501 100644 --- a/setuptools/tests/test_dist.py +++ b/setuptools/tests/test_dist.py @@ -116,7 +116,7 @@ def test_provides_extras_deterministic_order(): # Invalid value type. ( { - 'hello': str('*.msg'), + 'hello': '*.msg', }, ( "\"values of 'package_data' dict\" " @@ -142,7 +142,7 @@ def test_check_package_data(package_data, expected_message): assert check_package_data(None, 'package_data', package_data) is None else: with pytest.raises(DistutilsSetupError, match=re.escape(expected_message)): - check_package_data(None, str('package_data'), package_data) + check_package_data(None, 'package_data', package_data) def test_check_specifier(): diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index d0b95e09ea..c6e3bf039a 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -53,7 +53,7 @@ class FakeDist: def get_entry_map(self, group): if group != 'console_scripts': return {} - return {str('name'): 'ep'} + return {'name': 'ep'} def as_requirement(self): return 'spec' @@ -567,8 +567,8 @@ def test_setup_requires_honors_fetch_params(self, mock_index, monkeypatch): setup_requires, it should honor the fetch parameters (such as index-url, and find-links). """ - monkeypatch.setenv(str('PIP_RETRIES'), str('0')) - monkeypatch.setenv(str('PIP_TIMEOUT'), str('0')) + monkeypatch.setenv('PIP_RETRIES', '0') + monkeypatch.setenv('PIP_TIMEOUT', '0') monkeypatch.setenv('PIP_NO_INDEX', 'false') with contexts.quiet(): # create an sdist that has a build-time dependency. @@ -653,7 +653,7 @@ def test_setup_requires_overrides_version_conflict(self, use_setup_cfg): with contexts.quiet() as (stdout, stderr): # Don't even need to install the package, just # running the setup.py at all is sufficient - run_setup(test_setup_py, [str('--name')]) + run_setup(test_setup_py, ['--name']) lines = stdout.readlines() assert len(lines) > 0 @@ -716,7 +716,7 @@ def test_setup_requires_override_nspkg(self, use_setup_cfg): try: # Don't even need to install the package, just # running the setup.py at all is sufficient - run_setup(test_setup_py, [str('--name')]) + run_setup(test_setup_py, ['--name']) except pkg_resources.VersionConflict: self.fail( 'Installing setup.py requirements ' @@ -766,16 +766,16 @@ def make_dependency_sdist(dist_path, distname, version): ) test_setup_py = os.path.join(test_pkg, 'setup.py') with contexts.quiet() as (stdout, stderr): - run_setup(test_setup_py, [str('--version')]) + run_setup(test_setup_py, ['--version']) lines = stdout.readlines() assert len(lines) > 0 assert lines[-1].strip() == '42' def test_setup_requires_honors_pip_env(self, mock_index, monkeypatch): - monkeypatch.setenv(str('PIP_RETRIES'), str('0')) - monkeypatch.setenv(str('PIP_TIMEOUT'), str('0')) + monkeypatch.setenv('PIP_RETRIES', '0') + monkeypatch.setenv('PIP_TIMEOUT', '0') monkeypatch.setenv('PIP_NO_INDEX', 'false') - monkeypatch.setenv(str('PIP_INDEX_URL'), mock_index.url) + monkeypatch.setenv('PIP_INDEX_URL', mock_index.url) with contexts.save_pkg_resources_state(): with contexts.tempdir() as temp_dir: test_pkg = create_setup_requires_package( @@ -796,14 +796,14 @@ def test_setup_requires_honors_pip_env(self, mock_index, monkeypatch): ) test_setup_py = os.path.join(test_pkg, 'setup.py') with pytest.raises(distutils.errors.DistutilsError): - run_setup(test_setup_py, [str('--version')]) + run_setup(test_setup_py, ['--version']) assert len(mock_index.requests) == 1 assert mock_index.requests[0].path == '/python-xlib/' def test_setup_requires_with_pep508_url(self, mock_index, monkeypatch): - monkeypatch.setenv(str('PIP_RETRIES'), str('0')) - monkeypatch.setenv(str('PIP_TIMEOUT'), str('0')) - monkeypatch.setenv(str('PIP_INDEX_URL'), mock_index.url) + monkeypatch.setenv('PIP_RETRIES', '0') + monkeypatch.setenv('PIP_TIMEOUT', '0') + monkeypatch.setenv('PIP_INDEX_URL', mock_index.url) with contexts.save_pkg_resources_state(): with contexts.tempdir() as temp_dir: dep_sdist = os.path.join(temp_dir, 'dep.tar.gz') @@ -817,7 +817,7 @@ def test_setup_requires_with_pep508_url(self, mock_index, monkeypatch): setup_attrs=dict(setup_requires='dependency @ %s' % dep_url), ) test_setup_py = os.path.join(test_pkg, 'setup.py') - run_setup(test_setup_py, [str('--version')]) + run_setup(test_setup_py, ['--version']) assert len(mock_index.requests) == 0 def test_setup_requires_with_allow_hosts(self, mock_index): @@ -843,15 +843,15 @@ def test_setup_requires_with_allow_hosts(self, mock_index): path.build(files, prefix=temp_dir) setup_py = str(pathlib.Path(temp_dir, 'test_pkg', 'setup.py')) with pytest.raises(distutils.errors.DistutilsError): - run_setup(setup_py, [str('--version')]) + run_setup(setup_py, ['--version']) assert len(mock_index.requests) == 0 def test_setup_requires_with_python_requires(self, monkeypatch, tmpdir): """Check `python_requires` is honored.""" - monkeypatch.setenv(str('PIP_RETRIES'), str('0')) - monkeypatch.setenv(str('PIP_TIMEOUT'), str('0')) - monkeypatch.setenv(str('PIP_NO_INDEX'), str('1')) - monkeypatch.setenv(str('PIP_VERBOSE'), str('1')) + monkeypatch.setenv('PIP_RETRIES', '0') + monkeypatch.setenv('PIP_TIMEOUT', '0') + monkeypatch.setenv('PIP_NO_INDEX', '1') + monkeypatch.setenv('PIP_VERBOSE', '1') dep_1_0_sdist = 'dep-1.0.tar.gz' dep_1_0_url = path_to_url(str(tmpdir / dep_1_0_sdist)) dep_1_0_python_requires = '>=2.7' @@ -898,7 +898,7 @@ def test_setup_requires_with_python_requires(self, monkeypatch, tmpdir): setup_attrs=dict(setup_requires='dep', dependency_links=[index_url]), ) test_setup_py = os.path.join(test_pkg, 'setup.py') - run_setup(test_setup_py, [str('--version')]) + run_setup(test_setup_py, ['--version']) eggs = list( map(str, pkg_resources.find_distributions(os.path.join(test_pkg, '.eggs'))) ) @@ -908,8 +908,8 @@ def test_setup_requires_with_python_requires(self, monkeypatch, tmpdir): def test_setup_requires_with_find_links_in_setup_cfg( self, monkeypatch, with_dependency_links_in_setup_py ): - monkeypatch.setenv(str('PIP_RETRIES'), str('0')) - monkeypatch.setenv(str('PIP_TIMEOUT'), str('0')) + monkeypatch.setenv('PIP_RETRIES', '0') + monkeypatch.setenv('PIP_TIMEOUT', '0') with contexts.save_pkg_resources_state(): with contexts.tempdir() as temp_dir: make_trivial_sdist( @@ -946,7 +946,7 @@ def test_setup_requires_with_find_links_in_setup_cfg( find_links=temp_dir, ) ) - run_setup(test_setup_py, [str('--version')]) + run_setup(test_setup_py, ['--version']) def test_setup_requires_with_transitive_extra_dependency(self, monkeypatch): """ @@ -979,7 +979,7 @@ def test_setup_requires_with_transitive_extra_dependency(self, monkeypatch): prefix=dep_pkg, ) # "Install" dep. - run_setup(os.path.join(dep_pkg, 'setup.py'), [str('dist_info')]) + run_setup(os.path.join(dep_pkg, 'setup.py'), ['dist_info']) working_set.add_entry(dep_pkg) # Create source tree for test package. test_pkg = os.path.join(temp_dir, 'test_pkg') @@ -995,11 +995,11 @@ def test_setup_requires_with_transitive_extra_dependency(self, monkeypatch): ) ) # Check... - monkeypatch.setenv(str('PIP_FIND_LINKS'), str(temp_dir)) - monkeypatch.setenv(str('PIP_NO_INDEX'), str('1')) - monkeypatch.setenv(str('PIP_RETRIES'), str('0')) - monkeypatch.setenv(str('PIP_TIMEOUT'), str('0')) - run_setup(test_setup_py, [str('--version')]) + monkeypatch.setenv('PIP_FIND_LINKS', str(temp_dir)) + monkeypatch.setenv('PIP_NO_INDEX', '1') + monkeypatch.setenv('PIP_RETRIES', '0') + monkeypatch.setenv('PIP_TIMEOUT', '0') + run_setup(test_setup_py, ['--version']) def test_setup_requires_with_distutils_command_dep(self, monkeypatch): """ @@ -1063,7 +1063,7 @@ class epcmd(build_py): prefix=dep_pkg, ) # "Install" dep. - run_setup(os.path.join(dep_pkg, 'setup.py'), [str('dist_info')]) + run_setup(os.path.join(dep_pkg, 'setup.py'), ['dist_info']) working_set.add_entry(dep_pkg) # Create source tree for test package. test_pkg = os.path.join(temp_dir, 'test_pkg') @@ -1079,10 +1079,10 @@ class epcmd(build_py): ) ) # Check... - monkeypatch.setenv(str('PIP_FIND_LINKS'), str(temp_dir)) - monkeypatch.setenv(str('PIP_NO_INDEX'), str('1')) - monkeypatch.setenv(str('PIP_RETRIES'), str('0')) - monkeypatch.setenv(str('PIP_TIMEOUT'), str('0')) + monkeypatch.setenv('PIP_FIND_LINKS', str(temp_dir)) + monkeypatch.setenv('PIP_NO_INDEX', '1') + monkeypatch.setenv('PIP_RETRIES', '0') + monkeypatch.setenv('PIP_TIMEOUT', '0') run_setup(test_setup_py, ['epcmd']) @@ -1286,7 +1286,7 @@ def test_get_script_header_non_ascii_exe(self): actual = ei.ScriptWriter.get_header( '#!/usr/bin/python', executable=self.non_ascii_exe ) - expected = str('#!%s -x\n') % self.non_ascii_exe + expected = '#!%s -x\n' % self.non_ascii_exe assert actual == expected def test_get_script_header_exe_with_spaces(self): diff --git a/setuptools/tests/test_integration.py b/setuptools/tests/test_integration.py index e17ffc5d5c..1aa16172b5 100644 --- a/setuptools/tests/test_integration.py +++ b/setuptools/tests/test_integration.py @@ -64,7 +64,7 @@ def fin(): monkeypatch.setattr('site.USER_BASE', user_base.strpath) monkeypatch.setattr('site.USER_SITE', user_site.strpath) monkeypatch.setattr('sys.path', sys.path + [install_dir.strpath]) - monkeypatch.setenv(str('PYTHONPATH'), str(os.path.pathsep.join(sys.path))) + monkeypatch.setenv('PYTHONPATH', str(os.path.pathsep.join(sys.path))) # Set up the command for performing the installation. dist = Distribution() From 8da168860bb7aa9d6209b10d5db6d5e61feabc81 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Wed, 22 Nov 2023 01:44:35 +0100 Subject: [PATCH 06/12] =?UTF-8?q?os.error=20=E2=86=92=20OSError?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is an alias for the built-in OSError exception: https://docs.python.org/3/library/os.html#os.error Fixed by running `ruff --select UP024 --fix .`: UP024 [*] Replace aliased errors with `OSError` --- pkg_resources/__init__.py | 4 ++-- setuptools/command/easy_install.py | 2 +- setuptools/glob.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 9adc214676..dc51076c3a 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -1895,7 +1895,7 @@ def _extract_resource(self, manager, zip_path): # noqa: C901 try: rename(tmpnam, real_path) - except os.error: + except OSError: if os.path.isfile(real_path): if self._is_current(real_path, zip_path): # the file became current since it was checked above, @@ -1908,7 +1908,7 @@ def _extract_resource(self, manager, zip_path): # noqa: C901 return real_path raise - except os.error: + except OSError: # report a user-friendly error manager.extraction_error() diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 3231650c5c..4de28bb98f 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -2023,7 +2023,7 @@ def chmod(path, mode): log.debug("changing mode of %s to %o", path, mode) try: _chmod(path, mode) - except os.error as e: + except OSError as e: log.debug("chmod failed: %s", e) diff --git a/setuptools/glob.py b/setuptools/glob.py index ac901d9253..a184c0b643 100644 --- a/setuptools/glob.py +++ b/setuptools/glob.py @@ -125,7 +125,7 @@ def _rlistdir(dirname): dirname = os.curdir try: names = os.listdir(dirname) - except os.error: + except OSError: return for x in names: yield x From a628dc5dfb83f950c8810e65afe019b3760a7c1d Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Wed, 22 Nov 2023 01:54:00 +0100 Subject: [PATCH 07/12] Use `capture_output` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In Python ≥ 3.7, `capture_output` can be used instead of `stdout=PIPE` / `stderr=PIPE`. Fixed by running `ruff --select UP022 --fix --unsafe-fixes .`: UP022 Sending `stdout` and `stderr` to `PIPE` is deprecated, use `capture_output` --- setuptools/tests/integration/helpers.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setuptools/tests/integration/helpers.py b/setuptools/tests/integration/helpers.py index 824dfdfe1a..62076bdf7d 100644 --- a/setuptools/tests/integration/helpers.py +++ b/setuptools/tests/integration/helpers.py @@ -15,8 +15,7 @@ def run(cmd, env=None): r = subprocess.run( cmd, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, + capture_output=True, universal_newlines=True, env={**os.environ, **(env or {})}, # ^-- allow overwriting instead of discarding the current env From b5f07c9b52b3d35b72f4ab7f29ba574b60b24139 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Wed, 22 Nov 2023 01:58:24 +0100 Subject: [PATCH 08/12] Remove extraneous pair of prentheses Fixed by running `ruff --select UP034 --fix .`: UP034 [*] Avoid extraneous parentheses --- setuptools/command/editable_wheel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/command/editable_wheel.py b/setuptools/command/editable_wheel.py index 73fa9fff52..57e35d53e4 100644 --- a/setuptools/command/editable_wheel.py +++ b/setuptools/command/editable_wheel.py @@ -400,7 +400,7 @@ def __init__(self, dist: Distribution, name: str, path_entries: List[Path]): self.path_entries = path_entries def __call__(self, wheel: "WheelFile", files: List[str], mapping: Dict[str, str]): - entries = "\n".join((str(p.resolve()) for p in self.path_entries)) + entries = "\n".join(str(p.resolve()) for p in self.path_entries) contents = _encode_pth(f"{entries}\n") wheel.writestr(f"__editable__.{self.name}.pth", contents) From 86bb681be5e5e4e08b42f1bdf1bf48f1d41d8e0e Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Wed, 22 Nov 2023 02:05:57 +0100 Subject: [PATCH 09/12] Get rid of one last `coding: utf-8` In Python 3, the source encodign is implict, UTF-8 by default. This is a suggestion from pyupgrade: https://github.com/asottile/pyupgrade#-coding--comment Fixed by running `ruff --select UP009 --fix .`: UP009 [*] UTF-8 encoding declaration is unnecessary --- setuptools/tests/test_archive_util.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/setuptools/tests/test_archive_util.py b/setuptools/tests/test_archive_util.py index 7f9962440c..06d7f05aa0 100644 --- a/setuptools/tests/test_archive_util.py +++ b/setuptools/tests/test_archive_util.py @@ -1,5 +1,3 @@ -# coding: utf-8 - import tarfile import io From 5ba5c2ed29ab165b8677aaa66e45e5b13c4abfba Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Wed, 22 Nov 2023 02:08:47 +0100 Subject: [PATCH 10/12] Use byte literals instead of .encode() This is a suggestion from pyupgrade: https://github.com/asottile/pyupgrade#encode-to-bytes-literals Fixed by running `ruff --select UP012 --fix .`: UP012 [*] Unnecessary call to `encode` as UTF-8 --- setuptools/command/sdist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py index 95d325717a..71f695fd36 100644 --- a/setuptools/command/sdist.py +++ b/setuptools/command/sdist.py @@ -189,7 +189,7 @@ def _manifest_is_not_generated(self): with open(self.manifest, 'rb') as fp: first_line = fp.readline() - return first_line != '# file GENERATED by distutils, do NOT edit\n'.encode() + return first_line != b'# file GENERATED by distutils, do NOT edit\n' def read_manifest(self): """Read the manifest file (named by 'self.manifest') and use it to From a14299108147d551cba219908dc180e2a2b0eeb1 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Wed, 22 Nov 2023 02:11:04 +0100 Subject: [PATCH 11/12] Use generator instead of list Fixed by running `ruff --select UP027 --fix .`: UP027 [*] Replace unpacked list comprehension with a generator expression --- pkg_resources/tests/test_working_set.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg_resources/tests/test_working_set.py b/pkg_resources/tests/test_working_set.py index f8e60e752a..57f62b5492 100644 --- a/pkg_resources/tests/test_working_set.py +++ b/pkg_resources/tests/test_working_set.py @@ -76,10 +76,10 @@ def parametrize_test_working_set_resolve(*test_list): requirements, expected1, expected2, - ) = [ + ) = ( strip_comments(s.lstrip()) for s in textwrap.dedent(test).lstrip().split('\n\n', 5) - ] + ) installed_dists = list(parse_distributions(installed_dists)) installable_dists = list(parse_distributions(installable_dists)) requirements = list(pkg_resources.parse_requirements(requirements)) From 07774d965eccd43bc2d46d24c7264276ca2bba3b Mon Sep 17 00:00:00 2001 From: Anderson Bravalheri Date: Fri, 5 Jan 2024 19:55:10 +0000 Subject: [PATCH 12/12] Ignore path that are automatically generated --- ruff.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ruff.toml b/ruff.toml index 791cfdc0a5..89c2910997 100644 --- a/ruff.toml +++ b/ruff.toml @@ -29,12 +29,14 @@ extend-ignore = [ extend-exclude = [ "**/_vendor", "setuptools/_distutils", + "setuptools/config/_validate_pyproject", ] [format] extend-exclude = [ "**/_vendor", "setuptools/_distutils", + "setuptools/config/_validate_pyproject", ] # https://docs.astral.sh/ruff/settings/#format-quote-style quote-style = "preserve"