Merge "Bump Python version used for linters to 3.10"
This commit is contained in:
@@ -22,7 +22,7 @@ repos:
|
|||||||
hooks:
|
hooks:
|
||||||
- id: doc8
|
- id: doc8
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
rev: v0.9.6
|
rev: v0.11.8
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff
|
- id: ruff
|
||||||
args: ['--fix', '--unsafe-fixes']
|
args: ['--fix', '--unsafe-fixes']
|
||||||
@@ -35,7 +35,7 @@ repos:
|
|||||||
- flake8-import-order~=0.18.2
|
- flake8-import-order~=0.18.2
|
||||||
exclude: '^(doc|releasenotes|tools)/.*$'
|
exclude: '^(doc|releasenotes|tools)/.*$'
|
||||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||||
rev: v1.13.0
|
rev: v1.15.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: mypy
|
- id: mypy
|
||||||
additional_dependencies:
|
additional_dependencies:
|
||||||
|
@@ -47,9 +47,9 @@ class BaseAPI:
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
session: ty.Optional[ksa_session.Session] = None,
|
session: ksa_session.Session | None = None,
|
||||||
service_type: ty.Optional[str] = None,
|
service_type: str | None = None,
|
||||||
endpoint: ty.Optional[str] = None,
|
endpoint: str | None = None,
|
||||||
**kwargs: ty.Any,
|
**kwargs: ty.Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Base object that contains some common API objects and methods
|
"""Base object that contains some common API objects and methods
|
||||||
@@ -83,7 +83,7 @@ class BaseAPI:
|
|||||||
self.service_type = service_type
|
self.service_type = service_type
|
||||||
self.endpoint = self._munge_endpoint(endpoint)
|
self.endpoint = self._munge_endpoint(endpoint)
|
||||||
|
|
||||||
def _munge_endpoint(self, endpoint: ty.Optional[str]) -> ty.Optional[str]:
|
def _munge_endpoint(self, endpoint: str | None) -> str | None:
|
||||||
"""Hook to allow subclasses to massage the passed-in endpoint
|
"""Hook to allow subclasses to massage the passed-in endpoint
|
||||||
|
|
||||||
Hook to massage passed-in endpoints from arbitrary sources,
|
Hook to massage passed-in endpoints from arbitrary sources,
|
||||||
@@ -108,7 +108,7 @@ class BaseAPI:
|
|||||||
self,
|
self,
|
||||||
method: str,
|
method: str,
|
||||||
url: str,
|
url: str,
|
||||||
session: ty.Optional[ksa_session.Session] = None,
|
session: ksa_session.Session | None = None,
|
||||||
**kwargs: ty.Any,
|
**kwargs: ty.Any,
|
||||||
) -> requests.Response:
|
) -> requests.Response:
|
||||||
"""Perform call into session
|
"""Perform call into session
|
||||||
@@ -159,10 +159,10 @@ class BaseAPI:
|
|||||||
def create(
|
def create(
|
||||||
self,
|
self,
|
||||||
url: str,
|
url: str,
|
||||||
session: ty.Optional[ksa_session.Session] = None,
|
session: ksa_session.Session | None = None,
|
||||||
method: ty.Optional[str] = None,
|
method: str | None = None,
|
||||||
**params: ty.Any,
|
**params: ty.Any,
|
||||||
) -> ty.Union[requests.Response, ty.Any]:
|
) -> requests.Response | ty.Any:
|
||||||
"""Create a new resource
|
"""Create a new resource
|
||||||
|
|
||||||
:param string url:
|
:param string url:
|
||||||
@@ -185,7 +185,7 @@ class BaseAPI:
|
|||||||
def delete(
|
def delete(
|
||||||
self,
|
self,
|
||||||
url: str,
|
url: str,
|
||||||
session: ty.Optional[ksa_session.Session] = None,
|
session: ksa_session.Session | None = None,
|
||||||
**params: ty.Any,
|
**params: ty.Any,
|
||||||
) -> requests.Response:
|
) -> requests.Response:
|
||||||
"""Delete a resource
|
"""Delete a resource
|
||||||
@@ -201,12 +201,12 @@ class BaseAPI:
|
|||||||
def list(
|
def list(
|
||||||
self,
|
self,
|
||||||
path: str,
|
path: str,
|
||||||
session: ty.Optional[ksa_session.Session] = None,
|
session: ksa_session.Session | None = None,
|
||||||
body: ty.Any = None,
|
body: ty.Any = None,
|
||||||
detailed: bool = False,
|
detailed: bool = False,
|
||||||
headers: ty.Optional[dict[str, str]] = None,
|
headers: dict[str, str] | None = None,
|
||||||
**params: ty.Any,
|
**params: ty.Any,
|
||||||
) -> ty.Union[requests.Response, ty.Any]:
|
) -> requests.Response | ty.Any:
|
||||||
"""Return a list of resources
|
"""Return a list of resources
|
||||||
|
|
||||||
GET ${ENDPOINT}/${PATH}?${PARAMS}
|
GET ${ENDPOINT}/${PATH}?${PARAMS}
|
||||||
@@ -258,9 +258,9 @@ class BaseAPI:
|
|||||||
def find_attr(
|
def find_attr(
|
||||||
self,
|
self,
|
||||||
path: str,
|
path: str,
|
||||||
value: ty.Optional[str] = None,
|
value: str | None = None,
|
||||||
attr: ty.Optional[str] = None,
|
attr: str | None = None,
|
||||||
resource: ty.Optional[str] = None,
|
resource: str | None = None,
|
||||||
) -> ty.Any:
|
) -> ty.Any:
|
||||||
"""Find a resource via attribute or ID
|
"""Find a resource via attribute or ID
|
||||||
|
|
||||||
@@ -324,7 +324,7 @@ class BaseAPI:
|
|||||||
def find_bulk(
|
def find_bulk(
|
||||||
self,
|
self,
|
||||||
path: str,
|
path: str,
|
||||||
headers: ty.Optional[dict[str, str]] = None,
|
headers: dict[str, str] | None = None,
|
||||||
**kwargs: ty.Any,
|
**kwargs: ty.Any,
|
||||||
) -> builtins.list[ty.Any]:
|
) -> builtins.list[ty.Any]:
|
||||||
"""Bulk load and filter locally
|
"""Bulk load and filter locally
|
||||||
@@ -376,9 +376,9 @@ class BaseAPI:
|
|||||||
def find(
|
def find(
|
||||||
self,
|
self,
|
||||||
path: str,
|
path: str,
|
||||||
value: ty.Optional[str] = None,
|
value: str | None = None,
|
||||||
attr: ty.Optional[str] = None,
|
attr: str | None = None,
|
||||||
headers: ty.Optional[dict[str, str]] = None,
|
headers: dict[str, str] | None = None,
|
||||||
) -> ty.Any:
|
) -> ty.Any:
|
||||||
"""Find a single resource by name or ID
|
"""Find a single resource by name or ID
|
||||||
|
|
||||||
|
@@ -223,10 +223,10 @@ def build_auth_plugins_option_parser(
|
|||||||
def get_keystone2keystone_auth(
|
def get_keystone2keystone_auth(
|
||||||
local_auth: identity_base.BaseIdentityPlugin,
|
local_auth: identity_base.BaseIdentityPlugin,
|
||||||
service_provider: str,
|
service_provider: str,
|
||||||
project_id: ty.Optional[str] = None,
|
project_id: str | None = None,
|
||||||
project_name: ty.Optional[str] = None,
|
project_name: str | None = None,
|
||||||
project_domain_id: ty.Optional[str] = None,
|
project_domain_id: str | None = None,
|
||||||
project_domain_name: ty.Optional[str] = None,
|
project_domain_name: str | None = None,
|
||||||
) -> k2k.Keystone2Keystone:
|
) -> k2k.Keystone2Keystone:
|
||||||
"""Return Keystone 2 Keystone authentication for service provider.
|
"""Return Keystone 2 Keystone authentication for service provider.
|
||||||
|
|
||||||
|
@@ -20,11 +20,11 @@ _T = ty.TypeVar('_T', bound=list[ty.Any])
|
|||||||
|
|
||||||
|
|
||||||
def simple_filter(
|
def simple_filter(
|
||||||
data: ty.Optional[_T] = None,
|
data: _T | None = None,
|
||||||
attr: ty.Optional[str] = None,
|
attr: str | None = None,
|
||||||
value: ty.Optional[str] = None,
|
value: str | None = None,
|
||||||
property_field: ty.Optional[str] = None,
|
property_field: str | None = None,
|
||||||
) -> ty.Optional[_T]:
|
) -> _T | None:
|
||||||
"""Filter a list of dicts
|
"""Filter a list of dicts
|
||||||
|
|
||||||
:param list data:
|
:param list data:
|
||||||
|
@@ -62,7 +62,7 @@ class ListDictColumn(columns.FormattableColumn[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[ty.Union[int, float]]):
|
class SizeColumn(columns.FormattableColumn[int | float]):
|
||||||
"""Format column for file size content"""
|
"""Format column for file size content"""
|
||||||
|
|
||||||
def human_readable(self) -> str:
|
def human_readable(self) -> str:
|
||||||
|
@@ -12,7 +12,6 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import typing as ty
|
|
||||||
|
|
||||||
from openstack import connection
|
from openstack import connection
|
||||||
from openstack import exceptions
|
from openstack import exceptions
|
||||||
@@ -49,7 +48,7 @@ def add_project_owner_option_to_parser(
|
|||||||
def find_project(
|
def find_project(
|
||||||
sdk_connection: connection.Connection,
|
sdk_connection: connection.Connection,
|
||||||
name_or_id: str,
|
name_or_id: str,
|
||||||
domain_name_or_id: ty.Optional[str] = None,
|
domain_name_or_id: str | None = None,
|
||||||
) -> project.Project:
|
) -> project.Project:
|
||||||
"""Find a project by its name name or ID.
|
"""Find a project by its name name or ID.
|
||||||
|
|
||||||
|
@@ -34,8 +34,8 @@ class KeyValueAction(argparse.Action):
|
|||||||
self,
|
self,
|
||||||
parser: argparse.ArgumentParser,
|
parser: argparse.ArgumentParser,
|
||||||
namespace: argparse.Namespace,
|
namespace: argparse.Namespace,
|
||||||
values: ty.Union[str, ty.Sequence[ty.Any], None],
|
values: str | ty.Sequence[ty.Any] | None,
|
||||||
option_string: ty.Optional[str] = None,
|
option_string: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
if not isinstance(values, str):
|
if not isinstance(values, str):
|
||||||
raise TypeError('expected str')
|
raise TypeError('expected str')
|
||||||
@@ -68,8 +68,8 @@ class KeyValueAppendAction(argparse.Action):
|
|||||||
self,
|
self,
|
||||||
parser: argparse.ArgumentParser,
|
parser: argparse.ArgumentParser,
|
||||||
namespace: argparse.Namespace,
|
namespace: argparse.Namespace,
|
||||||
values: ty.Union[str, ty.Sequence[ty.Any], None],
|
values: str | ty.Sequence[ty.Any] | None,
|
||||||
option_string: ty.Optional[str] = None,
|
option_string: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
if not isinstance(values, str):
|
if not isinstance(values, str):
|
||||||
raise TypeError('expected str')
|
raise TypeError('expected str')
|
||||||
@@ -110,16 +110,16 @@ class MultiKeyValueAction(argparse.Action):
|
|||||||
self,
|
self,
|
||||||
option_strings: ty.Sequence[str],
|
option_strings: ty.Sequence[str],
|
||||||
dest: str,
|
dest: str,
|
||||||
nargs: ty.Union[int, str, None] = None,
|
nargs: int | str | None = None,
|
||||||
required_keys: ty.Optional[ty.Sequence[str]] = None,
|
required_keys: ty.Sequence[str] | None = None,
|
||||||
optional_keys: ty.Optional[ty.Sequence[str]] = None,
|
optional_keys: ty.Sequence[str] | None = None,
|
||||||
const: ty.Optional[_T] = None,
|
const: _T | None = None,
|
||||||
default: ty.Union[_T, str, None] = None,
|
default: _T | str | None = None,
|
||||||
type: ty.Optional[collections.abc.Callable[[str], _T]] = None,
|
type: collections.abc.Callable[[str], _T] | None = None,
|
||||||
choices: ty.Optional[collections.abc.Iterable[_T]] = None,
|
choices: collections.abc.Iterable[_T] | None = None,
|
||||||
required: bool = False,
|
required: bool = False,
|
||||||
help: ty.Optional[str] = None,
|
help: str | None = None,
|
||||||
metavar: ty.Union[str, tuple[str, ...], None] = None,
|
metavar: str | tuple[str, ...] | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the action object, and parse customized options
|
"""Initialize the action object, and parse customized options
|
||||||
|
|
||||||
@@ -203,8 +203,8 @@ class MultiKeyValueAction(argparse.Action):
|
|||||||
self,
|
self,
|
||||||
parser: argparse.ArgumentParser,
|
parser: argparse.ArgumentParser,
|
||||||
namespace: argparse.Namespace,
|
namespace: argparse.Namespace,
|
||||||
values: ty.Union[str, ty.Sequence[ty.Any], None],
|
values: str | ty.Sequence[ty.Any] | None,
|
||||||
option_string: ty.Optional[str] = None,
|
option_string: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
if not isinstance(values, str):
|
if not isinstance(values, str):
|
||||||
raise TypeError('expected str')
|
raise TypeError('expected str')
|
||||||
@@ -249,8 +249,8 @@ class MultiKeyValueCommaAction(MultiKeyValueAction):
|
|||||||
self,
|
self,
|
||||||
parser: argparse.ArgumentParser,
|
parser: argparse.ArgumentParser,
|
||||||
namespace: argparse.Namespace,
|
namespace: argparse.Namespace,
|
||||||
values: ty.Union[str, ty.Sequence[ty.Any], None],
|
values: str | ty.Sequence[ty.Any] | None,
|
||||||
option_string: ty.Optional[str] = None,
|
option_string: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Overwrite the __call__ function of MultiKeyValueAction
|
"""Overwrite the __call__ function of MultiKeyValueAction
|
||||||
|
|
||||||
@@ -308,8 +308,8 @@ class RangeAction(argparse.Action):
|
|||||||
self,
|
self,
|
||||||
parser: argparse.ArgumentParser,
|
parser: argparse.ArgumentParser,
|
||||||
namespace: argparse.Namespace,
|
namespace: argparse.Namespace,
|
||||||
values: ty.Union[str, ty.Sequence[ty.Any], None],
|
values: str | ty.Sequence[ty.Any] | None,
|
||||||
option_string: ty.Optional[str] = None,
|
option_string: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
if not isinstance(values, str):
|
if not isinstance(values, str):
|
||||||
msg = _("Invalid range, non-string value provided")
|
msg = _("Invalid range, non-string value provided")
|
||||||
@@ -352,10 +352,10 @@ class NonNegativeAction(argparse.Action):
|
|||||||
self,
|
self,
|
||||||
parser: argparse.ArgumentParser,
|
parser: argparse.ArgumentParser,
|
||||||
namespace: argparse.Namespace,
|
namespace: argparse.Namespace,
|
||||||
values: ty.Union[str, ty.Sequence[ty.Any], None],
|
values: str | ty.Sequence[ty.Any] | None,
|
||||||
option_string: ty.Optional[str] = None,
|
option_string: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
if not isinstance(values, (str, int, float)):
|
if not isinstance(values, str | int | float):
|
||||||
msg = _("%s expected a non-negative integer")
|
msg = _("%s expected a non-negative integer")
|
||||||
raise argparse.ArgumentError(self, msg % str(option_string))
|
raise argparse.ArgumentError(self, msg % str(option_string))
|
||||||
|
|
||||||
|
@@ -59,7 +59,7 @@ class ClientCache:
|
|||||||
|
|
||||||
|
|
||||||
class _PasswordHelper(ty.Protocol):
|
class _PasswordHelper(ty.Protocol):
|
||||||
def __call__(self, prompt: ty.Optional[str] = None) -> str: ...
|
def __call__(self, prompt: str | None = None) -> str: ...
|
||||||
|
|
||||||
|
|
||||||
class ClientManager:
|
class ClientManager:
|
||||||
@@ -75,10 +75,10 @@ class ClientManager:
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
cli_options: cloud_region.CloudRegion,
|
cli_options: cloud_region.CloudRegion,
|
||||||
api_version: ty.Optional[dict[str, str]],
|
api_version: dict[str, str] | None,
|
||||||
pw_func: ty.Optional[_PasswordHelper] = None,
|
pw_func: _PasswordHelper | None = None,
|
||||||
app_name: ty.Optional[str] = None,
|
app_name: str | None = None,
|
||||||
app_version: ty.Optional[str] = None,
|
app_version: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up a ClientManager
|
"""Set up a ClientManager
|
||||||
|
|
||||||
@@ -212,7 +212,7 @@ class ClientManager:
|
|||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def auth_ref(self) -> ty.Optional[ksa_access.AccessInfo]:
|
def auth_ref(self) -> ksa_access.AccessInfo | None:
|
||||||
"""Dereference will trigger an auth if it hasn't already"""
|
"""Dereference will trigger an auth if it hasn't already"""
|
||||||
if (
|
if (
|
||||||
not self._auth_required
|
not self._auth_required
|
||||||
@@ -226,11 +226,11 @@ class ClientManager:
|
|||||||
self._auth_ref = self.auth.get_auth_ref(self.session)
|
self._auth_ref = self.auth.get_auth_ref(self.session)
|
||||||
return self._auth_ref
|
return self._auth_ref
|
||||||
|
|
||||||
def _override_for(self, service_type: str) -> ty.Optional[str]:
|
def _override_for(self, service_type: str) -> str | None:
|
||||||
key = '{}_endpoint_override'.format(service_type.replace('-', '_'))
|
key = '{}_endpoint_override'.format(service_type.replace('-', '_'))
|
||||||
return ty.cast(ty.Optional[str], self._cli_options.config.get(key))
|
return ty.cast(str | None, self._cli_options.config.get(key))
|
||||||
|
|
||||||
def is_service_available(self, service_type: str) -> ty.Optional[bool]:
|
def is_service_available(self, service_type: str) -> bool | None:
|
||||||
"""Check if a service type is in the current Service Catalog"""
|
"""Check if a service type is in the current Service Catalog"""
|
||||||
# If there is an override, assume the service is available
|
# If there is an override, assume the service is available
|
||||||
if self._override_for(service_type):
|
if self._override_for(service_type):
|
||||||
@@ -256,9 +256,9 @@ class ClientManager:
|
|||||||
def get_endpoint_for_service_type(
|
def get_endpoint_for_service_type(
|
||||||
self,
|
self,
|
||||||
service_type: str,
|
service_type: str,
|
||||||
region_name: ty.Optional[str] = None,
|
region_name: str | None = None,
|
||||||
interface: str = 'public',
|
interface: str = 'public',
|
||||||
) -> ty.Optional[str]:
|
) -> str | None:
|
||||||
"""Return the endpoint URL for the service type."""
|
"""Return the endpoint URL for the service type."""
|
||||||
# Overrides take priority unconditionally
|
# Overrides take priority unconditionally
|
||||||
override = self._override_for(service_type)
|
override = self._override_for(service_type)
|
||||||
|
@@ -15,8 +15,6 @@
|
|||||||
|
|
||||||
"""Exception definitions."""
|
"""Exception definitions."""
|
||||||
|
|
||||||
import typing as ty
|
|
||||||
|
|
||||||
|
|
||||||
class CommandError(Exception):
|
class CommandError(Exception):
|
||||||
pass
|
pass
|
||||||
@@ -66,9 +64,9 @@ class ClientException(Exception):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
code: ty.Union[int, str],
|
code: int | str,
|
||||||
message: ty.Optional[str] = None,
|
message: str | None = None,
|
||||||
details: ty.Optional[str] = None,
|
details: str | None = None,
|
||||||
):
|
):
|
||||||
if not isinstance(code, int) and message is None:
|
if not isinstance(code, int) and message is None:
|
||||||
message = code
|
message = code
|
||||||
|
@@ -96,8 +96,8 @@ class _FileFormatter(logging.Formatter):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
options: ty.Optional[argparse.Namespace] = None,
|
options: argparse.Namespace | None = None,
|
||||||
config: ty.Optional[cloud_config.CloudConfig] = None,
|
config: cloud_config.CloudConfig | None = None,
|
||||||
**kwargs: ty.Any,
|
**kwargs: ty.Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
context = {}
|
context = {}
|
||||||
|
@@ -48,7 +48,7 @@ DEFAULT_DOMAIN = 'default'
|
|||||||
DEFAULT_INTERFACE = 'public'
|
DEFAULT_INTERFACE = 'public'
|
||||||
|
|
||||||
|
|
||||||
def prompt_for_password(prompt: ty.Optional[str] = None) -> str:
|
def prompt_for_password(prompt: str | None = None) -> str:
|
||||||
"""Prompt user for a password
|
"""Prompt user for a password
|
||||||
|
|
||||||
Prompt for a password if stdin is a tty.
|
Prompt for a password if stdin is a tty.
|
||||||
@@ -86,15 +86,14 @@ class OpenStackShell(app.App):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
description: ty.Optional[str] = None,
|
description: str | None = None,
|
||||||
version: ty.Optional[str] = None,
|
version: str | None = None,
|
||||||
command_manager: ty.Optional[commandmanager.CommandManager] = None,
|
command_manager: commandmanager.CommandManager | None = None,
|
||||||
stdin: ty.Optional[ty.TextIO] = None,
|
stdin: ty.TextIO | None = None,
|
||||||
stdout: ty.Optional[ty.TextIO] = None,
|
stdout: ty.TextIO | None = None,
|
||||||
stderr: ty.Optional[ty.TextIO] = None,
|
stderr: ty.TextIO | None = None,
|
||||||
interactive_app_factory: ty.Optional[
|
interactive_app_factory: type['interactive.InteractiveApp']
|
||||||
type['interactive.InteractiveApp']
|
| None = None,
|
||||||
] = None,
|
|
||||||
deferred_help: bool = False,
|
deferred_help: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
# Patch command.Command to add a default auth_required = True
|
# Patch command.Command to add a default auth_required = True
|
||||||
@@ -198,9 +197,9 @@ class OpenStackShell(app.App):
|
|||||||
|
|
||||||
def build_option_parser(
|
def build_option_parser(
|
||||||
self,
|
self,
|
||||||
description: ty.Optional[str],
|
description: str | None,
|
||||||
version: ty.Optional[str],
|
version: str | None,
|
||||||
argparse_kwargs: ty.Optional[dict[str, ty.Any]] = None,
|
argparse_kwargs: dict[str, ty.Any] | None = None,
|
||||||
) -> _argparse.ArgumentParser:
|
) -> _argparse.ArgumentParser:
|
||||||
parser = super().build_option_parser(
|
parser = super().build_option_parser(
|
||||||
description,
|
description,
|
||||||
@@ -532,7 +531,7 @@ class OpenStackShell(app.App):
|
|||||||
self,
|
self,
|
||||||
cmd: 'command.Command',
|
cmd: 'command.Command',
|
||||||
result: int,
|
result: int,
|
||||||
err: ty.Optional[BaseException],
|
err: BaseException | None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.log.debug('clean_up %s: %s', cmd.__class__.__name__, err or '')
|
self.log.debug('clean_up %s: %s', cmd.__class__.__name__, err or '')
|
||||||
|
|
||||||
@@ -570,7 +569,7 @@ class OpenStackShell(app.App):
|
|||||||
tcmd.run(targs)
|
tcmd.run(targs)
|
||||||
|
|
||||||
|
|
||||||
def main(argv: ty.Optional[list[str]] = None) -> int:
|
def main(argv: list[str] | None = 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)
|
||||||
|
@@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import functools
|
import functools
|
||||||
import sys
|
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
from osc_lib.tests import utils as test_utils
|
from osc_lib.tests import utils as test_utils
|
||||||
@@ -216,10 +215,7 @@ class TestTagHelps(test_utils.TestCase):
|
|||||||
:param exp_enhanced: Expected output with ``enhance_help`` set to
|
:param exp_enhanced: Expected output with ``enhance_help`` set to
|
||||||
``help_enhancer``
|
``help_enhancer``
|
||||||
"""
|
"""
|
||||||
if sys.version_info >= (3, 10):
|
|
||||||
options_name = 'options'
|
options_name = 'options'
|
||||||
else:
|
|
||||||
options_name = 'optional arguments'
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
formatter_class=functools.partial(argparse.HelpFormatter, width=78)
|
formatter_class=functools.partial(argparse.HelpFormatter, width=78)
|
||||||
)
|
)
|
||||||
|
@@ -155,7 +155,7 @@ def calculate_header_and_attrs(
|
|||||||
return column_headers, attrs
|
return column_headers, attrs
|
||||||
|
|
||||||
|
|
||||||
def env(*vars: str, **kwargs: ty.Any) -> ty.Optional[str]:
|
def env(*vars: str, **kwargs: ty.Any) -> str | None:
|
||||||
"""Search for the first defined of possibly many env vars
|
"""Search for the first defined of possibly many env vars
|
||||||
|
|
||||||
Returns the first environment variable defined in vars, or
|
Returns the first environment variable defined in vars, or
|
||||||
@@ -327,9 +327,7 @@ def find_resource(
|
|||||||
raise exceptions.CommandError(msg % name_or_id)
|
raise exceptions.CommandError(msg % name_or_id)
|
||||||
|
|
||||||
|
|
||||||
def format_dict(
|
def format_dict(data: dict[str, ty.Any], prefix: str | None = None) -> str:
|
||||||
data: dict[str, ty.Any], prefix: ty.Optional[str] = None
|
|
||||||
) -> str:
|
|
||||||
"""Return a formatted string of key value pairs
|
"""Return a formatted string of key value pairs
|
||||||
|
|
||||||
:param data: a dict
|
:param data: a dict
|
||||||
@@ -358,8 +356,8 @@ def format_dict(
|
|||||||
|
|
||||||
|
|
||||||
def format_dict_of_list(
|
def format_dict_of_list(
|
||||||
data: ty.Optional[dict[str, list[ty.Any]]], separator: str = '; '
|
data: dict[str, list[ty.Any]] | None, separator: str = '; '
|
||||||
) -> ty.Optional[str]:
|
) -> str | None:
|
||||||
"""Return a formatted string of key value pair
|
"""Return a formatted string of key value pair
|
||||||
|
|
||||||
:param data: a dict, key is string, value is a list of string, for example:
|
:param data: a dict, key is string, value is a list of string, for example:
|
||||||
@@ -385,8 +383,8 @@ def format_dict_of_list(
|
|||||||
|
|
||||||
|
|
||||||
def format_list(
|
def format_list(
|
||||||
data: ty.Optional[list[ty.Any]], separator: str = ', '
|
data: list[ty.Any] | None, separator: str = ', '
|
||||||
) -> ty.Optional[str]:
|
) -> str | None:
|
||||||
"""Return a formatted strings
|
"""Return a formatted strings
|
||||||
|
|
||||||
:param data: a list of strings
|
:param data: a list of strings
|
||||||
@@ -400,8 +398,8 @@ def format_list(
|
|||||||
|
|
||||||
|
|
||||||
def format_list_of_dicts(
|
def format_list_of_dicts(
|
||||||
data: ty.Optional[list[dict[str, ty.Any]]],
|
data: list[dict[str, ty.Any]] | None,
|
||||||
) -> ty.Optional[str]:
|
) -> str | None:
|
||||||
"""Return a formatted string of key value pairs for each dict
|
"""Return a formatted string of key value pairs for each dict
|
||||||
|
|
||||||
:param data: a list of dicts
|
:param data: a list of dicts
|
||||||
@@ -413,7 +411,7 @@ def format_list_of_dicts(
|
|||||||
return '\n'.join(format_dict(i) for i in data)
|
return '\n'.join(format_dict(i) for i in data)
|
||||||
|
|
||||||
|
|
||||||
def format_size(size: ty.Union[int, float, None]) -> str:
|
def format_size(size: int | float | None) -> str:
|
||||||
"""Display size of a resource in a human readable format
|
"""Display size of a resource in a human readable format
|
||||||
|
|
||||||
:param size:
|
:param size:
|
||||||
@@ -444,7 +442,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: str | int | float,
|
||||||
version_map: dict[str, 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
|
||||||
@@ -485,10 +483,9 @@ def get_client_class(
|
|||||||
def get_dict_properties(
|
def get_dict_properties(
|
||||||
item: dict[str, _T],
|
item: dict[str, _T],
|
||||||
fields: collections.abc.Sequence[str],
|
fields: collections.abc.Sequence[str],
|
||||||
mixed_case_fields: ty.Optional[collections.abc.Sequence[str]] = None,
|
mixed_case_fields: collections.abc.Sequence[str] | None = None,
|
||||||
formatters: ty.Optional[
|
formatters: dict[str, type[cliff_columns.FormattableColumn[ty.Any]]]
|
||||||
dict[str, type[cliff_columns.FormattableColumn[ty.Any]]]
|
| None = None,
|
||||||
] = None,
|
|
||||||
) -> tuple[ty.Any, ...]:
|
) -> tuple[ty.Any, ...]:
|
||||||
"""Return a tuple containing the item properties.
|
"""Return a tuple containing the item properties.
|
||||||
|
|
||||||
@@ -537,10 +534,9 @@ def get_dict_properties(
|
|||||||
def get_item_properties(
|
def get_item_properties(
|
||||||
item: dict[str, _T],
|
item: dict[str, _T],
|
||||||
fields: collections.abc.Sequence[str],
|
fields: collections.abc.Sequence[str],
|
||||||
mixed_case_fields: ty.Optional[collections.abc.Sequence[str]] = None,
|
mixed_case_fields: collections.abc.Sequence[str] | None = None,
|
||||||
formatters: ty.Optional[
|
formatters: dict[str, type[cliff_columns.FormattableColumn[ty.Any]]]
|
||||||
dict[str, type[cliff_columns.FormattableColumn[ty.Any]]]
|
| None = None,
|
||||||
] = None,
|
|
||||||
) -> tuple[ty.Any, ...]:
|
) -> tuple[ty.Any, ...]:
|
||||||
"""Return a tuple containing the item properties.
|
"""Return a tuple containing the item properties.
|
||||||
|
|
||||||
@@ -612,7 +608,7 @@ def get_field(item: _T, field: str) -> ty.Any:
|
|||||||
|
|
||||||
def get_password(
|
def get_password(
|
||||||
stdin: ty.TextIO,
|
stdin: ty.TextIO,
|
||||||
prompt: ty.Optional[str] = None,
|
prompt: str | None = None,
|
||||||
confirm: bool = True,
|
confirm: bool = True,
|
||||||
) -> str:
|
) -> str:
|
||||||
message = prompt or "User Password:"
|
message = prompt or "User Password:"
|
||||||
@@ -634,7 +630,7 @@ def get_password(
|
|||||||
raise exceptions.CommandError(msg)
|
raise exceptions.CommandError(msg)
|
||||||
|
|
||||||
|
|
||||||
def is_ascii(string: ty.Union[str, bytes]) -> bool:
|
def is_ascii(string: str | bytes) -> bool:
|
||||||
try:
|
try:
|
||||||
if isinstance(string, bytes):
|
if isinstance(string, bytes):
|
||||||
string.decode('ascii')
|
string.decode('ascii')
|
||||||
@@ -658,7 +654,7 @@ def read_blob_file_contents(blob_file: str) -> str:
|
|||||||
def sort_items(
|
def sort_items(
|
||||||
items: collections.abc.Sequence[_T],
|
items: collections.abc.Sequence[_T],
|
||||||
sort_str: str,
|
sort_str: str,
|
||||||
sort_type: ty.Optional[type[ty.Any]] = None,
|
sort_type: type[ty.Any] | None = None,
|
||||||
) -> collections.abc.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.
|
||||||
|
|
||||||
@@ -724,7 +720,7 @@ def wait_for_delete(
|
|||||||
exception_name: collections.abc.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[collections.abc.Callable[[int], None]] = None,
|
callback: collections.abc.Callable[[int], None] | None = None,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""Wait for resource deletion
|
"""Wait for resource deletion
|
||||||
|
|
||||||
@@ -782,7 +778,7 @@ def wait_for_status(
|
|||||||
success_status: collections.abc.Sequence[str] = ['active'],
|
success_status: collections.abc.Sequence[str] = ['active'],
|
||||||
error_status: collections.abc.Sequence[str] = ['error'],
|
error_status: collections.abc.Sequence[str] = ['error'],
|
||||||
sleep_time: int = 5,
|
sleep_time: int = 5,
|
||||||
callback: ty.Optional[collections.abc.Callable[[int], None]] = None,
|
callback: collections.abc.Callable[[int], None] | 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
|
||||||
|
|
||||||
@@ -820,7 +816,7 @@ 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: dict[str, str],
|
osc_column_map: dict[str, str],
|
||||||
invisible_columns: ty.Optional[collections.abc.Sequence[str]] = None,
|
invisible_columns: collections.abc.Sequence[str] | None = None,
|
||||||
) -> tuple[tuple[str, ...], 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.
|
||||||
|
|
||||||
|
@@ -78,7 +78,7 @@ def get_column_definitions(
|
|||||||
|
|
||||||
def get_columns(
|
def get_columns(
|
||||||
item: dict[str, ty.Any],
|
item: dict[str, ty.Any],
|
||||||
attr_map: ty.Optional[list[tuple[str, str, str]]] = None,
|
attr_map: list[tuple[str, str, str]] | None = None,
|
||||||
) -> tuple[tuple[str, ...], 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.
|
||||||
|
|
||||||
|
@@ -22,8 +22,8 @@ class _CommaListAction(argparse.Action):
|
|||||||
self,
|
self,
|
||||||
parser: argparse.ArgumentParser,
|
parser: argparse.ArgumentParser,
|
||||||
namespace: argparse.Namespace,
|
namespace: argparse.Namespace,
|
||||||
values: ty.Union[str, ty.Sequence[ty.Any], None],
|
values: str | ty.Sequence[ty.Any] | None,
|
||||||
option_string: ty.Optional[str] = None,
|
option_string: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
if not isinstance(values, str):
|
if not isinstance(values, str):
|
||||||
raise TypeError('expected str')
|
raise TypeError('expected str')
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
[tool.mypy]
|
[tool.mypy]
|
||||||
python_version = "3.9"
|
python_version = "3.10"
|
||||||
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,6 +33,7 @@ ignore_errors = true
|
|||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
line-length = 79
|
line-length = 79
|
||||||
|
target-version = "py310"
|
||||||
|
|
||||||
[tool.ruff.format]
|
[tool.ruff.format]
|
||||||
quote-style = "preserve"
|
quote-style = "preserve"
|
||||||
|
Reference in New Issue
Block a user