Skip to content

Commit faa4d51

Browse files
committed
typing: Add hints to network commands
Change-Id: Ie3d3745461c361befd0b61bc0893bd39814035a0 Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
1 parent 41fb914 commit faa4d51

42 files changed

Lines changed: 1226 additions & 631 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

openstackclient/network/client.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
# License for the specific language governing permissions and limitations
1111
# under the License.
1212

13+
import argparse
1314
import logging
15+
from typing import Any
1416

1517
from osc_lib import utils
1618

@@ -26,7 +28,7 @@
2628
API_EXTENSIONS = ('fwaas', 'taas')
2729

2830

29-
def make_client(instance):
31+
def make_client(instance: Any) -> Any:
3032
"""Returns a network proxy"""
3133
LOG.debug(
3234
'Network client initialized using OpenStack SDK: %s',
@@ -35,7 +37,9 @@ def make_client(instance):
3537
return instance.sdk_connection.network
3638

3739

38-
def build_option_parser(parser):
40+
def build_option_parser(
41+
parser: argparse.ArgumentParser,
42+
) -> argparse.ArgumentParser:
3943
"""Hook to add global options"""
4044
parser.add_argument(
4145
'--os-network-api-version',

openstackclient/network/common.py

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@
1212
#
1313

1414
import abc
15+
import argparse
16+
from collections.abc import Generator
1517
import contextlib
1618
import logging
1719
from typing import Any
1820

19-
from cliff import _argparse
2021
import openstack.exceptions
2122
from osc_lib.cli import parseractions
2223
from osc_lib import exceptions
@@ -43,7 +44,9 @@
4344

4445

4546
@contextlib.contextmanager
46-
def check_missing_extension_if_error(client_manager, attrs):
47+
def check_missing_extension_if_error(
48+
client_manager: Any, attrs: dict[str, Any]
49+
) -> Generator[None, None, None]:
4750
# If specified option requires extension, then try to
4851
# find out if it exists. If it does not exist,
4952
# then an exception with the appropriate message
@@ -68,7 +71,7 @@ class NetDetectionMixin(command.Command, metaclass=abc.ABCMeta):
6871
"""
6972

7073
@property
71-
def _network_type(self):
74+
def _network_type(self) -> str | None:
7275
"""Discover whether the running cloud is using neutron or nova-network.
7376
7477
:return:
@@ -96,31 +99,31 @@ def _network_type(self):
9699
return self._net_type
97100

98101
@property
99-
def is_neutron(self):
102+
def is_neutron(self) -> bool:
100103
return self._network_type is _NET_TYPE_NEUTRON
101104

102105
@property
103-
def is_nova_network(self):
106+
def is_nova_network(self) -> bool:
104107
return self._network_type is _NET_TYPE_COMPUTE
105108

106109
@property
107-
def is_docs_build(self):
110+
def is_docs_build(self) -> bool:
108111
return self._network_type is None
109112

110-
def enhance_help_neutron(self, _help):
113+
def enhance_help_neutron(self, _help: str) -> str:
111114
if self.is_docs_build:
112115
# Why can't we say 'neutron'?
113116
return _QUALIFIER_FMT % (_help, _("Network version 2 only"))
114117
return _help
115118

116-
def enhance_help_nova_network(self, _help):
119+
def enhance_help_nova_network(self, _help: str) -> str:
117120
if self.is_docs_build:
118121
# Why can't we say 'nova-network'?
119122
return _QUALIFIER_FMT % (_help, _("Compute version 2 only"))
120123
return _help
121124

122125
@staticmethod
123-
def split_help(network_help, compute_help):
126+
def split_help(network_help: str, compute_help: str) -> str:
124127
return (
125128
"*{network_qualifier}:*\n {network_help}\n\n"
126129
"*{compute_qualifier}:*\n {compute_help}".format(
@@ -133,7 +136,7 @@ def split_help(network_help, compute_help):
133136
)
134137
)
135138

136-
def get_parser(self, prog_name: str) -> _argparse.ArgumentParser:
139+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
137140
LOG.debug('get_parser(%s)', prog_name)
138141
parser = super().get_parser(prog_name)
139142
parser = self.update_parser_common(parser)
@@ -145,19 +148,25 @@ def get_parser(self, prog_name: str) -> _argparse.ArgumentParser:
145148
parser = self.update_parser_compute(parser)
146149
return parser
147150

148-
def update_parser_common(self, parser):
151+
def update_parser_common(
152+
self, parser: argparse.ArgumentParser
153+
) -> argparse.ArgumentParser:
149154
"""Default is no updates to parser."""
150155
return parser
151156

152-
def update_parser_network(self, parser):
157+
def update_parser_network(
158+
self, parser: argparse.ArgumentParser
159+
) -> argparse.ArgumentParser:
153160
"""Default is no updates to parser."""
154161
return parser
155162

156-
def update_parser_compute(self, parser):
163+
def update_parser_compute(
164+
self, parser: argparse.ArgumentParser
165+
) -> argparse.ArgumentParser:
157166
"""Default is no updates to parser."""
158167
return parser
159168

160-
def take_action(self, parsed_args):
169+
def take_action(self, parsed_args: argparse.Namespace) -> Any:
161170
if self.is_neutron:
162171
return self.take_action_network(
163172
self.app.client_manager.network,
@@ -169,11 +178,15 @@ def take_action(self, parsed_args):
169178
parsed_args,
170179
)
171180

172-
def take_action_network(self, client, parsed_args):
181+
def take_action_network(
182+
self, client: Any, parsed_args: argparse.Namespace
183+
) -> Any:
173184
"""Override to do something useful."""
174185
pass
175186

176-
def take_action_compute(self, client, parsed_args):
187+
def take_action_compute(
188+
self, client: Any, parsed_args: argparse.Namespace
189+
) -> Any:
177190
"""Override to do something useful."""
178191
pass
179192

@@ -204,7 +217,7 @@ class NetworkAndComputeDelete(NetworkAndComputeCommand, metaclass=abc.ABCMeta):
204217

205218
resource: str
206219

207-
def take_action(self, parsed_args):
220+
def take_action(self, parsed_args: argparse.Namespace) -> None:
208221
ret = 0
209222
resources = getattr(parsed_args, self.resource, [])
210223

@@ -267,7 +280,7 @@ class NetworkAndComputeShowOne(
267280
arguments.
268281
"""
269282

270-
def take_action(self, parsed_args):
283+
def take_action(self, parsed_args: argparse.Namespace) -> Any:
271284
try:
272285
if self.app.client_manager.is_network_endpoint_enabled():
273286
return self.take_action_network(
@@ -300,7 +313,7 @@ class NeutronCommandWithExtraArgs(command.Command):
300313
'str': str,
301314
}
302315

303-
def _get_property_converter(self, _property):
316+
def _get_property_converter(self, _property: dict[str, Any]) -> Any:
304317
if 'type' in _property:
305318
converter = self._allowed_types_dict.get(_property['type'])
306319
else:
@@ -316,15 +329,17 @@ def _get_property_converter(self, _property):
316329
)
317330
return converter
318331

319-
def _parse_extra_properties(self, extra_properties):
332+
def _parse_extra_properties(
333+
self, extra_properties: list[dict[str, Any]] | None
334+
) -> dict[str, Any]:
320335
result: dict[str, Any] = {}
321336
if extra_properties:
322337
for _property in extra_properties:
323338
converter = self._get_property_converter(_property)
324339
result[_property['name']] = converter(_property['value'])
325340
return result
326341

327-
def get_parser(self, prog_name):
342+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
328343
parser = super().get_parser(prog_name)
329344
parser.add_argument(
330345
'--extra-property',
@@ -349,7 +364,9 @@ def get_parser(self, prog_name):
349364

350365

351366
class NeutronUnsetCommandWithExtraArgs(NeutronCommandWithExtraArgs):
352-
def _parse_extra_properties(self, extra_properties):
367+
def _parse_extra_properties(
368+
self, extra_properties: list[dict[str, Any]] | None
369+
) -> dict[str, Any]:
353370
result: dict[str, Any] = {}
354371
if extra_properties:
355372
for _property in extra_properties:

openstackclient/network/utils.py

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,18 @@
1111
# under the License.
1212
#
1313

14+
from collections.abc import Iterable, Sequence
15+
from typing import Any, cast
16+
1417
from osc_lib import exceptions
1518

1619
from openstackclient.i18n import _
1720

1821

1922
# Transform compute security group rule for display.
20-
def transform_compute_security_group_rule(sg_rule):
23+
def transform_compute_security_group_rule(
24+
sg_rule: dict[str, Any],
25+
) -> dict[str, Any]:
2126
info = {}
2227
info.update(sg_rule)
2328
from_port = info.pop('from_port')
@@ -45,14 +50,14 @@ def transform_compute_security_group_rule(sg_rule):
4550
return info
4651

4752

48-
def str2bool(strbool):
53+
def str2bool(strbool: str | None) -> bool | None:
4954
if strbool is None:
5055
return None
5156
return strbool.lower() == 'true'
5257

5358

54-
def str2list(strlist):
55-
result = []
59+
def str2list(strlist: str | None) -> list[str]:
60+
result: list[str] = []
5661
if strlist:
5762
result = strlist.split(';')
5863
return result
@@ -83,12 +88,15 @@ def str2dict(strdict: str) -> dict[str, str]:
8388
return result
8489

8590

86-
def format_security_group_rule_show(obj):
91+
def format_security_group_rule_show(
92+
obj: dict[str, Any],
93+
) -> tuple[Sequence[str], Iterable[Any]]:
8794
data = transform_compute_security_group_rule(obj)
88-
return zip(*sorted(data.items()))
95+
col_headers, col_data = zip(*sorted(data.items()))
96+
return col_headers, col_data
8997

9098

91-
def format_network_port_range(rule):
99+
def format_network_port_range(rule: dict[str, Any]) -> str:
92100
# Display port range or ICMP type and code. For example:
93101
# - ICMP type: 'type=3'
94102
# - ICMP type and code: 'type=3:code=0'
@@ -114,8 +122,8 @@ def format_network_port_range(rule):
114122
return port_range
115123

116124

117-
def format_remote_ip_prefix(rule):
118-
remote_ip_prefix = rule['remote_ip_prefix']
125+
def format_remote_ip_prefix(rule: dict[str, Any]) -> str | None:
126+
remote_ip_prefix = cast(str | None, rule['remote_ip_prefix'])
119127
if remote_ip_prefix is None:
120128
ethertype = rule['ether_type']
121129
if ethertype == 'IPv4':
@@ -125,15 +133,15 @@ def format_remote_ip_prefix(rule):
125133
return remote_ip_prefix
126134

127135

128-
def convert_ipvx_case(string):
136+
def convert_ipvx_case(string: str) -> str:
129137
if string.lower() == 'ipv4':
130138
return 'IPv4'
131139
if string.lower() == 'ipv6':
132140
return 'IPv6'
133141
return string
134142

135143

136-
def is_icmp_protocol(protocol):
144+
def is_icmp_protocol(protocol: str | None) -> bool:
137145
# NOTE(rtheis): Neutron has deprecated protocol icmpv6.
138146
# However, while the OSC CLI doesn't document the protocol,
139147
# the code must still handle it. In addition, handle both
@@ -144,12 +152,14 @@ def is_icmp_protocol(protocol):
144152
return False
145153

146154

147-
def convert_to_lowercase(string):
155+
def convert_to_lowercase(string: str) -> str:
148156
return string.lower()
149157

150158

151-
def get_protocol(parsed_args, default_protocol='any'):
152-
protocol = default_protocol
159+
def get_protocol(
160+
parsed_args: Any, default_protocol: str = 'any'
161+
) -> str | None:
162+
protocol: str | None = default_protocol
153163
if parsed_args.protocol is not None:
154164
protocol = parsed_args.protocol
155165
if hasattr(parsed_args, "proto") and parsed_args.proto is not None:
@@ -159,7 +169,7 @@ def get_protocol(parsed_args, default_protocol='any'):
159169
return protocol
160170

161171

162-
def get_ethertype(parsed_args, protocol):
172+
def get_ethertype(parsed_args: Any, protocol: str | None) -> str:
163173
ethertype = 'IPv4'
164174
if parsed_args.ethertype is not None:
165175
ethertype = parsed_args.ethertype
@@ -168,7 +178,7 @@ def get_ethertype(parsed_args, protocol):
168178
return ethertype
169179

170180

171-
def is_ipv6_protocol(protocol):
181+
def is_ipv6_protocol(protocol: str | None) -> bool:
172182
# NOTE(rtheis): Neutron has deprecated protocol icmpv6.
173183
# However, while the OSC CLI doesn't document the protocol,
174184
# the code must still handle it. In addition, handle both

0 commit comments

Comments
 (0)