Improve Lint

This commit is contained in:
nicolargo 2023-05-01 10:12:09 +02:00
parent 4caa267eec
commit f4873cef08
20 changed files with 138 additions and 65 deletions

View File

@ -34,6 +34,8 @@ jobs:
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --exclude=.git,./docs,./glances/outputs/static
# - name: Lint with Ruff
# uses: chartboost/ruff-action@v1
- name: Static type check
run: |

View File

@ -61,6 +61,9 @@ format: venv-dev-upgrade ## Format the code
flake8: venv-dev-upgrade ## Run flake8 linter.
@git ls-files '*.py' | xargs ./venv/bin/python -m flake8 --config=.flake8
ruff: venv-dev-upgrade ## Run Ruff (fastest) linter.
./venv/bin/python -m ruff check . --config=./pyproject.toml
codespell: venv-dev-upgrade ## Run codespell to fix common misspellings in text files
./venv/bin/codespell -S .git,./docs/_build,./Glances.egg-info,./venv,./glances/outputs,*.svg -L hart,bu,te,statics

View File

@ -5,6 +5,7 @@ requirements-parser
flake8
autopep8
autoflake
ruff
codespell
memory-profiler
matplotlib

View File

@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
# SPDX-FileCopyrightText: 2022 Nicolas Hennion <nicolas@nicolargo.com>
# SPDX-FileCopyrightText: 2023 Nicolas Hennion <nicolas@nicolargo.com>
#
# SPDX-License-Identifier: LGPL-3.0-only
#
@ -42,7 +42,7 @@ class GlancesAmp(object):
# AMP name (= module name without glances_)
if name is None:
self.amp_name = self.__class__.__module__[len('glances_') :]
self.amp_name = self.__class__.__module__[len('glances_'):]
else:
self.amp_name = name

View File

@ -67,14 +67,14 @@ class Amp(GlancesAmp):
# For each line
for r in res.split('\n'):
# Split per space .*
l = r.split()
if len(l) < 4:
line = r.split()
if len(line) < 4:
continue
if l[1] == '+':
if line[1] == '+':
status['running'] += 1
elif l[1] == '-':
elif line[1] == '-':
status['stopped'] += 1
elif l[1] == '?':
elif line[1] == '?':
status['upstart'] += 1
# Build the output (string) message
output = 'Services\n'

View File

@ -49,7 +49,9 @@ class AmpsList(object):
# Display a warning (deprecated) message if the monitor section exist
if "monitor" in self.config.sections():
logger.warning(
"A deprecated [monitor] section exists in the Glances configuration file. You should use the new Applications Monitoring Process module instead (http://glances.readthedocs.io/en/develop/aoa/amps.html)."
"A deprecated [monitor] section exists in the Glances configuration file. You should use the new \
Applications Monitoring Process module instead \
(http://glances.readthedocs.io/en/develop/aoa/amps.html)."
)
header = "glances_"
@ -140,9 +142,9 @@ class AmpsList(object):
# Search in both cmdline and name (for kernel thread, see #1261)
for p in processlist:
if (re.search(amp_value.regex(), p['name']) is not None) or (
p['cmdline'] is not None
and p['cmdline'] != []
and re.search(amp_value.regex(), ' '.join(p['cmdline'])) is not None
p['cmdline'] is not None and
p['cmdline'] != [] and
re.search(amp_value.regex(), ' '.join(p['cmdline'])) is not None
):
ret.append(
{'pid': p['pid'], 'cpu_percent': p['cpu_percent'], 'memory_percent': p['memory_percent']}

View File

@ -77,7 +77,7 @@ class CpuPercent(object):
# @TODO: Multisystem...
try:
self.cpu_info['cpu_name'] = open('/proc/cpuinfo', 'r').readlines()[4].split(':')[1].strip()
except:
except (FileNotFoundError, PermissionError, IOError, IndexError, KeyError, AttributeError):
self.cpu_info['cpu_name'] = 'CPU'
return self.cpu_info['cpu_name']

View File

@ -94,7 +94,8 @@ class Export(GlancesExport):
# Table
try:
session.execute(
"CREATE TABLE %s (plugin text, time timeuuid, stat map<text,float>, PRIMARY KEY (plugin, time)) WITH CLUSTERING ORDER BY (time DESC)"
"CREATE TABLE %s (plugin text, time timeuuid, stat map<text,float>, PRIMARY KEY (plugin, time)) \
WITH CLUSTERING ORDER BY (time DESC)"
% self.table
)
except Exception:

View File

@ -10,7 +10,6 @@
"""MongoDB interface class."""
import sys
from datetime import datetime
from glances.logger import logger
from glances.exports.glances_export import GlancesExport

View File

@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
# SPDX-FileCopyrightText: 2022 Nicolas Hennion <nicolas@nicolargo.com>
# SPDX-FileCopyrightText: 2023 Nicolas Hennion <nicolas@nicolargo.com>
#
# SPDX-License-Identifier: LGPL-3.0-only
#
@ -76,12 +76,12 @@ class FolderList(object):
The list is defined in the Glances configuration file.
"""
for l in range(1, self.__folder_list_max_size + 1):
for line in range(1, self.__folder_list_max_size + 1):
value = {}
key = 'folder_' + str(l) + '_'
key = 'folder_' + str(line) + '_'
# Path is mandatory
value['indice'] = str(l)
value['indice'] = str(line)
value['path'] = self.config.get_value(section, key + 'path')
if value['path'] is None:
continue

View File

@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
# SPDX-FileCopyrightText: 2022 Nicolas Hennion <nicolas@nicolargo.com>
# SPDX-FileCopyrightText: 2023 Nicolas Hennion <nicolas@nicolargo.com>
#
# SPDX-License-Identifier: LGPL-3.0-only
#
@ -62,7 +62,7 @@ def json_dumps_dictlist(data, item):
if isinstance(data, dict):
try:
return json_dumps({item: data[item]})
except:
except (TypeError, IndexError, KeyError):
return None
elif isinstance(data, list):
try:
@ -70,7 +70,7 @@ def json_dumps_dictlist(data, item):
# http://stackoverflow.com/questions/4573875/python-get-index-of-dictionary-item-in-list
# But https://github.com/nicolargo/glances/issues/1401
return json_dumps({item: list(map(itemgetter(item), data))})
except:
except (TypeError, IndexError, KeyError):
return None
else:
return None

View File

@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
# SPDX-FileCopyrightText: 2022 Nicolas Hennion <nicolas@nicolargo.com>
# SPDX-FileCopyrightText: 2023 Nicolas Hennion <nicolas@nicolargo.com>
#
# SPDX-License-Identifier: LGPL-3.0-only
#
@ -123,7 +123,8 @@ Examples of use:
'--disable-plugin',
'--disable-plugins',
dest='disable_plugin',
help='disable plugin (comma separated list or all). If all is used, then you need to configure --enable-plugin.',
help='disable plugin (comma separated list or all). If all is used, \
then you need to configure --enable-plugin.',
)
parser.add_argument(
'--enable-plugin', '--enable-plugins', dest='enable_plugin', help='enable plugin (comma separated list)'

View File

@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
# SPDX-FileCopyrightText: 2022 Nicolas Hennion <nicolas@nicolargo.com>
# SPDX-FileCopyrightText: 2023 Nicolas Hennion <nicolas@nicolargo.com>
#
# SPDX-License-Identifier: LGPL-3.0-only
#
@ -1066,7 +1066,7 @@ class _GlancesCurses(object):
# Return to the first column
x = display_x
continue
except:
except Exception:
# Avoid exception (see issue #1692)
pass
# Do not display outside the screen

View File

@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
# SPDX-FileCopyrightText: 2022 Nicolas Hennion <nicolas@nicolargo.com>
# SPDX-FileCopyrightText: 2023 Nicolas Hennion <nicolas@nicolargo.com>
#
# SPDX-License-Identifier: LGPL-3.0-only
#
@ -23,7 +23,7 @@ import glances
try:
TERMINAL_WIDTH = shutil.get_terminal_size(fallback=(79, 24)).columns
except:
except Exception:
TERMINAL_WIDTH = 79

View File

@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
# SPDX-FileCopyrightText: 2022 Nicolas Hennion <nicolas@nicolargo.com>
# SPDX-FileCopyrightText: 2023 Nicolas Hennion <nicolas@nicolargo.com>
#
# SPDX-License-Identifier: LGPL-3.0-only
#
@ -57,11 +57,13 @@ tree_new = {
'_yes': {
'mem': {
'_yes': {
# Once you've identified the offenders, the resolution will again depend on whether their memory usage seems
# business-as-usual or not. For example, a memory leak can be satisfactorily addressed by a one-time or periodic
# restart of the process.
# Once you've identified the offenders, the resolution will again
# depend on whether their memory usage seems business-as-usual or not.
# For example, a memory leak can be satisfactorily addressed by a one-time
# or periodic restart of the process.
# - if memory usage seems anomalous: kill the offending processes.
# - if memory usage seems business-as-usual: add RAM to the server, or split high-memory using services to other servers.
# - if memory usage seems business-as-usual: add RAM to the server,
# or split high-memory using services to other servers.
'_msg': "Memory issue"
},
'_no': {
@ -86,15 +88,22 @@ tree_new = {
'cpu_user': {
'_yes': {
# We expect the user-time percentage to be high.
# There's most likely a program or service you've configured on you server that's hogging CPU.
# There's most likely a program or service you've configured on you server that's
# hogging CPU.
# Checking the % user time just confirms this. When you see that the % user-time is high,
# it's time to see what executable is monopolizing the CPU
# Once you've confirmed that the % usertime is high, check the process list(also provided by top).
# Be default, top sorts the process list by % CPU, so you can just look at the top process or processes.
# If there's a single process hogging the CPU in a way that seems abnormal, it's an anomalous situation
# that a service restart can fix. If there are are multiple processes taking up CPU resources, or it
# there's one process that takes lots of resources while otherwise functioning normally, than your setup
# may just be underpowered. You'll need to upgrade your server(add more cores), or split services out onto
# Once you've confirmed that the % usertime is high, check the process list(also provided
# by top).
# Be default, top sorts the process list by % CPU, so you can just look at the top process
# or processes.
# If there's a single process hogging the CPU in a way that seems abnormal, it's an
# anomalous situation
# that a service restart can fix. If there are are multiple processes taking up CPU
# resources, or it
# there's one process that takes lots of resources while otherwise functioning normally,
# than your setup
# may just be underpowered. You'll need to upgrade your server(add more cores),
# or split services out onto
# other boxes. In either case, you have a resolution:
# - if situation seems anomalous: kill the offending processes.
# - if situation seems typical given history: upgrade server or add more servers.
@ -119,13 +128,14 @@ tree_new = {
# Your slowness isn't due to CPU or IO problems, so it's likely an application-specific issue.
# It's also possible that the slowness is being caused by another server in your cluster, or
# by an external service you rely on.
# start by checking important applications for uncharacteristic slowness(the DB is a good place to start),
# think through which parts of your infrastructure could be slowed down externally. For example, do you
# use an externally hosted email service that could slow down critical parts of your application?
# If you suspect another server in your cluster, strace and lsof can provide information on what the
# process is doing or waiting on. Strace will show you which file descriptors are being read or written
# to(or being attempted to be read from) and lsof can give you a mapping of those file descriptors to
# network connections.
# start by checking important applications for uncharacteristic slowness(the DB is a good place
# to start), think through which parts of your infrastructure could be slowed down externally.
# For example, do you use an externally hosted email service that could slow down critical
# parts of your application ?
# If you suspect another server in your cluster, strace and lsof can provide information on
# what the process is doing or waiting on. Strace will show you which file descriptors are
# being read or written to (or being attempted to be read from) and lsof can give you a
# mapping of those file descriptors to network connections.
'_msg': "External issue"
},
},

View File

@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
# SPDX-FileCopyrightText: 2022 Nicolas Hennion <nicolas@nicolargo.com>
# SPDX-FileCopyrightText: 2023 Nicolas Hennion <nicolas@nicolargo.com>
#
# SPDX-License-Identifier: LGPL-3.0-only
#
@ -101,7 +101,7 @@ class Plugin(GlancesPlugin):
first_column = '{}'.format(m['name'])
first_column_style = self.get_alert(m['count'], m['countmin'], m['countmax'])
second_column = '{}'.format(m['count'] if m['regex'] else '')
for l in m['result'].split('\n'):
for line in m['result'].split('\n'):
# Display first column with the process name...
msg = '{:<16} '.format(first_column)
ret.append(self.curse_add_line(msg, first_column_style))
@ -111,7 +111,7 @@ class Plugin(GlancesPlugin):
# ... only on the first line
first_column = second_column = ''
# Display AMP result in the third column
ret.append(self.curse_add_line(l, splittable=True))
ret.append(self.curse_add_line(line, splittable=True))
ret.append(self.curse_new_line())
# Delete the last empty line

View File

@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
# SPDX-FileCopyrightText: 2022 Nicolas Hennion <nicolas@nicolargo.com>
# SPDX-FileCopyrightText: 2023 Nicolas Hennion <nicolas@nicolargo.com>
#
# SPDX-License-Identifier: LGPL-3.0-only
#
@ -19,7 +19,6 @@ from glances.processes import glances_processes, sort_stats
from glances.outputs.glances_unicode import unicode_message
from glances.plugins.glances_core import Plugin as CorePlugin
from glances.plugins.glances_plugin import GlancesPlugin
from glances.outputs.glances_bars import Bar
def seconds_to_hms(input_seconds):
@ -326,8 +325,8 @@ class Plugin(GlancesPlugin):
# Display rate if stats is available and io_tag ([4]) == 1
# IO
io = int(
(p['io_counters'][0 if rorw == 'ior' else 1] - p['io_counters'][2 if rorw == 'ior' else 3])
/ p['time_since_update']
(p['io_counters'][0 if rorw == 'ior' else 1] - p['io_counters'][2 if rorw == 'ior' else 3]) /
p['time_since_update']
)
if io == 0:
msg = self.layout_stat[rorw].format("0")
@ -358,7 +357,8 @@ class Plugin(GlancesPlugin):
# When a process is selected:
# * display a special character at the beginning of the line
# * underline the command name
ret.append(self.curse_add_line(unicode_message('PROCESS_SELECTOR') if (selected and not args.disable_cursor) else ' ', 'SELECTED'))
ret.append(self.curse_add_line(unicode_message('PROCESS_SELECTOR') if (selected and not args.disable_cursor)
else ' ', 'SELECTED'))
# CPU
ret.append(self._get_process_curses_cpu(p, selected, args))
@ -491,7 +491,8 @@ class Plugin(GlancesPlugin):
Input p is a dict with the following keys:
{'status': 'S',
'memory_info': pmem(rss=466890752, vms=3365347328, shared=68153344, text=659456, lib=0, data=774647808, dirty=0),
'memory_info': pmem(rss=466890752, vms=3365347328, shared=68153344,
text=659456, lib=0, data=774647808, dirty=0),
'pid': 4980,
'io_counters': [165385216, 0, 165385216, 0, 1],
'num_threads': 20,
@ -577,10 +578,12 @@ class Plugin(GlancesPlugin):
if 'memory_info' in p and p['memory_info'] is not None:
ret.append(self.curse_add_line(' Memory info: '))
for k in p['memory_info']._asdict():
ret.append(self.curse_add_line(self.auto_unit(p['memory_info']._asdict()[k], low_precision=False), decoration='INFO', splittable=True))
ret.append(self.curse_add_line(self.auto_unit(p['memory_info']._asdict()[k], low_precision=False),
decoration='INFO', splittable=True))
ret.append(self.curse_add_line(' ' + k + ' ', splittable=True))
if 'memory_swap' in p and p['memory_swap'] is not None:
ret.append(self.curse_add_line(self.auto_unit(p['memory_swap'], low_precision=False), decoration='INFO', splittable=True))
ret.append(self.curse_add_line(self.auto_unit(p['memory_swap'], low_precision=False),
decoration='INFO', splittable=True))
ret.append(self.curse_add_line(' swap ', splittable=True))
# Third line is for open files/network sessions
@ -672,9 +675,9 @@ class Plugin(GlancesPlugin):
ret.append(self.curse_add_line(msg, decoration=self.__mmm_deco(mmm)))
# VIRT and RES memory sum
if (
'memory_info' in self.stats[0]
and self.stats[0]['memory_info'] is not None
and self.stats[0]['memory_info'] != ''
'memory_info' in self.stats[0] and
self.stats[0]['memory_info'] is not None and
self.stats[0]['memory_info'] != ''
):
# VMS
msg = self.layout_stat['virt'].format(

View File

@ -188,7 +188,7 @@ class Plugin(GlancesPlugin):
# Add the new hotspot to the message
msg = '{:{width}}'.format(nativestr(hotspot_name), width=if_name_max_width)
ret.append(self.curse_add_line(msg))
msg = '{:>7}'.format(i['signal'], width=if_name_max_width)
msg = '{:>7}'.format(i['signal'], )
ret.append(
self.curse_add_line(msg, self.get_views(item=i[self.get_key()], key='signal', option='decoration'))
)

View File

@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
# SPDX-FileCopyrightText: 2022 Nicolas Hennion <nicolas@nicolargo.com>
# SPDX-FileCopyrightText: 2023 Nicolas Hennion <nicolas@nicolargo.com>
#
# SPDX-License-Identifier: LGPL-3.0-only
#
@ -313,11 +313,15 @@ class GlancesProcesses(object):
if stat_prefix + '_min' not in self.extended_process:
ret[stat_prefix + '_min'] = proc[stat_prefix + '_percent']
else:
ret[stat_prefix + '_min'] = proc[stat_prefix + '_percent'] if proc[stat_prefix + '_min'] > proc[stat_prefix + '_percent'] else proc[stat_prefix + '_min']
ret[stat_prefix + '_min'] = \
proc[stat_prefix + '_percent'] if proc[stat_prefix + '_min'] > proc[stat_prefix + '_percent'] \
else proc[stat_prefix + '_min']
if stat_prefix + '_max' not in self.extended_process:
ret[stat_prefix + '_max'] = proc[stat_prefix + '_percent']
else:
ret[stat_prefix + '_max'] = proc[stat_prefix + '_percent'] if proc[stat_prefix + '_max'] < proc[stat_prefix + '_percent'] else proc[stat_prefix + '_max']
ret[stat_prefix + '_max'] = \
proc[stat_prefix + '_percent'] if proc[stat_prefix + '_max'] < proc[stat_prefix + '_percent'] \
else proc[stat_prefix + '_max']
if stat_prefix + '_mean_sum' not in self.extended_process:
ret[stat_prefix + '_mean_sum'] = proc[stat_prefix + '_percent']
else:

View File

@ -1,4 +1,51 @@
[tool.black]
line-length = 120
skip-string-normalization = true
exclude = '\./glances/outputs/static/*'
exclude = '\./glances/outputs/static/*'
[tool.ruff]
# Enable pycodestyle (`E`) and Pyflakes (`F`) codes by default.
select = ["E", "F"]
ignore = []
# Allow autofix for all enabled rules (when `--fix`) is provided.
fixable = ["A", "B", "C", "D", "E", "F", "G", "I", "N", "Q", "S", "T", "W", "ANN", "ARG", "BLE", "COM", "DJ", "DTZ", "EM", "ERA", "EXE", "FBT", "ICN", "INP", "ISC", "NPY", "PD", "PGH", "PIE", "PL", "PT", "PTH", "PYI", "RET", "RSE", "RUF", "SIM", "SLF", "TCH", "TID", "TRY", "UP", "YTT"]
unfixable = []
# Exclude a variety of commonly ignored directories.
exclude = [
".bzr",
".direnv",
".eggs",
".git",
".hg",
".mypy_cache",
".nox",
".pants.d",
".pytype",
".ruff_cache",
".svn",
".tox",
".venv",
"__pypackages__",
"_build",
"buck-out",
"build",
"dist",
"node_modules",
"venv",
"docs"
]
# Same as Black.
line-length = 120
# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
# Assume Python 3.11
target-version = "py311"
[tool.ruff.mccabe]
# Unlike Flake8, default to a complexity level of 10.
max-complexity = 10