Merge "Revert "Use Python 3.8-style type hints""

This commit is contained in:
Zuul
2025-05-26 15:56:31 +00:00
committed by Gerrit Code Review
15 changed files with 112 additions and 110 deletions

View File

@@ -13,6 +13,7 @@
"""Base API Library""" """Base API Library"""
import builtins
import typing as ty import typing as ty
import warnings import warnings
@@ -203,7 +204,7 @@ class BaseAPI:
session: ty.Optional[ksa_session.Session] = None, session: ty.Optional[ksa_session.Session] = None,
body: ty.Any = None, body: ty.Any = None,
detailed: bool = False, detailed: bool = False,
headers: ty.Optional[ty.Dict[str, str]] = None, headers: ty.Optional[dict[str, str]] = None,
**params: ty.Any, **params: ty.Any,
) -> ty.Union[requests.Response, ty.Any]: ) -> ty.Union[requests.Response, ty.Any]:
"""Return a list of resources """Return a list of resources
@@ -290,7 +291,7 @@ class BaseAPI:
if resource is None: if resource is None:
resource = path resource = path
def getlist(kw: ty.Dict[str, ty.Any]) -> ty.Any: def getlist(kw: dict[str, ty.Any]) -> ty.Any:
"""Do list call, unwrap resource dict if present""" """Do list call, unwrap resource dict if present"""
ret = self.list(path, **kw) ret = self.list(path, **kw)
if isinstance(ret, dict) and resource in ret: if isinstance(ret, dict) and resource in ret:
@@ -323,9 +324,9 @@ class BaseAPI:
def find_bulk( def find_bulk(
self, self,
path: str, path: str,
headers: ty.Optional[ty.Dict[str, str]] = None, headers: ty.Optional[dict[str, str]] = None,
**kwargs: ty.Any, **kwargs: ty.Any,
) -> ty.List[ty.Any]: ) -> builtins.list[ty.Any]:
"""Bulk load and filter locally """Bulk load and filter locally
:param string path: :param string path:
@@ -377,7 +378,7 @@ class BaseAPI:
path: str, path: str,
value: ty.Optional[str] = None, value: ty.Optional[str] = None,
attr: ty.Optional[str] = None, attr: ty.Optional[str] = None,
headers: ty.Optional[ty.Dict[str, str]] = None, headers: ty.Optional[dict[str, str]] = None,
) -> ty.Any: ) -> ty.Any:
"""Find a single resource by name or ID """Find a single resource by name or ID

View File

@@ -39,10 +39,10 @@ class _OptionDict(ty.TypedDict):
# List of plugin command line options # List of plugin command line options
OPTIONS_LIST: ty.Dict[str, _OptionDict] = {} OPTIONS_LIST: dict[str, _OptionDict] = {}
def get_plugin_list() -> ty.FrozenSet[str]: def get_plugin_list() -> frozenset[str]:
"""Gather plugin list and cache it""" """Gather plugin list and cache it"""
global PLUGIN_LIST global PLUGIN_LIST
@@ -52,7 +52,7 @@ def get_plugin_list() -> ty.FrozenSet[str]:
return PLUGIN_LIST return PLUGIN_LIST
def get_options_list() -> ty.Dict[str, _OptionDict]: def get_options_list() -> dict[str, _OptionDict]:
"""Gather plugin options so the help action has them available""" """Gather plugin options so the help action has them available"""
global OPTIONS_LIST global OPTIONS_LIST

View File

@@ -16,7 +16,7 @@
import typing as ty import typing as ty
_T = ty.TypeVar('_T', bound=ty.List[ty.Any]) _T = ty.TypeVar('_T', bound=list[ty.Any])
def simple_filter( def simple_filter(

View File

@@ -29,8 +29,8 @@ LOG = logging.getLogger(__name__)
# before auth plugins are loaded # before auth plugins are loaded
class OSC_Config(config.OpenStackConfig): # type: ignore class OSC_Config(config.OpenStackConfig): # type: ignore
def _auth_select_default_plugin( def _auth_select_default_plugin(
self, config: ty.Dict[str, ty.Any] self, config: dict[str, ty.Any]
) -> ty.Dict[str, ty.Any]: ) -> dict[str, ty.Any]:
"""Select a default plugin based on supplied arguments """Select a default plugin based on supplied arguments
Migrated from auth.select_auth_plugin() Migrated from auth.select_auth_plugin()
@@ -64,8 +64,8 @@ class OSC_Config(config.OpenStackConfig): # type: ignore
return config return config
def _auth_v2_arguments( def _auth_v2_arguments(
self, config: ty.Dict[str, ty.Any] self, config: dict[str, ty.Any]
) -> ty.Dict[str, ty.Any]: ) -> dict[str, ty.Any]:
"""Set up v2-required arguments from v3 info """Set up v2-required arguments from v3 info
Migrated from auth.build_auth_params() Migrated from auth.build_auth_params()
@@ -79,8 +79,8 @@ class OSC_Config(config.OpenStackConfig): # type: ignore
return config return config
def _auth_v2_ignore_v3( def _auth_v2_ignore_v3(
self, config: ty.Dict[str, ty.Any] self, config: dict[str, ty.Any]
) -> ty.Dict[str, ty.Any]: ) -> dict[str, ty.Any]:
"""Remove v3 arguments if present for v2 plugin """Remove v3 arguments if present for v2 plugin
Migrated from clientmanager.setup_auth() Migrated from clientmanager.setup_auth()
@@ -119,8 +119,8 @@ class OSC_Config(config.OpenStackConfig): # type: ignore
return config return config
def _auth_default_domain( def _auth_default_domain(
self, config: ty.Dict[str, ty.Any] self, config: dict[str, ty.Any]
) -> ty.Dict[str, ty.Any]: ) -> dict[str, ty.Any]:
"""Set a default domain from available arguments """Set a default domain from available arguments
Migrated from clientmanager.setup_auth() Migrated from clientmanager.setup_auth()
@@ -161,9 +161,7 @@ class OSC_Config(config.OpenStackConfig): # type: ignore
config['auth']['user_domain_id'] = default_domain config['auth']['user_domain_id'] = default_domain
return config return config
def auth_config_hook( def auth_config_hook(self, config: dict[str, ty.Any]) -> dict[str, ty.Any]:
self, config: ty.Dict[str, ty.Any]
) -> ty.Dict[str, ty.Any]:
"""Allow examination of config values before loading auth plugin """Allow examination of config values before loading auth plugin
OpenStackClient will override this to perform additional checks OpenStackClient will override this to perform additional checks
@@ -183,9 +181,9 @@ class OSC_Config(config.OpenStackConfig): # type: ignore
def _validate_auth( def _validate_auth(
self, self,
config: ty.Dict[str, ty.Any], config: dict[str, ty.Any],
loader: ksa_loading.BaseIdentityLoader, # type: ignore loader: ksa_loading.BaseIdentityLoader[ty.Any],
) -> ty.Dict[str, ty.Any]: ) -> dict[str, ty.Any]:
"""Validate auth plugin arguments""" """Validate auth plugin arguments"""
# May throw a keystoneauth1.exceptions.NoMatchingPlugin # May throw a keystoneauth1.exceptions.NoMatchingPlugin
@@ -250,7 +248,7 @@ class OSC_Config(config.OpenStackConfig): # type: ignore
return config return config
# TODO(stephenfin): Add type once we have typing for SDK # TODO(stephenfin): Add type once we have typing for SDK
def load_auth_plugin(self, config: ty.Dict[str, ty.Any]) -> ty.Any: def load_auth_plugin(self, config: dict[str, ty.Any]) -> ty.Any:
"""Get auth plugin and validate args""" """Get auth plugin and validate args"""
loader = self._get_auth_loader(config) loader = self._get_auth_loader(config)

View File

@@ -22,47 +22,47 @@ from cliff import columns
from osc_lib import utils from osc_lib import utils
class DictColumn(columns.FormattableColumn): # type: ignore class DictColumn(columns.FormattableColumn[dict[str, ty.Any]]):
"""Format column for dict content""" """Format column for dict content"""
def human_readable(self) -> str: def human_readable(self) -> str:
return utils.format_dict(self._value) return utils.format_dict(self._value)
def machine_readable(self) -> ty.Dict[str, ty.Any]: def machine_readable(self) -> dict[str, ty.Any]:
return dict(self._value or {}) return dict(self._value or {})
class DictListColumn(columns.FormattableColumn): # type: ignore class DictListColumn(columns.FormattableColumn[dict[str, list[ty.Any]]]):
"""Format column for dict, key is string, value is list""" """Format column for dict, key is string, value is list"""
def human_readable(self) -> str: def human_readable(self) -> str:
return utils.format_dict_of_list(self._value) or '' return utils.format_dict_of_list(self._value) or ''
def machine_readable(self) -> ty.Dict[str, ty.List[ty.Any]]: def machine_readable(self) -> dict[str, list[ty.Any]]:
return dict(self._value or {}) return dict(self._value or {})
class ListColumn(columns.FormattableColumn): # type: ignore class ListColumn(columns.FormattableColumn[list[ty.Any]]):
"""Format column for list content""" """Format column for list content"""
def human_readable(self) -> str: def human_readable(self) -> str:
return utils.format_list(self._value) or '' return utils.format_list(self._value) or ''
def machine_readable(self) -> ty.List[ty.Any]: def machine_readable(self) -> list[ty.Any]:
return [x for x in self._value or []] return [x for x in self._value or []]
class ListDictColumn(columns.FormattableColumn): # type: ignore class ListDictColumn(columns.FormattableColumn[list[dict[str, ty.Any]]]):
"""Format column for list of dict content""" """Format column for list of dict content"""
def human_readable(self) -> str: def human_readable(self) -> str:
return utils.format_list_of_dicts(self._value) or '' return utils.format_list_of_dicts(self._value) or ''
def machine_readable(self) -> ty.List[ty.Dict[str, ty.Any]]: def machine_readable(self) -> list[dict[str, ty.Any]]:
return [dict(x) for x in self._value or []] return [dict(x) for x in self._value or []]
class SizeColumn(columns.FormattableColumn): # type: ignore class SizeColumn(columns.FormattableColumn[ty.Union[int, float]]):
"""Format column for file size content""" """Format column for file size content"""
def human_readable(self) -> str: def human_readable(self) -> str:

View File

@@ -16,6 +16,7 @@
"""argparse Custom Actions""" """argparse Custom Actions"""
import argparse import argparse
import collections.abc
import typing as ty import typing as ty
from osc_lib.i18n import _ from osc_lib.i18n import _
@@ -114,11 +115,11 @@ class MultiKeyValueAction(argparse.Action):
optional_keys: ty.Optional[ty.Sequence[str]] = None, optional_keys: ty.Optional[ty.Sequence[str]] = None,
const: ty.Optional[_T] = None, const: ty.Optional[_T] = None,
default: ty.Union[_T, str, None] = None, default: ty.Union[_T, str, None] = None,
type: ty.Optional[ty.Callable[[str], _T]] = None, type: ty.Optional[collections.abc.Callable[[str], _T]] = None,
choices: ty.Optional[ty.Iterable[_T]] = None, choices: ty.Optional[collections.abc.Iterable[_T]] = None,
required: bool = False, required: bool = False,
help: ty.Optional[str] = None, help: ty.Optional[str] = None,
metavar: ty.Union[str, ty.Tuple[str, ...], None] = None, metavar: ty.Union[str, tuple[str, ...], None] = None,
) -> None: ) -> None:
"""Initialize the action object, and parse customized options """Initialize the action object, and parse customized options
@@ -212,7 +213,7 @@ class MultiKeyValueAction(argparse.Action):
if getattr(namespace, self.dest, None) is None: if getattr(namespace, self.dest, None) is None:
setattr(namespace, self.dest, []) setattr(namespace, self.dest, [])
params: ty.Dict[str, str] = {} params: dict[str, str] = {}
for kv in values.split(','): for kv in values.split(','):
# Add value if an assignment else raise ArgumentError # Add value if an assignment else raise ArgumentError
if '=' in kv: if '=' in kv:
@@ -264,7 +265,7 @@ class MultiKeyValueCommaAction(MultiKeyValueAction):
if getattr(namespace, self.dest, None) is None: if getattr(namespace, self.dest, None) is None:
setattr(namespace, self.dest, []) setattr(namespace, self.dest, [])
params: ty.Dict[str, str] = {} params: dict[str, str] = {}
key = '' key = ''
for kv in values.split(','): for kv in values.split(','):
# Add value if an assignment else raise ArgumentError # Add value if an assignment else raise ArgumentError

View File

@@ -75,7 +75,7 @@ class ClientManager:
def __init__( def __init__(
self, self,
cli_options: cloud_region.CloudRegion, cli_options: cloud_region.CloudRegion,
api_version: ty.Optional[ty.Dict[str, str]], api_version: ty.Optional[dict[str, str]],
pw_func: ty.Optional[_PasswordHelper] = None, pw_func: ty.Optional[_PasswordHelper] = None,
app_name: ty.Optional[str] = None, app_name: ty.Optional[str] = None,
app_version: ty.Optional[str] = None, app_version: ty.Optional[str] = None,
@@ -283,5 +283,5 @@ class ClientManager:
) )
return endpoint return endpoint
def get_configuration(self) -> ty.Dict[str, ty.Any]: def get_configuration(self) -> dict[str, ty.Any]:
return copy.deepcopy(self._cli_options.config) return copy.deepcopy(self._cli_options.config)

View File

@@ -27,10 +27,10 @@ from osc_lib.i18n import _
class CommandMeta(abc.ABCMeta): class CommandMeta(abc.ABCMeta):
def __new__( def __new__(
mcs: ty.Type['CommandMeta'], mcs: type['CommandMeta'],
name: str, name: str,
bases: ty.Tuple[ty.Type[ty.Any], ...], bases: tuple[type[ty.Any], ...],
namespace: ty.Dict[str, ty.Any], namespace: dict[str, ty.Any],
) -> 'CommandMeta': ) -> 'CommandMeta':
if 'log' not in namespace: if 'log' not in namespace:
namespace['log'] = logging.getLogger( namespace['log'] = logging.getLogger(

View File

@@ -29,7 +29,7 @@ class Timing(command.Lister):
def take_action( def take_action(
self, parsed_args: argparse.Namespace self, parsed_args: argparse.Namespace
) -> ty.Tuple[ty.Tuple[str, ...], ty.List[ty.Any]]: ) -> tuple[tuple[str, ...], list[ty.Any]]:
column_headers = ( column_headers = (
'URL', 'URL',
'Seconds', 'Seconds',

View File

@@ -14,6 +14,7 @@
"""Application logging""" """Application logging"""
import argparse import argparse
import collections.abc
import logging import logging
import sys import sys
import typing as ty import typing as ty
@@ -22,7 +23,7 @@ import warnings
from openstack.config import cloud_config from openstack.config import cloud_config
def get_loggers() -> ty.Dict[str, str]: def get_loggers() -> dict[str, str]:
loggers = {} loggers = {}
for logkey in logging.Logger.manager.loggerDict.keys(): for logkey in logging.Logger.manager.loggerDict.keys():
loggers[logkey] = logging.getLevelName(logging.getLogger(logkey).level) loggers[logkey] = logging.getLevelName(logging.getLogger(logkey).level)
@@ -56,7 +57,7 @@ def log_level_from_string(level_string: str) -> int:
return log_level return log_level
def log_level_from_config(config: ty.Mapping[str, ty.Any]) -> int: def log_level_from_config(config: collections.abc.Mapping[str, ty.Any]) -> int:
# Check the command line option # Check the command line option
verbose_level = config.get('verbose_level') verbose_level = config.get('verbose_level')
if config.get('debug', False): if config.get('debug', False):

View File

@@ -82,7 +82,7 @@ class OpenStackShell(app.App):
client_manager: clientmanager.ClientManager client_manager: clientmanager.ClientManager
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
timing_data: ty.List[ty.Any] = [] timing_data: list[ty.Any] = []
def __init__( def __init__(
self, self,
@@ -93,7 +93,7 @@ class OpenStackShell(app.App):
stdout: ty.Optional[ty.TextIO] = None, stdout: ty.Optional[ty.TextIO] = None,
stderr: ty.Optional[ty.TextIO] = None, stderr: ty.Optional[ty.TextIO] = None,
interactive_app_factory: ty.Optional[ interactive_app_factory: ty.Optional[
ty.Type['interactive.InteractiveApp'] type['interactive.InteractiveApp']
] = None, ] = None,
deferred_help: bool = False, deferred_help: bool = False,
) -> None: ) -> None:
@@ -127,7 +127,7 @@ class OpenStackShell(app.App):
# Set in subclasses # Set in subclasses
self.api_version = None self.api_version = None
self.command_options: ty.List[str] = [] self.command_options: list[str] = []
self.do_profile = False self.do_profile = False
@@ -136,7 +136,7 @@ class OpenStackShell(app.App):
self.log_configurator = logs.LogConfigurator(self.options) self.log_configurator = logs.LogConfigurator(self.options)
self.dump_stack_trace = self.log_configurator.dump_trace self.dump_stack_trace = self.log_configurator.dump_trace
def run(self, argv: ty.List[str]) -> int: def run(self, argv: list[str]) -> int:
ret_val = 1 ret_val = 1
self.command_options = argv self.command_options = argv
try: try:
@@ -180,7 +180,7 @@ class OpenStackShell(app.App):
f"osprofiler trace show --html {trace_id} " f"osprofiler trace show --html {trace_id} "
) )
def run_subcommand(self, argv: ty.List[str]) -> int: def run_subcommand(self, argv: list[str]) -> int:
self.init_profile() self.init_profile()
try: try:
ret_value = super().run_subcommand(argv) ret_value = super().run_subcommand(argv)
@@ -200,7 +200,7 @@ class OpenStackShell(app.App):
self, self,
description: ty.Optional[str], description: ty.Optional[str],
version: ty.Optional[str], version: ty.Optional[str],
argparse_kwargs: ty.Optional[ty.Dict[str, ty.Any]] = None, argparse_kwargs: ty.Optional[dict[str, ty.Any]] = None,
) -> _argparse.ArgumentParser: ) -> _argparse.ArgumentParser:
parser = super().build_option_parser( parser = super().build_option_parser(
description, description,
@@ -416,7 +416,7 @@ class OpenStackShell(app.App):
""" """
pass pass
def initialize_app(self, argv: ty.List[str]) -> None: def initialize_app(self, argv: list[str]) -> None:
"""Global app init bits: """Global app init bits:
* set up API versions * set up API versions
@@ -570,7 +570,7 @@ class OpenStackShell(app.App):
tcmd.run(targs) tcmd.run(targs)
def main(argv: ty.Optional[ty.List[str]] = None) -> int: def main(argv: ty.Optional[list[str]] = None) -> int:
if argv is None: if argv is None:
argv = sys.argv[1:] argv = sys.argv[1:]
return OpenStackShell().run(argv) return OpenStackShell().run(argv)

View File

@@ -16,6 +16,7 @@
"""Common client utilities""" """Common client utilities"""
import argparse import argparse
import collections.abc
import copy import copy
import functools import functools
import getpass import getpass
@@ -38,10 +39,10 @@ _T = ty.TypeVar('_T')
def backward_compat_col_lister( def backward_compat_col_lister(
column_headers: ty.List[str], column_headers: list[str],
columns: ty.List[str], columns: list[str],
column_map: ty.Dict[str, str], column_map: dict[str, str],
) -> ty.List[str]: ) -> list[str]:
"""Convert the column headers to keep column backward compatibility. """Convert the column headers to keep column backward compatibility.
Replace the new column name of column headers by old name, so that Replace the new column name of column headers by old name, so that
@@ -74,10 +75,10 @@ def backward_compat_col_lister(
def backward_compat_col_showone( def backward_compat_col_showone(
show_object: ty.MutableMapping[str, _T], show_object: collections.abc.MutableMapping[str, _T],
columns: ty.List[str], columns: list[str],
column_map: ty.Dict[str, str], column_map: dict[str, str],
) -> ty.MutableMapping[str, _T]: ) -> collections.abc.MutableMapping[str, _T]:
"""Convert the output object to keep column backward compatibility. """Convert the output object to keep column backward compatibility.
Replace the new column name of output object by old name, so that Replace the new column name of output object by old name, so that
@@ -107,7 +108,7 @@ def backward_compat_col_showone(
return show_object return show_object
def build_kwargs_dict(arg_name: str, value: _T) -> ty.Dict[str, _T]: def build_kwargs_dict(arg_name: str, value: _T) -> dict[str, _T]:
"""Return a dictionary containing `arg_name` if `value` is set.""" """Return a dictionary containing `arg_name` if `value` is set."""
kwargs = {} kwargs = {}
if value: if value:
@@ -116,10 +117,10 @@ def build_kwargs_dict(arg_name: str, value: _T) -> ty.Dict[str, _T]:
def calculate_header_and_attrs( def calculate_header_and_attrs(
column_headers: ty.Sequence[str], column_headers: collections.abc.Sequence[str],
attrs: ty.Sequence[str], attrs: collections.abc.Sequence[str],
parsed_args: argparse.Namespace, parsed_args: argparse.Namespace,
) -> ty.Tuple[ty.Sequence[str], ty.Sequence[str]]: ) -> tuple[collections.abc.Sequence[str], collections.abc.Sequence[str]]:
"""Calculate headers and attribute names based on parsed_args.column. """Calculate headers and attribute names based on parsed_args.column.
When --column (-c) option is specified, this function calculates When --column (-c) option is specified, this function calculates
@@ -172,10 +173,10 @@ def env(*vars: str, **kwargs: ty.Any) -> ty.Optional[str]:
def find_min_match( def find_min_match(
items: ty.Sequence[_T], items: collections.abc.Sequence[_T],
sort_attr: str, sort_attr: str,
**kwargs: ty.Any, **kwargs: ty.Any,
) -> ty.Sequence[_T]: ) -> collections.abc.Sequence[_T]:
"""Find all resources meeting the given minimum constraints """Find all resources meeting the given minimum constraints
:param items: A List of objects to consider :param items: A List of objects to consider
@@ -327,7 +328,7 @@ def find_resource(
def format_dict( def format_dict(
data: ty.Dict[str, ty.Any], prefix: ty.Optional[str] = None data: dict[str, ty.Any], prefix: ty.Optional[str] = None
) -> str: ) -> str:
"""Return a formatted string of key value pairs """Return a formatted string of key value pairs
@@ -357,7 +358,7 @@ def format_dict(
def format_dict_of_list( def format_dict_of_list(
data: ty.Optional[ty.Dict[str, ty.List[ty.Any]]], separator: str = '; ' data: ty.Optional[dict[str, list[ty.Any]]], separator: str = '; '
) -> ty.Optional[str]: ) -> ty.Optional[str]:
"""Return a formatted string of key value pair """Return a formatted string of key value pair
@@ -384,7 +385,7 @@ def format_dict_of_list(
def format_list( def format_list(
data: ty.Optional[ty.List[ty.Any]], separator: str = ', ' data: ty.Optional[list[ty.Any]], separator: str = ', '
) -> ty.Optional[str]: ) -> ty.Optional[str]:
"""Return a formatted strings """Return a formatted strings
@@ -399,7 +400,7 @@ def format_list(
def format_list_of_dicts( def format_list_of_dicts(
data: ty.Optional[ty.List[ty.Dict[str, ty.Any]]], data: ty.Optional[list[dict[str, ty.Any]]],
) -> ty.Optional[str]: ) -> ty.Optional[str]:
"""Return a formatted string of key value pairs for each dict """Return a formatted string of key value pairs for each dict
@@ -444,7 +445,7 @@ def format_size(size: ty.Union[int, float, None]) -> str:
def get_client_class( def get_client_class(
api_name: str, api_name: str,
version: ty.Union[str, int, float], version: ty.Union[str, int, float],
version_map: ty.Dict[str, ty.Type[_T]], version_map: dict[str, type[_T]],
) -> ty.Any: ) -> ty.Any:
"""Returns the client class for the requested API version """Returns the client class for the requested API version
@@ -482,13 +483,13 @@ def get_client_class(
def get_dict_properties( def get_dict_properties(
item: ty.Dict[str, _T], item: dict[str, _T],
fields: ty.Sequence[str], fields: collections.abc.Sequence[str],
mixed_case_fields: ty.Optional[ty.Sequence[str]] = None, mixed_case_fields: ty.Optional[collections.abc.Sequence[str]] = None,
formatters: ty.Optional[ # type: ignore formatters: ty.Optional[
ty.Dict[str, ty.Type[cliff_columns.FormattableColumn]] dict[str, type[cliff_columns.FormattableColumn[ty.Any]]]
] = None, ] = None,
) -> ty.Tuple[ty.Any, ...]: ) -> tuple[ty.Any, ...]:
"""Return a tuple containing the item properties. """Return a tuple containing the item properties.
:param item: a single dict resource :param item: a single dict resource
@@ -534,13 +535,13 @@ def get_dict_properties(
def get_item_properties( def get_item_properties(
item: ty.Dict[str, _T], item: dict[str, _T],
fields: ty.Sequence[str], fields: collections.abc.Sequence[str],
mixed_case_fields: ty.Optional[ty.Sequence[str]] = None, mixed_case_fields: ty.Optional[collections.abc.Sequence[str]] = None,
formatters: ty.Optional[ # type: ignore formatters: ty.Optional[
ty.Dict[str, ty.Type[cliff_columns.FormattableColumn]] dict[str, type[cliff_columns.FormattableColumn[ty.Any]]]
] = None, ] = None,
) -> ty.Tuple[ty.Any, ...]: ) -> tuple[ty.Any, ...]:
"""Return a tuple containing the item properties. """Return a tuple containing the item properties.
:param item: a single item resource (e.g. Server, Project, etc) :param item: a single item resource (e.g. Server, Project, etc)
@@ -655,10 +656,10 @@ def read_blob_file_contents(blob_file: str) -> str:
def sort_items( def sort_items(
items: ty.Sequence[_T], items: collections.abc.Sequence[_T],
sort_str: str, sort_str: str,
sort_type: ty.Optional[ty.Type[ty.Any]] = None, sort_type: ty.Optional[type[ty.Any]] = None,
) -> ty.Sequence[_T]: ) -> collections.abc.Sequence[_T]:
"""Sort items based on sort keys and sort directions given by sort_str. """Sort items based on sort keys and sort directions given by sort_str.
:param items: a list or generator object of items :param items: a list or generator object of items
@@ -719,11 +720,11 @@ def wait_for_delete(
manager: ty.Any, manager: ty.Any,
res_id: str, res_id: str,
status_field: str = 'status', status_field: str = 'status',
error_status: ty.Sequence[str] = ['error'], error_status: collections.abc.Sequence[str] = ['error'],
exception_name: ty.Sequence[str] = ['NotFound'], exception_name: collections.abc.Sequence[str] = ['NotFound'],
sleep_time: int = 5, sleep_time: int = 5,
timeout: int = 300, timeout: int = 300,
callback: ty.Optional[ty.Callable[[int], None]] = None, callback: ty.Optional[collections.abc.Callable[[int], None]] = None,
) -> bool: ) -> bool:
"""Wait for resource deletion """Wait for resource deletion
@@ -775,13 +776,13 @@ def wait_for_delete(
def wait_for_status( def wait_for_status(
status_f: ty.Callable[[str], object], status_f: collections.abc.Callable[[str], object],
res_id: str, res_id: str,
status_field: str = 'status', status_field: str = 'status',
success_status: ty.Sequence[str] = ['active'], success_status: collections.abc.Sequence[str] = ['active'],
error_status: ty.Sequence[str] = ['error'], error_status: collections.abc.Sequence[str] = ['error'],
sleep_time: int = 5, sleep_time: int = 5,
callback: ty.Optional[ty.Callable[[int], None]] = None, callback: ty.Optional[collections.abc.Callable[[int], None]] = None,
) -> bool: ) -> bool:
"""Wait for status change on a resource during a long-running operation """Wait for status change on a resource during a long-running operation
@@ -818,9 +819,9 @@ def wait_for_status(
def get_osc_show_columns_for_sdk_resource( def get_osc_show_columns_for_sdk_resource(
sdk_resource: resource.Resource, sdk_resource: resource.Resource,
osc_column_map: ty.Dict[str, str], osc_column_map: dict[str, str],
invisible_columns: ty.Optional[ty.Sequence[str]] = None, invisible_columns: ty.Optional[collections.abc.Sequence[str]] = None,
) -> ty.Tuple[ty.Tuple[str, ...], ty.Tuple[str, ...]]: ) -> tuple[tuple[str, ...], tuple[str, ...]]:
"""Get and filter the display and attribute columns for an SDK resource. """Get and filter the display and attribute columns for an SDK resource.
Common utility function for preparing the output of an OSC show command. Common utility function for preparing the output of an OSC show command.

View File

@@ -19,8 +19,8 @@ LIST_LONG_ONLY = 'long_only'
def get_column_definitions( def get_column_definitions(
attr_map: ty.List[ty.Tuple[str, str, str]], long_listing: bool attr_map: list[tuple[str, str, str]], long_listing: bool
) -> ty.Tuple[ty.List[str], ty.List[str]]: ) -> tuple[list[str], list[str]]:
"""Return table headers and column names for a listing table. """Return table headers and column names for a listing table.
An attribute map (attr_map) is a list of table entry definitions An attribute map (attr_map) is a list of table entry definitions
@@ -77,9 +77,9 @@ def get_column_definitions(
def get_columns( def get_columns(
item: ty.Dict[str, ty.Any], item: dict[str, ty.Any],
attr_map: ty.Optional[ty.List[ty.Tuple[str, str, str]]] = None, attr_map: ty.Optional[list[tuple[str, str, str]]] = None,
) -> ty.Tuple[ty.Tuple[str, ...], ty.Tuple[str, ...]]: ) -> tuple[tuple[str, ...], tuple[str, ...]]:
"""Return pair of resource attributes and corresponding display names. """Return pair of resource attributes and corresponding display names.
:param item: a dictionary which represents a resource. :param item: a dictionary which represents a resource.

View File

@@ -11,6 +11,7 @@
# under the License. # under the License.
import argparse import argparse
import collections.abc
import typing as ty import typing as ty
from osc_lib.i18n import _ from osc_lib.i18n import _
@@ -32,7 +33,7 @@ class _CommaListAction(argparse.Action):
def add_tag_filtering_option_to_parser( def add_tag_filtering_option_to_parser(
parser: argparse.ArgumentParser, parser: argparse.ArgumentParser,
resource_name: str, resource_name: str,
enhance_help: ty.Callable[[str], str] = lambda _h: _h, enhance_help: collections.abc.Callable[[str], str] = lambda _h: _h,
) -> None: ) -> None:
"""Add tag filtering options to a parser. """Add tag filtering options to a parser.
@@ -96,7 +97,7 @@ def add_tag_filtering_option_to_parser(
def get_tag_filtering_args( def get_tag_filtering_args(
parsed_args: argparse.Namespace, parsed_args: argparse.Namespace,
args: ty.Dict[str, ty.Any], args: dict[str, ty.Any],
) -> None: ) -> None:
"""Adds the tag arguments to an args list. """Adds the tag arguments to an args list.
@@ -119,7 +120,7 @@ def get_tag_filtering_args(
def add_tag_option_to_parser_for_create( def add_tag_option_to_parser_for_create(
parser: argparse.ArgumentParser, parser: argparse.ArgumentParser,
resource_name: str, resource_name: str,
enhance_help: ty.Callable[[str], str] = lambda _h: _h, enhance_help: collections.abc.Callable[[str], str] = lambda _h: _h,
) -> None: ) -> None:
"""Add tag options to a parser for create commands. """Add tag options to a parser for create commands.
@@ -152,7 +153,7 @@ def add_tag_option_to_parser_for_create(
def add_tag_option_to_parser_for_set( def add_tag_option_to_parser_for_set(
parser: argparse.ArgumentParser, parser: argparse.ArgumentParser,
resource_name: str, resource_name: str,
enhance_help: ty.Callable[[str], str] = lambda _h: _h, enhance_help: collections.abc.Callable[[str], str] = lambda _h: _h,
) -> None: ) -> None:
"""Add tag options to a parser for set commands. """Add tag options to a parser for set commands.
@@ -190,7 +191,7 @@ def add_tag_option_to_parser_for_set(
def add_tag_option_to_parser_for_unset( def add_tag_option_to_parser_for_unset(
parser: argparse.ArgumentParser, parser: argparse.ArgumentParser,
resource_name: str, resource_name: str,
enhance_help: ty.Callable[[str], str] = lambda _h: _h, enhance_help: collections.abc.Callable[[str], str] = lambda _h: _h,
) -> None: ) -> None:
"""Add tag options to a parser for set commands. """Add tag options to a parser for set commands.

View File

@@ -1,5 +1,5 @@
[tool.mypy] [tool.mypy]
python_version = "3.8" python_version = "3.9"
show_column_numbers = true show_column_numbers = true
show_error_context = true show_error_context = true
ignore_missing_imports = true ignore_missing_imports = true
@@ -33,7 +33,6 @@ ignore_errors = true
[tool.ruff] [tool.ruff]
line-length = 79 line-length = 79
target-version = "py38"
[tool.ruff.format] [tool.ruff.format]
quote-style = "preserve" quote-style = "preserve"