From 0489aa1c1631debf96667bfedd811183d3c9edf0 Mon Sep 17 00:00:00 2001 From: Carlos Huaccho Date: Mon, 20 Jul 2026 11:44:01 -0400 Subject: [PATCH 1/2] adding fix to skip the update of arg keys/values when an error is present and type annotation updates --- netutils/nist.py | 26 +++++++++++++------------- netutils/os_version.py | 16 +++++++--------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/netutils/nist.py b/netutils/nist.py index a3162805..894a7d92 100644 --- a/netutils/nist.py +++ b/netutils/nist.py @@ -9,7 +9,7 @@ from netutils.os_version import version_metadata # Setting up the dataclass values for specific parsers -PLATFORM_FIELDS: t.Dict[str, t.Any] = { +PLATFORM_FIELDS: dict[str, t.Any] = { "default": [ ("vendor", str), ("os_type", str), @@ -38,15 +38,15 @@ } -class OsPlatform(metaclass=abc.ABCMeta): +class OsPlatform(abc.ABC): """Base class for dynamically generated vendor specific platform data classes.""" - def asdict(self) -> t.Dict[str, t.Any]: + def asdict(self) -> dict[str, t.Any]: """Returns dictionary representation of the class attributes.""" return dataclasses.asdict(self) # type: ignore @abc.abstractmethod - def get_nist_urls(self) -> t.List[str]: + def get_nist_urls(self) -> list[str]: """Returns list of NIST URLs for the platform.""" def get(self, key: str) -> t.Any: @@ -63,7 +63,7 @@ def __getitem__(self, key: str) -> t.Any: return getattr(self, key) -def _get_nist_urls_juniper_junos(os_platform_data: t.Dict[str, t.Any]) -> t.List[str]: # pylint: disable=R0911 +def _get_nist_urls_juniper_junos(os_platform_data: dict[str, t.Any]) -> list[str]: # pylint: disable=R0911 """Create a list of possible NIST Url strings for JuniperPlatform. Returns: @@ -108,14 +108,14 @@ def _get_nist_urls_juniper_junos(os_platform_data: t.Dict[str, t.Any]) -> t.List return nist_urls - elif os_platform_data["isspecial"]: + if os_platform_data["isspecial"]: # nist_urls.append(juniper:junos:12.1x47:d40:*:*:*:*:*:*) nist_urls.append(f"{base_ext}:{_service}{_service_build}{delim_six}") # nist_urls.append(juniper:junos:12.1x47-d40:*:*:*:*:*:*:*) nist_urls.append(f"{base_ext}-{_service}{_service_build}{delim_seven}") - return nist_urls # + return nist_urls if not os_platform_data.get("type"): # nist_urls.append(juniper:junos:12.1:-:*:*:*:*:*:*) @@ -159,7 +159,7 @@ def _get_nist_urls_juniper_junos(os_platform_data: t.Dict[str, t.Any]) -> t.List raise ValueError("Failure creating Juniper JunOS Version. Format is unknown.") -def _get_nist_urls_default(os_platform_data: t.Dict[str, t.Any]) -> t.List[str]: +def _get_nist_urls_default(os_platform_data: dict[str, t.Any]) -> list[str]: r"""Create a list of possible NIST Url strings. Child models with NIST URL customizations need their own "get_nist_urls" method. @@ -172,7 +172,7 @@ def _get_nist_urls_default(os_platform_data: t.Dict[str, t.Any]) -> t.List[str]: base_url = f"{'https://services.nvd.nist.gov/rest/json/cves/2.0?cpeName=cpe:2.3:o:'}" os_platform_data = {"base_url": base_url, **os_platform_data} - os_platform_data["version_string"] = os_platform_data.get("version_string").replace("-", ":") # type: ignore + os_platform_data["version_string"] = os_platform_data.get("version_string", "").replace("-", ":") # type: ignore version_string = os_platform_data.get("version_string", "").lower() for escape_char in escape_list: @@ -218,7 +218,7 @@ def _os_platform_object_builder(vendor: str, platform: str, version: str) -> obj "version_string": version, } - if version_parser: + if version_parser and "Error" not in version_parser: field_values.update(version_parser) class_name = f"{vendor.capitalize()}{platform.capitalize()}" @@ -231,13 +231,13 @@ def _os_platform_object_builder(vendor: str, platform: str, version: str) -> obj return platform_cls(**field_values) -get_nist_url_funcs: t.Dict[str, t.Any] = { +get_nist_url_funcs: dict[str, t.Any] = { "default": _get_nist_urls_default, "juniper": {"junos": _get_nist_urls_juniper_junos}, } -def get_nist_vendor_platform_urls(vendor: str, platform: str, version: str) -> t.List[str]: +def get_nist_vendor_platform_urls(vendor: str, platform: str, version: str) -> list[str]: """Generate list of possible NIST URLs for the Vendor, OS Platform, and Version. Args: @@ -261,7 +261,7 @@ def get_nist_vendor_platform_urls(vendor: str, platform: str, version: str) -> t return _get_nist_urls_default(platform_data) -def get_nist_urls(network_driver: str, version: str) -> t.List[str]: +def get_nist_urls(network_driver: str, version: str) -> list[str]: """Generate list of possible NIST URLs for the Network Driver, and Version. Args: diff --git a/netutils/os_version.py b/netutils/os_version.py index 3edc07f4..21ae3d1e 100644 --- a/netutils/os_version.py +++ b/netutils/os_version.py @@ -6,7 +6,7 @@ from netutils._private.version import LooseVersion, StrictVersion # type: ignore -def get_upgrade_path(current_version: str, target_version: str, firmware_list: t.List[str]) -> t.List[str]: +def get_upgrade_path(current_version: str, target_version: str, firmware_list: list[str]) -> list[str]: """Utility to return the upgrade path from the current to target firmware version. Returns: @@ -76,8 +76,7 @@ def _compare_version(current_version: str, comparison: str, target_version: str, def compare_version_loose(current_version: str, comparison: str, target_version: str) -> bool: - """ - Compares two version strings using the specified comparison operation, based on LooseVersion. + """Compares two version strings using the specified comparison operation, based on LooseVersion. Args: current_version (str): The current version string to compare. @@ -105,8 +104,7 @@ def compare_version_loose(current_version: str, comparison: str, target_version: def compare_version_strict(current_version: str, comparison: str, target_version: str) -> bool: - """ - Compares two version strings using the specified comparison operation, based on LooseVersion. + """Compares two version strings using the specified comparison operation, based on LooseVersion. Args: current_version (str): The current version string to compare. @@ -133,7 +131,7 @@ def compare_version_strict(current_version: str, comparison: str, target_version return _compare_version(current_version, comparison, target_version, "strict") -def _juniper_junos_version_metadata(version: str) -> t.Dict[str, t.Any]: +def _juniper_junos_version_metadata(version: str) -> dict[str, t.Any]: """Parses JunOS Version into usable bits matching JunOS Standards. Args: @@ -170,7 +168,7 @@ def _juniper_junos_version_metadata(version: str) -> t.Dict[str, t.Any]: ) # Set empty params for service pieces and complete them if a second indice exists from the version split # Define isservice, isfrs, isspecial, ismaintenance - parsed_version: t.Dict[str, t.Any] = { + parsed_version: dict[str, t.Any] = { "isservice": False, "ismaintenance": False, "isfrs": False, @@ -219,7 +217,7 @@ def _juniper_junos_version_metadata(version: str) -> t.Dict[str, t.Any]: return parsed_version -def _basic_version_metadata(version: str) -> t.Dict[str, t.Any]: +def _basic_version_metadata(version: str) -> dict[str, t.Any]: """Parses version value using SemVer 2.0.0 standards. https://semver.org/spec/v2.0.0.html. Args: @@ -289,7 +287,7 @@ def _basic_version_metadata(version: str) -> t.Dict[str, t.Any]: } -def version_metadata(vendor: str, os_type: str, version: str) -> t.Dict[str, t.Any]: +def version_metadata(vendor: str, os_type: str, version: str) -> dict[str, t.Any]: """If a custom version parser is avaialable, use it. Args: From 8e1f9613477ecf35a8cb00c817cd414898fee13a Mon Sep 17 00:00:00 2001 From: Carlos Huaccho Date: Mon, 20 Jul 2026 11:55:01 -0400 Subject: [PATCH 2/2] removing mypy ignore comment and adding changelog --- changes/861.fixed | 1 + netutils/nist.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changes/861.fixed diff --git a/changes/861.fixed b/changes/861.fixed new file mode 100644 index 00000000..6580fab5 --- /dev/null +++ b/changes/861.fixed @@ -0,0 +1 @@ +Fixed raising TypeError when calling the dynamicaly created dataclass when the "Error" key is present in the arguments when running netutils.nist._os_platform_object_builder function diff --git a/netutils/nist.py b/netutils/nist.py index 894a7d92..3e0e4f9a 100644 --- a/netutils/nist.py +++ b/netutils/nist.py @@ -172,7 +172,7 @@ def _get_nist_urls_default(os_platform_data: dict[str, t.Any]) -> list[str]: base_url = f"{'https://services.nvd.nist.gov/rest/json/cves/2.0?cpeName=cpe:2.3:o:'}" os_platform_data = {"base_url": base_url, **os_platform_data} - os_platform_data["version_string"] = os_platform_data.get("version_string", "").replace("-", ":") # type: ignore + os_platform_data["version_string"] = os_platform_data.get("version_string", "").replace("-", ":") version_string = os_platform_data.get("version_string", "").lower() for escape_char in escape_list: