Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deps(python): drop Python 3.7 support #150

Merged
merged 4 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

- Operating system and version: [e.g. Ubuntu 20.04 LTS / Windows 10 Build 19043.1110]
- Terminal emulator and version: [e.g. GNOME Terminal 3.36.2 / Windows Terminal 1.8.1521.0]
- Python version: [e.g. `3.7.2` / `3.9.6`]
- Python version: [e.g. `3.8.2` / `3.9.6`]
- NVML version (driver version): [e.g. `460.84`]
- `nvitop` version or commit: [e.g. `0.10.0` / `0.10.1.dev7+ga083321` / `main@75ae3c`]
- `python-ml-py` version: [e.g. `11.450.51`]
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
id: py
uses: actions/setup-python@v5
with:
python-version: "3.7 - 3.13"
python-version: "3.8 - 3.13"
update-environment: true

- name: Upgrade build dependencies
Expand Down Expand Up @@ -129,7 +129,7 @@ jobs:
uses: actions/setup-python@v5
if: startsWith(github.ref, 'refs/tags/')
with:
python-version: "3.7 - 3.13"
python-version: "3.8 - 3.13"
update-environment: true

- name: Upgrade pip
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
id: py
uses: actions/setup-python@v5
with:
python-version: "3.7 - 3.13"
python-version: "3.8 - 3.13"
update-environment: true

- name: Upgrade pip
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ repos:
- id: debug-statements
- id: double-quote-string-fixer
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.3
rev: v0.9.4
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
Expand All @@ -34,7 +34,7 @@ repos:
rev: v3.19.1
hooks:
- id: pyupgrade
args: [--py37-plus] # sync with requires-python
args: [--py38-plus] # sync with requires-python
- repo: https://github.com/pycqa/flake8
rev: 7.1.1
hooks:
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Removed

-
- Drop Python 3.7 support by [@XuehaiPan](https://github.com/XuehaiPan) in [#150](https://github.com/XuehaiPan/nvitop/pull/150).

------

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<!-- markdownlint-disable html -->

![Python 3.7+](https://img.shields.io/badge/Python-3.7%2B-brightgreen)
![Python 3.8+](https://img.shields.io/badge/Python-3.8%2B-brightgreen)
[![PyPI](https://img.shields.io/pypi/v/nvitop?label=pypi&logo=pypi)](https://pypi.org/project/nvitop)
[![conda-forge](https://img.shields.io/conda/vn/conda-forge/nvitop?label=conda&logo=condaforge)](https://anaconda.org/conda-forge/nvitop)
[![Documentation Status](https://img.shields.io/readthedocs/nvitop?label=docs&logo=readthedocs)](https://nvitop.readthedocs.io)
Expand Down Expand Up @@ -111,7 +111,7 @@ An interactive NVIDIA-GPU process viewer and beyond, the one-stop solution for G

## Requirements

- Python 3.7+
- Python 3.8+
- NVIDIA Management Library (NVML)
- nvidia-ml-py
- psutil
Expand Down
4 changes: 2 additions & 2 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ An interactive NVIDIA-GPU process viewer and beyond, the one-stop solution for G
.. |GitHub| image:: https://img.shields.io/badge/GitHub-Homepage-blue?logo=github
.. _GitHub: https://github.com/XuehaiPan/nvitop

.. |Python Version| image:: https://img.shields.io/badge/Python-3.7%2B-brightgreen
.. |Python Version| image:: https://img.shields.io/badge/Python-3.8%2B-brightgreen
.. _Python Version: https://pypi.org/project/nvitop

.. |PyPI Package| image:: https://img.shields.io/pypi/v/nvitop?label=pypi&logo=pypi
Expand Down Expand Up @@ -56,7 +56,7 @@ Install from PyPI (|PyPI Package|_):

.. note::

Python 3.7+ is required, and Python versions lower than 3.7 is not supported.
Python 3.8+ is required, and Python versions lower than 3.8 is not supported.

Install from conda-forge (|Conda-forge Package|_):

Expand Down
3 changes: 1 addition & 2 deletions nvitop-exporter/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
name = "nvitop-exporter"
description = "Prometheus exporter built on top of `nvitop`."
readme = "README.md"
requires-python = ">= 3.7"
requires-python = ">= 3.8"
authors = [{ name = "Xuehai Pan", email = "[email protected]" }]
license = { text = "Apache License, Version 2.0 (Apache-2.0)" }
keywords = [
Expand All @@ -27,7 +27,6 @@ classifiers = [
"Development Status :: 5 - Production/Stable",
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
Expand Down
5 changes: 4 additions & 1 deletion nvitop/api/caching.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def __init__(
@overload
def ttl_cache(
maxsize: int | None = 128,
*,
ttl: float = 600.0,
timer: Callable[[], float] = time.monotonic,
typed: bool = False,
Expand All @@ -132,6 +133,7 @@ def ttl_cache(
@overload
def ttl_cache(
maxsize: Callable[_P, _T],
*,
ttl: float = 600.0,
timer: Callable[[], float] = time.monotonic,
typed: bool = False,
Expand All @@ -141,6 +143,7 @@ def ttl_cache(
# pylint: disable-next=too-many-statements
def ttl_cache(
maxsize: int | Callable[_P, _T] | None = 128,
*,
ttl: float = 600.0,
timer: Callable[[], float] = time.monotonic,
typed: bool = False,
Expand All @@ -165,7 +168,7 @@ def ttl_cache(
return functools.lru_cache(maxsize=maxsize, typed=typed) # type: ignore[return-value]

# pylint: disable-next=too-many-statements,too-many-locals
def wrapper(func: Callable[_P, _T]) -> Callable[_P, _T]:
def wrapper(func: Callable[_P, _T], /) -> Callable[_P, _T]:
cache: dict[Any, _TTLCacheLink] = {}
cache_get = cache.get # bound method to lookup a key or return None
cache_len = cache.__len__ # get cache size without calling len()
Expand Down
4 changes: 3 additions & 1 deletion nvitop/api/collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class SnapshotResult(NamedTuple): # pylint: disable=missing-class-docstring
_T = TypeVar('_T')


def _unique(iterable: Iterable[_T]) -> list[_T]:
def _unique(iterable: Iterable[_T], /) -> list[_T]:
return list(OrderedDict.fromkeys(iterable).keys())


Expand Down Expand Up @@ -399,6 +399,7 @@ class ResourceMetricCollector: # pylint: disable=too-many-instance-attributes
def __init__(
self,
devices: Iterable[Device] | None = None,
*,
root_pids: Iterable[int] | None = None,
interval: float = 1.0,
) -> None:
Expand Down Expand Up @@ -778,6 +779,7 @@ def __init__(
self,
tag: str,
collector: ResourceMetricCollector,
*,
prev: _MetricBuffer | None = None,
) -> None:
self.collector: ResourceMetricCollector = collector
Expand Down
3 changes: 2 additions & 1 deletion nvitop/api/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -1589,6 +1589,7 @@ def nvlink_throughput(self, interval: float | None = None) -> list[ThroughputInf
return []

def query_nvlink_throughput_counters() -> tuple[tuple[int | NaType, int]]:
assert self._handle is not None
return tuple( # type: ignore[return-value]
libnvml.nvmlQueryFieldValues(
self._handle,
Expand Down Expand Up @@ -3149,7 +3150,7 @@ def _parse_cuda_visible_devices(
) -> list[str]: ...


@functools.lru_cache()
@functools.lru_cache
def _parse_cuda_visible_devices( # pylint: disable=too-many-branches,too-many-statements
cuda_visible_devices: str | None = None,
format: Literal['index', 'uuid'] = 'index', # pylint: disable=redefined-builtin
Expand Down
4 changes: 2 additions & 2 deletions nvitop/api/libcuda.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ def __reduce__(self) -> tuple[type[CUDAError], tuple[int]]:
return CUDAError, (self.value,) # pylint: disable=no-member


def cudaExceptionClass(cudaErrorCode: int) -> type[CUDAError]:
def cudaExceptionClass(cudaErrorCode: int, /) -> type[CUDAError]:
"""Map value to a proper subclass of :class:`CUDAError`.

Raises:
Expand Down Expand Up @@ -348,7 +348,7 @@ def __new__(cls) -> CUDAError: # type: ignore[misc,empty-body]
del _extract_cuda_errors_as_classes


def _cudaCheckReturn(ret: _Any) -> _Any:
def _cudaCheckReturn(ret: _Any, /) -> _Any:
if ret != CUDA_SUCCESS:
raise CUDAError(ret)
return ret
Expand Down
6 changes: 3 additions & 3 deletions nvitop/api/libcudart.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ def __reduce__(self) -> tuple[type[cudaError], tuple[int]]:
return cudaError, (self.value,) # pylint: disable=no-member


def cudaExceptionClass(cudaErrorCode: int) -> type[cudaError]:
def cudaExceptionClass(cudaErrorCode: int, /) -> type[cudaError]:
"""Map value to a proper subclass of :class:`cudaError`.

Raises:
Expand Down Expand Up @@ -399,7 +399,7 @@ def __new__(cls) -> cudaError: # type: ignore[misc,empty-body]
del _extract_cuda_errors_as_classes


def _cudaCheckReturn(ret: _Any) -> _Any:
def _cudaCheckReturn(ret: _Any, /) -> _Any:
if ret != cudaSuccess:
raise cudaError(ret)
return ret
Expand All @@ -412,7 +412,7 @@ def _cudaCheckReturn(ret: _Any) -> _Any:
__cudaGetFunctionPointer_cache: dict[str, _ctypes._CFuncPtr] = {} # type: ignore[name-defined]


def __cudaGetFunctionPointer(name: str) -> _ctypes._CFuncPtr: # type: ignore[name-defined]
def __cudaGetFunctionPointer(name: str, /) -> _ctypes._CFuncPtr: # type: ignore[name-defined]
"""Get the function pointer from the CUDA Runtime library.

Raises:
Expand Down
13 changes: 11 additions & 2 deletions nvitop/api/libnvml.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,14 @@

# 5. Add explicit references to appease linters
# pylint: disable=no-member
c_nvmlDevice_t: _TypeAlias = _pynvml.c_nvmlDevice_t # noqa: PYI042
if _TYPE_CHECKING:
# pylint: disable-next=missing-class-docstring,too-few-public-methods,function-redefined
class c_nvmlDevice_t(_ctypes.c_void_p):
pass

else:
c_nvmlDevice_t: _TypeAlias = _pynvml.c_nvmlDevice_t # type: ignore[no-redef] # noqa: PYI042

c_nvmlFieldValue_t: _TypeAlias = _pynvml.c_nvmlFieldValue_t # noqa: PYI042
NVML_SUCCESS: int = _pynvml.NVML_SUCCESS
NVML_ERROR_INSUFFICIENT_SIZE: int = _pynvml.NVML_ERROR_INSUFFICIENT_SIZE
Expand Down Expand Up @@ -377,6 +384,7 @@ def nvmlShutdown() -> None: # pylint: disable=function-redefined

def nvmlQuery(
func: _Callable[..., _Any] | str,
/,
*args: _Any,
default: _Any = NA,
ignore_errors: bool = True,
Expand Down Expand Up @@ -513,7 +521,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
Expand Down Expand Up @@ -643,6 +651,7 @@ def lookup(symbol: str) -> _Any | None:

def __nvml_device_get_running_processes(
func: str,
/,
handle: c_nvmlDevice_t,
) -> list[c_nvmlProcessInfo_t]:
"""Helper function for :func:`nvmlDeviceGet{Compute,Graphics,MPSCompute}RunningProcesses`.
Expand Down
4 changes: 2 additions & 2 deletions nvitop/api/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ def auto_garbage_clean(
raises an exception when falls.
"""

def wrapper(func: Callable[..., Any]) -> Callable[..., Any]:
def wrapper(func: Callable[..., Any], /) -> Callable[..., Any]:
@functools.wraps(func)
def wrapped(self: GpuProcess, *args: Any, **kwargs: Any) -> Any:
def wrapped(self: GpuProcess, /, *args: Any, **kwargs: Any) -> Any:
try:
return func(self, *args, **kwargs)
except host.PsutilError as ex:
Expand Down
2 changes: 2 additions & 0 deletions nvitop/api/termcolor.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ def _can_do_color(
# pylint: disable-next=too-many-arguments
def colored(
text: Any,
/,
color: Color | None = None,
on_color: Highlight | None = None,
attrs: Iterable[Attribute] | None = None,
Expand Down Expand Up @@ -258,6 +259,7 @@ def colored(
# pylint: disable-next=too-many-arguments
def cprint(
text: object,
/,
color: Color | None = None,
on_color: Highlight | None = None,
attrs: Iterable[Attribute] | None = None,
Expand Down
Loading