From 077225d455cf04e3691d333cb8f635fbe5c48ed3 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Tue, 3 Oct 2023 22:40:28 +0200 Subject: [PATCH 01/50] git pre commit: rm checks of py files content Signed-off-by: Giampaolo Rodola --- scripts/internal/git_pre_commit.py | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/scripts/internal/git_pre_commit.py b/scripts/internal/git_pre_commit.py index 7ace3c08b..ee3c5f65e 100755 --- a/scripts/internal/git_pre_commit.py +++ b/scripts/internal/git_pre_commit.py @@ -106,27 +106,6 @@ def git_commit_files(): def main(): py_files, c_files, rst_files, new_rm_mv = git_commit_files() - # Check file content. - for path in py_files: - if os.path.realpath(path) == THIS_SCRIPT: - continue - with open_text(path) as f: - lines = f.readlines() - for lineno, line in enumerate(lines, 1): - # space at end of line - if line.endswith(' '): - print("%s:%s %r" % (path, lineno, line)) - return sys.exit("space at end of line") - line = line.rstrip() - # # pdb (now provided by flake8-debugger plugin) - # if "pdb.set_trace" in line: - # print("%s:%s %s" % (path, lineno, line)) - # return sys.exit("you forgot a pdb in your python code") - # # bare except clause (now provided by flake8-blind-except plugin) - # if "except:" in line and not line.endswith("# NOQA"): - # print("%s:%s %s" % (path, lineno, line)) - # return sys.exit("bare except clause") - # Python linters if py_files: # flake8 From 31411bab4c1da817b044ab9e4e21bc17d943a130 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Tue, 3 Oct 2023 23:35:58 +0200 Subject: [PATCH 02/50] get rid of flake8 (woha!) --- .flake8 | 34 ------------------------------ .github/workflows/build.yml | 2 +- MANIFEST.in | 1 - Makefile | 20 +++++------------- docs/DEVGUIDE.rst | 2 +- scripts/internal/git_pre_commit.py | 13 ------------ scripts/internal/winmake.py | 17 --------------- 7 files changed, 7 insertions(+), 82 deletions(-) delete mode 100644 .flake8 diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 8347d048a..000000000 --- a/.flake8 +++ /dev/null @@ -1,34 +0,0 @@ -# Configuration file for flake 8. This is used by "make lint" and by the -# GIT commit hook script. - -[flake8] -ignore = - # line break after binary operator - W504, - - # --- flake8-bugbear plugin - # Loop control variable 'keyword' not used within the loop body. If this is intended, start the name with an underscore. - B007, - # Redundant exception types in `except (IOError, OSError) as err:`. Write `except OSError as err:`, which catches exactly the same exceptions. - B014, - # Do not perform function calls in argument defaults. - B008, - - # --- flake8-blind-except plugin - # blind except Exception: statement - B902, - - # --- flake8-quotes plugin - # Double quotes found but single quotes preferred - Q000, - - # --- flake8-quotes naming; disable all except N804 and N805 - N801, N802, N803, N806, N807, N811, N812, N813, N814, N815, N816, N817, N818 - -per-file-ignores = - # T001, T201 = print() statement (flake8-print plugin) - setup.py:T001,T201 - scripts/*:T001,T201 - psutil/tests/runner.py:T001,T201 - psutil/tests/test_memleaks.py:T001,T201 - .github/workflows/*:T001,T201 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3f3ad76d9..0171e8a43 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -115,7 +115,7 @@ jobs: python-version: 3.x - name: 'Run linters' run: | - python3 -m pip install isort rstcheck toml-sort flake8 flake8-blind-except flake8-bugbear flake8-debugger flake8-print flake8-quotes sphinx + python3 -m pip install isort rstcheck toml-sort sphinx make lint-all # Check sanity of .tar.gz + wheel files diff --git a/MANIFEST.in b/MANIFEST.in index 78cb836a6..fb25643af 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,3 @@ -include .flake8 include .gitignore include CONTRIBUTING.md include CREDITS diff --git a/Makefile b/Makefile index 95276f664..dfacfb60e 100644 --- a/Makefile +++ b/Makefile @@ -9,17 +9,9 @@ TSCRIPT = psutil/tests/runner.py # Internal. PY3_DEPS = \ - autoflake \ - autopep8 \ check-manifest \ concurrencytest \ coverage \ - flake8 \ - flake8-blind-except \ - flake8-bugbear \ - flake8-debugger \ - flake8-print \ - flake8-quotes \ isort \ pep8-naming \ pylint \ @@ -200,8 +192,8 @@ test-coverage: ## Run test coverage. # Linters # =================================================================== -flake8: ## Run flake8 linter. - @git ls-files '*.py' | xargs $(PYTHON) -m flake8 --config=.flake8 --jobs=${NUM_WORKERS} +ruff: ## Run ruff linter. + @git ls-files '*.py' | xargs $(PYTHON) -m ruff check --config=pyproject.toml --no-cache isort: ## Run isort linter. @git ls-files '*.py' | xargs $(PYTHON) -m isort --check-only --jobs=${NUM_WORKERS} @@ -219,7 +211,6 @@ lint-toml: ## Linter for pyproject.toml @git ls-files '*.toml' | xargs toml-sort --check lint-all: ## Run all linters - ${MAKE} flake8 ${MAKE} isort ${MAKE} lint-c ${MAKE} lint-rst @@ -229,9 +220,8 @@ lint-all: ## Run all linters # Fixers # =================================================================== -fix-flake8: ## Run autopep8, fix some Python flake8 / pep8 issues. - @git ls-files '*.py' | xargs $(PYTHON) -m autopep8 --in-place --jobs=${NUM_WORKERS} --global-config=.flake8 - @git ls-files '*.py' | xargs $(PYTHON) -m autoflake --in-place --jobs=${NUM_WORKERS} --remove-all-unused-imports --remove-unused-variables --remove-duplicate-keys +fix-ruff: + @git ls-files '*.py' | xargs $(PYTHON) -m ruff --config=pyproject.toml --no-cache --fix fix-imports: ## Fix imports with isort. @git ls-files '*.py' | xargs $(PYTHON) -m isort --jobs=${NUM_WORKERS} @@ -243,7 +233,7 @@ fix-toml: ## Fix pyproject.toml @git ls-files '*.toml' | xargs toml-sort fix-all: ## Run all code fixers. - ${MAKE} fix-flake8 + ${MAKE} fix-ruff ${MAKE} fix-imports ${MAKE} fix-unittests ${MAKE} fix-toml diff --git a/docs/DEVGUIDE.rst b/docs/DEVGUIDE.rst index c59502dfd..a53235dab 100644 --- a/docs/DEVGUIDE.rst +++ b/docs/DEVGUIDE.rst @@ -12,7 +12,7 @@ Once you have a compiler installed run: .. code-block:: bash git clone git@github.com:giampaolo/psutil.git - make setup-dev-env # install useful dev libs (flake8, coverage, ...) + make setup-dev-env # install useful dev libs (ruff, coverage, ...) make build make install make test diff --git a/scripts/internal/git_pre_commit.py b/scripts/internal/git_pre_commit.py index 40eaee980..99601de9f 100755 --- a/scripts/internal/git_pre_commit.py +++ b/scripts/internal/git_pre_commit.py @@ -12,7 +12,6 @@ - assert no space at EOLs - assert not pdb.set_trace in code - assert no bare except clause ("except:") in code -- assert "flake8" checks pass - assert "isort" checks pass - assert C linter checks pass - assert RsT checks pass @@ -108,17 +107,6 @@ def git_commit_files(): return (py_files, c_files, rst_files, toml_files, new_rm_mv) -def flake8(files): - assert os.path.exists('.flake8') - print("running flake8 (%s files)" % len(files)) - cmd = [PYTHON, "-m", "flake8", "--config=.flake8"] + files - if subprocess.call(cmd) != 0: - return sys.exit( - "python code didn't pass 'flake8' style check; " + - "try running 'make fix-flake8'" - ) - - def isort(files): print("running isort (%s)" % len(files)) cmd = [PYTHON, "-m", "isort", "--check-only"] + files @@ -174,7 +162,6 @@ def main(): # return sys.exit("bare except clause") if py_files: - flake8(py_files) isort(py_files) if c_files: c_linter(c_files) diff --git a/scripts/internal/winmake.py b/scripts/internal/winmake.py index 5ec2ecbfd..355c3412c 100755 --- a/scripts/internal/winmake.py +++ b/scripts/internal/winmake.py @@ -40,10 +40,6 @@ PYPY = '__pypy__' in sys.builtin_module_names DEPS = [ "coverage", - "flake8", - "flake8-blind-except", - "flake8-debugger", - "flake8-print", "nose", "pdbpp", "pip", @@ -58,8 +54,6 @@ DEPS.append('mock') DEPS.append('ipaddress') DEPS.append('enum34') -else: - DEPS.append('flake8-bugbear') if not PYPY: DEPS.append("pywin32") @@ -382,16 +376,6 @@ def setup_dev_env(): sh("%s -m pip install -U %s" % (PYTHON, " ".join(DEPS))) -def flake8(): - """Run flake8 against all py files""" - py_files = subprocess.check_output("git ls-files") - if PY3: - py_files = py_files.decode() - py_files = [x for x in py_files.split() if x.endswith('.py')] - py_files = ' '.join(py_files) - sh("%s -m flake8 %s" % (PYTHON, py_files), nolog=True) - - def test(name=RUNNER_PY): """Run tests""" build() @@ -572,7 +556,6 @@ def parse_args(): sp.add_parser('install', help="build + install in develop/edit mode") sp.add_parser('install-git-hooks', help="install GIT pre-commit hook") sp.add_parser('install-pip', help="install pip") - sp.add_parser('flake8', help="run flake8 against all py files") sp.add_parser('print-access-denied', help="print AD exceptions") sp.add_parser('print-api-speed', help="benchmark all API calls") sp.add_parser('setup-dev-env', help="install deps") From b8f19dc91e3c91dcf8706cbdce85ea2fa214ebf7 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Tue, 3 Oct 2023 23:40:36 +0200 Subject: [PATCH 03/50] add ruff config (taken from pyftpdlib) --- .github/workflows/issues.py | 0 pyproject.toml | 71 +++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) mode change 100644 => 100755 .github/workflows/issues.py diff --git a/.github/workflows/issues.py b/.github/workflows/issues.py old mode 100644 new mode 100755 diff --git a/pyproject.toml b/pyproject.toml index bf9435958..2ad6f2bb2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,74 @@ +[tool.ruff] +# https://beta.ruff.rs/docs/settings/ +target-version = "py37" +line-length = 79 +select = [ + "ALL", # to get a list of all values: `python3 -m ruff linter` +] +ignore = [ + "A", # flake8-builtins + "ANN", # flake8-annotations + "ARG", # flake8-unused-arguments + "B007", # Loop control variable `x` not used within loop body + "B904", # Within an `except` clause, raise exceptions with `raise ... from err` (PYTHON2.7 COMPAT) + "BLE001", # Do not catch blind exception: `Exception` + "C4", # flake8-comprehensions (PYTHON2.7 COMPAT) + # "C408", # Unnecessary `dict` call (rewrite as a literal) + "C90", # mccabe (function `X` is too complex) + "COM812", # Trailing comma missing + "D", # pydocstyle + "DTZ", # flake8-datetimez + "EM", # flake8-errmsg + "ERA001", # Found commented-out code + "FBT", # flake8-boolean-trap + "FIX", # Line contains TODO / XXX / ..., consider resolving the issue + "FLY", # flynt (PYTHON2.7 COMPAT) + "INP", # flake8-no-pep420 + "N801", # Class name `async_chat` should use CapWords convention (ASYNCORE COMPAT) + "N802", # Function name X should be lowercase. + "N803", # Argument name X should be lowercase. + "N806", # Variable X in function should be lowercase. + "N812", # Lowercase `error` imported as non-lowercase `FooBarError` + "N818", # Exception name `FooBar` should be named with an Error suffix + "PERF", # Perflint + "PGH004", # Use specific rule codes when using `noqa` + "PLR", # pylint + "PLW", # pylint + "PT", # flake8-pytest-style + "PTH", # flake8-use-pathlib + "PYI", # flake8-pyi + "Q000", # Single quotes found but double quotes preferred + "RET", # flake8-return + "RUF", # Ruff-specific rules + "S", # flake8-bandit + "SIM102", # Use a single `if` statement instead of nested `if` statements + "SIM105", # Use `contextlib.suppress(OSError)` instead of `try`-`except`-`pass` + "SIM115", # Use context handler for opening files + "SIM117", # Use a single `with` statement with multiple contexts instead of nested `with` statements + "SLF", # flake8-self + "TD", # all TODOs, XXXs, etc. + "TRY003", # Avoid specifying long messages outside the exception class + "TRY200", # Use `raise from` to specify exception cause (PYTHON2.7 COMPAT) + "TRY300", # Consider moving this statement to an `else` block + "TRY301", # Abstract `raise` to an inner function + "UP010", # [*] Unnecessary `__future__` import `print_function` for target Python version (PYTHON2.7 COMPAT) + "UP024", # [*] Replace aliased errors with `OSError` (PYTHON2.7 COMPAT) + "UP031", # [*] Use format specifiers instead of percent format +] + +[tool.ruff.per-file-ignores] +# T201 == print(), T203 == pprint() +".github/workflows/*" = ["T201", "T203"] +"psutil/tests/runner.py" = ["T201", "T203"] +"scripts/*" = ["T201", "T203"] +"scripts/internal/*" = ["T201", "T203"] +"setup.py" = ["T201", "T203"] + +[tool.ruff.isort] +# https://beta.ruff.rs/docs/settings/#isort +force-single-line = true # one import per line +lines-after-imports = 2 + [tool.isort] force_single_line = true # one import per line lines_after_imports = 2 # blank spaces after import section From 7604a18dd3353848bea47aee4762224d9a252839 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Tue, 3 Oct 2023 23:46:11 +0200 Subject: [PATCH 04/50] run fixer for unnecessary parentheses --- pyproject.toml | 1 + scripts/procinfo.py | 2 +- scripts/top.py | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 2ad6f2bb2..4dbae3b73 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,6 +51,7 @@ ignore = [ "TRY200", # Use `raise from` to specify exception cause (PYTHON2.7 COMPAT) "TRY300", # Consider moving this statement to an `else` block "TRY301", # Abstract `raise` to an inner function + "UP009", # [*] UTF-8 encoding declaration is unnecessary (PYTHON2.7 COMPAT) "UP010", # [*] Unnecessary `__future__` import `print_function` for target Python version (PYTHON2.7 COMPAT) "UP024", # [*] Replace aliased errors with `OSError` (PYTHON2.7 COMPAT) "UP031", # [*] Use format specifiers instead of percent format diff --git a/scripts/procinfo.py b/scripts/procinfo.py index fd44c83e7..ee6eadfdb 100755 --- a/scripts/procinfo.py +++ b/scripts/procinfo.py @@ -175,7 +175,7 @@ def run(pid, verbose=False): cpu_tot_time = datetime.timedelta(seconds=sum(pinfo['cpu_times'])) cpu_tot_time = "%s:%s.%s" % ( cpu_tot_time.seconds // 60 % 60, - str((cpu_tot_time.seconds % 60)).zfill(2), + str(cpu_tot_time.seconds % 60).zfill(2), str(cpu_tot_time.microseconds)[:2]) print_('cpu-tspent', cpu_tot_time) print_('cpu-times', str_ntuple(pinfo['cpu_times'])) diff --git a/scripts/top.py b/scripts/top.py index e07a58f1a..a938ce9fb 100755 --- a/scripts/top.py +++ b/scripts/top.py @@ -117,7 +117,7 @@ def print_header(procs_status, num_procs): """Print system-related info, above the process list.""" def get_dashes(perc): - dashes = "|" * int((float(perc) / 10 * 4)) + dashes = "|" * int(float(perc) / 10 * 4) empty_dashes = " " * (40 - len(dashes)) return dashes, empty_dashes @@ -182,7 +182,7 @@ def refresh_window(procs, procs_status): if p.dict['cpu_times'] is not None: ctime = datetime.timedelta(seconds=sum(p.dict['cpu_times'])) ctime = "%s:%s.%s" % (ctime.seconds // 60 % 60, - str((ctime.seconds % 60)).zfill(2), + str(ctime.seconds % 60).zfill(2), str(ctime.microseconds)[:2]) else: ctime = '' From 6208d91a3a778a4c4daf5506a3d0435c50ac3e83 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Tue, 3 Oct 2023 23:48:49 +0200 Subject: [PATCH 05/50] run fixer for unnecessary open(..., mode) param --- docs/conf.py | 2 +- psutil/_common.py | 4 ++-- psutil/tests/__init__.py | 4 ++-- psutil/tests/runner.py | 4 ++-- psutil/tests/test_bsd.py | 2 +- psutil/tests/test_linux.py | 10 +++++----- psutil/tests/test_misc.py | 6 +++--- psutil/tests/test_testutils.py | 2 +- scripts/internal/check_broken_links.py | 4 ++-- scripts/internal/clinter.py | 2 +- scripts/internal/git_pre_commit.py | 2 +- scripts/internal/winmake.py | 8 ++++---- setup.py | 2 +- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index f0de77723..0edad708f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -34,7 +34,7 @@ def get_version(): INIT = os.path.abspath(os.path.join(HERE, '../psutil/__init__.py')) - with open(INIT, 'r') as f: + with open(INIT) as f: for line in f: if line.startswith('__version__'): ret = eval(line.strip().split(' = ')[1]) diff --git a/psutil/_common.py b/psutil/_common.py index a0d49d638..a8a868b5f 100644 --- a/psutil/_common.py +++ b/psutil/_common.py @@ -772,12 +772,12 @@ def open_text(fname): On Python 2 this is just an alias for open(name, 'rt'). """ if not PY3: - return open(fname, "rt", buffering=FILE_READ_BUFFER_SIZE) + return open(fname, buffering=FILE_READ_BUFFER_SIZE) # See: # https://github.com/giampaolo/psutil/issues/675 # https://github.com/giampaolo/psutil/pull/733 - fobj = open(fname, "rt", buffering=FILE_READ_BUFFER_SIZE, + fobj = open(fname, buffering=FILE_READ_BUFFER_SIZE, encoding=ENCODING, errors=ENCODING_ERRS) try: # Dictates per-line read(2) buffer size. Defaults is 8k. See: diff --git a/psutil/tests/__init__.py b/psutil/tests/__init__.py index 1aba0418f..0bd4d1cae 100644 --- a/psutil/tests/__init__.py +++ b/psutil/tests/__init__.py @@ -478,7 +478,7 @@ def pyrun(src, **kwds): kwds.setdefault("stderr", None) srcfile = get_testfn() try: - with open(srcfile, 'wt') as f: + with open(srcfile, "w") as f: f.write(src) subp = spawn_testproc([PYTHON_EXE, f.name], **kwds) wait_for_pid(subp.pid) @@ -849,7 +849,7 @@ def create_exe(outpath, c_code=None): } """) assert isinstance(c_code, str), c_code - with open(get_testfn(suffix='.c'), 'wt') as f: + with open(get_testfn(suffix='.c'), "w") as f: f.write(c_code) try: subprocess.check_call(["gcc", f.name, "-o", outpath]) diff --git a/psutil/tests/runner.py b/psutil/tests/runner.py index 2e6f83e26..4d4b7929f 100755 --- a/psutil/tests/runner.py +++ b/psutil/tests/runner.py @@ -108,7 +108,7 @@ def last_failed(self): suite = unittest.TestSuite() if not os.path.isfile(FAILED_TESTS_FNAME): return suite - with open(FAILED_TESTS_FNAME, 'rt') as f: + with open(FAILED_TESTS_FNAME) as f: names = f.read().split() for n in names: test = unittest.defaultTestLoader.loadTestsFromName(n) @@ -163,7 +163,7 @@ def _makeResult(self): def _write_last_failed(self): if self.failed_tnames: - with open(FAILED_TESTS_FNAME, 'wt') as f: + with open(FAILED_TESTS_FNAME, "w") as f: for tname in self.failed_tnames: f.write(tname + '\n') diff --git a/psutil/tests/test_bsd.py b/psutil/tests/test_bsd.py index 69f50732b..c5a5e7abc 100755 --- a/psutil/tests/test_bsd.py +++ b/psutil/tests/test_bsd.py @@ -503,7 +503,7 @@ class NetBSDTestCase(PsutilTestCase): @staticmethod def parse_meminfo(look_for): - with open('/proc/meminfo', 'rt') as f: + with open('/proc/meminfo') as f: for line in f: if line.startswith(look_for): return int(line.split()[1]) * 1024 diff --git a/psutil/tests/test_linux.py b/psutil/tests/test_linux.py index adb6ff606..063fbabf3 100755 --- a/psutil/tests/test_linux.py +++ b/psutil/tests/test_linux.py @@ -113,7 +113,7 @@ def get_ipv4_broadcast(ifname): def get_ipv6_addresses(ifname): - with open("/proc/net/if_inet6", 'rt') as f: + with open("/proc/net/if_inet6") as f: all_fields = [] for line in f.readlines(): fields = line.split() @@ -943,7 +943,7 @@ class TestLoadAvg(PsutilTestCase): @unittest.skipIf(not HAS_GETLOADAVG, "not supported") def test_getloadavg(self): psutil_value = psutil.getloadavg() - with open("/proc/loadavg", "r") as f: + with open("/proc/loadavg") as f: proc_value = f.read().split() self.assertAlmostEqual(float(proc_value[0]), psutil_value[0], delta=1) @@ -1015,7 +1015,7 @@ def test_against_ifconfig(self): def test_mtu(self): for name, stats in psutil.net_if_stats().items(): - with open("/sys/class/net/%s/mtu" % name, "rt") as f: + with open("/sys/class/net/%s/mtu" % name) as f: self.assertEqual(stats.mtu, int(f.read().strip())) @unittest.skipIf(not which("ifconfig"), "ifconfig utility not available") @@ -1159,7 +1159,7 @@ def df(path): def test_zfs_fs(self): # Test that ZFS partitions are returned. - with open("/proc/filesystems", "r") as f: + with open("/proc/filesystems") as f: data = f.read() if 'zfs' in data: for part in psutil.disk_partitions(): @@ -1896,7 +1896,7 @@ def get_test_file(fname): testfn = self.get_testfn() with open(testfn, "w"): self.assertEqual(get_test_file(testfn).mode, "w") - with open(testfn, "r"): + with open(testfn): self.assertEqual(get_test_file(testfn).mode, "r") with open(testfn, "a"): self.assertEqual(get_test_file(testfn).mode, "a") diff --git a/psutil/tests/test_misc.py b/psutil/tests/test_misc.py index 53c640121..12f360eae 100755 --- a/psutil/tests/test_misc.py +++ b/psutil/tests/test_misc.py @@ -563,7 +563,7 @@ def test_debug(self): def test_cat_bcat(self): testfn = self.get_testfn() - with open(testfn, "wt") as f: + with open(testfn, "w") as f: f.write("foo") self.assertEqual(cat(testfn), "foo") self.assertEqual(bcat(testfn), b"foo") @@ -846,9 +846,9 @@ def assert_stdout(exe, *args, **kwargs): def assert_syntax(exe): exe = os.path.join(SCRIPTS_DIR, exe) if PY3: - f = open(exe, 'rt', encoding='utf8') + f = open(exe, encoding='utf8') else: - f = open(exe, 'rt') + f = open(exe) with f: src = f.read() ast.parse(src) diff --git a/psutil/tests/test_testutils.py b/psutil/tests/test_testutils.py index 65ca0c4d4..95fd49052 100755 --- a/psutil/tests/test_testutils.py +++ b/psutil/tests/test_testutils.py @@ -170,7 +170,7 @@ class TestFSTestUtils(PsutilTestCase): def test_open_text(self): with open_text(__file__) as f: - self.assertEqual(f.mode, 'rt') + self.assertEqual(f.mode, 'r') def test_open_binary(self): with open_binary(__file__) as f: diff --git a/scripts/internal/check_broken_links.py b/scripts/internal/check_broken_links.py index f5375a860..60f623d19 100755 --- a/scripts/internal/check_broken_links.py +++ b/scripts/internal/check_broken_links.py @@ -161,7 +161,7 @@ def parse_c(fname): def parse_generic(fname): - with open(fname, 'rt', errors='ignore') as f: + with open(fname, errors='ignore') as f: text = f.read() return find_urls(text) @@ -175,7 +175,7 @@ def get_urls(fname): elif fname.endswith('.c') or fname.endswith('.h'): return parse_c(fname) else: - with open(fname, 'rt', errors='ignore') as f: + with open(fname, errors='ignore') as f: if f.readline().strip().startswith('#!/usr/bin/env python3'): return parse_py(fname) return parse_generic(fname) diff --git a/scripts/internal/clinter.py b/scripts/internal/clinter.py index 384951da8..51b0c8ad0 100755 --- a/scripts/internal/clinter.py +++ b/scripts/internal/clinter.py @@ -60,7 +60,7 @@ def check_line(path, line, idx, lines): def process(path): - with open(path, 'rt') as f: + with open(path) as f: lines = f.readlines() for idx, line in enumerate(lines): check_line(path, line, idx, lines) diff --git a/scripts/internal/git_pre_commit.py b/scripts/internal/git_pre_commit.py index 99601de9f..8d3049d00 100755 --- a/scripts/internal/git_pre_commit.py +++ b/scripts/internal/git_pre_commit.py @@ -85,7 +85,7 @@ def sh(cmd): def open_text(path): kw = {'encoding': 'utf8'} if PY3 else {} - return open(path, 'rt', **kw) + return open(path, **kw) def git_commit_files(): diff --git a/scripts/internal/winmake.py b/scripts/internal/winmake.py index 355c3412c..46afdaf65 100755 --- a/scripts/internal/winmake.py +++ b/scripts/internal/winmake.py @@ -327,7 +327,7 @@ def uninstall(): # easy_install can add a line (installation path) into # easy-install.pth; that line alters sys.path. path = os.path.join(dir, name) - with open(path, 'rt') as f: + with open(path) as f: lines = f.readlines() hasit = False for line in lines: @@ -335,7 +335,7 @@ def uninstall(): hasit = True break if hasit: - with open(path, 'wt') as f: + with open(path, "w") as f: for line in lines: if 'psutil' not in line: f.write(line) @@ -465,8 +465,8 @@ def install_git_hooks(): ROOT_DIR, "scripts", "internal", "git_pre_commit.py") dst = os.path.realpath( os.path.join(ROOT_DIR, ".git", "hooks", "pre-commit")) - with open(src, "rt") as s: - with open(dst, "wt") as d: + with open(src) as s: + with open(dst, "w") as d: d.write(s.read()) diff --git a/setup.py b/setup.py index 35467e131..c79ad926d 100755 --- a/setup.py +++ b/setup.py @@ -98,7 +98,7 @@ def get_version(): INIT = os.path.join(HERE, 'psutil/__init__.py') - with open(INIT, 'r') as f: + with open(INIT) as f: for line in f: if line.startswith('__version__'): ret = eval(line.strip().split(' = ')[1]) From 087706049fa44e1644f8bfef37ee5d101a7f9024 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Tue, 3 Oct 2023 23:49:19 +0200 Subject: [PATCH 06/50] run fixer for unnecessary u'...' literal --- docs/conf.py | 8 ++++---- scripts/internal/winmake.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 0edad708f..9756430b1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -27,7 +27,7 @@ PROJECT_NAME = "psutil" -AUTHOR = u"Giampaolo Rodola" +AUTHOR = "Giampaolo Rodola" THIS_YEAR = str(datetime.datetime.now().year) HERE = os.path.abspath(os.path.dirname(__file__)) @@ -288,7 +288,7 @@ def get_version(): # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'psutil.tex', u'psutil Documentation', + (master_doc, 'psutil.tex', 'psutil Documentation', AUTHOR, 'manual'), ] @@ -330,7 +330,7 @@ def get_version(): # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - (master_doc, 'psutil', u'psutil Documentation', + (master_doc, 'psutil', 'psutil Documentation', [author], 1) ] @@ -345,7 +345,7 @@ def get_version(): # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'psutil', u'psutil Documentation', + (master_doc, 'psutil', 'psutil Documentation', author, 'psutil', 'One line description of project.', 'Miscellaneous'), ] diff --git a/scripts/internal/winmake.py b/scripts/internal/winmake.py index 46afdaf65..e01a664ae 100755 --- a/scripts/internal/winmake.py +++ b/scripts/internal/winmake.py @@ -192,7 +192,7 @@ def onerror(fun, path, excinfo): def recursive_rm(*patterns): """Recursively remove a file or matching a list of patterns.""" - for root, dirs, files in os.walk(u'.'): + for root, dirs, files in os.walk('.'): root = os.path.normpath(root) if root.startswith('.git/'): continue From 103b0c0705cad339eb9a5b8d027f24eda4aed5d3 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Tue, 3 Oct 2023 23:51:34 +0200 Subject: [PATCH 07/50] run fixer for unnecessary inheritance from (object) --- psutil/__init__.py | 2 +- psutil/_psaix.py | 2 +- psutil/_psbsd.py | 2 +- psutil/_pslinux.py | 2 +- psutil/_psosx.py | 2 +- psutil/_pssunos.py | 2 +- psutil/_pswindows.py | 4 ++-- psutil/tests/__init__.py | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/psutil/__init__.py b/psutil/__init__.py index 5a5a20606..2300dd62f 100644 --- a/psutil/__init__.py +++ b/psutil/__init__.py @@ -279,7 +279,7 @@ def _pprint_secs(secs): # ===================================================================== -class Process(object): +class Process(object): # noqa: UP004 """Represents an OS process with the given PID. If PID is omitted current process PID (os.getpid()) is used. Raise NoSuchProcess if PID does not exist. diff --git a/psutil/_psaix.py b/psutil/_psaix.py index 67f0314f7..f28044ac2 100644 --- a/psutil/_psaix.py +++ b/psutil/_psaix.py @@ -330,7 +330,7 @@ def wrapper(self, *args, **kwargs): return wrapper -class Process(object): +class Process: """Wrapper class around underlying C implementation.""" __slots__ = ["pid", "_name", "_ppid", "_procfs_path", "_cache"] diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py index fb4217efe..f0fdaf543 100644 --- a/psutil/_psbsd.py +++ b/psutil/_psbsd.py @@ -599,7 +599,7 @@ def wrap_exceptions_procfs(inst): raise AccessDenied(inst.pid, inst._name) -class Process(object): +class Process: """Wrapper class around underlying C implementation.""" __slots__ = ["pid", "_name", "_ppid", "_cache"] diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py index 0f102cbfa..0cd906663 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -1664,7 +1664,7 @@ def wrapper(self, *args, **kwargs): return wrapper -class Process(object): +class Process: """Linux process implementation.""" __slots__ = ["pid", "_name", "_ppid", "_procfs_path", "_cache"] diff --git a/psutil/_psosx.py b/psutil/_psosx.py index 8da2d9a32..21b0b6328 100644 --- a/psutil/_psosx.py +++ b/psutil/_psosx.py @@ -354,7 +354,7 @@ def wrapper(self, *args, **kwargs): return wrapper -class Process(object): +class Process: """Wrapper class around underlying C implementation.""" __slots__ = ["pid", "_name", "_ppid", "_cache"] diff --git a/psutil/_pssunos.py b/psutil/_pssunos.py index d44bf2d78..007ac9b01 100644 --- a/psutil/_pssunos.py +++ b/psutil/_pssunos.py @@ -369,7 +369,7 @@ def wrapper(self, *args, **kwargs): return wrapper -class Process(object): +class Process: """Wrapper class around underlying C implementation.""" __slots__ = ["pid", "_name", "_ppid", "_procfs_path", "_cache"] diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py index eec2db84d..c9e4d57d7 100644 --- a/psutil/_pswindows.py +++ b/psutil/_pswindows.py @@ -493,7 +493,7 @@ def win_service_get(name): return service -class WindowsService(object): +class WindowsService: """Represents an installed Windows service.""" def __init__(self, name, display_name): @@ -725,7 +725,7 @@ def wrapper(self, *args, **kwargs): return wrapper -class Process(object): +class Process: """Wrapper class around underlying C implementation.""" __slots__ = ["pid", "_name", "_ppid", "_cache"] diff --git a/psutil/tests/__init__.py b/psutil/tests/__init__.py index 0bd4d1cae..52b56a510 100644 --- a/psutil/tests/__init__.py +++ b/psutil/tests/__init__.py @@ -682,7 +682,7 @@ def get_winver(): # =================================================================== -class retry(object): +class retry: """A retry decorator.""" def __init__(self, From f0265eb5ade4fb011bc5fdffaf4a882e89fb0ad8 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Tue, 3 Oct 2023 23:57:51 +0200 Subject: [PATCH 08/50] add fixes --- psutil/__init__.py | 2 +- psutil/_compat.py | 2 +- psutil/tests/test_connections.py | 6 +++--- psutil/tests/test_process.py | 2 +- psutil/tests/test_system.py | 6 +++--- psutil/tests/test_testutils.py | 10 +++++----- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/psutil/__init__.py b/psutil/__init__.py index 2300dd62f..7d0c2b325 100644 --- a/psutil/__init__.py +++ b/psutil/__init__.py @@ -1384,7 +1384,7 @@ def __getattribute__(self, name): def wait(self, timeout=None): if self.__subproc.returncode is not None: return self.__subproc.returncode - ret = super(Popen, self).wait(timeout) + ret = super(Popen, self).wait(timeout) # noqa self.__subproc.returncode = ret return ret diff --git a/psutil/_compat.py b/psutil/_compat.py index 2531cf4b6..c85799d26 100644 --- a/psutil/_compat.py +++ b/psutil/_compat.py @@ -152,7 +152,7 @@ def __init__(self, *args, **kwargs): if not attr.startswith('__'): setattr(self, attr, getattr(unwrap_me, attr)) else: - super(TemporaryClass, self).__init__(*args, **kwargs) + super(TemporaryClass, self).__init__(*args, **kwargs) # noqa class __metaclass__(type): def __instancecheck__(cls, inst): diff --git a/psutil/tests/test_connections.py b/psutil/tests/test_connections.py index aec164e85..b785acd49 100755 --- a/psutil/tests/test_connections.py +++ b/psutil/tests/test_connections.py @@ -533,10 +533,10 @@ def test_connection_constants(self): ints.append(num) strs.append(str_) if SUNOS: - psutil.CONN_IDLE - psutil.CONN_BOUND + psutil.CONN_IDLE # noqa + psutil.CONN_BOUND # noqa if WINDOWS: - psutil.CONN_DELETE_TCB + psutil.CONN_DELETE_TCB # noqa if __name__ == '__main__': diff --git a/psutil/tests/test_process.py b/psutil/tests/test_process.py index ae0192708..ece7c4aac 100755 --- a/psutil/tests/test_process.py +++ b/psutil/tests/test_process.py @@ -1525,7 +1525,7 @@ def test_misc(self): stderr=subprocess.PIPE, env=PYTHON_EXE_ENV) as proc: proc.name() proc.cpu_times() - proc.stdin + proc.stdin # noqa self.assertTrue(dir(proc)) self.assertRaises(AttributeError, getattr, proc, 'foo') proc.terminate() diff --git a/psutil/tests/test_system.py b/psutil/tests/test_system.py index 80e4988d5..68bfc24c9 100755 --- a/psutil/tests/test_system.py +++ b/psutil/tests/test_system.py @@ -216,8 +216,8 @@ def test_users(self): self.assertIsInstance(user.terminal, (str, type(None))) if user.host is not None: self.assertIsInstance(user.host, (str, type(None))) - user.terminal - user.host + user.terminal # noqa + user.host # noqa assert user.started > 0.0, user datetime.datetime.fromtimestamp(user.started) if WINDOWS or OPENBSD: @@ -617,7 +617,7 @@ def check_ntuple(nt): else: # we cannot make any assumption about this, see: # http://goo.gl/p9c43 - disk.device + disk.device # noqa # 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 95fd49052..58d348416 100755 --- a/psutil/tests/test_testutils.py +++ b/psutil/tests/test_testutils.py @@ -71,7 +71,7 @@ def test_retry_success(self, sleep): def foo(): while queue: queue.pop() - 1 / 0 + 1 / 0 # noqa return 1 queue = list(range(3)) @@ -85,7 +85,7 @@ def test_retry_failure(self, sleep): def foo(): while queue: queue.pop() - 1 / 0 + 1 / 0 # noqa return 1 queue = list(range(6)) @@ -107,7 +107,7 @@ def test_no_interval_arg(self, sleep): @retry(retries=5, interval=None, logfun=None) def foo(): - 1 / 0 + 1 / 0 # noqa self.assertRaises(ZeroDivisionError, foo) self.assertEqual(sleep.call_count, 0) @@ -117,7 +117,7 @@ def test_retries_arg(self, sleep): @retry(retries=5, interval=1, logfun=None) def foo(): - 1 / 0 + 1 / 0 # noqa self.assertRaises(ZeroDivisionError, foo) self.assertEqual(sleep.call_count, 5) @@ -407,7 +407,7 @@ def fun(): def test_execute_w_exc(self): def fun_1(): - 1 / 0 + 1 / 0 # noqa self.execute_w_exc(ZeroDivisionError, fun_1) with self.assertRaises(ZeroDivisionError): self.execute_w_exc(OSError, fun_1) From 48825bde4c3b5eb9bdc5c450ed098eb595cd91d9 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Tue, 3 Oct 2023 23:59:00 +0200 Subject: [PATCH 09/50] run fixer for ternary operator --- psutil/__init__.py | 5 +---- psutil/_pslinux.py | 5 +---- psutil/tests/__init__.py | 5 +---- psutil/tests/test_misc.py | 5 +---- psutil/tests/test_posix.py | 5 +---- scripts/internal/winmake.py | 5 +---- scripts/procinfo.py | 5 +---- scripts/sensors.py | 5 +---- scripts/top.py | 5 +---- 9 files changed, 9 insertions(+), 36 deletions(-) diff --git a/psutil/__init__.py b/psutil/__init__.py index 7d0c2b325..3d47e3394 100644 --- a/psutil/__init__.py +++ b/psutil/__init__.py @@ -267,10 +267,7 @@ def _pprint_secs(secs): """Format seconds in a human readable form.""" now = time.time() secs_ago = int(now - secs) - if secs_ago < 60 * 60 * 24: - fmt = "%H:%M:%S" - else: - fmt = "%Y-%m-%d %H:%M:%S" + fmt = "%H:%M:%S" if secs_ago < 60 * 60 * 24 else "%Y-%m-%d %H:%M:%S" return datetime.datetime.fromtimestamp(secs).strftime(fmt) diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py index 0cd906663..08c208987 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -968,10 +968,7 @@ def process_unix(file, family, inodes, filter_pid=None): if filter_pid is not None and filter_pid != pid: continue else: - if len(tokens) == 8: - path = tokens[-1] - else: - path = "" + path = tokens[-1] if len(tokens) == 8 else '' type_ = _common.socktype_to_enum(int(type_)) # XXX: determining the remote endpoint of a # UNIX socket on Linux is not possible, see: diff --git a/psutil/tests/__init__.py b/psutil/tests/__init__.py index 52b56a510..b39f4f6ae 100644 --- a/psutil/tests/__init__.py +++ b/psutil/tests/__init__.py @@ -670,10 +670,7 @@ def get_winver(): sp = wv.service_pack_major or 0 else: r = re.search(r"\s\d$", wv[4]) - if r: - sp = int(r.group(0)) - else: - sp = 0 + sp = int(r.group(0)) if r else 0 return (wv[0], wv[1], sp) diff --git a/psutil/tests/test_misc.py b/psutil/tests/test_misc.py index 12f360eae..35014294a 100755 --- a/psutil/tests/test_misc.py +++ b/psutil/tests/test_misc.py @@ -845,10 +845,7 @@ def assert_stdout(exe, *args, **kwargs): @staticmethod def assert_syntax(exe): exe = os.path.join(SCRIPTS_DIR, exe) - if PY3: - f = open(exe, encoding='utf8') - else: - f = open(exe) + f = open(exe, encoding="utf8") if PY3 else open(exe) with f: src = f.read() ast.parse(src) diff --git a/psutil/tests/test_posix.py b/psutil/tests/test_posix.py index fe6936de5..e04397d05 100755 --- a/psutil/tests/test_posix.py +++ b/psutil/tests/test_posix.py @@ -68,10 +68,7 @@ def ps(fmt, pid=None): output = sh(cmd) - if LINUX: - output = output.splitlines() - else: - output = output.splitlines()[1:] + output = output.splitlines() if LINUX else output.splitlines()[1:] all_output = [] for line in output: diff --git a/scripts/internal/winmake.py b/scripts/internal/winmake.py index e01a664ae..9ee90f0f9 100755 --- a/scripts/internal/winmake.py +++ b/scripts/internal/winmake.py @@ -28,10 +28,7 @@ APPVEYOR = bool(os.environ.get('APPVEYOR')) -if APPVEYOR: - PYTHON = sys.executable -else: - PYTHON = os.getenv('PYTHON', sys.executable) +PYTHON = sys.executable if APPVEYOR else os.getenv('PYTHON', sys.executable) RUNNER_PY = 'psutil\\tests\\runner.py' GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py" PY3 = sys.version_info[0] == 3 diff --git a/scripts/procinfo.py b/scripts/procinfo.py index ee6eadfdb..0ffdf40e2 100755 --- a/scripts/procinfo.py +++ b/scripts/procinfo.py @@ -147,10 +147,7 @@ def run(pid, verbose=False): with proc.oneshot(): try: parent = proc.parent() - if parent: - parent = '(%s)' % parent.name() - else: - parent = '' + parent = '(%s)' % parent.name() if parent else '' except psutil.Error: parent = '' try: diff --git a/scripts/sensors.py b/scripts/sensors.py index 3dc823803..edbec8e4c 100755 --- a/scripts/sensors.py +++ b/scripts/sensors.py @@ -45,10 +45,7 @@ def main(): temps = psutil.sensors_temperatures() else: temps = {} - if hasattr(psutil, "sensors_fans"): - fans = psutil.sensors_fans() - else: - fans = {} + fans = psutil.sensors_fans() if hasattr(psutil, "sensors_fans") else {} if hasattr(psutil, "sensors_battery"): battery = psutil.sensors_battery() else: diff --git a/scripts/top.py b/scripts/top.py index a938ce9fb..d6120c796 100755 --- a/scripts/top.py +++ b/scripts/top.py @@ -192,10 +192,7 @@ def refresh_window(procs, procs_status): p.dict['memory_percent'] = '' if p.dict['cpu_percent'] is None: p.dict['cpu_percent'] = '' - if p.dict['username']: - username = p.dict['username'][:8] - else: - username = "" + username = p.dict['username'][:8] if p.dict['username'] else '' line = templ % (p.pid, username, p.dict['nice'], From a410b08d84ee9074401fabfa9b892fb008c6157b Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 00:00:35 +0200 Subject: [PATCH 10/50] run fixer for use unpack tuple comprehension instead of list --- psutil/_psaix.py | 12 ++++++------ psutil/_pslinux.py | 2 +- psutil/_pssunos.py | 4 ++-- psutil/tests/test_linux.py | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/psutil/_psaix.py b/psutil/_psaix.py index f28044ac2..39b15229f 100644 --- a/psutil/_psaix.py +++ b/psutil/_psaix.py @@ -149,8 +149,8 @@ def cpu_count_cores(): stderr=subprocess.PIPE) stdout, stderr = p.communicate() if PY3: - stdout, stderr = [x.decode(sys.stdout.encoding) - for x in (stdout, stderr)] + stdout, stderr = (x.decode(sys.stdout.encoding) + for x in (stdout, stderr)) if p.returncode != 0: raise RuntimeError("%r command error\n%s" % (cmd, stderr)) processors = stdout.strip().splitlines() @@ -249,8 +249,8 @@ def net_if_stats(): stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() if PY3: - stdout, stderr = [x.decode(sys.stdout.encoding) - for x in (stdout, stderr)] + stdout, stderr = (x.decode(sys.stdout.encoding) + for x in (stdout, stderr)) if p.returncode == 0: re_result = re.search( r"Running: (\d+) Mbps.*?(\w+) Duplex", stdout) @@ -511,8 +511,8 @@ def open_files(self): stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() if PY3: - stdout, stderr = [x.decode(sys.stdout.encoding) - for x in (stdout, stderr)] + stdout, stderr = (x.decode(sys.stdout.encoding) + for x in (stdout, stderr)) if "no such process" in stderr.lower(): raise NoSuchProcess(self.pid, self._name) procfiles = re.findall(r"(\d+): S_IFREG.*\s*.*name:(.*)\n", stdout) diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py index 08c208987..0d9110b43 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -1898,7 +1898,7 @@ def memory_info(self): # ============================================================ with open_binary("%s/%s/statm" % (self._procfs_path, self.pid)) as f: vms, rss, shared, text, lib, data, dirty = \ - [int(x) * PAGESIZE for x in f.readline().split()[:7]] + (int(x) * PAGESIZE for x in f.readline().split()[:7]) return pmem(rss, vms, shared, text, lib, data, dirty) if HAS_PROC_SMAPS_ROLLUP or HAS_PROC_SMAPS: diff --git a/psutil/_pssunos.py b/psutil/_pssunos.py index 007ac9b01..66805ff6b 100644 --- a/psutil/_pssunos.py +++ b/psutil/_pssunos.py @@ -622,8 +622,8 @@ def _get_unix_sockets(self, pid): stderr=subprocess.PIPE) stdout, stderr = p.communicate() if PY3: - stdout, stderr = [x.decode(sys.stdout.encoding) - for x in (stdout, stderr)] + stdout, stderr = (x.decode(sys.stdout.encoding) + for x in (stdout, stderr)) if p.returncode != 0: if 'permission denied' in stderr.lower(): raise AccessDenied(self.pid, self._name) diff --git a/psutil/tests/test_linux.py b/psutil/tests/test_linux.py index 063fbabf3..2fc9955e0 100755 --- a/psutil/tests/test_linux.py +++ b/psutil/tests/test_linux.py @@ -180,7 +180,7 @@ def free_physmem(): for line in lines: if line.startswith('Mem'): total, used, free, shared = \ - [int(x) for x in line.split()[1:5]] + (int(x) for x in line.split()[1:5]) nt = collections.namedtuple( 'free', 'total used free shared output') return nt(total, used, free, shared, out) From df059d0538f3ac9ef6f052ff49f0a0c7dc08cea6 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 00:03:04 +0200 Subject: [PATCH 11/50] run anoter fixer --- .github/workflows/issues.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/issues.py b/.github/workflows/issues.py index 77a9bc96b..9bc14272e 100755 --- a/.github/workflows/issues.py +++ b/.github/workflows/issues.py @@ -144,10 +144,7 @@ def has_label(issue, label): def has_os_label(issue): labels = set([x.name for x in issue.labels]) - for label in OS_LABELS: - if label in labels: - return True - return False + return any(x in labels for x in OS_LABELS) def get_repo(): From 82a76fd38e371e91fd0bf4a7caacb587eee132ac Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 00:56:21 +0200 Subject: [PATCH 12/50] fix eval() --- docs/conf.py | 5 +++-- psutil/tests/__init__.py | 2 +- psutil/tests/test_connections.py | 8 ++++---- setup.py | 3 ++- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 9756430b1..9e0434706 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,6 +22,7 @@ # -- General configuration ------------------------------------------------ +import ast import datetime import os @@ -37,7 +38,7 @@ def get_version(): with open(INIT) as f: for line in f: if line.startswith('__version__'): - ret = eval(line.strip().split(' = ')[1]) + ret = ast.literal_eval(line.strip().split(' = ')[1]) assert ret.count('.') == 2, ret for num in ret.split('.'): assert num.isdigit(), ret @@ -314,7 +315,7 @@ def get_version(): # # latex_appendices = [] -# It false, will not define \strong, \code, itleref, \crossref ... but only +# It false, will not define \strong, \code, itleref, \crossref ... but only # \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added # packages. # diff --git a/psutil/tests/__init__.py b/psutil/tests/__init__.py index b39f4f6ae..96f339788 100644 --- a/psutil/tests/__init__.py +++ b/psutil/tests/__init__.py @@ -769,7 +769,7 @@ def call_until(fun, expr): expression is True. """ ret = fun() - assert eval(expr) + assert eval(expr) # noqa return ret diff --git a/psutil/tests/test_connections.py b/psutil/tests/test_connections.py index b785acd49..13d1aebe9 100755 --- a/psutil/tests/test_connections.py +++ b/psutil/tests/test_connections.py @@ -357,14 +357,14 @@ def check_conn(proc, conn, family, type, laddr, raddr, status, kinds): # 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)) + tcp4_addr = eval(wait_for_file(testfile, delete=True)) # noqa udp4_proc = self.pyrun(udp4_template) - udp4_addr = eval(wait_for_file(testfile, delete=True)) + udp4_addr = eval(wait_for_file(testfile, delete=True)) # noqa if supports_ipv6(): tcp6_proc = self.pyrun(tcp6_template) - tcp6_addr = eval(wait_for_file(testfile, delete=True)) + tcp6_addr = eval(wait_for_file(testfile, delete=True)) # noqa udp6_proc = self.pyrun(udp6_template) - udp6_addr = eval(wait_for_file(testfile, delete=True)) + udp6_addr = eval(wait_for_file(testfile, delete=True)) # noqa else: tcp6_proc = None udp6_proc = None diff --git a/setup.py b/setup.py index c79ad926d..eef7bf455 100755 --- a/setup.py +++ b/setup.py @@ -8,6 +8,7 @@ from __future__ import print_function +import ast import contextlib import glob import io @@ -101,7 +102,7 @@ def get_version(): with open(INIT) as f: for line in f: if line.startswith('__version__'): - ret = eval(line.strip().split(' = ')[1]) + ret = ast.literal_eval(line.strip().split(' = ')[1]) assert ret.count('.') == 2, ret for num in ret.split('.'): assert num.isdigit(), ret From 94cda627caa166f407b200935517100d424525da Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 10:42:14 +0200 Subject: [PATCH 13/50] run anoter fixer --- psutil/__init__.py | 4 ++-- psutil/_pslinux.py | 8 ++++---- psutil/_pswindows.py | 2 +- psutil/tests/__init__.py | 8 +++++--- scripts/internal/print_downloads.py | 4 ++-- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/psutil/__init__.py b/psutil/__init__.py index 3d47e3394..f4a19e465 100644 --- a/psutil/__init__.py +++ b/psutil/__init__.py @@ -227,8 +227,8 @@ # See: https://github.com/giampaolo/psutil/issues/564 if (int(__version__.replace('.', '')) != getattr(_psplatform.cext, 'version', None)): - msg = "version conflict: %r C extension module was built for another " \ - "version of psutil" % _psplatform.cext.__file__ + msg = "version conflict: %r C extension module was built for another " + \ + "version of psutil" % _psplatform.cext.__file__ if hasattr(_psplatform.cext, 'version'): msg += " (%s instead of %s)" % ( '.'.join([x for x in str(_psplatform.cext.version)]), __version__) diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py index 0d9110b43..32414a800 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -549,8 +549,8 @@ def swap_memory(): f = open_binary("%s/vmstat" % get_procfs_path()) except IOError as err: # see https://github.com/giampaolo/psutil/issues/722 - msg = "'sin' and 'sout' swap memory stats couldn't " \ - "be determined and were set to 0 (%s)" % str(err) + msg = "'sin' and 'sout' swap memory stats couldn't " + \ + "be determined and were set to 0 (%s)" % str(err) warnings.warn(msg, RuntimeWarning, stacklevel=2) sin = sout = 0 else: @@ -569,8 +569,8 @@ def swap_memory(): # we might get here when dealing with exotic Linux # flavors, see: # https://github.com/giampaolo/psutil/issues/313 - msg = "'sin' and 'sout' swap memory stats couldn't " \ - "be determined and were set to 0" + msg = "'sin' and 'sout' swap memory stats couldn't " + \ + "be determined and were set to 0" warnings.warn(msg, RuntimeWarning, stacklevel=2) sin = sout = 0 return _common.sswap(total, used, free, percent, sin, sout) diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py index c9e4d57d7..7fd900732 100644 --- a/psutil/_pswindows.py +++ b/psutil/_pswindows.py @@ -719,7 +719,7 @@ def wrapper(self, *args, **kwargs): else: raise else: - msg = "%s retried %s times, converted to AccessDenied as it's " \ + msg = "%s retried %s times, converted to AccessDenied as it's " + \ "still returning %r" % (fun, times, err) raise AccessDenied(pid=self.pid, name=self._name, msg=msg) return wrapper diff --git a/psutil/tests/__init__.py b/psutil/tests/__init__.py index 96f339788..59ff5dc38 100644 --- a/psutil/tests/__init__.py +++ b/psutil/tests/__init__.py @@ -368,9 +368,11 @@ def spawn_testproc(cmd=None, **kwds): testfn = get_testfn() try: safe_rmpath(testfn) - pyline = "from time import sleep;" \ - "open(r'%s', 'w').close();" \ - "sleep(60);" % testfn + pyline = ( + "from time import sleep;" + + "open(r'%s', 'w').close();" + + "sleep(60);" % testfn + ) cmd = [PYTHON_EXE, "-c", pyline] sproc = subprocess.Popen(cmd, **kwds) _subprocesses_started.add(sproc) diff --git a/scripts/internal/print_downloads.py b/scripts/internal/print_downloads.py index b6df3b38c..563fbb767 100755 --- a/scripts/internal/print_downloads.py +++ b/scripts/internal/print_downloads.py @@ -28,8 +28,8 @@ PKGNAME = 'psutil' DAYS = 30 LIMIT = 100 -GITHUB_SCRIPT_URL = "https://github.com/giampaolo/psutil/blob/master/" \ - "scripts/internal/pypistats.py" +GITHUB_SCRIPT_URL = "https://github.com/giampaolo/psutil/blob/master/" + \ + "scripts/internal/pypistats.py" LAST_UPDATE = None bytes_billed = 0 From c167bdc807f632ef428cf4e213323f55ec39b53d Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 10:44:34 +0200 Subject: [PATCH 14/50] run another fixer --- psutil/tests/test_linux.py | 4 ++-- psutil/tests/test_process.py | 2 +- scripts/iotop.py | 2 +- scripts/nettop.py | 2 +- scripts/top.py | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/psutil/tests/test_linux.py b/psutil/tests/test_linux.py index 2fc9955e0..fccc3e9a9 100755 --- a/psutil/tests/test_linux.py +++ b/psutil/tests/test_linux.py @@ -123,7 +123,7 @@ def get_ipv6_addresses(ifname): if len(all_fields) == 0: raise ValueError("could not find interface %r" % ifname) - for i in range(0, len(all_fields)): + for i in range(len(all_fields)): unformatted = all_fields[i][0] groups = [] for j in range(0, len(unformatted), 4): @@ -2178,7 +2178,7 @@ def test_status_file_parsing(self): self.assertEqual(gids.real, 1004) self.assertEqual(gids.effective, 1005) self.assertEqual(gids.saved, 1006) - self.assertEqual(p._proc._get_eligible_cpus(), list(range(0, 8))) + self.assertEqual(p._proc._get_eligible_cpus(), list(range(8))) def test_connections_enametoolong(self): # Simulate a case where /proc/{pid}/fd/{fd} symlink points to diff --git a/psutil/tests/test_process.py b/psutil/tests/test_process.py index ece7c4aac..7f78f6759 100755 --- a/psutil/tests/test_process.py +++ b/psutil/tests/test_process.py @@ -964,7 +964,7 @@ def test_cpu_affinity_all_combinations(self): if len(initial) > 12: initial = initial[:12] # ...otherwise it will take forever combos = [] - for i in range(0, len(initial) + 1): + for i in range(len(initial) + 1): for subset in itertools.combinations(initial, i): if subset: combos.append(list(subset)) diff --git a/scripts/iotop.py b/scripts/iotop.py index 07ae2fa3d..3d03d4a50 100755 --- a/scripts/iotop.py +++ b/scripts/iotop.py @@ -143,7 +143,7 @@ def refresh_window(procs, disks_read, disks_write): def setup(): curses.start_color() curses.use_default_colors() - for i in range(0, curses.COLORS): + for i in range(curses.COLORS): curses.init_pair(i + 1, i, -1) curses.endwin() win.nodelay(1) diff --git a/scripts/nettop.py b/scripts/nettop.py index 9e1abe764..84b2f0deb 100755 --- a/scripts/nettop.py +++ b/scripts/nettop.py @@ -128,7 +128,7 @@ def refresh_window(tot_before, tot_after, pnic_before, pnic_after): def setup(): curses.start_color() curses.use_default_colors() - for i in range(0, curses.COLORS): + for i in range(curses.COLORS): curses.init_pair(i + 1, i, -1) curses.endwin() win.nodelay(1) diff --git a/scripts/top.py b/scripts/top.py index d6120c796..5240268dd 100755 --- a/scripts/top.py +++ b/scripts/top.py @@ -213,7 +213,7 @@ def refresh_window(procs, procs_status): def setup(): curses.start_color() curses.use_default_colors() - for i in range(0, curses.COLORS): + for i in range(curses.COLORS): curses.init_pair(i + 1, i, -1) curses.endwin() win.nodelay(1) From 1ac91b7d6da74b98368c0c9b31462f9231211074 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 10:46:15 +0200 Subject: [PATCH 15/50] run another fixer --- psutil/tests/test_linux.py | 14 ++++++++------ scripts/internal/check_broken_links.py | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/psutil/tests/test_linux.py b/psutil/tests/test_linux.py index fccc3e9a9..ad6f4a40b 100755 --- a/psutil/tests/test_linux.py +++ b/psutil/tests/test_linux.py @@ -1597,7 +1597,7 @@ def test_percent(self): def test_emulate_power_plugged(self): # Pretend the AC power cable is connected. def open_mock(name, *args, **kwargs): - if name.endswith("AC0/online") or name.endswith("AC/online"): + if name.endswith(('AC0/online', 'AC/online')): return io.BytesIO(b"1") else: return orig_open(name, *args, **kwargs) @@ -1614,7 +1614,7 @@ def test_emulate_power_plugged_2(self): # Same as above but pretend /AC0/online does not exist in which # case code relies on /status file. def open_mock(name, *args, **kwargs): - if name.endswith("AC0/online") or name.endswith("AC/online"): + if name.endswith(('AC0/online', 'AC/online')): raise IOError(errno.ENOENT, "") elif name.endswith("/status"): return io.StringIO(u("charging")) @@ -1630,7 +1630,7 @@ def open_mock(name, *args, **kwargs): def test_emulate_power_not_plugged(self): # Pretend the AC power cable is not connected. def open_mock(name, *args, **kwargs): - if name.endswith("AC0/online") or name.endswith("AC/online"): + if name.endswith(('AC0/online', 'AC/online')): return io.BytesIO(b"0") else: return orig_open(name, *args, **kwargs) @@ -1645,7 +1645,7 @@ def test_emulate_power_not_plugged_2(self): # Same as above but pretend /AC0/online does not exist in which # case code relies on /status file. def open_mock(name, *args, **kwargs): - if name.endswith("AC0/online") or name.endswith("AC/online"): + if name.endswith(('AC0/online', 'AC/online')): raise IOError(errno.ENOENT, "") elif name.endswith("/status"): return io.StringIO(u("discharging")) @@ -1662,8 +1662,10 @@ def test_emulate_power_undetermined(self): # Pretend we can't know whether the AC power cable not # connected (assert fallback to False). def open_mock(name, *args, **kwargs): - if name.startswith("/sys/class/power_supply/AC0/online") or \ - name.startswith("/sys/class/power_supply/AC/online"): + if name.startswith( + ('/sys/class/power_supply/AC0/online', + '/sys/class/power_supply/AC/online') + ): raise IOError(errno.ENOENT, "") elif name.startswith("/sys/class/power_supply/BAT0/status"): return io.BytesIO(b"???") diff --git a/scripts/internal/check_broken_links.py b/scripts/internal/check_broken_links.py index 60f623d19..8511befde 100755 --- a/scripts/internal/check_broken_links.py +++ b/scripts/internal/check_broken_links.py @@ -172,7 +172,7 @@ def get_urls(fname): return parse_rst(fname) elif fname.endswith('.py'): return parse_py(fname) - elif fname.endswith('.c') or fname.endswith('.h'): + elif fname.endswith(('.c', '.h')): return parse_c(fname) else: with open(fname, errors='ignore') as f: From c6ac87cd361b62a869c83acb84e4de8b36e2849a Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 10:48:37 +0200 Subject: [PATCH 16/50] run another fixer --- psutil/_pslinux.py | 3 ++- psutil/_pswindows.py | 2 +- scripts/internal/clinter.py | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py index 32414a800..67df8c5d6 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -68,7 +68,8 @@ # connection status constants "CONN_ESTABLISHED", "CONN_SYN_SENT", "CONN_SYN_RECV", "CONN_FIN_WAIT1", "CONN_FIN_WAIT2", "CONN_TIME_WAIT", "CONN_CLOSE", "CONN_CLOSE_WAIT", - "CONN_LAST_ACK", "CONN_LISTEN", "CONN_CLOSING", ] + "CONN_LAST_ACK", "CONN_LISTEN", "CONN_CLOSING" +] # ===================================================================== diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py index 7fd900732..a04e951e8 100644 --- a/psutil/_pswindows.py +++ b/psutil/_pswindows.py @@ -851,7 +851,7 @@ def memory_info(self): t = self._get_raw_meminfo() rss = t[2] # wset vms = t[7] # pagefile - return pmem(*(rss, vms, ) + t) + return pmem(*(rss, vms) + t) @wrap_exceptions def memory_full_info(self): diff --git a/scripts/internal/clinter.py b/scripts/internal/clinter.py index 51b0c8ad0..71c77e402 100755 --- a/scripts/internal/clinter.py +++ b/scripts/internal/clinter.py @@ -54,7 +54,7 @@ def check_line(path, line, idx, lines): warn(path, line, lineno, "no blank line at EOF") ss = s.strip() - if ss.startswith(("printf(", "printf (", )): + if ss.startswith(("printf(", "printf (")): if not ss.endswith(("// NOQA", "// NOQA")): warn(path, line, lineno, "printf() statement") From 6c38c3b333d8d67743b5ad631615365a008ffd73 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 10:50:48 +0200 Subject: [PATCH 17/50] run another fixer --- psutil/_common.py | 2 +- psutil/tests/test_posix.py | 2 +- pyproject.toml | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/psutil/_common.py b/psutil/_common.py index a8a868b5f..e0197b6c5 100644 --- a/psutil/_common.py +++ b/psutil/_common.py @@ -689,7 +689,7 @@ def run(self, input_dict, name): old_dict = self.cache[name] new_dict = {} - for key in input_dict.keys(): + for key in input_dict: input_tuple = input_dict[key] try: old_tuple = old_dict[key] diff --git a/psutil/tests/test_posix.py b/psutil/tests/test_posix.py index e04397d05..be8f2bcd2 100755 --- a/psutil/tests/test_posix.py +++ b/psutil/tests/test_posix.py @@ -321,7 +321,7 @@ def test_pids(self): @unittest.skipIf(not HAS_NET_IO_COUNTERS, "not supported") def test_nic_names(self): output = sh("ifconfig -a") - for nic in psutil.net_io_counters(pernic=True).keys(): + for nic in psutil.net_io_counters(pernic=True): for line in output.split(): if line.startswith(nic): break diff --git a/pyproject.toml b/pyproject.toml index 4dbae3b73..d2abedeb9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,6 +55,7 @@ ignore = [ "UP010", # [*] Unnecessary `__future__` import `print_function` for target Python version (PYTHON2.7 COMPAT) "UP024", # [*] Replace aliased errors with `OSError` (PYTHON2.7 COMPAT) "UP031", # [*] Use format specifiers instead of percent format + "UP032", # [*] Use f-string instead of `format` call (PYTHON2.7 COMPAT) ] [tool.ruff.per-file-ignores] From d67ff0f5ed0c31205613fe0058bc27cdbfbd1b06 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 10:53:59 +0200 Subject: [PATCH 18/50] fix str formatting --- psutil/__init__.py | 4 ++-- psutil/tests/__init__.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/psutil/__init__.py b/psutil/__init__.py index f4a19e465..5538df010 100644 --- a/psutil/__init__.py +++ b/psutil/__init__.py @@ -227,8 +227,8 @@ # See: https://github.com/giampaolo/psutil/issues/564 if (int(__version__.replace('.', '')) != getattr(_psplatform.cext, 'version', None)): - msg = "version conflict: %r C extension module was built for another " + \ - "version of psutil" % _psplatform.cext.__file__ + msg = "version conflict: %r C extension " % _psplatform.cext.__file__ + msg += "module was built for another version of psutil" if hasattr(_psplatform.cext, 'version'): msg += " (%s instead of %s)" % ( '.'.join([x for x in str(_psplatform.cext.version)]), __version__) diff --git a/psutil/tests/__init__.py b/psutil/tests/__init__.py index 59ff5dc38..35edb75c6 100644 --- a/psutil/tests/__init__.py +++ b/psutil/tests/__init__.py @@ -370,8 +370,8 @@ def spawn_testproc(cmd=None, **kwds): safe_rmpath(testfn) pyline = ( "from time import sleep;" + - "open(r'%s', 'w').close();" + - "sleep(60);" % testfn + "open(r'%s', 'w').close();" % testfn + + "sleep(60);" ) cmd = [PYTHON_EXE, "-c", pyline] sproc = subprocess.Popen(cmd, **kwds) From 718d148b77ebca46cfacdbd3ad1458ee59dc5c71 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 10:55:36 +0200 Subject: [PATCH 19/50] run another fixer --- psutil/tests/test_contracts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psutil/tests/test_contracts.py b/psutil/tests/test_contracts.py index 040807821..cd0509174 100755 --- a/psutil/tests/test_contracts.py +++ b/psutil/tests/test_contracts.py @@ -195,7 +195,7 @@ def test_cpu_num(self): def test_memory_maps(self): hasit = hasattr(psutil.Process, "memory_maps") self.assertEqual( - hasit, False if OPENBSD or NETBSD or AIX or MACOS else True) + hasit, not (OPENBSD or NETBSD or AIX or MACOS)) # =================================================================== From 72c2540f6a57df7b61834e63628d8d078462277d Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 10:56:01 +0200 Subject: [PATCH 20/50] run another fixer --- psutil/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psutil/__init__.py b/psutil/__init__.py index 5538df010..82155b9cc 100644 --- a/psutil/__init__.py +++ b/psutil/__init__.py @@ -2197,7 +2197,7 @@ def net_if_addrs(): if WINDOWS and fam == -1: fam = _psplatform.AF_LINK elif (hasattr(_psplatform, "AF_LINK") and - _psplatform.AF_LINK == fam): + fam == _psplatform.AF_LINK): # Linux defines AF_LINK as an alias for AF_PACKET. # We re-set the family here so that repr(family) # will show AF_LINK rather than AF_PACKET From 1adf92dc230732862dc33c6152cc8086fa101352 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 10:57:12 +0200 Subject: [PATCH 21/50] run another fixer --- psutil/tests/test_windows.py | 2 +- pyproject.toml | 1 + scripts/internal/print_downloads.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/psutil/tests/test_windows.py b/psutil/tests/test_windows.py index bb6faabe2..21b7b4428 100755 --- a/psutil/tests/test_windows.py +++ b/psutil/tests/test_windows.py @@ -379,7 +379,7 @@ def test_special_pid(self): rss, vms = p.memory_info()[:2] except psutil.AccessDenied: # expected on Windows Vista and Windows 7 - if not platform.uname()[1] in ('vista', 'win-7', 'win7'): + if platform.uname()[1] not in ('vista', 'win-7', 'win7'): raise else: self.assertGreater(rss, 0) diff --git a/pyproject.toml b/pyproject.toml index d2abedeb9..e319fcf6b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,6 +54,7 @@ ignore = [ "UP009", # [*] UTF-8 encoding declaration is unnecessary (PYTHON2.7 COMPAT) "UP010", # [*] Unnecessary `__future__` import `print_function` for target Python version (PYTHON2.7 COMPAT) "UP024", # [*] Replace aliased errors with `OSError` (PYTHON2.7 COMPAT) + "UP028", # [*] Replace `yield` over `for` loop with `yield from` (PYTHON2.7 COMPAT) "UP031", # [*] Use format specifiers instead of percent format "UP032", # [*] Use f-string instead of `format` call (PYTHON2.7 COMPAT) ] diff --git a/scripts/internal/print_downloads.py b/scripts/internal/print_downloads.py index 563fbb767..3d9fac094 100755 --- a/scripts/internal/print_downloads.py +++ b/scripts/internal/print_downloads.py @@ -108,7 +108,7 @@ def downloads_by_distro(): def print_row(left, right): if isinstance(right, int): - right = '{0:,}'.format(right) + right = '{:,}'.format(right) print(templ % (left, right)) From 5315b34494230305ef1dfdb94a50c72aef191ca1 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 10:59:46 +0200 Subject: [PATCH 22/50] fix str format --- psutil/_pswindows.py | 4 ++-- psutil/tests/test_memleaks.py | 0 2 files changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 psutil/tests/test_memleaks.py diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py index a04e951e8..72f6f776c 100644 --- a/psutil/_pswindows.py +++ b/psutil/_pswindows.py @@ -719,8 +719,8 @@ def wrapper(self, *args, **kwargs): else: raise else: - msg = "%s retried %s times, converted to AccessDenied as it's " + \ - "still returning %r" % (fun, times, err) + msg = "{} retried {} times, converted to AccessDenied as it's " + \ + "still returning {}".format(fun, times, err) raise AccessDenied(pid=self.pid, name=self._name, msg=msg) return wrapper diff --git a/psutil/tests/test_memleaks.py b/psutil/tests/test_memleaks.py old mode 100644 new mode 100755 From 52db13d6863883b9c5d9ff78aa4a40eb06f54ece Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 11:01:41 +0200 Subject: [PATCH 23/50] run another fixer --- psutil/_common.py | 2 +- psutil/_compat.py | 2 +- scripts/internal/git_pre_commit.py | 2 +- scripts/internal/winmake.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/psutil/_common.py b/psutil/_common.py index e0197b6c5..8d73802d8 100644 --- a/psutil/_common.py +++ b/psutil/_common.py @@ -37,7 +37,7 @@ # can't take it from _common.py as this script is imported by setup.py -PY3 = sys.version_info[0] == 3 +PY3 = sys.version_info[0] >= 3 if PY3: import enum else: diff --git a/psutil/_compat.py b/psutil/_compat.py index c85799d26..18eabcdd8 100644 --- a/psutil/_compat.py +++ b/psutil/_compat.py @@ -34,7 +34,7 @@ "InterruptedError", "ChildProcessError", "FileExistsError"] -PY3 = sys.version_info[0] == 3 +PY3 = sys.version_info[0] >= 3 _SENTINEL = object() if PY3: diff --git a/scripts/internal/git_pre_commit.py b/scripts/internal/git_pre_commit.py index 8d3049d00..14268f037 100755 --- a/scripts/internal/git_pre_commit.py +++ b/scripts/internal/git_pre_commit.py @@ -30,7 +30,7 @@ PYTHON = sys.executable -PY3 = sys.version_info[0] == 3 +PY3 = sys.version_info[0] >= 3 THIS_SCRIPT = os.path.realpath(__file__) diff --git a/scripts/internal/winmake.py b/scripts/internal/winmake.py index 9ee90f0f9..222bf5cf3 100755 --- a/scripts/internal/winmake.py +++ b/scripts/internal/winmake.py @@ -31,7 +31,7 @@ PYTHON = sys.executable if APPVEYOR else os.getenv('PYTHON', sys.executable) RUNNER_PY = 'psutil\\tests\\runner.py' GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py" -PY3 = sys.version_info[0] == 3 +PY3 = sys.version_info[0] >= 3 HERE = os.path.abspath(os.path.dirname(__file__)) ROOT_DIR = os.path.realpath(os.path.join(HERE, "..", "..")) PYPY = '__pypy__' in sys.builtin_module_names From 92f1f6bcd642fc4a0f8cef257a93b29123eca2c6 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 11:04:36 +0200 Subject: [PATCH 24/50] run another fixer --- psutil/_pslinux.py | 4 ++-- scripts/internal/print_downloads.py | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py index 67df8c5d6..d6028489b 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -570,8 +570,8 @@ def swap_memory(): # we might get here when dealing with exotic Linux # flavors, see: # https://github.com/giampaolo/psutil/issues/313 - msg = "'sin' and 'sout' swap memory stats couldn't " + \ - "be determined and were set to 0" + msg = "'sin' and 'sout' swap memory stats couldn't " + msg += "be determined and were set to 0" warnings.warn(msg, RuntimeWarning, stacklevel=2) sin = sout = 0 return _common.sswap(total, used, free, percent, sin, sout) diff --git a/scripts/internal/print_downloads.py b/scripts/internal/print_downloads.py index 3d9fac094..bceef3c87 100755 --- a/scripts/internal/print_downloads.py +++ b/scripts/internal/print_downloads.py @@ -28,8 +28,10 @@ PKGNAME = 'psutil' DAYS = 30 LIMIT = 100 -GITHUB_SCRIPT_URL = "https://github.com/giampaolo/psutil/blob/master/" + \ +GITHUB_SCRIPT_URL = ( + "https://github.com/giampaolo/psutil/blob/master/" "scripts/internal/pypistats.py" +) LAST_UPDATE = None bytes_billed = 0 From 0447fe6f430d4ffcc9ddee8a0d90c760d4d9d999 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 11:11:36 +0200 Subject: [PATCH 25/50] run another fixer --- scripts/internal/git_pre_commit.py | 6 +++--- scripts/internal/print_api_speed.py | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/scripts/internal/git_pre_commit.py b/scripts/internal/git_pre_commit.py index 14268f037..e44045b85 100755 --- a/scripts/internal/git_pre_commit.py +++ b/scripts/internal/git_pre_commit.py @@ -111,9 +111,9 @@ def isort(files): print("running isort (%s)" % len(files)) cmd = [PYTHON, "-m", "isort", "--check-only"] + files if subprocess.call(cmd) != 0: - return sys.exit( - "python code didn't pass 'isort' style check; " + - "try running 'make fix-imports'") + msg = "python code didn't pass 'isort' style check; " + msg += "try running 'make fix-imports'" + return sys.exit(msg) def c_linter(files): diff --git a/scripts/internal/print_api_speed.py b/scripts/internal/print_api_speed.py index e85b70382..2d62320f9 100755 --- a/scripts/internal/print_api_speed.py +++ b/scripts/internal/print_api_speed.py @@ -192,8 +192,9 @@ def main(): print_timings() if not prio_set: - print_color("\nWARN: couldn't set highest process priority " + - "(requires root)", "red") + msg = "\nWARN: couldn't set highest process priority " + msg += "(requires root)", "red" + print_color(msg) if __name__ == '__main__': From adf6449d759ef36c1631fa66526ca11445e8fad9 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 11:18:16 +0200 Subject: [PATCH 26/50] run another fixer --- psutil/__init__.py | 2 +- psutil/_compat.py | 2 +- psutil/_psbsd.py | 4 ++-- psutil/tests/__init__.py | 2 +- psutil/tests/runner.py | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/psutil/__init__.py b/psutil/__init__.py index 82155b9cc..1d140591e 100644 --- a/psutil/__init__.py +++ b/psutil/__init__.py @@ -2422,7 +2422,7 @@ def test(): # pragma: no cover del memoize_when_activated, division if sys.version_info[0] < 3: - del num, x + del num, x # noqa if __name__ == "__main__": test() diff --git a/psutil/_compat.py b/psutil/_compat.py index 18eabcdd8..3e6cf53a4 100644 --- a/psutil/_compat.py +++ b/psutil/_compat.py @@ -222,7 +222,7 @@ def FileExistsError(inst): "CacheInfo", ["hits", "misses", "maxsize", "currsize"]) class _HashedSeq(list): - __slots__ = 'hashvalue' + __slots__ = ('hashvalue', ) def __init__(self, tup, hash=hash): self[:] = tup diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py index f0fdaf543..833b67cec 100644 --- a/psutil/_psbsd.py +++ b/psutil/_psbsd.py @@ -8,7 +8,7 @@ import errno import functools import os -import xml.etree.ElementTree as ET +import xml.etree.ElementTree as ElementTree from collections import defaultdict from collections import namedtuple @@ -284,7 +284,7 @@ def cpu_count_cores(): index = s.rfind("") if index != -1: s = s[:index + 9] - root = ET.fromstring(s) + root = ElementTree.fromstring(s) try: ret = len(root.findall('group/children/group/cpu')) or None finally: diff --git a/psutil/tests/__init__.py b/psutil/tests/__init__.py index 35edb75c6..9adaeed37 100644 --- a/psutil/tests/__init__.py +++ b/psutil/tests/__init__.py @@ -893,7 +893,7 @@ def __str__(self): # assertRaisesRegexp renamed to assertRaisesRegex in 3.3; # add support for the new name. if not hasattr(unittest.TestCase, 'assertRaisesRegex'): - assertRaisesRegex = unittest.TestCase.assertRaisesRegexp + assertRaisesRegex = unittest.TestCase.assertRaisesRegexp # noqa # ...otherwise multiprocessing.Pool complains if not PY3: diff --git a/psutil/tests/runner.py b/psutil/tests/runner.py index 4d4b7929f..730058967 100755 --- a/psutil/tests/runner.py +++ b/psutil/tests/runner.py @@ -59,7 +59,7 @@ USE_COLORS = not CI_TESTING and term_supports_colors() HERE = os.path.abspath(os.path.dirname(__file__)) -loadTestsFromTestCase = unittest.defaultTestLoader.loadTestsFromTestCase +loadTestsFromTestCase = unittest.defaultTestLoader.loadTestsFromTestCase # noqa def cprint(msg, color, bold=False, file=None): From 770fb506af74f1da160249304562d3655705a6f7 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 11:20:01 +0200 Subject: [PATCH 27/50] run another fixer --- psutil/tests/test_linux.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psutil/tests/test_linux.py b/psutil/tests/test_linux.py index ad6f4a40b..7d5538863 100755 --- a/psutil/tests/test_linux.py +++ b/psutil/tests/test_linux.py @@ -1779,7 +1779,7 @@ def open_mock(name, *args, **kwargs): return orig_open(name, *args, **kwargs) def glob_mock(path): - if path == '/sys/class/hwmon/hwmon*/temp*_*': + if path == '/sys/class/hwmon/hwmon*/temp*_*': # noqa: SIM116 return [] elif path == '/sys/class/hwmon/hwmon*/device/temp*_*': return [] From 793ae88b73556936fdaaa7ee2175f8e00d67fcd0 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 11:21:10 +0200 Subject: [PATCH 28/50] run another fixer --- psutil/_psposix.py | 2 +- psutil/_pswindows.py | 4 +++- psutil/tests/test_linux.py | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/psutil/_psposix.py b/psutil/_psposix.py index 0039daf44..4144b5902 100644 --- a/psutil/_psposix.py +++ b/psutil/_psposix.py @@ -78,7 +78,7 @@ def negsig_to_enum(num): def wait_pid(pid, timeout=None, proc_name=None, _waitpid=os.waitpid, - _timer=getattr(time, 'monotonic', time.time), + _timer=getattr(time, 'monotonic', time.time), # noqa: B008 _min=min, _sleep=time.sleep, _pid_exists=pid_exists): diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py index 72f6f776c..b68c7dd4f 100644 --- a/psutil/_pswindows.py +++ b/psutil/_pswindows.py @@ -719,8 +719,10 @@ def wrapper(self, *args, **kwargs): else: raise else: - msg = "{} retried {} times, converted to AccessDenied as it's " + \ + msg = ( + "{} retried {} times, converted to AccessDenied as it's " "still returning {}".format(fun, times, err) + ) raise AccessDenied(pid=self.pid, name=self._name, msg=msg) return wrapper diff --git a/psutil/tests/test_linux.py b/psutil/tests/test_linux.py index 7d5538863..55839a1ba 100755 --- a/psutil/tests/test_linux.py +++ b/psutil/tests/test_linux.py @@ -1779,7 +1779,7 @@ def open_mock(name, *args, **kwargs): return orig_open(name, *args, **kwargs) def glob_mock(path): - if path == '/sys/class/hwmon/hwmon*/temp*_*': # noqa: SIM116 + if path == '/sys/class/hwmon/hwmon*/temp*_*': # noqa return [] elif path == '/sys/class/hwmon/hwmon*/device/temp*_*': return [] From c9805e5223dd25276ec64161e9d9c6f933c28422 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 11:22:11 +0200 Subject: [PATCH 29/50] run another fixer --- psutil/_common.py | 2 +- psutil/_pslinux.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/psutil/_common.py b/psutil/_common.py index 8d73802d8..4df75c3ff 100644 --- a/psutil/_common.py +++ b/psutil/_common.py @@ -286,7 +286,7 @@ def _infodict(self, attrs): info = collections.OrderedDict() for name in attrs: value = getattr(self, name, None) - if value: + if value: # noqa info[name] = value elif name == "pid" and value == 0: info[name] = value diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py index d6028489b..ce4e0bc8b 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -959,7 +959,7 @@ def process_unix(file, family, inodes, filter_pid=None): raise RuntimeError( "error while parsing %s; malformed line %r" % ( file, line)) - if inode in inodes: + if inode in inodes: # noqa # With UNIX sockets we can have a single inode # referencing many file descriptors. pairs = inodes[inode] From 03b2a6dda5f3f4ad118d4a3769b522da494dff66 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 11:27:48 +0200 Subject: [PATCH 30/50] run another fixer --- psutil/tests/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/psutil/tests/__init__.py b/psutil/tests/__init__.py index 9adaeed37..9d2a82551 100644 --- a/psutil/tests/__init__.py +++ b/psutil/tests/__init__.py @@ -1914,4 +1914,4 @@ def cleanup_test_procs(): # module. With this it will. See: # https://gmpy.dev/blog/2016/how-to-always-execute-exit-functions-in-python if POSIX: - signal.signal(signal.SIGTERM, lambda sig, frame: sys.exit(sig)) + signal.signal(signal.SIGTERM, lambda sig, _: sys.exit(sig)) From 1eadac7b5c347aceef5a5b1f7b2868e3aeee04db Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 11:39:19 +0200 Subject: [PATCH 31/50] add 1 docstyle rule --- psutil/_common.py | 5 +++++ psutil/_pslinux.py | 1 + psutil/tests/__init__.py | 3 +++ psutil/tests/runner.py | 1 + psutil/tests/test_process.py | 1 + psutil/tests/test_unicode.py | 2 ++ pyproject.toml | 1 + 7 files changed, 14 insertions(+) diff --git a/psutil/_common.py b/psutil/_common.py index 4df75c3ff..9749d394c 100644 --- a/psutil/_common.py +++ b/psutil/_common.py @@ -280,6 +280,7 @@ class Error(Exception): """Base exception class. All other psutil exceptions inherit from this one. """ + __module__ = 'psutil' def _infodict(self, attrs): @@ -313,6 +314,7 @@ class NoSuchProcess(Error): """Exception raised when a process with a certain PID doesn't or no longer exists. """ + __module__ = 'psutil' def __init__(self, pid, name=None, msg=None): @@ -329,6 +331,7 @@ class ZombieProcess(NoSuchProcess): On Linux all zombie processes are querable (hence this is never raised). Windows doesn't have zombie processes. """ + __module__ = 'psutil' def __init__(self, pid, name=None, ppid=None, msg=None): @@ -339,6 +342,7 @@ def __init__(self, pid, name=None, ppid=None, msg=None): class AccessDenied(Error): """Exception raised when permission to perform an action is denied.""" + __module__ = 'psutil' def __init__(self, pid=None, name=None, msg=None): @@ -352,6 +356,7 @@ class TimeoutExpired(Error): """Raised on Process.wait(timeout) if timeout expires and process is still alive. """ + __module__ = 'psutil' def __init__(self, seconds, pid=None, name=None): diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py index ce4e0bc8b..860cbd622 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -1191,6 +1191,7 @@ class RootFsDeviceFinder: https://bootlin.com/blog/find-root-device/ https://www.systutorials.com/how-to-find-the-disk-where-root-is-on-in-bash-on-linux/ """ + __slots__ = ['major', 'minor'] def __init__(self): diff --git a/psutil/tests/__init__.py b/psutil/tests/__init__.py index 9d2a82551..8c492c75b 100644 --- a/psutil/tests/__init__.py +++ b/psutil/tests/__init__.py @@ -1083,6 +1083,7 @@ class TestLeaks(psutil.tests.TestMemoryLeak): def test_fun(self): self.execute(some_function) """ + # Configurable class attrs. times = 200 warmup_times = 10 @@ -1315,6 +1316,7 @@ class process_namespace: >>> for fun, name in ns.iter(ns.getters): ... fun() """ + utils = [ ('cpu_percent', (), {}), ('memory_percent', (), {}), @@ -1451,6 +1453,7 @@ class system_namespace: >>> for fun, name in ns.iter(ns.getters): ... fun() """ + getters = [ ('boot_time', (), {}), ('cpu_count', (), {'logical': False}), diff --git a/psutil/tests/runner.py b/psutil/tests/runner.py index 730058967..90c707545 100755 --- a/psutil/tests/runner.py +++ b/psutil/tests/runner.py @@ -149,6 +149,7 @@ class ColouredTextRunner(unittest.TextTestRunner): A coloured text runner which also prints failed tests on KeyboardInterrupt and save failed tests in a file so that they can be re-run. """ + resultclass = ColouredResult if USE_COLORS else unittest.TextTestResult def __init__(self, *args, **kwargs): diff --git a/psutil/tests/test_process.py b/psutil/tests/test_process.py index 7f78f6759..6a90c5b93 100755 --- a/psutil/tests/test_process.py +++ b/psutil/tests/test_process.py @@ -1462,6 +1462,7 @@ class LimitedUserTestCase(TestProcess): 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() diff --git a/psutil/tests/test_unicode.py b/psutil/tests/test_unicode.py index c7d8dfbc0..4614039ce 100755 --- a/psutil/tests/test_unicode.py +++ b/psutil/tests/test_unicode.py @@ -309,6 +309,7 @@ def normpath(p): @unittest.skipIf(CI_TESTING, "unreliable on CI") class TestFSAPIsWithInvalidPath(TestFSAPIs): """Test FS APIs with a funky, invalid path name.""" + funky_suffix = INVALID_UNICODE_SUFFIX def expect_exact_path_match(self): @@ -323,6 +324,7 @@ def expect_exact_path_match(self): class TestNonFSAPIS(BaseUnicodeTest): """Unicode tests for non fs-related APIs.""" + funky_suffix = UNICODE_SUFFIX if PY3 else 'è' @unittest.skipIf(not HAS_ENVIRON, "not supported") diff --git a/pyproject.toml b/pyproject.toml index e319fcf6b..3cb60ea64 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,6 +4,7 @@ target-version = "py37" line-length = 79 select = [ "ALL", # to get a list of all values: `python3 -m ruff linter` + "D204", # [*] 1 blank line required after class docstring (pydocstyle) ] ignore = [ "A", # flake8-builtins From 17b3a67977bdcb1804176bc1f7dd5d1e8bc7b7d1 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 11:40:52 +0200 Subject: [PATCH 32/50] add 1 docstyle rule --- psutil/_pslinux.py | 3 +-- psutil/tests/__init__.py | 4 +--- psutil/tests/test_misc.py | 4 +--- psutil/tests/test_testutils.py | 4 +--- pyproject.toml | 1 + scripts/internal/generate_manifest.py | 4 +--- scripts/internal/print_timeline.py | 4 +--- scripts/killall.py | 4 +--- 8 files changed, 8 insertions(+), 20 deletions(-) diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py index 860cbd622..a5c46db51 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -711,8 +711,7 @@ def cpu_stats(): def _cpu_get_cpuinfo_freq(): - """Return current CPU frequency from cpuinfo if available. - """ + """Return current CPU frequency from cpuinfo if available.""" ret = [] with open_binary('%s/cpuinfo' % get_procfs_path()) as f: for line in f: diff --git a/psutil/tests/__init__.py b/psutil/tests/__init__.py index 8c492c75b..cf7e58660 100644 --- a/psutil/tests/__init__.py +++ b/psutil/tests/__init__.py @@ -4,9 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Test utilities. -""" +"""Test utilities.""" from __future__ import print_function diff --git a/psutil/tests/test_misc.py b/psutil/tests/test_misc.py index 35014294a..d2880d5f8 100755 --- a/psutil/tests/test_misc.py +++ b/psutil/tests/test_misc.py @@ -5,9 +5,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Miscellaneous tests. -""" +"""Miscellaneous tests.""" import ast import collections diff --git a/psutil/tests/test_testutils.py b/psutil/tests/test_testutils.py index 58d348416..bff43b1c9 100755 --- a/psutil/tests/test_testutils.py +++ b/psutil/tests/test_testutils.py @@ -5,9 +5,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Tests for testing utils (psutil.tests namespace). -""" +"""Tests for testing utils (psutil.tests namespace).""" import collections import contextlib diff --git a/pyproject.toml b/pyproject.toml index 3cb60ea64..106730ec8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,6 +4,7 @@ target-version = "py37" line-length = 79 select = [ "ALL", # to get a list of all values: `python3 -m ruff linter` + "D200", # [*] One-line docstring should fit on one line (pydocstyle) "D204", # [*] 1 blank line required after class docstring (pydocstyle) ] ignore = [ diff --git a/scripts/internal/generate_manifest.py b/scripts/internal/generate_manifest.py index b7ad8c7e1..53725163d 100755 --- a/scripts/internal/generate_manifest.py +++ b/scripts/internal/generate_manifest.py @@ -4,9 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Generate MANIFEST.in file. -""" +"""Generate MANIFEST.in file.""" import os import subprocess diff --git a/scripts/internal/print_timeline.py b/scripts/internal/print_timeline.py index 0ea7355eb..54cab8956 100755 --- a/scripts/internal/print_timeline.py +++ b/scripts/internal/print_timeline.py @@ -4,9 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Prints releases' timeline in RST format. -""" +"""Prints releases' timeline in RST format.""" import subprocess diff --git a/scripts/killall.py b/scripts/killall.py index d985185f8..0308370de 100755 --- a/scripts/killall.py +++ b/scripts/killall.py @@ -4,9 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Kill a process by name. -""" +"""Kill a process by name.""" import os import sys From 7f4baf77691ac32b24b156744885b5aa27c215c8 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 11:53:30 +0200 Subject: [PATCH 33/50] add 1 docstyle rule --- psutil/tests/__init__.py | 2 +- psutil/tests/test_misc.py | 8 ++++---- pyproject.toml | 1 + scripts/internal/check_broken_links.py | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/psutil/tests/__init__.py b/psutil/tests/__init__.py index cf7e58660..d4d8faf6d 100644 --- a/psutil/tests/__init__.py +++ b/psutil/tests/__init__.py @@ -490,7 +490,7 @@ def pyrun(src, **kwds): @_reap_children_on_err def sh(cmd, **kwds): - """run cmd in a subprocess and return its output. + """Run cmd in a subprocess and return its output. raises RuntimeError on error. """ # Prevents subprocess to open error dialogs in case of error. diff --git a/psutil/tests/test_misc.py b/psutil/tests/test_misc.py index d2880d5f8..47877b558 100755 --- a/psutil/tests/test_misc.py +++ b/psutil/tests/test_misc.py @@ -334,7 +334,7 @@ def run_against(self, obj, expected_retval=None): def test_function(self): @memoize def foo(*args, **kwargs): - """my docstring""" + """My docstring""" baseclass.calls.append((args, kwargs)) return 22 @@ -374,7 +374,7 @@ class Foo: @staticmethod @memoize def bar(*args, **kwargs): - """my docstring""" + """My docstring""" baseclass.calls.append((args, kwargs)) return 22 @@ -386,7 +386,7 @@ class Foo: @classmethod @memoize def bar(cls, *args, **kwargs): - """my docstring""" + """My docstring""" baseclass.calls.append((args, kwargs)) return 22 @@ -398,7 +398,7 @@ def test_original(self): # against different types. Keeping it anyway. @memoize def foo(*args, **kwargs): - """foo docstring""" + """Foo docstring""" calls.append(None) return (args, kwargs) diff --git a/pyproject.toml b/pyproject.toml index 106730ec8..073254151 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,6 +6,7 @@ select = [ "ALL", # to get a list of all values: `python3 -m ruff linter` "D200", # [*] One-line docstring should fit on one line (pydocstyle) "D204", # [*] 1 blank line required after class docstring (pydocstyle) + "D403", # [*] First word of the first line should be capitalized ] ignore = [ "A", # flake8-builtins diff --git a/scripts/internal/check_broken_links.py b/scripts/internal/check_broken_links.py index 8511befde..d36ab3284 100755 --- a/scripts/internal/check_broken_links.py +++ b/scripts/internal/check_broken_links.py @@ -198,7 +198,7 @@ def validate_url(url): def parallel_validator(urls): - """validates all urls in parallel + """Validates all urls in parallel urls: tuple(filename, url) """ fails = [] # list of tuples (filename, url) From aa335dc3460275d65a9426c92c84369b6336b05b Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 12:49:51 +0200 Subject: [PATCH 34/50] add 1 docstyle rule --- psutil/_common.py | 11 +++---- psutil/_compat.py | 6 ++-- psutil/_psaix.py | 4 +-- psutil/_psbsd.py | 8 ++--- psutil/_pslinux.py | 8 ++--- psutil/_psosx.py | 4 +-- psutil/_psposix.py | 2 +- psutil/_pssunos.py | 4 +-- psutil/_pswindows.py | 6 ++-- psutil/tests/__main__.py | 2 +- psutil/tests/runner.py | 2 +- psutil/tests/test_contracts.py | 4 +-- psutil/tests/test_misc.py | 10 +++--- psutil/tests/test_unicode.py | 2 +- psutil/tests/test_windows.py | 2 +- pyproject.toml | 1 + scripts/internal/bench_oneshot.py | 2 +- scripts/internal/check_broken_links.py | 2 +- scripts/internal/download_wheels_appveyor.py | 2 +- scripts/internal/download_wheels_github.py | 2 +- scripts/internal/print_announce.py | 2 +- scripts/internal/print_downloads.py | 2 +- scripts/internal/print_hashes.py | 2 +- scripts/internal/winmake.py | 34 ++++++++++---------- scripts/pidof.py | 1 + scripts/procinfo.py | 1 + 26 files changed, 64 insertions(+), 62 deletions(-) diff --git a/psutil/_common.py b/psutil/_common.py index 9749d394c..a4116e5fc 100644 --- a/psutil/_common.py +++ b/psutil/_common.py @@ -519,7 +519,7 @@ def cache_deactivate(proc): def isfile_strict(path): """Same as os.path.isfile() but does not swallow EACCES / EPERM exceptions, see: - http://mail.python.org/pipermail/python-dev/2012-June/120787.html + http://mail.python.org/pipermail/python-dev/2012-June/120787.html. """ try: st = os.stat(path) @@ -533,8 +533,8 @@ def isfile_strict(path): def path_exists_strict(path): """Same as os.path.exists() but does not swallow EACCES / EPERM - exceptions, see: - http://mail.python.org/pipermail/python-dev/2012-June/120787.html + exceptions. See: + http://mail.python.org/pipermail/python-dev/2012-June/120787.html. """ try: os.stat(path) @@ -683,7 +683,7 @@ def _remove_dead_reminders(self, input_dict, name): def run(self, input_dict, name): """Cache dict and sum numbers which overflow and wrap. - Return an updated copy of `input_dict` + Return an updated copy of `input_dict`. """ if name not in self.cache: # This was the first call. @@ -820,8 +820,7 @@ def bcat(fname, fallback=_DEFAULT): def bytes2human(n, format="%(value).1f%(symbol)s"): - """Used by various scripts. See: - http://goo.gl/zeJZl + """Used by various scripts. See: http://goo.gl/zeJZl. >>> bytes2human(10000) '9.8K' diff --git a/psutil/_compat.py b/psutil/_compat.py index 3e6cf53a4..95754113d 100644 --- a/psutil/_compat.py +++ b/psutil/_compat.py @@ -251,7 +251,7 @@ def _make_key(args, kwds, typed, def lru_cache(maxsize=100, typed=False): """Least-recently-used cache decorator, see: - http://docs.python.org/3/library/functools.html#functools.lru_cache + http://docs.python.org/3/library/functools.html#functools.lru_cache. """ def decorating_function(user_function): cache = {} @@ -328,7 +328,7 @@ def wrapper(*args, **kwds): return result def cache_info(): - """Report cache statistics""" + """Report cache statistics.""" lock.acquire() try: return _CacheInfo(stats[HITS], stats[MISSES], maxsize, @@ -337,7 +337,7 @@ def cache_info(): lock.release() def cache_clear(): - """Clear the cache and cache statistics""" + """Clear the cache and cache statistics.""" lock.acquire() try: cache.clear() diff --git a/psutil/_psaix.py b/psutil/_psaix.py index 39b15229f..24f64a0c6 100644 --- a/psutil/_psaix.py +++ b/psutil/_psaix.py @@ -123,13 +123,13 @@ def swap_memory(): def cpu_times(): - """Return system-wide CPU times as a named tuple""" + """Return system-wide CPU times as a named tuple.""" ret = cext.per_cpu_times() return scputimes(*[sum(x) for x in zip(*ret)]) def per_cpu_times(): - """Return system per-CPU times as a list of named tuples""" + """Return system per-CPU times as a list of named tuples.""" ret = cext.per_cpu_times() return [scputimes(*x) for x in ret] diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py index 833b67cec..6f6cce1ec 100644 --- a/psutil/_psbsd.py +++ b/psutil/_psbsd.py @@ -226,14 +226,14 @@ def swap_memory(): def cpu_times(): - """Return system per-CPU times as a namedtuple""" + """Return system per-CPU times as a namedtuple.""" user, nice, system, idle, irq = cext.cpu_times() return scputimes(user, nice, system, idle, irq) if HAS_PER_CPU_TIMES: def per_cpu_times(): - """Return system CPU times as a namedtuple""" + """Return system CPU times as a namedtuple.""" ret = [] for cpu_t in cext.per_cpu_times(): user, nice, system, idle, irq = cpu_t @@ -249,7 +249,7 @@ def per_cpu_times(): # crash at psutil import time. # Next calls will fail with NotImplementedError def per_cpu_times(): - """Return system CPU times as a namedtuple""" + """Return system CPU times as a namedtuple.""" if cpu_count_logical() == 1: return [cpu_times()] if per_cpu_times.__called__: @@ -365,7 +365,7 @@ def cpu_freq(): def disk_partitions(all=False): """Return mounted disk partitions as a list of namedtuples. 'all' argument is ignored, see: - https://github.com/giampaolo/psutil/issues/906 + https://github.com/giampaolo/psutil/issues/906. """ retlist = [] partitions = cext.disk_partitions() diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py index a5c46db51..cc37c0615 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -346,7 +346,7 @@ class StructRlimit(ctypes.Structure): def calculate_avail_vmem(mems): """Fallback for kernels < 3.14 where /proc/meminfo does not provide "MemAvailable", see: - https://blog.famzah.net/2014/09/24/ + https://blog.famzah.net/2014/09/24/. This code reimplements the algorithm outlined here: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/ @@ -1188,7 +1188,7 @@ class RootFsDeviceFinder: or "rootfs". This container class uses different strategies to try to obtain the real device path. Resources: https://bootlin.com/blog/find-root-device/ - https://www.systutorials.com/how-to-find-the-disk-where-root-is-on-in-bash-on-linux/ + https://www.systutorials.com/how-to-find-the-disk-where-root-is-on-in-bash-on-linux/. """ __slots__ = ['major', 'minor'] @@ -1453,7 +1453,7 @@ def sensors_battery(): Implementation note: it appears /sys/class/power_supply/BAT0/ directory structure may vary and provide files with the same meaning but under different names, see: - https://github.com/giampaolo/psutil/issues/966 + https://github.com/giampaolo/psutil/issues/966. """ null = object() @@ -1979,7 +1979,7 @@ def memory_full_info(self): def memory_maps(self): """Return process's mapped memory regions as a list of named tuples. Fields are explained in 'man proc'; here is an updated - (Apr 2012) version: http://goo.gl/fmebo + (Apr 2012) version: http://goo.gl/fmebo. /proc/{PID}/smaps does not exist on kernels < 2.6.14 or if CONFIG_MMU kernel configuration option is not enabled. diff --git a/psutil/_psosx.py b/psutil/_psosx.py index 21b0b6328..482a9d430 100644 --- a/psutil/_psosx.py +++ b/psutil/_psosx.py @@ -144,7 +144,7 @@ def cpu_times(): def per_cpu_times(): - """Return system CPU times as a named tuple""" + """Return system CPU times as a named tuple.""" ret = [] for cpu_t in cext.per_cpu_times(): user, nice, system, idle = cpu_t @@ -174,7 +174,7 @@ def cpu_freq(): """Return CPU frequency. On macOS per-cpu frequency is not supported. Also, the returned frequency never changes, see: - https://arstechnica.com/civis/viewtopic.php?f=19&t=465002 + https://arstechnica.com/civis/viewtopic.php?f=19&t=465002. """ curr, min_, max_ = cext.cpu_freq() return [_common.scpufreq(curr, min_, max_)] diff --git a/psutil/_psposix.py b/psutil/_psposix.py index 4144b5902..1b26589db 100644 --- a/psutil/_psposix.py +++ b/psutil/_psposix.py @@ -219,7 +219,7 @@ def disk_usage(path): @memoize def get_terminal_map(): """Get a map of device-id -> path as a dict. - Used by Process.terminal() + Used by Process.terminal(). """ ret = {} ls = glob.glob('/dev/tty*') + glob.glob('/dev/pts/*') diff --git a/psutil/_pssunos.py b/psutil/_pssunos.py index 66805ff6b..8d5c8d8c1 100644 --- a/psutil/_pssunos.py +++ b/psutil/_pssunos.py @@ -170,13 +170,13 @@ def swap_memory(): def cpu_times(): - """Return system-wide CPU times as a named tuple""" + """Return system-wide CPU times as a named tuple.""" ret = cext.per_cpu_times() return scputimes(*[sum(x) for x in zip(*ret)]) def per_cpu_times(): - """Return system per-CPU times as a list of named tuples""" + """Return system per-CPU times as a list of named tuples.""" ret = cext.per_cpu_times() return [scputimes(*x) for x in ret] diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py index b68c7dd4f..65ae0f0d6 100644 --- a/psutil/_pswindows.py +++ b/psutil/_pswindows.py @@ -195,7 +195,7 @@ def convert_dos_path(s): r"""Convert paths using native DOS format like: "\Device\HarddiskVolume1\Windows\systemew\file.txt" into: - "C:\Windows\systemew\file.txt" + "C:\Windows\systemew\file.txt". """ rawdrive = '\\'.join(s.split('\\')[:3]) driveletter = cext.QueryDosDevice(rawdrive) @@ -348,7 +348,7 @@ def cpu_freq(): def getloadavg(): """Return the number of processes in the system run queue averaged - over the last 1, 5, and 15 minutes respectively as a tuple""" + over the last 1, 5, and 15 minutes respectively as a tuple.""" global _loadavg_inititialized if not _loadavg_inititialized: @@ -701,7 +701,7 @@ def wrapper(self, *args, **kwargs): def retry_error_partial_copy(fun): """Workaround for https://github.com/giampaolo/psutil/issues/875. - See: https://stackoverflow.com/questions/4457745#4457745 + See: https://stackoverflow.com/questions/4457745#4457745. """ @functools.wraps(fun) def wrapper(self, *args, **kwargs): diff --git a/psutil/tests/__main__.py b/psutil/tests/__main__.py index e67735275..3792ca9de 100755 --- a/psutil/tests/__main__.py +++ b/psutil/tests/__main__.py @@ -6,7 +6,7 @@ """ Run unit tests. This is invoked by: -$ python -m psutil.tests +$ python -m psutil.tests. """ from .runner import main diff --git a/psutil/tests/runner.py b/psutil/tests/runner.py index 90c707545..027234d82 100755 --- a/psutil/tests/runner.py +++ b/psutil/tests/runner.py @@ -9,7 +9,7 @@ - colourized output - parallel run (UNIX only) - print failures/tracebacks on CTRL+C -- re-run failed tests only (make test-failed) +- re-run failed tests only (make test-failed). Invocation examples: - make test diff --git a/psutil/tests/test_contracts.py b/psutil/tests/test_contracts.py index cd0509174..892894176 100755 --- a/psutil/tests/test_contracts.py +++ b/psutil/tests/test_contracts.py @@ -6,7 +6,7 @@ """Contracts tests. These tests mainly check API sanity in terms of returned types and APIs availability. -Some of these are duplicates of tests test_system.py and test_process.py +Some of these are duplicates of tests test_system.py and test_process.py. """ import errno @@ -206,7 +206,7 @@ def test_memory_maps(self): class TestSystemAPITypes(PsutilTestCase): """Check the return types of system related APIs. Mainly we want to test we never return unicode on Python 2, see: - https://github.com/giampaolo/psutil/issues/1039 + https://github.com/giampaolo/psutil/issues/1039. """ @classmethod diff --git a/psutil/tests/test_misc.py b/psutil/tests/test_misc.py index 47877b558..9f700d70d 100755 --- a/psutil/tests/test_misc.py +++ b/psutil/tests/test_misc.py @@ -334,7 +334,7 @@ def run_against(self, obj, expected_retval=None): def test_function(self): @memoize def foo(*args, **kwargs): - """My docstring""" + """My docstring.""" baseclass.calls.append((args, kwargs)) return 22 @@ -344,7 +344,7 @@ def foo(*args, **kwargs): def test_class(self): @memoize class Foo: - """my docstring""" + """my docstring.""" def __init__(self, *args, **kwargs): baseclass.calls.append((args, kwargs)) @@ -374,7 +374,7 @@ class Foo: @staticmethod @memoize def bar(*args, **kwargs): - """My docstring""" + """My docstring.""" baseclass.calls.append((args, kwargs)) return 22 @@ -386,7 +386,7 @@ class Foo: @classmethod @memoize def bar(cls, *args, **kwargs): - """My docstring""" + """My docstring.""" baseclass.calls.append((args, kwargs)) return 22 @@ -398,7 +398,7 @@ def test_original(self): # against different types. Keeping it anyway. @memoize def foo(*args, **kwargs): - """Foo docstring""" + """Foo docstring.""" calls.append(None) return (args, kwargs) diff --git a/psutil/tests/test_unicode.py b/psutil/tests/test_unicode.py index 4614039ce..cbd87b7e9 100755 --- a/psutil/tests/test_unicode.py +++ b/psutil/tests/test_unicode.py @@ -7,7 +7,7 @@ """ Notes about unicode handling in psutil -====================================== +======================================. Starting from version 5.3.0 psutil adds unicode support, see: https://github.com/giampaolo/psutil/issues/1040 diff --git a/psutil/tests/test_windows.py b/psutil/tests/test_windows.py index 21b7b4428..b63cfd90e 100755 --- a/psutil/tests/test_windows.py +++ b/psutil/tests/test_windows.py @@ -632,7 +632,7 @@ class TestDualProcessImplementation(PsutilTestCase): case the first fails because of limited permission error. Here we test that the two methods return the exact same value, see: - https://github.com/giampaolo/psutil/issues/304 + https://github.com/giampaolo/psutil/issues/304. """ @classmethod diff --git a/pyproject.toml b/pyproject.toml index 073254151..6eb2c9bc9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,6 +7,7 @@ select = [ "D200", # [*] One-line docstring should fit on one line (pydocstyle) "D204", # [*] 1 blank line required after class docstring (pydocstyle) "D403", # [*] First word of the first line should be capitalized + "D415", # [*] First line should end with a period, question mark, or exclamation point ] ignore = [ "A", # flake8-builtins diff --git a/scripts/internal/bench_oneshot.py b/scripts/internal/bench_oneshot.py index 605958760..78f1feaed 100755 --- a/scripts/internal/bench_oneshot.py +++ b/scripts/internal/bench_oneshot.py @@ -7,7 +7,7 @@ """ A simple micro benchmark script which prints the speedup when using Process.oneshot() ctx manager. -See: https://github.com/giampaolo/psutil/issues/799 +See: https://github.com/giampaolo/psutil/issues/799. """ from __future__ import division diff --git a/scripts/internal/check_broken_links.py b/scripts/internal/check_broken_links.py index d36ab3284..eb50c4082 100755 --- a/scripts/internal/check_broken_links.py +++ b/scripts/internal/check_broken_links.py @@ -199,7 +199,7 @@ def validate_url(url): def parallel_validator(urls): """Validates all urls in parallel - urls: tuple(filename, url) + urls: tuple(filename, url). """ fails = [] # list of tuples (filename, url) current = 0 diff --git a/scripts/internal/download_wheels_appveyor.py b/scripts/internal/download_wheels_appveyor.py index dcded559b..203c0367f 100755 --- a/scripts/internal/download_wheels_appveyor.py +++ b/scripts/internal/download_wheels_appveyor.py @@ -9,7 +9,7 @@ https://ci.appveyor.com/project/giampaolo/psutil Re-adapted from the original recipe of Ibarra Corretge' : -http://code.saghul.net/index.php/2015/09/09/ +http://code.saghul.net/index.php/2015/09/09/. """ from __future__ import print_function diff --git a/scripts/internal/download_wheels_github.py b/scripts/internal/download_wheels_github.py index 00f57116f..cd6c6c45a 100755 --- a/scripts/internal/download_wheels_github.py +++ b/scripts/internal/download_wheels_github.py @@ -12,7 +12,7 @@ The token must be created with at least "public_repo" scope/rights. If you lose it, just generate a new token. REST API doc: -https://developer.github.com/v3/actions/artifacts/ +https://developer.github.com/v3/actions/artifacts/. """ import argparse diff --git a/scripts/internal/print_announce.py b/scripts/internal/print_announce.py index 33fca4220..87384aa47 100755 --- a/scripts/internal/print_announce.py +++ b/scripts/internal/print_announce.py @@ -6,7 +6,7 @@ """ Prints release announce based on HISTORY.rst file content. -See: https://pip.pypa.io/en/stable/reference/pip_install/#hash-checking-mode +See: https://pip.pypa.io/en/stable/reference/pip_install/#hash-checking-mode. """ import os diff --git a/scripts/internal/print_downloads.py b/scripts/internal/print_downloads.py index bceef3c87..718cd3eec 100755 --- a/scripts/internal/print_downloads.py +++ b/scripts/internal/print_downloads.py @@ -9,7 +9,7 @@ Useful sites: * https://pepy.tech/project/psutil * https://pypistats.org/packages/psutil -* https://hugovk.github.io/top-pypi-packages/ +* https://hugovk.github.io/top-pypi-packages/. """ from __future__ import print_function diff --git a/scripts/internal/print_hashes.py b/scripts/internal/print_hashes.py index 69bc9edbe..cabce5906 100755 --- a/scripts/internal/print_hashes.py +++ b/scripts/internal/print_hashes.py @@ -6,7 +6,7 @@ """ Prints files hashes, see: -https://pip.pypa.io/en/stable/reference/pip_install/#hash-checking-mode +https://pip.pypa.io/en/stable/reference/pip_install/#hash-checking-mode. """ import argparse diff --git a/scripts/internal/winmake.py b/scripts/internal/winmake.py index 222bf5cf3..44b28ffe7 100755 --- a/scripts/internal/winmake.py +++ b/scripts/internal/winmake.py @@ -209,7 +209,7 @@ def recursive_rm(*patterns): def build(): - """Build / compile""" + """Build / compile.""" # Make sure setuptools is installed (needed for 'develop' / # edit mode). sh('%s -c "import setuptools"' % PYTHON) @@ -260,7 +260,7 @@ def upload_wheels(): def install_pip(): - """Install pip""" + """Install pip.""" try: sh('%s -c "import pip"' % PYTHON) except SystemExit: @@ -289,13 +289,13 @@ def install_pip(): def install(): - """Install in develop / edit mode""" + """Install in develop / edit mode.""" build() sh("%s setup.py develop" % PYTHON) def uninstall(): - """Uninstall psutil""" + """Uninstall psutil.""" # Uninstalling psutil on Windows seems to be tricky. # On "import psutil" tests may import a psutil version living in # C:\PythonXY\Lib\site-packages which is not what we want, so @@ -341,7 +341,7 @@ def uninstall(): def clean(): - """Deletes dev files""" + """Deletes dev files.""" recursive_rm( "$testfn*", "*.bak", @@ -367,14 +367,14 @@ def clean(): def setup_dev_env(): - """Install useful deps""" + """Install useful deps.""" install_pip() install_git_hooks() sh("%s -m pip install -U %s" % (PYTHON, " ".join(DEPS))) def test(name=RUNNER_PY): - """Run tests""" + """Run tests.""" build() sh("%s %s" % (PYTHON, name)) @@ -390,55 +390,55 @@ def coverage(): def test_process(): - """Run process tests""" + """Run process tests.""" build() sh("%s psutil\\tests\\test_process.py" % PYTHON) def test_system(): - """Run system tests""" + """Run system tests.""" build() sh("%s psutil\\tests\\test_system.py" % PYTHON) def test_platform(): - """Run windows only tests""" + """Run windows only tests.""" build() sh("%s psutil\\tests\\test_windows.py" % PYTHON) def test_misc(): - """Run misc tests""" + """Run misc tests.""" build() sh("%s psutil\\tests\\test_misc.py" % PYTHON) def test_unicode(): - """Run unicode tests""" + """Run unicode tests.""" build() sh("%s psutil\\tests\\test_unicode.py" % PYTHON) def test_connections(): - """Run connections tests""" + """Run connections tests.""" build() sh("%s psutil\\tests\\test_connections.py" % PYTHON) def test_contracts(): - """Run contracts tests""" + """Run contracts tests.""" build() sh("%s psutil\\tests\\test_contracts.py" % PYTHON) def test_testutils(): - """Run test utilities tests""" + """Run test utilities tests.""" build() sh("%s psutil\\tests\\test_testutils.py" % PYTHON) def test_by_name(name): - """Run test by name""" + """Run test by name.""" build() sh("%s -m unittest -v %s" % (PYTHON, name)) @@ -450,7 +450,7 @@ def test_failed(): def test_memleaks(): - """Run memory leaks tests""" + """Run memory leaks tests.""" build() sh("%s psutil\\tests\\test_memleaks.py" % PYTHON) diff --git a/scripts/pidof.py b/scripts/pidof.py index da9371072..9da8e6733 100755 --- a/scripts/pidof.py +++ b/scripts/pidof.py @@ -7,6 +7,7 @@ """ A clone of 'pidof' cmdline utility. + $ pidof python 1140 1138 1136 1134 1133 1129 1127 1125 1121 1120 1119 """ diff --git a/scripts/procinfo.py b/scripts/procinfo.py index 0ffdf40e2..4ae4a63ed 100755 --- a/scripts/procinfo.py +++ b/scripts/procinfo.py @@ -6,6 +6,7 @@ """ Print detailed information about a process. + Author: Giampaolo Rodola' $ python3 scripts/procinfo.py From f8d0b5ddd4b84302051bdb095d52b50279c61bfb Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 12:54:55 +0200 Subject: [PATCH 35/50] add 1 docstyle rule --- psutil/__init__.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/psutil/__init__.py b/psutil/__init__.py index 1d140591e..c4ea86f87 100644 --- a/psutil/__init__.py +++ b/psutil/__init__.py @@ -1330,7 +1330,7 @@ class Popen(Process): >>> p.username() 'giampaolo' >>> p.communicate() - ('hi\n', None) + ('hi', None) >>> p.terminate() >>> p.wait(timeout=2) 0 diff --git a/pyproject.toml b/pyproject.toml index 6eb2c9bc9..df44e89dd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,8 +6,8 @@ select = [ "ALL", # to get a list of all values: `python3 -m ruff linter` "D200", # [*] One-line docstring should fit on one line (pydocstyle) "D204", # [*] 1 blank line required after class docstring (pydocstyle) + "D301", # Use `r"""` if any backslashes in a docstring "D403", # [*] First word of the first line should be capitalized - "D415", # [*] First line should end with a period, question mark, or exclamation point ] ignore = [ "A", # flake8-builtins From df651a8b2cdc79c522849e9f8c07b37e8ad561f7 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 12:56:48 +0200 Subject: [PATCH 36/50] add 1 docstyle rule --- psutil/__init__.py | 3 ++- psutil/_common.py | 3 ++- psutil/_pswindows.py | 3 ++- pyproject.toml | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/psutil/__init__.py b/psutil/__init__.py index c4ea86f87..5bf6501ab 100644 --- a/psutil/__init__.py +++ b/psutil/__init__.py @@ -866,7 +866,8 @@ def cpu_num(self): def environ(self): """The environment variables of the process as a dict. Note: this - might not reflect changes made after the process started. """ + might not reflect changes made after the process started. + """ return self._proc.environ() if WINDOWS: diff --git a/psutil/_common.py b/psutil/_common.py index a4116e5fc..4057f541b 100644 --- a/psutil/_common.py +++ b/psutil/_common.py @@ -501,7 +501,8 @@ def wrapper(self): def cache_activate(proc): """Activate cache. Expects a Process instance. Cache will be - stored as a "_cache" instance attribute.""" + stored as a "_cache" instance attribute. + """ proc._cache = {} def cache_deactivate(proc): diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py index 65ae0f0d6..6fd2b54bb 100644 --- a/psutil/_pswindows.py +++ b/psutil/_pswindows.py @@ -348,7 +348,8 @@ def cpu_freq(): def getloadavg(): """Return the number of processes in the system run queue averaged - over the last 1, 5, and 15 minutes respectively as a tuple.""" + over the last 1, 5, and 15 minutes respectively as a tuple. + """ global _loadavg_inititialized if not _loadavg_inititialized: diff --git a/pyproject.toml b/pyproject.toml index df44e89dd..bc9170e2c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,6 +6,7 @@ select = [ "ALL", # to get a list of all values: `python3 -m ruff linter` "D200", # [*] One-line docstring should fit on one line (pydocstyle) "D204", # [*] 1 blank line required after class docstring (pydocstyle) + "D209", # [*] Multi-line docstring closing quotes should be on a separate line "D301", # Use `r"""` if any backslashes in a docstring "D403", # [*] First word of the first line should be capitalized ] From 13df6f42fbdb1af49c2e1966c19d9def479c98ba Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 12:59:10 +0200 Subject: [PATCH 37/50] add 1 docstyle rule --- .github/workflows/issues.py | 3 +-- psutil/tests/__main__.py | 3 +-- psutil/tests/runner.py | 9 ++++----- psutil/tests/test_memleaks.py | 3 +-- psutil/tests/test_posix.py | 3 +-- psutil/tests/test_unicode.py | 3 +-- psutil/tests/test_windows.py | 3 +-- pyproject.toml | 1 + scripts/battery.py | 3 +-- scripts/cpu_distribution.py | 3 +-- scripts/disk_usage.py | 3 +-- scripts/fans.py | 3 +-- scripts/free.py | 3 +-- scripts/ifconfig.py | 3 +-- scripts/internal/bench_oneshot.py | 3 +-- scripts/internal/bench_oneshot_2.py | 3 +-- scripts/internal/check_broken_links.py | 3 +-- scripts/internal/convert_readme.py | 3 +-- scripts/internal/download_wheels_appveyor.py | 3 +-- scripts/internal/download_wheels_github.py | 3 +-- scripts/internal/git_pre_commit.py | 3 +-- scripts/internal/print_access_denied.py | 3 +-- scripts/internal/print_announce.py | 3 +-- scripts/internal/print_api_speed.py | 3 +-- scripts/internal/print_downloads.py | 3 +-- scripts/internal/print_hashes.py | 3 +-- scripts/internal/purge_installation.py | 3 +-- scripts/iotop.py | 3 +-- scripts/meminfo.py | 3 +-- scripts/netstat.py | 3 +-- scripts/nettop.py | 3 +-- scripts/pidof.py | 3 +-- scripts/pmap.py | 5 ++--- scripts/procinfo.py | 3 +-- scripts/procsmem.py | 3 +-- scripts/ps.py | 3 +-- scripts/pstree.py | 3 +-- scripts/sensors.py | 3 +-- scripts/temperatures.py | 3 +-- scripts/top.py | 3 +-- scripts/who.py | 3 +-- scripts/winservices.py | 3 +-- 42 files changed, 46 insertions(+), 86 deletions(-) diff --git a/.github/workflows/issues.py b/.github/workflows/issues.py index 9bc14272e..b89def6ff 100755 --- a/.github/workflows/issues.py +++ b/.github/workflows/issues.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Bot triggered by Github Actions every time a new issue, PR or comment +"""Bot triggered by Github Actions every time a new issue, PR or comment is created. Assign labels, provide replies, closes issues, etc. depending on the situation. """ diff --git a/psutil/tests/__main__.py b/psutil/tests/__main__.py index 3792ca9de..434515d21 100755 --- a/psutil/tests/__main__.py +++ b/psutil/tests/__main__.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Run unit tests. This is invoked by: +"""Run unit tests. This is invoked by: $ python -m psutil.tests. """ diff --git a/psutil/tests/runner.py b/psutil/tests/runner.py index 027234d82..d3938b05a 100755 --- a/psutil/tests/runner.py +++ b/psutil/tests/runner.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Unit test runner, providing new features on top of unittest module: +"""Unit test runner, providing new features on top of unittest module: - colourized output - parallel run (UNIX only) - print failures/tracebacks on CTRL+C @@ -145,9 +144,9 @@ def printErrorList(self, flavour, errors): class ColouredTextRunner(unittest.TextTestRunner): - """ - A coloured text runner which also prints failed tests on KeyboardInterrupt - and save failed tests in a file so that they can be re-run. + """A coloured text runner which also prints failed tests on + KeyboardInterrupt and save failed tests in a file so that they can + be re-run. """ resultclass = ColouredResult if USE_COLORS else unittest.TextTestResult diff --git a/psutil/tests/test_memleaks.py b/psutil/tests/test_memleaks.py index dbd1588df..cd1b3f290 100755 --- a/psutil/tests/test_memleaks.py +++ b/psutil/tests/test_memleaks.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Tests for detecting function memory leaks (typically the ones +"""Tests for detecting function memory leaks (typically the ones implemented in C). It does so by calling a function many times and checking whether process memory usage keeps increasing between calls or over time. diff --git a/psutil/tests/test_posix.py b/psutil/tests/test_posix.py index be8f2bcd2..eaaf0d1c2 100755 --- a/psutil/tests/test_posix.py +++ b/psutil/tests/test_posix.py @@ -43,8 +43,7 @@ def ps(fmt, pid=None): - """ - Wrapper for calling the ps command with a little bit of cross-platform + """Wrapper for calling the ps command with a little bit of cross-platform support for a narrow range of features. """ diff --git a/psutil/tests/test_unicode.py b/psutil/tests/test_unicode.py index cbd87b7e9..cf9500a3f 100755 --- a/psutil/tests/test_unicode.py +++ b/psutil/tests/test_unicode.py @@ -5,8 +5,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Notes about unicode handling in psutil +"""Notes about unicode handling in psutil ======================================. Starting from version 5.3.0 psutil adds unicode support, see: diff --git a/psutil/tests/test_windows.py b/psutil/tests/test_windows.py index b63cfd90e..47d6ad3f1 100755 --- a/psutil/tests/test_windows.py +++ b/psutil/tests/test_windows.py @@ -625,8 +625,7 @@ def test_create_time(self): @unittest.skipIf(not WINDOWS, "WINDOWS only") class TestDualProcessImplementation(PsutilTestCase): - """ - Certain APIs on Windows have 2 internal implementations, one + """Certain APIs on Windows have 2 internal implementations, one based on documented Windows APIs, another one based NtQuerySystemInformation() which gets called as fallback in case the first fails because of limited permission error. diff --git a/pyproject.toml b/pyproject.toml index bc9170e2c..e3483416d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,6 +7,7 @@ select = [ "D200", # [*] One-line docstring should fit on one line (pydocstyle) "D204", # [*] 1 blank line required after class docstring (pydocstyle) "D209", # [*] Multi-line docstring closing quotes should be on a separate line + "D212", # [*] Multi-line docstring summary should start at the first line "D301", # Use `r"""` if any backslashes in a docstring "D403", # [*] First word of the first line should be capitalized ] diff --git a/scripts/battery.py b/scripts/battery.py index bf0503e0e..040f94819 100755 --- a/scripts/battery.py +++ b/scripts/battery.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Show battery information. +"""Show battery information. $ python3 scripts/battery.py charge: 74% diff --git a/scripts/cpu_distribution.py b/scripts/cpu_distribution.py index ba71ca9cc..bfbb14b6c 100755 --- a/scripts/cpu_distribution.py +++ b/scripts/cpu_distribution.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Shows CPU workload split across different CPUs. +"""Shows CPU workload split across different CPUs. $ python3 scripts/cpu_workload.py CPU 0 CPU 1 CPU 2 CPU 3 CPU 4 CPU 5 CPU 6 CPU 7 diff --git a/scripts/disk_usage.py b/scripts/disk_usage.py index 65ae31382..d801c6ddd 100755 --- a/scripts/disk_usage.py +++ b/scripts/disk_usage.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -List all mounted disk partitions a-la "df -h" command. +"""List all mounted disk partitions a-la "df -h" command. $ python3 scripts/disk_usage.py Device Total Used Free Use % Type Mount diff --git a/scripts/fans.py b/scripts/fans.py index 304277157..a9a8b8e67 100755 --- a/scripts/fans.py +++ b/scripts/fans.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Show fans information. +"""Show fans information. $ python fans.py asus diff --git a/scripts/free.py b/scripts/free.py index 8c3359d86..f72149ac3 100755 --- a/scripts/free.py +++ b/scripts/free.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -A clone of 'free' cmdline utility. +"""A clone of 'free' cmdline utility. $ python3 scripts/free.py total used free shared buffers cache diff --git a/scripts/ifconfig.py b/scripts/ifconfig.py index 23fd26b47..7fdfa1e12 100755 --- a/scripts/ifconfig.py +++ b/scripts/ifconfig.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -A clone of 'ifconfig' on UNIX. +"""A clone of 'ifconfig' on UNIX. $ python3 scripts/ifconfig.py lo: diff --git a/scripts/internal/bench_oneshot.py b/scripts/internal/bench_oneshot.py index 78f1feaed..74f8150ae 100755 --- a/scripts/internal/bench_oneshot.py +++ b/scripts/internal/bench_oneshot.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -A simple micro benchmark script which prints the speedup when using +"""A simple micro benchmark script which prints the speedup when using Process.oneshot() ctx manager. See: https://github.com/giampaolo/psutil/issues/799. """ diff --git a/scripts/internal/bench_oneshot_2.py b/scripts/internal/bench_oneshot_2.py index 051d00360..2a63dca25 100755 --- a/scripts/internal/bench_oneshot_2.py +++ b/scripts/internal/bench_oneshot_2.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Same as bench_oneshot.py but uses perf module instead, which is +"""Same as bench_oneshot.py but uses perf module instead, which is supposed to be more precise. """ diff --git a/scripts/internal/check_broken_links.py b/scripts/internal/check_broken_links.py index eb50c4082..315f06fa1 100755 --- a/scripts/internal/check_broken_links.py +++ b/scripts/internal/check_broken_links.py @@ -4,8 +4,7 @@ # All rights reserved. Use of this source code is governed by a # BSD-style license that can be found in the LICENSE file. -""" -Checks for broken links in file names specified as command line +"""Checks for broken links in file names specified as command line parameters. There are a ton of a solutions available for validating URLs in string diff --git a/scripts/internal/convert_readme.py b/scripts/internal/convert_readme.py index d96c6c5d3..0c4fade50 100755 --- a/scripts/internal/convert_readme.py +++ b/scripts/internal/convert_readme.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Remove raw HTML from README.rst to make it compatible with PyPI on +"""Remove raw HTML from README.rst to make it compatible with PyPI on dist upload. """ diff --git a/scripts/internal/download_wheels_appveyor.py b/scripts/internal/download_wheels_appveyor.py index 203c0367f..dc9ebec25 100755 --- a/scripts/internal/download_wheels_appveyor.py +++ b/scripts/internal/download_wheels_appveyor.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Script which downloads wheel files hosted on AppVeyor: +"""Script which downloads wheel files hosted on AppVeyor: https://ci.appveyor.com/project/giampaolo/psutil Re-adapted from the original recipe of Ibarra Corretge' : diff --git a/scripts/internal/download_wheels_github.py b/scripts/internal/download_wheels_github.py index cd6c6c45a..d3710e3cc 100755 --- a/scripts/internal/download_wheels_github.py +++ b/scripts/internal/download_wheels_github.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Script which downloads wheel files hosted on GitHub: +"""Script which downloads wheel files hosted on GitHub: https://github.com/giampaolo/psutil/actions It needs an access token string generated from personal GitHub profile: https://github.com/settings/tokens diff --git a/scripts/internal/git_pre_commit.py b/scripts/internal/git_pre_commit.py index e44045b85..007ba4c2d 100755 --- a/scripts/internal/git_pre_commit.py +++ b/scripts/internal/git_pre_commit.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -This gets executed on 'git commit' and rejects the commit in case the +"""This gets executed on 'git commit' and rejects the commit in case the submitted code does not pass validation. Validation is run only against the files which were modified in the commit. Checks: diff --git a/scripts/internal/print_access_denied.py b/scripts/internal/print_access_denied.py index f3d0166e5..7759ca7b2 100755 --- a/scripts/internal/print_access_denied.py +++ b/scripts/internal/print_access_denied.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Helper script iterates over all processes and . +"""Helper script iterates over all processes and . It prints how many AccessDenied exceptions are raised in total and for what Process method. diff --git a/scripts/internal/print_announce.py b/scripts/internal/print_announce.py index 87384aa47..5743d580e 100755 --- a/scripts/internal/print_announce.py +++ b/scripts/internal/print_announce.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Prints release announce based on HISTORY.rst file content. +"""Prints release announce based on HISTORY.rst file content. See: https://pip.pypa.io/en/stable/reference/pip_install/#hash-checking-mode. """ diff --git a/scripts/internal/print_api_speed.py b/scripts/internal/print_api_speed.py index 2d62320f9..baa1c5a28 100755 --- a/scripts/internal/print_api_speed.py +++ b/scripts/internal/print_api_speed.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Benchmark all API calls and print them from fastest to slowest. +"""Benchmark all API calls and print them from fastest to slowest. $ make print_api_speed SYSTEM APIS NUM CALLS SECONDS diff --git a/scripts/internal/print_downloads.py b/scripts/internal/print_downloads.py index 718cd3eec..9d60f7c08 100755 --- a/scripts/internal/print_downloads.py +++ b/scripts/internal/print_downloads.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Print PYPI statistics in MarkDown format. +"""Print PYPI statistics in MarkDown format. Useful sites: * https://pepy.tech/project/psutil * https://pypistats.org/packages/psutil diff --git a/scripts/internal/print_hashes.py b/scripts/internal/print_hashes.py index cabce5906..68e06201c 100755 --- a/scripts/internal/print_hashes.py +++ b/scripts/internal/print_hashes.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Prints files hashes, see: +"""Prints files hashes, see: https://pip.pypa.io/en/stable/reference/pip_install/#hash-checking-mode. """ diff --git a/scripts/internal/purge_installation.py b/scripts/internal/purge_installation.py index 8a9597f0b..55b2f5c50 100755 --- a/scripts/internal/purge_installation.py +++ b/scripts/internal/purge_installation.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Purge psutil installation by removing psutil-related files and +"""Purge psutil installation by removing psutil-related files and directories found in site-packages directories. This is needed mainly because sometimes "import psutil" imports a leftover installation from site-packages directory instead of the main working directory. diff --git a/scripts/iotop.py b/scripts/iotop.py index 3d03d4a50..a8f04c870 100755 --- a/scripts/iotop.py +++ b/scripts/iotop.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -A clone of iotop (http://guichaz.free.fr/iotop/) showing real time +"""A clone of iotop (http://guichaz.free.fr/iotop/) showing real time disk I/O statistics. It works on Linux only (FreeBSD and macOS are missing support for IO diff --git a/scripts/meminfo.py b/scripts/meminfo.py index b98aa60be..a13b7e00b 100755 --- a/scripts/meminfo.py +++ b/scripts/meminfo.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Print system memory information. +"""Print system memory information. $ python3 scripts/meminfo.py MEMORY diff --git a/scripts/netstat.py b/scripts/netstat.py index 476b082e5..7a9b2908c 100755 --- a/scripts/netstat.py +++ b/scripts/netstat.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -A clone of 'netstat -antp' on Linux. +"""A clone of 'netstat -antp' on Linux. $ python3 scripts/netstat.py Proto Local address Remote address Status PID Program name diff --git a/scripts/nettop.py b/scripts/nettop.py index 84b2f0deb..fedc644d0 100755 --- a/scripts/nettop.py +++ b/scripts/nettop.py @@ -6,8 +6,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Shows real-time network statistics. +"""Shows real-time network statistics. Author: Giampaolo Rodola' diff --git a/scripts/pidof.py b/scripts/pidof.py index 9da8e6733..b809fafbe 100755 --- a/scripts/pidof.py +++ b/scripts/pidof.py @@ -5,8 +5,7 @@ # found in the LICENSE file. -""" -A clone of 'pidof' cmdline utility. +"""A clone of 'pidof' cmdline utility. $ pidof python 1140 1138 1136 1134 1133 1129 1127 1125 1121 1120 1119 diff --git a/scripts/pmap.py b/scripts/pmap.py index 459927bfd..56c1b4882 100755 --- a/scripts/pmap.py +++ b/scripts/pmap.py @@ -4,9 +4,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -A clone of 'pmap' utility on Linux, 'vmmap' on macOS and 'procstat -v' on BSD. -Report memory map of a process. +"""A clone of 'pmap' utility on Linux, 'vmmap' on macOS and 'procstat +-v' on BSD. Report memory map of a process. $ python3 scripts/pmap.py 32402 Address RSS Mode Mapping diff --git a/scripts/procinfo.py b/scripts/procinfo.py index 4ae4a63ed..562a61a46 100755 --- a/scripts/procinfo.py +++ b/scripts/procinfo.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Print detailed information about a process. +"""Print detailed information about a process. Author: Giampaolo Rodola' diff --git a/scripts/procsmem.py b/scripts/procsmem.py index ca03729ec..574e37041 100755 --- a/scripts/procsmem.py +++ b/scripts/procsmem.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Show detailed memory usage about all (querable) processes. +"""Show detailed memory usage about all (querable) processes. Processes are sorted by their "USS" (Unique Set Size) memory, which is probably the most representative metric for determining how much memory diff --git a/scripts/ps.py b/scripts/ps.py index a234209fb..58a1d8c29 100755 --- a/scripts/ps.py +++ b/scripts/ps.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -A clone of 'ps aux'. +"""A clone of 'ps aux'. $ python3 scripts/ps.py USER PID %MEM VSZ RSS NICE STATUS START TIME CMDLINE diff --git a/scripts/pstree.py b/scripts/pstree.py index 18732b8cb..e873e467d 100755 --- a/scripts/pstree.py +++ b/scripts/pstree.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -Similar to 'ps aux --forest' on Linux, prints the process list +"""Similar to 'ps aux --forest' on Linux, prints the process list as a tree structure. $ python3 scripts/pstree.py diff --git a/scripts/sensors.py b/scripts/sensors.py index edbec8e4c..a5f9729b4 100755 --- a/scripts/sensors.py +++ b/scripts/sensors.py @@ -5,8 +5,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -A clone of 'sensors' utility on Linux printing hardware temperatures, +"""A clone of 'sensors' utility on Linux printing hardware temperatures, fans speed and battery info. $ python3 scripts/sensors.py diff --git a/scripts/temperatures.py b/scripts/temperatures.py index 90097e514..a211b8873 100755 --- a/scripts/temperatures.py +++ b/scripts/temperatures.py @@ -5,8 +5,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -A clone of 'sensors' utility on Linux printing hardware temperatures. +"""A clone of 'sensors' utility on Linux printing hardware temperatures. $ python3 scripts/sensors.py asus diff --git a/scripts/top.py b/scripts/top.py index 5240268dd..675f541ef 100755 --- a/scripts/top.py +++ b/scripts/top.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -A clone of top / htop. +"""A clone of top / htop. Author: Giampaolo Rodola' diff --git a/scripts/who.py b/scripts/who.py index c1e407299..18db1b17a 100755 --- a/scripts/who.py +++ b/scripts/who.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -""" -A clone of 'who' command; print information about users who are +"""A clone of 'who' command; print information about users who are currently logged in. $ python3 scripts/who.py diff --git a/scripts/winservices.py b/scripts/winservices.py index 5c710159b..d9c6a14a9 100755 --- a/scripts/winservices.py +++ b/scripts/winservices.py @@ -4,8 +4,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -r""" -List all Windows services installed. +r"""List all Windows services installed. $ python3 scripts/winservices.py AeLookupSvc (Application Experience) From db3dc8c378f53a1b50e0141d42efff8c11a87427 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 13:11:37 +0200 Subject: [PATCH 38/50] git pre commit script: remove manual file content checks --- scripts/internal/git_pre_commit.py | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/scripts/internal/git_pre_commit.py b/scripts/internal/git_pre_commit.py index 007ba4c2d..bd501810a 100755 --- a/scripts/internal/git_pre_commit.py +++ b/scripts/internal/git_pre_commit.py @@ -139,27 +139,6 @@ def rstcheck(files): def main(): py_files, c_files, rst_files, toml_files, new_rm_mv = git_commit_files() - # Check file content. - for path in py_files: - if os.path.realpath(path) == THIS_SCRIPT: - continue - with open_text(path) as f: - lines = f.readlines() - for lineno, line in enumerate(lines, 1): - # space at end of line - if line.endswith(' '): - print("%s:%s %r" % (path, lineno, line)) - return sys.exit("space at end of line") - line = line.rstrip() - # # pdb (now provided by flake8-debugger plugin) - # if "pdb.set_trace" in line: - # print("%s:%s %s" % (path, lineno, line)) - # return sys.exit("you forgot a pdb in your python code") - # # bare except clause (now provided by flake8-blind-except plugin) - # if "except:" in line and not line.endswith("# NOQA"): - # print("%s:%s %s" % (path, lineno, line)) - # return sys.exit("bare except clause") - if py_files: isort(py_files) if c_files: From b9919ebf5a9a5c6f6b85307ebfe2b4b901d2c392 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 13:16:46 +0200 Subject: [PATCH 39/50] apply style change --- pyproject.toml | 3 +-- scripts/internal/download_wheels_appveyor.py | 11 ++++++----- scripts/internal/download_wheels_github.py | 11 ++++++----- scripts/internal/print_announce.py | 3 ++- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e3483416d..1ebd67926 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,7 +26,7 @@ ignore = [ "DTZ", # flake8-datetimez "EM", # flake8-errmsg "ERA001", # Found commented-out code - "FBT", # flake8-boolean-trap + "FBT", # flake8-boolean-trap (makes zero sense) "FIX", # Line contains TODO / XXX / ..., consider resolving the issue "FLY", # flynt (PYTHON2.7 COMPAT) "INP", # flake8-no-pep420 @@ -34,7 +34,6 @@ ignore = [ "N802", # Function name X should be lowercase. "N803", # Argument name X should be lowercase. "N806", # Variable X in function should be lowercase. - "N812", # Lowercase `error` imported as non-lowercase `FooBarError` "N818", # Exception name `FooBar` should be named with an Error suffix "PERF", # Perflint "PGH004", # Use specific rule codes when using `noqa` diff --git a/scripts/internal/download_wheels_appveyor.py b/scripts/internal/download_wheels_appveyor.py index dc9ebec25..47a33d996 100755 --- a/scripts/internal/download_wheels_appveyor.py +++ b/scripts/internal/download_wheels_appveyor.py @@ -19,13 +19,14 @@ import requests -from psutil import __version__ as PSUTIL_VERSION +from psutil import __version__ from psutil._common import bytes2human from psutil._common import print_color USER = "giampaolo" PROJECT = "psutil" +PROJECT_VERSION = __version__ BASE_URL = 'https://ci.appveyor.com/api' PY_VERSIONS = ['2.7'] TIMEOUT = 30 @@ -70,12 +71,12 @@ def get_file_urls(): def rename_win27_wheels(): # See: https://github.com/giampaolo/psutil/issues/810 - src = 'dist/psutil-%s-cp27-cp27m-win32.whl' % PSUTIL_VERSION - dst = 'dist/psutil-%s-cp27-none-win32.whl' % PSUTIL_VERSION + src = 'dist/psutil-%s-cp27-cp27m-win32.whl' % PROJECT_VERSION + dst = 'dist/psutil-%s-cp27-none-win32.whl' % PROJECT_VERSION print("rename: %s\n %s" % (src, dst)) os.rename(src, dst) - src = 'dist/psutil-%s-cp27-cp27m-win_amd64.whl' % PSUTIL_VERSION - dst = 'dist/psutil-%s-cp27-none-win_amd64.whl' % PSUTIL_VERSION + src = 'dist/psutil-%s-cp27-cp27m-win_amd64.whl' % PROJECT_VERSION + dst = 'dist/psutil-%s-cp27-none-win_amd64.whl' % PROJECT_VERSION print("rename: %s\n %s" % (src, dst)) os.rename(src, dst) diff --git a/scripts/internal/download_wheels_github.py b/scripts/internal/download_wheels_github.py index d3710e3cc..310826cb5 100755 --- a/scripts/internal/download_wheels_github.py +++ b/scripts/internal/download_wheels_github.py @@ -22,13 +22,14 @@ import requests -from psutil import __version__ as PSUTIL_VERSION +from psutil import __version__ from psutil._common import bytes2human from psutil.tests import safe_rmpath USER = "giampaolo" PROJECT = "psutil" +PROJECT_VERSION = __version__ OUTFILE = "wheels-github.zip" TOKEN = "" @@ -56,13 +57,13 @@ def download_zip(url): def rename_win27_wheels(): # See: https://github.com/giampaolo/psutil/issues/810 - src = 'dist/psutil-%s-cp27-cp27m-win32.whl' % PSUTIL_VERSION - dst = 'dist/psutil-%s-cp27-none-win32.whl' % PSUTIL_VERSION + src = 'dist/psutil-%s-cp27-cp27m-win32.whl' % PROJECT_VERSION + dst = 'dist/psutil-%s-cp27-none-win32.whl' % PROJECT_VERSION if os.path.exists(src): print("rename: %s\n %s" % (src, dst)) os.rename(src, dst) - src = 'dist/psutil-%s-cp27-cp27m-win_amd64.whl' % PSUTIL_VERSION - dst = 'dist/psutil-%s-cp27-none-win_amd64.whl' % PSUTIL_VERSION + src = 'dist/psutil-%s-cp27-cp27m-win_amd64.whl' % PROJECT_VERSION + dst = 'dist/psutil-%s-cp27-none-win_amd64.whl' % PROJECT_VERSION if os.path.exists(src): print("rename: %s\n %s" % (src, dst)) os.rename(src, dst) diff --git a/scripts/internal/print_announce.py b/scripts/internal/print_announce.py index 5743d580e..2297c0950 100755 --- a/scripts/internal/print_announce.py +++ b/scripts/internal/print_announce.py @@ -13,7 +13,7 @@ import subprocess import sys -from psutil import __version__ as PRJ_VERSION +from psutil import __version__ HERE = os.path.abspath(os.path.dirname(__file__)) @@ -23,6 +23,7 @@ ROOT, 'scripts', 'internal', 'print_hashes.py') PRJ_NAME = 'psutil' +PRJ_VERSION = __version__ PRJ_URL_HOME = 'https://github.com/giampaolo/psutil' PRJ_URL_DOC = 'http://psutil.readthedocs.io' PRJ_URL_DOWNLOAD = 'https://pypi.org/project/psutil/#files' From abfcc79eb7571d5f1566e86e766a854ada6936e0 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 13:20:52 +0200 Subject: [PATCH 40/50] apply style change --- psutil/tests/test_contracts.py | 2 +- pyproject.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/psutil/tests/test_contracts.py b/psutil/tests/test_contracts.py index 892894176..152a5b739 100755 --- a/psutil/tests/test_contracts.py +++ b/psutil/tests/test_contracts.py @@ -297,7 +297,7 @@ def test_net_if_stats(self): @unittest.skipIf(not HAS_NET_IO_COUNTERS, 'not supported') def test_net_io_counters(self): # Duplicate of test_system.py. Keep it anyway. - for ifname, _ in psutil.net_io_counters(pernic=True).items(): + for ifname in psutil.net_io_counters(pernic=True): self.assertIsInstance(ifname, str) @unittest.skipIf(not HAS_SENSORS_FANS, "not supported") diff --git a/pyproject.toml b/pyproject.toml index 1ebd67926..d530b02bc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,6 +10,7 @@ select = [ "D212", # [*] Multi-line docstring summary should start at the first line "D301", # Use `r"""` if any backslashes in a docstring "D403", # [*] First word of the first line should be capitalized + "PERF102", # [*] When using only the keys of a dict use the `keys()` method ] ignore = [ "A", # flake8-builtins From bb62e52e9e9ce29c05e9dd8bc266d6a5f559bace Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 13:25:13 +0200 Subject: [PATCH 41/50] apply style change --- psutil/_psbsd.py | 2 +- pyproject.toml | 1 + scripts/internal/git_pre_commit.py | 11 +++++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py index 6f6cce1ec..eeab18a9a 100644 --- a/psutil/_psbsd.py +++ b/psutil/_psbsd.py @@ -8,9 +8,9 @@ import errno import functools import os -import xml.etree.ElementTree as ElementTree from collections import defaultdict from collections import namedtuple +from xml.etree import ElementTree from . import _common from . import _psposix diff --git a/pyproject.toml b/pyproject.toml index d530b02bc..d9f4c4092 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,6 +11,7 @@ select = [ "D301", # Use `r"""` if any backslashes in a docstring "D403", # [*] First word of the first line should be capitalized "PERF102", # [*] When using only the keys of a dict use the `keys()` method + "PLR5501", # Use `elif` instead of `else` then `if`, to reduce indentation ] ignore = [ "A", # flake8-builtins diff --git a/scripts/internal/git_pre_commit.py b/scripts/internal/git_pre_commit.py index bd501810a..5fefac8b6 100755 --- a/scripts/internal/git_pre_commit.py +++ b/scripts/internal/git_pre_commit.py @@ -106,6 +106,16 @@ def git_commit_files(): return (py_files, c_files, rst_files, toml_files, new_rm_mv) +def ruff(files): + print("running ruff (%s)" % len(files)) + cmd = [PYTHON, "-m", "ruff", "check", "--no-cache"] + files + if subprocess.call(cmd) != 0: + return exit( + "Python code didn't pass 'ruff' style check." + "Try running 'make fix-ruff'." + ) + + def isort(files): print("running isort (%s)" % len(files)) cmd = [PYTHON, "-m", "isort", "--check-only"] + files @@ -140,6 +150,7 @@ def rstcheck(files): def main(): py_files, c_files, rst_files, toml_files, new_rm_mv = git_commit_files() if py_files: + ruff(py_files) isort(py_files) if c_files: c_linter(c_files) From 4e47fe85b85f145911b3fee5564f27a8b4d285bc Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 13:31:48 +0200 Subject: [PATCH 42/50] fix tests --- psutil/tests/test_misc.py | 6 +++--- pyproject.toml | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/psutil/tests/test_misc.py b/psutil/tests/test_misc.py index 9f700d70d..64b998da3 100755 --- a/psutil/tests/test_misc.py +++ b/psutil/tests/test_misc.py @@ -329,7 +329,7 @@ def run_against(self, obj, expected_retval=None): self.assertEqual(ret, expected_retval) self.assertEqual(len(self.calls), 4) # docstring - self.assertEqual(obj.__doc__, "my docstring") + self.assertEqual(obj.__doc__, "My docstring.") def test_function(self): @memoize @@ -344,7 +344,7 @@ def foo(*args, **kwargs): def test_class(self): @memoize class Foo: - """my docstring.""" + """My docstring.""" def __init__(self, *args, **kwargs): baseclass.calls.append((args, kwargs)) @@ -428,7 +428,7 @@ def foo(*args, **kwargs): self.assertEqual(ret, expected) self.assertEqual(len(calls), 4) # docstring - self.assertEqual(foo.__doc__, "foo docstring") + self.assertEqual(foo.__doc__, "Foo docstring.") class TestCommonModule(PsutilTestCase): diff --git a/pyproject.toml b/pyproject.toml index d9f4c4092..d530b02bc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,6 @@ select = [ "D301", # Use `r"""` if any backslashes in a docstring "D403", # [*] First word of the first line should be capitalized "PERF102", # [*] When using only the keys of a dict use the `keys()` method - "PLR5501", # Use `elif` instead of `else` then `if`, to reduce indentation ] ignore = [ "A", # flake8-builtins From 5e96514fa546e7b81ec5e016acb4f413e3e95018 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 13:43:11 +0200 Subject: [PATCH 43/50] subprocess.Popen: don't use shell=True --- psutil/_psaix.py | 5 ++--- psutil/_pssunos.py | 4 ++-- scripts/internal/generate_manifest.py | 3 ++- scripts/internal/print_downloads.py | 3 ++- scripts/internal/print_timeline.py | 3 ++- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/psutil/_psaix.py b/psutil/_psaix.py index 24f64a0c6..6c2962c5e 100644 --- a/psutil/_psaix.py +++ b/psutil/_psaix.py @@ -144,9 +144,8 @@ def cpu_count_logical(): def cpu_count_cores(): - cmd = "lsdev -Cc processor" - p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + cmd = ["lsdev", "-Cc", "processor"] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() if PY3: stdout, stderr = (x.decode(sys.stdout.encoding) diff --git a/psutil/_pssunos.py b/psutil/_pssunos.py index 8d5c8d8c1..291dc5a00 100644 --- a/psutil/_pssunos.py +++ b/psutil/_pssunos.py @@ -617,8 +617,8 @@ def _get_unix_sockets(self, pid): """Get UNIX sockets used by process by parsing 'pfiles' output.""" # TODO: rewrite this in C (...but the damn netstat source code # does not include this part! Argh!!) - cmd = "pfiles %s" % pid - p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, + cmd = ["pfiles", str(pid)] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() if PY3: diff --git a/scripts/internal/generate_manifest.py b/scripts/internal/generate_manifest.py index 53725163d..290e8b49f 100755 --- a/scripts/internal/generate_manifest.py +++ b/scripts/internal/generate_manifest.py @@ -7,6 +7,7 @@ """Generate MANIFEST.in file.""" import os +import shlex import subprocess @@ -17,7 +18,7 @@ def sh(cmd): return subprocess.check_output( - cmd, shell=True, universal_newlines=True).strip() + shlex.split(cmd), universal_newlines=True).strip() def main(): diff --git a/scripts/internal/print_downloads.py b/scripts/internal/print_downloads.py index 9d60f7c08..1ee37e534 100755 --- a/scripts/internal/print_downloads.py +++ b/scripts/internal/print_downloads.py @@ -15,6 +15,7 @@ import json import os +import shlex import subprocess import sys @@ -42,7 +43,7 @@ def sh(cmd): assert os.path.exists(AUTH_FILE) env = os.environ.copy() env['GOOGLE_APPLICATION_CREDENTIALS'] = AUTH_FILE - p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, + p = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) stdout, stderr = p.communicate() if p.returncode != 0: diff --git a/scripts/internal/print_timeline.py b/scripts/internal/print_timeline.py index 54cab8956..a046e670a 100755 --- a/scripts/internal/print_timeline.py +++ b/scripts/internal/print_timeline.py @@ -6,6 +6,7 @@ """Prints releases' timeline in RST format.""" +import shlex import subprocess @@ -18,7 +19,7 @@ def sh(cmd): return subprocess.check_output( - cmd, shell=True, universal_newlines=True).strip() + shlex.split(cmd), universal_newlines=True).strip() def get_tag_date(tag): From a395cd072faa90da7272b1cf7e2fd842f6764f3b Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 13:47:35 +0200 Subject: [PATCH 44/50] add rule --- pyproject.toml | 2 ++ scripts/internal/download_wheels_github.py | 7 +++++-- scripts/internal/winmake.py | 5 ++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d530b02bc..b5875657b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,6 +11,8 @@ select = [ "D301", # Use `r"""` if any backslashes in a docstring "D403", # [*] First word of the first line should be capitalized "PERF102", # [*] When using only the keys of a dict use the `keys()` method + "S113", # Probable use of requests call without timeout + "S602", # `subprocess` call with `shell=True` identified, security issue ] ignore = [ "A", # flake8-builtins diff --git a/scripts/internal/download_wheels_github.py b/scripts/internal/download_wheels_github.py index 310826cb5..de6c34faa 100755 --- a/scripts/internal/download_wheels_github.py +++ b/scripts/internal/download_wheels_github.py @@ -32,12 +32,14 @@ PROJECT_VERSION = __version__ OUTFILE = "wheels-github.zip" TOKEN = "" +TIMEOUT = 30 def get_artifacts(): base_url = "https://api.github.com/repos/%s/%s" % (USER, PROJECT) url = base_url + "/actions/artifacts" - res = requests.get(url=url, headers={"Authorization": "token %s" % TOKEN}) + res = requests.get(url=url, headers={ + "Authorization": "token %s" % TOKEN}, timeout=TIMEOUT) res.raise_for_status() data = json.loads(res.content) return data @@ -45,7 +47,8 @@ def get_artifacts(): def download_zip(url): print("downloading: " + url) - res = requests.get(url=url, headers={"Authorization": "token %s" % TOKEN}) + res = requests.get(url=url, headers={ + "Authorization": "token %s" % TOKEN}, timeout=TIMEOUT) res.raise_for_status() totbytes = 0 with open(OUTFILE, 'wb') as f: diff --git a/scripts/internal/winmake.py b/scripts/internal/winmake.py index 44b28ffe7..c2c20bc0a 100755 --- a/scripts/internal/winmake.py +++ b/scripts/internal/winmake.py @@ -19,6 +19,7 @@ import errno import fnmatch import os +import shlex import shutil import site import ssl @@ -115,7 +116,9 @@ def win_colorprint(s, color=LIGHTBLUE): def sh(cmd, nolog=False): if not nolog: safe_print("cmd: " + cmd) - p = subprocess.Popen(cmd, shell=True, env=os.environ, cwd=os.getcwd()) + if isinstance(cmd, str): + cmd = shlex.split(cmd) + p = subprocess.Popen(cmd, env=os.environ, cwd=os.getcwd()) p.communicate() if p.returncode != 0: sys.exit(p.returncode) From c90bbd47c115b726bb60e77f68af3483b7381be3 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 13:50:42 +0200 Subject: [PATCH 45/50] small refact --- psutil/tests/test_misc.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/psutil/tests/test_misc.py b/psutil/tests/test_misc.py index 64b998da3..b3515de31 100755 --- a/psutil/tests/test_misc.py +++ b/psutil/tests/test_misc.py @@ -843,8 +843,7 @@ def assert_stdout(exe, *args, **kwargs): @staticmethod def assert_syntax(exe): exe = os.path.join(SCRIPTS_DIR, exe) - f = open(exe, encoding="utf8") if PY3 else open(exe) - with f: + with open(exe, encoding="utf8") if PY3 else open(exe) as f: src = f.read() ast.parse(src) From 4407cb64926a0bb6f30066f00e60e75970a28cb1 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 14:21:48 +0200 Subject: [PATCH 46/50] get rid of isort --- .github/workflows/build.yml | 2 +- Makefile | 11 +---------- pyproject.toml | 13 +++++-------- scripts/internal/git_pre_commit.py | 28 ++++------------------------ scripts/internal/winmake.py | 1 - 5 files changed, 11 insertions(+), 44 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0171e8a43..4bb8d108b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -115,7 +115,7 @@ jobs: python-version: 3.x - name: 'Run linters' run: | - python3 -m pip install isort rstcheck toml-sort sphinx + python3 -m pip install ruff rstcheck toml-sort sphinx make lint-all # Check sanity of .tar.gz + wheel files diff --git a/Makefile b/Makefile index dfacfb60e..06dd2a5d5 100644 --- a/Makefile +++ b/Makefile @@ -12,8 +12,6 @@ PY3_DEPS = \ check-manifest \ concurrencytest \ coverage \ - isort \ - pep8-naming \ pylint \ pyperf \ pypinfo \ @@ -195,9 +193,6 @@ test-coverage: ## Run test coverage. ruff: ## Run ruff linter. @git ls-files '*.py' | xargs $(PYTHON) -m ruff check --config=pyproject.toml --no-cache -isort: ## Run isort linter. - @git ls-files '*.py' | xargs $(PYTHON) -m isort --check-only --jobs=${NUM_WORKERS} - _pylint: ## Python pylint (not mandatory, just run it from time to time) @git ls-files '*.py' | xargs $(PYTHON) -m pylint --rcfile=pyproject.toml --jobs=${NUM_WORKERS} @@ -211,7 +206,7 @@ lint-toml: ## Linter for pyproject.toml @git ls-files '*.toml' | xargs toml-sort --check lint-all: ## Run all linters - ${MAKE} isort + ${MAKE} ruff ${MAKE} lint-c ${MAKE} lint-rst ${MAKE} lint-toml @@ -223,9 +218,6 @@ lint-all: ## Run all linters fix-ruff: @git ls-files '*.py' | xargs $(PYTHON) -m ruff --config=pyproject.toml --no-cache --fix -fix-imports: ## Fix imports with isort. - @git ls-files '*.py' | xargs $(PYTHON) -m isort --jobs=${NUM_WORKERS} - fix-unittests: ## Fix unittest idioms. @git ls-files '*test_*.py' | xargs $(PYTHON) -m teyit --show-stats @@ -234,7 +226,6 @@ fix-toml: ## Fix pyproject.toml fix-all: ## Run all code fixers. ${MAKE} fix-ruff - ${MAKE} fix-imports ${MAKE} fix-unittests ${MAKE} fix-toml diff --git a/pyproject.toml b/pyproject.toml index b5875657b..d99de4271 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,9 +3,10 @@ target-version = "py37" line-length = 79 select = [ - "ALL", # to get a list of all values: `python3 -m ruff linter` - "D200", # [*] One-line docstring should fit on one line (pydocstyle) - "D204", # [*] 1 blank line required after class docstring (pydocstyle) + # To get a list of all values: `python3 -m ruff linter`. + "ALL", + "D200", # [*] One-line docstring should fit on one line + "D204", # [*] 1 blank line required after class docstring "D209", # [*] Multi-line docstring closing quotes should be on a separate line "D212", # [*] Multi-line docstring summary should start at the first line "D301", # Use `r"""` if any backslashes in a docstring @@ -22,7 +23,7 @@ ignore = [ "B904", # Within an `except` clause, raise exceptions with `raise ... from err` (PYTHON2.7 COMPAT) "BLE001", # Do not catch blind exception: `Exception` "C4", # flake8-comprehensions (PYTHON2.7 COMPAT) - # "C408", # Unnecessary `dict` call (rewrite as a literal) + "C408", # Unnecessary `dict` call (rewrite as a literal) "C90", # mccabe (function `X` is too complex) "COM812", # Trailing comma missing "D", # pydocstyle @@ -80,10 +81,6 @@ ignore = [ force-single-line = true # one import per line lines-after-imports = 2 -[tool.isort] -force_single_line = true # one import per line -lines_after_imports = 2 # blank spaces after import section - [tool.coverage.report] exclude_lines = [ "enum.IntEnum", diff --git a/scripts/internal/git_pre_commit.py b/scripts/internal/git_pre_commit.py index 5fefac8b6..92852f836 100755 --- a/scripts/internal/git_pre_commit.py +++ b/scripts/internal/git_pre_commit.py @@ -4,20 +4,10 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -"""This gets executed on 'git commit' and rejects the commit in case the -submitted code does not pass validation. Validation is run only against -the files which were modified in the commit. Checks: - -- assert no space at EOLs -- assert not pdb.set_trace in code -- assert no bare except clause ("except:") in code -- assert "isort" checks pass -- assert C linter checks pass -- assert RsT checks pass -- assert TOML checks pass -- abort if files were added/renamed/removed and MANIFEST.in was not updated - -Install this with "make install-git-hooks". +"""This gets executed on 'git commit' and rejects the commit in case +the submitted code does not pass validation. Validation is run only +against the files which were modified in the commit. Install this with +"make install-git-hooks". """ from __future__ import print_function @@ -116,15 +106,6 @@ def ruff(files): ) -def isort(files): - print("running isort (%s)" % len(files)) - cmd = [PYTHON, "-m", "isort", "--check-only"] + files - if subprocess.call(cmd) != 0: - msg = "python code didn't pass 'isort' style check; " - msg += "try running 'make fix-imports'" - return sys.exit(msg) - - def c_linter(files): print("running clinter (%s)" % len(files)) # XXX: we should escape spaces and possibly other amenities here @@ -151,7 +132,6 @@ def main(): py_files, c_files, rst_files, toml_files, new_rm_mv = git_commit_files() if py_files: ruff(py_files) - isort(py_files) if c_files: c_linter(c_files) if rst_files: diff --git a/scripts/internal/winmake.py b/scripts/internal/winmake.py index c2c20bc0a..cb039d02d 100755 --- a/scripts/internal/winmake.py +++ b/scripts/internal/winmake.py @@ -38,7 +38,6 @@ PYPY = '__pypy__' in sys.builtin_module_names DEPS = [ "coverage", - "nose", "pdbpp", "pip", "pyperf", From ddca4dbe4ce27c955ce8d455a91683556487a257 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 14:29:14 +0200 Subject: [PATCH 47/50] try to fix win test --- scripts/internal/winmake.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/scripts/internal/winmake.py b/scripts/internal/winmake.py index cb039d02d..6978a7e61 100755 --- a/scripts/internal/winmake.py +++ b/scripts/internal/winmake.py @@ -19,7 +19,6 @@ import errno import fnmatch import os -import shlex import shutil import site import ssl @@ -115,9 +114,7 @@ def win_colorprint(s, color=LIGHTBLUE): def sh(cmd, nolog=False): if not nolog: safe_print("cmd: " + cmd) - if isinstance(cmd, str): - cmd = shlex.split(cmd) - p = subprocess.Popen(cmd, env=os.environ, cwd=os.getcwd()) + p = subprocess.Popen(cmd, shell=True, env=os.environ, cwd=os.getcwd()) # noqa p.communicate() if p.returncode != 0: sys.exit(p.returncode) From 0fdfe80f6f2923e9765f661fae7c2bf834031e51 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 14:32:09 +0200 Subject: [PATCH 48/50] fix syntax err --- scripts/internal/print_api_speed.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/internal/print_api_speed.py b/scripts/internal/print_api_speed.py index baa1c5a28..8abaed0c4 100755 --- a/scripts/internal/print_api_speed.py +++ b/scripts/internal/print_api_speed.py @@ -192,8 +192,8 @@ def main(): if not prio_set: msg = "\nWARN: couldn't set highest process priority " - msg += "(requires root)", "red" - print_color(msg) + msg += "(requires root)" + print_color(msg, "red") if __name__ == '__main__': From db91bebaff6231763a7d43392df40fefa43505bd Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 14:40:14 +0200 Subject: [PATCH 49/50] expand make clean Signed-off-by: Giampaolo Rodola --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 06dd2a5d5..862c8b6c4 100644 --- a/Makefile +++ b/Makefile @@ -72,6 +72,7 @@ clean: ## Remove all build files. .coverage \ .failed-tests.txt \ .pytest_cache \ + .ruff_cache/ \ build/ \ dist/ \ docs/_build/ \ From 5058281ed15543333fe17445730fa25cb1abc168 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 4 Oct 2023 14:45:44 +0200 Subject: [PATCH 50/50] update HISTORY --- HISTORY.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HISTORY.rst b/HISTORY.rst index 3b00b3b9d..78e533234 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -17,6 +17,8 @@ XXXX-XX-XX - 2246_: drop python 3.4 & 3.5 support. (patch by Matthieu Darbois) - 2290_: PID reuse is now pre-emptively checked for `Process.ppid()`_ and `Process.parents()`_. +- 2312_: use ``ruff`` Python linter instead of ``flake8 + isort``. It's an + order of magnitude faster + it adds a ton of new code quality checks. **Bug fixes**