commit:     1a2c70dd32ab335b38fa6da8a625ff47a3467dfa
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Mon Aug  7 00:29:39 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Mon Aug  7 00:32:33 2023 +0000
URL:        https://gitweb.gentoo.org/proj/gentoolkit.git/commit/?id=1a2c70dd

Run `pyupgrade --py39-plus`

Signed-off-by: Sam James <sam <AT> gentoo.org>

 .github/workflows/ci.yml                   |  4 ----
 bin/epkginfo                               |  2 +-
 bin/eshowkw                                |  1 -
 bin/merge-driver-ekeyword                  | 11 +++++-----
 pym/gentoolkit/atom.py                     |  8 +++----
 pym/gentoolkit/base.py                     | 26 +++++++++++-----------
 pym/gentoolkit/cpv.py                      | 10 ++++-----
 pym/gentoolkit/dependencies.py             |  4 ++--
 pym/gentoolkit/eclean/clean.py             |  8 +++----
 pym/gentoolkit/eclean/cli.py               | 24 ++++++++------------
 pym/gentoolkit/eclean/exclude.py           |  3 +--
 pym/gentoolkit/eclean/search.py            |  4 ++--
 pym/gentoolkit/ekeyword/ekeyword.py        | 16 +++++++-------
 pym/gentoolkit/enalyze/__init__.py         |  2 +-
 pym/gentoolkit/enalyze/analyze.py          |  6 ++---
 pym/gentoolkit/enalyze/output.py           |  2 +-
 pym/gentoolkit/enalyze/rebuild.py          | 14 +++++-------
 pym/gentoolkit/equery/__init__.py          | 30 ++++++++++++-------------
 pym/gentoolkit/equery/depgraph.py          |  2 +-
 pym/gentoolkit/equery/has.py               |  2 +-
 pym/gentoolkit/equery/keywords.py          |  1 -
 pym/gentoolkit/equery/list_.py             |  2 +-
 pym/gentoolkit/equery/meta.py              | 24 ++++++++++----------
 pym/gentoolkit/equery/size.py              |  2 +-
 pym/gentoolkit/equery/uses.py              | 18 +++++++--------
 pym/gentoolkit/errors.py                   |  2 +-
 pym/gentoolkit/eshowkw/__init__.py         | 11 ++++------
 pym/gentoolkit/eshowkw/display_pretty.py   |  3 +--
 pym/gentoolkit/eshowkw/keywords_content.py | 15 ++++++-------
 pym/gentoolkit/eshowkw/keywords_header.py  |  1 -
 pym/gentoolkit/flag.py                     |  2 +-
 pym/gentoolkit/formatters.py               |  2 +-
 pym/gentoolkit/helpers.py                  |  6 ++---
 pym/gentoolkit/imlate/imlate.py            | 20 ++++++++---------
 pym/gentoolkit/keyword.py                  |  4 ++--
 pym/gentoolkit/module_base.py              |  2 +-
 pym/gentoolkit/package.py                  | 12 +++++-----
 pym/gentoolkit/pprinter.py                 |  2 +-
 pym/gentoolkit/profile.py                  |  6 ++---
 pym/gentoolkit/query.py                    | 10 ++++-----
 pym/gentoolkit/revdep_rebuild/analyse.py   |  3 +--
 pym/gentoolkit/revdep_rebuild/assign.py    | 23 ++++++++------------
 pym/gentoolkit/revdep_rebuild/cache.py     | 14 +++++-------
 pym/gentoolkit/revdep_rebuild/collect.py   | 35 ++++++++++++------------------
 pym/gentoolkit/revdep_rebuild/rebuild.py   |  1 -
 pym/gentoolkit/revdep_rebuild/runner.py    |  2 --
 pym/gentoolkit/sets.py                     |  2 +-
 pym/gentoolkit/test/eclean/creator.py      |  2 +-
 pym/gentoolkit/test/eclean/distsupport.py  |  2 +-
 pym/gentoolkit/test/eclean/test_search.py  | 10 +++++----
 pym/gentoolkit/test/test_atom.py           | 12 +++++-----
 pym/gentoolkit/versionmatch.py             | 10 ++++-----
 setup.py                                   |  4 ++--
 53 files changed, 200 insertions(+), 244 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 509f82e..36a636a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -9,14 +9,10 @@ jobs:
     strategy:
       matrix:
         python-version:
-        - '3.7'
-        - '3.8'
         - '3.9'
         - '3.10'
         - '3.11'
         - '3.12-dev'
-        - 'pypy-3.7'
-        - 'pypy-3.8'
         - 'pypy-3.9'
 
     env:

diff --git a/bin/epkginfo b/bin/epkginfo
index 4cb483e..29c4c4d 100755
--- a/bin/epkginfo
+++ b/bin/epkginfo
@@ -28,7 +28,7 @@ def print_epkginfo_help():
 
 equery.initialize_configuration()
 args = sys.argv[1:]
-if not args or set(('-h', '--help')).intersection(args):
+if not args or {'-h', '--help'}.intersection(args):
     print_epkginfo_help()
 else:
     try:

diff --git a/bin/eshowkw b/bin/eshowkw
index 0ef4dda..d32ba6c 100755
--- a/bin/eshowkw
+++ b/bin/eshowkw
@@ -1,5 +1,4 @@
 #!/usr/bin/python
-#      vim:fileencoding=utf-8
 # Copyright 2010 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 

diff --git a/bin/merge-driver-ekeyword b/bin/merge-driver-ekeyword
index 73e0430..f75056c 100755
--- a/bin/merge-driver-ekeyword
+++ b/bin/merge-driver-ekeyword
@@ -14,15 +14,16 @@ import os
 import sys
 import tempfile
 
-from typing import List, Optional, Sequence, Tuple
+from typing import List, Optional, Tuple
+from collections.abc import Sequence
 
 from gentoolkit.ekeyword import ekeyword
 
 
-KeywordChanges = List[Tuple[Optional[List[str]], Optional[List[str]]]]
+KeywordChanges = list[tuple[Optional[list[str]], Optional[list[str]]]]
 
 
-def keyword_array(keyword_line: str) -> List[str]:
+def keyword_array(keyword_line: str) -> list[str]:
     # Find indices of string inside the double-quotes
     i1: int = keyword_line.find('"') + 1
     i2: int = keyword_line.rfind('"')
@@ -32,8 +33,8 @@ def keyword_array(keyword_line: str) -> List[str]:
 
 
 def keyword_line_changes(old: str, new: str) -> KeywordChanges:
-    a: List[str] = keyword_array(old)
-    b: List[str] = keyword_array(new)
+    a: list[str] = keyword_array(old)
+    b: list[str] = keyword_array(new)
 
     s = difflib.SequenceMatcher(a=a, b=b)
 

diff --git a/pym/gentoolkit/atom.py b/pym/gentoolkit/atom.py
index dd843d7..27cf77c 100644
--- a/pym/gentoolkit/atom.py
+++ b/pym/gentoolkit/atom.py
@@ -167,21 +167,21 @@ class Atom(portage.dep.Atom, CPV):
     def __le__(self, other):
         if not isinstance(other, self.__class__):
             raise TypeError(
-                "other isn't of %s type, is %s" % (self.__class__, 
other.__class__)
+                f"other isn't of {self.__class__} type, is {other.__class__}"
             )
         return self < other or self == other
 
     def __ge__(self, other):
         if not isinstance(other, self.__class__):
             raise TypeError(
-                "other isn't of %s type, is %s" % (self.__class__, 
other.__class__)
+                f"other isn't of {self.__class__} type, is {other.__class__}"
             )
         return self > other or self == other
 
     def __repr__(self):
         uc = self.use_conditional
         uc = "%s? " % uc if uc is not None else ""
-        return "<%s %r>" % (self.__class__.__name__, "%s%s" % (uc, self.atom))
+        return "<{} {!r}>".format(self.__class__.__name__, f"{uc}{self.atom}")
 
     def __setattr__(self, name, value):
         object.__setattr__(self, name, value)
@@ -336,7 +336,7 @@ class Atom(portage.dep.Atom, CPV):
         """Returns a string representation of the original dep"""
         uc = self.use_conditional
         uc = "%s? " % uc if uc is not None else ""
-        return "%s%s" % (uc, self.atom)
+        return f"{uc}{self.atom}"
 
 
 # vim: set ts=4 sw=4 tw=79:

diff --git a/pym/gentoolkit/base.py b/pym/gentoolkit/base.py
index 230e040..4dcbfa1 100644
--- a/pym/gentoolkit/base.py
+++ b/pym/gentoolkit/base.py
@@ -58,13 +58,13 @@ def split_arguments(args):
 
 def main_usage(module_info):
     """Return the main usage message for analyse"""
-    return "%(usage)s %(product)s [%(g_opts)s] %(mod_name)s [%(mod_opts)s]" % {
-        "usage": pp.emph("Usage:"),
-        "product": pp.productname(module_info["__productname__"]),
-        "g_opts": pp.globaloption("global-options"),
-        "mod_name": pp.command("module-name"),
-        "mod_opts": pp.localoption("module-options"),
-    }
+    return "{usage} {product} [{g_opts}] {mod_name} [{mod_opts}]".format(
+        usage=pp.emph("Usage:"),
+        product=pp.productname(module_info["__productname__"]),
+        g_opts=pp.globaloption("global-options"),
+        mod_name=pp.command("module-name"),
+        mod_opts=pp.localoption("module-options"),
+    )
 
 
 def print_version(module_info):
@@ -145,9 +145,9 @@ def mod_usage(mod_name="module", arg="pkgspec", 
optional=False):
     @param optional: is the argument optional?
     """
 
-    return "%(usage)s: %(mod_name)s [%(opts)s] %(arg)s" % {
-        "usage": pp.emph("Usage"),
-        "mod_name": pp.command(mod_name),
-        "opts": pp.localoption("options"),
-        "arg": ("[%s]" % pp.emph(arg)) if optional else pp.emph(arg),
-    }
+    return "{usage}: {mod_name} [{opts}] {arg}".format(
+        usage=pp.emph("Usage"),
+        mod_name=pp.command(mod_name),
+        opts=pp.localoption("options"),
+        arg=("[%s]" % pp.emph(arg)) if optional else pp.emph(arg),
+    )

diff --git a/pym/gentoolkit/cpv.py b/pym/gentoolkit/cpv.py
index 6b2a533..c58243e 100644
--- a/pym/gentoolkit/cpv.py
+++ b/pym/gentoolkit/cpv.py
@@ -124,7 +124,7 @@ class CPV:
     def __lt__(self, other):
         if not isinstance(other, self.__class__):
             raise TypeError(
-                "other isn't of %s type, is %s" % (self.__class__, 
other.__class__)
+                f"other isn't of {self.__class__} type, is {other.__class__}"
             )
 
         if self.category != other.category:
@@ -140,26 +140,26 @@ class CPV:
     def __gt__(self, other):
         if not isinstance(other, self.__class__):
             raise TypeError(
-                "other isn't of %s type, is %s" % (self.__class__, 
other.__class__)
+                f"other isn't of {self.__class__} type, is {other.__class__}"
             )
         return not self <= other
 
     def __le__(self, other):
         if not isinstance(other, self.__class__):
             raise TypeError(
-                "other isn't of %s type, is %s" % (self.__class__, 
other.__class__)
+                f"other isn't of {self.__class__} type, is {other.__class__}"
             )
         return self < other or self == other
 
     def __ge__(self, other):
         if not isinstance(other, self.__class__):
             raise TypeError(
-                "other isn't of %s type, is %s" % (self.__class__, 
other.__class__)
+                f"other isn't of {self.__class__} type, is {other.__class__}"
             )
         return self > other or self == other
 
     def __repr__(self):
-        return "<%s %r>" % (self.__class__.__name__, str(self))
+        return f"<{self.__class__.__name__} {str(self)!r}>"
 
     def __str__(self):
         return self.cpv

diff --git a/pym/gentoolkit/dependencies.py b/pym/gentoolkit/dependencies.py
index cff2080..8dd4867 100644
--- a/pym/gentoolkit/dependencies.py
+++ b/pym/gentoolkit/dependencies.py
@@ -43,7 +43,7 @@ class Dependencies(Query):
     def __init__(self, query, parser=None):
         Query.__init__(self, query)
         self.use = []
-        self.depatom = str()
+        self.depatom = ""
 
         # Allow a custom parser function:
         self.parser = parser if parser else self._parser
@@ -61,7 +61,7 @@ class Dependencies(Query):
         return hash((self.atom, self.depatom, tuple(self.use)))
 
     def __repr__(self):
-        return "<%s %r>" % (self.__class__.__name__, self.atom)
+        return f"<{self.__class__.__name__} {self.atom!r}>"
 
     def environment(self, envvars):
         """Returns predefined env vars DEPEND, SRC_URI, etc."""

diff --git a/pym/gentoolkit/eclean/clean.py b/pym/gentoolkit/eclean/clean.py
index 37a042a..87d7aac 100644
--- a/pym/gentoolkit/eclean/clean.py
+++ b/pym/gentoolkit/eclean/clean.py
@@ -98,7 +98,7 @@ class CleanUp:
                 statinfo = os.stat(file_)
                 if statinfo.st_nlink == 1:
                     key_size += statinfo.st_size
-            except EnvironmentError as er:
+            except OSError as er:
                 print(pp.error("Could not get stat info for:" + file_), 
file=sys.stderr)
                 print(pp.error("Error: %s" % str(er)), file=sys.stderr)
         return key_size
@@ -111,7 +111,7 @@ class CleanUp:
             # ...get its statinfo
             try:
                 statinfo = os.stat(file_)
-            except EnvironmentError as er:
+            except OSError as er:
                 if not os.path.exists(os.readlink(file_)):
                     try:
                         os.remove(file_)
@@ -120,7 +120,7 @@ class CleanUp:
                             file=sys.stderr,
                         )
                         break
-                    except EnvironmentError as er:
+                    except OSError as er:
                         print(
                             pp.error("Error deleting broken symbolic link " + 
file_),
                             file=sys.stderr,
@@ -144,7 +144,7 @@ class CleanUp:
                             os.rmdir(os.path.dirname(file_))
                         except OSError:
                             pass
-                except EnvironmentError as er:
+                except OSError as er:
                     print(pp.error("Could not delete " + file_), 
file=sys.stderr)
                     print(pp.error("Error: %s" % str(er)), file=sys.stderr)
         return clean_size

diff --git a/pym/gentoolkit/eclean/cli.py b/pym/gentoolkit/eclean/cli.py
index 4902354..fa94a55 100644
--- a/pym/gentoolkit/eclean/cli.py
+++ b/pym/gentoolkit/eclean/cli.py
@@ -40,9 +40,9 @@ from gentoolkit.eprefix import EPREFIX
 
 def printVersion():
     """Output the version info."""
-    print("%s (%s) - %s" % (__productname__, __version__, __description__))
+    print(f"{__productname__} ({__version__}) - {__description__}")
     print()
-    print("Author: %s <%s>" % (__author__, __email__))
+    print(f"Author: {__author__} <{__email__}>")
     print("Copyright 2003-2023 Gentoo Authors")
     print("Distributed under the terms of the GNU General Public License v2")
 
@@ -586,13 +586,9 @@ def doAction(action, options, exclude={}, output=None):
     if saved and not options["quiet"]:
         print()
         print(
-            (
-                pp.emph("   The following ")
-                + yellow("unavailable")
-                + pp.emph(
-                    " files were saved from cleaning due to exclusion file 
entries"
-                )
-            )
+            pp.emph("   The following ")
+            + yellow("unavailable")
+            + pp.emph(" files were saved from cleaning due to exclusion file 
entries")
         )
         output.set_colors("deprecated")
         clean_size = cleaner.pretend_clean(saved)
@@ -600,11 +596,9 @@ def doAction(action, options, exclude={}, output=None):
     if deprecated and not options["quiet"]:
         print()
         print(
-            (
-                pp.emph("   The following ")
-                + yellow("unavailable")
-                + pp.emph(" installed packages were found")
-            )
+            pp.emph("   The following ")
+            + yellow("unavailable")
+            + pp.emph(" installed packages were found")
         )
         output.set_colors("deprecated")
         output.list_pkgs(deprecated)
@@ -646,7 +640,7 @@ def main():
     # parse the exclusion file
     if not "exclude-file" in options:
         # set it to the default exclude file if it exists
-        exclude_file = "%s/etc/%s/%s.exclude" % (EPREFIX, __productname__, 
action)
+        exclude_file = f"{EPREFIX}/etc/{__productname__}/{action}.exclude"
         if os.path.isfile(exclude_file):
             options["exclude-file"] = exclude_file
     if "exclude-file" in options:

diff --git a/pym/gentoolkit/eclean/exclude.py b/pym/gentoolkit/eclean/exclude.py
index a5c29d4..c731ec0 100644
--- a/pym/gentoolkit/eclean/exclude.py
+++ b/pym/gentoolkit/eclean/exclude.py
@@ -80,10 +80,9 @@ def parseExcludeFile(filepath, output):
     try:
         file_ = open(
             _unicode_encode(filepath, encoding=_encodings["fs"]),
-            mode="r",
             encoding=_encodings["content"],
         )
-    except IOError:
+    except OSError:
         raise ParseExcludeFileException("Could not open exclusion file: " + 
filepath)
     filecontents = file_.readlines()
     file_.close()

diff --git a/pym/gentoolkit/eclean/search.py b/pym/gentoolkit/eclean/search.py
index 60ced02..3288208 100644
--- a/pym/gentoolkit/eclean/search.py
+++ b/pym/gentoolkit/eclean/search.py
@@ -188,7 +188,7 @@ class DistfilesSearch:
             filepath = os.path.join(_distdir, file)
             try:
                 file_stat = os.lstat(filepath)
-            except EnvironmentError:
+            except OSError:
                 continue
             is_dirty = False
             # for check, check_name in checks:
@@ -547,7 +547,7 @@ def findPackages(
     try:
         test = os.listdir(pkgdir)
         del test
-    except EnvironmentError as er:
+    except OSError as er:
         if options["ignore-failure"]:
             exit(0)
         print(pp.error("Error accessing PKGDIR."), file=sys.stderr)

diff --git a/pym/gentoolkit/ekeyword/ekeyword.py 
b/pym/gentoolkit/ekeyword/ekeyword.py
index 70f44ea..0eaca78 100755
--- a/pym/gentoolkit/ekeyword/ekeyword.py
+++ b/pym/gentoolkit/ekeyword/ekeyword.py
@@ -175,7 +175,7 @@ def process_keywords(keywords, ops, arch_status=None):
         if oarch == "all":
             if arch_status is None:
                 raise ValueError('unable to process "all" w/out profiles.desc')
-            old_arches = set([keyword_to_arch(a) for a in new_keywords])
+            old_arches = {keyword_to_arch(a) for a in new_keywords}
             if op is None:
                 # Process just stable keywords.
                 arches = [
@@ -219,12 +219,12 @@ def process_keywords(keywords, ops, arch_status=None):
 
         # Finally do the actual update of the keywords list.
         for arch in arches:
-            new_keywords -= set(["%s%s" % (x, arch) for x in ("", "~", "-")])
+            new_keywords -= {f"{x}{arch}" for x in ("", "~", "-")}
 
             if op is None:
                 new_keywords.add(arch)
             elif op in ("~", "-"):
-                new_keywords.add("%s%s" % (op, arch))
+                new_keywords.add(f"{op}{arch}")
             elif op == "^":
                 # Already deleted.  Whee.
                 pass
@@ -243,7 +243,7 @@ def process_content(
         disp_name = ebuild
 
         def logit(msg):
-            print("%s: %s" % (disp_name, msg))
+            print(f"{disp_name}: {msg}")
 
     elif quiet > 1:
 
@@ -255,7 +255,7 @@ def process_content(
         disp_name, _, _ = os.path.basename(ebuild).partition(".ebuild")
 
         def logit(msg):
-            print("%s: %s" % (disp_name, msg))
+            print(f"{disp_name}: {msg}")
 
     # Match any KEYWORDS= entry that isn't commented out.
     keywords_re = re.compile(r'^([^#]*\bKEYWORDS=)([\'"])(.*)(\2)(.*)')
@@ -297,7 +297,7 @@ def process_content(
                 old_keywords = sort_keywords(old_keywords)
 
             new_keywords = sort_keywords(new_keywords)
-            line = '%s"%s"%s\n' % (m.group(1), " ".join(new_keywords), 
m.group(5))
+            line = '{}"{}"{}\n'.format(m.group(1), " ".join(new_keywords), 
m.group(5))
             if style in ("color-inline", "inline"):
                 logit(diff_keywords(old_keywords, new_keywords, style=style))
             else:
@@ -359,7 +359,7 @@ def process_ebuild(
     Returns:
       Whether any updates were processed
     """
-    with io.open(ebuild, encoding="utf8") as f:
+    with open(ebuild, encoding="utf8") as f:
         updated, content = process_content(
             ebuild,
             f,
@@ -370,7 +370,7 @@ def process_ebuild(
             style=style,
         )
         if updated and not dry_run:
-            with io.open(ebuild, "w", encoding="utf8") as f:
+            with open(ebuild, "w", encoding="utf8") as f:
                 f.writelines(content)
             if manifest:
                 subprocess.check_call(["ebuild", ebuild, "manifest"])

diff --git a/pym/gentoolkit/enalyze/__init__.py 
b/pym/gentoolkit/enalyze/__init__.py
index f884dcf..1f099ac 100644
--- a/pym/gentoolkit/enalyze/__init__.py
+++ b/pym/gentoolkit/enalyze/__init__.py
@@ -110,7 +110,7 @@ def main():
         loaded_module.main(module_args)
     except portage.exception.AmbiguousPackageName as err:
         raise errors.GentoolkitAmbiguousPackage(err.args[0])
-    except IOError as err:
+    except OSError as err:
         if err.errno != errno.EPIPE:
             raise
 

diff --git a/pym/gentoolkit/enalyze/analyze.py 
b/pym/gentoolkit/enalyze/analyze.py
index 553ba5e..c64465d 100644
--- a/pym/gentoolkit/enalyze/analyze.py
+++ b/pym/gentoolkit/enalyze/analyze.py
@@ -435,10 +435,8 @@ class Analyse(ModuleBase):
             if self.analyser.mismatched:
                 print("_________________________________________________")
                 print(
-                    (
-                        "The following packages were found to have a \n"
-                        + "different recorded ARCH than the current system 
ARCH"
-                    )
+                    "The following packages were found to have a \n"
+                    + "different recorded ARCH than the current system ARCH"
                 )
                 for cpv in self.analyser.mismatched:
                     print("\t", pp.cpv(cpv))

diff --git a/pym/gentoolkit/enalyze/output.py b/pym/gentoolkit/enalyze/output.py
index 1778304..b9d937e 100644
--- a/pym/gentoolkit/enalyze/output.py
+++ b/pym/gentoolkit/enalyze/output.py
@@ -22,7 +22,7 @@ def nl(lines=1):
     @param lines: optional number of blank lines to print
             default = 1
     """
-    print(("\n" * lines))
+    print("\n" * lines)
 
 
 class AnalysisPrinter(CpvValueWrapper):

diff --git a/pym/gentoolkit/enalyze/rebuild.py 
b/pym/gentoolkit/enalyze/rebuild.py
index e3396f3..074e2f5 100644
--- a/pym/gentoolkit/enalyze/rebuild.py
+++ b/pym/gentoolkit/enalyze/rebuild.py
@@ -247,11 +247,9 @@ class Rebuild(ModuleBase):
         if self.options["verbose"]:
             print()
             print(
-                (
-                    pp.emph("  -- Found ")
-                    + pp.number(str(pkg_count))
-                    + pp.emph(" packages that need entries")
-                )
+                pp.emph("  -- Found ")
+                + pp.number(str(pkg_count))
+                + pp.emph(" packages that need entries")
             )
             # print pp.emph("     package.use to maintain their current 
setting")
         pkg_keys = []
@@ -364,10 +362,8 @@ class Rebuild(ModuleBase):
             if self.analyser.mismatched:
                 print("_________________________________________________")
                 print(
-                    (
-                        "The following packages were found to have a \n"
-                        + "different recorded ARCH than the current system 
ARCH"
-                    )
+                    "The following packages were found to have a \n"
+                    + "different recorded ARCH than the current system ARCH"
                 )
                 for cpv in self.analyser.mismatched:
                     print("\t", pp.cpv(cpv))

diff --git a/pym/gentoolkit/equery/__init__.py 
b/pym/gentoolkit/equery/__init__.py
index a83d31a..15a9b6a 100644
--- a/pym/gentoolkit/equery/__init__.py
+++ b/pym/gentoolkit/equery/__init__.py
@@ -183,7 +183,7 @@ def format_filetype(path, fdesc, show_type=False, 
show_md5=False, show_timestamp
         ftype = "fifo"
         fpath = path
     else:
-        sys.stderr.write(pp.error("%s has unknown type: %s" % (path, 
fdesc[0])))
+        sys.stderr.write(pp.error(f"{path} has unknown type: {fdesc[0]}"))
 
     result = ""
     if show_type:
@@ -235,13 +235,13 @@ def initialize_configuration():
 def main_usage():
     """Return the main usage message for equery"""
 
-    return "%(usage)s %(product)s [%(g_opts)s] %(mod_name)s [%(mod_opts)s]" % {
-        "usage": pp.emph("Usage:"),
-        "product": pp.productname(__productname__),
-        "g_opts": pp.globaloption("global-options"),
-        "mod_name": pp.command("module-name"),
-        "mod_opts": pp.localoption("module-options"),
-    }
+    return "{usage} {product} [{g_opts}] {mod_name} [{mod_opts}]".format(
+        usage=pp.emph("Usage:"),
+        product=pp.productname(__productname__),
+        g_opts=pp.globaloption("global-options"),
+        mod_name=pp.command("module-name"),
+        mod_opts=pp.localoption("module-options"),
+    )
 
 
 def mod_usage(mod_name="module", arg="pkgspec", optional=False):
@@ -253,12 +253,12 @@ def mod_usage(mod_name="module", arg="pkgspec", 
optional=False):
     @param optional: is the argument optional?
     """
 
-    return "%(usage)s: %(mod_name)s [%(opts)s] %(arg)s" % {
-        "usage": pp.emph("Usage"),
-        "mod_name": pp.command(mod_name),
-        "opts": pp.localoption("options"),
-        "arg": ("[%s]" % pp.emph(arg)) if optional else pp.emph(arg),
-    }
+    return "{usage}: {mod_name} [{opts}] {arg}".format(
+        usage=pp.emph("Usage"),
+        mod_name=pp.command(mod_name),
+        opts=pp.localoption("options"),
+        arg=("[%s]" % pp.emph(arg)) if optional else pp.emph(arg),
+    )
 
 
 def parse_global_options(global_opts, args):
@@ -361,7 +361,7 @@ def main(argv):
         loaded_module.main(module_args)
     except portage.exception.AmbiguousPackageName as err:
         raise errors.GentoolkitAmbiguousPackage(err.args[0])
-    except IOError as err:
+    except OSError as err:
         if err.errno != errno.EPIPE:
             raise
 

diff --git a/pym/gentoolkit/equery/depgraph.py 
b/pym/gentoolkit/equery/depgraph.py
index d9e3901..4d38bda 100644
--- a/pym/gentoolkit/equery/depgraph.py
+++ b/pym/gentoolkit/equery/depgraph.py
@@ -140,7 +140,7 @@ def depgraph_printer(
             if dep.operator == "=*":
                 atom += " (=%s*)" % dep.cpv
             else:
-                atom += " (%s%s)" % (dep.operator, dep.cpv)
+                atom += f" ({dep.operator}{dep.cpv})"
         if not no_use and dep is not None and dep.use:
             use = " [%s]" % " ".join(
                 pp.useflag(x, enabled=True) for x in dep.use.tokens

diff --git a/pym/gentoolkit/equery/has.py b/pym/gentoolkit/equery/has.py
index bc98097..ca30ae2 100644
--- a/pym/gentoolkit/equery/has.py
+++ b/pym/gentoolkit/equery/has.py
@@ -77,7 +77,7 @@ def query_in_env(query, env_var, pkg):
 
     try:
         if env_var in ("USE", "IUSE", "CFLAGS", "CXXFLAGS", "LDFLAGS"):
-            results = set([x.lstrip("+-") for x in 
pkg.environment(env_var).split()])
+            results = {x.lstrip("+-") for x in 
pkg.environment(env_var).split()}
         else:
             results = set(pkg.environment(env_var).split())
     except errors.GentoolkitFatalError:

diff --git a/pym/gentoolkit/equery/keywords.py 
b/pym/gentoolkit/equery/keywords.py
index dbe5133..142a5f6 100644
--- a/pym/gentoolkit/equery/keywords.py
+++ b/pym/gentoolkit/equery/keywords.py
@@ -1,4 +1,3 @@
-#      vim:fileencoding=utf-8
 # Copyright 2010 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 

diff --git a/pym/gentoolkit/equery/list_.py b/pym/gentoolkit/equery/list_.py
index 237e7fe..23a902c 100644
--- a/pym/gentoolkit/equery/list_.py
+++ b/pym/gentoolkit/equery/list_.py
@@ -111,7 +111,7 @@ def get_binpkgs_missing(matches):
 
     result = []
     binary_packages = set(get_bintree_cpvs())
-    matched_packages = set(x.cpv for x in matches)
+    matched_packages = {x.cpv for x in matches}
     missing_binary_packages = set(matched_packages.difference(binary_packages))
 
     for pkg in matches:

diff --git a/pym/gentoolkit/equery/meta.py b/pym/gentoolkit/equery/meta.py
index 22e9ad8..02b6f67 100644
--- a/pym/gentoolkit/equery/meta.py
+++ b/pym/gentoolkit/equery/meta.py
@@ -108,7 +108,7 @@ def stablereq(matches):
     for pkg in matches:
         keywords_str = pkg.environment(("KEYWORDS"), prefer_vdb=False)
         # get any unstable keywords
-        keywords = set([x.lstrip("~") for x in keywords_str.split() if "~" in 
x])
+        keywords = {x.lstrip("~") for x in keywords_str.split() if "~" in x}
         stable_arches = set(list(STABLEREQ_arches))
         cc_keywords = stable_arches.intersection(keywords)
         # add cc's
@@ -165,9 +165,9 @@ def format_maintainers(maints):
     for maint in maints:
         maintstr = maint.email or ""
         if CONFIG["verbose"]:
-            maintstr += " (%s)" % (maint.name,) if maint.name else ""
-            maintstr += " - %s" % (maint.restrict,) if maint.restrict else ""
-            maintstr += " - %s" % (maint.description,) if maint.description 
else ""
+            maintstr += f" ({maint.name})" if maint.name else ""
+            maintstr += f" - {maint.restrict}" if maint.restrict else ""
+            maintstr += f" - {maint.description}" if maint.description else ""
         result.append(maintstr)
 
     return result
@@ -183,7 +183,7 @@ def format_upstream(upstream):
             doc_lang = doc[1]
             docstr = doc_location
             if doc_lang is not None:
-                docstr += " (%s)" % (doc_lang,)
+                docstr += f" ({doc_lang})"
             result.append(docstr)
         return result
 
@@ -192,7 +192,7 @@ def format_upstream(upstream):
         for id_ in ids:
             site = id_[0]
             proj_id = id_[1]
-            idstr = "%s ID: %s" % (site, proj_id)
+            idstr = f"{site} ID: {proj_id}"
             result.append(idstr)
         return result
 
@@ -255,10 +255,10 @@ def format_keywords_line(pkg, fmtd_keywords, slot, 
verstr_len):
     """Format the entire keywords line for display."""
 
     ver = pkg.fullversion
-    result = "%s:%s: %s" % (ver, pp.slot(slot), fmtd_keywords)
+    result = f"{ver}:{pp.slot(slot)}: {fmtd_keywords}"
     if CONFIG["verbose"] and fmtd_keywords:
         result = format_line(
-            fmtd_keywords, "%s:%s: " % (ver, pp.slot(slot)), " " * (verstr_len 
+ 2)
+            fmtd_keywords, f"{ver}:{pp.slot(slot)}: ", " " * (verstr_len + 2)
         )
 
     return result
@@ -266,7 +266,7 @@ def format_keywords_line(pkg, fmtd_keywords, slot, 
verstr_len):
 
 def format_stablereq_line(pkg, fmtd_ccs, slot):
     """Format the entire stablereq line for display (no indented 
linewrapping)"""
-    return "%s:%s: %s" % (pkg.fullversion, pp.slot(slot), fmtd_ccs)
+    return f"{pkg.fullversion}:{pp.slot(slot)}: {fmtd_ccs}"
 
 
 def format_homepage(homepage):
@@ -282,7 +282,7 @@ def call_format_functions(best_match, matches):
 
     if CONFIG["verbose"]:
         repo = best_match.repo_name()
-        pp.uprint(" * %s [%s]" % (pp.cpv(best_match.cp), pp.section(repo)))
+        pp.uprint(f" * {pp.cpv(best_match.cp)} [{pp.section(repo)}]")
 
     got_opts = False
     if any(QUERY_OPTS.values()):
@@ -532,9 +532,7 @@ def main(input_args):
 
         if best_match.metadata is None:
             print(
-                pp.warn(
-                    "Package {0} is missing " 
"metadata.xml".format(best_match.cpv)
-                ),
+                pp.warn("Package {} is missing " 
"metadata.xml".format(best_match.cpv)),
                 file=sys.stderr,
             )
             continue

diff --git a/pym/gentoolkit/equery/size.py b/pym/gentoolkit/equery/size.py
index 068e701..994417a 100644
--- a/pym/gentoolkit/equery/size.py
+++ b/pym/gentoolkit/equery/size.py
@@ -87,7 +87,7 @@ def display_size(match_set):
             print("Total files : %s".rjust(25) % pp.number(str(files)))
 
             if uncounted:
-                print(("Inaccessible files : %s".rjust(25) % 
pp.number(str(uncounted))))
+                print("Inaccessible files : %s".rjust(25) % 
pp.number(str(uncounted)))
 
             if QUERY_OPTS["size_in_bytes"]:
                 size_str = pp.number(str(size))

diff --git a/pym/gentoolkit/equery/uses.py b/pym/gentoolkit/equery/uses.py
index eeea356..bcc3d09 100644
--- a/pym/gentoolkit/equery/uses.py
+++ b/pym/gentoolkit/equery/uses.py
@@ -98,11 +98,11 @@ def display_useflags(output):
         if CONFIG["verbose"]:
             flag_name = ""
             if in_makeconf != in_installed:
-                flag_name += pp.emph(
-                    " %s %s" % (markers[in_makeconf], markers[in_installed])
-                )
+                flag_name += pp.emph(f" {markers[in_makeconf]} 
{markers[in_installed]}")
             else:
-                flag_name += " %s %s" % (markers[in_makeconf], 
markers[in_installed])
+                flag_name += " {} {}".format(
+                    markers[in_makeconf], markers[in_installed]
+                )
 
             flag_name += " " + color[in_makeconf % 2](flag.ljust(maxflag_len))
             flag_name += " : "
@@ -114,7 +114,7 @@ def display_useflags(output):
 
             # print description
             if restrict:
-                restrict = "(%s %s)" % (pp.emph("Restricted to"), 
pp.cpv(restrict))
+                restrict = "({} {})".format(pp.emph("Restricted to"), 
pp.cpv(restrict))
                 twrap.initial_indent = flag_name
                 pp.uprint(twrap.fill(restrict))
                 if desc:
@@ -161,7 +161,7 @@ def get_global_useflags():
                 fields = line.split(" - ", 1)
                 if len(fields) == 2:
                     global_usedesc[fields[0]] = fields[1].rstrip()
-    except IOError:
+    except OSError:
         sys.stderr.write(
             pp.warn("Could not load USE flag descriptions from %s" % 
pp.path(path))
         )
@@ -179,12 +179,12 @@ def get_global_useflags():
                         continue
                     fields = [field.strip() for field in line.split(" - ", 1)]
                     if len(fields) == 2:
-                        expanded_useflag = "%s_%s" % (
+                        expanded_useflag = "{}_{}".format(
                             path.split("/")[-1][0:-5],
                             fields[0],
                         )
                         global_usedesc[expanded_useflag] = fields[1]
-        except IOError:
+        except OSError:
             sys.stderr.write(
                 pp.warn("Could not load USE flag descriptions from %s" % path)
             )
@@ -343,7 +343,7 @@ def main(input_args):
                     if not legend_printed:
                         print_legend()
                         legend_printed = True
-                    print((" * Found these USE flags for %s:" % 
pp.cpv(str(pkg.cpv))))
+                    print(" * Found these USE flags for %s:" % 
pp.cpv(str(pkg.cpv)))
                     print(pp.emph(" U I"))
                 display_useflags(output)
             else:

diff --git a/pym/gentoolkit/errors.py b/pym/gentoolkit/errors.py
index ffb79e0..c3bcdd4 100644
--- a/pym/gentoolkit/errors.py
+++ b/pym/gentoolkit/errors.py
@@ -142,7 +142,7 @@ class GentoolkitNoMatches(GentoolkitException):
 
     def __str__(self):
         inst = "installed " if self.in_installed else ""
-        return "No %spackages matching '%s'" % (inst, self.query)
+        return f"No {inst}packages matching '{self.query}'"
 
 
 class GentoolkitUnknownKeyword(GentoolkitException):

diff --git a/pym/gentoolkit/eshowkw/__init__.py 
b/pym/gentoolkit/eshowkw/__init__.py
index 4bef14e..1aa6982 100644
--- a/pym/gentoolkit/eshowkw/__init__.py
+++ b/pym/gentoolkit/eshowkw/__init__.py
@@ -1,4 +1,3 @@
-#      vim:fileencoding=utf-8
 # Copyright 2010-2016 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
@@ -35,7 +34,7 @@ def process_display(package, keywords, dbapi):
         )
         # -1 : space is taken in account and appended by us
         filler = "".ljust(portdata.slot_length - 1)
-        header = ["%s%s%s" % (x, filler, y) for x, y in zip(header, extra)]
+        header = [f"{x}{filler}{y}" for x, y in zip(header, extra)]
         content = portdata.content
         header_length = portdata.version_length
         content_length = keywords.length
@@ -172,7 +171,7 @@ def main(argv, indirect=False):
         if len(ebuilds) <= 0:
             msg_err = 'No ebuilds at "%s"' % currdir
             raise SystemExit(msg_err)
-        package = "%s/%s" % (
+        package = "{}/{}".format(
             os.path.basename(os.path.abspath("../")),
             os.path.basename(currdir),
         )
@@ -192,13 +191,11 @@ def main(argv, indirect=False):
             for repo in ports.repositories:
                 repos[repo.name] = repo.location
 
-            with open(os.path.join(ourtree, "profiles", "repo_name"), "rt") as 
f:
+            with open(os.path.join(ourtree, "profiles", "repo_name")) as f:
                 repo_name = f.readline().strip()
 
             repos[repo_name] = ourtree
-            repos = "".join(
-                "[{}]\nlocation={}\n".format(k, v) for k, v in repos.items()
-            )
+            repos = "".join(f"[{k}]\nlocation={v}\n" for k, v in repos.items())
             mysettings = portc(local_config=False, 
env={"PORTAGE_REPOSITORIES": repos})
             dbapi = portdbapi(mysettings=mysettings)
         # specify that we want just our nice tree we are in cwd

diff --git a/pym/gentoolkit/eshowkw/display_pretty.py 
b/pym/gentoolkit/eshowkw/display_pretty.py
index 9a769f9..74f5698 100644
--- a/pym/gentoolkit/eshowkw/display_pretty.py
+++ b/pym/gentoolkit/eshowkw/display_pretty.py
@@ -1,4 +1,3 @@
-#   vim:fileencoding=utf-8
 # Copyright 2010 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
@@ -31,7 +30,7 @@ def display(
     if toplist != "archlist":
         corner_image.extend(plain_list)
     data_printout = [
-        "%s%s" % (x, y)
+        f"{x}{y}"
         for x, y in zip_longest(corner_image, rotated_list, 
fillvalue=corner_image[0])
     ]
     if toplist == "archlist":

diff --git a/pym/gentoolkit/eshowkw/keywords_content.py 
b/pym/gentoolkit/eshowkw/keywords_content.py
index d70be72..5a5685a 100644
--- a/pym/gentoolkit/eshowkw/keywords_content.py
+++ b/pym/gentoolkit/eshowkw/keywords_content.py
@@ -1,4 +1,3 @@
-#      vim:fileencoding=utf-8
 # Copyright 2010 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
@@ -131,13 +130,13 @@ class keywords_content:
                 suffix = "%s " % suffix
 
             if mask and install:
-                pv = "[M][I]%s%s" % (pv, suffix)
+                pv = f"[M][I]{pv}{suffix}"
             elif mask:
-                pv = "[M]%s%s" % (pv, suffix)
+                pv = f"[M]{pv}{suffix}"
             elif install:
-                pv = "[I]%s%s" % (pv, suffix)
+                pv = f"[I]{pv}{suffix}"
             else:
-                pv = "%s%s" % (pv, suffix)
+                pv = f"{pv}{suffix}"
             return pv
 
         def __getMaskStatus(self, cpv):
@@ -155,7 +154,7 @@ class keywords_content:
 
         def __getInstallStatus(self, cpv, repo):
             """Check if package version we test is installed."""
-            return bool(self.vartree.match("=%s::%s" % (cpv, repo)))
+            return bool(self.vartree.match(f"={cpv}::{repo}"))
 
         def __init__(self, packages):
             """Query all relevant data for version data formatting"""
@@ -187,7 +186,7 @@ class keywords_content:
         except port.exception.AmbiguousPackageName as Arg:
             msg_err = 'Ambiguous package name "%s".\n' % package
             found = "Possibilities: %s" % Arg
-            raise SystemExit("%s%s" % (msg_err, found))
+            raise SystemExit(f"{msg_err}{found}")
         except port.exception.InvalidAtom:
             msg_err = 'No such package "%s"' % package
             raise SystemExit(msg_err)
@@ -397,7 +396,7 @@ class keywords_content:
         slt = self.__formatAdditional(self.slots, "bold", self.slot_length)
         rep = self.__formatAdditional(self.repositories, "yellow", 
repositories_length)
         # those + numbers are spaces in printout. keywords are multiplied also 
because of that
-        linesep = "%s+%s+%s+%s" % (
+        linesep = "{}+{}+{}+{}".format(
             "".ljust(self.version_length + 1, "-"),
             "".ljust(self.keyword_length * 2 + 1, "-"),
             "".ljust(redundant_length + self.slot_length + 1 + 4, "-"),

diff --git a/pym/gentoolkit/eshowkw/keywords_header.py 
b/pym/gentoolkit/eshowkw/keywords_header.py
index 5ca892e..cbbfc40 100644
--- a/pym/gentoolkit/eshowkw/keywords_header.py
+++ b/pym/gentoolkit/eshowkw/keywords_header.py
@@ -1,4 +1,3 @@
-#      vim:fileencoding=utf-8
 # Copyright 2001-2018 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 

diff --git a/pym/gentoolkit/flag.py b/pym/gentoolkit/flag.py
index 478eb6d..f2bed6f 100644
--- a/pym/gentoolkit/flag.py
+++ b/pym/gentoolkit/flag.py
@@ -118,7 +118,7 @@ def filter_flags(use, use_expand_hidden, usemasked, 
useforced):
     """
     # clean out some environment flags, since they will most probably
     # be confusing for the user
-    use = dict((reduce_flag(flag), flag) for flag in use)
+    use = {reduce_flag(flag): flag for flag in use}
     for f in use_expand_hidden:
         f = f.lower() + "_"
         for x in list(use):

diff --git a/pym/gentoolkit/formatters.py b/pym/gentoolkit/formatters.py
index 84c66ee..af8271d 100644
--- a/pym/gentoolkit/formatters.py
+++ b/pym/gentoolkit/formatters.py
@@ -73,7 +73,7 @@ def format_filetype(path, fdesc, show_type=False, 
show_md5=False, show_timestamp
         ftype = "dev"
         fpath = path
     else:
-        sys.stderr.write(pp.error("%s has unknown type: %s" % (path, 
fdesc[0])))
+        sys.stderr.write(pp.error(f"{path} has unknown type: {fdesc[0]}"))
     result = ""
     if show_type:
         result += "%4s " % ftype

diff --git a/pym/gentoolkit/helpers.py b/pym/gentoolkit/helpers.py
index 72c5d13..c883ad3 100644
--- a/pym/gentoolkit/helpers.py
+++ b/pym/gentoolkit/helpers.py
@@ -268,8 +268,7 @@ def get_installed_cpvs(predicate=None):
         if predicate(x)
     )
 
-    for cpv in installed_cpvs:
-        yield cpv
+    yield from installed_cpvs
 
 
 def get_bintree_cpvs(predicate=None):
@@ -295,8 +294,7 @@ def get_bintree_cpvs(predicate=None):
         if predicate(x)
     )
 
-    for cpv in installed_cpvs:
-        yield cpv
+    yield from installed_cpvs
 
 
 def print_file(path):

diff --git a/pym/gentoolkit/imlate/imlate.py b/pym/gentoolkit/imlate/imlate.py
index d8c9fe0..1db322a 100755
--- a/pym/gentoolkit/imlate/imlate.py
+++ b/pym/gentoolkit/imlate/imlate.py
@@ -65,7 +65,7 @@ def _add_ent(imlate, cat, pkg, ver, our_ver):
 
 def _fill(width, line, fill=" "):
     while len(line) < width:
-        line = "%s%s" % (str(line), str(fill))
+        line = f"{str(line)}{str(fill)}"
     return line
 
 
@@ -78,13 +78,13 @@ def show_result(conf, pkgs):
     col2 = -1
     for cat in pkgs:
         for pkg in pkgs[cat]:
-            col1 = max(col1, len(("%s/%s" % (cat, pkg))))
+            col1 = max(col1, len(f"{cat}/{pkg}"))
             col2 = max(col2, len(pkgs[cat][pkg][1]))
     col1 += 1
     col2 += 1
 
     _header = "%s candidates for 'gentoo' on '%s'"
-    _helper = "%s%s%s" % (
+    _helper = "{}{}{}".format(
         _fill(col1, "category/package[:SLOT])"),
         _fill(col2, "our version"),
         "best version",
@@ -125,7 +125,7 @@ def show_result(conf, pkgs):
             print(
                 "%s%s%s"
                 % (
-                    _fill(col1, ("%s/%s" % (cat, pkg))),
+                    _fill(col1, (f"{cat}/{pkg}")),
                     _fill(col2, pkgs[cat][pkg][1]),
                     pkgs[cat][pkg][0],
                 ),
@@ -240,7 +240,7 @@ def get_packages(conf):
                     _pkgs[cat][pkg] = []
 
                 if rev != "r0":
-                    ver = "%s-%s" % (ver, rev)
+                    ver = f"{ver}-{rev}"
 
                 _pkgs[cat][pkg].append(ver)
 
@@ -278,7 +278,7 @@ def get_imlate(conf, pkgs):
                 # -* would be overridden by ~arch or arch
                 kwd_type = 0
 
-                cpvr = "%s/%s-%s" % (cat, pkg, vr)
+                cpvr = f"{cat}/{pkg}-{vr}"
 
                 # absolute ebuild path for mtime check
                 abs_pkg = join(conf["PORTDIR"], cat, pkg, basename(cpvr))
@@ -324,13 +324,13 @@ def get_imlate(conf, pkgs):
 
                 # look for an existing stable version
                 our = portage.versions.best(
-                    conf["portdb"].dbapi.match("%s/%s%s" % (cat, pkg, slot))
+                    conf["portdb"].dbapi.match(f"{cat}/{pkg}{slot}")
                 )
                 if our:
                     _foo = portage.versions.pkgsplit(our)
                     our_ver = _foo[1]
                     if _foo[2] != "r0":
-                        our_ver = "%s-%s" % (our_ver, _foo[2])
+                        our_ver = f"{our_ver}-{_foo[2]}"
                 else:
                     our_ver = ""
 
@@ -340,11 +340,11 @@ def get_imlate(conf, pkgs):
                         continue
 
                 if kwd_type == 1 and conf["STABLE"]:
-                    imlate = _add_ent(imlate, cat, ("%s%s" % (pkg, slot)), vr, 
our_ver)
+                    imlate = _add_ent(imlate, cat, (f"{pkg}{slot}"), vr, 
our_ver)
                     conf["STABLE_SUM"] += 1
                 elif kwd_type == 0 and conf["KEYWORD"]:
                     conf["KEYWORD_SUM"] += 1
-                    imlate = _add_ent(imlate, cat, ("~%s%s" % (pkg, slot)), 
vr, our_ver)
+                    imlate = _add_ent(imlate, cat, (f"~{pkg}{slot}"), vr, 
our_ver)
 
     return imlate
 

diff --git a/pym/gentoolkit/keyword.py b/pym/gentoolkit/keyword.py
index 4160781..da4ada2 100644
--- a/pym/gentoolkit/keyword.py
+++ b/pym/gentoolkit/keyword.py
@@ -39,7 +39,7 @@ class Keyword:
     def __lt__(self, other):
         if not isinstance(other, self.__class__):
             raise TypeError(
-                "other isn't of %s type, is %s" % (self.__class__, 
other.__class__)
+                f"other isn't of {self.__class__} type, is {other.__class__}"
             )
         if self.os < other.os:
             return True
@@ -101,7 +101,7 @@ def reduce_keywords(keywords):
     @type keywords: array
     @rtype: set
     """
-    return set(x.lstrip("~") for x in keywords)
+    return {x.lstrip("~") for x in keywords}
 
 
 abs_keywords = reduce_keywords

diff --git a/pym/gentoolkit/module_base.py b/pym/gentoolkit/module_base.py
index e6e668e..a8e9c9e 100644
--- a/pym/gentoolkit/module_base.py
+++ b/pym/gentoolkit/module_base.py
@@ -152,7 +152,7 @@ class ModuleBase:
                 % pp.emph(self.command_name)
             )
         )
-        print("module: %s, target: %s" % (pp.emph(self.module_name), 
pp.emph(target)))
+        print(f"module: {pp.emph(self.module_name)}, target: 
{pp.emph(target)}")
         print()
 
 

diff --git a/pym/gentoolkit/package.py b/pym/gentoolkit/package.py
index 612fbd3..2159782 100644
--- a/pym/gentoolkit/package.py
+++ b/pym/gentoolkit/package.py
@@ -110,7 +110,7 @@ class Package(CPV):
         self._portdir_path = None
 
     def __repr__(self):
-        return "<%s %r>" % (self.__class__.__name__, self.cpv)
+        return f"<{self.__class__.__name__} {self.cpv!r}>"
 
     def __hash__(self):
         return hash(self.cpv)
@@ -135,7 +135,7 @@ class Package(CPV):
 
             try:
                 self._metadata = MetaDataXML(metadata_path, projects_path)
-            except IOError as error:
+            except OSError as error:
                 import errno
 
                 if error.errno != errno.ENOENT:
@@ -151,7 +151,7 @@ class Package(CPV):
         if self._dblink is None:
             self._dblink = portage.dblink(
                 self.category,
-                "%s-%s" % (self.name, self.fullversion),
+                f"{self.name}-{self.fullversion}",
                 self._settings["ROOT"],
                 self._settings,
             )
@@ -502,7 +502,7 @@ class PackageFormatter:
         self.pkg = pkg
 
     def __repr__(self):
-        return "<%s %s @%#8x>" % (self.__class__.__name__, self.pkg, id(self))
+        return f"<{self.__class__.__name__} {self.pkg} @{id(self):#8x}>"
 
     def __str__(self):
         if self._str is None:
@@ -597,7 +597,7 @@ class PackageFormatter:
             result += 1
         if "missing keyword" in masking_status:
             result += 2
-        if set(("profile", "package.mask")).intersection(masking_status):
+        if {"profile", "package.mask"}.intersection(masking_status):
             result += 3
 
         return (result, masking_status)
@@ -621,7 +621,7 @@ class PackageFormatter:
         return pp.keyword(
             maskmode,
             stable=not maskmode.strip(),
-            hard_masked=set(("M", "?", "-")).intersection(maskmode),
+            hard_masked={"M", "?", "-"}.intersection(maskmode),
         )
 
     def format_cpv(self, attr=None):

diff --git a/pym/gentoolkit/pprinter.py b/pym/gentoolkit/pprinter.py
index c42c354..fac1d16 100644
--- a/pym/gentoolkit/pprinter.py
+++ b/pym/gentoolkit/pprinter.py
@@ -181,7 +181,7 @@ def uprint(*args, **kw):
     end = kw.pop("end", "\n")
     file = kw.pop("file", sys.stdout)
     if kw:
-        raise TypeError("got invalid keyword arguments: {0}".format(list(kw)))
+        raise TypeError(f"got invalid keyword arguments: {list(kw)}")
     file = getattr(file, "buffer", file)
 
     encoding = locale.getpreferredencoding()

diff --git a/pym/gentoolkit/profile.py b/pym/gentoolkit/profile.py
index 7469138..11a6560 100644
--- a/pym/gentoolkit/profile.py
+++ b/pym/gentoolkit/profile.py
@@ -54,7 +54,7 @@ def load_profile_data(portdir=None, repo=""):
                 line = line.split("#", 1)[0].strip()
                 if line:
                     arch_status[line] = None
-    except IOError:
+    except OSError:
         pass
 
     try:
@@ -78,7 +78,7 @@ def load_profile_data(portdir=None, repo=""):
                     new_status = profile_status[status]
                     if new_status < curr_status:
                         arch_status[arch] = status
-    except IOError:
+    except OSError:
         pass
 
     if arch_status:
@@ -99,7 +99,7 @@ def load_profile_data(portdir=None, repo=""):
                 if line:
                     arch, status = line
                     arches_desc[arch] = status
-    except IOError:
+    except OSError:
         # backwards compatibility
         arches_desc = {
             "alpha": "testing",

diff --git a/pym/gentoolkit/query.py b/pym/gentoolkit/query.py
index 4304670..3fa4463 100644
--- a/pym/gentoolkit/query.py
+++ b/pym/gentoolkit/query.py
@@ -74,7 +74,7 @@ class Query(CPV):
         repo = ""
         if self.repo_filter:
             repo = " in %s" % self.repo_filter
-        return "<%s%s %r%s>" % (self.__class__.__name__, rx, self.query, repo)
+        return f"<{self.__class__.__name__}{rx} {self.query!r}{repo}>"
 
     def __str__(self):
         return self.query
@@ -105,7 +105,7 @@ class Query(CPV):
         if self.repo_filter is not None:
             repo = " %s" % pp.section(self.repo_filter)
 
-        pp.uprint(" * Searching%s for %s %s..." % (repo, pkg_str, cat_str))
+        pp.uprint(f" * Searching{repo} for {pkg_str} {cat_str}...")
 
     def smart_find(
         self,
@@ -115,7 +115,7 @@ class Query(CPV):
         include_masked=True,
         show_progress=True,
         no_matches_fatal=True,
-        **kwargs
+        **kwargs,
     ):
         """A high-level wrapper around gentoolkit package-finder functions.
 
@@ -195,7 +195,7 @@ class Query(CPV):
                     portage.db[portage.root]["vartree"].dbapi.match(self.query)
                 )
         except portage.exception.InvalidAtom as err:
-            message = "query.py: find(), query=%s, InvalidAtom=%s" % (
+            message = "query.py: find(), query={}, InvalidAtom={}".format(
                 self.query,
                 str(err),
             )
@@ -239,7 +239,7 @@ class Query(CPV):
         except portage.exception.InvalidAtom as err:
             message = (
                 "query.py: find_best(), bestmatch-visible, "
-                + "query=%s, InvalidAtom=%s" % (self.query, str(err))
+                + f"query={self.query}, InvalidAtom={str(err)}"
             )
             raise errors.GentoolkitInvalidAtom(message)
         # xmatch can return an empty string, so checking for None is not enough

diff --git a/pym/gentoolkit/revdep_rebuild/analyse.py 
b/pym/gentoolkit/revdep_rebuild/analyse.py
index b176943..1431a2f 100644
--- a/pym/gentoolkit/revdep_rebuild/analyse.py
+++ b/pym/gentoolkit/revdep_rebuild/analyse.py
@@ -92,7 +92,6 @@ def extract_dependencies_from_la(la, libraries, to_check, 
logger):
 
         for line in open(
             _unicode_encode(_file, encoding=_encodings["fs"]),
-            mode="r",
             encoding=_encodings["content"],
         ).readlines():
             line = line.strip()
@@ -256,7 +255,7 @@ class LibCheck:
                             try:
                                 found_libs[bits][l].add(filename)
                             except KeyError:
-                                found_libs[bits][l] = set([filename])
+                                found_libs[bits][l] = {filename}
                                 count += 1
                             fcount += 1
                             self.logger.debug(

diff --git a/pym/gentoolkit/revdep_rebuild/assign.py 
b/pym/gentoolkit/revdep_rebuild/assign.py
index bfc56eb..328db54 100644
--- a/pym/gentoolkit/revdep_rebuild/assign.py
+++ b/pym/gentoolkit/revdep_rebuild/assign.py
@@ -86,7 +86,7 @@ def assign_packages(broken, logger, settings):
             if os.path.exists(f):
                 contents_matcher = _file_matcher()
                 try:
-                    with io.open(f, "r", encoding="utf_8") as cnt:
+                    with open(f, encoding="utf_8") as cnt:
                         for line in cnt.readlines():
                             m = re.match(r"^obj (/[^ ]+)", line)
                             if m is not None:
@@ -125,20 +125,17 @@ def get_best_match(cpv, cp, logger):
 
     slot = portage.db[portage.root]["vartree"].dbapi.aux_get(cpv, ["SLOT"])[0]
     logger.warning(
-        '\t%s "%s" %s.' % (yellow("* Warning:"), cpv, bold("ebuild not 
found."))
+        '\t{} "{}" {}.'.format(yellow("* Warning:"), cpv, bold("ebuild not 
found."))
     )
-    logger.debug("\tget_best_match(); Looking for %s:%s" % (cp, slot))
+    logger.debug(f"\tget_best_match(); Looking for {cp}:{slot}")
     try:
-        match = portdb.match("%s:%s" % (cp, slot))
+        match = portdb.match(f"{cp}:{slot}")
     except portage.exception.InvalidAtom:
         match = None
 
     if not match:
         logger.warning(
-            "\t"
-            + red("!!")
-            + " "
-            + yellow("Could not find ebuild for %s:%s" % (cp, slot))
+            "\t" + red("!!") + " " + yellow(f"Could not find ebuild for 
{cp}:{slot}")
         )
         slot = [""]
         match = portdb.match(cp)
@@ -159,12 +156,10 @@ def get_slotted_cps(cpvs, logger):
         parts = catpkgsplit(cpv)
         if not parts:
             logger.warning(
-                (
-                    "\t"
-                    + red(
-                        "Failed to split the following pkg: "
-                        "%s, not a valid cat/pkg-ver" % cpv
-                    )
+                "\t"
+                + red(
+                    "Failed to split the following pkg: "
+                    "%s, not a valid cat/pkg-ver" % cpv
                 )
             )
             continue

diff --git a/pym/gentoolkit/revdep_rebuild/cache.py 
b/pym/gentoolkit/revdep_rebuild/cache.py
index 3815d72..36d8684 100644
--- a/pym/gentoolkit/revdep_rebuild/cache.py
+++ b/pym/gentoolkit/revdep_rebuild/cache.py
@@ -37,7 +37,7 @@ def read_cache(temp_path=DEFAULTS["DEFAULT_TMP_DIR"]):
                 val.add(line.strip())
             # libraries.remove('\n')
             _file.close()
-    except EnvironmentError:
+    except OSError:
         pass
 
     return (
@@ -139,13 +139,11 @@ if __name__ == "__main__":
     lib_dirs.update(ld)
     bin_dirs.update(ld)
     masked_dirs.update(
-        set(
-            [
-                "/lib/modules",
-                "/lib32/modules",
-                "/lib64/modules",
-            ]
-        )
+        {
+            "/lib/modules",
+            "/lib32/modules",
+            "/lib64/modules",
+        }
     )
 
     (

diff --git a/pym/gentoolkit/revdep_rebuild/collect.py 
b/pym/gentoolkit/revdep_rebuild/collect.py
index 897a12c..a36b701 100644
--- a/pym/gentoolkit/revdep_rebuild/collect.py
+++ b/pym/gentoolkit/revdep_rebuild/collect.py
@@ -45,7 +45,7 @@ def parse_conf(conf_file, visited=None, logger=None):
                             to_parse.update(glob.glob(path))
                     else:
                         lib_dirs.add(line)
-        except EnvironmentError:
+        except OSError:
             logger.warn("\t" + yellow("Error when parsing file %s" % conf))
 
     if visited is None:
@@ -64,18 +64,14 @@ def prepare_search_dirs(logger, settings):
     (list_of_bin_dirs, list_of_lib_dirs)
     """
 
-    bin_dirs = set(
-        [
-            "/bin",
-            "/usr/bin",
-        ]
-    )
-    lib_dirs = set(
-        [
-            "/lib",
-            "/usr/lib",
-        ]
-    )
+    bin_dirs = {
+        "/bin",
+        "/usr/bin",
+    }
+    lib_dirs = {
+        "/lib",
+        "/usr/lib",
+    }
 
     # try:
     with open(
@@ -83,7 +79,6 @@ def prepare_search_dirs(logger, settings):
             os.path.join(portage.root, settings["DEFAULT_ENV_FILE"]),
             encoding=_encodings["fs"],
         ),
-        mode="r",
         encoding=_encodings["content"],
     ) as _file:
         for line in _file.readlines():
@@ -235,13 +230,11 @@ if __name__ == "__main__":
     lib_dirs.update(ld)
     bin_dirs.update(ld)
     masked_dirs.update(
-        set(
-            [
-                "/lib/modules",
-                "/lib32/modules",
-                "/lib64/modules",
-            ]
-        )
+        {
+            "/lib/modules",
+            "/lib32/modules",
+            "/lib64/modules",
+        }
     )
 
     libraries, la_libraries, libraries_links = collect_libraries_from_dir(

diff --git a/pym/gentoolkit/revdep_rebuild/rebuild.py 
b/pym/gentoolkit/revdep_rebuild/rebuild.py
index 16d07b8..d7bf69e 100644
--- a/pym/gentoolkit/revdep_rebuild/rebuild.py
+++ b/pym/gentoolkit/revdep_rebuild/rebuild.py
@@ -1,5 +1,4 @@
 #!/usr/bin/python
-# -*- coding: utf-8 -*-
 
 
 """ Rebuild module

diff --git a/pym/gentoolkit/revdep_rebuild/runner.py 
b/pym/gentoolkit/revdep_rebuild/runner.py
index 5dd5c33..06b3968 100644
--- a/pym/gentoolkit/revdep_rebuild/runner.py
+++ b/pym/gentoolkit/revdep_rebuild/runner.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
 import threading
 import subprocess
 

diff --git a/pym/gentoolkit/sets.py b/pym/gentoolkit/sets.py
index 4fd5ff4..31c0df5 100644
--- a/pym/gentoolkit/sets.py
+++ b/pym/gentoolkit/sets.py
@@ -55,7 +55,7 @@ def get_set_atoms(setname):
     if _sets_available:
         _init_set_config()
         try:
-            return set([Atom(str(x)) for x in 
_set_config.getSetAtoms(setname)])
+            return {Atom(str(x)) for x in _set_config.getSetAtoms(setname)}
         except portage._sets.PackageSetNotFound:
             raise errors.GentoolkitSetNotFound(setname)
     raise errors.GentoolkitSetNotFound(setname)

diff --git a/pym/gentoolkit/test/eclean/creator.py 
b/pym/gentoolkit/test/eclean/creator.py
index 7c47cf2..795d2ba 100644
--- a/pym/gentoolkit/test/eclean/creator.py
+++ b/pym/gentoolkit/test/eclean/creator.py
@@ -29,7 +29,7 @@ def make_dir(path):
     Will Error and exit if the target dir already exits"""
     try:
         os.makedirs(path, dir_mode)
-    except EnvironmentError as er:
+    except OSError as er:
         print(pp.error("Error creating path:%s" % path), file=sys.stderr)
         print(pp.error("Error: %s" % str(er), file=sys.stderr))
         sys.exit(1)

diff --git a/pym/gentoolkit/test/eclean/distsupport.py 
b/pym/gentoolkit/test/eclean/distsupport.py
index 58f5624..9ea0c8d 100644
--- a/pym/gentoolkit/test/eclean/distsupport.py
+++ b/pym/gentoolkit/test/eclean/distsupport.py
@@ -499,7 +499,7 @@ class TestDisfiles:
         self.workdir = os.path.join(self.tmpdir, "distfiles")
         dir = os.path.dirname(os.path.abspath(__file__))
         file = os.path.join(dir, "testdistfiles.tar.gz")
-        command = "tar -xpf %s -C %s" % (file, self.tmpdir)
+        command = f"tar -xpf {file} -C {self.tmpdir}"
         subprocess.call(command, shell=True)
         # create a symlink as part of the test files
         # print()

diff --git a/pym/gentoolkit/test/eclean/test_search.py 
b/pym/gentoolkit/test/eclean/test_search.py
index 714fbb5..32d360c 100755
--- a/pym/gentoolkit/test/eclean/test_search.py
+++ b/pym/gentoolkit/test/eclean/test_search.py
@@ -313,11 +313,13 @@ class TestFetchRestricted(unittest.TestCase):
                     test = "OK"
                 else:
                     test = "FAILED"
-                print("comparing %s, %s" % (key, item), test)
+                print(f"comparing {key}, {item}", test)
                 self.assertEqual(
                     sorted(testdata[item]),
                     sorted(results[item]),
-                    "\n%s: %s %s data does not match\nresult=" % (test_name, 
key, item)
+                    "\n{}: {} {} data does not match\nresult=".format(
+                        test_name, key, item
+                    )
                     + str(results[item])
                     + "\ntestdata="
                     + str(testdata[item]),
@@ -559,13 +561,13 @@ class TestNonDestructive(unittest.TestCase):
                     test = "OK"
                 else:
                     test = "FAILED"
-                print("comparing %s, %s..." % (key, item), test)
+                print(f"comparing {key}, {item}...", test)
                 if test == "FAILED":
                     print("", sorted(results[item]), "\n", 
sorted(testdata[item]))
                 self.assertEqual(
                     sorted(testdata[item]),
                     sorted(results[item]),
-                    "\n%s: %s, %s data does not match\n" % (test_name, key, 
item)
+                    f"\n{test_name}: {key}, {item} data does not match\n"
                     + "result="
                     + str(results[item])
                     + "\ntestdata="

diff --git a/pym/gentoolkit/test/test_atom.py b/pym/gentoolkit/test/test_atom.py
index f5a2a4b..a96b8a2 100644
--- a/pym/gentoolkit/test/test_atom.py
+++ b/pym/gentoolkit/test/test_atom.py
@@ -56,19 +56,19 @@ class TestGentoolkitAtom(unittest.TestCase):
         for lesser, greater in (("0.1", "1"), ("1", "1-r1"), ("1.1", "1.2")):
             self.assertTrue(
                 Atom("=d/b-%s" % lesser) < Atom("=d/b-%s" % greater),
-                msg="d/b-%s < d/b-%s" % (lesser, greater),
+                msg=f"d/b-{lesser} < d/b-{greater}",
             )
             self.assertFalse(
                 Atom("=d/b-%s" % lesser) > Atom("=d/b-%s" % greater),
-                msg="!: d/b-%s < d/b-%s" % (lesser, greater),
+                msg=f"!: d/b-{lesser} < d/b-{greater}",
             )
             self.assertTrue(
                 Atom("=d/b-%s" % greater) > Atom("=d/b-%s" % lesser),
-                msg="d/b-%s > d/b-%s" % (greater, lesser),
+                msg=f"d/b-{greater} > d/b-{lesser}",
             )
             self.assertFalse(
                 Atom("=d/b-%s" % greater) < Atom("=d/b-%s" % lesser),
-                msg="!: d/b-%s > d/b-%s" % (greater, lesser),
+                msg=f"!: d/b-{greater} > d/b-{lesser}",
             )
 
         # self.assertTrue(Atom("!!=d/b-1", eapi=2) > Atom("!=d/b-1"))
@@ -120,12 +120,12 @@ class TestGentoolkitAtom(unittest.TestCase):
             self.assertEqual(
                 result,
                 this_atom.intersects(that_atom),
-                "%s intersecting %s should be %s" % (this, that, result),
+                f"{this} intersecting {that} should be {result}",
             )
             self.assertEqual(
                 result,
                 that_atom.intersects(this_atom),
-                "%s intersecting %s should be %s" % (that, this, result),
+                f"{that} intersecting {this} should be {result}",
             )
 
     def test_intersects_nameonly(self):

diff --git a/pym/gentoolkit/versionmatch.py b/pym/gentoolkit/versionmatch.py
index 48c12ad..c93297b 100644
--- a/pym/gentoolkit/versionmatch.py
+++ b/pym/gentoolkit/versionmatch.py
@@ -31,7 +31,7 @@ class VersionMatch:
 
     _convert_op2int = {(-1,): "<", (-1, 0): "<=", (0,): "=", (0, 1): ">=", 
(1,): ">"}
 
-    _convert_int2op = dict([(v, k) for k, v in _convert_op2int.items()])
+    _convert_int2op = {v: k for k, v in _convert_op2int.items()}
 
     def __init__(self, cpv, op="="):
         """Initialize a VersionMatch instance.
@@ -93,17 +93,17 @@ class VersionMatch:
         operator = self._convert_op2int[self.values]
 
         if self.droprevision or not self.revision:
-            return "ver %s %s" % (operator, self.version)
-        return "ver-rev %s %s-%s" % (operator, self.version, self.revision)
+            return f"ver {operator} {self.version}"
+        return f"ver-rev {operator} {self.version}-{self.revision}"
 
     def __repr__(self):
-        return "<%s %r>" % (self.__class__.__name__, str(self))
+        return f"<{self.__class__.__name__} {str(self)!r}>"
 
     @staticmethod
     def _convert_ops(inst):
         if inst.droprevision:
             return inst.values
-        return tuple(sorted(set((-1, 0, 1)).difference(inst.values)))
+        return tuple(sorted({-1, 0, 1}.difference(inst.values)))
 
     def __eq__(self, other):
         if self is other:

diff --git a/setup.py b/setup.py
index 23e9b36..6299ac8 100755
--- a/setup.py
+++ b/setup.py
@@ -86,11 +86,11 @@ class set_version(core.Command):
         def sub(files, pattern):
             for f in files:
                 updated_file = []
-                with io.open(f[0], "r", 1, "utf_8") as s:
+                with open(f[0], "r", 1, "utf_8") as s:
                     for line in s:
                         newline = re.sub(pattern % f[1], '"%s"' % ver, line, 1)
                         updated_file.append(newline)
-                with io.open(f[0], "w", 1, "utf_8") as s:
+                with open(f[0], "w", 1, "utf_8") as s:
                     s.writelines(updated_file)
 
         quote = r'[\'"]{1}'

Reply via email to