From fc9f889ccf13ecc4667857d43731d2a09cc2b498 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 10 Sep 2024 12:25:40 +0200 Subject: [PATCH 1/8] Enforce ruff/pyupgrade rule UP030 UP030 Use implicit references for positional format fields --- ruff.toml | 1 - setuptools/command/sdist.py | 2 +- setuptools/tests/test_wheel.py | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/ruff.toml b/ruff.toml index 27757bcf4b..4830b9674e 100644 --- a/ruff.toml +++ b/ruff.toml @@ -35,7 +35,6 @@ ignore = [ "TRY003", # raise-vanilla-args, avoid multitude of exception classes "TRY301", # raise-within-try, it's handy "UP015", # redundant-open-modes, explicit is preferred - "UP030", # temporarily disabled "UP031", # temporarily disabled "UP032", # temporarily disabled "UP038", # Using `X | Y` in `isinstance` call is slower and more verbose https://github.com/astral-sh/ruff/issues/7871 diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py index 64e866c96b..bf085cb56b 100644 --- a/setuptools/command/sdist.py +++ b/setuptools/command/sdist.py @@ -53,7 +53,7 @@ class sdist(orig.sdist): negative_opt: ClassVar[dict[str, str]] = {} README_EXTENSIONS = ['', '.rst', '.txt', '.md'] - READMES = tuple('README{0}'.format(ext) for ext in README_EXTENSIONS) + READMES = tuple('README{}'.format(ext) for ext in README_EXTENSIONS) def run(self) -> None: self.run_command('egg_info') diff --git a/setuptools/tests/test_wheel.py b/setuptools/tests/test_wheel.py index 5724c6eabc..5c6bda0454 100644 --- a/setuptools/tests/test_wheel.py +++ b/setuptools/tests/test_wheel.py @@ -605,7 +605,7 @@ def test_wheel_install_pep_503(): def test_wheel_no_dist_dir(): project_name = 'nodistinfo' version = '1.0' - wheel_name = '{0}-{1}-py2.py3-none-any.whl'.format(project_name, version) + wheel_name = '{}-{}-py2.py3-none-any.whl'.format(project_name, version) with tempdir() as source_dir: wheel_path = os.path.join(source_dir, wheel_name) # create an empty zip file From 050eafb6d82472c1b1f11ee9ba0a35911fcd26ef Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 10 Sep 2024 12:26:25 +0200 Subject: [PATCH 2/8] Enforce ruff/pyupgrade rule UP031 UP031 Use format specifiers instead of percent format --- pkg_resources/__init__.py | 36 ++++++------ ruff.toml | 1 - setuptools/__init__.py | 4 +- setuptools/_core_metadata.py | 6 +- setuptools/_imp.py | 6 +- setuptools/archive_util.py | 8 +-- setuptools/command/alias.py | 4 +- setuptools/command/bdist_egg.py | 2 +- setuptools/command/build_clib.py | 16 +++--- setuptools/command/build_ext.py | 2 +- setuptools/command/build_py.py | 4 +- setuptools/command/easy_install.py | 35 ++++++------ setuptools/command/egg_info.py | 13 ++--- setuptools/command/install_egg_info.py | 2 +- setuptools/command/sdist.py | 2 +- setuptools/command/setopt.py | 2 +- setuptools/config/expand.py | 2 +- setuptools/config/setupcfg.py | 14 ++++- setuptools/depends.py | 2 +- setuptools/dist.py | 15 +++-- setuptools/monkey.py | 2 +- setuptools/msvc.py | 72 ++++++++++++------------ setuptools/package_index.py | 34 ++++++----- setuptools/tests/config/test_setupcfg.py | 8 +-- setuptools/tests/server.py | 6 +- setuptools/tests/test_build_ext.py | 2 +- setuptools/tests/test_core_metadata.py | 2 +- setuptools/tests/test_dist.py | 2 +- setuptools/tests/test_easy_install.py | 34 ++++++----- setuptools/tests/test_egg_info.py | 5 +- setuptools/tests/test_install_scripts.py | 8 +-- setuptools/tests/test_manifest.py | 5 +- setuptools/tests/test_sandbox.py | 2 +- setuptools/tests/test_sdist.py | 5 +- setuptools/tests/test_wheel.py | 14 ++--- setuptools/wheel.py | 8 +-- 36 files changed, 191 insertions(+), 194 deletions(-) diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 74b0465bfa..94dde1f218 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -200,7 +200,7 @@ def get_supported_platform(): m = macosVersionString.match(plat) if m is not None and sys.platform == "darwin": try: - plat = 'macosx-%s-%s' % ('.'.join(_macos_vers()[:2]), m.group(3)) + plat = 'macosx-{}-{}'.format('.'.join(_macos_vers()[:2]), m.group(3)) except ValueError: # not macOS pass @@ -492,7 +492,7 @@ def compatible_platforms(provided: str | None, required: str | None) -> bool: provDarwin = darwinVersionString.match(provided) if provDarwin: dversion = int(provDarwin.group(1)) - macosversion = "%s.%s" % (reqMac.group(1), reqMac.group(2)) + macosversion = "{}.{}".format(reqMac.group(1), reqMac.group(2)) if ( dversion == 7 and macosversion >= "10.3" @@ -1316,7 +1316,7 @@ def __iadd__(self, other: Distribution | Environment) -> Self: for dist in other[project]: self.add(dist) else: - raise TypeError("Can't add %r to environment" % (other,)) + raise TypeError("Can't add {!r} to environment".format(other)) return self def __add__(self, other: Distribution | Environment) -> Self: @@ -2018,7 +2018,7 @@ def _zipinfo_name(self, fspath): return '' if fspath.startswith(self.zip_pre): return fspath[len(self.zip_pre) :] - raise AssertionError("%s is not a subpath of %s" % (fspath, self.zip_pre)) + raise AssertionError("{} is not a subpath of {}".format(fspath, self.zip_pre)) def _parts(self, zip_path): # Convert a zipfile subpath into an egg-relative path part list. @@ -2026,7 +2026,7 @@ def _parts(self, zip_path): fspath = self.zip_pre + zip_path if fspath.startswith(self.egg_root + os.sep): return fspath[len(self.egg_root) + 1 :].split(os.sep) - raise AssertionError("%s is not a subpath of %s" % (fspath, self.egg_root)) + raise AssertionError("{} is not a subpath of {}".format(fspath, self.egg_root)) @property def zipinfo(self): @@ -2729,15 +2729,15 @@ def __init__( self.dist = dist def __str__(self) -> str: - s = "%s = %s" % (self.name, self.module_name) + s = "{} = {}".format(self.name, self.module_name) if self.attrs: s += ':' + '.'.join(self.attrs) if self.extras: - s += ' [%s]' % ','.join(self.extras) + s += ' [{}]'.format(','.join(self.extras)) return s def __repr__(self) -> str: - return "EntryPoint.parse(%r)" % str(self) + return "EntryPoint.parse({!r})".format(str(self)) @overload def load( @@ -3108,7 +3108,7 @@ def requires(self, extras: Iterable[str] = ()) -> list[Requirement]: deps.extend(dm[safe_extra(ext)]) except KeyError as e: raise UnknownExtra( - "%s has no such extra feature %r" % (self, ext) + "{} has no such extra feature {!r}".format(self, ext) ) from e return deps @@ -3150,7 +3150,7 @@ def activate(self, path: list[str] | None = None, replace: bool = False) -> None def egg_name(self): """Return what this distribution's standard .egg filename should be""" - filename = "%s-%s-py%s" % ( + filename = "{}-{}-py{}".format( to_filename(self.project_name), to_filename(self.version), self.py_version or PY_MAJOR, @@ -3162,7 +3162,7 @@ def egg_name(self): def __repr__(self) -> str: if self.location: - return "%s (%s)" % (self, self.location) + return "{} ({})".format(self, self.location) else: return str(self) @@ -3172,7 +3172,7 @@ def __str__(self) -> str: except ValueError: version = None version = version or "[unknown version]" - return "%s %s" % (self.project_name, version) + return "{} {}".format(self.project_name, version) def __getattr__(self, attr: str): """Delegate all unrecognized public attributes to .metadata provider""" @@ -3200,9 +3200,9 @@ def from_filename( def as_requirement(self): """Return a ``Requirement`` that matches this distribution exactly""" if isinstance(self.parsed_version, packaging.version.Version): - spec = "%s==%s" % (self.project_name, self.parsed_version) + spec = "{}=={}".format(self.project_name, self.parsed_version) else: - spec = "%s===%s" % (self.project_name, self.parsed_version) + spec = "{}==={}".format(self.project_name, self.parsed_version) return Requirement.parse(spec) @@ -3210,7 +3210,7 @@ def load_entry_point(self, group: str, name: str) -> _ResolvedEntryPoint: """Return the `name` entry point of `group` or raise ImportError""" ep = self.get_entry_info(group, name) if ep is None: - raise ImportError("Entry point %r not found" % ((group, name),)) + raise ImportError("Entry point {!r} not found".format((group, name))) return ep.load() @overload @@ -3327,8 +3327,8 @@ def check_version_conflict(self): ): continue issue_warning( - "Module %s was already imported from %s, but %s is being added" - " to sys.path" % (modname, fn, self.location), + "Module {} was already imported from {}, but {} is being added" + " to sys.path".format(modname, fn, self.location), ) def has_version(self) -> bool: @@ -3512,7 +3512,7 @@ def __hash__(self) -> int: return self.__hash def __repr__(self) -> str: - return "Requirement.parse(%r)" % str(self) + return "Requirement.parse({!r})".format(str(self)) @staticmethod def parse(s: str | Iterable[str]) -> Requirement: diff --git a/ruff.toml b/ruff.toml index 4830b9674e..e7005e27d9 100644 --- a/ruff.toml +++ b/ruff.toml @@ -35,7 +35,6 @@ ignore = [ "TRY003", # raise-vanilla-args, avoid multitude of exception classes "TRY301", # raise-within-try, it's handy "UP015", # redundant-open-modes, explicit is preferred - "UP031", # temporarily disabled "UP032", # temporarily disabled "UP038", # Using `X | Y` in `isinstance` call is slower and more verbose https://github.com/astral-sh/ruff/issues/7871 # Only enforcing return type annotations for public functions diff --git a/setuptools/__init__.py b/setuptools/__init__.py index 4f5c01708a..ab3be9581c 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -182,7 +182,7 @@ def _ensure_stringlike(self, option, what, default=None): return default elif not isinstance(val, str): raise DistutilsOptionError( - "'%s' must be a %s (got `%s`)" % (option, what, val) + "'{}' must be a {} (got `{}`)".format(option, what, val) ) return val @@ -210,7 +210,7 @@ def ensure_string_list(self, option: str) -> None: ok = False if not ok: raise DistutilsOptionError( - "'%s' must be a list of strings (got %r)" % (option, val) + "'{}' must be a list of strings (got {!r})".format(option, val) ) @overload diff --git a/setuptools/_core_metadata.py b/setuptools/_core_metadata.py index 2e9c48a77b..72b745dc93 100644 --- a/setuptools/_core_metadata.py +++ b/setuptools/_core_metadata.py @@ -150,7 +150,7 @@ def write_pkg_file(self, file): # noqa: C901 # is too complex (14) # FIXME version = self.get_metadata_version() def write_field(key, value): - file.write("%s: %s\n" % (key, value)) + file.write("{}: {}\n".format(key, value)) write_field('Metadata-Version', str(version)) write_field('Name', self.get_name()) @@ -179,7 +179,7 @@ def write_field(key, value): write_field('License', rfc822_escape(license)) for project_url in self.project_urls.items(): - write_field('Project-URL', '%s, %s' % project_url) + write_field('Project-URL', '{}, {}'.format(*project_url)) keywords = ','.join(self.get_keywords()) if keywords: @@ -209,7 +209,7 @@ def write_field(key, value): long_description = self.get_long_description() if long_description: - file.write("\n%s" % long_description) + file.write("\n{}".format(long_description)) if not long_description.endswith("\n"): file.write("\n") diff --git a/setuptools/_imp.py b/setuptools/_imp.py index bddbf6a683..f0fba01e50 100644 --- a/setuptools/_imp.py +++ b/setuptools/_imp.py @@ -29,7 +29,7 @@ def find_module(module, paths=None): """Just like 'imp.find_module()', but with package support""" spec = find_spec(module, paths) if spec is None: - raise ImportError("Can't find %s" % module) + raise ImportError("Can't find {}".format(module)) if not spec.has_location and hasattr(spec, 'submodule_search_locations'): spec = importlib.util.spec_from_loader('__init__.py', spec.loader) @@ -76,12 +76,12 @@ def find_module(module, paths=None): def get_frozen_object(module, paths=None): spec = find_spec(module, paths) if not spec: - raise ImportError("Can't find %s" % module) + raise ImportError("Can't find {}".format(module)) return spec.loader.get_code(module) def get_module(module, paths, info): spec = find_spec(module, paths) if not spec: - raise ImportError("Can't find %s" % module) + raise ImportError("Can't find {}".format(module)) return module_from_spec(spec) diff --git a/setuptools/archive_util.py b/setuptools/archive_util.py index cd9cf9c08f..7ef5294b55 100644 --- a/setuptools/archive_util.py +++ b/setuptools/archive_util.py @@ -62,7 +62,7 @@ def unpack_archive( else: return else: - raise UnrecognizedFormat("Not a recognized archive type: %s" % filename) + raise UnrecognizedFormat("Not a recognized archive type: {}".format(filename)) def unpack_directory(filename, extract_dir, progress_filter=default_filter) -> None: @@ -71,7 +71,7 @@ def unpack_directory(filename, extract_dir, progress_filter=default_filter) -> N Raises ``UnrecognizedFormat`` if `filename` is not a directory """ if not os.path.isdir(filename): - raise UnrecognizedFormat("%s is not a directory" % filename) + raise UnrecognizedFormat("{} is not a directory".format(filename)) paths = { filename: ('', extract_dir), @@ -101,7 +101,7 @@ def unpack_zipfile(filename, extract_dir, progress_filter=default_filter) -> Non """ if not zipfile.is_zipfile(filename): - raise UnrecognizedFormat("%s is not a zip file" % (filename,)) + raise UnrecognizedFormat("{} is not a zip file".format(filename)) with zipfile.ZipFile(filename) as z: _unpack_zipfile_obj(z, extract_dir, progress_filter) @@ -198,7 +198,7 @@ def unpack_tarfile(filename, extract_dir, progress_filter=default_filter) -> boo tarobj = tarfile.open(filename) except tarfile.TarError as e: raise UnrecognizedFormat( - "%s is not a compressed or uncompressed tar file" % (filename,) + "{} is not a compressed or uncompressed tar file".format(filename) ) from e for member, final_dst in _iter_open_tar( diff --git a/setuptools/command/alias.py b/setuptools/command/alias.py index 388830d7a6..9903a23503 100644 --- a/setuptools/command/alias.py +++ b/setuptools/command/alias.py @@ -55,7 +55,7 @@ def run(self) -> None: print("setup.py alias", format_alias(alias, aliases)) return else: - print("No alias definition found for %r" % alias) + print("No alias definition found for {!r}".format(alias)) return else: alias = self.args[0] @@ -73,5 +73,5 @@ def format_alias(name, aliases): elif source == config_file('local'): source = '' else: - source = '--filename=%r' % source + source = '--filename={!r}'.format(source) return source + name + ' ' + command diff --git a/setuptools/command/bdist_egg.py b/setuptools/command/bdist_egg.py index ac3e6ef1f9..d991049b5b 100644 --- a/setuptools/command/bdist_egg.py +++ b/setuptools/command/bdist_egg.py @@ -263,7 +263,7 @@ def zap_pyfiles(self): pattern = r'(?P.+)\.(?P[^.]+)\.pyc' m = re.match(pattern, name) path_new = os.path.join(base, os.pardir, m.group('name') + '.pyc') - log.info("Renaming file from [%s] to [%s]" % (path_old, path_new)) + log.info("Renaming file from [{}] to [{}]".format(path_old, path_new)) try: os.remove(path_new) except OSError: diff --git a/setuptools/command/build_clib.py b/setuptools/command/build_clib.py index bee3d58c03..f2705cecdc 100644 --- a/setuptools/command/build_clib.py +++ b/setuptools/command/build_clib.py @@ -29,9 +29,9 @@ def build_libraries(self, libraries) -> None: sources = build_info.get('sources') if sources is None or not isinstance(sources, (list, tuple)): raise DistutilsSetupError( - "in 'libraries' option (library '%s'), " + "in 'libraries' option (library '{}'), " "'sources' must be present and must be " - "a list of source filenames" % lib_name + "a list of source filenames".format(lib_name) ) sources = sorted(list(sources)) @@ -43,9 +43,9 @@ def build_libraries(self, libraries) -> None: obj_deps = build_info.get('obj_deps', dict()) if not isinstance(obj_deps, dict): raise DistutilsSetupError( - "in 'libraries' option (library '%s'), " + "in 'libraries' option (library '{}'), " "'obj_deps' must be a dictionary of " - "type 'source: list'" % lib_name + "type 'source: list'".format(lib_name) ) dependencies = [] @@ -54,9 +54,9 @@ def build_libraries(self, libraries) -> None: global_deps = obj_deps.get('', list()) if not isinstance(global_deps, (list, tuple)): raise DistutilsSetupError( - "in 'libraries' option (library '%s'), " + "in 'libraries' option (library '{}'), " "'obj_deps' must be a dictionary of " - "type 'source: list'" % lib_name + "type 'source: list'".format(lib_name) ) # Build the list to be used by newer_pairwise_group @@ -67,9 +67,9 @@ def build_libraries(self, libraries) -> None: extra_deps = obj_deps.get(source, list()) if not isinstance(extra_deps, (list, tuple)): raise DistutilsSetupError( - "in 'libraries' option (library '%s'), " + "in 'libraries' option (library '{}'), " "'obj_deps' must be a dictionary of " - "type 'source: list'" % lib_name + "type 'source: list'".format(lib_name) ) src_deps.extend(extra_deps) dependencies.append(src_deps) diff --git a/setuptools/command/build_ext.py b/setuptools/command/build_ext.py index e5c6b76b38..b8a395bafa 100644 --- a/setuptools/command/build_ext.py +++ b/setuptools/command/build_ext.py @@ -360,7 +360,7 @@ def _write_stub_file(self, stub_file: str, ext: Extension, compile=False): " global __bootstrap__, __file__, __loader__", " import sys, os, pkg_resources, importlib.util" + if_dl(", dl"), " __file__ = pkg_resources.resource_filename" - "(__name__,%r)" % os.path.basename(ext._file_name), + "(__name__,{!r})".format(os.path.basename(ext._file_name)), " del __bootstrap__", " if '__loader__' in globals():", " del __loader__", diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index e7d60c6440..f17cd66fe9 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -259,10 +259,10 @@ def check_package(self, package, package_dir): contents = f.read() if b'declare_namespace' not in contents: raise distutils.errors.DistutilsError( - "Namespace package problem: %s is a namespace package, but " + "Namespace package problem: {} is a namespace package, but " "its\n__init__.py does not call declare_namespace()! Please " 'fix it.\n(See the setuptools manual under ' - '"Namespace Packages" for details.)\n"' % (package,) + '"Namespace Packages" for details.)\n"'.format(package) ) return init_py diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 66fe68f7a9..88d39c043a 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -148,7 +148,7 @@ class easy_install(Command): None, "Don't load find-links defined in packages being installed", ), - ('user', None, "install in user site-package '%s'" % site.USER_SITE), + ('user', None, "install in user site-package '{}'".format(site.USER_SITE)), ] boolean_options = [ 'zip-ok', @@ -446,7 +446,7 @@ def run(self, show_deprecation: bool = True) -> None: self.execute( file_util.write_file, (self.record, outputs), - "writing list of installed files to '%s'" % self.record, + "writing list of installed files to '{}'".format(self.record), ) self.warn_deprecated_options() finally: @@ -461,7 +461,7 @@ def pseudo_tempname(self): pid = os.getpid() except Exception: pid = random.randint(0, sys.maxsize) - return os.path.join(self.install_dir, "test-easy-install-%s" % pid) + return os.path.join(self.install_dir, "test-easy-install-{}".format(pid)) def warn_deprecated_options(self) -> None: pass @@ -649,8 +649,8 @@ def add_output(self, path) -> None: def not_editable(self, spec) -> None: if self.editable: raise DistutilsArgError( - "Invalid argument %r: you can't use filenames or URLs " - "with --editable (except via the --find-links option)." % (spec,) + "Invalid argument {!r}: you can't use filenames or URLs " + "with --editable (except via the --find-links option).".format(spec) ) def check_editable(self, spec) -> None: @@ -659,8 +659,7 @@ def check_editable(self, spec) -> None: if os.path.exists(os.path.join(self.build_directory, spec.key)): raise DistutilsArgError( - "%r already exists in %s; can't do a checkout there" - % (spec.key, self.build_directory) + "{!r} already exists in {}; can't do a checkout there".format(spec.key, self.build_directory) ) @contextlib.contextmanager @@ -698,7 +697,7 @@ def easy_install(self, spec, deps: bool = False) -> Distribution | None: self.local_index, ) if dist is None: - msg = "Could not find suitable distribution for %r" % spec + msg = "Could not find suitable distribution for {!r}".format(spec) if self.always_copy: msg += " (--always-copy skips system and development eggs)" raise DistutilsError(msg) @@ -917,12 +916,11 @@ def install_eggs(self, spec, dist_filename, tmpdir) -> list[Distribution]: setups = glob(os.path.join(setup_base, '*', 'setup.py')) if not setups: raise DistutilsError( - "Couldn't find a setup script in %s" - % os.path.abspath(dist_filename) + "Couldn't find a setup script in {}".format(os.path.abspath(dist_filename)) ) if len(setups) > 1: raise DistutilsError( - "Multiple setup scripts in %s" % os.path.abspath(dist_filename) + "Multiple setup scripts in {}".format(os.path.abspath(dist_filename)) ) setup_script = setups[0] @@ -1000,7 +998,7 @@ def install_exe(self, dist_filename, tmpdir): cfg = extract_wininst_cfg(dist_filename) if cfg is None: raise DistutilsError( - "%s is not a valid distutils Windows .exe" % dist_filename + "{} is not a valid distutils Windows .exe".format(dist_filename) ) # Create a dummy distribution object until we build the real distro dist = Distribution( @@ -1026,7 +1024,7 @@ def install_exe(self, dist_filename, tmpdir): f.write('Metadata-Version: 1.0\n') for k, v in cfg.items('metadata'): if k != 'target_version': - f.write('%s: %s\n' % (k.replace('_', '-').title(), v)) + f.write('{}: {}\n'.format(k.replace('_', '-').title(), v)) script_dir = os.path.join(_egg_info, 'scripts') # delete entry-point scripts to avoid duping self.delete_blockers([ @@ -1114,8 +1112,7 @@ def install_wheel(self, wheel_path, tmpdir): self.execute( wheel.install_as_egg, (destination,), - ("Installing %s to %s") - % (os.path.basename(wheel_path), os.path.dirname(destination)), + ("Installing {} to {}").format(os.path.basename(wheel_path), os.path.dirname(destination)), ) finally: update_dist_caches(destination, fix_zipimporter_caches=False) @@ -1191,7 +1188,7 @@ def run_setup(self, setup_script, setup_base, args) -> None: try: run_setup(setup_script, args) except SystemExit as v: - raise DistutilsError("Setup script exited with %s" % (v.args[0],)) from v + raise DistutilsError("Setup script exited with {}".format(v.args[0])) from v def build_and_install(self, setup_script, setup_base): args = ['bdist_egg', '--dist-dir'] @@ -1374,7 +1371,7 @@ def create_home_path(self) -> None: home = convert_path(os.path.expanduser("~")) for path in only_strs(self.config_vars.values()): if path.startswith(home) and not os.path.isdir(path): - self.debug_print("os.makedirs('%s', 0o700)" % path) + self.debug_print("os.makedirs('{}', 0o700)".format(path)) os.makedirs(path, 0o700) INSTALL_SCHEMES = dict( @@ -1599,7 +1596,7 @@ def get_exe_prefixes(exe_filename): for pth in yield_lines(contents): pth = pth.strip().replace('\\', '/') if not pth.startswith('import'): - prefixes.append((('%s/%s/' % (parts[0], pth)), '')) + prefixes.append((('{}/{}/'.format(parts[0], pth)), '')) finally: z.close() prefixes = [(x.lower(), y) for x, y in prefixes] @@ -2305,7 +2302,7 @@ def get_win_launcher(type): Returns the executable as a byte string. """ - launcher_fn = '%s.exe' % type + launcher_fn = '{}.exe'.format(type) if is_64bit(): if get_platform() == "win-arm64": launcher_fn = launcher_fn.replace(".", "-arm64.") diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index a300356d33..9a9ea63322 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -48,7 +48,7 @@ def translate_pattern(glob): # noqa: C901 # is too complex (14) # FIXME chunks = glob.split(os.path.sep) sep = re.escape(os.sep) - valid_char = '[^%s]' % (sep,) + valid_char = '[^{}]'.format(sep) for c, chunk in enumerate(chunks): last_chunk = c == len(chunks) - 1 @@ -60,7 +60,7 @@ def translate_pattern(glob): # noqa: C901 # is too complex (14) # FIXME pat += '.*' else: # Match '(name/)*' - pat += '(?:%s+%s)*' % (valid_char, sep) + pat += '(?:{}+{})*'.format(valid_char, sep) continue # Break here as the whole path component has been handled # Find any special characters in the remainder @@ -102,7 +102,7 @@ def translate_pattern(glob): # noqa: C901 # is too complex (14) # FIXME inner = inner[1:] char_class += re.escape(inner) - pat += '[%s]' % (char_class,) + pat += '[{}]'.format(char_class) # Skip to the end ] i = inner_i @@ -231,8 +231,7 @@ def finalize_options(self) -> None: packaging.requirements.Requirement(spec % (self.egg_name, self.egg_version)) except ValueError as e: raise distutils.errors.DistutilsOptionError( - "Invalid distribution name or version syntax: %s-%s" - % (self.egg_name, self.egg_version) + "Invalid distribution name or version syntax: {}-{}".format(self.egg_name, self.egg_version) ) from e if self.egg_base is None: @@ -502,7 +501,7 @@ def _safe_path(self, path): # To avoid accidental trans-codings errors, first to unicode u_path = unicode_utils.filesys_decode(path) if u_path is None: - log.warn("'%s' in unexpected encoding -- skipping" % path) + log.warn("'{}' in unexpected encoding -- skipping".format(path)) return False # Must ensure utf-8 encodability @@ -564,7 +563,7 @@ def write_manifest(self) -> None: # Now _repairs should encodability, but not unicode files = [self._manifest_normalize(f) for f in self.filelist.files] - msg = "writing manifest file '%s'" % self.manifest + msg = "writing manifest file '{}'".format(self.manifest) self.execute(write_file, (self.manifest, files), msg) def warn(self, msg) -> None: diff --git a/setuptools/command/install_egg_info.py b/setuptools/command/install_egg_info.py index a6e6ec6446..991531caa0 100644 --- a/setuptools/command/install_egg_info.py +++ b/setuptools/command/install_egg_info.py @@ -36,7 +36,7 @@ def run(self) -> None: self.execute(os.unlink, (self.target,), "Removing " + self.target) if not self.dry_run: ensure_directory(self.target) - self.execute(self.copytree, (), "Copying %s to %s" % (self.source, self.target)) + self.execute(self.copytree, (), "Copying {} to {}".format(self.source, self.target)) self.install_namespaces() def get_outputs(self): diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py index bf085cb56b..03a70ce9c9 100644 --- a/setuptools/command/sdist.py +++ b/setuptools/command/sdist.py @@ -207,7 +207,7 @@ def read_manifest(self): try: line = bytes_line.decode('UTF-8') except UnicodeDecodeError: - log.warn("%r not UTF-8 decodable -- skipping" % line) + log.warn("{!r} not UTF-8 decodable -- skipping".format(line)) continue # ignore comments and blank lines line = line.strip() diff --git a/setuptools/command/setopt.py b/setuptools/command/setopt.py index 200cdff0f7..ee220f9454 100644 --- a/setuptools/command/setopt.py +++ b/setuptools/command/setopt.py @@ -23,7 +23,7 @@ def config_file(kind="local"): return os.path.join(os.path.dirname(distutils.__file__), 'distutils.cfg') if kind == 'user': dot = os.name == 'posix' and '.' or '' - return os.path.expanduser(convert_path("~/%spydistutils.cfg" % dot)) + return os.path.expanduser(convert_path("~/{}pydistutils.cfg".format(dot))) raise ValueError("config_file() type must be 'local', 'global', or 'user'", kind) diff --git a/setuptools/config/expand.py b/setuptools/config/expand.py index 54c68bed4f..8469e979a1 100644 --- a/setuptools/config/expand.py +++ b/setuptools/config/expand.py @@ -329,7 +329,7 @@ def version(value: Callable | Iterable[str | int] | str) -> str: return _value if hasattr(_value, '__iter__'): return '.'.join(map(str, _value)) - return '%s' % _value + return '{}'.format(_value) def canonic_package_data(package_data: dict) -> dict: diff --git a/setuptools/config/setupcfg.py b/setuptools/config/setupcfg.py index b35d0b00cd..0f9167be77 100644 --- a/setuptools/config/setupcfg.py +++ b/setuptools/config/setupcfg.py @@ -272,7 +272,7 @@ def _section_options( def parsers(self): """Metadata item name to parser function mapping.""" raise NotImplementedError( - '%s must provide .parsers property' % self.__class__.__name__ + '{} must provide .parsers property'.format(self.__class__.__name__) ) def __setitem__(self, option_name, value) -> None: @@ -483,12 +483,24 @@ def parse(self) -> None: for section_name, section_options in self.sections.items(): method_postfix = '' if section_name: # [section.option] variant +<<<<<<< HEAD method_postfix = f"_{section_name}" +||||||| parent of e98b9ffc4 (Enforce ruff/pyupgrade rule UP031) + method_postfix = '_%s' % section_name +======= + method_postfix = '_{}'.format(section_name) +>>>>>>> e98b9ffc4 (Enforce ruff/pyupgrade rule UP031) section_parser_method: Callable | None = getattr( self, # Dots in section names are translated into dunderscores. +<<<<<<< HEAD f'parse_section{method_postfix}'.replace('.', '__'), +||||||| parent of e98b9ffc4 (Enforce ruff/pyupgrade rule UP031) + ('parse_section%s' % method_postfix).replace('.', '__'), +======= + ('parse_section{}'.format(method_postfix)).replace('.', '__'), +>>>>>>> e98b9ffc4 (Enforce ruff/pyupgrade rule UP031) None, ) diff --git a/setuptools/depends.py b/setuptools/depends.py index 1be71857a5..09eff3855f 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -43,7 +43,7 @@ def __init__( def full_name(self): """Return full package/distribution name, w/version""" if self.requested_version is not None: - return '%s-%s' % (self.name, self.requested_version) + return '{}-{}'.format(self.name, self.requested_version) return self.name def version_ok(self, version): diff --git a/setuptools/dist.py b/setuptools/dist.py index 5b3175fb5b..182a03b36a 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -85,7 +85,7 @@ def check_importable(dist, attr, value): assert not ep.extras except (TypeError, ValueError, AttributeError, AssertionError) as e: raise DistutilsSetupError( - "%r must be importable 'module:attrs' string (got %r)" % (attr, value) + "{!r} must be importable 'module:attrs' string (got {!r})".format(attr, value) ) from e @@ -111,7 +111,7 @@ def check_nsp(dist, attr, value): if not dist.has_contents_for(nsp): raise DistutilsSetupError( "Distribution contains no modules or packages for " - + "namespace package %r" % nsp + + "namespace package {!r}".format(nsp) ) parent, _sep, _child = nsp.rpartition('.') if parent and parent not in ns_packages: @@ -588,10 +588,10 @@ def _set_command_options(self, command_obj, option_dict=None): # noqa: C901 option_dict = self.get_option_dict(command_name) if DEBUG: - self.announce(" setting options for '%s' command:" % command_name) + self.announce(" setting options for '{}' command:".format(command_name)) for option, (source, value) in option_dict.items(): if DEBUG: - self.announce(" %s = %s (from %s)" % (option, value, source)) + self.announce(" {} = {} (from {})".format(option, value, source)) try: bool_opts = [translate_longopt(o) for o in command_obj.boolean_options] except AttributeError: @@ -611,8 +611,7 @@ def _set_command_options(self, command_obj, option_dict=None): # noqa: C901 setattr(command_obj, option, value) else: raise DistutilsOptionError( - "error in %s: command '%s' has no such option '%s'" - % (source, command_name, option) + "error in {}: command '{}' has no such option '{}'".format(source, command_name, option) ) except ValueError as e: raise DistutilsOptionError(e) from e @@ -818,7 +817,7 @@ def _exclude_misc(self, name: str, value: _Sequence) -> None: try: old = getattr(self, name) except AttributeError as e: - raise DistutilsSetupError("%s: No such distribution setting" % name) from e + raise DistutilsSetupError(f"{name}: No such distribution setting") from e if old is not None and not isinstance(old, _sequence): raise DistutilsSetupError( name + ": this setting cannot be changed via include/exclude" @@ -836,7 +835,7 @@ def _include_misc(self, name: str, value: _Sequence) -> None: try: old = getattr(self, name) except AttributeError as e: - raise DistutilsSetupError("%s: No such distribution setting" % name) from e + raise DistutilsSetupError("{}: No such distribution setting".format(name)) from e if old is None: setattr(self, name, value) elif not isinstance(old, _sequence): diff --git a/setuptools/monkey.py b/setuptools/monkey.py index d8e30dbb80..ec5d8cdae1 100644 --- a/setuptools/monkey.py +++ b/setuptools/monkey.py @@ -64,7 +64,7 @@ def get_unpatched_class(cls: type[_T]) -> type[_T]: ) base = next(external_bases) if not base.__module__.startswith('distutils'): - msg = "distutils has already been patched by %r" % cls + msg = "distutils has already been patched by {!r}".format(cls) raise AssertionError(msg) return base diff --git a/setuptools/msvc.py b/setuptools/msvc.py index 8d6d2cf084..55e5cd21fd 100644 --- a/setuptools/msvc.py +++ b/setuptools/msvc.py @@ -108,7 +108,7 @@ def current_dir(self, hidex86=False, x64=False) -> str: if (self.current_cpu == 'x86' and hidex86) else r'\x64' if (self.current_cpu == 'amd64' and x64) - else r'\%s' % self.current_cpu + else r'\{}'.format(self.current_cpu) ) def target_dir(self, hidex86=False, x64=False) -> str: @@ -132,7 +132,7 @@ def target_dir(self, hidex86=False, x64=False) -> str: if (self.target_cpu == 'x86' and hidex86) else r'\x64' if (self.target_cpu == 'amd64' and x64) - else r'\%s' % self.target_cpu + else r'\{}'.format(self.target_cpu) ) def cross_dir(self, forcex86=False): @@ -155,7 +155,7 @@ def cross_dir(self, forcex86=False): return ( '' if self.target_cpu == current - else self.target_dir().replace('\\', '\\%s_' % current) + else self.target_dir().replace('\\', '\\{}_'.format(current)) ) @@ -497,11 +497,11 @@ def VSInstallDir(self): """ # Default path default = os.path.join( - self.ProgramFilesx86, 'Microsoft Visual Studio %0.1f' % self.vs_ver + self.ProgramFilesx86, 'Microsoft Visual Studio {:0.1f}'.format(self.vs_ver) ) # Try to get path from registry, if fail use default path - return self.ri.lookup(self.ri.vs, '%0.1f' % self.vs_ver) or default + return self.ri.lookup(self.ri.vs, '{:0.1f}'.format(self.vs_ver)) or default @property def VCInstallDir(self): @@ -561,16 +561,16 @@ def _guess_vc_legacy(self): path """ default = os.path.join( - self.ProgramFilesx86, r'Microsoft Visual Studio %0.1f\VC' % self.vs_ver + self.ProgramFilesx86, r'Microsoft Visual Studio {:0.1f}\VC'.format(self.vs_ver) ) # Try to get "VC++ for Python" path from registry as default path - reg_path = os.path.join(self.ri.vc_for_python, '%0.1f' % self.vs_ver) + reg_path = os.path.join(self.ri.vc_for_python, '{:0.1f}'.format(self.vs_ver)) python_vc = self.ri.lookup(reg_path, 'installdir') default_vc = os.path.join(python_vc, 'VC') if python_vc else default # Try to get path from registry, if fail use default path - return self.ri.lookup(self.ri.vc, '%0.1f' % self.vs_ver) or default_vc + return self.ri.lookup(self.ri.vc, '{:0.1f}'.format(self.vs_ver)) or default_vc @property def WindowsSdkVersion(self) -> tuple[LiteralString, ...]: @@ -619,13 +619,13 @@ def WindowsSdkDir(self) -> str | None: # noqa: C901 # is too complex (12) # F sdkdir: str | None = '' for ver in self.WindowsSdkVersion: # Try to get it from registry - loc = os.path.join(self.ri.windows_sdk, 'v%s' % ver) + loc = os.path.join(self.ri.windows_sdk, 'v{}'.format(ver)) sdkdir = self.ri.lookup(loc, 'installationfolder') if sdkdir: break if not sdkdir or not os.path.isdir(sdkdir): # Try to get "VC++ for Python" version from registry - path = os.path.join(self.ri.vc_for_python, '%0.1f' % self.vc_ver) + path = os.path.join(self.ri.vc_for_python, '{:0.1f}'.format(self.vc_ver)) install_base = self.ri.lookup(path, 'installdir') if install_base: sdkdir = os.path.join(install_base, 'WinSDK') @@ -633,14 +633,14 @@ def WindowsSdkDir(self) -> str | None: # noqa: C901 # is too complex (12) # F # If fail, use default new path for ver in self.WindowsSdkVersion: intver = ver[: ver.rfind('.')] - path = r'Microsoft SDKs\Windows Kits\%s' % intver + path = r'Microsoft SDKs\Windows Kits\{}'.format(intver) d = os.path.join(self.ProgramFiles, path) if os.path.isdir(d): sdkdir = d if not sdkdir or not os.path.isdir(sdkdir): # If fail, use default old path for ver in self.WindowsSdkVersion: - path = r'Microsoft SDKs\Windows\v%s' % ver + path = r'Microsoft SDKs\Windows\v{}'.format(ver) d = os.path.join(self.ProgramFiles, path) if os.path.isdir(d): sdkdir = d @@ -676,7 +676,7 @@ def WindowsSDKExecutablePath(self): regpaths += [os.path.join(self.ri.netfx_sdk, ver, fx)] for ver in self.WindowsSdkVersion: - regpaths += [os.path.join(self.ri.windows_sdk, 'v%sA' % ver, fx)] + regpaths += [os.path.join(self.ri.windows_sdk, 'v{}A'.format(ver), fx)] # Return installation folder from the more recent path for path in regpaths: @@ -696,7 +696,7 @@ def FSharpInstallDir(self): str path """ - path = os.path.join(self.ri.visualstudio, r'%0.1f\Setup\F#' % self.vs_ver) + path = os.path.join(self.ri.visualstudio, r'{:0.1f}\Setup\F#'.format(self.vs_ver)) return self.ri.lookup(path, 'productdir') or '' @property @@ -714,7 +714,7 @@ def UniversalCRTSdkDir(self): # Find path of the more recent Kit for ver in vers: - sdkdir = self.ri.lookup(self.ri.windows_kits_roots, 'kitsroot%s' % ver) + sdkdir = self.ri.lookup(self.ri.windows_kits_roots, 'kitsroot{}'.format(ver)) if sdkdir: return sdkdir or '' @@ -960,7 +960,7 @@ def VSTools(self): arch_subdir = self.pi.current_dir(hidex86=True, x64=True) paths += [r'Common7\IDE\CommonExtensions\Microsoft\TestWindow'] paths += [r'Team Tools\Performance Tools'] - paths += [r'Team Tools\Performance Tools%s' % arch_subdir] + paths += [r'Team Tools\Performance Tools{}'.format(arch_subdir)] return [os.path.join(self.si.VSInstallDir, path) for path in paths] @@ -993,10 +993,10 @@ def VCLibraries(self): arch_subdir = self.pi.target_dir(x64=True) else: arch_subdir = self.pi.target_dir(hidex86=True) - paths = ['Lib%s' % arch_subdir, r'ATLMFC\Lib%s' % arch_subdir] + paths = ['Lib{}'.format(arch_subdir), r'ATLMFC\Lib{}'.format(arch_subdir)] if self.vs_ver >= 14.0: - paths += [r'Lib\store%s' % arch_subdir] + paths += [r'Lib\store{}'.format(arch_subdir)] return [os.path.join(self.si.VCInstallDir, path) for path in paths] @@ -1030,10 +1030,10 @@ def VCTools(self): forcex86 = True if self.vs_ver <= 10.0 else False arch_subdir = self.pi.cross_dir(forcex86) if arch_subdir: - tools += [os.path.join(si.VCInstallDir, 'Bin%s' % arch_subdir)] + tools += [os.path.join(si.VCInstallDir, 'Bin{}'.format(arch_subdir))] if self.vs_ver == 14.0: - path = 'Bin%s' % self.pi.current_dir(hidex86=True) + path = 'Bin{}'.format(self.pi.current_dir(hidex86=True)) tools += [os.path.join(si.VCInstallDir, path)] elif self.vs_ver >= 15.0: @@ -1068,13 +1068,13 @@ def OSLibraries(self): """ if self.vs_ver <= 10.0: arch_subdir = self.pi.target_dir(hidex86=True, x64=True) - return [os.path.join(self.si.WindowsSdkDir, 'Lib%s' % arch_subdir)] + return [os.path.join(self.si.WindowsSdkDir, 'Lib{}'.format(arch_subdir))] else: arch_subdir = self.pi.target_dir(x64=True) lib = os.path.join(self.si.WindowsSdkDir, 'lib') libver = self._sdk_subdir - return [os.path.join(lib, '%sum%s' % (libver, arch_subdir))] + return [os.path.join(lib, '{}um{}'.format(libver, arch_subdir))] @property def OSIncludes(self): @@ -1097,9 +1097,9 @@ def OSIncludes(self): else: sdkver = '' return [ - os.path.join(include, '%sshared' % sdkver), - os.path.join(include, '%sum' % sdkver), - os.path.join(include, '%swinrt' % sdkver), + os.path.join(include, '{}shared'.format(sdkver)), + os.path.join(include, '{}um'.format(sdkver)), + os.path.join(include, '{}winrt'.format(sdkver)), ] @property @@ -1134,7 +1134,7 @@ def OSLibpath(self): self.si.WindowsSdkDir, 'ExtensionSDKs', 'Microsoft.VCLibs', - '%0.1f' % self.vs_ver, + '{:0.1f}'.format(self.vs_ver), 'References', 'CommonConfiguration', 'neutral', @@ -1169,7 +1169,7 @@ def _sdk_tools(self): if not self.pi.current_is_x86(): arch_subdir = self.pi.current_dir(x64=True) - path = 'Bin%s' % arch_subdir + path = 'Bin{}'.format(arch_subdir) yield os.path.join(self.si.WindowsSdkDir, path) if self.vs_ver in (10.0, 11.0): @@ -1177,14 +1177,14 @@ def _sdk_tools(self): arch_subdir = '' else: arch_subdir = self.pi.current_dir(hidex86=True, x64=True) - path = r'Bin\NETFX 4.0 Tools%s' % arch_subdir + path = r'Bin\NETFX 4.0 Tools{}'.format(arch_subdir) yield os.path.join(self.si.WindowsSdkDir, path) elif self.vs_ver >= 15.0: path = os.path.join(self.si.WindowsSdkDir, 'Bin') arch_subdir = self.pi.current_dir(x64=True) sdkver = self.si.WindowsSdkLastVersion - yield os.path.join(path, '%s%s' % (sdkver, arch_subdir)) + yield os.path.join(path, '{}{}'.format(sdkver, arch_subdir)) if self.si.WindowsSDKExecutablePath: yield self.si.WindowsSDKExecutablePath @@ -1200,7 +1200,7 @@ def _sdk_subdir(self): subdir """ ucrtver = self.si.WindowsSdkLastVersion - return ('%s\\' % ucrtver) if ucrtver else '' + return ('{}\\'.format(ucrtver)) if ucrtver else '' @property def SdkSetup(self): @@ -1262,7 +1262,7 @@ def NetFxSDKLibraries(self): return [] arch_subdir = self.pi.target_dir(x64=True) - return [os.path.join(self.si.NetFxSdkDir, r'lib\um%s' % arch_subdir)] + return [os.path.join(self.si.NetFxSdkDir, r'lib\um{}'.format(arch_subdir))] @property def NetFxSDKIncludes(self): @@ -1310,7 +1310,7 @@ def MSBuild(self): base_path = self.si.VSInstallDir arch_subdir = '' - path = r'MSBuild\%0.1f\bin%s' % (self.vs_ver, arch_subdir) + path = r'MSBuild\{:0.1f}\bin{}'.format(self.vs_ver, arch_subdir) build = [os.path.join(base_path, path)] if self.vs_ver >= 15.0: @@ -1350,7 +1350,7 @@ def UCRTLibraries(self): arch_subdir = self.pi.target_dir(x64=True) lib = os.path.join(self.si.UniversalCRTSdkDir, 'lib') ucrtver = self._ucrt_subdir - return [os.path.join(lib, '%sucrt%s' % (ucrtver, arch_subdir))] + return [os.path.join(lib, '{}ucrt{}'.format(ucrtver, arch_subdir))] @property def UCRTIncludes(self): @@ -1366,7 +1366,7 @@ def UCRTIncludes(self): return [] include = os.path.join(self.si.UniversalCRTSdkDir, 'include') - return [os.path.join(include, '%sucrt' % self._ucrt_subdir)] + return [os.path.join(include, '{}ucrt'.format(self._ucrt_subdir))] @property def _ucrt_subdir(self): @@ -1379,7 +1379,7 @@ def _ucrt_subdir(self): subdir """ ucrtver = self.si.UniversalCRTSdkLastVersion - return ('%s\\' % ucrtver) if ucrtver else '' + return ('{}\\'.format(ucrtver)) if ucrtver else '' @property def FSharp(self): @@ -1520,7 +1520,7 @@ def _build_paths(self, name, spec_path_lists, exists): paths = itertools.chain(spec_paths, env_paths) extant_paths = list(filter(os.path.isdir, paths)) if exists else paths if not extant_paths: - msg = "%s environment variable is empty" % name.upper() + msg = "{} environment variable is empty".format(name.upper()) raise distutils.errors.DistutilsPlatformError(msg) unique_paths = unique_everseen(extant_paths) return os.pathsep.join(unique_paths) diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 97806e8ff8..24fae988a2 100644 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -74,7 +74,7 @@ def parse_requirement_arg(spec): return Requirement.parse(spec) except ValueError as e: raise DistutilsError( - "Not a URL, existing file, or requirement spec: %r" % (spec,) + "Not a URL, existing file, or requirement spec: {!r}".format(spec) ) from e @@ -357,7 +357,7 @@ def process_url(self, url, retrieve: bool = False) -> None: # noqa: C901 if f is None: return if isinstance(f, urllib.error.HTTPError) and f.code == 401: - self.info("Authentication error: %s" % f.msg) + self.info("Authentication error: {}".format(f.msg)) self.fetched_urls[f.url] = True if 'html' not in f.headers.get('content-type', '').lower(): f.close() # not html, we can't process it @@ -474,13 +474,13 @@ def process_index(self, url, page): base, frag = egg_info_for_url(new_url) if base.endswith('.py') and not frag: if ver: - new_url += '#egg=%s-%s' % (pkg, ver) + new_url += '#egg={}-{}'.format(pkg, ver) else: self.need_version_info(url) self.scan_url(new_url) return PYPI_MD5.sub( - lambda m: '%s' % m.group(1, 3, 2), page + lambda m: '{}'.format(*m.group(1, 3, 2)), page ) def need_version_info(self, url) -> None: @@ -525,14 +525,13 @@ def check_hash(self, checker, filename, tfp) -> None: """ checker is a ContentChecker """ - checker.report(self.debug, "Validating %%s checksum for %s" % filename) + checker.report(self.debug, "Validating %s checksum for {}".format(filename)) if not checker.is_valid(): tfp.close() os.unlink(filename) raise DistutilsError( - "%s validation failed for %s; " - "possible download problem?" - % (checker.hash.name, os.path.basename(filename)) + "{} validation failed for {}; " + "possible download problem?".format(checker.hash.name, os.path.basename(filename)) ) def add_find_links(self, urls) -> None: @@ -720,8 +719,7 @@ def gen_setup(self, filename, fragment, tmpdir): with open(os.path.join(tmpdir, 'setup.py'), 'w', encoding="utf-8") as file: file.write( "from setuptools import setup\n" - "setup(name=%r, version=%r, py_modules=[%r])\n" - % ( + "setup(name={!r}, version={!r}, py_modules=[{!r}])\n".format( dists[0].project_name, dists[0].version, os.path.splitext(basename)[0], @@ -731,9 +729,9 @@ def gen_setup(self, filename, fragment, tmpdir): elif match: raise DistutilsError( - "Can't unambiguously interpret project/version identifier %r; " + "Can't unambiguously interpret project/version identifier {!r}; " "any dashes in the name or version should be escaped using " - "underscores. %r" % (fragment, dists) + "underscores. {!r}".format(fragment, dists) ) else: raise DistutilsError( @@ -752,7 +750,7 @@ def _download_to(self, url, filename): fp = self.open_url(url) if isinstance(fp, urllib.error.HTTPError): raise DistutilsError( - "Can't download %s: %s %s" % (url, fp.code, fp.msg) + "Can't download {}: {} {}".format(url, fp.code, fp.msg) ) headers = fp.info() blocknum = 0 @@ -793,7 +791,7 @@ def open_url(self, url, warning=None): # noqa: C901 # is too complex (12) if warning: self.warn(warning, msg) else: - raise DistutilsError('%s %s' % (url, msg)) from v + raise DistutilsError('{} {}'.format(url, msg)) from v except urllib.error.HTTPError as v: return v except urllib.error.URLError as v: @@ -801,21 +799,21 @@ def open_url(self, url, warning=None): # noqa: C901 # is too complex (12) self.warn(warning, v.reason) else: raise DistutilsError( - "Download error for %s: %s" % (url, v.reason) + "Download error for {}: {}".format(url, v.reason) ) from v except http.client.BadStatusLine as v: if warning: self.warn(warning, v.line) else: raise DistutilsError( - '%s returned a bad status line. The server might be ' - 'down, %s' % (url, v.line) + '{} returned a bad status line. The server might be ' + 'down, {}'.format(url, v.line) ) from v except (http.client.HTTPException, OSError) as v: if warning: self.warn(warning, v) else: - raise DistutilsError("Download error for %s: %s" % (url, v)) from v + raise DistutilsError("Download error for {}: {}".format(url, v)) from v def _download_url(self, url, tmpdir): # Determine download filename diff --git a/setuptools/tests/config/test_setupcfg.py b/setuptools/tests/config/test_setupcfg.py index b31118c0fb..399c9dd743 100644 --- a/setuptools/tests/config/test_setupcfg.py +++ b/setuptools/tests/config/test_setupcfg.py @@ -87,14 +87,14 @@ def test_basic(self, tmpdir): '[options]\n' 'scripts = bin/a.py, bin/b.py\n', ) - config_dict = read_configuration('%s' % config) + config_dict = read_configuration('{}'.format(config)) assert config_dict['metadata']['version'] == '10.1.1' assert config_dict['metadata']['keywords'] == ['one', 'two'] assert config_dict['options']['scripts'] == ['bin/a.py', 'bin/b.py'] def test_no_config(self, tmpdir): with pytest.raises(DistutilsFileError): - read_configuration('%s' % tmpdir.join('setup.cfg')) + read_configuration('{}'.format(tmpdir.join('setup.cfg'))) def test_ignore_errors(self, tmpdir): _, config = fake_env( @@ -102,9 +102,9 @@ def test_ignore_errors(self, tmpdir): '[metadata]\nversion = attr: none.VERSION\nkeywords = one, two\n', ) with pytest.raises(ImportError): - read_configuration('%s' % config) + read_configuration('{}'.format(config)) - config_dict = read_configuration('%s' % config, ignore_option_errors=True) + config_dict = read_configuration('{}'.format(config), ignore_option_errors=True) assert config_dict['metadata']['keywords'] == ['one', 'two'] assert 'version' not in config_dict['metadata'] diff --git a/setuptools/tests/server.py b/setuptools/tests/server.py index 15bbc3b1f0..0a0fc2b668 100644 --- a/setuptools/tests/server.py +++ b/setuptools/tests/server.py @@ -44,7 +44,7 @@ def stop(self): def base_url(self): port = self.server_port - return 'http://127.0.0.1:%s/setuptools/tests/indexes/' % port + return 'http://127.0.0.1:{}/setuptools/tests/indexes/'.format(port) class RequestRecorder(http.server.BaseHTTPRequestHandler): @@ -70,11 +70,11 @@ def run(self): @property def netloc(self): - return 'localhost:%s' % self.server_port + return 'localhost:{}'.format(self.server_port) @property def url(self): - return 'http://%s/' % self.netloc + return 'http://{}/'.format(self.netloc) def path_to_url(path, authority=None): diff --git a/setuptools/tests/test_build_ext.py b/setuptools/tests/test_build_ext.py index 5ce96a66f7..be7b7cc01c 100644 --- a/setuptools/tests/test_build_ext.py +++ b/setuptools/tests/test_build_ext.py @@ -290,4 +290,4 @@ def test_build_ext_config_handling(tmpdir_cwd): cmd=['build'], data_stream=(0, 2), ) - assert code == 0, '\nSTDOUT:\n%s\nSTDERR:\n%s' % output + assert code == 0, '\nSTDOUT:\n{}\nSTDERR:\n{}'.format(*output) diff --git a/setuptools/tests/test_core_metadata.py b/setuptools/tests/test_core_metadata.py index b67373bc37..89b2ea3054 100644 --- a/setuptools/tests/test_core_metadata.py +++ b/setuptools/tests/test_core_metadata.py @@ -311,7 +311,7 @@ def test_maintainer_author(name, attrs, tmpdir): for line in pkg_lines: assert not line.startswith(fkey + ':') else: - line = '%s: %s' % (fkey, val) + line = '{}: {}'.format(fkey, val) assert line in pkg_lines_set diff --git a/setuptools/tests/test_dist.py b/setuptools/tests/test_dist.py index 7b8cb91469..e1d7c1e043 100644 --- a/setuptools/tests/test_dist.py +++ b/setuptools/tests/test_dist.py @@ -24,7 +24,7 @@ def test_dist_fetch_build_egg(tmpdir): def sdist_with_index(distname, version): dist_dir = index.mkdir(distname) - dist_sdist = '%s-%s.tar.gz' % (distname, version) + dist_sdist = '{}-{}.tar.gz'.format(distname, version) make_nspkg_sdist(str(dist_dir.join(dist_sdist)), distname, version) with dist_dir.join('index.html').open('w') as fp: fp.write( diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 586324be37..a34f9bd525 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -814,7 +814,7 @@ def test_setup_requires_with_pep508_url(self, mock_index, monkeypatch): # Ignored (overridden by setup_attrs) 'python-xlib', '0.19', - setup_attrs=dict(setup_requires='dependency @ %s' % dep_url), + setup_attrs=dict(setup_requires='dependency @ {}'.format(dep_url)), ) test_setup_py = os.path.join(test_pkg, 'setup.py') run_setup(test_setup_py, ['--version']) @@ -1103,11 +1103,10 @@ def make_trivial_sdist(dist_path, distname, version): """\ import setuptools setuptools.setup( - name=%r, - version=%r + name={!r}, + version={!r} ) - """ - % (distname, version) + """.format(distname, version) ), ), ('setup.cfg', ''), @@ -1131,13 +1130,12 @@ def make_nspkg_sdist(dist_path, distname, version): """\ import setuptools setuptools.setup( - name=%r, - version=%r, - packages=%r, - namespace_packages=[%r] + name={!r}, + version={!r}, + packages={!r}, + namespace_packages=[{!r}] ) - """ - % (distname, version, packages, nspackage) + """.format(distname, version, packages, nspackage) ) init = "__import__('pkg_resources').declare_namespace(__name__)" @@ -1212,7 +1210,7 @@ def create_setup_requires_package( test_setup_attrs = { 'name': 'test_pkg', 'version': '0.0', - 'setup_requires': ['%s==%s' % (distname, version)], + 'setup_requires': ['{}=={}'.format(distname, version)], 'dependency_links': [os.path.abspath(path)], } if setup_attrs: @@ -1233,7 +1231,7 @@ def create_setup_requires_package( section = options if isinstance(value, (tuple, list)): value = ';'.join(value) - section.append('%s: %s' % (name, value)) + section.append('{}: {}'.format(name, value)) test_setup_cfg_contents = DALS( """ [metadata] @@ -1261,7 +1259,7 @@ def create_setup_requires_package( with open(os.path.join(test_pkg, 'setup.py'), 'w', encoding="utf-8") as f: f.write(setup_py_template % test_setup_attrs) - foobar_path = os.path.join(path, '%s-%s.tar.gz' % (distname, version)) + foobar_path = os.path.join(path, '{}-{}.tar.gz'.format(distname, version)) make_package(foobar_path, distname, version) return test_pkg @@ -1276,12 +1274,12 @@ class TestScriptHeader: exe_with_spaces = r'C:\Program Files\Python36\python.exe' def test_get_script_header(self): - expected = '#!%s\n' % ei.nt_quote_arg(os.path.normpath(sys.executable)) + expected = '#!{}\n'.format(ei.nt_quote_arg(os.path.normpath(sys.executable))) actual = ei.ScriptWriter.get_header('#!/usr/local/bin/python') assert actual == expected def test_get_script_header_args(self): - expected = '#!%s -x\n' % ei.nt_quote_arg(os.path.normpath(sys.executable)) + expected = '#!{} -x\n'.format(ei.nt_quote_arg(os.path.normpath(sys.executable))) actual = ei.ScriptWriter.get_header('#!/usr/bin/python -x') assert actual == expected @@ -1289,14 +1287,14 @@ def test_get_script_header_non_ascii_exe(self): actual = ei.ScriptWriter.get_header( '#!/usr/bin/python', executable=self.non_ascii_exe ) - expected = '#!%s -x\n' % self.non_ascii_exe + expected = '#!{} -x\n'.format(self.non_ascii_exe) assert actual == expected def test_get_script_header_exe_with_spaces(self): actual = ei.ScriptWriter.get_header( '#!/usr/bin/python', executable='"' + self.exe_with_spaces + '"' ) - expected = '#!"%s"\n' % self.exe_with_spaces + expected = '#!"{}"\n'.format(self.exe_with_spaces) assert actual == expected diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py index a68ecaba4c..24e73be44f 100644 --- a/setuptools/tests/test_egg_info.py +++ b/setuptools/tests/test_egg_info.py @@ -38,9 +38,8 @@ def env(): '.pydistutils.cfg': DALS( """ [egg_info] - egg-base = %(egg-base)s - """ - % env.paths + egg-base = {egg-base} + """.format(**env.paths) ) } }) diff --git a/setuptools/tests/test_install_scripts.py b/setuptools/tests/test_install_scripts.py index 2ae5496525..f496fe5917 100644 --- a/setuptools/tests/test_install_scripts.py +++ b/setuptools/tests/test_install_scripts.py @@ -38,7 +38,7 @@ def test_sys_executable_escaping_unix(self, tmpdir, monkeypatch): Ensure that shebang is not quoted on Unix when getting the Python exe from sys.executable. """ - expected = '#!%s\n' % self.unix_exe + expected = '#!{}\n'.format(self.unix_exe) monkeypatch.setattr('sys.executable', self.unix_exe) with tmpdir.as_cwd(): self._run_install_scripts(str(tmpdir)) @@ -52,7 +52,7 @@ def test_sys_executable_escaping_win32(self, tmpdir, monkeypatch): Ensure that shebang is quoted on Windows when getting the Python exe from sys.executable and it contains a space. """ - expected = '#!"%s"\n' % self.win32_exe + expected = '#!"{}"\n'.format(self.win32_exe) monkeypatch.setattr('sys.executable', self.win32_exe) with tmpdir.as_cwd(): self._run_install_scripts(str(tmpdir)) @@ -67,7 +67,7 @@ def test_executable_with_spaces_escaping_unix(self, tmpdir): a value with spaces is specified using --executable. """ - expected = '#!%s\n' % self.unix_spaces_exe + expected = '#!{}\n'.format(self.unix_spaces_exe) with tmpdir.as_cwd(): self._run_install_scripts(str(tmpdir), self.unix_spaces_exe) with open(str(tmpdir.join('foo')), 'r', encoding="utf-8") as f: @@ -81,7 +81,7 @@ def test_executable_arg_escaping_win32(self, tmpdir): getting a path with spaces from --executable, that is itself properly quoted. """ - expected = '#!"%s"\n' % self.win32_exe + expected = '#!"{}"\n'.format(self.win32_exe) with tmpdir.as_cwd(): self._run_install_scripts(str(tmpdir), '"' + self.win32_exe + '"') with open(str(tmpdir.join('foo-script.py')), 'r', encoding="utf-8") as f: diff --git a/setuptools/tests/test_manifest.py b/setuptools/tests/test_manifest.py index ad988d2c5f..333644051f 100644 --- a/setuptools/tests/test_manifest.py +++ b/setuptools/tests/test_manifest.py @@ -38,9 +38,8 @@ def make_local_path(s): """\ from setuptools import setup -setup(**%r) -""" - % SETUP_ATTRS +setup(**{!r}) +""".format(SETUP_ATTRS) ) diff --git a/setuptools/tests/test_sandbox.py b/setuptools/tests/test_sandbox.py index 20db6baaa6..5531ea8660 100644 --- a/setuptools/tests/test_sandbox.py +++ b/setuptools/tests/test_sandbox.py @@ -76,7 +76,7 @@ class CantPickleThis(Exception): "This Exception is unpickleable because it's not in globals" def __repr__(self) -> str: - return 'CantPickleThis%r' % (self.args,) + return 'CantPickleThis{!r}'.format(self.args) with setuptools.sandbox.ExceptionSaver() as saved_exc: raise CantPickleThis('detail') diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 30347190db..3ad1f070f6 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -41,9 +41,8 @@ """\ from setuptools import setup -setup(**%r) -""" - % SETUP_ATTRS +setup(**{!r}) +""".format(SETUP_ATTRS) ) EXTENSION = Extension( diff --git a/setuptools/tests/test_wheel.py b/setuptools/tests/test_wheel.py index 5c6bda0454..7e700a14d2 100644 --- a/setuptools/tests/test_wheel.py +++ b/setuptools/tests/test_wheel.py @@ -176,7 +176,7 @@ def __init__(self, id, **kwargs): self._fields = kwargs def __repr__(self) -> str: - return '%s(**%r)' % (self._id, self._fields) + return '{}(**{!r})'.format(self._id, self._fields) # Using Any to avoid possible type union issues later in test @@ -369,9 +369,8 @@ def __repr__(self) -> str: id='requires2', install_requires=""" bar - foo<=2.0; %r in sys_platform - """ - % sys.platform, + foo<=2.0; {!r} in sys_platform + """.format(sys.platform), requires_txt=DALS( """ bar @@ -382,9 +381,8 @@ def __repr__(self) -> str: dict( id='requires3', install_requires=""" - bar; %r != sys_platform - """ - % sys.platform, + bar; {!r} != sys_platform + """.format(sys.platform), ), dict( id='requires4', @@ -406,7 +404,7 @@ def __repr__(self) -> str: dict( id='requires5', extras_require={ - 'extra': 'foobar; %r != sys_platform' % sys.platform, + 'extra': 'foobar; {!r} != sys_platform'.format(sys.platform), }, requires_txt=DALS( """ diff --git a/setuptools/wheel.py b/setuptools/wheel.py index fb19f1a65a..08821b7c7a 100644 --- a/setuptools/wheel.py +++ b/setuptools/wheel.py @@ -79,7 +79,7 @@ class Wheel: def __init__(self, filename) -> None: match = WHEEL_NAME(os.path.basename(filename)) if match is None: - raise ValueError('invalid wheel name: %r' % filename) + raise ValueError('invalid wheel name: {!r}'.format(filename)) self.filename = filename for k, v in match.groupdict().items(): setattr(self, k, v) @@ -122,9 +122,9 @@ def install_as_egg(self, destination_eggdir) -> None: self._install_as_egg(destination_eggdir, zf) def _install_as_egg(self, destination_eggdir, zf): - dist_basename = '%s-%s' % (self.project_name, self.version) + dist_basename = '{}-{}'.format(self.project_name, self.version) dist_info = self.get_dist_info(zf) - dist_data = '%s.data' % dist_basename + dist_data = '{}.data'.format(dist_basename) egg_info = os.path.join(destination_eggdir, 'EGG-INFO') self._convert_metadata(zf, destination_eggdir, dist_info, egg_info) @@ -145,7 +145,7 @@ def get_metadata(name): wheel_version = parse_version(wheel_metadata.get('Wheel-Version')) wheel_v1 = parse_version('1.0') <= wheel_version < parse_version('2.0dev0') if not wheel_v1: - raise ValueError('unsupported wheel format version: %s' % wheel_version) + raise ValueError('unsupported wheel format version: {}'.format(wheel_version)) # Extract to target directory. _unpack_zipfile_obj(zf, destination_eggdir) # Convert metadata. From f28308aba4a62b1602e0dfc750b3016e22fad89a Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 10 Sep 2024 12:26:55 +0200 Subject: [PATCH 3/8] A round of `ruff format` after `ruff check --fix` --- setuptools/command/bdist_egg.py | 4 +++- setuptools/command/easy_install.py | 16 ++++++++++++---- setuptools/command/egg_info.py | 4 +++- setuptools/command/install_egg_info.py | 4 +++- setuptools/dist.py | 12 +++++++++--- setuptools/msvc.py | 11 ++++++++--- setuptools/package_index.py | 5 +++-- setuptools/tests/test_manifest.py | 4 +--- setuptools/tests/test_sdist.py | 4 +--- setuptools/wheel.py | 4 +++- 10 files changed, 46 insertions(+), 22 deletions(-) diff --git a/setuptools/command/bdist_egg.py b/setuptools/command/bdist_egg.py index d991049b5b..44ccdfd240 100644 --- a/setuptools/command/bdist_egg.py +++ b/setuptools/command/bdist_egg.py @@ -263,7 +263,9 @@ def zap_pyfiles(self): pattern = r'(?P.+)\.(?P[^.]+)\.pyc' m = re.match(pattern, name) path_new = os.path.join(base, os.pardir, m.group('name') + '.pyc') - log.info("Renaming file from [{}] to [{}]".format(path_old, path_new)) + log.info( + "Renaming file from [{}] to [{}]".format(path_old, path_new) + ) try: os.remove(path_new) except OSError: diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 88d39c043a..53f96aef2b 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -659,7 +659,9 @@ def check_editable(self, spec) -> None: if os.path.exists(os.path.join(self.build_directory, spec.key)): raise DistutilsArgError( - "{!r} already exists in {}; can't do a checkout there".format(spec.key, self.build_directory) + "{!r} already exists in {}; can't do a checkout there".format( + spec.key, self.build_directory + ) ) @contextlib.contextmanager @@ -916,11 +918,15 @@ def install_eggs(self, spec, dist_filename, tmpdir) -> list[Distribution]: setups = glob(os.path.join(setup_base, '*', 'setup.py')) if not setups: raise DistutilsError( - "Couldn't find a setup script in {}".format(os.path.abspath(dist_filename)) + "Couldn't find a setup script in {}".format( + os.path.abspath(dist_filename) + ) ) if len(setups) > 1: raise DistutilsError( - "Multiple setup scripts in {}".format(os.path.abspath(dist_filename)) + "Multiple setup scripts in {}".format( + os.path.abspath(dist_filename) + ) ) setup_script = setups[0] @@ -1112,7 +1118,9 @@ def install_wheel(self, wheel_path, tmpdir): self.execute( wheel.install_as_egg, (destination,), - ("Installing {} to {}").format(os.path.basename(wheel_path), os.path.dirname(destination)), + ("Installing {} to {}").format( + os.path.basename(wheel_path), os.path.dirname(destination) + ), ) finally: update_dist_caches(destination, fix_zipimporter_caches=False) diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 9a9ea63322..335eeb4efd 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -231,7 +231,9 @@ def finalize_options(self) -> None: packaging.requirements.Requirement(spec % (self.egg_name, self.egg_version)) except ValueError as e: raise distutils.errors.DistutilsOptionError( - "Invalid distribution name or version syntax: {}-{}".format(self.egg_name, self.egg_version) + "Invalid distribution name or version syntax: {}-{}".format( + self.egg_name, self.egg_version + ) ) from e if self.egg_base is None: diff --git a/setuptools/command/install_egg_info.py b/setuptools/command/install_egg_info.py index 991531caa0..42cfe4e64d 100644 --- a/setuptools/command/install_egg_info.py +++ b/setuptools/command/install_egg_info.py @@ -36,7 +36,9 @@ def run(self) -> None: self.execute(os.unlink, (self.target,), "Removing " + self.target) if not self.dry_run: ensure_directory(self.target) - self.execute(self.copytree, (), "Copying {} to {}".format(self.source, self.target)) + self.execute( + self.copytree, (), "Copying {} to {}".format(self.source, self.target) + ) self.install_namespaces() def get_outputs(self): diff --git a/setuptools/dist.py b/setuptools/dist.py index 182a03b36a..13a0b43448 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -85,7 +85,9 @@ def check_importable(dist, attr, value): assert not ep.extras except (TypeError, ValueError, AttributeError, AssertionError) as e: raise DistutilsSetupError( - "{!r} must be importable 'module:attrs' string (got {!r})".format(attr, value) + "{!r} must be importable 'module:attrs' string (got {!r})".format( + attr, value + ) ) from e @@ -611,7 +613,9 @@ def _set_command_options(self, command_obj, option_dict=None): # noqa: C901 setattr(command_obj, option, value) else: raise DistutilsOptionError( - "error in {}: command '{}' has no such option '{}'".format(source, command_name, option) + "error in {}: command '{}' has no such option '{}'".format( + source, command_name, option + ) ) except ValueError as e: raise DistutilsOptionError(e) from e @@ -835,7 +839,9 @@ def _include_misc(self, name: str, value: _Sequence) -> None: try: old = getattr(self, name) except AttributeError as e: - raise DistutilsSetupError("{}: No such distribution setting".format(name)) from e + raise DistutilsSetupError( + "{}: No such distribution setting".format(name) + ) from e if old is None: setattr(self, name, value) elif not isinstance(old, _sequence): diff --git a/setuptools/msvc.py b/setuptools/msvc.py index 55e5cd21fd..727897d1d3 100644 --- a/setuptools/msvc.py +++ b/setuptools/msvc.py @@ -561,7 +561,8 @@ def _guess_vc_legacy(self): path """ default = os.path.join( - self.ProgramFilesx86, r'Microsoft Visual Studio {:0.1f}\VC'.format(self.vs_ver) + self.ProgramFilesx86, + r'Microsoft Visual Studio {:0.1f}\VC'.format(self.vs_ver), ) # Try to get "VC++ for Python" path from registry as default path @@ -696,7 +697,9 @@ def FSharpInstallDir(self): str path """ - path = os.path.join(self.ri.visualstudio, r'{:0.1f}\Setup\F#'.format(self.vs_ver)) + path = os.path.join( + self.ri.visualstudio, r'{:0.1f}\Setup\F#'.format(self.vs_ver) + ) return self.ri.lookup(path, 'productdir') or '' @property @@ -714,7 +717,9 @@ def UniversalCRTSdkDir(self): # Find path of the more recent Kit for ver in vers: - sdkdir = self.ri.lookup(self.ri.windows_kits_roots, 'kitsroot{}'.format(ver)) + sdkdir = self.ri.lookup( + self.ri.windows_kits_roots, 'kitsroot{}'.format(ver) + ) if sdkdir: return sdkdir or '' diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 24fae988a2..373c047b93 100644 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -530,8 +530,9 @@ def check_hash(self, checker, filename, tfp) -> None: tfp.close() os.unlink(filename) raise DistutilsError( - "{} validation failed for {}; " - "possible download problem?".format(checker.hash.name, os.path.basename(filename)) + "{} validation failed for {}; " "possible download problem?".format( + checker.hash.name, os.path.basename(filename) + ) ) def add_find_links(self, urls) -> None: diff --git a/setuptools/tests/test_manifest.py b/setuptools/tests/test_manifest.py index 333644051f..a821cf778b 100644 --- a/setuptools/tests/test_manifest.py +++ b/setuptools/tests/test_manifest.py @@ -34,13 +34,11 @@ def make_local_path(s): 'packages': ['app'], } -SETUP_PY = ( - """\ +SETUP_PY = """\ from setuptools import setup setup(**{!r}) """.format(SETUP_ATTRS) -) @contextlib.contextmanager diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 3ad1f070f6..8f5e620f0d 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -37,13 +37,11 @@ 'data_files': [("data", [os.path.join("d", "e.dat")])], } -SETUP_PY = ( - """\ +SETUP_PY = """\ from setuptools import setup setup(**{!r}) """.format(SETUP_ATTRS) -) EXTENSION = Extension( name="sdist_test.f", diff --git a/setuptools/wheel.py b/setuptools/wheel.py index 08821b7c7a..9ccd9e7ede 100644 --- a/setuptools/wheel.py +++ b/setuptools/wheel.py @@ -145,7 +145,9 @@ def get_metadata(name): wheel_version = parse_version(wheel_metadata.get('Wheel-Version')) wheel_v1 = parse_version('1.0') <= wheel_version < parse_version('2.0dev0') if not wheel_v1: - raise ValueError('unsupported wheel format version: {}'.format(wheel_version)) + raise ValueError( + 'unsupported wheel format version: {}'.format(wheel_version) + ) # Extract to target directory. _unpack_zipfile_obj(zf, destination_eggdir) # Convert metadata. From c0c1b8b60e0f4af2444f47054f93ef4af7bbf0ea Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 10 Sep 2024 12:27:29 +0200 Subject: [PATCH 4/8] Enforce ruff/pyupgrade rule UP032 UP032 Use f-string instead of `format` call --- pkg_resources/__init__.py | 42 ++++++------- pkg_resources/tests/test_pkg_resources.py | 10 ++-- ruff.toml | 1 - setuptools/__init__.py | 4 +- setuptools/_core_metadata.py | 4 +- setuptools/_imp.py | 6 +- setuptools/archive_util.py | 8 +-- setuptools/command/alias.py | 4 +- setuptools/command/bdist_egg.py | 2 +- setuptools/command/build_clib.py | 16 ++--- setuptools/command/build_ext.py | 2 +- setuptools/command/build_py.py | 4 +- setuptools/command/dist_info.py | 2 +- setuptools/command/easy_install.py | 38 +++++------- setuptools/command/egg_info.py | 14 ++--- setuptools/command/install_egg_info.py | 2 +- setuptools/command/sdist.py | 4 +- setuptools/command/setopt.py | 2 +- setuptools/config/expand.py | 2 +- setuptools/config/setupcfg.py | 14 +---- setuptools/depends.py | 2 +- setuptools/dist.py | 24 ++++---- setuptools/monkey.py | 2 +- setuptools/msvc.py | 72 +++++++++++------------ setuptools/package_index.py | 36 +++++------- setuptools/tests/config/test_setupcfg.py | 6 +- setuptools/tests/server.py | 6 +- setuptools/tests/test_core_metadata.py | 2 +- setuptools/tests/test_dist.py | 2 +- setuptools/tests/test_easy_install.py | 44 +++++++------- setuptools/tests/test_egg_info.py | 8 +-- setuptools/tests/test_install_scripts.py | 8 +-- setuptools/tests/test_manifest.py | 6 +- setuptools/tests/test_sandbox.py | 2 +- setuptools/tests/test_sdist.py | 6 +- setuptools/tests/test_wheel.py | 18 +++--- setuptools/tests/test_windows_wrappers.py | 4 +- setuptools/wheel.py | 8 +-- 38 files changed, 196 insertions(+), 241 deletions(-) diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 94dde1f218..044c1a04ef 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -492,7 +492,7 @@ def compatible_platforms(provided: str | None, required: str | None) -> bool: provDarwin = darwinVersionString.match(provided) if provDarwin: dversion = int(provDarwin.group(1)) - macosversion = "{}.{}".format(reqMac.group(1), reqMac.group(2)) + macosversion = f"{reqMac.group(1)}.{reqMac.group(2)}" if ( dversion == 7 and macosversion >= "10.3" @@ -1316,7 +1316,7 @@ def __iadd__(self, other: Distribution | Environment) -> Self: for dist in other[project]: self.add(dist) else: - raise TypeError("Can't add {!r} to environment".format(other)) + raise TypeError(f"Can't add {other!r} to environment") return self def __add__(self, other: Distribution | Environment) -> Self: @@ -1699,7 +1699,7 @@ def get_metadata(self, name: str) -> str: except UnicodeDecodeError as exc: # Include the path in the error message to simplify # troubleshooting, and without changing the exception type. - exc.reason += ' in {} file at path: {}'.format(name, path) + exc.reason += f' in {name} file at path: {path}' raise def get_metadata_lines(self, name: str) -> Iterator[str]: @@ -2018,7 +2018,7 @@ def _zipinfo_name(self, fspath): return '' if fspath.startswith(self.zip_pre): return fspath[len(self.zip_pre) :] - raise AssertionError("{} is not a subpath of {}".format(fspath, self.zip_pre)) + raise AssertionError(f"{fspath} is not a subpath of {self.zip_pre}") def _parts(self, zip_path): # Convert a zipfile subpath into an egg-relative path part list. @@ -2026,7 +2026,7 @@ def _parts(self, zip_path): fspath = self.zip_pre + zip_path if fspath.startswith(self.egg_root + os.sep): return fspath[len(self.egg_root) + 1 :].split(os.sep) - raise AssertionError("{} is not a subpath of {}".format(fspath, self.egg_root)) + raise AssertionError(f"{fspath} is not a subpath of {self.egg_root}") @property def zipinfo(self): @@ -2729,7 +2729,7 @@ def __init__( self.dist = dist def __str__(self) -> str: - s = "{} = {}".format(self.name, self.module_name) + s = f"{self.name} = {self.module_name}" if self.attrs: s += ':' + '.'.join(self.attrs) if self.extras: @@ -2737,7 +2737,7 @@ def __str__(self) -> str: return s def __repr__(self) -> str: - return "EntryPoint.parse({!r})".format(str(self)) + return f"EntryPoint.parse({str(self)!r})" @overload def load( @@ -3049,9 +3049,7 @@ def version(self): version = self._get_version() if version is None: path = self._get_metadata_path_for_display(self.PKG_INFO) - msg = ("Missing 'Version:' header and/or {} file at path: {}").format( - self.PKG_INFO, path - ) + msg = (f"Missing 'Version:' header and/or {self.PKG_INFO} file at path: {path}") raise ValueError(msg, self) from e return version @@ -3108,7 +3106,7 @@ def requires(self, extras: Iterable[str] = ()) -> list[Requirement]: deps.extend(dm[safe_extra(ext)]) except KeyError as e: raise UnknownExtra( - "{} has no such extra feature {!r}".format(self, ext) + f"{self} has no such extra feature {ext!r}" ) from e return deps @@ -3150,11 +3148,7 @@ def activate(self, path: list[str] | None = None, replace: bool = False) -> None def egg_name(self): """Return what this distribution's standard .egg filename should be""" - filename = "{}-{}-py{}".format( - to_filename(self.project_name), - to_filename(self.version), - self.py_version or PY_MAJOR, - ) + filename = f"{to_filename(self.project_name)}-{to_filename(self.version)}-py{self.py_version or PY_MAJOR}" if self.platform: filename += '-' + self.platform @@ -3162,7 +3156,7 @@ def egg_name(self): def __repr__(self) -> str: if self.location: - return "{} ({})".format(self, self.location) + return f"{self} ({self.location})" else: return str(self) @@ -3172,7 +3166,7 @@ def __str__(self) -> str: except ValueError: version = None version = version or "[unknown version]" - return "{} {}".format(self.project_name, version) + return f"{self.project_name} {version}" def __getattr__(self, attr: str): """Delegate all unrecognized public attributes to .metadata provider""" @@ -3200,9 +3194,9 @@ def from_filename( def as_requirement(self): """Return a ``Requirement`` that matches this distribution exactly""" if isinstance(self.parsed_version, packaging.version.Version): - spec = "{}=={}".format(self.project_name, self.parsed_version) + spec = f"{self.project_name}=={self.parsed_version}" else: - spec = "{}==={}".format(self.project_name, self.parsed_version) + spec = f"{self.project_name}==={self.parsed_version}" return Requirement.parse(spec) @@ -3210,7 +3204,7 @@ def load_entry_point(self, group: str, name: str) -> _ResolvedEntryPoint: """Return the `name` entry point of `group` or raise ImportError""" ep = self.get_entry_info(group, name) if ep is None: - raise ImportError("Entry point {!r} not found".format((group, name))) + raise ImportError(f"Entry point {(group, name)!r} not found") return ep.load() @overload @@ -3327,8 +3321,8 @@ def check_version_conflict(self): ): continue issue_warning( - "Module {} was already imported from {}, but {} is being added" - " to sys.path".format(modname, fn, self.location), + f"Module {modname} was already imported from {fn}, but {self.location} is being added" + " to sys.path", ) def has_version(self) -> bool: @@ -3512,7 +3506,7 @@ def __hash__(self) -> int: return self.__hash def __repr__(self) -> str: - return "Requirement.parse({!r})".format(str(self)) + return f"Requirement.parse({str(self)!r})" @staticmethod def parse(s: str | Iterable[str]) -> Requirement: diff --git a/pkg_resources/tests/test_pkg_resources.py b/pkg_resources/tests/test_pkg_resources.py index 2e5526d1aa..27ddaab42f 100644 --- a/pkg_resources/tests/test_pkg_resources.py +++ b/pkg_resources/tests/test_pkg_resources.py @@ -214,8 +214,8 @@ def test_get_metadata__bad_utf8(tmpdir): "codec can't decode byte 0xe9 in position 1: " 'invalid continuation byte in METADATA file at path: ' ) - assert expected in actual, 'actual: {}'.format(actual) - assert actual.endswith(metadata_path), 'actual: {}'.format(actual) + assert expected in actual, f'actual: {actual}' + assert actual.endswith(metadata_path), f'actual: {actual}' def make_distribution_no_version(tmpdir, basename): @@ -252,12 +252,10 @@ def test_distribution_version_missing( """ Test Distribution.version when the "Version" header is missing. """ - basename = 'foo.{}'.format(suffix) + basename = f'foo.{suffix}' dist, dist_dir = make_distribution_no_version(tmpdir, basename) - expected_text = ("Missing 'Version:' header and/or {} file at path: ").format( - expected_filename - ) + expected_text = (f"Missing 'Version:' header and/or {expected_filename} file at path: ") metadata_path = os.path.join(dist_dir, expected_filename) # Now check the exception raised when the "version" attribute is accessed. diff --git a/ruff.toml b/ruff.toml index e7005e27d9..b9c4a8f569 100644 --- a/ruff.toml +++ b/ruff.toml @@ -35,7 +35,6 @@ ignore = [ "TRY003", # raise-vanilla-args, avoid multitude of exception classes "TRY301", # raise-within-try, it's handy "UP015", # redundant-open-modes, explicit is preferred - "UP032", # temporarily disabled "UP038", # Using `X | Y` in `isinstance` call is slower and more verbose https://github.com/astral-sh/ruff/issues/7871 # Only enforcing return type annotations for public functions "ANN202", # missing-return-type-private-function diff --git a/setuptools/__init__.py b/setuptools/__init__.py index ab3be9581c..8b83a5271d 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -182,7 +182,7 @@ def _ensure_stringlike(self, option, what, default=None): return default elif not isinstance(val, str): raise DistutilsOptionError( - "'{}' must be a {} (got `{}`)".format(option, what, val) + f"'{option}' must be a {what} (got `{val}`)" ) return val @@ -210,7 +210,7 @@ def ensure_string_list(self, option: str) -> None: ok = False if not ok: raise DistutilsOptionError( - "'{}' must be a list of strings (got {!r})".format(option, val) + f"'{option}' must be a list of strings (got {val!r})" ) @overload diff --git a/setuptools/_core_metadata.py b/setuptools/_core_metadata.py index 72b745dc93..a5e18a4006 100644 --- a/setuptools/_core_metadata.py +++ b/setuptools/_core_metadata.py @@ -150,7 +150,7 @@ def write_pkg_file(self, file): # noqa: C901 # is too complex (14) # FIXME version = self.get_metadata_version() def write_field(key, value): - file.write("{}: {}\n".format(key, value)) + file.write(f"{key}: {value}\n") write_field('Metadata-Version', str(version)) write_field('Name', self.get_name()) @@ -209,7 +209,7 @@ def write_field(key, value): long_description = self.get_long_description() if long_description: - file.write("\n{}".format(long_description)) + file.write(f"\n{long_description}") if not long_description.endswith("\n"): file.write("\n") diff --git a/setuptools/_imp.py b/setuptools/_imp.py index f0fba01e50..f1d9f29218 100644 --- a/setuptools/_imp.py +++ b/setuptools/_imp.py @@ -29,7 +29,7 @@ def find_module(module, paths=None): """Just like 'imp.find_module()', but with package support""" spec = find_spec(module, paths) if spec is None: - raise ImportError("Can't find {}".format(module)) + raise ImportError(f"Can't find {module}") if not spec.has_location and hasattr(spec, 'submodule_search_locations'): spec = importlib.util.spec_from_loader('__init__.py', spec.loader) @@ -76,12 +76,12 @@ def find_module(module, paths=None): def get_frozen_object(module, paths=None): spec = find_spec(module, paths) if not spec: - raise ImportError("Can't find {}".format(module)) + raise ImportError(f"Can't find {module}") return spec.loader.get_code(module) def get_module(module, paths, info): spec = find_spec(module, paths) if not spec: - raise ImportError("Can't find {}".format(module)) + raise ImportError(f"Can't find {module}") return module_from_spec(spec) diff --git a/setuptools/archive_util.py b/setuptools/archive_util.py index 7ef5294b55..1a02010bb2 100644 --- a/setuptools/archive_util.py +++ b/setuptools/archive_util.py @@ -62,7 +62,7 @@ def unpack_archive( else: return else: - raise UnrecognizedFormat("Not a recognized archive type: {}".format(filename)) + raise UnrecognizedFormat(f"Not a recognized archive type: {filename}") def unpack_directory(filename, extract_dir, progress_filter=default_filter) -> None: @@ -71,7 +71,7 @@ def unpack_directory(filename, extract_dir, progress_filter=default_filter) -> N Raises ``UnrecognizedFormat`` if `filename` is not a directory """ if not os.path.isdir(filename): - raise UnrecognizedFormat("{} is not a directory".format(filename)) + raise UnrecognizedFormat(f"{filename} is not a directory") paths = { filename: ('', extract_dir), @@ -101,7 +101,7 @@ def unpack_zipfile(filename, extract_dir, progress_filter=default_filter) -> Non """ if not zipfile.is_zipfile(filename): - raise UnrecognizedFormat("{} is not a zip file".format(filename)) + raise UnrecognizedFormat(f"{filename} is not a zip file") with zipfile.ZipFile(filename) as z: _unpack_zipfile_obj(z, extract_dir, progress_filter) @@ -198,7 +198,7 @@ def unpack_tarfile(filename, extract_dir, progress_filter=default_filter) -> boo tarobj = tarfile.open(filename) except tarfile.TarError as e: raise UnrecognizedFormat( - "{} is not a compressed or uncompressed tar file".format(filename) + f"{filename} is not a compressed or uncompressed tar file" ) from e for member, final_dst in _iter_open_tar( diff --git a/setuptools/command/alias.py b/setuptools/command/alias.py index 9903a23503..b8d74af71d 100644 --- a/setuptools/command/alias.py +++ b/setuptools/command/alias.py @@ -55,7 +55,7 @@ def run(self) -> None: print("setup.py alias", format_alias(alias, aliases)) return else: - print("No alias definition found for {!r}".format(alias)) + print(f"No alias definition found for {alias!r}") return else: alias = self.args[0] @@ -73,5 +73,5 @@ def format_alias(name, aliases): elif source == config_file('local'): source = '' else: - source = '--filename={!r}'.format(source) + source = f'--filename={source!r}' return source + name + ' ' + command diff --git a/setuptools/command/bdist_egg.py b/setuptools/command/bdist_egg.py index 44ccdfd240..21e3e8f14d 100644 --- a/setuptools/command/bdist_egg.py +++ b/setuptools/command/bdist_egg.py @@ -264,7 +264,7 @@ def zap_pyfiles(self): m = re.match(pattern, name) path_new = os.path.join(base, os.pardir, m.group('name') + '.pyc') log.info( - "Renaming file from [{}] to [{}]".format(path_old, path_new) + f"Renaming file from [{path_old}] to [{path_new}]" ) try: os.remove(path_new) diff --git a/setuptools/command/build_clib.py b/setuptools/command/build_clib.py index f2705cecdc..f376f4ce4d 100644 --- a/setuptools/command/build_clib.py +++ b/setuptools/command/build_clib.py @@ -29,9 +29,9 @@ def build_libraries(self, libraries) -> None: sources = build_info.get('sources') if sources is None or not isinstance(sources, (list, tuple)): raise DistutilsSetupError( - "in 'libraries' option (library '{}'), " + f"in 'libraries' option (library '{lib_name}'), " "'sources' must be present and must be " - "a list of source filenames".format(lib_name) + "a list of source filenames" ) sources = sorted(list(sources)) @@ -43,9 +43,9 @@ def build_libraries(self, libraries) -> None: obj_deps = build_info.get('obj_deps', dict()) if not isinstance(obj_deps, dict): raise DistutilsSetupError( - "in 'libraries' option (library '{}'), " + f"in 'libraries' option (library '{lib_name}'), " "'obj_deps' must be a dictionary of " - "type 'source: list'".format(lib_name) + "type 'source: list'" ) dependencies = [] @@ -54,9 +54,9 @@ def build_libraries(self, libraries) -> None: global_deps = obj_deps.get('', list()) if not isinstance(global_deps, (list, tuple)): raise DistutilsSetupError( - "in 'libraries' option (library '{}'), " + f"in 'libraries' option (library '{lib_name}'), " "'obj_deps' must be a dictionary of " - "type 'source: list'".format(lib_name) + "type 'source: list'" ) # Build the list to be used by newer_pairwise_group @@ -67,9 +67,9 @@ def build_libraries(self, libraries) -> None: extra_deps = obj_deps.get(source, list()) if not isinstance(extra_deps, (list, tuple)): raise DistutilsSetupError( - "in 'libraries' option (library '{}'), " + f"in 'libraries' option (library '{lib_name}'), " "'obj_deps' must be a dictionary of " - "type 'source: list'".format(lib_name) + "type 'source: list'" ) src_deps.extend(extra_deps) dependencies.append(src_deps) diff --git a/setuptools/command/build_ext.py b/setuptools/command/build_ext.py index b8a395bafa..6e56ae4ca2 100644 --- a/setuptools/command/build_ext.py +++ b/setuptools/command/build_ext.py @@ -360,7 +360,7 @@ def _write_stub_file(self, stub_file: str, ext: Extension, compile=False): " global __bootstrap__, __file__, __loader__", " import sys, os, pkg_resources, importlib.util" + if_dl(", dl"), " __file__ = pkg_resources.resource_filename" - "(__name__,{!r})".format(os.path.basename(ext._file_name)), + f"(__name__,{os.path.basename(ext._file_name)!r})", " del __bootstrap__", " if '__loader__' in globals():", " del __loader__", diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index f17cd66fe9..2f6fcb7cdc 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -259,10 +259,10 @@ def check_package(self, package, package_dir): contents = f.read() if b'declare_namespace' not in contents: raise distutils.errors.DistutilsError( - "Namespace package problem: {} is a namespace package, but " + f"Namespace package problem: {package} is a namespace package, but " "its\n__init__.py does not call declare_namespace()! Please " 'fix it.\n(See the setuptools manual under ' - '"Namespace Packages" for details.)\n"'.format(package) + '"Namespace Packages" for details.)\n"' ) return init_py diff --git a/setuptools/command/dist_info.py b/setuptools/command/dist_info.py index 0192ebb260..dca01ff0ce 100644 --- a/setuptools/command/dist_info.py +++ b/setuptools/command/dist_info.py @@ -95,7 +95,7 @@ def run(self) -> None: egg_info_dir = self.egg_info.egg_info assert os.path.isdir(egg_info_dir), ".egg-info dir should have been created" - log.info("creating '{}'".format(os.path.abspath(self.dist_info_dir))) + log.info(f"creating '{os.path.abspath(self.dist_info_dir)}'") bdist_wheel = self.get_finalized_command('bdist_wheel') # TODO: if bdist_wheel if merged into setuptools, just add "keep_egg_info" there diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 53f96aef2b..379beede14 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -148,7 +148,7 @@ class easy_install(Command): None, "Don't load find-links defined in packages being installed", ), - ('user', None, "install in user site-package '{}'".format(site.USER_SITE)), + ('user', None, f"install in user site-package '{site.USER_SITE}'"), ] boolean_options = [ 'zip-ok', @@ -446,7 +446,7 @@ def run(self, show_deprecation: bool = True) -> None: self.execute( file_util.write_file, (self.record, outputs), - "writing list of installed files to '{}'".format(self.record), + f"writing list of installed files to '{self.record}'", ) self.warn_deprecated_options() finally: @@ -461,7 +461,7 @@ def pseudo_tempname(self): pid = os.getpid() except Exception: pid = random.randint(0, sys.maxsize) - return os.path.join(self.install_dir, "test-easy-install-{}".format(pid)) + return os.path.join(self.install_dir, f"test-easy-install-{pid}") def warn_deprecated_options(self) -> None: pass @@ -649,8 +649,8 @@ def add_output(self, path) -> None: def not_editable(self, spec) -> None: if self.editable: raise DistutilsArgError( - "Invalid argument {!r}: you can't use filenames or URLs " - "with --editable (except via the --find-links option).".format(spec) + f"Invalid argument {spec!r}: you can't use filenames or URLs " + "with --editable (except via the --find-links option)." ) def check_editable(self, spec) -> None: @@ -659,9 +659,7 @@ def check_editable(self, spec) -> None: if os.path.exists(os.path.join(self.build_directory, spec.key)): raise DistutilsArgError( - "{!r} already exists in {}; can't do a checkout there".format( - spec.key, self.build_directory - ) + f"{spec.key!r} already exists in {self.build_directory}; can't do a checkout there" ) @contextlib.contextmanager @@ -699,7 +697,7 @@ def easy_install(self, spec, deps: bool = False) -> Distribution | None: self.local_index, ) if dist is None: - msg = "Could not find suitable distribution for {!r}".format(spec) + msg = f"Could not find suitable distribution for {spec!r}" if self.always_copy: msg += " (--always-copy skips system and development eggs)" raise DistutilsError(msg) @@ -918,15 +916,11 @@ def install_eggs(self, spec, dist_filename, tmpdir) -> list[Distribution]: setups = glob(os.path.join(setup_base, '*', 'setup.py')) if not setups: raise DistutilsError( - "Couldn't find a setup script in {}".format( - os.path.abspath(dist_filename) - ) + f"Couldn't find a setup script in {os.path.abspath(dist_filename)}" ) if len(setups) > 1: raise DistutilsError( - "Multiple setup scripts in {}".format( - os.path.abspath(dist_filename) - ) + f"Multiple setup scripts in {os.path.abspath(dist_filename)}" ) setup_script = setups[0] @@ -1004,7 +998,7 @@ def install_exe(self, dist_filename, tmpdir): cfg = extract_wininst_cfg(dist_filename) if cfg is None: raise DistutilsError( - "{} is not a valid distutils Windows .exe".format(dist_filename) + f"{dist_filename} is not a valid distutils Windows .exe" ) # Create a dummy distribution object until we build the real distro dist = Distribution( @@ -1118,9 +1112,7 @@ def install_wheel(self, wheel_path, tmpdir): self.execute( wheel.install_as_egg, (destination,), - ("Installing {} to {}").format( - os.path.basename(wheel_path), os.path.dirname(destination) - ), + (f"Installing {os.path.basename(wheel_path)} to {os.path.dirname(destination)}"), ) finally: update_dist_caches(destination, fix_zipimporter_caches=False) @@ -1196,7 +1188,7 @@ def run_setup(self, setup_script, setup_base, args) -> None: try: run_setup(setup_script, args) except SystemExit as v: - raise DistutilsError("Setup script exited with {}".format(v.args[0])) from v + raise DistutilsError(f"Setup script exited with {v.args[0]}") from v def build_and_install(self, setup_script, setup_base): args = ['bdist_egg', '--dist-dir'] @@ -1379,7 +1371,7 @@ def create_home_path(self) -> None: home = convert_path(os.path.expanduser("~")) for path in only_strs(self.config_vars.values()): if path.startswith(home) and not os.path.isdir(path): - self.debug_print("os.makedirs('{}', 0o700)".format(path)) + self.debug_print(f"os.makedirs('{path}', 0o700)") os.makedirs(path, 0o700) INSTALL_SCHEMES = dict( @@ -1604,7 +1596,7 @@ def get_exe_prefixes(exe_filename): for pth in yield_lines(contents): pth = pth.strip().replace('\\', '/') if not pth.startswith('import'): - prefixes.append((('{}/{}/'.format(parts[0], pth)), '')) + prefixes.append(((f'{parts[0]}/{pth}/'), '')) finally: z.close() prefixes = [(x.lower(), y) for x, y in prefixes] @@ -2310,7 +2302,7 @@ def get_win_launcher(type): Returns the executable as a byte string. """ - launcher_fn = '{}.exe'.format(type) + launcher_fn = f'{type}.exe' if is_64bit(): if get_platform() == "win-arm64": launcher_fn = launcher_fn.replace(".", "-arm64.") diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 335eeb4efd..f77631168f 100644 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -48,7 +48,7 @@ def translate_pattern(glob): # noqa: C901 # is too complex (14) # FIXME chunks = glob.split(os.path.sep) sep = re.escape(os.sep) - valid_char = '[^{}]'.format(sep) + valid_char = f'[^{sep}]' for c, chunk in enumerate(chunks): last_chunk = c == len(chunks) - 1 @@ -60,7 +60,7 @@ def translate_pattern(glob): # noqa: C901 # is too complex (14) # FIXME pat += '.*' else: # Match '(name/)*' - pat += '(?:{}+{})*'.format(valid_char, sep) + pat += f'(?:{valid_char}+{sep})*' continue # Break here as the whole path component has been handled # Find any special characters in the remainder @@ -102,7 +102,7 @@ def translate_pattern(glob): # noqa: C901 # is too complex (14) # FIXME inner = inner[1:] char_class += re.escape(inner) - pat += '[{}]'.format(char_class) + pat += f'[{char_class}]' # Skip to the end ] i = inner_i @@ -231,9 +231,7 @@ def finalize_options(self) -> None: packaging.requirements.Requirement(spec % (self.egg_name, self.egg_version)) except ValueError as e: raise distutils.errors.DistutilsOptionError( - "Invalid distribution name or version syntax: {}-{}".format( - self.egg_name, self.egg_version - ) + f"Invalid distribution name or version syntax: {self.egg_name}-{self.egg_version}" ) from e if self.egg_base is None: @@ -503,7 +501,7 @@ def _safe_path(self, path): # To avoid accidental trans-codings errors, first to unicode u_path = unicode_utils.filesys_decode(path) if u_path is None: - log.warn("'{}' in unexpected encoding -- skipping".format(path)) + log.warn(f"'{path}' in unexpected encoding -- skipping") return False # Must ensure utf-8 encodability @@ -565,7 +563,7 @@ def write_manifest(self) -> None: # Now _repairs should encodability, but not unicode files = [self._manifest_normalize(f) for f in self.filelist.files] - msg = "writing manifest file '{}'".format(self.manifest) + msg = f"writing manifest file '{self.manifest}'" self.execute(write_file, (self.manifest, files), msg) def warn(self, msg) -> None: diff --git a/setuptools/command/install_egg_info.py b/setuptools/command/install_egg_info.py index 42cfe4e64d..cbf125c764 100644 --- a/setuptools/command/install_egg_info.py +++ b/setuptools/command/install_egg_info.py @@ -37,7 +37,7 @@ def run(self) -> None: if not self.dry_run: ensure_directory(self.target) self.execute( - self.copytree, (), "Copying {} to {}".format(self.source, self.target) + self.copytree, (), f"Copying {self.source} to {self.target}" ) self.install_namespaces() diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py index 03a70ce9c9..9631cf3114 100644 --- a/setuptools/command/sdist.py +++ b/setuptools/command/sdist.py @@ -53,7 +53,7 @@ class sdist(orig.sdist): negative_opt: ClassVar[dict[str, str]] = {} README_EXTENSIONS = ['', '.rst', '.txt', '.md'] - READMES = tuple('README{}'.format(ext) for ext in README_EXTENSIONS) + READMES = tuple(f'README{ext}' for ext in README_EXTENSIONS) def run(self) -> None: self.run_command('egg_info') @@ -207,7 +207,7 @@ def read_manifest(self): try: line = bytes_line.decode('UTF-8') except UnicodeDecodeError: - log.warn("{!r} not UTF-8 decodable -- skipping".format(line)) + log.warn(f"{line!r} not UTF-8 decodable -- skipping") continue # ignore comments and blank lines line = line.strip() diff --git a/setuptools/command/setopt.py b/setuptools/command/setopt.py index ee220f9454..678a0593d6 100644 --- a/setuptools/command/setopt.py +++ b/setuptools/command/setopt.py @@ -23,7 +23,7 @@ def config_file(kind="local"): return os.path.join(os.path.dirname(distutils.__file__), 'distutils.cfg') if kind == 'user': dot = os.name == 'posix' and '.' or '' - return os.path.expanduser(convert_path("~/{}pydistutils.cfg".format(dot))) + return os.path.expanduser(convert_path(f"~/{dot}pydistutils.cfg")) raise ValueError("config_file() type must be 'local', 'global', or 'user'", kind) diff --git a/setuptools/config/expand.py b/setuptools/config/expand.py index 8469e979a1..ccb5d63cd2 100644 --- a/setuptools/config/expand.py +++ b/setuptools/config/expand.py @@ -329,7 +329,7 @@ def version(value: Callable | Iterable[str | int] | str) -> str: return _value if hasattr(_value, '__iter__'): return '.'.join(map(str, _value)) - return '{}'.format(_value) + return f'{_value}' def canonic_package_data(package_data: dict) -> dict: diff --git a/setuptools/config/setupcfg.py b/setuptools/config/setupcfg.py index 0f9167be77..f2eb833b22 100644 --- a/setuptools/config/setupcfg.py +++ b/setuptools/config/setupcfg.py @@ -272,7 +272,7 @@ def _section_options( def parsers(self): """Metadata item name to parser function mapping.""" raise NotImplementedError( - '{} must provide .parsers property'.format(self.__class__.__name__) + f'{self.__class__.__name__} must provide .parsers property' ) def __setitem__(self, option_name, value) -> None: @@ -483,24 +483,12 @@ def parse(self) -> None: for section_name, section_options in self.sections.items(): method_postfix = '' if section_name: # [section.option] variant -<<<<<<< HEAD method_postfix = f"_{section_name}" -||||||| parent of e98b9ffc4 (Enforce ruff/pyupgrade rule UP031) - method_postfix = '_%s' % section_name -======= - method_postfix = '_{}'.format(section_name) ->>>>>>> e98b9ffc4 (Enforce ruff/pyupgrade rule UP031) section_parser_method: Callable | None = getattr( self, # Dots in section names are translated into dunderscores. -<<<<<<< HEAD f'parse_section{method_postfix}'.replace('.', '__'), -||||||| parent of e98b9ffc4 (Enforce ruff/pyupgrade rule UP031) - ('parse_section%s' % method_postfix).replace('.', '__'), -======= - ('parse_section{}'.format(method_postfix)).replace('.', '__'), ->>>>>>> e98b9ffc4 (Enforce ruff/pyupgrade rule UP031) None, ) diff --git a/setuptools/depends.py b/setuptools/depends.py index 09eff3855f..e5223b7956 100644 --- a/setuptools/depends.py +++ b/setuptools/depends.py @@ -43,7 +43,7 @@ def __init__( def full_name(self): """Return full package/distribution name, w/version""" if self.requested_version is not None: - return '{}-{}'.format(self.name, self.requested_version) + return f'{self.name}-{self.requested_version}' return self.name def version_ok(self, version): diff --git a/setuptools/dist.py b/setuptools/dist.py index 13a0b43448..639a435ad4 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -85,9 +85,7 @@ def check_importable(dist, attr, value): assert not ep.extras except (TypeError, ValueError, AttributeError, AssertionError) as e: raise DistutilsSetupError( - "{!r} must be importable 'module:attrs' string (got {!r})".format( - attr, value - ) + f"{attr!r} must be importable 'module:attrs' string (got {value!r})" ) from e @@ -113,7 +111,7 @@ def check_nsp(dist, attr, value): if not dist.has_contents_for(nsp): raise DistutilsSetupError( "Distribution contains no modules or packages for " - + "namespace package {!r}".format(nsp) + + f"namespace package {nsp!r}" ) parent, _sep, _child = nsp.rpartition('.') if parent and parent not in ns_packages: @@ -212,15 +210,15 @@ def check_package_data(dist, attr, value): """Verify that value is a dictionary of package names to glob lists""" if not isinstance(value, dict): raise DistutilsSetupError( - "{!r} must be a dictionary mapping package names to lists of " - "string wildcard patterns".format(attr) + f"{attr!r} must be a dictionary mapping package names to lists of " + "string wildcard patterns" ) for k, v in value.items(): if not isinstance(k, str): raise DistutilsSetupError( - "keys of {!r} dict must be strings (got {!r})".format(attr, k) + f"keys of {attr!r} dict must be strings (got {k!r})" ) - assert_string_list(dist, 'values of {!r} dict'.format(attr), v) + assert_string_list(dist, f'values of {attr!r} dict', v) def check_packages(dist, attr, value): @@ -590,10 +588,10 @@ def _set_command_options(self, command_obj, option_dict=None): # noqa: C901 option_dict = self.get_option_dict(command_name) if DEBUG: - self.announce(" setting options for '{}' command:".format(command_name)) + self.announce(f" setting options for '{command_name}' command:") for option, (source, value) in option_dict.items(): if DEBUG: - self.announce(" {} = {} (from {})".format(option, value, source)) + self.announce(f" {option} = {value} (from {source})") try: bool_opts = [translate_longopt(o) for o in command_obj.boolean_options] except AttributeError: @@ -613,9 +611,7 @@ def _set_command_options(self, command_obj, option_dict=None): # noqa: C901 setattr(command_obj, option, value) else: raise DistutilsOptionError( - "error in {}: command '{}' has no such option '{}'".format( - source, command_name, option - ) + f"error in {source}: command '{command_name}' has no such option '{option}'" ) except ValueError as e: raise DistutilsOptionError(e) from e @@ -840,7 +836,7 @@ def _include_misc(self, name: str, value: _Sequence) -> None: old = getattr(self, name) except AttributeError as e: raise DistutilsSetupError( - "{}: No such distribution setting".format(name) + f"{name}: No such distribution setting" ) from e if old is None: setattr(self, name, value) diff --git a/setuptools/monkey.py b/setuptools/monkey.py index ec5d8cdae1..6ad1abac29 100644 --- a/setuptools/monkey.py +++ b/setuptools/monkey.py @@ -64,7 +64,7 @@ def get_unpatched_class(cls: type[_T]) -> type[_T]: ) base = next(external_bases) if not base.__module__.startswith('distutils'): - msg = "distutils has already been patched by {!r}".format(cls) + msg = f"distutils has already been patched by {cls!r}" raise AssertionError(msg) return base diff --git a/setuptools/msvc.py b/setuptools/msvc.py index 727897d1d3..4ed97c75a1 100644 --- a/setuptools/msvc.py +++ b/setuptools/msvc.py @@ -108,7 +108,7 @@ def current_dir(self, hidex86=False, x64=False) -> str: if (self.current_cpu == 'x86' and hidex86) else r'\x64' if (self.current_cpu == 'amd64' and x64) - else r'\{}'.format(self.current_cpu) + else rf'\{self.current_cpu}' ) def target_dir(self, hidex86=False, x64=False) -> str: @@ -132,7 +132,7 @@ def target_dir(self, hidex86=False, x64=False) -> str: if (self.target_cpu == 'x86' and hidex86) else r'\x64' if (self.target_cpu == 'amd64' and x64) - else r'\{}'.format(self.target_cpu) + else rf'\{self.target_cpu}' ) def cross_dir(self, forcex86=False): @@ -155,7 +155,7 @@ def cross_dir(self, forcex86=False): return ( '' if self.target_cpu == current - else self.target_dir().replace('\\', '\\{}_'.format(current)) + else self.target_dir().replace('\\', f'\\{current}_') ) @@ -497,11 +497,11 @@ def VSInstallDir(self): """ # Default path default = os.path.join( - self.ProgramFilesx86, 'Microsoft Visual Studio {:0.1f}'.format(self.vs_ver) + self.ProgramFilesx86, f'Microsoft Visual Studio {self.vs_ver:0.1f}' ) # Try to get path from registry, if fail use default path - return self.ri.lookup(self.ri.vs, '{:0.1f}'.format(self.vs_ver)) or default + return self.ri.lookup(self.ri.vs, f'{self.vs_ver:0.1f}') or default @property def VCInstallDir(self): @@ -562,16 +562,16 @@ def _guess_vc_legacy(self): """ default = os.path.join( self.ProgramFilesx86, - r'Microsoft Visual Studio {:0.1f}\VC'.format(self.vs_ver), + rf'Microsoft Visual Studio {self.vs_ver:0.1f}\VC', ) # Try to get "VC++ for Python" path from registry as default path - reg_path = os.path.join(self.ri.vc_for_python, '{:0.1f}'.format(self.vs_ver)) + reg_path = os.path.join(self.ri.vc_for_python, f'{self.vs_ver:0.1f}') python_vc = self.ri.lookup(reg_path, 'installdir') default_vc = os.path.join(python_vc, 'VC') if python_vc else default # Try to get path from registry, if fail use default path - return self.ri.lookup(self.ri.vc, '{:0.1f}'.format(self.vs_ver)) or default_vc + return self.ri.lookup(self.ri.vc, f'{self.vs_ver:0.1f}') or default_vc @property def WindowsSdkVersion(self) -> tuple[LiteralString, ...]: @@ -620,13 +620,13 @@ def WindowsSdkDir(self) -> str | None: # noqa: C901 # is too complex (12) # F sdkdir: str | None = '' for ver in self.WindowsSdkVersion: # Try to get it from registry - loc = os.path.join(self.ri.windows_sdk, 'v{}'.format(ver)) + loc = os.path.join(self.ri.windows_sdk, f'v{ver}') sdkdir = self.ri.lookup(loc, 'installationfolder') if sdkdir: break if not sdkdir or not os.path.isdir(sdkdir): # Try to get "VC++ for Python" version from registry - path = os.path.join(self.ri.vc_for_python, '{:0.1f}'.format(self.vc_ver)) + path = os.path.join(self.ri.vc_for_python, f'{self.vc_ver:0.1f}') install_base = self.ri.lookup(path, 'installdir') if install_base: sdkdir = os.path.join(install_base, 'WinSDK') @@ -634,14 +634,14 @@ def WindowsSdkDir(self) -> str | None: # noqa: C901 # is too complex (12) # F # If fail, use default new path for ver in self.WindowsSdkVersion: intver = ver[: ver.rfind('.')] - path = r'Microsoft SDKs\Windows Kits\{}'.format(intver) + path = rf'Microsoft SDKs\Windows Kits\{intver}' d = os.path.join(self.ProgramFiles, path) if os.path.isdir(d): sdkdir = d if not sdkdir or not os.path.isdir(sdkdir): # If fail, use default old path for ver in self.WindowsSdkVersion: - path = r'Microsoft SDKs\Windows\v{}'.format(ver) + path = rf'Microsoft SDKs\Windows\v{ver}' d = os.path.join(self.ProgramFiles, path) if os.path.isdir(d): sdkdir = d @@ -677,7 +677,7 @@ def WindowsSDKExecutablePath(self): regpaths += [os.path.join(self.ri.netfx_sdk, ver, fx)] for ver in self.WindowsSdkVersion: - regpaths += [os.path.join(self.ri.windows_sdk, 'v{}A'.format(ver), fx)] + regpaths += [os.path.join(self.ri.windows_sdk, f'v{ver}A', fx)] # Return installation folder from the more recent path for path in regpaths: @@ -698,7 +698,7 @@ def FSharpInstallDir(self): path """ path = os.path.join( - self.ri.visualstudio, r'{:0.1f}\Setup\F#'.format(self.vs_ver) + self.ri.visualstudio, rf'{self.vs_ver:0.1f}\Setup\F#' ) return self.ri.lookup(path, 'productdir') or '' @@ -718,7 +718,7 @@ def UniversalCRTSdkDir(self): # Find path of the more recent Kit for ver in vers: sdkdir = self.ri.lookup( - self.ri.windows_kits_roots, 'kitsroot{}'.format(ver) + self.ri.windows_kits_roots, f'kitsroot{ver}' ) if sdkdir: return sdkdir or '' @@ -965,7 +965,7 @@ def VSTools(self): arch_subdir = self.pi.current_dir(hidex86=True, x64=True) paths += [r'Common7\IDE\CommonExtensions\Microsoft\TestWindow'] paths += [r'Team Tools\Performance Tools'] - paths += [r'Team Tools\Performance Tools{}'.format(arch_subdir)] + paths += [rf'Team Tools\Performance Tools{arch_subdir}'] return [os.path.join(self.si.VSInstallDir, path) for path in paths] @@ -998,10 +998,10 @@ def VCLibraries(self): arch_subdir = self.pi.target_dir(x64=True) else: arch_subdir = self.pi.target_dir(hidex86=True) - paths = ['Lib{}'.format(arch_subdir), r'ATLMFC\Lib{}'.format(arch_subdir)] + paths = [f'Lib{arch_subdir}', rf'ATLMFC\Lib{arch_subdir}'] if self.vs_ver >= 14.0: - paths += [r'Lib\store{}'.format(arch_subdir)] + paths += [rf'Lib\store{arch_subdir}'] return [os.path.join(self.si.VCInstallDir, path) for path in paths] @@ -1035,10 +1035,10 @@ def VCTools(self): forcex86 = True if self.vs_ver <= 10.0 else False arch_subdir = self.pi.cross_dir(forcex86) if arch_subdir: - tools += [os.path.join(si.VCInstallDir, 'Bin{}'.format(arch_subdir))] + tools += [os.path.join(si.VCInstallDir, f'Bin{arch_subdir}')] if self.vs_ver == 14.0: - path = 'Bin{}'.format(self.pi.current_dir(hidex86=True)) + path = f'Bin{self.pi.current_dir(hidex86=True)}' tools += [os.path.join(si.VCInstallDir, path)] elif self.vs_ver >= 15.0: @@ -1073,13 +1073,13 @@ def OSLibraries(self): """ if self.vs_ver <= 10.0: arch_subdir = self.pi.target_dir(hidex86=True, x64=True) - return [os.path.join(self.si.WindowsSdkDir, 'Lib{}'.format(arch_subdir))] + return [os.path.join(self.si.WindowsSdkDir, f'Lib{arch_subdir}')] else: arch_subdir = self.pi.target_dir(x64=True) lib = os.path.join(self.si.WindowsSdkDir, 'lib') libver = self._sdk_subdir - return [os.path.join(lib, '{}um{}'.format(libver, arch_subdir))] + return [os.path.join(lib, f'{libver}um{arch_subdir}')] @property def OSIncludes(self): @@ -1102,9 +1102,9 @@ def OSIncludes(self): else: sdkver = '' return [ - os.path.join(include, '{}shared'.format(sdkver)), - os.path.join(include, '{}um'.format(sdkver)), - os.path.join(include, '{}winrt'.format(sdkver)), + os.path.join(include, f'{sdkver}shared'), + os.path.join(include, f'{sdkver}um'), + os.path.join(include, f'{sdkver}winrt'), ] @property @@ -1139,7 +1139,7 @@ def OSLibpath(self): self.si.WindowsSdkDir, 'ExtensionSDKs', 'Microsoft.VCLibs', - '{:0.1f}'.format(self.vs_ver), + f'{self.vs_ver:0.1f}', 'References', 'CommonConfiguration', 'neutral', @@ -1174,7 +1174,7 @@ def _sdk_tools(self): if not self.pi.current_is_x86(): arch_subdir = self.pi.current_dir(x64=True) - path = 'Bin{}'.format(arch_subdir) + path = f'Bin{arch_subdir}' yield os.path.join(self.si.WindowsSdkDir, path) if self.vs_ver in (10.0, 11.0): @@ -1182,14 +1182,14 @@ def _sdk_tools(self): arch_subdir = '' else: arch_subdir = self.pi.current_dir(hidex86=True, x64=True) - path = r'Bin\NETFX 4.0 Tools{}'.format(arch_subdir) + path = rf'Bin\NETFX 4.0 Tools{arch_subdir}' yield os.path.join(self.si.WindowsSdkDir, path) elif self.vs_ver >= 15.0: path = os.path.join(self.si.WindowsSdkDir, 'Bin') arch_subdir = self.pi.current_dir(x64=True) sdkver = self.si.WindowsSdkLastVersion - yield os.path.join(path, '{}{}'.format(sdkver, arch_subdir)) + yield os.path.join(path, f'{sdkver}{arch_subdir}') if self.si.WindowsSDKExecutablePath: yield self.si.WindowsSDKExecutablePath @@ -1205,7 +1205,7 @@ def _sdk_subdir(self): subdir """ ucrtver = self.si.WindowsSdkLastVersion - return ('{}\\'.format(ucrtver)) if ucrtver else '' + return (f'{ucrtver}\\') if ucrtver else '' @property def SdkSetup(self): @@ -1267,7 +1267,7 @@ def NetFxSDKLibraries(self): return [] arch_subdir = self.pi.target_dir(x64=True) - return [os.path.join(self.si.NetFxSdkDir, r'lib\um{}'.format(arch_subdir))] + return [os.path.join(self.si.NetFxSdkDir, rf'lib\um{arch_subdir}')] @property def NetFxSDKIncludes(self): @@ -1315,7 +1315,7 @@ def MSBuild(self): base_path = self.si.VSInstallDir arch_subdir = '' - path = r'MSBuild\{:0.1f}\bin{}'.format(self.vs_ver, arch_subdir) + path = rf'MSBuild\{self.vs_ver:0.1f}\bin{arch_subdir}' build = [os.path.join(base_path, path)] if self.vs_ver >= 15.0: @@ -1355,7 +1355,7 @@ def UCRTLibraries(self): arch_subdir = self.pi.target_dir(x64=True) lib = os.path.join(self.si.UniversalCRTSdkDir, 'lib') ucrtver = self._ucrt_subdir - return [os.path.join(lib, '{}ucrt{}'.format(ucrtver, arch_subdir))] + return [os.path.join(lib, f'{ucrtver}ucrt{arch_subdir}')] @property def UCRTIncludes(self): @@ -1371,7 +1371,7 @@ def UCRTIncludes(self): return [] include = os.path.join(self.si.UniversalCRTSdkDir, 'include') - return [os.path.join(include, '{}ucrt'.format(self._ucrt_subdir))] + return [os.path.join(include, f'{self._ucrt_subdir}ucrt')] @property def _ucrt_subdir(self): @@ -1384,7 +1384,7 @@ def _ucrt_subdir(self): subdir """ ucrtver = self.si.UniversalCRTSdkLastVersion - return ('{}\\'.format(ucrtver)) if ucrtver else '' + return (f'{ucrtver}\\') if ucrtver else '' @property def FSharp(self): @@ -1525,7 +1525,7 @@ def _build_paths(self, name, spec_path_lists, exists): paths = itertools.chain(spec_paths, env_paths) extant_paths = list(filter(os.path.isdir, paths)) if exists else paths if not extant_paths: - msg = "{} environment variable is empty".format(name.upper()) + msg = f"{name.upper()} environment variable is empty" raise distutils.errors.DistutilsPlatformError(msg) unique_paths = unique_everseen(extant_paths) return os.pathsep.join(unique_paths) diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 373c047b93..25ca98b334 100644 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -74,7 +74,7 @@ def parse_requirement_arg(spec): return Requirement.parse(spec) except ValueError as e: raise DistutilsError( - "Not a URL, existing file, or requirement spec: {!r}".format(spec) + f"Not a URL, existing file, or requirement spec: {spec!r}" ) from e @@ -357,7 +357,7 @@ def process_url(self, url, retrieve: bool = False) -> None: # noqa: C901 if f is None: return if isinstance(f, urllib.error.HTTPError) and f.code == 401: - self.info("Authentication error: {}".format(f.msg)) + self.info(f"Authentication error: {f.msg}") self.fetched_urls[f.url] = True if 'html' not in f.headers.get('content-type', '').lower(): f.close() # not html, we can't process it @@ -474,7 +474,7 @@ def process_index(self, url, page): base, frag = egg_info_for_url(new_url) if base.endswith('.py') and not frag: if ver: - new_url += '#egg={}-{}'.format(pkg, ver) + new_url += f'#egg={pkg}-{ver}' else: self.need_version_info(url) self.scan_url(new_url) @@ -525,14 +525,12 @@ def check_hash(self, checker, filename, tfp) -> None: """ checker is a ContentChecker """ - checker.report(self.debug, "Validating %s checksum for {}".format(filename)) + checker.report(self.debug, f"Validating %s checksum for {filename}") if not checker.is_valid(): tfp.close() os.unlink(filename) raise DistutilsError( - "{} validation failed for {}; " "possible download problem?".format( - checker.hash.name, os.path.basename(filename) - ) + f"{checker.hash.name} validation failed for {os.path.basename(filename)}; " "possible download problem?" ) def add_find_links(self, urls) -> None: @@ -720,19 +718,15 @@ def gen_setup(self, filename, fragment, tmpdir): with open(os.path.join(tmpdir, 'setup.py'), 'w', encoding="utf-8") as file: file.write( "from setuptools import setup\n" - "setup(name={!r}, version={!r}, py_modules=[{!r}])\n".format( - dists[0].project_name, - dists[0].version, - os.path.splitext(basename)[0], - ) + f"setup(name={dists[0].project_name!r}, version={dists[0].version!r}, py_modules=[{os.path.splitext(basename)[0]!r}])\n" ) return filename elif match: raise DistutilsError( - "Can't unambiguously interpret project/version identifier {!r}; " + f"Can't unambiguously interpret project/version identifier {fragment!r}; " "any dashes in the name or version should be escaped using " - "underscores. {!r}".format(fragment, dists) + f"underscores. {dists!r}" ) else: raise DistutilsError( @@ -751,7 +745,7 @@ def _download_to(self, url, filename): fp = self.open_url(url) if isinstance(fp, urllib.error.HTTPError): raise DistutilsError( - "Can't download {}: {} {}".format(url, fp.code, fp.msg) + f"Can't download {url}: {fp.code} {fp.msg}" ) headers = fp.info() blocknum = 0 @@ -792,7 +786,7 @@ def open_url(self, url, warning=None): # noqa: C901 # is too complex (12) if warning: self.warn(warning, msg) else: - raise DistutilsError('{} {}'.format(url, msg)) from v + raise DistutilsError(f'{url} {msg}') from v except urllib.error.HTTPError as v: return v except urllib.error.URLError as v: @@ -800,21 +794,21 @@ def open_url(self, url, warning=None): # noqa: C901 # is too complex (12) self.warn(warning, v.reason) else: raise DistutilsError( - "Download error for {}: {}".format(url, v.reason) + f"Download error for {url}: {v.reason}" ) from v except http.client.BadStatusLine as v: if warning: self.warn(warning, v.line) else: raise DistutilsError( - '{} returned a bad status line. The server might be ' - 'down, {}'.format(url, v.line) + f'{url} returned a bad status line. The server might be ' + f'down, {v.line}' ) from v except (http.client.HTTPException, OSError) as v: if warning: self.warn(warning, v) else: - raise DistutilsError("Download error for {}: {}".format(url, v)) from v + raise DistutilsError(f"Download error for {url}: {v}") from v def _download_url(self, url, tmpdir): # Determine download filename @@ -1133,7 +1127,7 @@ def local_open(url): break elif os.path.isdir(filepath): f += '/' - files.append('{name}'.format(name=f)) + files.append(f'{f}') else: tmpl = "{url}{files}" body = tmpl.format(url=url, files='\n'.join(files)) diff --git a/setuptools/tests/config/test_setupcfg.py b/setuptools/tests/config/test_setupcfg.py index 399c9dd743..407419b2ea 100644 --- a/setuptools/tests/config/test_setupcfg.py +++ b/setuptools/tests/config/test_setupcfg.py @@ -87,7 +87,7 @@ def test_basic(self, tmpdir): '[options]\n' 'scripts = bin/a.py, bin/b.py\n', ) - config_dict = read_configuration('{}'.format(config)) + config_dict = read_configuration(f'{config}') assert config_dict['metadata']['version'] == '10.1.1' assert config_dict['metadata']['keywords'] == ['one', 'two'] assert config_dict['options']['scripts'] == ['bin/a.py', 'bin/b.py'] @@ -102,9 +102,9 @@ def test_ignore_errors(self, tmpdir): '[metadata]\nversion = attr: none.VERSION\nkeywords = one, two\n', ) with pytest.raises(ImportError): - read_configuration('{}'.format(config)) + read_configuration(f'{config}') - config_dict = read_configuration('{}'.format(config), ignore_option_errors=True) + config_dict = read_configuration(f'{config}', ignore_option_errors=True) assert config_dict['metadata']['keywords'] == ['one', 'two'] assert 'version' not in config_dict['metadata'] diff --git a/setuptools/tests/server.py b/setuptools/tests/server.py index 0a0fc2b668..623a49a550 100644 --- a/setuptools/tests/server.py +++ b/setuptools/tests/server.py @@ -44,7 +44,7 @@ def stop(self): def base_url(self): port = self.server_port - return 'http://127.0.0.1:{}/setuptools/tests/indexes/'.format(port) + return f'http://127.0.0.1:{port}/setuptools/tests/indexes/' class RequestRecorder(http.server.BaseHTTPRequestHandler): @@ -70,11 +70,11 @@ def run(self): @property def netloc(self): - return 'localhost:{}'.format(self.server_port) + return f'localhost:{self.server_port}' @property def url(self): - return 'http://{}/'.format(self.netloc) + return f'http://{self.netloc}/' def path_to_url(path, authority=None): diff --git a/setuptools/tests/test_core_metadata.py b/setuptools/tests/test_core_metadata.py index 89b2ea3054..c34b9eb831 100644 --- a/setuptools/tests/test_core_metadata.py +++ b/setuptools/tests/test_core_metadata.py @@ -311,7 +311,7 @@ def test_maintainer_author(name, attrs, tmpdir): for line in pkg_lines: assert not line.startswith(fkey + ':') else: - line = '{}: {}'.format(fkey, val) + line = f'{fkey}: {val}' assert line in pkg_lines_set diff --git a/setuptools/tests/test_dist.py b/setuptools/tests/test_dist.py index e1d7c1e043..533eb9f45e 100644 --- a/setuptools/tests/test_dist.py +++ b/setuptools/tests/test_dist.py @@ -24,7 +24,7 @@ def test_dist_fetch_build_egg(tmpdir): def sdist_with_index(distname, version): dist_dir = index.mkdir(distname) - dist_sdist = '{}-{}.tar.gz'.format(distname, version) + dist_sdist = f'{distname}-{version}.tar.gz' make_nspkg_sdist(str(dist_dir.join(dist_sdist)), distname, version) with dist_dir.join('index.html').open('w') as fp: fp.write( diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index a34f9bd525..e9b96027ce 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -735,14 +735,14 @@ def make_dependency_sdist(dist_path, distname, version): ( 'setup.py', DALS( - """ + f""" import setuptools setuptools.setup( - name={name!r}, + name={distname!r}, version={version!r}, - py_modules=[{name!r}], + py_modules=[{distname!r}], ) - """.format(name=distname, version=version) + """ ), ), ( @@ -814,7 +814,7 @@ def test_setup_requires_with_pep508_url(self, mock_index, monkeypatch): # Ignored (overridden by setup_attrs) 'python-xlib', '0.19', - setup_attrs=dict(setup_requires='dependency @ {}'.format(dep_url)), + setup_attrs=dict(setup_requires=f'dependency @ {dep_url}'), ) test_setup_py = os.path.join(test_pkg, 'setup.py') run_setup(test_setup_py, ['--version']) @@ -1100,13 +1100,13 @@ def make_trivial_sdist(dist_path, distname, version): ( 'setup.py', DALS( - """\ + f"""\ import setuptools setuptools.setup( - name={!r}, - version={!r} + name={distname!r}, + version={version!r} ) - """.format(distname, version) + """ ), ), ('setup.cfg', ''), @@ -1127,15 +1127,15 @@ def make_nspkg_sdist(dist_path, distname, version): packages = ['.'.join(parts[:idx]) for idx in range(1, len(parts) + 1)] setup_py = DALS( - """\ + f"""\ import setuptools setuptools.setup( - name={!r}, - version={!r}, - packages={!r}, - namespace_packages=[{!r}] + name={distname!r}, + version={version!r}, + packages={packages!r}, + namespace_packages=[{nspackage!r}] ) - """.format(distname, version, packages, nspackage) + """ ) init = "__import__('pkg_resources').declare_namespace(__name__)" @@ -1210,7 +1210,7 @@ def create_setup_requires_package( test_setup_attrs = { 'name': 'test_pkg', 'version': '0.0', - 'setup_requires': ['{}=={}'.format(distname, version)], + 'setup_requires': [f'{distname}=={version}'], 'dependency_links': [os.path.abspath(path)], } if setup_attrs: @@ -1231,7 +1231,7 @@ def create_setup_requires_package( section = options if isinstance(value, (tuple, list)): value = ';'.join(value) - section.append('{}: {}'.format(name, value)) + section.append(f'{name}: {value}') test_setup_cfg_contents = DALS( """ [metadata] @@ -1259,7 +1259,7 @@ def create_setup_requires_package( with open(os.path.join(test_pkg, 'setup.py'), 'w', encoding="utf-8") as f: f.write(setup_py_template % test_setup_attrs) - foobar_path = os.path.join(path, '{}-{}.tar.gz'.format(distname, version)) + foobar_path = os.path.join(path, f'{distname}-{version}.tar.gz') make_package(foobar_path, distname, version) return test_pkg @@ -1274,12 +1274,12 @@ class TestScriptHeader: exe_with_spaces = r'C:\Program Files\Python36\python.exe' def test_get_script_header(self): - expected = '#!{}\n'.format(ei.nt_quote_arg(os.path.normpath(sys.executable))) + expected = f'#!{ei.nt_quote_arg(os.path.normpath(sys.executable))}\n' actual = ei.ScriptWriter.get_header('#!/usr/local/bin/python') assert actual == expected def test_get_script_header_args(self): - expected = '#!{} -x\n'.format(ei.nt_quote_arg(os.path.normpath(sys.executable))) + expected = f'#!{ei.nt_quote_arg(os.path.normpath(sys.executable))} -x\n' actual = ei.ScriptWriter.get_header('#!/usr/bin/python -x') assert actual == expected @@ -1287,14 +1287,14 @@ def test_get_script_header_non_ascii_exe(self): actual = ei.ScriptWriter.get_header( '#!/usr/bin/python', executable=self.non_ascii_exe ) - expected = '#!{} -x\n'.format(self.non_ascii_exe) + expected = f'#!{self.non_ascii_exe} -x\n' assert actual == expected def test_get_script_header_exe_with_spaces(self): actual = ei.ScriptWriter.get_header( '#!/usr/bin/python', executable='"' + self.exe_with_spaces + '"' ) - expected = '#!"{}"\n'.format(self.exe_with_spaces) + expected = f'#!"{self.exe_with_spaces}"\n' assert actual == expected diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py index 24e73be44f..9924f9cbbd 100644 --- a/setuptools/tests/test_egg_info.py +++ b/setuptools/tests/test_egg_info.py @@ -259,13 +259,9 @@ def _setup_script_with_requires(self, requires, use_setup_cfg=False): 'setup.cfg': setup_config, }) - mismatch_marker = "python_version<'{this_ver}'".format( - this_ver=sys.version_info.major, - ) + mismatch_marker = f"python_version<'{sys.version_info[0]}'" # Alternate equivalent syntax. - mismatch_marker_alternate = 'python_version < "{this_ver}"'.format( - this_ver=sys.version_info.major, - ) + mismatch_marker_alternate = f'python_version < "{sys.version_info[0]}"' invalid_marker = "<=>++" class RequiresTestHelper: diff --git a/setuptools/tests/test_install_scripts.py b/setuptools/tests/test_install_scripts.py index f496fe5917..e62a6b7f31 100644 --- a/setuptools/tests/test_install_scripts.py +++ b/setuptools/tests/test_install_scripts.py @@ -38,7 +38,7 @@ def test_sys_executable_escaping_unix(self, tmpdir, monkeypatch): Ensure that shebang is not quoted on Unix when getting the Python exe from sys.executable. """ - expected = '#!{}\n'.format(self.unix_exe) + expected = f'#!{self.unix_exe}\n' monkeypatch.setattr('sys.executable', self.unix_exe) with tmpdir.as_cwd(): self._run_install_scripts(str(tmpdir)) @@ -52,7 +52,7 @@ def test_sys_executable_escaping_win32(self, tmpdir, monkeypatch): Ensure that shebang is quoted on Windows when getting the Python exe from sys.executable and it contains a space. """ - expected = '#!"{}"\n'.format(self.win32_exe) + expected = f'#!"{self.win32_exe}"\n' monkeypatch.setattr('sys.executable', self.win32_exe) with tmpdir.as_cwd(): self._run_install_scripts(str(tmpdir)) @@ -67,7 +67,7 @@ def test_executable_with_spaces_escaping_unix(self, tmpdir): a value with spaces is specified using --executable. """ - expected = '#!{}\n'.format(self.unix_spaces_exe) + expected = f'#!{self.unix_spaces_exe}\n' with tmpdir.as_cwd(): self._run_install_scripts(str(tmpdir), self.unix_spaces_exe) with open(str(tmpdir.join('foo')), 'r', encoding="utf-8") as f: @@ -81,7 +81,7 @@ def test_executable_arg_escaping_win32(self, tmpdir): getting a path with spaces from --executable, that is itself properly quoted. """ - expected = '#!"{}"\n'.format(self.win32_exe) + expected = f'#!"{self.win32_exe}"\n' with tmpdir.as_cwd(): self._run_install_scripts(str(tmpdir), '"' + self.win32_exe + '"') with open(str(tmpdir.join('foo-script.py')), 'r', encoding="utf-8") as f: diff --git a/setuptools/tests/test_manifest.py b/setuptools/tests/test_manifest.py index a821cf778b..903a528db0 100644 --- a/setuptools/tests/test_manifest.py +++ b/setuptools/tests/test_manifest.py @@ -34,11 +34,11 @@ def make_local_path(s): 'packages': ['app'], } -SETUP_PY = """\ +SETUP_PY = f"""\ from setuptools import setup -setup(**{!r}) -""".format(SETUP_ATTRS) +setup(**{SETUP_ATTRS!r}) +""" @contextlib.contextmanager diff --git a/setuptools/tests/test_sandbox.py b/setuptools/tests/test_sandbox.py index 5531ea8660..a476b7c93d 100644 --- a/setuptools/tests/test_sandbox.py +++ b/setuptools/tests/test_sandbox.py @@ -76,7 +76,7 @@ class CantPickleThis(Exception): "This Exception is unpickleable because it's not in globals" def __repr__(self) -> str: - return 'CantPickleThis{!r}'.format(self.args) + return f'CantPickleThis{self.args!r}' with setuptools.sandbox.ExceptionSaver() as saved_exc: raise CantPickleThis('detail') diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 8f5e620f0d..3ee0511b1c 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -37,11 +37,11 @@ 'data_files': [("data", [os.path.join("d", "e.dat")])], } -SETUP_PY = """\ +SETUP_PY = f"""\ from setuptools import setup -setup(**{!r}) -""".format(SETUP_ATTRS) +setup(**{SETUP_ATTRS!r}) +""" EXTENSION = Extension( name="sdist_test.f", diff --git a/setuptools/tests/test_wheel.py b/setuptools/tests/test_wheel.py index 7e700a14d2..70165c608b 100644 --- a/setuptools/tests/test_wheel.py +++ b/setuptools/tests/test_wheel.py @@ -176,7 +176,7 @@ def __init__(self, id, **kwargs): self._fields = kwargs def __repr__(self) -> str: - return '{}(**{!r})'.format(self._id, self._fields) + return f'{self._id}(**{self._fields!r})' # Using Any to avoid possible type union issues later in test @@ -367,10 +367,10 @@ def __repr__(self) -> str: ), dict( id='requires2', - install_requires=""" + install_requires=f""" bar - foo<=2.0; {!r} in sys_platform - """.format(sys.platform), + foo<=2.0; {sys.platform!r} in sys_platform + """, requires_txt=DALS( """ bar @@ -380,9 +380,9 @@ def __repr__(self) -> str: ), dict( id='requires3', - install_requires=""" - bar; {!r} != sys_platform - """.format(sys.platform), + install_requires=f""" + bar; {sys.platform!r} != sys_platform + """, ), dict( id='requires4', @@ -404,7 +404,7 @@ def __repr__(self) -> str: dict( id='requires5', extras_require={ - 'extra': 'foobar; {!r} != sys_platform'.format(sys.platform), + 'extra': f'foobar; {sys.platform!r} != sys_platform', }, requires_txt=DALS( """ @@ -603,7 +603,7 @@ def test_wheel_install_pep_503(): def test_wheel_no_dist_dir(): project_name = 'nodistinfo' version = '1.0' - wheel_name = '{}-{}-py2.py3-none-any.whl'.format(project_name, version) + wheel_name = f'{project_name}-{version}-py2.py3-none-any.whl' with tempdir() as source_dir: wheel_path = os.path.join(source_dir, wheel_name) # create an empty zip file diff --git a/setuptools/tests/test_windows_wrappers.py b/setuptools/tests/test_windows_wrappers.py index e46bb6abc0..f895485387 100644 --- a/setuptools/tests/test_windows_wrappers.py +++ b/setuptools/tests/test_windows_wrappers.py @@ -57,9 +57,9 @@ def win_launcher_exe(prefix): """A simple routine to select launcher script based on platform.""" assert prefix in ('cli', 'gui') if platform.machine() == "ARM64": - return "{}-arm64.exe".format(prefix) + return f"{prefix}-arm64.exe" else: - return "{}-32.exe".format(prefix) + return f"{prefix}-32.exe" class TestCLI(WrapperTester): diff --git a/setuptools/wheel.py b/setuptools/wheel.py index 9ccd9e7ede..0ac8fc49c1 100644 --- a/setuptools/wheel.py +++ b/setuptools/wheel.py @@ -79,7 +79,7 @@ class Wheel: def __init__(self, filename) -> None: match = WHEEL_NAME(os.path.basename(filename)) if match is None: - raise ValueError('invalid wheel name: {!r}'.format(filename)) + raise ValueError(f'invalid wheel name: {filename!r}') self.filename = filename for k, v in match.groupdict().items(): setattr(self, k, v) @@ -122,9 +122,9 @@ def install_as_egg(self, destination_eggdir) -> None: self._install_as_egg(destination_eggdir, zf) def _install_as_egg(self, destination_eggdir, zf): - dist_basename = '{}-{}'.format(self.project_name, self.version) + dist_basename = f'{self.project_name}-{self.version}' dist_info = self.get_dist_info(zf) - dist_data = '{}.data'.format(dist_basename) + dist_data = f'{dist_basename}.data' egg_info = os.path.join(destination_eggdir, 'EGG-INFO') self._convert_metadata(zf, destination_eggdir, dist_info, egg_info) @@ -146,7 +146,7 @@ def get_metadata(name): wheel_v1 = parse_version('1.0') <= wheel_version < parse_version('2.0dev0') if not wheel_v1: raise ValueError( - 'unsupported wheel format version: {}'.format(wheel_version) + f'unsupported wheel format version: {wheel_version}' ) # Extract to target directory. _unpack_zipfile_obj(zf, destination_eggdir) From 88861f9b9e31af8d4e54ed3fedb4120efff98536 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 10 Sep 2024 12:27:49 +0200 Subject: [PATCH 5/8] A round of `ruff format` after `ruff check --fix` --- pkg_resources/__init__.py | 6 ++---- pkg_resources/tests/test_pkg_resources.py | 4 +++- setuptools/__init__.py | 4 +--- setuptools/command/bdist_egg.py | 4 +--- setuptools/command/easy_install.py | 4 +++- setuptools/command/install_egg_info.py | 4 +--- setuptools/dist.py | 4 +--- setuptools/msvc.py | 8 ++------ setuptools/package_index.py | 11 ++++------- setuptools/wheel.py | 4 +--- 10 files changed, 19 insertions(+), 34 deletions(-) diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 044c1a04ef..3a387d08e5 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -3049,7 +3049,7 @@ def version(self): version = self._get_version() if version is None: path = self._get_metadata_path_for_display(self.PKG_INFO) - msg = (f"Missing 'Version:' header and/or {self.PKG_INFO} file at path: {path}") + msg = f"Missing 'Version:' header and/or {self.PKG_INFO} file at path: {path}" raise ValueError(msg, self) from e return version @@ -3105,9 +3105,7 @@ def requires(self, extras: Iterable[str] = ()) -> list[Requirement]: try: deps.extend(dm[safe_extra(ext)]) except KeyError as e: - raise UnknownExtra( - f"{self} has no such extra feature {ext!r}" - ) from e + raise UnknownExtra(f"{self} has no such extra feature {ext!r}") from e return deps def _get_metadata_path_for_display(self, name): diff --git a/pkg_resources/tests/test_pkg_resources.py b/pkg_resources/tests/test_pkg_resources.py index 27ddaab42f..0f696e8502 100644 --- a/pkg_resources/tests/test_pkg_resources.py +++ b/pkg_resources/tests/test_pkg_resources.py @@ -255,7 +255,9 @@ def test_distribution_version_missing( basename = f'foo.{suffix}' dist, dist_dir = make_distribution_no_version(tmpdir, basename) - expected_text = (f"Missing 'Version:' header and/or {expected_filename} file at path: ") + expected_text = ( + f"Missing 'Version:' header and/or {expected_filename} file at path: " + ) metadata_path = os.path.join(dist_dir, expected_filename) # Now check the exception raised when the "version" attribute is accessed. diff --git a/setuptools/__init__.py b/setuptools/__init__.py index 8b83a5271d..64464dfaa3 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -181,9 +181,7 @@ def _ensure_stringlike(self, option, what, default=None): setattr(self, option, default) return default elif not isinstance(val, str): - raise DistutilsOptionError( - f"'{option}' must be a {what} (got `{val}`)" - ) + raise DistutilsOptionError(f"'{option}' must be a {what} (got `{val}`)") return val def ensure_string_list(self, option: str) -> None: diff --git a/setuptools/command/bdist_egg.py b/setuptools/command/bdist_egg.py index 21e3e8f14d..9a08b36585 100644 --- a/setuptools/command/bdist_egg.py +++ b/setuptools/command/bdist_egg.py @@ -263,9 +263,7 @@ def zap_pyfiles(self): pattern = r'(?P.+)\.(?P[^.]+)\.pyc' m = re.match(pattern, name) path_new = os.path.join(base, os.pardir, m.group('name') + '.pyc') - log.info( - f"Renaming file from [{path_old}] to [{path_new}]" - ) + log.info(f"Renaming file from [{path_old}] to [{path_new}]") try: os.remove(path_new) except OSError: diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 379beede14..4a93ff077e 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1112,7 +1112,9 @@ def install_wheel(self, wheel_path, tmpdir): self.execute( wheel.install_as_egg, (destination,), - (f"Installing {os.path.basename(wheel_path)} to {os.path.dirname(destination)}"), + ( + f"Installing {os.path.basename(wheel_path)} to {os.path.dirname(destination)}" + ), ) finally: update_dist_caches(destination, fix_zipimporter_caches=False) diff --git a/setuptools/command/install_egg_info.py b/setuptools/command/install_egg_info.py index cbf125c764..44f22ccf51 100644 --- a/setuptools/command/install_egg_info.py +++ b/setuptools/command/install_egg_info.py @@ -36,9 +36,7 @@ def run(self) -> None: self.execute(os.unlink, (self.target,), "Removing " + self.target) if not self.dry_run: ensure_directory(self.target) - self.execute( - self.copytree, (), f"Copying {self.source} to {self.target}" - ) + self.execute(self.copytree, (), f"Copying {self.source} to {self.target}") self.install_namespaces() def get_outputs(self): diff --git a/setuptools/dist.py b/setuptools/dist.py index 639a435ad4..18ba1883f2 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -835,9 +835,7 @@ def _include_misc(self, name: str, value: _Sequence) -> None: try: old = getattr(self, name) except AttributeError as e: - raise DistutilsSetupError( - f"{name}: No such distribution setting" - ) from e + raise DistutilsSetupError(f"{name}: No such distribution setting") from e if old is None: setattr(self, name, value) elif not isinstance(old, _sequence): diff --git a/setuptools/msvc.py b/setuptools/msvc.py index 4ed97c75a1..7f006c3c1a 100644 --- a/setuptools/msvc.py +++ b/setuptools/msvc.py @@ -697,9 +697,7 @@ def FSharpInstallDir(self): str path """ - path = os.path.join( - self.ri.visualstudio, rf'{self.vs_ver:0.1f}\Setup\F#' - ) + path = os.path.join(self.ri.visualstudio, rf'{self.vs_ver:0.1f}\Setup\F#') return self.ri.lookup(path, 'productdir') or '' @property @@ -717,9 +715,7 @@ def UniversalCRTSdkDir(self): # Find path of the more recent Kit for ver in vers: - sdkdir = self.ri.lookup( - self.ri.windows_kits_roots, f'kitsroot{ver}' - ) + sdkdir = self.ri.lookup(self.ri.windows_kits_roots, f'kitsroot{ver}') if sdkdir: return sdkdir or '' diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 25ca98b334..1a6abebcda 100644 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -530,7 +530,8 @@ def check_hash(self, checker, filename, tfp) -> None: tfp.close() os.unlink(filename) raise DistutilsError( - f"{checker.hash.name} validation failed for {os.path.basename(filename)}; " "possible download problem?" + f"{checker.hash.name} validation failed for {os.path.basename(filename)}; " + "possible download problem?" ) def add_find_links(self, urls) -> None: @@ -744,9 +745,7 @@ def _download_to(self, url, filename): checker = HashChecker.from_url(url) fp = self.open_url(url) if isinstance(fp, urllib.error.HTTPError): - raise DistutilsError( - f"Can't download {url}: {fp.code} {fp.msg}" - ) + raise DistutilsError(f"Can't download {url}: {fp.code} {fp.msg}") headers = fp.info() blocknum = 0 bs = self.dl_blocksize @@ -793,9 +792,7 @@ def open_url(self, url, warning=None): # noqa: C901 # is too complex (12) if warning: self.warn(warning, v.reason) else: - raise DistutilsError( - f"Download error for {url}: {v.reason}" - ) from v + raise DistutilsError(f"Download error for {url}: {v.reason}") from v except http.client.BadStatusLine as v: if warning: self.warn(warning, v.line) diff --git a/setuptools/wheel.py b/setuptools/wheel.py index 0ac8fc49c1..c7ca43b5cf 100644 --- a/setuptools/wheel.py +++ b/setuptools/wheel.py @@ -145,9 +145,7 @@ def get_metadata(name): wheel_version = parse_version(wheel_metadata.get('Wheel-Version')) wheel_v1 = parse_version('1.0') <= wheel_version < parse_version('2.0dev0') if not wheel_v1: - raise ValueError( - f'unsupported wheel format version: {wheel_version}' - ) + raise ValueError(f'unsupported wheel format version: {wheel_version}') # Extract to target directory. _unpack_zipfile_obj(zf, destination_eggdir) # Convert metadata. From 578d630f935dbb3a0a3c001c77b49a369f1b1b58 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 10 Sep 2024 12:35:07 +0200 Subject: [PATCH 6/8] Manual fixes after `ruff check --fix` runs --- pkg_resources/__init__.py | 11 +++++++---- setuptools/_core_metadata.py | 4 ++-- setuptools/command/bdist_egg.py | 2 +- setuptools/command/build_ext.py | 2 +- setuptools/command/easy_install.py | 7 ++++--- setuptools/dist.py | 3 +-- setuptools/tests/config/test_setupcfg.py | 8 ++++---- setuptools/tests/test_build_ext.py | 4 ++-- 8 files changed, 22 insertions(+), 19 deletions(-) diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 3a387d08e5..871f7344e4 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -200,7 +200,9 @@ def get_supported_platform(): m = macosVersionString.match(plat) if m is not None and sys.platform == "darwin": try: - plat = 'macosx-{}-{}'.format('.'.join(_macos_vers()[:2]), m.group(3)) + major_minor = '.'.join(_macos_vers()[:2]) + build = m.group(3) + plat = f'macosx-{major_minor}-{build}' except ValueError: # not macOS pass @@ -2733,7 +2735,8 @@ def __str__(self) -> str: if self.attrs: s += ':' + '.'.join(self.attrs) if self.extras: - s += ' [{}]'.format(','.join(self.extras)) + extras = ','.join(self.extras) + s += f' [{extras}]' return s def __repr__(self) -> str: @@ -3319,8 +3322,8 @@ def check_version_conflict(self): ): continue issue_warning( - f"Module {modname} was already imported from {fn}, but {self.location} is being added" - " to sys.path", + f"Module {modname} was already imported from {fn}, " + f"but {self.location} is being added to sys.path", ) def has_version(self) -> bool: diff --git a/setuptools/_core_metadata.py b/setuptools/_core_metadata.py index a5e18a4006..642b80df31 100644 --- a/setuptools/_core_metadata.py +++ b/setuptools/_core_metadata.py @@ -178,8 +178,8 @@ def write_field(key, value): if license: write_field('License', rfc822_escape(license)) - for project_url in self.project_urls.items(): - write_field('Project-URL', '{}, {}'.format(*project_url)) + for label, url in self.project_urls.items(): + write_field('Project-URL', f'{label}, {url}') keywords = ','.join(self.get_keywords()) if keywords: diff --git a/setuptools/command/bdist_egg.py b/setuptools/command/bdist_egg.py index 9a08b36585..7f66c3ba6a 100644 --- a/setuptools/command/bdist_egg.py +++ b/setuptools/command/bdist_egg.py @@ -69,7 +69,7 @@ def __bootstrap__(): class bdist_egg(Command): - description = "create an \"egg\" distribution" + description = 'create an "egg" distribution' user_options = [ ('bdist-dir=', 'b', "temporary directory for creating the distribution"), diff --git a/setuptools/command/build_ext.py b/setuptools/command/build_ext.py index 6e56ae4ca2..be833a379c 100644 --- a/setuptools/command/build_ext.py +++ b/setuptools/command/build_ext.py @@ -168,7 +168,7 @@ def get_ext_filename(self, fullname: str) -> str: if not isinstance(ext_suffix, str): raise OSError( "Configuration variable EXT_SUFFIX not found for this platform " - + "and environment variable SETUPTOOLS_EXT_SUFFIX is missing" + "and environment variable SETUPTOOLS_EXT_SUFFIX is missing" ) so_ext = ext_suffix diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 4a93ff077e..eb1b4c1fcc 100644 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -132,8 +132,8 @@ class easy_install(Command): ( 'optimize=', 'O', - "also compile with optimization: -O1 for \"python -O\", " - "-O2 for \"python -OO\", and -O0 to disable [default: -O0]", + 'also compile with optimization: -O1 for "python -O", ' + '-O2 for "python -OO", and -O0 to disable [default: -O0]', ), ('record=', None, "filename in which to record list of installed files"), ('always-unzip', 'Z', "don't install as a zipfile, no matter what"), @@ -1024,7 +1024,8 @@ def install_exe(self, dist_filename, tmpdir): f.write('Metadata-Version: 1.0\n') for k, v in cfg.items('metadata'): if k != 'target_version': - f.write('{}: {}\n'.format(k.replace('_', '-').title(), v)) + k = k.replace('_', '-').title() + f.write(f'{k}: {v}\n') script_dir = os.path.join(_egg_info, 'scripts') # delete entry-point scripts to avoid duping self.delete_blockers([ diff --git a/setuptools/dist.py b/setuptools/dist.py index 18ba1883f2..ba45504aa8 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -110,8 +110,7 @@ def check_nsp(dist, attr, value): for nsp in ns_packages: if not dist.has_contents_for(nsp): raise DistutilsSetupError( - "Distribution contains no modules or packages for " - + f"namespace package {nsp!r}" + f"Distribution contains no modules or packages for namespace package {nsp!r}" ) parent, _sep, _child = nsp.rpartition('.') if parent and parent not in ns_packages: diff --git a/setuptools/tests/config/test_setupcfg.py b/setuptools/tests/config/test_setupcfg.py index 407419b2ea..adadc02da3 100644 --- a/setuptools/tests/config/test_setupcfg.py +++ b/setuptools/tests/config/test_setupcfg.py @@ -87,14 +87,14 @@ def test_basic(self, tmpdir): '[options]\n' 'scripts = bin/a.py, bin/b.py\n', ) - config_dict = read_configuration(f'{config}') + config_dict = read_configuration(str(config)) assert config_dict['metadata']['version'] == '10.1.1' assert config_dict['metadata']['keywords'] == ['one', 'two'] assert config_dict['options']['scripts'] == ['bin/a.py', 'bin/b.py'] def test_no_config(self, tmpdir): with pytest.raises(DistutilsFileError): - read_configuration('{}'.format(tmpdir.join('setup.cfg'))) + read_configuration(str(tmpdir.join('setup.cfg'))) def test_ignore_errors(self, tmpdir): _, config = fake_env( @@ -102,9 +102,9 @@ def test_ignore_errors(self, tmpdir): '[metadata]\nversion = attr: none.VERSION\nkeywords = one, two\n', ) with pytest.raises(ImportError): - read_configuration(f'{config}') + read_configuration(str(config)) - config_dict = read_configuration(f'{config}', ignore_option_errors=True) + config_dict = read_configuration(str(config), ignore_option_errors=True) assert config_dict['metadata']['keywords'] == ['one', 'two'] assert 'version' not in config_dict['metadata'] diff --git a/setuptools/tests/test_build_ext.py b/setuptools/tests/test_build_ext.py index be7b7cc01c..c7b60ac32f 100644 --- a/setuptools/tests/test_build_ext.py +++ b/setuptools/tests/test_build_ext.py @@ -286,8 +286,8 @@ def test_build_ext_config_handling(tmpdir_cwd): ), } path.build(files) - code, output = environment.run_setup_py( + code, (stdout, stderr) = environment.run_setup_py( cmd=['build'], data_stream=(0, 2), ) - assert code == 0, '\nSTDOUT:\n{}\nSTDERR:\n{}'.format(*output) + assert code == 0, f'\nSTDOUT:\n{stdout}\nSTDERR:\n{stderr}' From 35365c6cd523941b94b6d7f763505c2d820a9bae Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 10 Sep 2024 12:42:35 +0200 Subject: [PATCH 7/8] Manually remove more .format() calls --- setuptools/command/bdist_wheel.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/setuptools/command/bdist_wheel.py b/setuptools/command/bdist_wheel.py index 234df2a7c7..994b4b4167 100644 --- a/setuptools/command/bdist_wheel.py +++ b/setuptools/command/bdist_wheel.py @@ -184,9 +184,7 @@ class bdist_wheel(Command): ( "compression=", None, - "zipfile compression (one of: {}) [default: 'deflated']".format( - ", ".join(supported_compressions) - ), + f"zipfile compression (one of: {', '.join(supported_compressions)}) [default: 'deflated']", ), ( "python-tag=", From f65ea5b380efdd828f3c3d76e682144177bcdc1a Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Tue, 10 Sep 2024 12:42:35 +0200 Subject: [PATCH 8/8] Manually remove more %-formatting --- docs/userguide/extension.rst | 2 +- pkg_resources/__init__.py | 8 ++------ setuptools/msvc.py | 14 +++++++------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/docs/userguide/extension.rst b/docs/userguide/extension.rst index e1e37b5db1..ef5e33f3a8 100644 --- a/docs/userguide/extension.rst +++ b/docs/userguide/extension.rst @@ -122,7 +122,7 @@ a non-``None`` value. Here's an example validation function:: """Verify that value is True, False, 0, or 1""" if bool(value) != value: raise SetupError( - "%r must be a boolean value (got %r)" % (attr,value) + f"{attr!r} must be a boolean value (got {value!r}" ) Your function should accept three arguments: the ``Distribution`` object, diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 871f7344e4..87cfa75218 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -451,12 +451,8 @@ def get_build_platform(): if sys.platform == "darwin" and not plat.startswith('macosx-'): try: version = _macos_vers() - machine = os.uname()[4].replace(" ", "_") - return "macosx-%d.%d-%s" % ( - int(version[0]), - int(version[1]), - _macos_arch(machine), - ) + machine = _macos_arch(os.uname()[4].replace(" ", "_")) + return f"macosx-{version[0]}.{version[1]}-{machine}" except ValueError: # if someone is running a non-Mac darwin system, this will fall # through to the default implementation diff --git a/setuptools/msvc.py b/setuptools/msvc.py index 7f006c3c1a..9c9a63568e 100644 --- a/setuptools/msvc.py +++ b/setuptools/msvc.py @@ -667,8 +667,8 @@ def WindowsSDKExecutablePath(self): else: netfxver = 40 hidex86 = True if self.vs_ver <= 12.0 else False - arch = self.pi.current_dir(x64=True, hidex86=hidex86) - fx = 'WinSDK-NetFx%dTools%s' % (netfxver, arch.replace('\\', '-')) + arch = self.pi.current_dir(x64=True, hidex86=hidex86).replace('\\', '-') + fx = f'WinSDK-NetFx{netfxver}Tools{arch}' # list all possibles registry paths regpaths = [] @@ -839,8 +839,8 @@ def _find_dot_net_versions(self, bits) -> tuple[str, ...]: versions """ # Find actual .NET version in registry - reg_ver = self.ri.lookup(self.ri.vc, 'frameworkver%d' % bits) - dot_net_dir = getattr(self, 'FrameworkDir%d' % bits) + reg_ver = self.ri.lookup(self.ri.vc, f'frameworkver{bits}') + dot_net_dir = getattr(self, f'FrameworkDir{bits}') ver = reg_ver or self._use_last_dir_name(dot_net_dir, 'v') or '' # Set .NET versions for specified MSVC++ version @@ -1404,7 +1404,7 @@ def VCRuntimeRedist(self) -> str | None: Returns the first suitable path found or None. """ - vcruntime = 'vcruntime%d0.dll' % self.vc_ver + vcruntime = f'vcruntime{self.vc_ver}0.dll' arch_subdir = self.pi.target_dir(x64=True).strip('\\') # Installation prefixes candidates @@ -1420,9 +1420,9 @@ def VCRuntimeRedist(self) -> str | None: # CRT directory crt_dirs = ( - 'Microsoft.VC%d.CRT' % (self.vc_ver * 10), + f'Microsoft.VC{self.vc_ver * 10}.CRT', # Sometime store in directory with VS version instead of VC - 'Microsoft.VC%d.CRT' % (int(self.vs_ver) * 10), + f'Microsoft.VC{int(self.vs_ver) * 10}.CRT', ) # vcruntime path