chore(pre-commit): update pre-commit hooks

This commit is contained in:
Xuehai Pan 2024-12-30 01:42:15 +08:00
parent 08f2131acd
commit 8ee9d5c430
16 changed files with 79 additions and 91 deletions

View file

@ -25,7 +25,7 @@ repos:
- id: debug-statements
- id: double-quote-string-fixer
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.4
rev: v0.9.0
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]

View file

@ -604,9 +604,9 @@ class PrometheusExporter: # pylint: disable=too-many-instance-attributes
username = process.username()
alive_pids.add((pid, username))
if (pid, username) not in host_snapshots: # noqa: SIM401,RUF100
host_snapshot = host_snapshots[(pid, username)] = process.host_snapshot()
host_snapshot = host_snapshots[pid, username] = process.host_snapshot()
else:
host_snapshot = host_snapshots[(pid, username)]
host_snapshot = host_snapshots[pid, username]
self.process_info.labels(
hostname=self.hostname,
index=index,

View file

@ -25,7 +25,7 @@ import os
import threading
import time
from collections import OrderedDict, defaultdict
from typing import Callable, ClassVar, Generator, Iterable, NamedTuple, TypeVar
from typing import TYPE_CHECKING, ClassVar, NamedTuple, TypeVar
from weakref import WeakSet
from nvitop.api import host
@ -34,6 +34,10 @@ from nvitop.api.process import GpuProcess, HostProcess
from nvitop.api.utils import GiB, MiB, Snapshot
if TYPE_CHECKING:
from collections.abc import Callable, Generator, Iterable
__all__ = ['take_snapshots', 'collect_in_background', 'ResourceMetricCollector']

View file

@ -115,7 +115,7 @@ import textwrap
import threading
import time
from collections import OrderedDict
from typing import TYPE_CHECKING, Any, Callable, ClassVar, Generator, Iterable, NamedTuple, overload
from typing import TYPE_CHECKING, Any, ClassVar, NamedTuple, overload
from nvitop.api import libcuda, libcudart, libnvml
from nvitop.api.process import GpuProcess
@ -131,7 +131,7 @@ from nvitop.api.utils import (
if TYPE_CHECKING:
from collections.abc import Hashable
from collections.abc import Callable, Generator, Hashable, Iterable
from typing_extensions import (
Literal, # Python 3.8+
Self, # Python 3.11+
@ -458,9 +458,7 @@ class Device: # pylint: disable=too-many-instance-attributes,too-many-public-me
return cuda_devices
@staticmethod
def from_cuda_indices(
cuda_indices: int | Iterable[int] | None = None,
) -> list[CudaDevice]:
def from_cuda_indices(cuda_indices: int | Iterable[int] | None = None) -> list[CudaDevice]:
"""Return a list of CUDA devices of the given CUDA indices.
The CUDA ordinal will be enumerate from the ``CUDA_VISIBLE_DEVICES`` environment variable.
@ -1528,10 +1526,7 @@ class Device: # pylint: disable=too-many-instance-attributes,too-many-public-me
return self._nvlink_link_count # type: ignore[return-value]
@memoize_when_activated
def nvlink_throughput(
self,
interval: float | None = None,
) -> list[ThroughputInfo]: # in KiB/s
def nvlink_throughput(self, interval: float | None = None) -> list[ThroughputInfo]: # in KiB/s
"""The current NVLink throughput for each NVLink in KiB/s.
This function is querying data counters between methods calls and thus is the NVLink
@ -1606,10 +1601,7 @@ class Device: # pylint: disable=too-many-instance-attributes,too-many-public-me
for tx, rx in zip(throughputs[:nvlink_link_count], throughputs[nvlink_link_count:])
]
def nvlink_total_throughput(
self,
interval: float | None = None,
) -> ThroughputInfo: # in KiB/s
def nvlink_total_throughput(self, interval: float | None = None) -> ThroughputInfo: # in KiB/s
"""The total NVLink throughput for all NVLinks in KiB/s.
This function is querying data counters between methods calls and thus is the NVLink
@ -1639,10 +1631,7 @@ class Device: # pylint: disable=too-many-instance-attributes,too-many-public-me
rx=sum(rx_throughputs) if rx_throughputs else NA,
)
def nvlink_mean_throughput(
self,
interval: float | None = None,
) -> ThroughputInfo: # in KiB/s
def nvlink_mean_throughput(self, interval: float | None = None) -> ThroughputInfo: # in KiB/s
"""The mean NVLink throughput for all NVLinks in KiB/s.
This function is querying data counters between methods calls and thus is the NVLink
@ -1672,10 +1661,7 @@ class Device: # pylint: disable=too-many-instance-attributes,too-many-public-me
rx=round(sum(rx_throughputs) / len(rx_throughputs)) if rx_throughputs else NA,
)
def nvlink_tx_throughput(
self,
interval: float | None = None,
) -> list[int | NaType]: # in KiB/s
def nvlink_tx_throughput(self, interval: float | None = None) -> list[int | NaType]: # in KiB/s
"""The current NVLink transmit data throughput in KiB/s for each NVLink.
This function is querying data counters between methods calls and thus is the NVLink
@ -1695,10 +1681,7 @@ class Device: # pylint: disable=too-many-instance-attributes,too-many-public-me
"""
return [tx for tx, _ in self.nvlink_throughput(interval=interval)]
def nvlink_mean_tx_throughput(
self,
interval: float | None = None,
) -> int | NaType: # in KiB/s
def nvlink_mean_tx_throughput(self, interval: float | None = None) -> int | NaType: # in KiB/s
"""The mean NVLink transmit data throughput for all NVLinks in KiB/s.
This function is querying data counters between methods calls and thus is the NVLink
@ -1718,10 +1701,7 @@ class Device: # pylint: disable=too-many-instance-attributes,too-many-public-me
"""
return self.nvlink_mean_throughput(interval=interval).tx
def nvlink_total_tx_throughput(
self,
interval: float | None = None,
) -> int | NaType: # in KiB/s
def nvlink_total_tx_throughput(self, interval: float | None = None) -> int | NaType: # in KiB/s
"""The total NVLink transmit data throughput for all NVLinks in KiB/s.
This function is querying data counters between methods calls and thus is the NVLink
@ -1741,10 +1721,7 @@ class Device: # pylint: disable=too-many-instance-attributes,too-many-public-me
"""
return self.nvlink_total_throughput(interval=interval).tx
def nvlink_rx_throughput(
self,
interval: float | None = None,
) -> list[int | NaType]: # in KiB/s
def nvlink_rx_throughput(self, interval: float | None = None) -> list[int | NaType]: # in KiB/s
"""The current NVLink receive data throughput for each NVLink in KiB/s.
This function is querying data counters between methods calls and thus is the NVLink
@ -1764,10 +1741,7 @@ class Device: # pylint: disable=too-many-instance-attributes,too-many-public-me
"""
return [rx for _, rx in self.nvlink_throughput(interval=interval)]
def nvlink_mean_rx_throughput(
self,
interval: float | None = None,
) -> int | NaType: # in KiB/s
def nvlink_mean_rx_throughput(self, interval: float | None = None) -> int | NaType: # in KiB/s
"""The mean NVLink receive data throughput for all NVLinks in KiB/s.
This function is querying data counters between methods calls and thus is the NVLink
@ -1787,10 +1761,7 @@ class Device: # pylint: disable=too-many-instance-attributes,too-many-public-me
"""
return self.nvlink_mean_throughput(interval=interval).rx
def nvlink_total_rx_throughput(
self,
interval: float | None = None,
) -> int | NaType: # in KiB/s
def nvlink_total_rx_throughput(self, interval: float | None = None) -> int | NaType: # in KiB/s
"""The total NVLink receive data throughput for all NVLinks in KiB/s.
This function is querying data counters between methods calls and thus is the NVLink

View file

@ -23,12 +23,16 @@ utilization (CPU, memory, disks, network, sensors) in Python.
from __future__ import annotations
import os as _os
from typing import Callable as _Callable
from typing import TYPE_CHECKING as _TYPE_CHECKING
import psutil as _psutil
from psutil import * # noqa: F403 # pylint: disable=wildcard-import,unused-wildcard-import,redefined-builtin
if _TYPE_CHECKING:
from collections.abc import Callable as _Callable
__all__ = [name for name in _psutil.__all__ if not name.startswith('_')] + [
'getuser',
'hostname',

View file

@ -28,11 +28,11 @@ import sys as _sys
import threading as _threading
from typing import TYPE_CHECKING as _TYPE_CHECKING
from typing import Any as _Any
from typing import Callable as _Callable
from typing import ClassVar as _ClassVar
if _TYPE_CHECKING:
from collections.abc import Callable as _Callable
from typing_extensions import Self as _Self # Python 3.11+
from typing_extensions import TypeAlias as _TypeAlias # Python 3.10+

View file

@ -28,11 +28,11 @@ import sys as _sys
import threading as _threading
from typing import TYPE_CHECKING as _TYPE_CHECKING
from typing import Any as _Any
from typing import Callable as _Callable
from typing import ClassVar as _ClassVar
if _TYPE_CHECKING:
from collections.abc import Callable as _Callable
from typing_extensions import Self as _Self # Python 3.11+

View file

@ -33,7 +33,6 @@ from types import FunctionType as _FunctionType
from types import ModuleType as _ModuleType
from typing import TYPE_CHECKING as _TYPE_CHECKING
from typing import Any as _Any
from typing import Callable as _Callable
from typing import ClassVar as _ClassVar
# Python Bindings for the NVIDIA Management Library (NVML)
@ -47,6 +46,7 @@ from nvitop.api.utils import colored as __colored
if _TYPE_CHECKING:
from collections.abc import Callable as _Callable
from typing_extensions import Self as _Self # Python 3.11+
from typing_extensions import TypeAlias as _TypeAlias # Python 3.10+
@ -513,10 +513,7 @@ def nvmlQueryFieldValues(
return values_with_timestamps
def nvmlCheckReturn(
retval: _Any,
types: type | tuple[type, ...] | None = None,
) -> bool:
def nvmlCheckReturn(retval: _Any, types: type | tuple[type, ...] | None = None) -> bool:
"""Check whether the return value is not :const:`nvitop.NA` and is one of the given types."""
if types is None:
return retval != NA
@ -595,12 +592,12 @@ if not _pynvml_installation_corrupted:
if __get_running_processes_version_suffix is None:
# pylint: disable-next=protected-access,no-member
_nvmlGetFunctionPointer = _pynvml._nvmlGetFunctionPointer
nvmlGetFunctionPointer = _pynvml._nvmlGetFunctionPointer
__get_running_processes_version_suffix = '_v3'
def lookup(symbol: str) -> _Any | None:
try:
ptr = _nvmlGetFunctionPointer(symbol)
ptr = nvmlGetFunctionPointer(symbol)
except NVMLError_FunctionNotFound:
LOGGER.debug('Failed to found symbol `%s`.', symbol)
return None
@ -711,10 +708,7 @@ if not _pynvml_installation_corrupted:
NVMLError_Unknown:
On any unexpected error.
"""
return __nvml_device_get_running_processes(
'nvmlDeviceGetComputeRunningProcesses',
handle,
)
return __nvml_device_get_running_processes('nvmlDeviceGetComputeRunningProcesses', handle)
def nvmlDeviceGetGraphicsRunningProcesses( # pylint: disable=function-redefined
handle: c_nvmlDevice_t,
@ -738,10 +732,7 @@ if not _pynvml_installation_corrupted:
NVMLError_Unknown:
On any unexpected error.
"""
return __nvml_device_get_running_processes(
'nvmlDeviceGetGraphicsRunningProcesses',
handle,
)
return __nvml_device_get_running_processes('nvmlDeviceGetGraphicsRunningProcesses', handle)
def nvmlDeviceGetMPSComputeRunningProcesses( # pylint: disable=function-redefined
handle: c_nvmlDevice_t,
@ -819,10 +810,10 @@ if not _pynvml_installation_corrupted:
if __get_memory_info_version_suffix is None:
# pylint: disable-next=protected-access,no-member
_nvmlGetFunctionPointer = _pynvml._nvmlGetFunctionPointer
nvml_get_function_pointer = _pynvml._nvmlGetFunctionPointer
__get_memory_info_version_suffix = '_v2'
try:
_nvmlGetFunctionPointer('nvmlDeviceGetMemoryInfo_v2')
nvml_get_function_pointer('nvmlDeviceGetMemoryInfo_v2')
except NVMLError_FunctionNotFound:
LOGGER.debug('Failed to found symbol `nvmlDeviceGetMemoryInfo_v2`.')
c_nvmlMemory_t = c_nvmlMemory_v1_t

View file

@ -25,9 +25,9 @@ import datetime
import functools
import os
import threading
from abc import ABCMeta
from abc import ABC
from types import FunctionType
from typing import TYPE_CHECKING, Any, Callable, Generator, Iterable
from typing import TYPE_CHECKING, Any
from weakref import WeakValueDictionary
from nvitop.api import host, libnvml
@ -43,6 +43,7 @@ from nvitop.api.utils import (
if TYPE_CHECKING:
from collections.abc import Callable, Generator, Iterable
from typing_extensions import Self # Python 3.11+
from nvitop.api.device import Device
@ -122,7 +123,7 @@ def auto_garbage_clean(
except host.PsutilError as ex:
try:
with GpuProcess.INSTANCE_LOCK:
del GpuProcess.INSTANCES[(self.pid, self.device)]
del GpuProcess.INSTANCES[self.pid, self.device]
except (KeyError, AttributeError):
pass
try:
@ -144,7 +145,7 @@ def auto_garbage_clean(
return wrapper
class HostProcess(host.Process, metaclass=ABCMeta):
class HostProcess(host.Process, ABC):
"""Represent an OS process with the given PID.
If PID is omitted current process PID (:func:`os.getpid`) is used. The instance will be cache
@ -476,7 +477,7 @@ class GpuProcess: # pylint: disable=too-many-instance-attributes,too-many-publi
with cls.INSTANCE_LOCK:
try:
instance = cls.INSTANCES[(pid, device)]
instance = cls.INSTANCES[pid, device]
if instance.is_running():
return instance # type: ignore[return-value]
except KeyError:
@ -492,7 +493,7 @@ class GpuProcess: # pylint: disable=too-many-instance-attributes,too-many-publi
instance._hash = None
instance._username = None
cls.INSTANCES[(pid, device)] = instance
cls.INSTANCES[pid, device] = instance
return instance

View file

@ -29,11 +29,15 @@ import re
import sys
import time
from collections.abc import KeysView
from typing import Any, Callable, Generator, Iterable, Iterator, TypeVar
from typing import TYPE_CHECKING, Any, Callable, TypeVar
from psutil import WINDOWS
if TYPE_CHECKING:
from collections.abc import Generator, Iterable, Iterator
__all__ = [
'NA',
'NaType',
@ -479,9 +483,10 @@ NotApplicableType = NaType
# NA == 'N/A' -> True
# NA is NaType() -> True (`NaType` is a singleton class)
NA = NaType()
NA.__doc__ = """The singleton instance of :class:`NaType`. The actual value is :const:`str: 'N/A'`.""" # pylint: disable=attribute-defined-outside-init
"""The singleton instance of :class:`NaType`. The actual value is :const:`str: 'N/A'`."""
NotApplicable = NA
"""The singleton instance of :class:`NaType`. The actual value is :const:`str: 'N/A'`."""
UINT_MAX: int = ctypes.c_uint(-1).value # 0xFFFFFFFF
"""The maximum value of :class:`ctypes.c_uint`."""

View file

@ -33,11 +33,11 @@ VALUE2SYMBOL_DOWN = {
SYMBOL2VALUE_UP = {v: k for k, v in VALUE2SYMBOL_UP.items()}
SYMBOL2VALUE_DOWN = {v: k for k, v in VALUE2SYMBOL_DOWN.items()}
PAIR2SYMBOL_UP = {
(s1, s2): VALUE2SYMBOL_UP[(SYMBOL2VALUE_UP[s1][-1], SYMBOL2VALUE_UP[s2][0])]
(s1, s2): VALUE2SYMBOL_UP[SYMBOL2VALUE_UP[s1][-1], SYMBOL2VALUE_UP[s2][0]]
for s1, s2 in itertools.product(SYMBOL2VALUE_UP, repeat=2)
}
PAIR2SYMBOL_DOWN = {
(s1, s2): VALUE2SYMBOL_DOWN[(SYMBOL2VALUE_DOWN[s1][-1], SYMBOL2VALUE_DOWN[s2][0])]
(s1, s2): VALUE2SYMBOL_DOWN[SYMBOL2VALUE_DOWN[s1][-1], SYMBOL2VALUE_DOWN[s2][0]]
for s1, s2 in itertools.product(SYMBOL2VALUE_DOWN, repeat=2)
}
GRAPH_SYMBOLS = ''.join(
@ -269,7 +269,7 @@ class HistoryGraph: # pylint: disable=too-many-instance-attributes
for h in range(self.height):
s1 = min(max(round(5 * (value1 - h)), 0), 4)
s2 = min(max(round(5 * (value2 - h)), 0), 4)
bar.append(self.value2symbol[(s1, s2)])
bar.append(self.value2symbol[s1, s2])
if not self.upsidedown:
bar.reverse()
return bar

View file

@ -7,10 +7,11 @@
import copy
import curses
import curses.ascii
import string
from collections import OrderedDict
DIGITS = set(map(ord, '0123456789'))
DIGITS = set(map(ord, string.digits))
# Arbitrary numbers which are not used with curses.KEY_XYZ
ANYKEY, PASSIVE_ACTION, ALT_KEY, QUANT_KEY = range(9001, 9005)
@ -54,7 +55,7 @@ VERY_SPECIAL_KEYS = {
}
def _uncase_special_key(string):
def _uncase_special_key(key_string):
"""Uncase a special key.
>>> _uncase_special_key('Esc')
@ -70,9 +71,9 @@ def _uncase_special_key(string):
>>> _uncase_special_key('A-x')
'a-x'
"""
uncased = string.lower()
uncased = key_string.lower()
if len(uncased) == 3 and (uncased.startswith(('a-', 'm-'))):
uncased = f'{uncased[0]}-{string[-1]}'
uncased = f'{uncased[0]}-{key_string[-1]}'
return uncased
@ -139,13 +140,13 @@ def parse_keybinding(obj): # pylint: disable=too-many-branches
if in_brackets:
if char == '>':
in_brackets = False
string = ''.join(bracket_content)
key_string = ''.join(bracket_content)
try:
keys = SPECIAL_KEYS_UNCASED[_uncase_special_key(string)]
keys = SPECIAL_KEYS_UNCASED[_uncase_special_key(key_string)]
yield from keys
except KeyError:
if string.isdigit():
yield int(string)
if key_string.isdigit():
yield int(key_string)
else:
yield ord('<')
for bracket_char in bracket_content:
@ -199,7 +200,7 @@ def construct_keybinding(keys):
continue
if alt_key_on:
try:
strings.append(f'<{REVERSED_SPECIAL_KEYS[(ALT_KEY, key)]}>')
strings.append(f'<{REVERSED_SPECIAL_KEYS[ALT_KEY, key]}>')
except KeyError:
strings.extend(map(key_to_string, (ALT_KEY, key)))
else:

View file

@ -5,6 +5,7 @@
# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring
import curses
import string
import threading
import time
from functools import partial
@ -16,6 +17,9 @@ from nvitop.gui.library.utils import cut_string
from nvitop.gui.library.widestring import WideString
DIGITS = set(string.digits)
class MessageBox(Displayable): # pylint: disable=too-many-instance-attributes
class Option: # pylint: disable=too-few-public-methods
# pylint: disable-next=too-many-arguments
@ -213,10 +217,7 @@ class MessageBox(Displayable): # pylint: disable=too-many-instance-attributes
keymaps.copy('messagebox', option.key, key)
keymaps['messagebox'][keymaps.keybuffer.quantifier_key] = 'false'
if (
len(set('0123456789').intersection(keymaps['messagebox'])) == 0
and self.num_options <= 9
):
if len(DIGITS.intersection(keymaps['messagebox'])) == 0 and self.num_options <= 9:
for key_n, option in zip('123456789', self.options):
keymaps.copy('messagebox', option.key, key_n)

View file

@ -3,11 +3,13 @@
# pylint: disable=missing-module-docstring,missing-class-docstring,missing-function-docstring
from __future__ import annotations
import itertools
import threading
import time
from operator import attrgetter, xor
from typing import Any, Callable, NamedTuple
from typing import TYPE_CHECKING, Any, NamedTuple
from cachetools.func import ttl_cache
@ -29,6 +31,10 @@ from nvitop.gui.library import (
)
if TYPE_CHECKING:
from collections.abc import Callable
class Order(NamedTuple):
key: Callable[[Any], Any]
reverse: bool

View file

@ -62,13 +62,14 @@ import math
import os
import sys
import warnings
from typing import TYPE_CHECKING, Callable, Iterable, Sequence, overload
from typing import TYPE_CHECKING, overload
from nvitop.api import Device, GpuProcess, Snapshot, colored, host, human2bytes, libnvml
from nvitop.version import __version__
if TYPE_CHECKING:
from collections.abc import Callable, Iterable, Sequence
from typing_extensions import Literal # Python 3.8+

View file

@ -160,6 +160,9 @@ ignore = [
"W505",
# ANN401: dynamically typed expressions (typing.Any) are disallowed
"ANN401",
# FURB189: use the `UserDict`, `UserList`, and `UserString` instead
# internally subclassing `dict`, `list`, and `str`
"FURB189",
# S101: use of `assert` detected
# internal use and may never raise at runtime
"S101",