diff --git a/CHANGELOG.md b/CHANGELOG.md index 94e7a17..a52306f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ recorded here; their history is the git log. ## [Unreleased] +### Changed +- Python 3.12 is the floor (`requires-python = ">=3.12"`): netOrk runs every driver + on 3.12, so 3.10 and 3.11 are no longer tested (NAPALM/driver-standard#6). +- The floor on napalm is 5.1: older releases import `pkg_resources`, which a Python + 3.12 venv no longer has. + ### Added - `HostShutdownMixin.shutdown_host()`, on `DeviceTypeDriver`: shut the device itself down cleanly through its own means; declared, so `hasattr` says whether a driver diff --git a/README.md b/README.md index 44c28e0..a206e3f 100644 --- a/README.md +++ b/README.md @@ -390,7 +390,7 @@ detection vs. presentation there. pip install napalm-device-types ``` -Requires Python ≥ 3.10 (tested up to 3.13) and NAPALM ≥ 4.0. +Requires Python ≥ 3.12 (tested up to 3.13) and NAPALM ≥ 4.0. ## Available base classes diff --git a/napalm_device_types/_matching.py b/napalm_device_types/_matching.py index 839c16e..5cab64d 100644 --- a/napalm_device_types/_matching.py +++ b/napalm_device_types/_matching.py @@ -8,12 +8,9 @@ name a single entry, and guessing would overwrite one the caller never meant. from __future__ import annotations from collections.abc import Callable, Iterable -from typing import TypeVar - -T = TypeVar("T") -def index_live(entries: Iterable[T], key: Callable[[T], str]) -> tuple[dict[str, T], set[str]]: +def index_live[T](entries: Iterable[T], key: Callable[[T], str]) -> tuple[dict[str, T], set[str]]: """Live entries by key, and the keys more than one of them holds. Entries without a key are left out: they are not the caller's to match. @@ -32,7 +29,9 @@ def index_live(entries: Iterable[T], key: Callable[[T], str]) -> tuple[dict[str, return by_key, shared -def check_desired(entries: list[T], key: Callable[[T], str], shared: set[str], what: str) -> None: +def check_desired[T]( + entries: list[T], key: Callable[[T], str], shared: set[str], what: str +) -> None: """``ValueError`` for a desired entry with no key, a key given twice, or a key that names more than one live entry.""" seen: set[str] = set() diff --git a/napalm_device_types/models.py b/napalm_device_types/models.py index 6b4effc..9dbb158 100644 --- a/napalm_device_types/models.py +++ b/napalm_device_types/models.py @@ -5,9 +5,9 @@ These supplement the types defined in napalm.base.models and are used by the abstract device-type driver classes in this package. """ -from typing import Literal, get_args +from typing import Literal, NotRequired, get_args -from typing_extensions import NotRequired, TypedDict +from typing_extensions import TypedDict # --------------------------------------------------------------------------- # Common (shared across device types) diff --git a/pyproject.toml b/pyproject.toml index 66b9c88..06800cb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ name = "napalm-device-types" version = "4.22.0" description = "Abstract device-type base classes for NAPALM drivers" readme = "README.md" -requires-python = ">=3.10" +requires-python = ">=3.12" license = "Apache-2.0" authors = [ { name = "Christian Manivong", email = "christian@manivong.de" }, @@ -30,8 +30,6 @@ classifiers = [ "Intended Audience :: System Administrators", "Operating System :: OS Independent", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Topic :: System :: Networking", @@ -39,7 +37,7 @@ classifiers = [ "Typing :: Typed", ] dependencies = [ - "napalm>=4.0", + "napalm>=5.1", # older releases import pkg_resources, which a 3.12 venv lacks "typing-extensions>=4.0", ] @@ -65,7 +63,7 @@ napalm_device_types = ["py.typed"] [tool.ruff] line-length = 100 -target-version = "py310" +target-version = "py312" [tool.ruff.lint] select = ["E", "F", "I", "UP", "B"] @@ -75,7 +73,7 @@ select = ["E", "F", "I", "UP", "B"] "tests/**" = ["E501"] [tool.mypy] -python_version = "3.10" +python_version = "3.12" strict = true ignore_missing_imports = true diff --git a/tests/test_fact_getters.py b/tests/test_fact_getters.py index ac820fa..d9cc556 100644 --- a/tests/test_fact_getters.py +++ b/tests/test_fact_getters.py @@ -30,8 +30,7 @@ def test_a_missing_license_may_say_what_the_device_withholds_without_it(): # A Supermicro X10 with only SFT-OOB-LIC answers Redfish but keeps its drives and # firmware inventory until DCMS is activated: partly licensed, not unlicensed. hints = get_type_hints(LicenseDict) - # Python 3.10 keeps NotRequired[...] around the type; later versions strip it. - assert "list[str]" in str(hints["withholds"]) + assert hints["withholds"] == list[str] assert "withholds" not in LicenseDict.__required_keys__