public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/_emerge/resolver/
@ 2019-12-15  6:48 Zac Medico
  0 siblings, 0 replies; 2+ messages in thread
From: Zac Medico @ 2019-12-15  6:48 UTC (permalink / raw
  To: gentoo-commits

commit:     463b2d36f3d95760e48543f1f30410aa76267538
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Sun Dec 15 05:30:13 2019 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Sun Dec 15 06:27:26 2019 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=463b2d36

emerge: Show package USE in conflict messages

Bug: https://bugs.gentoo.org/310009
Signed-off-by: Zac Medico <zmedico <AT> gentoo.org>

 lib/_emerge/depgraph.py                | 26 +++++++++++++++++++++-----
 lib/_emerge/resolver/slot_collision.py | 17 +++++++++++++----
 2 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py
index 02e0e075d..1a5448c8f 100644
--- a/lib/_emerge/depgraph.py
+++ b/lib/_emerge/depgraph.py
@@ -1285,7 +1285,10 @@ class depgraph(object):
 			msg.append("\n\n")
 
 			msg.append(indent)
-			msg.append(str(pkg))
+			msg.append("%s %s" % (pkg,
+				pkg_use_display(pkg,
+					self._frozen_config.myopts,
+					modified_use=self._pkg_use_enabled(pkg))))
 			msg.append(" conflicts with\n")
 
 			for parent, atom in parent_atoms:
@@ -1302,8 +1305,15 @@ class depgraph(object):
 					atom, marker = format_unmatched_atom(
 						pkg, atom, self._pkg_use_enabled)
 
+					if isinstance(parent, Package):
+						use_display = pkg_use_display(parent,
+							self._frozen_config.myopts,
+							modified_use=self._pkg_use_enabled(parent))
+					else:
+						use_display = ""
+
 					msg.append(2*indent)
-					msg.append("%s required by %s\n" % (atom, parent))
+					msg.append("%s required by %s %s\n" % (atom, parent, use_display))
 					msg.append(2*indent)
 					msg.append(marker)
 					msg.append("\n")
@@ -8472,14 +8482,20 @@ class depgraph(object):
 					else:
 						# Display the specific atom from SetArg or
 						# Package types.
+						if isinstance(parent, Package):
+							use_display = pkg_use_display(parent,
+								self._frozen_config.myopts,
+								modified_use=self._pkg_use_enabled(parent))
+						else:
+							use_display = ""
 						if atom.package and atom != atom.unevaluated_atom:
 							# Show the unevaluated atom, since it can reveal
 							# issues with conditional use-flags missing
 							# from IUSE.
-							msg.append("%s (%s) required by %s" %
-								(atom.unevaluated_atom, atom, parent))
+							msg.append("%s (%s) required by %s %s" %
+								(atom.unevaluated_atom, atom, parent, use_display))
 						else:
-							msg.append("%s required by %s" % (atom, parent))
+							msg.append("%s required by %s %s" % (atom, parent, use_display))
 					msg.append("\n")
 
 				msg.append("\n")

diff --git a/lib/_emerge/resolver/slot_collision.py b/lib/_emerge/resolver/slot_collision.py
index f676b38c8..682a3a0a5 100644
--- a/lib/_emerge/resolver/slot_collision.py
+++ b/lib/_emerge/resolver/slot_collision.py
@@ -9,6 +9,7 @@ from portage import _encodings, _unicode_encode
 from _emerge.AtomArg import AtomArg
 from _emerge.Package import Package
 from _emerge.PackageArg import PackageArg
+from _emerge.UseFlagDisplay import pkg_use_display
 from portage.dep import check_required_use
 from portage.output import colorize
 from portage._sets.base import InternalPackageSet
@@ -260,7 +261,9 @@ class slot_conflict_handler(object):
 
 			for pkg in pkgs:
 				msg.append(indent)
-				msg.append("%s" % (pkg,))
+				msg.append("%s %s" % (pkg, pkg_use_display(pkg,
+					self.depgraph._frozen_config.myopts,
+					modified_use=self.depgraph._pkg_use_enabled(pkg))))
 				parent_atoms = self.all_parents.get(pkg)
 				if parent_atoms:
 					#Create a list of collision reasons and map them to sets
@@ -569,9 +572,15 @@ class slot_conflict_handler(object):
 								ordered_list.append(parent_atom)
 					for parent_atom in ordered_list:
 						parent, atom = parent_atom
+						if isinstance(parent, Package):
+							use_display = pkg_use_display(parent,
+								self.depgraph._frozen_config.myopts,
+								modified_use=self.depgraph._pkg_use_enabled(parent))
+						else:
+							use_display = ""
 						if atom.soname:
-							msg.append("%s required by %s\n" %
-								(atom, parent))
+							msg.append("%s required by %s %s\n" %
+								(atom, parent, use_display))
 						elif isinstance(parent, PackageArg):
 							# For PackageArg it's
 							# redundant to display the atom attribute.
@@ -602,7 +611,7 @@ class slot_conflict_handler(object):
 							if version_violated or slot_violated:
 								self.is_a_version_conflict = True
 
-							cur_line = "%s required by %s\n" % (atom_str, parent)
+							cur_line = "%s required by %s %s\n" % (atom_str, parent, use_display)
 							marker_line = ""
 							for ii in range(len(cur_line)):
 								if ii in colored_idx:


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/_emerge/resolver/
@ 2023-04-30 23:30 Sam James
  0 siblings, 0 replies; 2+ messages in thread
From: Sam James @ 2023-04-30 23:30 UTC (permalink / raw
  To: gentoo-commits

commit:     0b21a5a392bd84c07b94373991f59108fbe98516
Author:     Oskari Pirhonen <xxc3ncoredxx <AT> gmail <DOT> com>
AuthorDate: Wed Mar 22 01:56:23 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Apr 30 23:30:07 2023 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=0b21a5a3

Convert %-formats to fstrings

Files under lib/_emerge

Signed-off-by: Oskari Pirhonen <xxc3ncoredxx <AT> gmail.com>
Closes: https://github.com/gentoo/portage/pull/1013
Signed-off-by: Sam James <sam <AT> gentoo.org>

 lib/_emerge/AbstractEbuildProcess.py   |  64 ++++-----
 lib/_emerge/AsynchronousLock.py        |   5 +-
 lib/_emerge/BinpkgEnvExtractor.py      |   5 +-
 lib/_emerge/BinpkgExtractorAsync.py    |  60 ++++-----
 lib/_emerge/BinpkgFetcher.py           |   3 +-
 lib/_emerge/BinpkgVerifier.py          |  17 +--
 lib/_emerge/EbuildMerge.py             |   8 +-
 lib/_emerge/JobStatusDisplay.py        |   8 +-
 lib/_emerge/MergeListItem.py           |   4 +-
 lib/_emerge/Package.py                 |   8 +-
 lib/_emerge/Scheduler.py               |   6 +-
 lib/_emerge/SpawnProcess.py            |  11 +-
 lib/_emerge/SubProcess.py              |   2 +-
 lib/_emerge/Task.py                    |   5 +-
 lib/_emerge/UserQuery.py               |   5 +-
 lib/_emerge/actions.py                 | 128 ++++++++----------
 lib/_emerge/chk_updated_cfg_files.py   |   6 +-
 lib/_emerge/countdown.py               |   6 +-
 lib/_emerge/depgraph.py                | 236 ++++++++++++---------------------
 lib/_emerge/resolver/output.py         |   3 +-
 lib/_emerge/resolver/output_helpers.py |  10 +-
 lib/_emerge/resolver/slot_collision.py |  65 +++------
 lib/_emerge/search.py                  |   3 +-
 lib/_emerge/unmerge.py                 |  28 ++--
 24 files changed, 271 insertions(+), 425 deletions(-)

diff --git a/lib/_emerge/AbstractEbuildProcess.py b/lib/_emerge/AbstractEbuildProcess.py
index fe2ef426a..be257a620 100644
--- a/lib/_emerge/AbstractEbuildProcess.py
+++ b/lib/_emerge/AbstractEbuildProcess.py
@@ -13,7 +13,6 @@ from _emerge.EbuildBuildDir import EbuildBuildDir
 from _emerge.EbuildIpcDaemon import EbuildIpcDaemon
 import portage
 from portage.elog import messages as elog_messages
-from portage.localization import _
 from portage.package.ebuild._ipc.ExitCommand import ExitCommand
 from portage.package.ebuild._ipc.QueryCommand import QueryCommand
 from portage import os
@@ -72,10 +71,10 @@ class AbstractEbuildProcess(SpawnProcess):
         # die_hooks for some reason, and PORTAGE_BUILDDIR
         # doesn't exist yet.
         if need_builddir and not os.path.isdir(self.settings["PORTAGE_BUILDDIR"]):
-            msg = _(
-                "The ebuild phase '%s' has been aborted "
-                "since PORTAGE_BUILDDIR does not exist: '%s'"
-            ) % (self.phase, self.settings["PORTAGE_BUILDDIR"])
+            msg = (
+                f"The ebuild phase '{self.phase}' has been aborted since "
+                f"PORTAGE_BUILDDIR does not exist: '{self.settings['PORTAGE_BUILDDIR']}'"
+            )
             self._eerror(textwrap.wrap(msg, 72))
             self.returncode = 1
             self._async_wait()
@@ -326,11 +325,10 @@ class AbstractEbuildProcess(SpawnProcess):
     def _orphan_process_warn(self):
         phase = self.phase
 
-        msg = _(
-            "The ebuild phase '%s' with pid %s appears "
-            "to have left an orphan process running in the "
-            "background."
-        ) % (phase, self.pid)
+        msg = (
+            f"The ebuild phase '{phase}' with pid {self.pid} appears "
+            "to have left an orphan process running in the background."
+        )
 
         self._eerror(textwrap.wrap(msg, 72))
 
@@ -346,38 +344,32 @@ class AbstractEbuildProcess(SpawnProcess):
         ) or os.isatty(slave_fd)
 
     def _killed_by_signal(self, signum):
-        msg = _("The ebuild phase '%s' has been " "killed by signal %s.") % (
-            self.phase,
-            signum,
-        )
+        msg = f"The ebuild phase '{self.phase}' has been killed by signal {signum}."
         self._eerror(textwrap.wrap(msg, 72))
 
     def _unexpected_exit(self):
         phase = self.phase
 
         msg = (
-            _(
-                "The ebuild phase '%s' has exited "
-                "unexpectedly. This type of behavior "
-                "is known to be triggered "
-                "by things such as failed variable "
-                "assignments (bug #190128) or bad substitution "
-                "errors (bug #200313). Normally, before exiting, bash should "
-                "have displayed an error message above. If bash did not "
-                "produce an error message above, it's possible "
-                "that the ebuild has called `exit` when it "
-                "should have called `die` instead. This behavior may also "
-                "be triggered by a corrupt bash binary or a hardware "
-                "problem such as memory or cpu malfunction. If the problem is not "
-                "reproducible or it appears to occur randomly, then it is likely "
-                "to be triggered by a hardware problem. "
-                "If you suspect a hardware problem then you should "
-                "try some basic hardware diagnostics such as memtest. "
-                "Please do not report this as a bug unless it is consistently "
-                "reproducible and you are sure that your bash binary and hardware "
-                "are functioning properly."
-            )
-            % phase
+            f"The ebuild phase '{phase}' has exited "
+            "unexpectedly. This type of behavior "
+            "is known to be triggered "
+            "by things such as failed variable "
+            "assignments (bug #190128) or bad substitution "
+            "errors (bug #200313). Normally, before exiting, bash should "
+            "have displayed an error message above. If bash did not "
+            "produce an error message above, it's possible "
+            "that the ebuild has called `exit` when it "
+            "should have called `die` instead. This behavior may also "
+            "be triggered by a corrupt bash binary or a hardware "
+            "problem such as memory or cpu malfunction. If the problem is not "
+            "reproducible or it appears to occur randomly, then it is likely "
+            "to be triggered by a hardware problem. "
+            "If you suspect a hardware problem then you should "
+            "try some basic hardware diagnostics such as memtest. "
+            "Please do not report this as a bug unless it is consistently "
+            "reproducible and you are sure that your bash binary and hardware "
+            "are functioning properly."
         )
 
         self._eerror(textwrap.wrap(msg, 72))

diff --git a/lib/_emerge/AsynchronousLock.py b/lib/_emerge/AsynchronousLock.py
index 329ce6bbe..1a69d0847 100644
--- a/lib/_emerge/AsynchronousLock.py
+++ b/lib/_emerge/AsynchronousLock.py
@@ -18,7 +18,6 @@ except ImportError:
 import portage
 from portage import os
 from portage.exception import TryAgain
-from portage.localization import _
 from portage.locks import lockfile, unlockfile
 from portage.util import writemsg_level
 from _emerge.AbstractPollTask import AbstractPollTask
@@ -244,9 +243,7 @@ class _LockProcess(AbstractPollTask):
                 # this failure appropriately.
                 if not (self.cancelled or self._kill_test):
                     writemsg_level(
-                        "_LockProcess: %s\n"
-                        % _("failed to acquire lock on '%s'")
-                        % (self.path,),
+                        "_LockProcess: failed to acquire lock on '{self.path}'\n",
                         level=logging.ERROR,
                         noiselevel=-1,
                     )

diff --git a/lib/_emerge/BinpkgEnvExtractor.py b/lib/_emerge/BinpkgEnvExtractor.py
index d25a2a8a7..7ce30548a 100644
--- a/lib/_emerge/BinpkgEnvExtractor.py
+++ b/lib/_emerge/BinpkgEnvExtractor.py
@@ -31,10 +31,7 @@ class BinpkgEnvExtractor(CompositeTask):
     def _start(self):
         saved_env_path = self._get_saved_env_path()
         dest_env_path = self._get_dest_env_path()
-        shell_cmd = (
-            "${PORTAGE_BUNZIP2_COMMAND:-${PORTAGE_BZIP2_COMMAND} -d} -c -- %s > %s"
-            % (_shell_quote(saved_env_path), _shell_quote(dest_env_path))
-        )
+        shell_cmd = f"${{PORTAGE_BUNZIP2_COMMAND:-${{PORTAGE_BZIP2_COMMAND}} -d}} -c -- {_shell_quote(saved_env_path)} > {_shell_quote(dest_env_path)}"
 
         logfile = None
         if self.settings.get("PORTAGE_BACKGROUND") != "subprocess":

diff --git a/lib/_emerge/BinpkgExtractorAsync.py b/lib/_emerge/BinpkgExtractorAsync.py
index f20b7707a..be7a653f9 100644
--- a/lib/_emerge/BinpkgExtractorAsync.py
+++ b/lib/_emerge/BinpkgExtractorAsync.py
@@ -5,7 +5,6 @@ import logging
 
 from _emerge.SpawnProcess import SpawnProcess
 import portage
-from portage.localization import _
 from portage.util.compression_probe import (
     compression_probe,
     _compressors,
@@ -21,6 +20,7 @@ from portage.binpkg import get_binpkg_format
 import signal
 import subprocess
 import tarfile
+import textwrap
 
 
 class BinpkgExtractorAsync(SpawnProcess):
@@ -72,9 +72,7 @@ class BinpkgExtractorAsync(SpawnProcess):
             decomp_cmd = None
         if decomp_cmd is None:
             self.scheduler.output(
-                "!!! %s\n"
-                % _("File compression header unrecognized: %s")
-                % self.pkg_path,
+                f"!!! File compression header unrecognized: {self.pkg_path}\n",
                 log_path=self.logfile,
                 background=self.background,
                 level=logging.ERROR,
@@ -104,15 +102,9 @@ class BinpkgExtractorAsync(SpawnProcess):
             if find_binary(decompression_binary) is None:
                 missing_package = decomp.get("package")
                 self.scheduler.output(
-                    "!!! %s\n"
-                    % _(
-                        "File compression unsupported %s.\n Command was: %s.\n Maybe missing package: %s"
-                    )
-                    % (
-                        self.pkg_path,
-                        varexpand(decomp_cmd, mydict=self.env),
-                        missing_package,
-                    ),
+                    f"!!! File compression unsupported {self.pkg_path}.\n"
+                    f" Command was: {varexpand(decomp_cmd, mydict=self.env)}.\n"
+                    f" Missing package: {missing_package}\n",
                     log_path=self.logfile,
                     background=self.background,
                     level=logging.ERROR,
@@ -129,26 +121,30 @@ class BinpkgExtractorAsync(SpawnProcess):
         self.args = [
             self._shell_binary,
             "-c",
-            (
-                "cmd0=(head -c %d -- %s) cmd1=(%s) cmd2=(tar -xp %s -C %s -f -); "
-                + '"${cmd0[@]}" | "${cmd1[@]}" | "${cmd2[@]}"; '
-                + "p=(${PIPESTATUS[@]}) ; for i in {0..2}; do "
-                + "if [[ ${p[$i]} != 0 && ${p[$i]} != %d ]] ; then "
-                + 'echo command $(eval "echo \\"\'\\${cmd$i[*]}\'\\"") '
-                + "failed with status ${p[$i]} ; exit ${p[$i]} ; fi ; done; "
-                + "if [ ${p[$i]} != 0 ] ; then "
-                + 'echo command $(eval "echo \\"\'\\${cmd$i[*]}\'\\"") '
-                + "failed with status ${p[$i]} ; exit ${p[$i]} ; fi ; "
-                + "exit 0 ;"
+            textwrap.dedent(
+                f"""
+                    cmd0=(head -c {pkg_xpak.filestat.st_size - pkg_xpak.xpaksize} -- {portage._shell_quote(self.pkg_path)})
+                    cmd1=({decomp_cmd})
+                    cmd2=(tar -xp {tar_options} -C {portage._shell_quote(self.image_dir)} -f -);
+                """
+                """
+                    "${cmd0[@]}" | "${cmd1[@]}" | "${cmd2[@]}";
+                    p=(${PIPESTATUS[@]}) ; for i in {0..2}; do
+                """
+                f"""
+                    if [[ ${{p[$i]}} != 0 && ${{p[$i]}} != {128 + signal.SIGPIPE} ]] ; then
+                """
+                """
+                    echo command $(eval "echo \\"'\\${cmd$i[*]}'\\"") failed with status ${p[$i]} ;
+                    exit ${p[$i]} ; fi ; done;
+                    if [ ${p[$i]} != 0 ] ; then
+                    echo command $(eval "echo \\"'\\${cmd$i[*]}'\\"") failed with status ${p[$i]} ;
+                    exit ${p[$i]} ; fi ;
+                    exit 0 ;
+                """
             )
-            % (
-                pkg_xpak.filestat.st_size - pkg_xpak.xpaksize,
-                portage._shell_quote(self.pkg_path),
-                decomp_cmd,
-                tar_options,
-                portage._shell_quote(self.image_dir),
-                128 + signal.SIGPIPE,
-            ),
+            .replace("\n", " ")
+            .strip(),
         ]
 
         SpawnProcess._start(self)

diff --git a/lib/_emerge/BinpkgFetcher.py b/lib/_emerge/BinpkgFetcher.py
index a18bed759..10f9b6e42 100644
--- a/lib/_emerge/BinpkgFetcher.py
+++ b/lib/_emerge/BinpkgFetcher.py
@@ -244,8 +244,7 @@ class _BinpkgFetcherProcess(SpawnProcess):
             else:
                 result.set_exception(
                     AssertionError(
-                        "AsynchronousLock failed with returncode %s"
-                        % (async_lock.returncode,)
+                        f"AsynchronousLock failed with returncode {async_lock.returncode}"
                     )
                 )
 

diff --git a/lib/_emerge/BinpkgVerifier.py b/lib/_emerge/BinpkgVerifier.py
index 4923331c3..58691e68b 100644
--- a/lib/_emerge/BinpkgVerifier.py
+++ b/lib/_emerge/BinpkgVerifier.py
@@ -42,7 +42,7 @@ class BinpkgVerifier(CompositeTask):
             if e.errno not in (errno.ENOENT, errno.ESTALE):
                 raise
             self.scheduler.output(
-                ("!!! Fetching Binary failed " "for '%s'\n") % self.pkg.cpv,
+                f"!!! Fetching Binary failed for '{self.pkg.cpv}'\n",
                 log_path=self.logfile,
                 background=self.background,
             )
@@ -123,15 +123,12 @@ class BinpkgVerifier(CompositeTask):
         )
 
         self.scheduler.output(
-            (
-                "\n!!! Digest verification failed:\n"
-                "!!! %s\n"
-                "!!! Reason: Failed on %s verification\n"
-                "!!! Got: %s\n"
-                "!!! Expected: %s\n"
-                "File renamed to '%s'\n"
-            )
-            % (self._pkg_path, name, value, expected, temp_filename),
+            "\n!!! Digest verification failed:\n"
+            f"!!! {self._pkg_path}\n"
+            f"!!! Reason: Failed on {name} verification\n"
+            f"!!! Got: {value}\n"
+            f"!!! Expected: {expected}\n"
+            f"File renamed to '{temp_filename}'\n",
             log_path=self.logfile,
             background=self.background,
         )

diff --git a/lib/_emerge/EbuildMerge.py b/lib/_emerge/EbuildMerge.py
index f91beff5a..7508c4a97 100644
--- a/lib/_emerge/EbuildMerge.py
+++ b/lib/_emerge/EbuildMerge.py
@@ -75,13 +75,13 @@ class EbuildMerge(CompositeTask):
                 pkg.cpv,
             )
             logger.log(
-                (" === (%s of %s) " + "Post-Build Cleaning (%s::%s)")
-                % (pkg_count.curval, pkg_count.maxval, pkg.cpv, pkg_path),
+                f" === ({pkg_count.curval} of {pkg_count.maxval}) "
+                f"Post-Build Cleaning ({pkg.cpv}::{pkg_path})",
                 short_msg=short_msg,
             )
         logger.log(
-            " ::: completed emerge (%s of %s) %s to %s"
-            % (pkg_count.curval, pkg_count.maxval, pkg.cpv, pkg.root)
+            f" ::: completed emerge ({pkg_count.curval} of {pkg_count.maxval}) "
+            f"{pkg.cpv} to {pkg.root}"
         )
 
         self._start_exit_hook(self.returncode)

diff --git a/lib/_emerge/JobStatusDisplay.py b/lib/_emerge/JobStatusDisplay.py
index dfdd37c27..9cf3c41db 100644
--- a/lib/_emerge/JobStatusDisplay.py
+++ b/lib/_emerge/JobStatusDisplay.py
@@ -191,13 +191,11 @@ class JobStatusDisplay:
         max_avg = max(avg)
 
         if max_avg < 10:
-            digits = 2
+            return ", ".join(f"{x:.2f}" for x in avg)
         elif max_avg < 100:
-            digits = 1
+            return ", ".join(f"{x:.1f}" for x in avg)
         else:
-            digits = 0
-
-        return ", ".join(("%%.%df" % digits) % x for x in avg)
+            return ", ".join(f"{x:.0f}" for x in avg)
 
     def display(self):
         """

diff --git a/lib/_emerge/MergeListItem.py b/lib/_emerge/MergeListItem.py
index fb3a0687a..efe485c2e 100644
--- a/lib/_emerge/MergeListItem.py
+++ b/lib/_emerge/MergeListItem.py
@@ -80,8 +80,8 @@ class MergeListItem(CompositeTask):
         if not build_opts.pretend:
             self.statusMessage(msg)
             logger.log(
-                " >>> emerge (%s of %s) %s to %s"
-                % (pkg_count.curval, pkg_count.maxval, pkg.cpv, pkg.root)
+                f" >>> emerge ({pkg_count.curval} of {pkg_count.maxval}) "
+                f"{pkg.cpv} to {pkg.root}"
             )
 
         if pkg.type_name == "ebuild":

diff --git a/lib/_emerge/Package.py b/lib/_emerge/Package.py
index 13ef5cabd..873edbf81 100644
--- a/lib/_emerge/Package.py
+++ b/lib/_emerge/Package.py
@@ -19,7 +19,6 @@ from portage.dep.soname.parse import parse_soname_deps
 from portage.versions import _pkg_str, _unknown_repo
 from portage.eapi import _get_eapi_attrs
 from portage.exception import InvalidData, InvalidDependString
-from portage.localization import _
 from _emerge.Task import Task
 
 
@@ -344,11 +343,8 @@ class Package(Task):
                             continue
                         if atom.slot_operator_built:
                             e = InvalidDependString(
-                                _(
-                                    "Improper context for slot-operator "
-                                    '"built" atom syntax: %s'
-                                )
-                                % (atom.unevaluated_atom,)
+                                'Improper context for slot-operator "built" '
+                                f"atom syntax: {atom.unevaluated_atom}"
                             )
                             self._metadata_exception(k, e)
 

diff --git a/lib/_emerge/Scheduler.py b/lib/_emerge/Scheduler.py
index d2b1b5999..ece3f27f7 100644
--- a/lib/_emerge/Scheduler.py
+++ b/lib/_emerge/Scheduler.py
@@ -2218,11 +2218,11 @@ class Scheduler(PollScheduler):
                 if atom is not None:
                     if hasattr(world_set, "add"):
                         self._status_msg(
-                            ('Recording %s in "world" ' + "favorites file...") % atom
+                            f'Recording {atom} in "world" favorites file...'
                         )
                         logger.log(
-                            " === (%s of %s) Updating world file (%s)"
-                            % (pkg_count.curval, pkg_count.maxval, pkg.cpv)
+                            f" === ({pkg_count.curval} of {pkg_count.maxval}) "
+                            f"Updating world file ({pkg.cpv})"
                         )
                         world_set.add(atom)
                     else:

diff --git a/lib/_emerge/SpawnProcess.py b/lib/_emerge/SpawnProcess.py
index c00f86d0e..db812a790 100644
--- a/lib/_emerge/SpawnProcess.py
+++ b/lib/_emerge/SpawnProcess.py
@@ -11,7 +11,6 @@ from _emerge.SubProcess import SubProcess
 import portage
 from portage import os
 from portage.const import BASH_BINARY
-from portage.localization import _
 from portage.output import EOutput
 from portage.util import writemsg_level
 from portage.util._async.BuildLogger import BuildLogger
@@ -271,7 +270,7 @@ class SpawnProcess(SubProcess):
                         if e.errno == errno.EPERM:
                             # Reported with hardened kernel (bug #358211).
                             writemsg_level(
-                                "!!! kill: (%i) - Operation not permitted\n" % (p,),
+                                f"!!! kill: ({p}) - Operation not permitted\n",
                                 level=logging.ERROR,
                                 noiselevel=-1,
                             )
@@ -291,11 +290,9 @@ class SpawnProcess(SubProcess):
             if pids:
                 msg = []
                 msg.append(
-                    _("Failed to kill pid(s) in '%(cgroup)s': %(pids)s")
-                    % dict(
-                        cgroup=os.path.join(self.cgroup, "cgroup.procs"),
-                        pids=" ".join(str(pid) for pid in pids),
-                    )
+                    "Failed to kill pid(s) in "
+                    f"'{os.path.join(self.cgroup, 'cgroup.procs')}': "
+                    f"{' '.join(str(pid) for pid in pids)}"
                 )
 
                 self._elog("eerror", msg)

diff --git a/lib/_emerge/SubProcess.py b/lib/_emerge/SubProcess.py
index ba783241c..b734591d1 100644
--- a/lib/_emerge/SubProcess.py
+++ b/lib/_emerge/SubProcess.py
@@ -30,7 +30,7 @@ class SubProcess(AbstractPollTask):
                 if e.errno == errno.EPERM:
                     # Reported with hardened kernel (bug #358211).
                     writemsg_level(
-                        "!!! kill: (%i) - Operation not permitted\n" % (self.pid,),
+                        f"!!! kill: ({self.pid}) - Operation not permitted\n",
                         level=logging.ERROR,
                         noiselevel=-1,
                     )

diff --git a/lib/_emerge/Task.py b/lib/_emerge/Task.py
index e3faec087..de57d27e6 100644
--- a/lib/_emerge/Task.py
+++ b/lib/_emerge/Task.py
@@ -41,7 +41,8 @@ class Task(SlotObject):
         Emulate tuple.__repr__, but don't show 'foo' as u'foo' for unicode
         strings.
         """
-        return "(%s)" % ", ".join("'%s'" % x for x in self._hash_key)
+        strings = (f"'{x}'" for x in self._hash_key)
+        return f"({', '.join(strings)})"
 
     def __repr__(self):
         if self._hash_key is None:
@@ -49,5 +50,5 @@ class Task(SlotObject):
             return SlotObject.__repr__(self)
         return "<{} ({})>".format(
             self.__class__.__name__,
-            ", ".join("'%s'" % x for x in self._hash_key),
+            ", ".join(f"'{x}'" for x in self._hash_key),
         )

diff --git a/lib/_emerge/UserQuery.py b/lib/_emerge/UserQuery.py
index c304a82cb..73ebd3ca4 100644
--- a/lib/_emerge/UserQuery.py
+++ b/lib/_emerge/UserQuery.py
@@ -54,10 +54,7 @@ class UserQuery:
             while True:
                 try:
                     response = input(
-                        "[%s] "
-                        % "/".join(
-                            [colours[i](responses[i]) for i in range(len(responses))]
-                        )
+                        f"[{'/'.join([colours[i](responses[i]) for i in range(len(responses))])}] "
                     )
                 except UnicodeDecodeError as e:
                     response = _unicode_decode(e.object).rstrip("\n")

diff --git a/lib/_emerge/actions.py b/lib/_emerge/actions.py
index 6017579c8..0aceb2c44 100644
--- a/lib/_emerge/actions.py
+++ b/lib/_emerge/actions.py
@@ -582,9 +582,7 @@ def action_build(
             for eroot in eroots:
                 if need_write_vardb and not trees[eroot]["vartree"].dbapi.writable:
                     writemsg_level(
-                        "!!! %s\n"
-                        % _("Read-only file system: %s")
-                        % trees[eroot]["vartree"].dbapi._dbroot,
+                        f"!!! Read-only file system: {trees[eroot]['vartree'].dbapi._dbroot}\n",
                         level=logging.ERROR,
                         noiselevel=-1,
                     )
@@ -601,9 +599,7 @@ def action_build(
                     and not trees[eroot]["bintree"].dbapi.writable
                 ):
                     writemsg_level(
-                        "!!! %s\n"
-                        % _("Read-only file system: %s")
-                        % trees[eroot]["bintree"].pkgdir,
+                        f"!!! Read-only file system: {trees[eroot]['bintree'].pkgdir}\n",
                         level=logging.ERROR,
                         noiselevel=-1,
                     )
@@ -943,8 +939,7 @@ def _calc_depclean(settings, trees, ldpath_mtimes, myopts, action, args_set, spi
             # A nested set could not be resolved, so ignore nested sets.
             set_atoms[k] = root_config.sets[k].getAtoms()
             writemsg_level(
-                _("!!! The set '%s' " "contains a non-existent set named '%s'.\n")
-                % (k, e),
+                f"!!! The set '{k}' contains a non-existent set named '{e}'.\n",
                 level=logging.ERROR,
                 noiselevel=-1,
             )
@@ -967,8 +962,7 @@ def _calc_depclean(settings, trees, ldpath_mtimes, myopts, action, args_set, spi
         world_atoms = bool(root_config.setconfig.getSetAtoms("world"))
     except portage.exception.PackageSetNotFound as e:
         writemsg_level(
-            _("!!! The set '%s' " "contains a non-existent set named '%s'.\n")
-            % ("world", e),
+            f"!!! The set 'world' contains a non-existent set named '{e}'.\n",
             level=logging.ERROR,
             noiselevel=-1,
         )
@@ -1052,8 +1046,8 @@ def _calc_depclean(settings, trees, ldpath_mtimes, myopts, action, args_set, spi
             if not pkgs_for_cp or pkg not in pkgs_for_cp:
                 raise AssertionError(
                     "package expected in matches: "
-                    + "cp = %s, cpv = %s matches = %s"
-                    % (pkg.cp, pkg.cpv, [str(x) for x in pkgs_for_cp])
+                    f"cp = {pkg.cp}, cpv = {pkg.cpv}, "
+                    f"matches = {[str(x) for x in pkgs_for_cp]}"
                 )
 
             highest_version = pkgs_for_cp[-1]
@@ -1065,8 +1059,8 @@ def _calc_depclean(settings, trees, ldpath_mtimes, myopts, action, args_set, spi
             if len(pkgs_for_cp) <= 1:
                 raise AssertionError(
                     "more packages expected: "
-                    + "cp = %s, cpv = %s matches = %s"
-                    % (pkg.cp, pkg.cpv, [str(x) for x in pkgs_for_cp])
+                    f"cp = {pkg.cp}, cpv = {pkg.cpv}, "
+                    f"matches = {[str(x) for x in pkgs_for_cp]}"
                 )
 
             try:
@@ -1256,11 +1250,8 @@ def _calc_depclean(settings, trees, ldpath_mtimes, myopts, action, args_set, spi
             # atoms in separate groups.
             atoms = sorted(atoms, reverse=True, key=operator.attrgetter("package"))
             parent_strs.append(
-                "%s requires %s"
-                % (
-                    getattr(parent, "cpv", parent),
-                    ", ".join(str(atom) for atom in atoms),
-                )
+                f"{getattr(parent, 'cpv', parent)} requires "
+                f"{', '.join(str(atom) for atom in atoms)}"
             )
         parent_strs.sort()
         msg = []
@@ -1777,8 +1768,8 @@ def action_deselect(settings, trees, opts, atoms):
                     filename = "world"
 
                 writemsg_stdout(
-                    '>>> %s %s from "%s" favorites file...\n'
-                    % (action_desc, colorize("INFORM", str(atom)), filename),
+                    f">>> {action_desc} {colorize('INFORM', str(atom))} "
+                    f'from "{filename}" favorites file...\n',
                     noiselevel=-1,
                 )
 
@@ -1874,8 +1865,7 @@ def action_info(settings, trees, myopts, myfiles):
             if settings["ROOT"] != "/":
                 xinfo = f"{xinfo} for {eroot}"
             writemsg(
-                "\nemerge: there are no ebuilds to satisfy %s.\n"
-                % colorize("INFORM", xinfo),
+                f"\nemerge: there are no ebuilds to satisfy {colorize('INFORM', xinfo)}.\n",
                 noiselevel=-1,
             )
 
@@ -1897,8 +1887,7 @@ def action_info(settings, trees, myopts, myfiles):
                     )
                 elif len(matches) > 1:
                     writemsg(
-                        "\nemerge: Maybe you meant any of these: %s?\n"
-                        % (", ".join(matches),),
+                        f"\nemerge: Maybe you meant any of these: {', '.join(matches)}?\n",
                         noiselevel=-1,
                     )
                 else:
@@ -1933,14 +1922,14 @@ def action_info(settings, trees, myopts, myfiles):
 
     vm_info = get_vm_info()
     if "ram.total" in vm_info:
-        line = "%-9s %10d total" % ("KiB Mem:", vm_info["ram.total"] // 1024)
+        line = f"KiB Mem:  {vm_info['ram.total'] // 1024:10d} total"
         if "ram.free" in vm_info:
-            line += ",%10d free" % (vm_info["ram.free"] // 1024,)
+            line += f",{vm_info['ram.free'] // 1024:10d} free"
         append(line)
     if "swap.total" in vm_info:
-        line = "%-9s %10d total" % ("KiB Swap:", vm_info["swap.total"] // 1024)
+        line = f"KiB Swap: {vm_info['swap.total'] // 1024:10d} total"
         if "swap.free" in vm_info:
-            line += ",%10d free" % (vm_info["swap.free"] // 1024,)
+            line += f",{vm_info['swap.free'] // 1024:10d} free"
         append(line)
 
     for repo in repos:
@@ -2068,7 +2057,7 @@ def action_info(settings, trees, myopts, myfiles):
         try:
             x = Atom(x)
         except InvalidAtom:
-            append("%-20s %s" % (x + ":", "[NOT VALID]"))
+            append(f"{x + ':':<20s} [NOT VALID]")
         else:
             for atom in expand_new_virt(vardb, x):
                 if not atom.blocker:
@@ -2262,18 +2251,18 @@ def action_info(settings, trees, myopts, myfiles):
 
             if pkg_type == "installed":
                 append(
-                    "\n%s was built with the following:"
-                    % colorize("INFORM", str(pkg.cpv + _repo_separator + pkg.repo))
+                    f"\n{colorize('INFORM', str(pkg.cpv + _repo_separator + pkg.repo))} "
+                    "was built with the following:"
                 )
             elif pkg_type == "ebuild":
                 append(
-                    "\n%s would be built with the following:"
-                    % colorize("INFORM", str(pkg.cpv + _repo_separator + pkg.repo))
+                    f"\n{colorize('INFORM', str(pkg.cpv + _repo_separator + pkg.repo))} "
+                    "would be built with the following:"
                 )
             elif pkg_type == "binary":
                 append(
-                    "\n%s (non-installed binary) was built with the following:"
-                    % colorize("INFORM", str(pkg.cpv + _repo_separator + pkg.repo))
+                    f"\n{colorize('INFORM', str(pkg.cpv + _repo_separator + pkg.repo))} "
+                    "(non-installed binary) was built with the following:"
                 )
 
             append(f"{pkg_use_display(pkg, myopts)}")
@@ -2474,11 +2463,7 @@ def action_uninstall(settings, trees, ldpath_mtimes, opts, action, files, spinne
             else:
                 if atom.use and atom.use.conditional:
                     writemsg_level(
-                        (
-                            "\n\n!!! '%s' contains a conditional "
-                            + "which is not allowed.\n"
-                        )
-                        % (x,),
+                        f"\n\n!!! '{x}' contains a conditional which is not allowed.\n",
                         level=logging.ERROR,
                         noiselevel=-1,
                     )
@@ -2492,7 +2477,7 @@ def action_uninstall(settings, trees, ldpath_mtimes, opts, action, files, spinne
         elif x.startswith(os.sep):
             if not x.startswith(eroot):
                 writemsg_level(
-                    ("!!! '%s' does not start with" + " $EROOT.\n") % x,
+                    f"!!! '{x}' does not start with $EROOT.\n",
                     level=logging.ERROR,
                     noiselevel=-1,
                 )
@@ -2577,7 +2562,7 @@ def action_uninstall(settings, trees, ldpath_mtimes, opts, action, files, spinne
                 valid_atoms.append(portage.dep.Atom(atom))
         else:
             writemsg_level(
-                ("!!! '%s' is not claimed " + "by any package.\n") % lookup_owners[0],
+                f"!!! '{lookup_owners[0]}' is not claimed by any package.\n",
                 level=logging.WARNING,
                 noiselevel=-1,
             )
@@ -2708,8 +2693,8 @@ def adjust_config(myopts, settings):
     except ValueError as e:
         portage.writemsg(f"!!! {str(e)}\n", noiselevel=-1)
         portage.writemsg(
-            "!!! Unable to parse integer: EMERGE_WARNING_DELAY='%s'\n"
-            % settings["EMERGE_WARNING_DELAY"],
+            "!!! Unable to parse integer: "
+            f"EMERGE_WARNING_DELAY='{settings['EMERGE_WARNING_DELAY']}'\n",
             noiselevel=-1,
         )
     settings["EMERGE_WARNING_DELAY"] = str(EMERGE_WARNING_DELAY)
@@ -2740,15 +2725,15 @@ def adjust_config(myopts, settings):
         PORTAGE_DEBUG = int(settings.get("PORTAGE_DEBUG", str(PORTAGE_DEBUG)))
         if PORTAGE_DEBUG not in (0, 1):
             portage.writemsg(
-                "!!! Invalid value: PORTAGE_DEBUG='%i'\n" % PORTAGE_DEBUG, noiselevel=-1
+                f"!!! Invalid value: PORTAGE_DEBUG='{PORTAGE_DEBUG}'\n",
+                noiselevel=-1,
             )
             portage.writemsg("!!! PORTAGE_DEBUG must be either 0 or 1\n", noiselevel=-1)
             PORTAGE_DEBUG = 0
     except ValueError as e:
         portage.writemsg(f"!!! {str(e)}\n", noiselevel=-1)
         portage.writemsg(
-            "!!! Unable to parse integer: PORTAGE_DEBUG='%s'\n"
-            % settings["PORTAGE_DEBUG"],
+            f"!!! Unable to parse integer: PORTAGE_DEBUG='{settings['PORTAGE_DEBUG']}'\n",
             noiselevel=-1,
         )
         del e
@@ -2783,8 +2768,8 @@ def adjust_config(myopts, settings):
 def display_missing_pkg_set(root_config, set_name):
     msg = []
     msg.append(
-        ("emerge: There are no sets to satisfy '%s'. " + "The following sets exist:")
-        % colorize("INFORM", set_name)
+        f"emerge: There are no sets to satisfy '{colorize('INFORM', set_name)}'. "
+        "The following sets exist:"
     )
     msg.append("")
 
@@ -2806,7 +2791,14 @@ def relative_profile_path(portdir, abs_profile):
 
 
 def getportageversion(portdir, _unused, profile, chost, vardb):
-    pythonver = "python %d.%d.%d-%s-%d" % sys.version_info[:]
+    pythonver = (
+        "python"
+        f" {sys.version_info[0]}"
+        f".{sys.version_info[1]}"
+        f".{sys.version_info[2]}"
+        f"-{sys.version_info[3]}"
+        f"-{sys.version_info[4]}"
+    )
     profilever = None
     repositories = vardb.settings.repositories
     if profile:
@@ -3078,7 +3070,7 @@ def ionice(settings):
 
     if rval != os.EX_OK:
         out = portage.output.EOutput()
-        out.eerror("PORTAGE_IONICE_COMMAND returned %d" % (rval,))
+        out.eerror(f"PORTAGE_IONICE_COMMAND returned {rval}")
         out.eerror(
             "See the make.conf(5) man page for PORTAGE_IONICE_COMMAND usage instructions."
         )
@@ -3157,7 +3149,7 @@ def missing_sets_warning(root_config, missing_sets):
         missing_sets_str = ", ".join(f'"{s}"' for s in missing_sets[:-1])
         missing_sets_str += f', and "{missing_sets[-1]}"'
     elif len(missing_sets) == 2:
-        missing_sets_str = '"%s" and "%s"' % tuple(missing_sets)
+        missing_sets_str = f'"{missing_sets[0]}" and "{missing_sets[1]}"'
     else:
         missing_sets_str = f'"{missing_sets[-1]}"'
     msg = [
@@ -3171,8 +3163,8 @@ def missing_sets_warning(root_config, missing_sets):
             portage.const.EPREFIX, portage.const.GLOBAL_CONFIG_PATH.lstrip(os.sep)
         )
     msg.append(
-        "        This usually means that '%s'"
-        % (os.path.join(global_config_path, "sets/portage.conf"),)
+        "        This usually means that "
+        f"'{os.path.join(global_config_path, 'sets/portage.conf')}'"
     )
     msg.append("        is missing or corrupt.")
     msg.append("        Falling back to default world and system set configuration!!!")
@@ -3283,11 +3275,7 @@ def expand_set_arguments(myfiles, myaction, root_config):
                 set_atoms = setconfig.getSetAtoms(s)
             except portage.exception.PackageSetNotFound as e:
                 writemsg_level(
-                    (
-                        "emerge: the given set '%s' "
-                        + "contains a non-existent set named '%s'.\n"
-                    )
-                    % (s, e),
+                    f"emerge: the given set '{s}' contains a non-existent set named '{e}'.\n",
                     level=logging.ERROR,
                     noiselevel=-1,
                 )
@@ -3297,12 +3285,8 @@ def expand_set_arguments(myfiles, myaction, root_config):
                 ):
                     writemsg_level(
                         (
-                            "Use `emerge --deselect %s%s` to "
+                            f"Use `emerge --deselect {SETPREFIX}{e}` to "
                             "remove this set from world_sets.\n"
-                        )
-                        % (
-                            SETPREFIX,
-                            e,
                         ),
                         level=logging.ERROR,
                         noiselevel=-1,
@@ -3519,11 +3503,7 @@ def run_action(emerge_config):
                 problematic = "PORTAGE_BINPKG_FORMAT"
 
             writemsg_level(
-                (
-                    "emerge: %s is not set correctly. Format "
-                    + "'%s' is not supported.\n"
-                )
-                % (problematic, fmt),
+                f"emerge: {problematic} is not set correctly. Format '{fmt}' is not supported.\n",
                 level=logging.ERROR,
                 noiselevel=-1,
             )
@@ -3598,8 +3578,7 @@ def run_action(emerge_config):
         and emerge_config.args
     ):
         writemsg(
-            "emerge: unexpected argument(s) for --resume: %s\n"
-            % " ".join(emerge_config.args),
+            f"emerge: unexpected argument(s) for --resume: {' '.join(emerge_config.args)}\n",
             noiselevel=-1,
         )
         return 1
@@ -3741,7 +3720,7 @@ def run_action(emerge_config):
                     emerge_config.opts["--pretend"] = True
                     emerge_config.opts.pop("--ask")
                 else:
-                    sys.stderr.write(("emerge: %s access is required\n") % access_desc)
+                    sys.stderr.write(f"emerge: {access_desc} access is required\n")
                     if portage.data.secpass < 1 and not need_superuser:
                         portage.data.portage_group_warning()
                     return 1
@@ -3853,8 +3832,7 @@ def run_action(emerge_config):
     if emerge_config.action in ("config", "metadata", "regen", "sync"):
         if "--pretend" in emerge_config.opts:
             sys.stderr.write(
-                ("emerge: The '%s' action does " + "not support '--pretend'.\n")
-                % emerge_config.action
+                f"emerge: The '{emerge_config.action}' action does not support '--pretend'.\n"
             )
             return 1
 

diff --git a/lib/_emerge/chk_updated_cfg_files.py b/lib/_emerge/chk_updated_cfg_files.py
index a92475601..db8b6e266 100644
--- a/lib/_emerge/chk_updated_cfg_files.py
+++ b/lib/_emerge/chk_updated_cfg_files.py
@@ -22,7 +22,7 @@ def chk_updated_cfg_files(eroot, config_protect):
         )
         if not x[1]:  # it's a protected file
             writemsg_level(
-                _("config file '%s' needs updating.\n") % x[0],
+                f"config file '{x[0]}' needs updating.\n",
                 level=logging.INFO,
                 noiselevel=-1,
             )
@@ -32,13 +32,13 @@ def chk_updated_cfg_files(eroot, config_protect):
                 tail = tail[len("._cfg0000_") :]
                 fpath = os.path.join(head, tail)
                 writemsg_level(
-                    _("config file '%s' needs updating.\n") % fpath,
+                    f"config file '{fpath}' needs updating.\n",
                     level=logging.INFO,
                     noiselevel=-1,
                 )
             else:
                 writemsg_level(
-                    _("%d config files in '%s' need updating.\n") % (len(x[1]), x[0]),
+                    f"{len(x[1])} config files in '{x[0]}' need updating.\n",
                     level=logging.INFO,
                     noiselevel=-1,
                 )

diff --git a/lib/_emerge/countdown.py b/lib/_emerge/countdown.py
index 9d506c3c7..cd27e59a5 100644
--- a/lib/_emerge/countdown.py
+++ b/lib/_emerge/countdown.py
@@ -10,13 +10,13 @@ from portage.output import colorize
 def countdown(secs=5, doing="Starting"):
     if secs:
         print(
-            ">>> Waiting %s seconds before starting...\n"
+            f">>> Waiting {secs} seconds before starting...\n"
             ">>> (Control-C to abort)...\n"
-            "%s in:" % (secs, doing),
+            f"{doing} in:",
             end="",
         )
         for sec in range(secs, 0, -1):
-            sys.stdout.write(colorize("UNMERGE_WARN", " %i" % sec))
+            sys.stdout.write(colorize("UNMERGE_WARN", f" {sec}"))
             sys.stdout.flush()
             time.sleep(1)
         print()

diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py
index 412dc7b6f..2c9820da1 100644
--- a/lib/_emerge/depgraph.py
+++ b/lib/_emerge/depgraph.py
@@ -46,7 +46,6 @@ from portage.exception import (
     PackageNotFound,
     PortageException,
 )
-from portage.localization import _
 from portage.output import colorize, create_color_func, darkgreen, green
 
 bad = create_color_func("BAD")
@@ -1131,11 +1130,7 @@ class depgraph:
             return
 
         writemsg(
-            "\n%s\n\n"
-            % colorize(
-                "WARN",
-                "!!! Detected ebuild dependency change(s) without revision bump:",
-            ),
+            f"\n{colorize('WARN','!!! Detected ebuild dependency change(s) without revision bump:')}\n\n",
             noiselevel=-1,
         )
 
@@ -1411,14 +1406,13 @@ class depgraph:
 
             msg.append(indent)
             msg.append(
-                "%s %s"
-                % (
-                    pkg,
+                f"{pkg} "
+                + str(
                     pkg_use_display(
                         pkg,
                         self._frozen_config.myopts,
                         modified_use=self._pkg_use_enabled(pkg),
-                    ),
+                    )
                 )
             )
             msg.append(" conflicts with\n")
@@ -1646,8 +1640,7 @@ class depgraph:
                         noiselevel=-1,
                     )
                     writemsg_level(
-                        "      arg, non-conflict: %s, %s\n"
-                        % (is_arg_parent, is_non_conflict_parent),
+                        f"      arg, non-conflict: {is_arg_parent}, {is_non_conflict_parent}\n",
                         level=logging.DEBUG,
                         noiselevel=-1,
                     )
@@ -1906,8 +1899,8 @@ class depgraph:
             ):
                 if debug:
                     writemsg_level(
-                        "!!! backtracking loop detected: %s %s\n"
-                        % (pkg, self._dynamic_config._runtime_pkg_mask[pkg]),
+                        f"!!! backtracking loop detected: {pkg} "
+                        f"{self._dynamic_config._runtime_pkg_mask[pkg]}\n",
                         level=logging.DEBUG,
                         noiselevel=-1,
                     )
@@ -2310,8 +2303,7 @@ class depgraph:
                         "",
                         "",
                         "_slot_operator_check_reverse_dependencies:",
-                        "   candidate package does not match atom '%s': %s"
-                        % (atom, candidate_pkg),
+                        f"   candidate package does not match atom '{atom}': {candidate_pkg}",
                         f"   parent: {parent}",
                         f"   parent atoms: {' '.join(parent_atoms)}",
                         "",
@@ -2553,8 +2545,8 @@ class depgraph:
                 "slot_operator_update_probe:",
                 f"   existing child package:  {dep.child}",
                 f"   existing parent package: {dep.parent}",
-                "   new child package:  %s" % None,
-                "   new parent package: %s" % None,
+                "   new child package:  None",
+                "   new parent package: None",
                 "",
             )
             writemsg_level("\n".join(msg), noiselevel=-1, level=logging.DEBUG)
@@ -2617,8 +2609,8 @@ class depgraph:
                 "slot_operator_unsatisfied_probe:",
                 f"   existing parent package: {dep.parent}",
                 f"   existing parent atom: {dep.atom}",
-                "   new parent package: %s" % None,
-                "   new child package:  %s" % None,
+                "   new parent package: None",
+                "   new child package:  None",
                 "",
             )
             writemsg_level("\n".join(msg), noiselevel=-1, level=logging.DEBUG)
@@ -3291,16 +3283,15 @@ class depgraph:
 
         if debug:
             writemsg_level(
-                "\n%s%s %s\n"
-                % (
-                    "Child:".ljust(15),
-                    pkg,
+                f"\n{'Child:':15}{pkg} "
+                + str(
                     pkg_use_display(
                         pkg,
                         self._frozen_config.myopts,
                         modified_use=self._pkg_use_enabled(pkg),
-                    ),
-                ),
+                    )
+                )
+                + "\n",
                 level=logging.DEBUG,
                 noiselevel=-1,
             )
@@ -3323,8 +3314,7 @@ class depgraph:
                 ):
                     uneval = f" ({dep.atom.unevaluated_atom})"
                 writemsg_level(
-                    "%s%s%s required by %s\n"
-                    % ("Parent Dep:".ljust(15), dep.atom, uneval, myparent),
+                    f"{'Parent Dep:':15}{dep.atom}{uneval} required by {myparent}\n",
                     level=logging.DEBUG,
                     noiselevel=-1,
                 )
@@ -3403,16 +3393,15 @@ class depgraph:
 
                         if debug:
                             writemsg_level(
-                                "%s%s %s\n"
-                                % (
-                                    "Re-used Child:".ljust(15),
-                                    pkg,
+                                f"{'Re-used Child:':15}{pkg} "
+                                + str(
                                     pkg_use_display(
                                         pkg,
                                         self._frozen_config.myopts,
                                         modified_use=self._pkg_use_enabled(pkg),
-                                    ),
-                                ),
+                                    )
+                                )
+                                + "\n",
                                 level=logging.DEBUG,
                                 noiselevel=-1,
                             )
@@ -3429,16 +3418,15 @@ class depgraph:
                     # missing dependencies, as discussed in bug 199856.
                     if debug:
                         writemsg_level(
-                            "%s%s %s\n"
-                            % (
-                                "Replace Child:".ljust(15),
-                                pkg,
+                            f"{'Replace Child:':15}{pkg} "
+                            + str(
                                 pkg_use_display(
                                     pkg,
                                     self._frozen_config.myopts,
                                     modified_use=self._pkg_use_enabled(pkg),
-                                ),
-                            ),
+                                )
+                            )
+                            + "\n",
                             level=logging.DEBUG,
                             noiselevel=-1,
                         )
@@ -3447,16 +3435,15 @@ class depgraph:
                 else:
                     if debug:
                         writemsg_level(
-                            "%s%s %s\n"
-                            % (
-                                "Slot Conflict:".ljust(15),
-                                existing_node,
+                            f"{'Slot Conflict:':15}{existing_node} "
+                            + str(
                                 pkg_use_display(
                                     existing_node,
                                     self._frozen_config.myopts,
                                     modified_use=self._pkg_use_enabled(existing_node),
-                                ),
-                            ),
+                                )
+                            )
+                            + "\n",
                             level=logging.DEBUG,
                             noiselevel=-1,
                         )
@@ -4542,7 +4529,7 @@ class depgraph:
                     writemsg(
                         colorize(
                             "BAD",
-                            "\n{e}\n" % x,
+                            f"\n{e}\n",
                         ),
                         noiselevel=-1,
                     )
@@ -4589,16 +4576,12 @@ class depgraph:
                         break
                 else:
                     writemsg(
-                        "\n%s\n\n"
-                        % colorize(
+                        "\n"
+                        + colorize(
                             "BAD",
-                            "*** "
-                            + _(
-                                "You need to adjust PKGDIR to emerge "
-                                "this package: %s"
-                            )
-                            % x,
-                        ),
+                            f"*** You need to adjust PKGDIR to emerge this package: {x}",
+                        )
+                        + "\n\n",
                         noiselevel=-1,
                     )
                     self._dynamic_config._skip_restart = True
@@ -4611,9 +4594,9 @@ class depgraph:
                 tree_root = os.path.dirname(os.path.dirname(pkgdir))
                 cp = pkgdir[len(tree_root) + 1 :]
                 error_msg = (
-                    "\n\n!!! '%s' is not in a valid ebuild repository "
+                    f"\n\n!!! '{x}' is not in a valid ebuild repository "
                     "hierarchy or does not exist\n"
-                ) % x
+                )
                 if not portage.isvalidatom(cp):
                     writemsg(error_msg, noiselevel=-1)
                     return 0, myfavorites
@@ -4676,7 +4659,7 @@ class depgraph:
             elif x.startswith(os.path.sep):
                 if not x.startswith(eroot):
                     portage.writemsg(
-                        ("\n\n!!! '%s' does not start with" + " $EROOT.\n") % x,
+                        f"\n\n!!! '{x}' does not start with $EROOT.\n",
                         noiselevel=-1,
                     )
                     self._dynamic_config._skip_restart = True
@@ -4688,11 +4671,7 @@ class depgraph:
                 f = os.path.abspath(x)
                 if not f.startswith(eroot):
                     portage.writemsg(
-                        (
-                            "\n\n!!! '%s' (resolved from '%s') does not start with"
-                            + " $EROOT.\n"
-                        )
-                        % (f, x),
+                        f"\n\n!!! '{f}' (resolved from '{x}') does not start with $EROOT.\n",
                         noiselevel=-1,
                     )
                     self._dynamic_config._skip_restart = True
@@ -4721,11 +4700,8 @@ class depgraph:
                                 )
 
                         writemsg_level(
-                            (
-                                "emerge: the given set '%s' "
-                                "contains a non-existent set named '%s'.\n"
-                            )
-                            % (s, e),
+                            f"emerge: the given set '{s}' contains a non-existent set named "
+                            f"'{e}'.\n",
                             level=logging.ERROR,
                             noiselevel=-1,
                         )
@@ -4734,14 +4710,8 @@ class depgraph:
                             and SETPREFIX + e.value in sets["selected"]
                         ):
                             writemsg_level(
-                                (
-                                    "Use `emerge --deselect %s%s` to "
-                                    "remove this set from world_sets.\n"
-                                )
-                                % (
-                                    SETPREFIX,
-                                    e,
-                                ),
+                                f"Use `emerge --deselect {SETPREFIX}{e}` to remove this set from "
+                                "world_sets.\n",
                                 level=logging.ERROR,
                                 noiselevel=-1,
                             )
@@ -4835,11 +4805,7 @@ class depgraph:
 
                 if atom.use and atom.use.conditional:
                     writemsg(
-                        (
-                            "\n\n!!! '%s' contains a conditional "
-                            + "which is not allowed.\n"
-                        )
-                        % (x,),
+                        f"\n\n!!! '{x}' contains a conditional which is not allowed.\n",
                         noiselevel=-1,
                     )
                     writemsg("!!! Please check ebuild(5) for full details.\n")
@@ -4867,8 +4833,7 @@ class depgraph:
 
             if not owners:
                 portage.writemsg(
-                    ("\n\n!!! '%s' is not claimed " + "by any package.\n")
-                    % lookup_owners[0],
+                    f"\n\n!!! '{lookup_owners[0]}' is not claimed by any package.\n",
                     noiselevel=-1,
                 )
                 self._dynamic_config._skip_restart = True
@@ -5001,11 +4966,7 @@ class depgraph:
                         ):
                             if not self.need_restart():
                                 writemsg(
-                                    (
-                                        "\n\n!!! Problem "
-                                        + "resolving dependencies for %s\n"
-                                    )
-                                    % arg.arg,
+                                    f"\n\n!!! Problem resolving dependencies for {arg.arg}\n",
                                     noiselevel=-1,
                                 )
                             return 0, myfavorites
@@ -5117,17 +5078,13 @@ class depgraph:
                             pass
                         elif isinstance(arg, SetArg):
                             writemsg(
-                                (
-                                    "\n\n!!! Problem resolving "
-                                    + "dependencies for %s from %s\n"
-                                )
-                                % (atom, arg.arg),
+                                f"\n\n!!! Problem resolving dependencies for {atom} from "
+                                f"{arg.arg}\n",
                                 noiselevel=-1,
                             )
                         else:
                             writemsg(
-                                ("\n\n!!! Problem resolving " + "dependencies for %s\n")
-                                % (atom,),
+                                f"\n\n!!! Problem resolving dependencies for {atom}\n",
                                 noiselevel=-1,
                             )
                         return 0, myfavorites
@@ -6209,8 +6166,8 @@ class depgraph:
                     ):
                         required_use_warning = (
                             ", this change violates use flag constraints "
-                            + "defined by %s: '%s'"
-                            % (pkg.cpv, human_readable_required_use(required_use))
+                            f"defined by {pkg.cpv}: "
+                            f"'{human_readable_required_use(required_use)}'"
                         )
 
                 if need_enable or need_disable:
@@ -6280,11 +6237,8 @@ class depgraph:
                         ):
                             required_use_warning = (
                                 ", this change violates use flag constraints "
-                                + "defined by %s: '%s'"
-                                % (
-                                    myparent.cpv,
-                                    human_readable_required_use(required_use),
-                                )
+                                f"defined by {myparent.cpv}: "
+                                f"'{human_readable_required_use(required_use)}'"
                             )
 
                     target_use = {}
@@ -6467,10 +6421,10 @@ class depgraph:
                 writemsg("\n", noiselevel=-1)
                 msg = (
                     "The current version of portage supports "
-                    + "EAPI '%s'. You must upgrade to a newer version"
-                    + " of portage before EAPI masked packages can"
-                    + " be installed."
-                ) % portage.const.EAPI
+                    f"EAPI '{portage.const.EAPI}'. You must upgrade to a newer version"
+                    " of portage before EAPI masked packages can"
+                    " be installed."
+                )
                 writemsg("\n".join(textwrap.wrap(msg, 75)), noiselevel=-1)
             writemsg("\n", noiselevel=-1)
             mask_docs = True
@@ -6481,17 +6435,16 @@ class depgraph:
                     cp_exists = True
                     break
 
-            writemsg(
-                "\nemerge: there are no %s to satisfy "
-                % (
-                    "binary packages"
-                    if self._frozen_config.myopts.get("--usepkgonly", "y") == True
-                    else "ebuilds"
+            if self._frozen_config.myopts.get("--usepkgonly", "y"):
+                writemsg(
+                    f"\nemerge: there are no binary packages to satisfy {green(xinfo)}.\n",
+                    noiselevel=-1,
+                )
+            else:
+                writemsg(
+                    f"\nemerge: there are no ebuilds to satisfy {green(xinfo)}.\n",
+                    noiselevel=-1,
                 )
-                + green(xinfo)
-                + ".\n",
-                noiselevel=-1,
-            )
             if (
                 isinstance(myparent, AtomArg)
                 and not cp_exists
@@ -6518,8 +6471,7 @@ class depgraph:
                     )
                 elif len(matches) > 1:
                     writemsg(
-                        "\nemerge: Maybe you meant any of these: %s?\n"
-                        % (", ".join(matches),),
+                        f"\nemerge: Maybe you meant any of these: {', '.join(matches)}?\n",
                         noiselevel=-1,
                     )
                 else:
@@ -6533,8 +6485,7 @@ class depgraph:
             dep_chain = self._get_dep_chain(myparent, atom)
             for node, node_type in dep_chain:
                 msg.append(
-                    '(dependency required by "%s" [%s])'
-                    % (colorize("INFORM", "%s" % (node)), node_type)
+                    f'(dependency required by "{colorize("INFORM", str(node))}" [{node_type}])'
                 )
 
         if msg:
@@ -7750,13 +7701,7 @@ class depgraph:
         if "--debug" in self._frozen_config.myopts:
             for pkg in matched_packages:
                 portage.writemsg(
-                    "%s %s%s%s\n"
-                    % (
-                        (pkg.type_name + ":").rjust(10),
-                        pkg.cpv,
-                        _repo_separator,
-                        pkg.repo,
-                    ),
+                    f"{pkg.type_name + ':':>10} {pkg.cpv}{_repo_separator}{pkg.repo}\n",
                     noiselevel=-1,
                 )
 
@@ -8962,8 +8907,7 @@ class depgraph:
             except portage.exception.InvalidDependString as e:
                 portage.writemsg(
                     "!!! Invalid RDEPEND in "
-                    + "'%svar/db/pkg/%s/RDEPEND': %s\n"
-                    % (running_root, running_portage.cpv, e),
+                    f"'{running_root}var/db/pkg/{running_portage.cpv}/RDEPEND': {e}\n",
                     noiselevel=-1,
                 )
                 del e
@@ -9247,8 +9191,7 @@ class depgraph:
 
                     if debug:
                         writemsg(
-                            "\nruntime cycle digraph (%s nodes):\n\n"
-                            % (len(selected_nodes),),
+                            f"\nruntime cycle digraph ({len(selected_nodes)} nodes):\n\n",
                             noiselevel=-1,
                         )
                         cycle_digraph.debug_print()
@@ -9695,8 +9638,9 @@ class depgraph:
                 for node in retlist:
                     if isinstance(node, Package) and node.operation == "uninstall":
                         msg.append(f"\t{node}")
+                temp_joined = "".join(f"{line}\n" for line in msg)
                 writemsg_level(
-                    "\n%s\n" % "".join("%s\n" % line for line in msg),
+                    f"\n{temp_joined}\n",
                     level=logging.DEBUG,
                     noiselevel=-1,
                 )
@@ -9912,8 +9856,8 @@ class depgraph:
                             # issues with conditional use-flags missing
                             # from IUSE.
                             msg.append(
-                                "%s (%s) required by %s %s"
-                                % (atom.unevaluated_atom, atom, parent, use_display)
+                                f"{atom.unevaluated_atom} ({atom}) "
+                                f"required by {parent} {use_display}"
                             )
                         else:
                             msg.append(f"{atom} required by {parent} {use_display}")
@@ -10247,8 +10191,7 @@ class depgraph:
             for (abs_user_config, f), path in file_to_write_to.items():
                 if path is None:
                     problems.append(
-                        "!!! No file to write for '%s'\n"
-                        % os.path.join(abs_user_config, f)
+                        f"!!! No file to write for '{os.path.join(abs_user_config, f)}'\n"
                     )
 
             write_to_file = not problems
@@ -10272,11 +10215,8 @@ class depgraph:
 
             def _writemsg(reason, file):
                 writemsg(
-                    (
-                        "\nThe following %s are necessary to proceed:\n"
-                        ' (see "%s" in the portage(5) man page for more details)\n'
-                    )
-                    % (colorize("BAD", reason), file),
+                    f"\nThe following {colorize('BAD', reason)} are necessary to proceed:\n"
+                    f' (see "{file}" in the portage(5) man page for more details)\n',
                     noiselevel=-1,
                 )
 
@@ -10674,8 +10614,7 @@ class depgraph:
                     noiselevel=-1,
                 )
                 writemsg(
-                    "!!! see '%s'\n\n"
-                    % os.path.join(x.root, portage.VDB_PATH, x.cpv, "PROVIDE"),
+                    f"!!! see '{os.path.join(x.root, portage.VDB_PATH, x.cpv, 'PROVIDE')}'\n\n",
                     noiselevel=-1,
                 )
                 del e
@@ -10718,8 +10657,8 @@ class depgraph:
                     else:
                         filename = "world"
                     writemsg_stdout(
-                        '>>> Recording %s in "%s" favorites file...\n'
-                        % (colorize("INFORM", str(a)), filename),
+                        f">>> Recording {colorize('INFORM', str(a))} "
+                        f'in "{filename}" favorites file...\n',
                         noiselevel=-1,
                     )
                 world_set.update(all_added)
@@ -11762,10 +11701,7 @@ def show_masked_packages(masked_packages):
             l_path = portdb.findLicensePath(l)
             if l_path is None:
                 continue
-            msg = ("A copy of the '%s' license" + " is located at '%s'.\n\n") % (
-                l,
-                l_path,
-            )
+            msg = f"A copy of the '{l}' license is located at '{l_path}'.\n\n"
             writemsg(msg, noiselevel=-1)
             shown_licenses.add(l)
     return have_eapi_mask

diff --git a/lib/_emerge/resolver/output.py b/lib/_emerge/resolver/output.py
index 4d4626c33..831076c8a 100644
--- a/lib/_emerge/resolver/output.py
+++ b/lib/_emerge/resolver/output.py
@@ -112,8 +112,7 @@ class Display:
         if self.resolved != blocker.atom:
             addl += colorize(
                 self.blocker_style,
-                ' ("%s" is %s %s)'
-                % (str(blocker.atom).lstrip("!"), blocking_desc, block_parents),
+                f' ("{str(blocker.atom).lstrip("!")}" is {blocking_desc} {block_parents})',
             )
         else:
             addl += colorize(

diff --git a/lib/_emerge/resolver/output_helpers.py b/lib/_emerge/resolver/output_helpers.py
index fb9a030ca..3669f3b6c 100644
--- a/lib/_emerge/resolver/output_helpers.py
+++ b/lib/_emerge/resolver/output_helpers.py
@@ -150,8 +150,9 @@ class _PackageCounters:
                 myoutput.append("s")
         if self.restrict_fetch_satisfied < self.restrict_fetch:
             myoutput.append(
-                bad(" (%s unsatisfied)")
-                % (self.restrict_fetch - self.restrict_fetch_satisfied)
+                bad(
+                    f" ({self.restrict_fetch - self.restrict_fetch_satisfied} unsatisfied)"
+                )
             )
         if self.blocks > 0:
             myoutput.append(f"\nConflict: {self.blocks} block")
@@ -159,7 +160,7 @@ class _PackageCounters:
                 myoutput.append("s")
             if self.blocks_satisfied < self.blocks:
                 myoutput.append(
-                    bad(" (%s unsatisfied)") % (self.blocks - self.blocks_satisfied)
+                    bad(f" ({self.blocks - self.blocks_satisfied} unsatisfied)")
                 )
             else:
                 myoutput.append(" (all satisfied)")
@@ -205,8 +206,7 @@ class _DisplayConfig:
             except ValueError as e:
                 writemsg(f"!!! {str(e)}\n", noiselevel=-1)
                 writemsg(
-                    "!!! Unable to parse COLUMNWIDTH='%s'\n"
-                    % frozen_config.settings["COLUMNWIDTH"],
+                    f"!!! Unable to parse COLUMNWIDTH='{frozen_config.settings['COLUMNWIDTH']}'\n",
                     noiselevel=-1,
                 )
                 del e

diff --git a/lib/_emerge/resolver/slot_collision.py b/lib/_emerge/resolver/slot_collision.py
index 4ccd756b7..7e579f394 100644
--- a/lib/_emerge/resolver/slot_collision.py
+++ b/lib/_emerge/resolver/slot_collision.py
@@ -266,14 +266,13 @@ class slot_conflict_handler:
             for pkg in pkgs:
                 msg.append(indent)
                 msg.append(
-                    "%s %s"
-                    % (
-                        pkg,
+                    f"{pkg} "
+                    + str(
                         pkg_use_display(
                             pkg,
                             self.depgraph._frozen_config.myopts,
                             modified_use=self.depgraph._pkg_use_enabled(pkg),
-                        ),
+                        )
                     )
                 )
                 parent_atoms = self.all_parents.get(pkg)
@@ -368,19 +367,12 @@ class slot_conflict_handler:
                                         msg = (
                                             "\n\n!!! BUG: Detected "
                                             "USE dep match inconsistency:\n"
-                                            "\tppkg: %s\n"
-                                            "\tviolated_atom: %s\n"
-                                            "\tatom: %s unevaluated: %s\n"
-                                            "\tother_pkg: %s IUSE: %s USE: %s\n"
-                                            % (
-                                                ppkg,
-                                                violated_atom,
-                                                atom,
-                                                atom.unevaluated_atom,
-                                                other_pkg,
-                                                sorted(other_pkg.iuse.all),
-                                                sorted(_pkg_use_enabled(other_pkg)),
-                                            )
+                                            f"\tppkg: {ppkg}\n"
+                                            f"\tviolated_atom: {violated_atom}\n"
+                                            f"\tatom: {atom} unevaluated: {atom.unevaluated_atom}\n"
+                                            f"\tother_pkg: {other_pkg} "
+                                            f"IUSE: {sorted(other_pkg.iuse.all)} "
+                                            f"USE: {sorted(_pkg_use_enabled(other_pkg))}\n"
                                         )
                                         writemsg(msg, noiselevel=-2)
                                         raise AssertionError(
@@ -703,13 +695,11 @@ class slot_conflict_handler:
                         msg.append(2 * indent)
                         if len(selected_for_display) > 1:
                             msg.append(
-                                "(and %d more with the same problems)\n"
-                                % omitted_parents
+                                f"(and {omitted_parents} more with the same problems)\n"
                             )
                         else:
                             msg.append(
-                                "(and %d more with the same problem)\n"
-                                % omitted_parents
+                                f"(and {omitted_parents} more with the same problem)\n"
                             )
                 else:
                     msg.append(" (no parents)\n")
@@ -824,11 +814,7 @@ class slot_conflict_handler:
                     ):
                         if self.debug:
                             writemsg(
-                                (
-                                    "%s has pending USE changes. "
-                                    "Rejecting configuration.\n"
-                                )
-                                % (pkg,),
+                                f"{pkg} has pending USE changes. Rejecting configuration.\n",
                                 noiselevel=-1,
                             )
                         return False
@@ -857,11 +843,8 @@ class slot_conflict_handler:
                     # Version range does not match.
                     if self.debug:
                         writemsg(
-                            (
-                                "%s does not satify all version "
-                                "requirements. Rejecting configuration.\n"
-                            )
-                            % (pkg,),
+                            f"{pkg} does not satify all version "
+                            "requirements. Rejecting configuration.\n",
                             noiselevel=-1,
                         )
                     return False
@@ -871,11 +854,7 @@ class slot_conflict_handler:
                     # FIXME: This needs to support use dep defaults.
                     if self.debug:
                         writemsg(
-                            (
-                                "%s misses needed flags from IUSE."
-                                " Rejecting configuration.\n"
-                            )
-                            % (pkg,),
+                            f"{pkg} misses needed flags from IUSE. Rejecting configuration.\n",
                             noiselevel=-1,
                         )
                     return False
@@ -909,11 +888,8 @@ class slot_conflict_handler:
                     # part of the conflict, isn't it?)
                     if self.debug:
                         writemsg(
-                            (
-                                "%s: installed package would need USE"
-                                " changes. Rejecting configuration.\n"
-                            )
-                            % (pkg,),
+                            f"{pkg}: installed package would need USE changes. "
+                            "Rejecting configuration.\n",
                             noiselevel=-1,
                         )
                     return False
@@ -1185,11 +1161,8 @@ class slot_conflict_handler:
                     is_valid_solution = False
                     if self.debug:
                         writemsg(
-                            (
-                                "new conflict introduced: %s"
-                                " does not match %s from %s\n"
-                            )
-                            % (pkg, new_atom, ppkg),
+                            f"new conflict introduced: {pkg} does not match "
+                            f"{new_atom} from {ppkg}\n",
                             noiselevel=-1,
                         )
                     break

diff --git a/lib/_emerge/search.py b/lib/_emerge/search.py
index eace589c2..e422434a7 100644
--- a/lib/_emerge/search.py
+++ b/lib/_emerge/search.py
@@ -502,8 +502,7 @@ class search:
                 if self.verbose:
                     if available:
                         msg.append(
-                            "      %s %s\n"
-                            % (darkgreen("Latest version available:"), myversion)
+                            f"      {darkgreen('Latest version available:')} {myversion}\n"
                         )
                     msg.append(
                         f"      {self.getInstallationStatus(mycat + '/' + mypkg)}\n"

diff --git a/lib/_emerge/unmerge.py b/lib/_emerge/unmerge.py
index e8fabb85f..398674c57 100644
--- a/lib/_emerge/unmerge.py
+++ b/lib/_emerge/unmerge.py
@@ -8,7 +8,6 @@ import textwrap
 import portage
 from portage import os
 from portage.dbapi._expand_new_virt import expand_new_virt
-from portage.localization import _
 from portage.output import bold, colorize, darkgreen, green
 from portage._sets import SETPREFIX
 from portage._sets.base import EditablePackageSet
@@ -228,8 +227,7 @@ def _unmerge_display(
                 mymatch = vartree.dep_match(x)
             if not mymatch:
                 portage.writemsg(
-                    "\n--- Couldn't find '%s' to %s.\n"
-                    % (x.replace("null/", ""), unmerge_action),
+                    f"\n--- Couldn't find '{x.replace('null/', '')}' to {unmerge_action}.\n",
                     noiselevel=-1,
                 )
                 continue
@@ -369,17 +367,17 @@ def _unmerge_display(
                 skip_pkg = False
                 if portage.match_from_list(portage.const.PORTAGE_PACKAGE_ATOM, [pkg]):
                     msg = (
-                        "Not unmerging package %s "
+                        f"Not unmerging package {pkg.cpv} "
                         "since there is no valid reason for Portage to "
-                        "%s itself."
-                    ) % (pkg.cpv, unmerge_action)
+                        f"{unmerge_action} itself."
+                    )
                     skip_pkg = True
                 elif vartree.dbapi._dblink(cpv).isowner(portage._python_interpreter):
                     msg = (
-                        "Not unmerging package %s since there is no valid "
-                        "reason for Portage to %s currently used Python "
+                        f"Not unmerging package {pkg.cpv} since there is no valid "
+                        f"reason for Portage to {unmerge_action} currently used Python "
                         "interpreter."
-                    ) % (pkg.cpv, unmerge_action)
+                    )
                     skip_pkg = True
                 if skip_pkg:
                     for line in textwrap.wrap(msg, 75):
@@ -404,12 +402,8 @@ def _unmerge_display(
                     unknown_sets.add(s)
                     out = portage.output.EOutput()
                     out.eerror(
-                        ("Unknown set '@%s' in %s%s")
-                        % (
-                            s,
-                            root_config.settings["EROOT"],
-                            portage.const.WORLD_SETS_FILE,
-                        )
+                        f"Unknown set '@{s}' in "
+                        f"{root_config.settings['EROOT']}{portage.const.WORLD_SETS_FILE}"
                     )
                     continue
 
@@ -555,7 +549,7 @@ def _unmerge_display(
             writemsg_level("\n", noiselevel=-1)
 
     writemsg_level(
-        "\nAll selected packages: %s\n" % " ".join("=%s" % x for x in all_selected),
+        f"\nAll selected packages: {' '.join(f'={x}' for x in all_selected)}\n",
         noiselevel=-1,
     )
 
@@ -632,7 +626,7 @@ def unmerge(
 
     if not vartree.dbapi.writable:
         writemsg_level(
-            "!!! %s\n" % _("Read-only file system: %s") % vartree.dbapi._dbroot,
+            f"!!! Read-only file system: {vartree.dbapi._dbroot}\n",
             level=logging.ERROR,
             noiselevel=-1,
         )


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-04-30 23:30 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-04-30 23:30 [gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/_emerge/resolver/ Sam James
  -- strict thread matches above, loose matches on Subject: below --
2019-12-15  6:48 Zac Medico

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox