diff options
26 files changed, 144 insertions, 107 deletions
diff --git a/docs/conf.py b/docs/conf.py index 51f800db..0a4594b3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -125,8 +125,7 @@ html_theme = 'sphinx_rtd_theme' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -html_theme_options = { -} +html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. # html_theme_path = [] @@ -166,14 +165,7 @@ html_static_path = ['_static'] # html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -html_sidebars = { - '**': [ - 'about.html', - 'navigation.html', - 'links.html', - 'searchbox.html' - ] -} +html_sidebars = {'**': ['about.html', 'navigation.html', 'links.html', 'searchbox.html']} # Additional templates that should be rendered to pages, maps page names to # template names. @@ -227,13 +219,10 @@ htmlhelp_basename = 'Glancesdoc' latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. # 'preamble': '', - # Latex figure (float) alignment # 'figure_align': 'htbp', } @@ -242,8 +231,7 @@ latex_elements = { # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'Glances.tex', 'Glances Documentation', - 'Nicolas Hennion', 'manual'), + (master_doc, 'Glances.tex', 'Glances Documentation', 'Nicolas Hennion', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -271,10 +259,7 @@ latex_documents = [ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - ('glances', 'glances', 'An eye on your system', - '', 1) -] +man_pages = [('glances', 'glances', 'An eye on your system', '', 1)] # If true, show URL addresses after external links. # man_show_urls = False @@ -286,9 +271,15 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'Glances', 'Glances Documentation', - author, 'Glances', 'One line description of project.', - 'Miscellaneous'), + ( + master_doc, + 'Glances', + 'Glances Documentation', + author, + 'Glances', + 'One line description of project.', + 'Miscellaneous', + ), ] # Documents to append as an appendix to all manuals. diff --git a/glances/client.py b/glances/client.py index ed020ef5..6b8d4033 100644 --- a/glances/client.py +++ b/glances/client.py @@ -122,8 +122,9 @@ class GlancesClient(object): else: self.log_and_exit( ( - 'Client and server not compatible: ' - 'Client version: {} / Server version: {}'.format(__version__, client_version) + 'Client and server not compatible: ' 'Client version: {} / Server version: {}'.format( + __version__, client_version + ) ) ) return False diff --git a/glances/exports/glances_restful/__init__.py b/glances/exports/glances_restful/__init__.py index 4c674d49..c983dfb9 100644 --- a/glances/exports/glances_restful/__init__.py +++ b/glances/exports/glances_restful/__init__.py @@ -9,7 +9,6 @@ """RESTful interface class.""" - from glances.globals import listkeys from glances.logger import logger from glances.exports.export import GlancesExport diff --git a/glances/folder_list.py b/glances/folder_list.py index aaa79575..f8d771f6 100644 --- a/glances/folder_list.py +++ b/glances/folder_list.py @@ -8,6 +8,7 @@ # """Manage the folder list.""" + from __future__ import unicode_literals diff --git a/glances/globals.py b/glances/globals.py index 6039f868..7e1d2721 100644 --- a/glances/globals.py +++ b/glances/globals.py @@ -19,8 +19,6 @@ import sys import platform import ujson from operator import itemgetter, methodcaller -import unicodedata -import types import subprocess from datetime import datetime import re @@ -28,14 +26,8 @@ import base64 import functools import weakref -import queue -from configparser import ConfigParser, NoOptionError, NoSectionError from statistics import mean -from xmlrpc.client import Fault, ProtocolError, ServerProxy, Transport, Server -from xmlrpc.server import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer from urllib.request import urlopen, Request -from urllib.error import HTTPError, URLError -from urllib.parse import urlparse # Correct issue #1025 by monkey path the xmlrpc lib from defusedxml.xmlrpc import monkey_patch diff --git a/glances/main.py b/glances/main.py index 27d0c982..f8423ea4 100644 --- a/glances/main.py +++ b/glances/main.py @@ -241,7 +241,7 @@ Examples of use: ) parser.add_argument( '--enable-irq', action='store_true', default=False, dest='enable_irq', help='enable IRQ module' - ), + ) parser.add_argument( '--enable-process-extended', action='store_true', @@ -255,14 +255,14 @@ Examples of use: default=True, dest='enable_separator', help='disable separator in the UI (between top and others modules)', - ), + ) parser.add_argument( '--disable-cursor', action='store_true', default=False, dest='disable_cursor', help='disable cursor (process selection) in the UI', - ), + ) # Sort processes list parser.add_argument( '--sort-processes', diff --git a/glances/outdated.py b/glances/outdated.py index 40574327..a7eab6ac 100644 --- a/glances/outdated.py +++ b/glances/outdated.py @@ -46,7 +46,7 @@ class Outdated(object): self.cache_file = os.path.join(self.cache_dir, 'glances-version.db') # Set default value... - self.data = {u'installed_version': __version__, u'latest_version': '0.0', u'refresh_date': datetime.now()} + self.data = {'installed_version': __version__, 'latest_version': '0.0', 'refresh_date': datetime.now()} # Disable update check if `packaging` is not installed if not PACKAGING_IMPORT: @@ -154,14 +154,14 @@ class Outdated(object): logger.debug("Get latest Glances version from the PyPI RESTful API ({})".format(PYPI_API_URL)) # Update the current time - self.data[u'refresh_date'] = datetime.now() + self.data['refresh_date'] = datetime.now() try: res = urlopen(PYPI_API_URL, timeout=3).read() except (HTTPError, URLError, CertificateError) as e: logger.debug("Cannot get Glances version from the PyPI RESTful API ({})".format(e)) else: - self.data[u'latest_version'] = json.loads(nativestr(res))['info']['version'] + self.data['latest_version'] = json.loads(nativestr(res))['info']['version'] logger.debug("Save Glances version to the cache file") # Save result to the cache file diff --git a/glances/outputs/glances_curses.py b/glances/outputs/glances_curses.py index 9d5ae178..9ab59606 100644 --- a/glances/outputs/glances_curses.py +++ b/glances/outputs/glances_curses.py @@ -8,6 +8,7 @@ # """Curses interface class.""" + from __future__ import unicode_literals import sys diff --git a/glances/outputs/glances_restful_api.py b/glances/outputs/glances_restful_api.py index c07ccba9..1fed6bf9 100644 --- a/glances/outputs/glances_restful_api.py +++ b/glances/outputs/glances_restful_api.py @@ -16,7 +16,7 @@ from io import open import webbrowser from urllib.parse import urljoin -try: +try: from typing import Annotated except ImportError: # Only for Python 3.8 diff --git a/glances/outputs/glances_stdout_apidoc.py b/glances/outputs/glances_stdout_apidoc.py index 7023617f..aa6b2465 100644 --- a/glances/outputs/glances_stdout_apidoc.py +++ b/glances/outputs/glances_stdout_apidoc.py @@ -75,9 +75,7 @@ WebUI refresh It is possible to change the Web UI refresh rate (default is 2 seconds) using the following option in the URL: ``http://localhost:61208/glances/?refresh=5`` -""".format( - api_version=__apiversion__ -) +""".format(api_version=__apiversion__) def indent_stat(stat, indent=' '): diff --git a/glances/outputs/glances_unicode.py b/glances/outputs/glances_unicode.py index 1e369de3..76ae3e60 100644 --- a/glances/outputs/glances_unicode.py +++ b/glances/outputs/glances_unicode.py @@ -10,14 +10,14 @@ """Manage unicode message for Glances output.""" _unicode_message = { - 'ARROW_LEFT': [u'\u2190', u'<'], - 'ARROW_RIGHT': [u'\u2192', u'>'], - 'ARROW_UP': [u'\u2191', u'^'], - 'ARROW_DOWN': [u'\u2193', u'v'], - 'CHECK': [u'\u2713', u''], - 'PROCESS_SELECTOR': [u'>', u'>'], - 'MEDIUM_LINE': [u'\u23AF', u'-'], - 'LOW_LINE': [u'\u2581', u'_'], + 'ARROW_LEFT': ['\u2190', '<'], + 'ARROW_RIGHT': ['\u2192', '>'], + 'ARROW_UP': ['\u2191', '^'], + 'ARROW_DOWN': ['\u2193', 'v'], + 'CHECK': ['\u2713', ''], + 'PROCESS_SELECTOR': ['>', '>'], + 'MEDIUM_LINE': ['\u23af', '-'], + 'LOW_LINE': ['\u2581', '_'], } diff --git a/glances/plugins/connections/__init__.py b/glances/plugins/connections/__init__.py index 61781ecc..e9b49116 100644 --- a/glances/plugins/connections/__init__.py +++ b/glances/plugins/connections/__init__.py @@ -8,6 +8,7 @@ # """Connections plugin.""" + from __future__ import unicode_literals from glances.logger import logger diff --git a/glances/plugins/containers/engines/docker.py b/glances/plugins/containers/engines/docker.py index b3a6a483..fae29a1d 100644 --- a/glances/plugins/containers/engines/docker.py +++ b/glances/plugins/containers/engines/docker.py @@ -8,6 +8,7 @@ # """Docker Extension unit for Glances' Containers plugin.""" + import time from glances.globals import iterkeys, itervalues, nativestr, pretty_date, replace_special_chars diff --git a/glances/plugins/containers/engines/podman.py b/glances/plugins/containers/engines/podman.py index ab016a9e..70572938 100644 --- a/glances/plugins/containers/engines/podman.py +++ b/glances/plugins/containers/engines/podman.py @@ -7,6 +7,7 @@ # SPDX-License-Identifier: LGPL-3.0-only """Podman Extension unit for Glances' Containers plugin.""" + from datetime import datetime from glances.globals import iterkeys, itervalues, nativestr, pretty_date, string_value_to_float, replace_special_chars diff --git a/glances/plugins/diskio/__init__.py b/glances/plugins/diskio/__init__.py index e1293697..8aed84e1 100644 --- a/glances/plugins/diskio/__init__.py +++ b/glances/plugins/diskio/__init__.py @@ -8,6 +8,7 @@ # """Disk I/O plugin.""" + from __future__ import unicode_literals from glances.logger import logger diff --git a/glances/plugins/folders/__init__.py b/glances/plugins/folders/__init__.py index 029069d7..968206ca 100644 --- a/glances/plugins/folders/__init__.py +++ b/glances/plugins/folders/__init__.py @@ -8,6 +8,7 @@ # """Folder plugin.""" + from __future__ import unicode_literals from glances.logger import logger diff --git a/glances/plugins/fs/__init__.py b/glances/plugins/fs/__init__.py index 0aecf250..25b683b3 100644 --- a/glances/plugins/fs/__init__.py +++ b/glances/plugins/fs/__init__.py @@ -8,6 +8,7 @@ # """File system plugin.""" + from __future__ import unicode_literals import operator @@ -166,7 +167,7 @@ class PluginModel(GlancesPluginModel): 'device_name': fs.device, 'fs_type': fs.fstype, # Manage non breaking space (see issue #1065) - 'mnt_point': u(fs.mountpoint).replace(u'\u00A0', ' '), + 'mnt_point': u(fs.mountpoint).replace('\u00a0', ' '), 'size': fs_usage.total, 'used': fs_usage.used, 'free': fs_usage.free, diff --git a/glances/plugins/help/__init__.py b/glances/plugins/help/__init__.py index 0fe571fa..1430447f 100644 --- a/glances/plugins/help/__init__.py +++ b/glances/plugins/help/__init__.py @@ -12,6 +12,7 @@ Help plugin. Just a stupid plugin to display the help screen. """ + import sys from glances.globals import iteritems from glances import __version__, psutil_version diff --git a/glances/plugins/network/__init__.py b/glances/plugins/network/__init__.py index 12fea9fb..aa60281e 100644 --- a/glances/plugins/network/__init__.py +++ b/glances/plugins/network/__init__.py @@ -8,6 +8,7 @@ # """Network plugin.""" + from __future__ import unicode_literals from glances.plugins.plugin.model import GlancesPluginModel diff --git a/glances/plugins/sensors/__init__.py b/glances/plugins/sensors/__init__.py index 8634d579..8aed0e94 100644 --- a/glances/plugins/sensors/__init__.py +++ b/glances/plugins/sensors/__init__.py @@ -8,6 +8,7 @@ # """Sensors plugin.""" + from enum import Enum from concurrent.futures import ThreadPoolExecutor from typing import List, Dict, Literal, Any @@ -369,8 +370,7 @@ class GlancesGrabSensors(object): sensors_current['label'] = feature.label # Sensors value, limit and unit sensors_current['unit'] = self.sensor_unit - sensors_current['value'] = int( - getattr(feature, 'current', 0) if getattr(feature, 'current', 0) else 0) + sensors_current['value'] = int(getattr(feature, 'current', 0) if getattr(feature, 'current', 0) else 0) system_warning = getattr(feature, 'high', None) system_critical = getattr(feature, 'critical', None) sensors_current['warning'] = int(system_warning) if system_warning is not None else None diff --git a/glances/snmp.py b/glances/snmp.py index aa123151..debfcdb6 100644 --- a/glances/snmp.py +++ b/glances/snmp.py @@ -97,7 +97,7 @@ class GlancesSNMPClient(object): cmdgen.UdpTransportTarget((self.host, self.port)), non_repeaters, max_repetitions, - *oid + *oid, ) if self.version.startswith('2'): errorIndication, errorStatus, errorIndex, varBindTable = self.cmdGen.bulkCmd( @@ -105,7 +105,7 @@ class GlancesSNMPClient(object): cmdgen.UdpTransportTarget((self.host, self.port)), non_repeaters, max_repetitions, - *oid + *oid, ) else: # Bulk request are not available with SNMP version 1 diff --git a/pyproject.toml b/pyproject.toml index 4fe27079..30158d4d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,6 +4,13 @@ skip-string-normalization = true exclude = '\./glances/outputs/static/*' [tool.ruff] +line-length = 120 +target-version = "py38" + +[tool.ruff.format] +quote-style = "preserve" + +[tool.ruff.lint] # Enable pycodestyle (`E`) and Pyflakes (`F`) codes by default. select = ["E", "F"] ignore = [] @@ -34,18 +41,13 @@ exclude = [ "dist", "node_modules", "venv", - "docs" + "docs", + "./glances/outputs/static/*" ] -# 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] +[tool.ruff.lint.mccabe] # Unlike Flake8, default to a complexity level of 10. max-complexity = 10
\ No newline at end of file @@ -3,6 +3,7 @@ import re import sys from glances import main + if __name__ == '__main__': sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) sys.exit(main()) @@ -32,16 +32,20 @@ with open('README.rst', encoding='utf-8') as f: def get_data_files(): data_files = [ - ('share/doc/glances', ['AUTHORS', 'COPYING', 'NEWS.rst', 'README.rst', "SECURITY.md", - 'CONTRIBUTING.md', 'conf/glances.conf']), - ('share/man/man1', ['docs/man/glances.1']) + ( + 'share/doc/glances', + ['AUTHORS', 'COPYING', 'NEWS.rst', 'README.rst', "SECURITY.md", 'CONTRIBUTING.md', 'conf/glances.conf'], + ), + ('share/man/man1', ['docs/man/glances.1']), ] return data_files + with open('requirements.txt') as f: required = f.read().splitlines() + def get_install_requires(): requires = required if sys.platform.startswith('win'): @@ -59,10 +63,23 @@ def get_install_extras_require(): 'browser': ['zeroconf>=0.19.1'], 'cloud': ['requests'], 'containers': ['docker>=6.1.1', 'python-dateutil', 'six', 'podman', 'packaging'], - 'export': ['bernhard', 'cassandra-driver', 'elasticsearch', 'graphitesender', - 'ibmcloudant', 'influxdb>=1.0.0', 'influxdb-client', 'pymongo', - 'kafka-python', 'pika', 'paho-mqtt', 'potsdb', 'prometheus_client', - 'pyzmq', 'statsd'], + 'export': [ + 'bernhard', + 'cassandra-driver', + 'elasticsearch', + 'graphitesender', + 'ibmcloudant', + 'influxdb>=1.0.0', + 'influxdb-client', + 'pymongo', + 'kafka-python', + 'pika', + 'paho-mqtt', + 'potsdb', + 'prometheus_client', + 'pyzmq', + 'statsd', + ], 'gpu': ['nvidia-ml-py'], 'graph': ['pygal'], 'ip': ['netifaces'], @@ -71,7 +88,7 @@ def get_install_extras_require(): 'snmp': ['pysnmp'], 'sparklines': ['sparklines'], 'web': ['fastapi', 'uvicorn', 'jinja2', 'requests'], - 'wifi': ['wifi'] + 'wifi': ['wifi'], } if sys.platform.startswith('linux'): extras_require['sensors'] = ['batinfo'] @@ -94,6 +111,7 @@ class tests(Command): def run(self): import subprocess import sys + for t in glob.glob('unittest-core.py'): ret = subprocess.call([sys.executable, t]) != 0 if ret != 0: @@ -138,6 +156,6 @@ setup( 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', - 'Topic :: System :: Monitoring' - ] + 'Topic :: System :: Monitoring', + ], ) diff --git a/unittest-core.py b/unittest-core.py index 6e45c0ce..cdaa6ea4 100755 --- a/unittest-core.py +++ b/unittest-core.py @@ -45,8 +45,7 @@ test_config = core.get_config() test_args = core.get_args() # Init Glances stats -stats = GlancesStats(config=test_config, - args=test_args) +stats = GlancesStats(config=test_config, args=test_args) # Unitest class # ============== @@ -78,7 +77,14 @@ class TestGlances(unittest.TestCase): self.assertIsInstance(plugin_instance.get_raw(), (dict, list)) if plugin_instance.history_enable() and isinstance(plugin_instance.get_raw(), dict): self.assertEqual(plugin_instance.get_key(), None) - self.assertTrue(all([f in [h['name'] for h in plugin_instance.items_history_list] for f in plugin_instance.get_raw_history()])) + self.assertTrue( + all( + [ + f in [h['name'] for h in plugin_instance.items_history_list] + for f in plugin_instance.get_raw_history() + ] + ) + ) elif plugin_instance.history_enable() and isinstance(plugin_instance.get_raw(), list): self.assertNotEqual(plugin_instance.get_key(), None) @@ -135,11 +141,17 @@ class TestGlances(unittest.TestCase): if isinstance(plugin_instance.get_raw(), dict): first_history_field = plugin_instance.get_items_history_list()[0]['name'] elif isinstance(plugin_instance.get_raw(), list): - first_history_field = '_'.join([plugin_instance.get_raw()[0][plugin_instance.get_key()], - plugin_instance.get_items_history_list()[0]['name']]) + first_history_field = '_'.join( + [ + plugin_instance.get_raw()[0][plugin_instance.get_key()], + plugin_instance.get_items_history_list()[0]['name'], + ] + ) self.assertEqual(len(plugin_instance.get_raw_history(first_history_field)), 2) - self.assertGreater(plugin_instance.get_raw_history(first_history_field)[1][0], - plugin_instance.get_raw_history(first_history_field)[0][0]) + self.assertGreater( + plugin_instance.get_raw_history(first_history_field)[1][0], + plugin_instance.get_raw_history(first_history_field)[0][0], + ) # Update stats (add third element) plugin_instance.update() @@ -158,10 +170,8 @@ class TestGlances(unittest.TestCase): elif isinstance(plugin_instance.get_raw(), list): first_history_field = plugin_instance.get_items_history_list()[0]['name'] first_item = plugin_instance.get_raw()[0][plugin_instance.get_key()] - self.assertIsInstance(plugin_instance.get_views(item=first_item, - key=first_history_field), dict) - self.assertTrue('decoration' in plugin_instance.get_views(item=first_item, - key=first_history_field)) + self.assertIsInstance(plugin_instance.get_views(item=first_item, key=first_history_field), dict) + self.assertTrue('decoration' in plugin_instance.get_views(item=first_item, key=first_history_field)) self.assertIsInstance(json.loads(plugin_instance.get_json_views()), dict) self.assertEqual(json.loads(plugin_instance.get_json_views()), plugin_instance.get_views()) @@ -352,12 +362,14 @@ class TestGlances(unittest.TestCase): def test_016_subsample(self): """Test subsampling function.""" print('INFO: [TEST_016] Subsampling') - for l_test in [([1, 2, 3], 4), - ([1, 2, 3, 4], 4), - ([1, 2, 3, 4, 5, 6, 7], 4), - ([1, 2, 3, 4, 5, 6, 7, 8], 4), - (list(range(1, 800)), 4), - (list(range(1, 8000)), 800)]: + for l_test in [ + ([1, 2, 3], 4), + ([1, 2, 3, 4], 4), + ([1, 2, 3, 4 |