From e799a4a676a81f29a8a77ffb13378700cb338d33 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 11 Dec 2025 15:20:21 +0000 Subject: [PATCH] typing: Add types to custom formatters We make a lot of use of typing.Any just to get this over the line. We can come back to this later. Change-Id: I03c18b0b44f210b2ad3e4012344d521fb85cae97 Signed-off-by: Stephen Finucane --- openstackclient/compute/v2/server.py | 7 ++++--- openstackclient/compute/v2/usage.py | 8 +++++--- openstackclient/identity/v2_0/catalog.py | 3 ++- openstackclient/identity/v2_0/role_assignment.py | 2 +- openstackclient/identity/v2_0/user.py | 2 +- openstackclient/identity/v3/application_credential.py | 5 +++-- openstackclient/identity/v3/catalog.py | 4 ++-- openstackclient/image/v1/image.py | 4 ++-- openstackclient/network/v2/network.py | 4 ++-- openstackclient/network/v2/network_agent.py | 4 ++-- openstackclient/network/v2/network_qos_policy.py | 3 ++- openstackclient/network/v2/network_trunk.py | 2 +- openstackclient/network/v2/port.py | 2 +- openstackclient/network/v2/router.py | 6 +++--- openstackclient/network/v2/security_group.py | 5 +++-- openstackclient/network/v2/subnet.py | 6 +++--- openstackclient/volume/v2/volume.py | 2 +- openstackclient/volume/v2/volume_backup.py | 2 +- openstackclient/volume/v2/volume_snapshot.py | 2 +- openstackclient/volume/v2/volume_type.py | 3 ++- openstackclient/volume/v3/volume.py | 2 +- openstackclient/volume/v3/volume_backup.py | 2 +- openstackclient/volume/v3/volume_snapshot.py | 2 +- openstackclient/volume/v3/volume_type.py | 4 ++-- 24 files changed, 47 insertions(+), 39 deletions(-) diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py index 250eacc77c..1eee828d9b 100644 --- a/openstackclient/compute/v2/server.py +++ b/openstackclient/compute/v2/server.py @@ -21,6 +21,7 @@ import getpass import json import logging import os +import typing as ty from cliff import columns as cliff_columns import iso8601 @@ -44,7 +45,7 @@ LOG = logging.getLogger(__name__) IMAGE_STRING_FOR_BFV = 'N/A (booted from volume)' -class PowerStateColumn(cliff_columns.FormattableColumn): +class PowerStateColumn(cliff_columns.FormattableColumn[int]): """Generate a formatted string of a server's power state.""" power_states = [ @@ -65,7 +66,7 @@ class PowerStateColumn(cliff_columns.FormattableColumn): return 'N/A' -class AddressesColumn(cliff_columns.FormattableColumn): +class AddressesColumn(cliff_columns.FormattableColumn[ty.Any]): """Generate a formatted string of a server's addresses.""" def human_readable(self): @@ -86,7 +87,7 @@ class AddressesColumn(cliff_columns.FormattableColumn): } -class HostColumn(cliff_columns.FormattableColumn): +class HostColumn(cliff_columns.FormattableColumn[str | None]): """Generate a formatted string of a hostname.""" def human_readable(self): diff --git a/openstackclient/compute/v2/usage.py b/openstackclient/compute/v2/usage.py index 3fe7f419ac..3015a9e709 100644 --- a/openstackclient/compute/v2/usage.py +++ b/openstackclient/compute/v2/usage.py @@ -15,8 +15,10 @@ """Usage action implementations""" +from collections.abc import Collection import datetime import functools +import typing as ty from cliff import columns as cliff_columns from osc_lib import utils @@ -27,7 +29,7 @@ from openstackclient.i18n import _ # TODO(stephenfin): This exists in a couple of places and should be moved to a # common module -class ProjectColumn(cliff_columns.FormattableColumn): +class ProjectColumn(cliff_columns.FormattableColumn[str]): """Formattable column for project column. Unlike the parent FormattableColumn class, the initializer of the class @@ -53,12 +55,12 @@ class ProjectColumn(cliff_columns.FormattableColumn): return project -class CountColumn(cliff_columns.FormattableColumn): +class CountColumn(cliff_columns.FormattableColumn[Collection[ty.Any]]): def human_readable(self): return len(self._value) if self._value is not None else None -class FloatColumn(cliff_columns.FormattableColumn): +class FloatColumn(cliff_columns.FormattableColumn[float]): def human_readable(self): return float(f"{self._value:.2f}") diff --git a/openstackclient/identity/v2_0/catalog.py b/openstackclient/identity/v2_0/catalog.py index a184f97dfd..437cad2fc2 100644 --- a/openstackclient/identity/v2_0/catalog.py +++ b/openstackclient/identity/v2_0/catalog.py @@ -14,6 +14,7 @@ """Identity v2 Service Catalog action implementations""" import logging +import typing as ty from cliff import columns as cliff_columns from osc_lib import exceptions @@ -26,7 +27,7 @@ from openstackclient.i18n import _ LOG = logging.getLogger(__name__) -class EndpointsColumn(cliff_columns.FormattableColumn): +class EndpointsColumn(cliff_columns.FormattableColumn[ty.Any]): def human_readable(self): if not self._value: return "" diff --git a/openstackclient/identity/v2_0/role_assignment.py b/openstackclient/identity/v2_0/role_assignment.py index 093df6a858..d616725dfa 100644 --- a/openstackclient/identity/v2_0/role_assignment.py +++ b/openstackclient/identity/v2_0/role_assignment.py @@ -80,7 +80,7 @@ class ListRoleAssignment(command.Lister): parsed_args.project, ) elif parsed_args.authproject: - if auth_ref: + if auth_ref and auth_ref.project_id: project = utils.find_resource( identity_client.projects, auth_ref.project_id ) diff --git a/openstackclient/identity/v2_0/user.py b/openstackclient/identity/v2_0/user.py index d80d0e8d07..244b9e9da9 100644 --- a/openstackclient/identity/v2_0/user.py +++ b/openstackclient/identity/v2_0/user.py @@ -30,7 +30,7 @@ from openstackclient.i18n import _ LOG = logging.getLogger(__name__) -class ProjectColumn(cliff_columns.FormattableColumn): +class ProjectColumn(cliff_columns.FormattableColumn[str]): """Formattable column for project column. Unlike the parent FormattableColumn class, the initializer of the diff --git a/openstackclient/identity/v3/application_credential.py b/openstackclient/identity/v3/application_credential.py index bc3e9ad042..2894d6ee9f 100644 --- a/openstackclient/identity/v3/application_credential.py +++ b/openstackclient/identity/v3/application_credential.py @@ -18,6 +18,7 @@ import datetime import json import logging +import typing as ty import uuid from cliff import columns as cliff_columns @@ -31,11 +32,11 @@ from openstackclient.identity import common LOG = logging.getLogger(__name__) -class RolesColumn(cliff_columns.FormattableColumn): +class RolesColumn(cliff_columns.FormattableColumn[ty.Any]): """Generate a formatted string of role names.""" def human_readable(self): - return utils.format_list(r['name'] for r in self._value) + return utils.format_list(list(r['name'] for r in self._value)) def _format_application_credential( diff --git a/openstackclient/identity/v3/catalog.py b/openstackclient/identity/v3/catalog.py index e9f03a31f1..7d37e6cbd2 100644 --- a/openstackclient/identity/v3/catalog.py +++ b/openstackclient/identity/v3/catalog.py @@ -9,11 +9,11 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -# """Identity v3 Service Catalog action implementations""" import logging +import typing as ty from cliff import columns as cliff_columns from osc_lib import exceptions @@ -26,7 +26,7 @@ from openstackclient.i18n import _ LOG = logging.getLogger(__name__) -class EndpointsColumn(cliff_columns.FormattableColumn): +class EndpointsColumn(cliff_columns.FormattableColumn[ty.Any]): def human_readable(self): if not self._value: return "" diff --git a/openstackclient/image/v1/image.py b/openstackclient/image/v1/image.py index 3f3d3a1a23..58fc3f4dd7 100644 --- a/openstackclient/image/v1/image.py +++ b/openstackclient/image/v1/image.py @@ -70,7 +70,7 @@ def _get_columns(item): _formatters = {} -class HumanReadableSizeColumn(cliff_columns.FormattableColumn): +class HumanReadableSizeColumn(cliff_columns.FormattableColumn[int]): def human_readable(self): """Return a formatted visibility string @@ -84,7 +84,7 @@ class HumanReadableSizeColumn(cliff_columns.FormattableColumn): return '' -class VisibilityColumn(cliff_columns.FormattableColumn): +class VisibilityColumn(cliff_columns.FormattableColumn[bool]): def human_readable(self): """Return a formatted visibility string diff --git a/openstackclient/network/v2/network.py b/openstackclient/network/v2/network.py index 7aefe50c3c..c8e1f360a7 100644 --- a/openstackclient/network/v2/network.py +++ b/openstackclient/network/v2/network.py @@ -24,12 +24,12 @@ from openstackclient.identity import common as identity_common from openstackclient.network import common -class AdminStateColumn(cliff_columns.FormattableColumn): +class AdminStateColumn(cliff_columns.FormattableColumn[bool]): def human_readable(self): return 'UP' if self._value else 'DOWN' -class RouterExternalColumn(cliff_columns.FormattableColumn): +class RouterExternalColumn(cliff_columns.FormattableColumn[bool]): def human_readable(self): return 'External' if self._value else 'Internal' diff --git a/openstackclient/network/v2/network_agent.py b/openstackclient/network/v2/network_agent.py index b2b4eaa73e..806422b102 100644 --- a/openstackclient/network/v2/network_agent.py +++ b/openstackclient/network/v2/network_agent.py @@ -26,12 +26,12 @@ from openstackclient.i18n import _ LOG = logging.getLogger(__name__) -class AliveColumn(cliff_columns.FormattableColumn): +class AliveColumn(cliff_columns.FormattableColumn[bool]): def human_readable(self): return ":-)" if self._value else "XXX" -class AdminStateColumn(cliff_columns.FormattableColumn): +class AdminStateColumn(cliff_columns.FormattableColumn[bool]): def human_readable(self): return 'UP' if self._value else 'DOWN' diff --git a/openstackclient/network/v2/network_qos_policy.py b/openstackclient/network/v2/network_qos_policy.py index 05f6d11be0..ab620b8490 100644 --- a/openstackclient/network/v2/network_qos_policy.py +++ b/openstackclient/network/v2/network_qos_policy.py @@ -14,6 +14,7 @@ # under the License. import logging +import typing as ty from cliff import columns as cliff_columns from osc_lib import exceptions @@ -27,7 +28,7 @@ from openstackclient.network import common LOG = logging.getLogger(__name__) -class RulesColumn(cliff_columns.FormattableColumn): +class RulesColumn(cliff_columns.FormattableColumn[ty.Any]): def human_readable(self): return '\n'.join(str(v) for v in self._value) diff --git a/openstackclient/network/v2/network_trunk.py b/openstackclient/network/v2/network_trunk.py index 5d1389b9bc..974a997636 100644 --- a/openstackclient/network/v2/network_trunk.py +++ b/openstackclient/network/v2/network_trunk.py @@ -36,7 +36,7 @@ TRUNKS = 'trunks' SUB_PORTS = 'sub_ports' -class AdminStateColumn(cliff_columns.FormattableColumn): +class AdminStateColumn(cliff_columns.FormattableColumn[bool]): def human_readable(self): return 'UP' if self._value else 'DOWN' diff --git a/openstackclient/network/v2/port.py b/openstackclient/network/v2/port.py index 080499d4bc..e1205153e6 100644 --- a/openstackclient/network/v2/port.py +++ b/openstackclient/network/v2/port.py @@ -34,7 +34,7 @@ from openstackclient.network import common LOG = logging.getLogger(__name__) -class AdminStateColumn(cliff_columns.FormattableColumn): +class AdminStateColumn(cliff_columns.FormattableColumn[bool]): def human_readable(self): return 'UP' if self._value else 'DOWN' diff --git a/openstackclient/network/v2/router.py b/openstackclient/network/v2/router.py index 1d21a80236..939167d850 100644 --- a/openstackclient/network/v2/router.py +++ b/openstackclient/network/v2/router.py @@ -35,12 +35,12 @@ from openstackclient.network import common LOG = logging.getLogger(__name__) -class AdminStateColumn(cliff_columns.FormattableColumn): +class AdminStateColumn(cliff_columns.FormattableColumn[bool]): def human_readable(self): return 'UP' if self._value else 'DOWN' -class RouterInfoColumn(cliff_columns.FormattableColumn): +class RouterInfoColumn(cliff_columns.FormattableColumn[ty.Any]): def human_readable(self): try: return json.dumps(self._value) @@ -48,7 +48,7 @@ class RouterInfoColumn(cliff_columns.FormattableColumn): return '' -class RoutesColumn(cliff_columns.FormattableColumn): +class RoutesColumn(cliff_columns.FormattableColumn[ty.Any]): def human_readable(self): # Map the route keys to match --route option. for route in self._value or []: diff --git a/openstackclient/network/v2/security_group.py b/openstackclient/network/v2/security_group.py index ee56f72360..c6930de78d 100644 --- a/openstackclient/network/v2/security_group.py +++ b/openstackclient/network/v2/security_group.py @@ -14,6 +14,7 @@ """Security Group action implementations""" import argparse +import typing as ty from cliff import columns as cliff_columns from osc_lib import utils @@ -65,12 +66,12 @@ def _format_compute_security_group_rules(sg_rules): return utils.format_list(rules, separator='\n') -class NetworkSecurityGroupRulesColumn(cliff_columns.FormattableColumn): +class NetworkSecurityGroupRulesColumn(cliff_columns.FormattableColumn[ty.Any]): def human_readable(self): return _format_network_security_group_rules(self._value) -class ComputeSecurityGroupRulesColumn(cliff_columns.FormattableColumn): +class ComputeSecurityGroupRulesColumn(cliff_columns.FormattableColumn[ty.Any]): def human_readable(self): return _format_compute_security_group_rules(self._value) diff --git a/openstackclient/network/v2/subnet.py b/openstackclient/network/v2/subnet.py index 4ff7ea8cb4..3357f8930e 100644 --- a/openstackclient/network/v2/subnet.py +++ b/openstackclient/network/v2/subnet.py @@ -44,7 +44,7 @@ def _update_arguments(obj_list, parsed_args_list, option): raise exceptions.CommandError(msg) -class AllocationPoolsColumn(cliff_columns.FormattableColumn): +class AllocationPoolsColumn(cliff_columns.FormattableColumn[ty.Any]): def human_readable(self): pool_formatted = [ '{}-{}'.format(pool.get('start', ''), pool.get('end', '')) @@ -53,7 +53,7 @@ class AllocationPoolsColumn(cliff_columns.FormattableColumn): return ','.join(pool_formatted) -class HostRoutesColumn(cliff_columns.FormattableColumn): +class HostRoutesColumn(cliff_columns.FormattableColumn[ty.Any]): def human_readable(self): # Map the host route keys to match --host-route option. return utils.format_list_of_dicts( @@ -61,7 +61,7 @@ class HostRoutesColumn(cliff_columns.FormattableColumn): ) -class UnsortedListColumn(cliff_columns.FormattableColumn): +class UnsortedListColumn(cliff_columns.FormattableColumn[list[ty.Any]]): # format_columns.ListColumn sorts the output, but for things like # DNS server addresses the order matters def human_readable(self): diff --git a/openstackclient/volume/v2/volume.py b/openstackclient/volume/v2/volume.py index 6b97d9b7e9..b4761ffabd 100644 --- a/openstackclient/volume/v2/volume.py +++ b/openstackclient/volume/v2/volume.py @@ -61,7 +61,7 @@ class KeyValueHintAction(argparse.Action): ) -class AttachmentsColumn(cliff_columns.FormattableColumn): +class AttachmentsColumn(cliff_columns.FormattableColumn[list[str]]): """Formattable column for attachments column. Unlike the parent FormattableColumn class, the initializer of the diff --git a/openstackclient/volume/v2/volume_backup.py b/openstackclient/volume/v2/volume_backup.py index e698af676b..7dbe92c962 100644 --- a/openstackclient/volume/v2/volume_backup.py +++ b/openstackclient/volume/v2/volume_backup.py @@ -28,7 +28,7 @@ from openstackclient.i18n import _ LOG = logging.getLogger(__name__) -class VolumeIdColumn(cliff_columns.FormattableColumn): +class VolumeIdColumn(cliff_columns.FormattableColumn[str]): """Formattable column for volume ID column. Unlike the parent FormattableColumn class, the initializer of the diff --git a/openstackclient/volume/v2/volume_snapshot.py b/openstackclient/volume/v2/volume_snapshot.py index 113b8badd9..3b1dbbabf2 100644 --- a/openstackclient/volume/v2/volume_snapshot.py +++ b/openstackclient/volume/v2/volume_snapshot.py @@ -34,7 +34,7 @@ from openstackclient.identity import common as identity_common LOG = logging.getLogger(__name__) -class VolumeIdColumn(cliff_columns.FormattableColumn): +class VolumeIdColumn(cliff_columns.FormattableColumn[str]): """Formattable column for volume ID column. Unlike the parent FormattableColumn class, the initializer of the diff --git a/openstackclient/volume/v2/volume_type.py b/openstackclient/volume/v2/volume_type.py index 7b6dc0392f..e7b90af95a 100644 --- a/openstackclient/volume/v2/volume_type.py +++ b/openstackclient/volume/v2/volume_type.py @@ -16,6 +16,7 @@ import functools import logging +import typing as ty from cliff import columns as cliff_columns from osc_lib.cli import format_columns @@ -31,7 +32,7 @@ from openstackclient.identity import common as identity_common LOG = logging.getLogger(__name__) -class EncryptionInfoColumn(cliff_columns.FormattableColumn): +class EncryptionInfoColumn(cliff_columns.FormattableColumn[ty.Any]): """Formattable column for encryption info column. Unlike the parent FormattableColumn class, the initializer of the diff --git a/openstackclient/volume/v3/volume.py b/openstackclient/volume/v3/volume.py index 4e689a37cb..50ea77fb5a 100644 --- a/openstackclient/volume/v3/volume.py +++ b/openstackclient/volume/v3/volume.py @@ -62,7 +62,7 @@ class KeyValueHintAction(argparse.Action): ) -class AttachmentsColumn(cliff_columns.FormattableColumn): +class AttachmentsColumn(cliff_columns.FormattableColumn[list[ty.Any]]): """Formattable column for attachments column. Unlike the parent FormattableColumn class, the initializer of the diff --git a/openstackclient/volume/v3/volume_backup.py b/openstackclient/volume/v3/volume_backup.py index f836eb39b2..df9a17eb03 100644 --- a/openstackclient/volume/v3/volume_backup.py +++ b/openstackclient/volume/v3/volume_backup.py @@ -31,7 +31,7 @@ from openstackclient.i18n import _ LOG = logging.getLogger(__name__) -class VolumeIdColumn(cliff_columns.FormattableColumn): +class VolumeIdColumn(cliff_columns.FormattableColumn[str]): """Formattable column for volume ID column. Unlike the parent FormattableColumn class, the initializer of the diff --git a/openstackclient/volume/v3/volume_snapshot.py b/openstackclient/volume/v3/volume_snapshot.py index 78e0f116a7..f89174c3da 100644 --- a/openstackclient/volume/v3/volume_snapshot.py +++ b/openstackclient/volume/v3/volume_snapshot.py @@ -33,7 +33,7 @@ from openstackclient.identity import common as identity_common LOG = logging.getLogger(__name__) -class VolumeIdColumn(cliff_columns.FormattableColumn): +class VolumeIdColumn(cliff_columns.FormattableColumn[str]): """Formattable column for volume ID column. Unlike the parent FormattableColumn class, the initializer of the diff --git a/openstackclient/volume/v3/volume_type.py b/openstackclient/volume/v3/volume_type.py index 562283ecd9..fbce2f2c9a 100644 --- a/openstackclient/volume/v3/volume_type.py +++ b/openstackclient/volume/v3/volume_type.py @@ -10,12 +10,12 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -# """Volume v3 Type action implementations""" import functools import logging +import typing as ty from cinderclient import api_versions from cliff import columns as cliff_columns @@ -32,7 +32,7 @@ from openstackclient.identity import common as identity_common LOG = logging.getLogger(__name__) -class EncryptionInfoColumn(cliff_columns.FormattableColumn): +class EncryptionInfoColumn(cliff_columns.FormattableColumn[ty.Any]): """Formattable column for encryption info column. Unlike the parent FormattableColumn class, the initializer of the