Repository: giampaolo/psutil
Pull request #2489 (2024-12-28 12:13:15)

New ruff rules


Patch:
diff --git a/.github/workflows/issues.py b/.github/workflows/issues.py
index 1cdc4d99..21c720ca 100755
--- a/.github/workflows/issues.py
+++ b/.github/workflows/issues.py
@@ -159,7 +159,7 @@ def get_repo():
 
 @functools.lru_cache()
 def _get_event_data():
-    with open(open(os.environ["GITHUB_EVENT_PATH"])) as f:
+    with open(os.environ["GITHUB_EVENT_PATH"]) as f:
         ret = json.load(f)
         pp(ret)
         return ret
diff --git a/psutil/__init__.py b/psutil/__init__.py
index 50b1f2a5..bc17aabf 100644
--- a/psutil/__init__.py
+++ b/psutil/__init__.py
@@ -51,16 +51,16 @@ from ._common import CONN_NONE
 from ._common import CONN_SYN_RECV
 from ._common import CONN_SYN_SENT
 from ._common import CONN_TIME_WAIT
-from ._common import FREEBSD  # NOQA
+from ._common import FREEBSD
 from ._common import LINUX
 from ._common import MACOS
-from ._common import NETBSD  # NOQA
+from ._common import NETBSD
 from ._common import NIC_DUPLEX_FULL
 from ._common import NIC_DUPLEX_HALF
 from ._common import NIC_DUPLEX_UNKNOWN
-from ._common import OPENBSD  # NOQA
+from ._common import OPENBSD
 from ._common import OSX  # deprecated alias
-from ._common import POSIX  # NOQA
+from ._common import POSIX
 from ._common import POWER_TIME_UNKNOWN
 from ._common import POWER_TIME_UNLIMITED
 from ._common import STATUS_DEAD
@@ -93,24 +93,24 @@ if LINUX:
     PROCFS_PATH = "/proc"
 
     from . import _pslinux as _psplatform
-    from ._pslinux import IOPRIO_CLASS_BE  # NOQA
-    from ._pslinux import IOPRIO_CLASS_IDLE  # NOQA
-    from ._pslinux import IOPRIO_CLASS_NONE  # NOQA
-    from ._pslinux import IOPRIO_CLASS_RT  # NOQA
+    from ._pslinux import IOPRIO_CLASS_BE  # noqa: F401
+    from ._pslinux import IOPRIO_CLASS_IDLE  # noqa: F401
+    from ._pslinux import IOPRIO_CLASS_NONE  # noqa: F401
+    from ._pslinux import IOPRIO_CLASS_RT  # noqa: F401
 
 elif WINDOWS:
     from . import _pswindows as _psplatform
-    from ._psutil_windows import ABOVE_NORMAL_PRIORITY_CLASS  # NOQA
-    from ._psutil_windows import BELOW_NORMAL_PRIORITY_CLASS  # NOQA
-    from ._psutil_windows import HIGH_PRIORITY_CLASS  # NOQA
-    from ._psutil_windows import IDLE_PRIORITY_CLASS  # NOQA
-    from ._psutil_windows import NORMAL_PRIORITY_CLASS  # NOQA
-    from ._psutil_windows import REALTIME_PRIORITY_CLASS  # NOQA
-    from ._pswindows import CONN_DELETE_TCB  # NOQA
-    from ._pswindows import IOPRIO_HIGH  # NOQA
-    from ._pswindows import IOPRIO_LOW  # NOQA
-    from ._pswindows import IOPRIO_NORMAL  # NOQA
-    from ._pswindows import IOPRIO_VERYLOW  # NOQA
+    from ._psutil_windows import ABOVE_NORMAL_PRIORITY_CLASS  # noqa: F401
+    from ._psutil_windows import BELOW_NORMAL_PRIORITY_CLASS  # noqa: F401
+    from ._psutil_windows import HIGH_PRIORITY_CLASS  # noqa: F401
+    from ._psutil_windows import IDLE_PRIORITY_CLASS  # noqa: F401
+    from ._psutil_windows import NORMAL_PRIORITY_CLASS  # noqa: F401
+    from ._psutil_windows import REALTIME_PRIORITY_CLASS  # noqa: F401
+    from ._pswindows import CONN_DELETE_TCB  # noqa: F401
+    from ._pswindows import IOPRIO_HIGH  # noqa: F401
+    from ._pswindows import IOPRIO_LOW  # noqa: F401
+    from ._pswindows import IOPRIO_NORMAL  # noqa: F401
+    from ._pswindows import IOPRIO_VERYLOW  # noqa: F401
 
 elif MACOS:
     from . import _psosx as _psplatform
@@ -120,8 +120,8 @@ elif BSD:
 
 elif SUNOS:
     from . import _pssunos as _psplatform
-    from ._pssunos import CONN_BOUND  # NOQA
-    from ._pssunos import CONN_IDLE  # NOQA
+    from ._pssunos import CONN_BOUND  # noqa: F401
+    from ._pssunos import CONN_IDLE  # noqa: F401
 
     # This is public writable API which is read from _pslinux.py and
     # _pssunos.py via sys.modules.
@@ -1201,7 +1201,7 @@ class Process:
                     except KeyError:
                         d[path] = nums
                 nt = _psplatform.pmmap_grouped
-                return [nt(path, *d[path]) for path in d]  # NOQA
+                return [nt(path, *d[path]) for path in d]
             else:
                 nt = _psplatform.pmmap_ext
                 return [nt(*x) for x in it]
@@ -1442,7 +1442,7 @@ class Popen(Process):
     def wait(self, timeout=None):
         if self.__subproc.returncode is not None:
             return self.__subproc.returncode
-        ret = super().wait(timeout)  # noqa
+        ret = super().wait(timeout)
         self.__subproc.returncode = ret
         return ret
 
@@ -1536,7 +1536,7 @@ def process_iter(attrs=None, ad_value=None):
         _pmap = pmap
 
 
-process_iter.cache_clear = lambda: _pmap.clear()  # noqa
+process_iter.cache_clear = lambda: _pmap.clear()  # noqa: PLW0108
 process_iter.cache_clear.__doc__ = "Clear process_iter() internal cache."
 
 
@@ -1619,7 +1619,7 @@ def wait_procs(procs, timeout=None, callback=None):
                 check_gone(proc, timeout)
             else:
                 check_gone(proc, max_timeout)
-        alive = alive - gone  # noqa PLR6104
+        alive = alive - gone  # noqa: PLR6104
 
     if alive:
         # Last attempt over processes survived so far.
diff --git a/psutil/_common.py b/psutil/_common.py
index a27351f4..0c385fa6 100644
--- a/psutil/_common.py
+++ b/psutil/_common.py
@@ -269,9 +269,7 @@ class Error(Exception):
         info = collections.OrderedDict()
         for name in attrs:
             value = getattr(self, name, None)
-            if value:  # noqa
-                info[name] = value
-            elif name == "pid" and value == 0:
+            if value or (name == "pid" and value == 0):
                 info[name] = value
         return info
 
@@ -876,9 +874,9 @@ def print_color(
 ):  # pragma: no cover
     """Print a colorized version of string."""
     if not term_supports_colors():
-        print(s, file=file)  # NOQA
+        print(s, file=file)
     elif POSIX:
-        print(hilite(s, color, bold), file=file)  # NOQA
+        print(hilite(s, color, bold), file=file)
     else:
         import ctypes
 
@@ -906,7 +904,7 @@ def print_color(
         handle = GetStdHandle(handle_id)
         SetConsoleTextAttribute(handle, color)
         try:
-            print(s, file=file)  # NOQA
+            print(s, file=file)
         finally:
             SetConsoleTextAttribute(handle, DEFAULT_COLOR)
 
@@ -925,6 +923,6 @@ def debug(msg):
                 msg = f"ignoring {msg}"
             else:
                 msg = f"ignoring {msg!r}"
-        print(  # noqa
+        print(  # noqa: T201
             f"psutil-debug [{fname}:{lineno}]> {msg}", file=sys.stderr
         )
diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py
index 303b6ad0..13bd926f 100644
--- a/psutil/_psbsd.py
+++ b/psutil/_psbsd.py
@@ -10,7 +10,7 @@ import functools
 import os
 from collections import defaultdict
 from collections import namedtuple
-from xml.etree import ElementTree  # noqa ICN001
+from xml.etree import ElementTree  # noqa: ICN001
 
 from . import _common
 from . import _psposix
@@ -192,8 +192,8 @@ def virtual_memory():
         # #2233), so zabbix seems to be wrong. Htop calculates it
         # differently, and the used value seem more realistic, so let's
         # match htop.
-        # https://github.com/htop-dev/htop/blob/e7f447b/netbsd/NetBSDProcessList.c#L162  # noqa
-        # https://github.com/zabbix/zabbix/blob/af5e0f8/src/libs/zbxsysinfo/netbsd/memory.c#L135  # noqa
+        # https://github.com/htop-dev/htop/blob/e7f447b/netbsd/NetBSDProcessList.c#L162
+        # https://github.com/zabbix/zabbix/blob/af5e0f8/src/libs/zbxsysinfo/netbsd/memory.c#L135
         used = active + wired
         avail = total - used
     else:
@@ -202,7 +202,7 @@ def virtual_memory():
         # * https://people.freebsd.org/~rse/dist/freebsd-memory
         # * https://www.cyberciti.biz/files/scripts/freebsd-memory.pl.txt
         # matches zabbix:
-        # * https://github.com/zabbix/zabbix/blob/af5e0f8/src/libs/zbxsysinfo/freebsd/memory.c#L143  # noqa
+        # * https://github.com/zabbix/zabbix/blob/af5e0f8/src/libs/zbxsysinfo/freebsd/memory.c#L143
         avail = inactive + cached + free
         used = active + wired + cached
 
diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py
index 4a539e06..165125fd 100644
--- a/psutil/_pslinux.py
+++ b/psutil/_pslinux.py
@@ -934,7 +934,7 @@ class NetConnections:
                         f"error while parsing {file}; malformed line {line!r}"
                     )
                     raise RuntimeError(msg)  # noqa: B904
-                if inode in inodes:  # noqa
+                if inode in inodes:  # noqa: SIM108, SIM401
                     # With UNIX sockets we can have a single inode
                     # referencing many file descriptors.
                     pairs = inodes[inode]
@@ -1327,7 +1327,7 @@ def sensors_temperatures():
     basenames2 = glob.glob(
         '/sys/devices/platform/coretemp.*/hwmon/hwmon*/temp*_*'
     )
-    repl = re.compile('/sys/devices/platform/coretemp.*/hwmon/')
+    repl = re.compile(r"/sys/devices/platform/coretemp.*/hwmon/")
     for name in basenames2:
         altname = repl.sub('/sys/class/hwmon/', name)
         if altname not in basenames:
@@ -1480,7 +1480,7 @@ def sensors_battery():
     # Get the first available battery. Usually this is "BAT0", except
     # some rare exceptions:
     # https://github.com/giampaolo/psutil/issues/1238
-    root = os.path.join(POWER_SUPPLY_PATH, sorted(bats)[0])
+    root = os.path.join(POWER_SUPPLY_PATH, min(bats))
 
     # Base metrics.
     energy_now = multi_bcat(root + "/energy_now", root + "/charge_now")
diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py
index a2818026..69820ba4 100644
--- a/psutil/_pswindows.py
+++ b/psutil/_pswindows.py
@@ -983,10 +983,10 @@ class Process:
         # Convert the first part in the corresponding drive letter
         # (e.g. "C:\") by using Windows's QueryDosDevice()
         raw_file_names = cext.proc_open_files(self.pid)
-        for _file in raw_file_names:
-            _file = convert_dos_path(_file)
-            if isfile_strict(_file):
-                ntuple = _common.popenfile(_file, -1)
+        for file in raw_file_names:
+            file = convert_dos_path(file)
+            if isfile_strict(file):
+                ntuple = _common.popenfile(file, -1)
                 ret.add(ntuple)
         return list(ret)
 
diff --git a/pyproject.toml b/pyproject.toml
index 5f8ef069..f6eb772d 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -51,14 +51,12 @@ ignore = [
     "FURB116",  # [*] Replace `hex` call with `f"{start:x}"`
     "FURB118",  # [*] Use `operator.add` instead of defining a lambda
     "FURB140",  # [*] Use `itertools.starmap` instead of the generator
-    "FURB192",  # [*] Prefer `min` over `sorted()` to compute the minimum value in a sequence
     "INP",  # flake8-no-pep420
     "N801",  # Class name `async_chat` should use CapWords convention (ASYNCORE COMPAT)
     "N802",  # Function name X should be lowercase.
     "N806",  # Variable X in function should be lowercase.
     "N818",  # Exception name `FooBar` should be named with an Error suffix
     "PERF",  # Perflint
-    "PGH004",  # Use specific rule codes when using `noqa`
     "PLC0415",  # `import` should be at the top-level of a file
     "PLC2701",  # Private name import `x` from external module `y`
     "PLR0904",  # Too many public methods (x > y)
@@ -79,8 +77,14 @@ ignore = [
     "PTH",  # flake8-use-pathlib
     "PYI",  # flake8-pyi (python types stuff)
     "Q000",  # Single quotes found but double quotes preferred
-    "RET",  # flake8-return
-    "RUF",  # Ruff-specific rules
+    "RET503",  # Missing explicit `return` at the end of function able to return non-`None` value
+    "RET504",  # Unnecessary assignment to `result` before `return` statement
+    "RET505",  # [*] Unnecessary `else` after `return` statement
+    "RUF005",  # Consider iterable unpacking instead of concatenation
+    "RUF012",  # Mutable class attributes should be annotated with `typing.ClassVar`
+    "RUF022",  # `__all__` is not sorted
+    "RUF028",  # This suppression comment is invalid
+    "RUF031",  # [*] Avoid parentheses for tuples in subscripts
     "S",  # flake8-bandit
     "SIM102",  # Use a single `if` statement instead of nested `if` statements
     "SIM105",  # Use `contextlib.suppress(OSError)` instead of `try`-`except`-`pass`
@@ -99,9 +103,10 @@ ignore = [
 # T201 == print()
 # T203 == pprint()
 # TRY003 == raise-vanilla-args
-# "B904",  # Use `raise from` to specify exception cause
+# B904 ==  Use `raise from` to specify exception cause
+# PLC1901 == `x == ""` can be simplified to `not x` as an empty string is falsey
 ".github/workflows/*" = ["B904", "EM101", "EM102", "EM103", "T201", "T203"]
-"psutil/tests/*" = ["B904", "EM101", "EM102", "EM103", "TRY003"]
+"psutil/tests/*" = ["B904", "EM101", "EM102", "EM103", "PLC1901", "TRY003"]
 "scripts/*" = ["B904", "EM101", "EM102", "EM103", "T201", "T203"]
 "scripts/internal/*" = ["B904", "EM101", "EM102", "EM103", "T201", "T203", "TRY003"]
 "setup.py" = [
diff --git a/scripts/internal/check_broken_links.py b/scripts/internal/check_broken_links.py
index 2a51381d..2c6852b9 100755
--- a/scripts/internal/check_broken_links.py
+++ b/scripts/internal/check_broken_links.py
@@ -122,7 +122,7 @@ def parse_py(fname):
                 subidx = i + 1
                 while True:
                     nextline = lines[subidx].strip()
-                    if re.match('^#     .+', nextline):
+                    if re.match(r"^#     .+", nextline):
                         url += nextline[1:].strip()
                     else:
                         break
@@ -143,7 +143,7 @@ def parse_c(fname):
                 subidx = i + 1
                 while True:
                     nextline = lines[subidx].strip()
-                    if re.match('^//     .+', nextline):
+                    if re.match(r"^//     .+", nextline):
                         url += nextline[2:].strip()
                     else:
                         break
diff --git a/scripts/internal/convert_readme.py b/scripts/internal/convert_readme.py
index 0c4fade5..9aa75b90 100755
--- a/scripts/internal/convert_readme.py
+++ b/scripts/internal/convert_readme.py
@@ -36,7 +36,7 @@ Sponsors
 
 `Add your logo <https://github.com/sponsors/giampaolo>`__.
 
-Example usages"""  # noqa
+Example usages"""
 
 
 def main():
diff --git a/scripts/internal/print_downloads.py b/scripts/internal/print_downloads.py
index d8be58a2..610a2018 100755
--- a/scripts/internal/print_downloads.py
+++ b/scripts/internal/print_downloads.py
@@ -18,7 +18,7 @@ import shlex
 import subprocess
 import sys
 
-import pypinfo  # NOQA
+import pypinfo  # noqa: F401
 
 from psutil._common import memoize
 
diff --git a/scripts/internal/print_timeline.py b/scripts/internal/print_timeline.py
index 6dec932b..94072412 100755
--- a/scripts/internal/print_timeline.py
+++ b/scripts/internal/print_timeline.py
@@ -14,7 +14,7 @@ entry = """\
 - {date}:
   `{ver} <https://pypi.org/project/psutil/{ver}/#files>`__ -
   `what's new <https://github.com/giampaolo/psutil/blob/master/HISTORY.rst#{nodotver}>`__ -
-  `diff <https://github.com/giampaolo/psutil/compare/{prevtag}...{tag}#files_bucket>`__"""  # NOQA
+  `diff <https://github.com/giampaolo/psutil/compare/{prevtag}...{tag}#files_bucket>`__"""  # noqa: E501
 
 
 def sh(cmd):
diff --git a/scripts/internal/winmake.py b/scripts/internal/winmake.py
index 1692c125..41fb6e74 100755
--- a/scripts/internal/winmake.py
+++ b/scripts/internal/winmake.py
@@ -33,7 +33,8 @@ WINDOWS = os.name == "nt"
 
 sys.path.insert(0, ROOT_DIR)  # so that we can import setup.py
 
-import setup  # NOQA
+import setup  # noqa: E402
+
 
 TEST_DEPS = setup.TEST_DEPS
 DEV_DEPS = setup.DEV_DEPS
@@ -239,7 +240,7 @@ def uninstall():
         os.chdir('C:\\')
         while True:
             try:
-                import psutil  # NOQA
+                import psutil  # noqa: F401
             except ImportError:
                 break
             else:
diff --git a/scripts/pidof.py b/scripts/pidof.py
index 7c3b93d8..c5af54c8 100755
--- a/scripts/pidof.py
+++ b/scripts/pidof.py
@@ -21,10 +21,8 @@ def pidof(pgname):
     pids = []
     for proc in psutil.process_iter(['name', 'cmdline']):
         # search for matches in the process name and cmdline
-        if (
-            proc.info['name'] == pgname
-            or proc.info['cmdline']
-            and proc.info['cmdline'][0] == pgname
+        if proc.info["name"] == pgname or (
+            proc.info["cmdline"] and proc.info["cmdline"][0] == pgname
         ):
             pids.append(str(proc.pid))
     return pids
diff --git a/setup.py b/setup.py
index 03077624..0014484a 100755
--- a/setup.py
+++ b/setup.py
@@ -58,17 +58,17 @@ HERE = os.path.abspath(os.path.dirname(__file__))
 # ...so we can import _common.py
 sys.path.insert(0, os.path.join(HERE, "psutil"))
 
-from _common import AIX  # NOQA
-from _common import BSD  # NOQA
-from _common import FREEBSD  # NOQA
-from _common import LINUX  # NOQA
-from _common import MACOS  # NOQA
-from _common import NETBSD  # NOQA
-from _common import OPENBSD  # NOQA
-from _common import POSIX  # NOQA
-from _common import SUNOS  # NOQA
-from _common import WINDOWS  # NOQA
-from _common import hilite  # NOQA
+from _common import AIX  # noqa: E402
+from _common import BSD  # noqa: E402
+from _common import FREEBSD  # noqa: E402
+from _common import LINUX  # noqa: E402
+from _common import MACOS  # noqa: E402
+from _common import NETBSD  # noqa: E402
+from _common import OPENBSD  # noqa: E402
+from _common import POSIX  # noqa: E402
+from _common import SUNOS  # noqa: E402
+from _common import WINDOWS  # noqa: E402
+from _common import hilite  # noqa: E402
 
 
 PYPY = '__pypy__' in sys.builtin_module_names


Test patch:
diff --git a/psutil/tests/__init__.py b/psutil/tests/__init__.py
index 9d837813..3817f8b1 100644
--- a/psutil/tests/__init__.py
+++ b/psutil/tests/__init__.py
@@ -707,14 +707,14 @@ class retry:
             for _ in self:
                 try:
                     return fun(*args, **kwargs)
-                except self.exception as _:  # NOQA
+                except self.exception as _:
                     exc = _
                     if self.logfun is not None:
                         self.logfun(exc)
                     self.sleep()
                     continue
 
-            raise exc  # noqa: PLE0704
+            raise exc
 
         # This way the user of the decorated function can change config
         # parameters.
@@ -890,7 +890,7 @@ class fake_pytest:
     """
 
     @staticmethod
-    def main(*args, **kw):  # noqa ARG004
+    def main(*args, **kw):  # noqa: ARG004
         """Mimics pytest.main(). It has the same effect as running
         `python3 -m unittest -v` from the project root directory.
         """
@@ -1228,7 +1228,7 @@ class TestMemoryLeak(PsutilTestCase):
                 return
             else:
                 if idx == 1:
-                    print()  # NOQA
+                    print()  # noqa: T201
                 self._log(msg)
                 times += increase
                 prev_mem = mem
@@ -1365,17 +1365,17 @@ def print_sysinfo():
     pinfo.pop('memory_maps', None)
     info['proc'] = pprint.pformat(pinfo)
 
-    print("=" * 70, file=sys.stderr)  # NOQA
+    print("=" * 70, file=sys.stderr)  # noqa: T201
     for k, v in info.items():
         print("{:<17} {}".format(k + ":", v), file=sys.stderr)  # noqa: T201
-    print("=" * 70, file=sys.stderr)  # NOQA
+    print("=" * 70, file=sys.stderr)  # noqa: T201
     sys.stdout.flush()
 
     # if WINDOWS:
     #     os.system("tasklist")
     # elif shutil.which("ps"):
     #     os.system("ps aux")
-    # print("=" * 70, file=sys.stderr)  # NOQA
+    # print("=" * 70, file=sys.stderr)
 
     sys.stdout.flush()
 
@@ -1621,7 +1621,7 @@ def retry_on_failure(retries=NO_RETRIES):
     """
 
     def logfun(exc):
-        print(f"{exc!r}, retrying", file=sys.stderr)  # NOQA
+        print(f"{exc!r}, retrying", file=sys.stderr)  # noqa: T201
 
     return retry(
         exception=AssertionError, timeout=None, retries=retries, logfun=logfun
diff --git a/psutil/tests/test_connections.py b/psutil/tests/test_connections.py
index a082f901..5ddeb855 100755
--- a/psutil/tests/test_connections.py
+++ b/psutil/tests/test_connections.py
@@ -184,7 +184,7 @@ class TestUnconnectedSockets(ConnectionTestCase):
         testfn = self.get_testfn()
         with closing(bind_unix_socket(testfn, type=SOCK_STREAM)) as sock:
             conn = self.check_socket(sock)
-            assert conn.raddr == ""  # noqa
+            assert conn.raddr == ""
             assert conn.status == psutil.CONN_NONE
 
     @pytest.mark.skipif(not POSIX, reason="POSIX only")
@@ -192,7 +192,7 @@ class TestUnconnectedSockets(ConnectionTestCase):
         testfn = self.get_testfn()
         with closing(bind_unix_socket(testfn, type=SOCK_STREAM)) as sock:
             conn = self.check_socket(sock)
-            assert conn.raddr == ""  # noqa
+            assert conn.raddr == ""
             assert conn.status == psutil.CONN_NONE
 
 
@@ -239,8 +239,8 @@ class TestConnectedSocket(ConnectionTestCase):
             assert len(cons) == 2
             if LINUX or FREEBSD or SUNOS or OPENBSD:
                 # remote path is never set
-                assert cons[0].raddr == ""  # noqa
-                assert cons[1].raddr == ""  # noqa
+                assert cons[0].raddr == ""
+                assert cons[1].raddr == ""
                 # one local address should though
                 assert testfn == (cons[0].laddr or cons[1].laddr)
             else:
@@ -356,14 +356,14 @@ class TestFilters(ConnectionTestCase):
         # launch various subprocess instantiating a socket of various
         # families and types to enrich psutil results
         tcp4_proc = self.pyrun(tcp4_template)
-        tcp4_addr = eval(wait_for_file(testfile, delete=True))  # noqa
+        tcp4_addr = eval(wait_for_file(testfile, delete=True))
         udp4_proc = self.pyrun(udp4_template)
-        udp4_addr = eval(wait_for_file(testfile, delete=True))  # noqa
+        udp4_addr = eval(wait_for_file(testfile, delete=True))
         if supports_ipv6():
             tcp6_proc = self.pyrun(tcp6_template)
-            tcp6_addr = eval(wait_for_file(testfile, delete=True))  # noqa
+            tcp6_addr = eval(wait_for_file(testfile, delete=True))
             udp6_proc = self.pyrun(udp6_template)
-            udp6_addr = eval(wait_for_file(testfile, delete=True))  # noqa
+            udp6_addr = eval(wait_for_file(testfile, delete=True))
         else:
             tcp6_proc = None
             udp6_proc = None
@@ -560,7 +560,7 @@ class TestMisc(PsutilTestCase):
                 ints.append(num)
                 strs.append(str_)
         if SUNOS:
-            psutil.CONN_IDLE  # noqa
-            psutil.CONN_BOUND  # noqa
+            psutil.CONN_IDLE  # noqa: B018
+            psutil.CONN_BOUND  # noqa: B018
         if WINDOWS:
-            psutil.CONN_DELETE_TCB  # noqa
+            psutil.CONN_DELETE_TCB  # noqa: B018
diff --git a/psutil/tests/test_linux.py b/psutil/tests/test_linux.py
index 25e4cae1..3672bc95 100755
--- a/psutil/tests/test_linux.py
+++ b/psutil/tests/test_linux.py
@@ -1763,9 +1763,10 @@ class TestSensorsTemperatures(PsutilTestCase):
                 return orig_open(name, *args, **kwargs)
 
         def glob_mock(path):
-            if path == '/sys/class/hwmon/hwmon*/temp*_*':  # noqa
-                return []
-            elif path == '/sys/class/hwmon/hwmon*/device/temp*_*':
+            if path in {
+                '/sys/class/hwmon/hwmon*/temp*_*',
+                '/sys/class/hwmon/hwmon*/device/temp*_*',
+            }:
                 return []
             elif path == '/sys/class/thermal/thermal_zone*':
                 return ['/sys/class/thermal/thermal_zone0']
@@ -1780,7 +1781,7 @@ class TestSensorsTemperatures(PsutilTestCase):
         with mock.patch("builtins.open", side_effect=open_mock):
             with mock.patch('glob.glob', create=True, side_effect=glob_mock):
                 temp = psutil.sensors_temperatures()['name'][0]
-                assert temp.label == ''  # noqa
+                assert temp.label == ''
                 assert temp.current == 30.0
                 assert temp.high == 50.0
                 assert temp.critical == 50.0
@@ -2055,7 +2056,7 @@ class TestProcess(PsutilTestCase):
             ):
                 ret = psutil.Process().exe()
                 assert m.called
-                assert ret == ""  # noqa
+                assert ret == ""
 
     def test_issue_1014(self):
         # Emulates a case where smaps file does not exist. In this case
diff --git a/psutil/tests/test_misc.py b/psutil/tests/test_misc.py
index 1c42b602..848b9284 100755
--- a/psutil/tests/test_misc.py
+++ b/psutil/tests/test_misc.py
@@ -100,7 +100,7 @@ class TestSpecialMethods(PsutilTestCase):
         assert repr(psutil.Error()) == "psutil.Error()"
 
     def test_error__str__(self):
-        assert str(psutil.Error()) == ""  # noqa
+        assert str(psutil.Error()) == ""
 
     def test_no_such_process__repr__(self):
         assert (
diff --git a/psutil/tests/test_osx.py b/psutil/tests/test_osx.py
index 682012ec..62895ccd 100755
--- a/psutil/tests/test_osx.py
+++ b/psutil/tests/test_osx.py
@@ -185,7 +185,7 @@ class TestSystemAPIs(PsutilTestCase):
     def test_sensors_battery(self):
         out = sh("pmset -g batt")
         percent = re.search(r"(\d+)%", out).group(1)
-        drawing_from = re.search("Now drawing from '([^']+)'", out).group(1)
+        drawing_from = re.search(r"Now drawing from '([^']+)'", out).group(1)
         power_plugged = drawing_from == "AC Power"
         psutil_result = psutil.sensors_battery()
         assert psutil_result.power_plugged == power_plugged
diff --git a/psutil/tests/test_process.py b/psutil/tests/test_process.py
index 64f71ff1..1d81d498 100755
--- a/psutil/tests/test_process.py
+++ b/psutil/tests/test_process.py
@@ -21,7 +21,6 @@ import subprocess
 import sys
 import textwrap
 import time
-import types
 from unittest import mock
 
 import psutil
@@ -625,7 +624,7 @@ class TestProcess(PsutilTestCase):
         for name in mem._fields:
             value = getattr(mem, name)
             assert value >= 0
-            if name == 'vms' and OSX or LINUX:
+            if (name == "vms" and OSX) or LINUX:
                 continue
             assert value <= total
         if LINUX or WINDOWS or MACOS:
@@ -642,33 +641,38 @@ class TestProcess(PsutilTestCase):
         ext_maps = p.memory_maps(grouped=False)
 
         for nt in maps:
-            if not nt.path.startswith('['):
-                if QEMU_USER and "/bin/qemu-" in nt.path:
-                    continue
-                assert os.path.isabs(nt.path), nt.path
-                if POSIX:
-                    try:
-                        assert os.path.exists(nt.path) or os.path.islink(
-                            nt.path
-                        ), nt.path
-                    except AssertionError:
-                        if not LINUX:
-                            raise
-                        # https://github.com/giampaolo/psutil/issues/759
-                        with open_text('/proc/self/smaps') as f:
-                            data = f.read()
-                        if f"{nt.path} (deleted)" not in data:
-                            raise
-                elif '64' not in os.path.basename(nt.path):
-                    # XXX - On Windows we have this strange behavior with
-                    # 64 bit dlls: they are visible via explorer but cannot
-                    # be accessed via os.stat() (wtf?).
-                    try:
-                        st = os.stat(nt.path)
-                    except FileNotFoundError:
-                        pass
-                    else:
-                        assert stat.S_ISREG(st.st_mode), nt.path
+            if nt.path.startswith('['):
+                continue
+            if BSD and nt.path == "pvclock":
+                continue
+            if QEMU_USER and "/bin/qemu-" in nt.path:
+                continue
+            assert os.path.isabs(nt.path), nt.path
+
+            if POSIX:
+                try:
+                    assert os.path.exists(nt.path) or os.path.islink(
+                        nt.path
+                    ), nt.path
+                except AssertionError:
+                    if not LINUX:
+                        raise
+                    # https://github.com/giampaolo/psutil/issues/759
+                    with open_text('/proc/self/smaps') as f:
+                        data = f.read()
+                    if f"{nt.path} (deleted)" not in data:
+                        raise
+            elif '64' not in os.path.basename(nt.path):
+                # XXX - On Windows we have this strange behavior with
+                # 64 bit dlls: they are visible via explorer but cannot
+                # be accessed via os.stat() (wtf?).
+                try:
+                    st = os.stat(nt.path)
+                except FileNotFoundError:
+                    pass
+                else:
+                    assert stat.S_ISREG(st.st_mode), nt.path
+
         for nt in ext_maps:
             for fname in nt._fields:
                 value = getattr(nt, fname)
@@ -1210,7 +1214,7 @@ class TestProcess(PsutilTestCase):
             except psutil.Error:
                 pass
         # this is the one, now let's make sure there are no duplicates
-        pid = sorted(table.items(), key=lambda x: x[1])[-1][0]
+        pid = max(table.items(), key=lambda x: x[1])[0]
         if LINUX and pid == 0:
             raise pytest.skip("PID 0")
         p = psutil.Process(pid)
@@ -1579,62 +1583,6 @@ class TestProcess(PsutilTestCase):
         assert sproc.returncode == 0
 
 
-# ===================================================================
-# --- Limited user tests
-# ===================================================================
-
-
-if POSIX and os.getuid() == 0:
-
-    class LimitedUserTestCase(TestProcess):
-        """Repeat the previous tests by using a limited user.
-        Executed only on UNIX and only if the user who run the test script
-        is root.
-        """
-
-        # the uid/gid the test suite runs under
-        if hasattr(os, 'getuid'):
-            PROCESS_UID = os.getuid()
-            PROCESS_GID = os.getgid()
-
-        def __init__(self, *args, **kwargs):
-            super().__init__(*args, **kwargs)
-            # re-define all existent test methods in order to
-            # ignore AccessDenied exceptions
-            for attr in [x for x in dir(self) if x.startswith('test')]:
-                meth = getattr(self, attr)
-
-                def test_(self):
-                    try:
-                        meth()  # noqa
-                    except psutil.AccessDenied:
-                        pass
-
-                setattr(self, attr, types.MethodType(test_, self))
-
-        def setUp(self):
-            super().setUp()
-            os.setegid(1000)
-            os.seteuid(1000)
-
-        def tearDown(self):
-            os.setegid(self.PROCESS_UID)
-            os.seteuid(self.PROCESS_GID)
-            super().tearDown()
-
-        def test_nice(self):
-            try:
-                psutil.Process().nice(-1)
-            except psutil.AccessDenied:
-                pass
-            else:
-                raise self.fail("exception not raised")
-
-        @pytest.mark.skipif(True, reason="causes problem as root")
-        def test_zombie_process(self):
-            pass
-
-
 # ===================================================================
 # --- psutil.Popen tests
 # ===================================================================
@@ -1664,10 +1612,10 @@ class TestPopen(PsutilTestCase):
         ) as proc:
             proc.name()
             proc.cpu_times()
-            proc.stdin  # noqa
+            proc.stdin  # noqa: B018
             assert dir(proc)
             with pytest.raises(AttributeError):
-                proc.foo  # noqa
+                proc.foo  # noqa: B018
             proc.terminate()
         if POSIX:
             assert proc.wait(5) == -signal.SIGTERM
diff --git a/psutil/tests/test_process_all.py b/psutil/tests/test_process_all.py
index 8dd2946c..cb7264d7 100755
--- a/psutil/tests/test_process_all.py
+++ b/psutil/tests/test_process_all.py
@@ -410,11 +410,14 @@ class TestFetchAllProcesses(PsutilTestCase):
             for fname in nt._fields:
                 value = getattr(nt, fname)
                 if fname == 'path':
-                    if not value.startswith(("[", "anon_inode:")):
-                        assert os.path.isabs(nt.path), nt.path
-                        # commented as on Linux we might get
-                        # '/foo/bar (deleted)'
-                        # assert os.path.exists(nt.path), nt.path
+                    if value.startswith(("[", "anon_inode:")):  # linux
+                        continue
+                    if BSD and value == "pvclock":  # seen on FreeBSD
+                        continue
+                    assert os.path.isabs(nt.path), nt.path
+                    # commented as on Linux we might get
+                    # '/foo/bar (deleted)'
+                    # assert os.path.exists(nt.path), nt.path
                 elif fname == 'addr':
                     assert value, repr(value)
                 elif fname == 'perms':
@@ -486,7 +489,7 @@ class TestPidsRange(PsutilTestCase):
     def test_it(self):
         def is_linux_tid(pid):
             try:
-                f = open(f"/proc/{pid}/status", "rb")
+                f = open(f"/proc/{pid}/status", "rb")  # noqa: SIM115
             except FileNotFoundError:
                 return False
             else:
diff --git a/psutil/tests/test_system.py b/psutil/tests/test_system.py
index bcf27054..f2eb4054 100755
--- a/psutil/tests/test_system.py
+++ b/psutil/tests/test_system.py
@@ -251,8 +251,8 @@ class TestMiscAPIs(PsutilTestCase):
                 assert isinstance(user.terminal, (str, type(None)))
                 if user.host is not None:
                     assert isinstance(user.host, (str, type(None)))
-                user.terminal  # noqa
-                user.host  # noqa
+                user.terminal  # noqa: B018
+                user.host  # noqa: B018
                 assert user.started > 0.0
                 datetime.datetime.fromtimestamp(user.started)
                 if WINDOWS or OPENBSD:
@@ -672,7 +672,7 @@ class TestDiskAPIs(PsutilTestCase):
             else:
                 # we cannot make any assumption about this, see:
                 # http://goo.gl/p9c43
-                disk.device  # noqa
+                disk.device  # noqa: B018
             # on modern systems mount points can also be files
             assert os.path.exists(disk.mountpoint), disk
             assert disk.fstype, disk
diff --git a/psutil/tests/test_testutils.py b/psutil/tests/test_testutils.py
index e6c3afa8..85f20c14 100755
--- a/psutil/tests/test_testutils.py
+++ b/psutil/tests/test_testutils.py
@@ -71,7 +71,7 @@ class TestRetryDecorator(PsutilTestCase):
         def foo():
             while queue:
                 queue.pop()
-                1 / 0  # noqa
+                1 / 0  # noqa: B018
             return 1
 
         queue = list(range(3))
@@ -85,7 +85,7 @@ class TestRetryDecorator(PsutilTestCase):
         def foo():
             while queue:
                 queue.pop()
-                1 / 0  # noqa
+                1 / 0  # noqa: B018
             return 1
 
         queue = list(range(6))
@@ -109,7 +109,7 @@ class TestRetryDecorator(PsutilTestCase):
 
         @retry(retries=5, interval=None, logfun=None)
         def foo():
-            1 / 0  # noqa
+            1 / 0  # noqa: B018
 
         with pytest.raises(ZeroDivisionError):
             foo()
@@ -119,7 +119,7 @@ class TestRetryDecorator(PsutilTestCase):
     def test_retries_arg(self, sleep):
         @retry(retries=5, interval=1, logfun=None)
         def foo():
-            1 / 0  # noqa
+            1 / 0  # noqa: B018
 
         with pytest.raises(ZeroDivisionError):
             foo()
@@ -407,7 +407,7 @@ class TestMemLeakClass(TestMemoryLeak):
 
     def test_unclosed_files(self):
         def fun():
-            f = open(__file__)
+            f = open(__file__)  # noqa: SIM115
             self.addCleanup(f.close)
             box.append(f)
 
@@ -429,7 +429,7 @@ class TestMemLeakClass(TestMemoryLeak):
 
     def test_execute_w_exc(self):
         def fun_1():
-            1 / 0  # noqa
+            1 / 0  # noqa: B018
 
         self.execute_w_exc(ZeroDivisionError, fun_1)
         with pytest.raises(ZeroDivisionError):
@@ -452,7 +452,7 @@ class TestFakePytest(PsutilTestCase):
 
     def test_raises(self):
         with fake_pytest.raises(ZeroDivisionError) as cm:
-            1 / 0  # noqa
+            1 / 0  # noqa: B018
         assert isinstance(cm.value, ZeroDivisionError)
 
         with fake_pytest.raises(ValueError, match="foo") as cm:
@@ -484,7 +484,7 @@ class TestFakePytest(PsutilTestCase):
         class TestCase(unittest.TestCase):
             @fake_pytest.mark.skipif(True, reason="reason")
             def foo(self):
-                assert 1 == 1  # noqa
+                assert 1 == 1  # noqa: PLR0133
 
         result = self.run_test_class(TestCase("foo"))
         assert result.wasSuccessful()
@@ -494,7 +494,7 @@ class TestFakePytest(PsutilTestCase):
         class TestCase(unittest.TestCase):
             @fake_pytest.mark.skipif(False, reason="reason")
             def foo(self):
-                assert 1 == 1  # noqa
+                assert 1 == 1  # noqa: PLR0133
 
         result = self.run_test_class(TestCase("foo"))
         assert result.wasSuccessful()
@@ -504,7 +504,7 @@ class TestFakePytest(PsutilTestCase):
         class TestCase(unittest.TestCase):
             def foo(self):
                 fake_pytest.skip("reason")
-                assert 1 == 0  # noqa
+                assert 1 == 0  # noqa: PLR0133
 
         result = self.run_test_class(TestCase("foo"))
         assert result.wasSuccessful()
@@ -564,12 +564,12 @@ class TestTestingUtils(PsutilTestCase):
         p = psutil.Process()
         ns = process_namespace(p)
         ns.test()
-        fun = [x for x in ns.iter(ns.getters) if x[1] == 'ppid'][0][0]
+        fun = next(x for x in ns.iter(ns.getters) if x[1] == 'ppid')[0]
         assert fun() == p.ppid()
 
     def test_system_namespace(self):
         ns = system_namespace()
-        fun = [x for x in ns.iter(ns.getters) if x[1] == 'net_if_addrs'][0][0]
+        fun = next(x for x in ns.iter(ns.getters) if x[1] == 'net_if_addrs')[0]
         assert fun() == psutil.net_if_addrs()
 
 
diff --git a/psutil/tests/test_windows.py b/psutil/tests/test_windows.py
index 667f1d68..9f54cf53 100755
--- a/psutil/tests/test_windows.py
+++ b/psutil/tests/test_windows.py
@@ -429,7 +429,7 @@ class TestProcess(WindowsTestCase):
         assert psutil.Process().username() == name
 
     def test_cmdline(self):
-        sys_value = re.sub('[ ]+', ' ', win32api.GetCommandLine()).strip()
+        sys_value = re.sub(r"[ ]+", " ", win32api.GetCommandLine()).strip()
         psutil_value = ' '.join(psutil.Process().cmdline())
         if sys_value[0] == '"' != psutil_value[0]:
             # The PyWin32 command line may retain quotes around argv[0] if they