Skip to content

Commit 054db28

Browse files
committed
typing: Add hints to identity commands
Change-Id: I0edabc266915a56749ae164fbd82d1c32a71c7f4 Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
1 parent f616971 commit 054db28

39 files changed

Lines changed: 883 additions & 446 deletions

openstackclient/identity/client.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
# License for the specific language governing permissions and limitations
1313
# under the License.
1414

15+
import argparse
1516
import logging
17+
from typing import Any
1618

1719
from keystoneclient.v2_0 import client as identity_client_v2
1820
from osc_lib import utils
@@ -39,7 +41,7 @@
3941
}
4042

4143

42-
def make_client(instance):
44+
def make_client(instance: Any) -> Any:
4345
"""Returns an identity service client."""
4446
identity_client = utils.get_client_class(
4547
API_NAME, instance._api_version[API_NAME], API_VERSIONS
@@ -56,7 +58,9 @@ def make_client(instance):
5658
return client
5759

5860

59-
def build_option_parser(parser):
61+
def build_option_parser(
62+
parser: argparse.ArgumentParser,
63+
) -> argparse.ArgumentParser:
6064
"""Hook to add global options"""
6165
parser.add_argument(
6266
'--os-identity-api-version',
@@ -70,10 +74,11 @@ def build_option_parser(parser):
7074
return parser
7175

7276

77+
# We're not going to add type hints to this at this point
7378
class IdentityClientv2(identity_client_v2.Client):
7479
"""Tweak the earlier client class to deal with some changes"""
7580

76-
def __getattr__(self, name):
81+
def __getattr__(self, name: str) -> Any:
7782
# Map v3 'projects' back to v2 'tenants'
7883
if name == "projects":
7984
return self.tenants

openstackclient/identity/common.py

Lines changed: 74 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515

1616
"""Common identity code"""
1717

18+
import argparse
19+
from collections.abc import Callable
20+
from typing import Any, cast
21+
1822
from keystoneclient import exceptions as identity_exc
1923
from keystoneclient.v3 import domains
2024
from keystoneclient.v3 import groups
@@ -27,7 +31,7 @@
2731
from openstackclient.i18n import _
2832

2933

30-
def find_service_in_list(service_list, service_id):
34+
def find_service_in_list(service_list: list[Any], service_id: str) -> Any:
3135
"""Find a service by id in service list."""
3236

3337
for service in service_list:
@@ -38,7 +42,7 @@ def find_service_in_list(service_list, service_id):
3842
)
3943

4044

41-
def find_service(identity_client, name_type_or_id):
45+
def find_service(identity_client: Any, name_type_or_id: str) -> Any:
4246
"""Find a service by id, name or type."""
4347

4448
try:
@@ -74,7 +78,7 @@ def find_service(identity_client, name_type_or_id):
7478
raise exceptions.CommandError(msg % name_type_or_id)
7579

7680

77-
def find_service_sdk(identity_client, name_type_or_id):
81+
def find_service_sdk(identity_client: Any, name_type_or_id: str) -> Any:
7882
"""Find a service by id, name or type."""
7983

8084
try:
@@ -107,7 +111,7 @@ def find_service_sdk(identity_client, name_type_or_id):
107111
return service
108112

109113

110-
def get_resource(manager, name_type_or_id):
114+
def get_resource(manager: Any, name_type_or_id: str) -> Any:
111115
# NOTE (vishakha): Due to bug #1799153 and for any another related case
112116
# where GET resource API does not support the filter by name,
113117
# osc_lib.utils.find_resource() method cannot be used because that method
@@ -126,7 +130,7 @@ def get_resource(manager, name_type_or_id):
126130
raise exceptions.CommandError(msg % name_type_or_id)
127131

128132

129-
def get_resource_by_id(manager, resource_id):
133+
def get_resource_by_id(manager: Any, resource_id: str) -> Any:
130134
"""Get resource by ID
131135
132136
Raises CommandError if the resource is not found
@@ -138,7 +142,12 @@ def get_resource_by_id(manager, resource_id):
138142
raise exceptions.CommandError(msg.format(resource_id))
139143

140144

141-
def _get_token_resource(client, resource, parsed_name, parsed_domain=None):
145+
def _get_token_resource(
146+
client: Any,
147+
resource: str,
148+
parsed_name: str,
149+
parsed_domain: str | None = None,
150+
) -> str:
142151
"""Peek into the user's auth token to get resource IDs
143152
144153
Look into a user's token to try and find the ID of a domain, project or
@@ -174,7 +183,7 @@ def _get_token_resource(client, resource, parsed_name, parsed_domain=None):
174183
if isinstance(obj, list):
175184
for item in obj:
176185
if item['name'] == parsed_name:
177-
return item['id']
186+
return cast(str, item['id'])
178187
if item['id'] == parsed_name:
179188
return parsed_name
180189
return parsed_name
@@ -184,23 +193,30 @@ def _get_token_resource(client, resource, parsed_name, parsed_domain=None):
184193
return parsed_name
185194

186195

187-
def find_domain(identity_client, name_or_id):
196+
def find_domain(identity_client: Any, name_or_id: str) -> domains.Domain:
188197
return _find_identity_resource(
189198
identity_client.domains, name_or_id, domains.Domain
190199
)
191200

192201

193202
def find_domain_id_sdk(
194-
identity_client, name_or_id, *, validate_actor_existence=True
195-
):
203+
identity_client: Any,
204+
name_or_id: str,
205+
*,
206+
validate_actor_existence: bool = True,
207+
) -> str:
196208
return _find_sdk_id(
197209
identity_client.find_domain,
198210
name_or_id=name_or_id,
199211
validate_actor_existence=validate_actor_existence,
200212
)
201213

202214

203-
def find_group(identity_client, name_or_id, domain_name_or_id=None):
215+
def find_group(
216+
identity_client: Any,
217+
name_or_id: str,
218+
domain_name_or_id: str | None = None,
219+
) -> groups.Group:
204220
if domain_name_or_id is None:
205221
return _find_identity_resource(
206222
identity_client.groups, name_or_id, groups.Group
@@ -216,12 +232,12 @@ def find_group(identity_client, name_or_id, domain_name_or_id=None):
216232

217233

218234
def find_group_id_sdk(
219-
identity_client,
220-
name_or_id,
221-
domain_name_or_id=None,
235+
identity_client: Any,
236+
name_or_id: str,
237+
domain_name_or_id: str | None = None,
222238
*,
223-
validate_actor_existence=True,
224-
):
239+
validate_actor_existence: bool = True,
240+
) -> str:
225241
if domain_name_or_id is None:
226242
return _find_sdk_id(
227243
identity_client.find_group,
@@ -242,7 +258,11 @@ def find_group_id_sdk(
242258
)
243259

244260

245-
def find_project(identity_client, name_or_id, domain_name_or_id=None):
261+
def find_project(
262+
identity_client: Any,
263+
name_or_id: str,
264+
domain_name_or_id: str | None = None,
265+
) -> projects.Project:
246266
if domain_name_or_id is None:
247267
return _find_identity_resource(
248268
identity_client.projects, name_or_id, projects.Project
@@ -257,13 +277,13 @@ def find_project(identity_client, name_or_id, domain_name_or_id=None):
257277

258278

259279
def find_project_id_sdk(
260-
identity_client,
261-
name_or_id,
262-
domain_name_or_id=None,
280+
identity_client: Any,
281+
name_or_id: str,
282+
domain_name_or_id: str | None = None,
263283
*,
264-
validate_actor_existence=True,
265-
validate_domain_actor_existence=None,
266-
):
284+
validate_actor_existence: bool = True,
285+
validate_domain_actor_existence: bool | None = None,
286+
) -> str:
267287
if domain_name_or_id is None:
268288
return _find_sdk_id(
269289
identity_client.find_project,
@@ -287,7 +307,11 @@ def find_project_id_sdk(
287307
)
288308

289309

290-
def find_user(identity_client, name_or_id, domain_name_or_id=None):
310+
def find_user(
311+
identity_client: Any,
312+
name_or_id: str,
313+
domain_name_or_id: str | None = None,
314+
) -> users.User:
291315
if domain_name_or_id is None:
292316
return _find_identity_resource(
293317
identity_client.users, name_or_id, users.User
@@ -299,12 +323,12 @@ def find_user(identity_client, name_or_id, domain_name_or_id=None):
299323

300324

301325
def find_user_id_sdk(
302-
identity_client,
303-
name_or_id,
304-
domain_name_or_id=None,
326+
identity_client: Any,
327+
name_or_id: str,
328+
domain_name_or_id: str | None = None,
305329
*,
306-
validate_actor_existence=True,
307-
):
330+
validate_actor_existence: bool = True,
331+
) -> str:
308332
if domain_name_or_id is None:
309333
return _find_sdk_id(
310334
identity_client.find_user,
@@ -325,8 +349,11 @@ def find_user_id_sdk(
325349

326350

327351
def _find_identity_resource(
328-
identity_client_manager, name_or_id, resource_type, **kwargs
329-
):
352+
identity_client_manager: Any,
353+
name_or_id: str,
354+
resource_type: Any,
355+
**kwargs: Any,
356+
) -> Any:
330357
"""Find a specific identity resource.
331358
332359
Using keystoneclient's manager, attempt to find a specific resource by its
@@ -365,8 +392,12 @@ def _find_identity_resource(
365392

366393

367394
def _find_sdk_id(
368-
find_command, name_or_id, *, validate_actor_existence=True, **kwargs
369-
):
395+
find_command: Callable[..., Any],
396+
name_or_id: str,
397+
*,
398+
validate_actor_existence: bool = True,
399+
**kwargs: Any,
400+
) -> str:
370401
try:
371402
resource = find_command(
372403
name_or_id=name_or_id, ignore_missing=False, **kwargs
@@ -377,10 +408,10 @@ def _find_sdk_id(
377408
if not validate_actor_existence:
378409
return name_or_id
379410
raise exceptions.CommandError from exc
380-
return resource.id
411+
return cast(str, resource.id)
381412

382413

383-
def add_user_domain_option_to_parser(parser):
414+
def add_user_domain_option_to_parser(parser: argparse.ArgumentParser) -> None:
384415
parser.add_argument(
385416
'--user-domain',
386417
metavar='<user-domain>',
@@ -392,7 +423,7 @@ def add_user_domain_option_to_parser(parser):
392423
)
393424

394425

395-
def add_group_domain_option_to_parser(parser):
426+
def add_group_domain_option_to_parser(parser: argparse.ArgumentParser) -> None:
396427
parser.add_argument(
397428
'--group-domain',
398429
metavar='<group-domain>',
@@ -404,7 +435,10 @@ def add_group_domain_option_to_parser(parser):
404435
)
405436

406437

407-
def add_project_domain_option_to_parser(parser, enhance_help=lambda _h: _h):
438+
def add_project_domain_option_to_parser(
439+
parser: argparse.ArgumentParser,
440+
enhance_help: Callable[[str], str] = lambda _h: _h,
441+
) -> None:
408442
parser.add_argument(
409443
'--project-domain',
410444
metavar='<project-domain>',
@@ -418,7 +452,7 @@ def add_project_domain_option_to_parser(parser, enhance_help=lambda _h: _h):
418452
)
419453

420454

421-
def add_role_domain_option_to_parser(parser):
455+
def add_role_domain_option_to_parser(parser: argparse.ArgumentParser) -> None:
422456
parser.add_argument(
423457
'--role-domain',
424458
metavar='<role-domain>',
@@ -430,7 +464,7 @@ def add_role_domain_option_to_parser(parser):
430464
)
431465

432466

433-
def add_inherited_option_to_parser(parser):
467+
def add_inherited_option_to_parser(parser: argparse.ArgumentParser) -> None:
434468
parser.add_argument(
435469
'--inherited',
436470
action='store_true',
@@ -441,7 +475,7 @@ def add_inherited_option_to_parser(parser):
441475
)
442476

443477

444-
def add_resource_option_to_parser(parser):
478+
def add_resource_option_to_parser(parser: argparse.ArgumentParser) -> None:
445479
immutable_group = parser.add_mutually_exclusive_group()
446480
immutable_group.add_argument(
447481
'--immutable',

openstackclient/identity/v2_0/catalog.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
"""Identity v2 Service Catalog action implementations"""
1515

16+
import argparse
17+
from collections.abc import Iterable, Sequence
1618
import logging
1719
from typing import Any
1820

@@ -28,7 +30,7 @@
2830

2931

3032
class EndpointsColumn(cliff_columns.FormattableColumn[Any]):
31-
def human_readable(self):
33+
def human_readable(self) -> str:
3234
if not self._value:
3335
return ""
3436
ret = ''
@@ -47,7 +49,9 @@ def human_readable(self):
4749
class ListCatalog(command.Lister):
4850
_description = _("List services in the service catalog")
4951

50-
def take_action(self, parsed_args):
52+
def take_action(
53+
self, parsed_args: argparse.Namespace
54+
) -> tuple[tuple[str, ...], Iterable[tuple[Any, ...]]]:
5155
# Trigger auth if it has not happened yet
5256
auth_ref = self.app.client_manager.auth_ref
5357
if not auth_ref:
@@ -75,7 +79,7 @@ def take_action(self, parsed_args):
7579
class ShowCatalog(command.ShowOne):
7680
_description = _("Display service catalog details")
7781

78-
def get_parser(self, prog_name):
82+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
7983
parser = super().get_parser(prog_name)
8084
parser.add_argument(
8185
'service',
@@ -84,7 +88,9 @@ def get_parser(self, prog_name):
8488
)
8589
return parser
8690

87-
def take_action(self, parsed_args):
91+
def take_action(
92+
self, parsed_args: argparse.Namespace
93+
) -> tuple[Sequence[str], Iterable[Any]]:
8894
# Trigger auth if it has not happened yet
8995
auth_ref = self.app.client_manager.auth_ref
9096
if not auth_ref:
@@ -108,4 +114,5 @@ def take_action(self, parsed_args):
108114
LOG.error(_('service %s not found\n'), parsed_args.service)
109115
return ((), ())
110116

111-
return zip(*sorted(data.items()))
117+
col_headers, col_data = zip(*sorted(data.items()))
118+
return col_headers, col_data

0 commit comments

Comments
 (0)