osc-lib 3.1.0__py3-none-any.whl → 4.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- osc_lib/api/api.py +67 -30
- osc_lib/api/auth.py +39 -25
- osc_lib/api/utils.py +10 -5
- osc_lib/cli/client_config.py +55 -35
- osc_lib/cli/format_columns.py +19 -17
- osc_lib/cli/identity.py +14 -3
- osc_lib/cli/pagination.py +83 -0
- osc_lib/cli/parseractions.py +116 -37
- osc_lib/clientmanager.py +49 -28
- osc_lib/command/command.py +20 -9
- osc_lib/command/timing.py +11 -1
- osc_lib/exceptions.py +13 -3
- osc_lib/logs.py +19 -9
- osc_lib/py.typed +0 -0
- osc_lib/shell.py +73 -56
- osc_lib/tests/api/fakes.py +1 -1
- osc_lib/tests/api/test_api.py +5 -5
- osc_lib/tests/api/test_utils.py +1 -1
- osc_lib/tests/cli/test_client_config.py +1 -1
- osc_lib/tests/cli/test_format_columns.py +1 -1
- osc_lib/tests/cli/test_parseractions.py +48 -100
- osc_lib/tests/command/test_timing.py +2 -2
- osc_lib/tests/fakes.py +10 -10
- osc_lib/tests/test_clientmanager.py +1 -1
- osc_lib/tests/test_logs.py +2 -2
- osc_lib/tests/test_shell.py +10 -10
- osc_lib/tests/utils/__init__.py +6 -25
- osc_lib/tests/utils/test_tags.py +22 -7
- osc_lib/tests/utils/test_utils.py +4 -14
- osc_lib/utils/__init__.py +183 -111
- osc_lib/utils/columns.py +25 -11
- osc_lib/utils/tags.py +39 -21
- {osc_lib-3.1.0.dist-info → osc_lib-4.0.0.dist-info}/AUTHORS +1 -0
- {osc_lib-3.1.0.dist-info → osc_lib-4.0.0.dist-info}/METADATA +11 -13
- osc_lib-4.0.0.dist-info/RECORD +53 -0
- {osc_lib-3.1.0.dist-info → osc_lib-4.0.0.dist-info}/WHEEL +1 -1
- osc_lib-4.0.0.dist-info/pbr.json +1 -0
- osc_lib-3.1.0.dist-info/RECORD +0 -51
- osc_lib-3.1.0.dist-info/pbr.json +0 -1
- {osc_lib-3.1.0.dist-info → osc_lib-4.0.0.dist-info}/LICENSE +0 -0
- {osc_lib-3.1.0.dist-info → osc_lib-4.0.0.dist-info}/top_level.txt +0 -0
osc_lib/logs.py
CHANGED
@@ -13,19 +13,24 @@
|
|
13
13
|
|
14
14
|
"""Application logging"""
|
15
15
|
|
16
|
+
import argparse
|
17
|
+
import collections.abc
|
16
18
|
import logging
|
17
19
|
import sys
|
20
|
+
import typing as ty
|
18
21
|
import warnings
|
19
22
|
|
23
|
+
from openstack.config import cloud_config
|
20
24
|
|
21
|
-
|
25
|
+
|
26
|
+
def get_loggers() -> dict[str, str]:
|
22
27
|
loggers = {}
|
23
28
|
for logkey in logging.Logger.manager.loggerDict.keys():
|
24
29
|
loggers[logkey] = logging.getLevelName(logging.getLogger(logkey).level)
|
25
30
|
return loggers
|
26
31
|
|
27
32
|
|
28
|
-
def log_level_from_options(options):
|
33
|
+
def log_level_from_options(options: argparse.Namespace) -> int:
|
29
34
|
# if --debug, --quiet or --verbose is not specified,
|
30
35
|
# the default logging level is warning
|
31
36
|
log_level = logging.WARNING
|
@@ -41,7 +46,7 @@ def log_level_from_options(options):
|
|
41
46
|
return log_level
|
42
47
|
|
43
48
|
|
44
|
-
def log_level_from_string(level_string):
|
49
|
+
def log_level_from_string(level_string: str) -> int:
|
45
50
|
log_level = {
|
46
51
|
'critical': logging.CRITICAL,
|
47
52
|
'error': logging.ERROR,
|
@@ -52,7 +57,7 @@ def log_level_from_string(level_string):
|
|
52
57
|
return log_level
|
53
58
|
|
54
59
|
|
55
|
-
def log_level_from_config(config):
|
60
|
+
def log_level_from_config(config: collections.abc.Mapping[str, ty.Any]) -> int:
|
56
61
|
# Check the command line option
|
57
62
|
verbose_level = config.get('verbose_level')
|
58
63
|
if config.get('debug', False):
|
@@ -70,7 +75,7 @@ def log_level_from_config(config):
|
|
70
75
|
return log_level_from_string(verbose_level)
|
71
76
|
|
72
77
|
|
73
|
-
def set_warning_filter(log_level):
|
78
|
+
def set_warning_filter(log_level: int) -> None:
|
74
79
|
if log_level == logging.ERROR:
|
75
80
|
warnings.simplefilter("ignore")
|
76
81
|
elif log_level == logging.WARNING:
|
@@ -89,7 +94,12 @@ class _FileFormatter(logging.Formatter):
|
|
89
94
|
_LOG_MESSAGE_END = '%(message)s'
|
90
95
|
_LOG_DATE_FORMAT = '%Y-%m-%d %H:%M:%S'
|
91
96
|
|
92
|
-
def __init__(
|
97
|
+
def __init__(
|
98
|
+
self,
|
99
|
+
options: ty.Optional[argparse.Namespace] = None,
|
100
|
+
config: ty.Optional[cloud_config.CloudConfig] = None,
|
101
|
+
**kwargs: ty.Any,
|
102
|
+
) -> None:
|
93
103
|
context = {}
|
94
104
|
if options:
|
95
105
|
context = {
|
@@ -114,10 +124,10 @@ class _FileFormatter(logging.Formatter):
|
|
114
124
|
logging.Formatter.__init__(self, self.fmt, self._LOG_DATE_FORMAT)
|
115
125
|
|
116
126
|
|
117
|
-
class LogConfigurator
|
127
|
+
class LogConfigurator:
|
118
128
|
_CONSOLE_MESSAGE_FORMAT = '%(message)s'
|
119
129
|
|
120
|
-
def __init__(self, options):
|
130
|
+
def __init__(self, options: argparse.Namespace) -> None:
|
121
131
|
self.root_logger = logging.getLogger('')
|
122
132
|
self.root_logger.setLevel(logging.DEBUG)
|
123
133
|
|
@@ -166,7 +176,7 @@ class LogConfigurator(object):
|
|
166
176
|
stevedore_log.setLevel(logging.ERROR)
|
167
177
|
iso8601_log.setLevel(logging.ERROR)
|
168
178
|
|
169
|
-
def configure(self, cloud_config):
|
179
|
+
def configure(self, cloud_config: cloud_config.CloudConfig) -> None:
|
170
180
|
log_level = log_level_from_config(cloud_config.config)
|
171
181
|
set_warning_filter(log_level)
|
172
182
|
self.dump_trace = cloud_config.config.get('debug', self.dump_trace)
|
osc_lib/py.typed
ADDED
File without changes
|
osc_lib/shell.py
CHANGED
@@ -20,12 +20,15 @@ import getpass
|
|
20
20
|
import logging
|
21
21
|
import sys
|
22
22
|
import traceback
|
23
|
+
import typing as ty
|
23
24
|
|
25
|
+
from cliff import _argparse
|
24
26
|
from cliff import app
|
25
27
|
from cliff import command
|
26
28
|
from cliff import commandmanager
|
27
29
|
from cliff import complete
|
28
30
|
from cliff import help
|
31
|
+
from cliff import interactive
|
29
32
|
from oslo_utils import importutils
|
30
33
|
from oslo_utils import strutils
|
31
34
|
|
@@ -45,7 +48,7 @@ DEFAULT_DOMAIN = 'default'
|
|
45
48
|
DEFAULT_INTERFACE = 'public'
|
46
49
|
|
47
50
|
|
48
|
-
def prompt_for_password(prompt=None):
|
51
|
+
def prompt_for_password(prompt: ty.Optional[str] = None) -> str:
|
49
52
|
"""Prompt user for a password
|
50
53
|
|
51
54
|
Prompt for a password if stdin is a tty.
|
@@ -76,26 +79,30 @@ def prompt_for_password(prompt=None):
|
|
76
79
|
class OpenStackShell(app.App):
|
77
80
|
CONSOLE_MESSAGE_FORMAT = '%(levelname)s: %(name)s %(message)s'
|
78
81
|
|
82
|
+
client_manager: clientmanager.ClientManager
|
83
|
+
|
79
84
|
log = logging.getLogger(__name__)
|
80
|
-
timing_data = []
|
85
|
+
timing_data: list[ty.Any] = []
|
81
86
|
|
82
87
|
def __init__(
|
83
88
|
self,
|
84
|
-
description=None,
|
85
|
-
version=None,
|
86
|
-
command_manager=None,
|
87
|
-
stdin=None,
|
88
|
-
stdout=None,
|
89
|
-
stderr=None,
|
90
|
-
interactive_app_factory
|
91
|
-
|
92
|
-
|
89
|
+
description: ty.Optional[str] = None,
|
90
|
+
version: ty.Optional[str] = None,
|
91
|
+
command_manager: ty.Optional[commandmanager.CommandManager] = None,
|
92
|
+
stdin: ty.Optional[ty.TextIO] = None,
|
93
|
+
stdout: ty.Optional[ty.TextIO] = None,
|
94
|
+
stderr: ty.Optional[ty.TextIO] = None,
|
95
|
+
interactive_app_factory: ty.Optional[
|
96
|
+
type['interactive.InteractiveApp']
|
97
|
+
] = None,
|
98
|
+
deferred_help: bool = False,
|
99
|
+
) -> None:
|
93
100
|
# Patch command.Command to add a default auth_required = True
|
94
|
-
command.Command
|
101
|
+
setattr(command.Command, 'auth_required', True)
|
95
102
|
|
96
103
|
# Some commands do not need authentication
|
97
|
-
help.HelpCommand
|
98
|
-
complete.CompleteCommand
|
104
|
+
setattr(help.HelpCommand, 'auth_required', False)
|
105
|
+
setattr(complete.CompleteCommand, 'auth_required', False)
|
99
106
|
|
100
107
|
# Slight change to the meaning of --debug
|
101
108
|
self.DEFAULT_DEBUG_VALUE = None
|
@@ -107,7 +114,7 @@ class OpenStackShell(app.App):
|
|
107
114
|
else:
|
108
115
|
cm = command_manager
|
109
116
|
|
110
|
-
super(
|
117
|
+
super().__init__(
|
111
118
|
description=__doc__.strip(),
|
112
119
|
version=version,
|
113
120
|
command_manager=cm,
|
@@ -120,21 +127,20 @@ class OpenStackShell(app.App):
|
|
120
127
|
# Set in subclasses
|
121
128
|
self.api_version = None
|
122
129
|
|
123
|
-
self.
|
124
|
-
self.command_options = None
|
130
|
+
self.command_options: list[str] = []
|
125
131
|
|
126
132
|
self.do_profile = False
|
127
133
|
|
128
|
-
def configure_logging(self):
|
134
|
+
def configure_logging(self) -> None:
|
129
135
|
"""Configure logging for the app."""
|
130
136
|
self.log_configurator = logs.LogConfigurator(self.options)
|
131
137
|
self.dump_stack_trace = self.log_configurator.dump_trace
|
132
138
|
|
133
|
-
def run(self, argv):
|
139
|
+
def run(self, argv: list[str]) -> int:
|
134
140
|
ret_val = 1
|
135
141
|
self.command_options = argv
|
136
142
|
try:
|
137
|
-
ret_val = super(
|
143
|
+
ret_val = super().run(argv)
|
138
144
|
return ret_val
|
139
145
|
except Exception as e:
|
140
146
|
if not logging.getLogger('').handlers:
|
@@ -147,14 +153,14 @@ class OpenStackShell(app.App):
|
|
147
153
|
return ret_val
|
148
154
|
|
149
155
|
finally:
|
150
|
-
self.log.
|
156
|
+
self.log.debug("END return value: %s", ret_val)
|
151
157
|
|
152
|
-
def init_profile(self):
|
158
|
+
def init_profile(self) -> None:
|
153
159
|
self.do_profile = osprofiler_profiler and self.options.profile
|
154
160
|
if self.do_profile:
|
155
161
|
osprofiler_profiler.init(self.options.profile)
|
156
162
|
|
157
|
-
def close_profile(self):
|
163
|
+
def close_profile(self) -> None:
|
158
164
|
if self.do_profile:
|
159
165
|
profiler = osprofiler_profiler.get()
|
160
166
|
trace_id = profiler.get_base_id()
|
@@ -165,35 +171,41 @@ class OpenStackShell(app.App):
|
|
165
171
|
# printed. In fact we can define custom log level here with value
|
166
172
|
# bigger than most big default one (CRITICAL) or something like
|
167
173
|
# that (PROFILE = 60 for instance), but not sure we need it here.
|
168
|
-
self.log.warning("Trace ID:
|
174
|
+
self.log.warning(f"Trace ID: {trace_id}")
|
169
175
|
self.log.warning(
|
170
|
-
"Short trace ID "
|
171
|
-
"for OpenTracing-based drivers: %s" % short_id
|
176
|
+
f"Short trace ID for OpenTracing-based drivers: {short_id}"
|
172
177
|
)
|
173
178
|
self.log.warning(
|
174
179
|
"Display trace data with command:\n"
|
175
|
-
"osprofiler trace show --html
|
180
|
+
f"osprofiler trace show --html {trace_id} "
|
176
181
|
)
|
177
182
|
|
178
|
-
def run_subcommand(self, argv):
|
183
|
+
def run_subcommand(self, argv: list[str]) -> int:
|
179
184
|
self.init_profile()
|
180
185
|
try:
|
181
|
-
ret_value = super(
|
186
|
+
ret_value = super().run_subcommand(argv)
|
182
187
|
finally:
|
183
188
|
self.close_profile()
|
184
189
|
return ret_value
|
185
190
|
|
186
|
-
def interact(self):
|
191
|
+
def interact(self) -> None:
|
187
192
|
self.init_profile()
|
188
193
|
try:
|
189
|
-
ret_value = super(
|
194
|
+
ret_value = super().interact()
|
190
195
|
finally:
|
191
196
|
self.close_profile()
|
192
197
|
return ret_value
|
193
198
|
|
194
|
-
def build_option_parser(
|
195
|
-
|
196
|
-
|
199
|
+
def build_option_parser(
|
200
|
+
self,
|
201
|
+
description: ty.Optional[str],
|
202
|
+
version: ty.Optional[str],
|
203
|
+
argparse_kwargs: ty.Optional[dict[str, ty.Any]] = None,
|
204
|
+
) -> _argparse.ArgumentParser:
|
205
|
+
parser = super().build_option_parser(
|
206
|
+
description,
|
207
|
+
version,
|
208
|
+
argparse_kwargs,
|
197
209
|
)
|
198
210
|
|
199
211
|
# service token auth argument
|
@@ -251,9 +263,7 @@ class OpenStackShell(app.App):
|
|
251
263
|
metavar='<auth-domain>',
|
252
264
|
dest='default_domain',
|
253
265
|
default=utils.env('OS_DEFAULT_DOMAIN', default=DEFAULT_DOMAIN),
|
254
|
-
help=_(
|
255
|
-
'Default domain ID, default=%s. ' '(Env: OS_DEFAULT_DOMAIN)'
|
256
|
-
)
|
266
|
+
help=_('Default domain ID, default=%s. (Env: OS_DEFAULT_DOMAIN)')
|
257
267
|
% DEFAULT_DOMAIN,
|
258
268
|
)
|
259
269
|
parser.add_argument(
|
@@ -350,7 +360,6 @@ class OpenStackShell(app.App):
|
|
350
360
|
)
|
351
361
|
|
352
362
|
return parser
|
353
|
-
# return clientmanager.build_plugin_option_parser(parser)
|
354
363
|
|
355
364
|
"""
|
356
365
|
Break up initialize_app() so that overriding it in a subclass does not
|
@@ -366,7 +375,7 @@ class OpenStackShell(app.App):
|
|
366
375
|
|
367
376
|
"""
|
368
377
|
|
369
|
-
def _final_defaults(self):
|
378
|
+
def _final_defaults(self) -> None:
|
370
379
|
# Set the default plugin to None
|
371
380
|
# NOTE(dtroyer): This is here to set up for setting it to a default
|
372
381
|
# in the calling CLI
|
@@ -393,21 +402,21 @@ class OpenStackShell(app.App):
|
|
393
402
|
# Save default domain
|
394
403
|
self.default_domain = self.options.default_domain
|
395
404
|
|
396
|
-
def _load_plugins(self):
|
405
|
+
def _load_plugins(self) -> None:
|
397
406
|
"""Load plugins via stevedore
|
398
407
|
|
399
408
|
osc-lib has no opinion on what plugins should be loaded
|
400
409
|
"""
|
401
410
|
pass
|
402
411
|
|
403
|
-
def _load_commands(self):
|
412
|
+
def _load_commands(self) -> None:
|
404
413
|
"""Load commands via cliff/stevedore
|
405
414
|
|
406
415
|
osc-lib has no opinion on what commands should be loaded
|
407
416
|
"""
|
408
417
|
pass
|
409
418
|
|
410
|
-
def initialize_app(self, argv):
|
419
|
+
def initialize_app(self, argv: list[str]) -> None:
|
411
420
|
"""Global app init bits:
|
412
421
|
|
413
422
|
* set up API versions
|
@@ -416,10 +425,12 @@ class OpenStackShell(app.App):
|
|
416
425
|
"""
|
417
426
|
|
418
427
|
# Parent __init__ parses argv into self.options
|
419
|
-
super(
|
428
|
+
super().initialize_app(argv)
|
420
429
|
self.log.info(
|
421
430
|
"START with options: %s",
|
422
|
-
strutils.mask_password(" ".join(self.command_options))
|
431
|
+
strutils.mask_password(" ".join(self.command_options))
|
432
|
+
if self.command_options
|
433
|
+
else "",
|
423
434
|
)
|
424
435
|
self.log.debug("options: %s", strutils.mask_password(self.options))
|
425
436
|
|
@@ -435,7 +446,7 @@ class OpenStackShell(app.App):
|
|
435
446
|
'auth_type': self._auth_type,
|
436
447
|
},
|
437
448
|
)
|
438
|
-
except
|
449
|
+
except OSError as e:
|
439
450
|
self.log.critical("Could not read clouds.yaml configuration file")
|
440
451
|
self.print_help_if_requested()
|
441
452
|
raise e
|
@@ -476,23 +487,23 @@ class OpenStackShell(app.App):
|
|
476
487
|
pw_func=prompt_for_password,
|
477
488
|
)
|
478
489
|
|
479
|
-
def prepare_to_run_command(self, cmd):
|
490
|
+
def prepare_to_run_command(self, cmd: 'command.Command') -> None:
|
480
491
|
"""Set up auth and API versions"""
|
481
|
-
self.log.
|
492
|
+
self.log.debug(
|
482
493
|
'command: %s -> %s.%s (auth=%s)',
|
483
494
|
getattr(cmd, 'cmd_name', '<none>'),
|
484
495
|
cmd.__class__.__module__,
|
485
496
|
cmd.__class__.__name__,
|
486
|
-
cmd
|
497
|
+
getattr(cmd, 'auth_required', None),
|
487
498
|
)
|
488
499
|
|
489
500
|
# NOTE(dtroyer): If auth is not required for a command, skip
|
490
501
|
# get_one()'s validation to avoid loading plugins
|
491
|
-
validate = cmd
|
502
|
+
validate = getattr(cmd, 'auth_required', False)
|
492
503
|
|
493
504
|
# NOTE(dtroyer): Save the auth required state of the _current_ command
|
494
505
|
# in the ClientManager
|
495
|
-
self.client_manager._auth_required =
|
506
|
+
self.client_manager._auth_required = validate
|
496
507
|
|
497
508
|
# Validate auth options
|
498
509
|
self.cloud = self.cloud_config.get_one(
|
@@ -506,26 +517,31 @@ class OpenStackShell(app.App):
|
|
506
517
|
# Push the updated args into ClientManager
|
507
518
|
self.client_manager._cli_options = self.cloud
|
508
519
|
|
509
|
-
if
|
520
|
+
if validate:
|
510
521
|
self.client_manager.setup_auth()
|
511
522
|
if hasattr(cmd, 'required_scope') and cmd.required_scope:
|
512
523
|
# let the command decide whether we need a scoped token
|
513
524
|
self.client_manager.validate_scope()
|
514
525
|
# Trigger the Identity client to initialize
|
515
|
-
self.client_manager.session.auth.auth_ref = (
|
526
|
+
self.client_manager.session.auth.auth_ref = ( # type: ignore
|
516
527
|
self.client_manager.auth_ref
|
517
528
|
)
|
518
529
|
return
|
519
530
|
|
520
|
-
def clean_up(
|
531
|
+
def clean_up(
|
532
|
+
self,
|
533
|
+
cmd: 'command.Command',
|
534
|
+
result: int,
|
535
|
+
err: ty.Optional[BaseException],
|
536
|
+
) -> None:
|
521
537
|
self.log.debug('clean_up %s: %s', cmd.__class__.__name__, err or '')
|
522
538
|
|
523
539
|
# Close SDK connection if available to have proper cleanup there
|
524
|
-
if
|
540
|
+
if getattr(self.client_manager, "sdk_connection", None) is not None:
|
525
541
|
self.client_manager.sdk_connection.close()
|
526
542
|
|
527
543
|
# Close session if available
|
528
|
-
if
|
544
|
+
if getattr(self.client_manager.session, "session", None) is not None:
|
529
545
|
self.client_manager.session.session.close()
|
530
546
|
|
531
547
|
# Process collected timing data
|
@@ -544,6 +560,7 @@ class OpenStackShell(app.App):
|
|
544
560
|
# Check the formatter used in the actual command
|
545
561
|
if (
|
546
562
|
hasattr(cmd, 'formatter')
|
563
|
+
and hasattr(cmd, '_formatter_plugins')
|
547
564
|
and cmd.formatter != cmd._formatter_plugins['table'].obj
|
548
565
|
):
|
549
566
|
format = 'csv'
|
@@ -553,7 +570,7 @@ class OpenStackShell(app.App):
|
|
553
570
|
tcmd.run(targs)
|
554
571
|
|
555
572
|
|
556
|
-
def main(argv=None):
|
573
|
+
def main(argv: ty.Optional[list[str]] = None) -> int:
|
557
574
|
if argv is None:
|
558
575
|
argv = sys.argv[1:]
|
559
576
|
return OpenStackShell().run(argv)
|
osc_lib/tests/api/fakes.py
CHANGED
osc_lib/tests/api/test_api.py
CHANGED
@@ -23,7 +23,7 @@ from osc_lib.tests.api import fakes as api_fakes
|
|
23
23
|
|
24
24
|
class TestBaseAPIDefault(api_fakes.TestSession):
|
25
25
|
def setUp(self):
|
26
|
-
super(
|
26
|
+
super().setUp()
|
27
27
|
self.api = api.BaseAPI()
|
28
28
|
|
29
29
|
def test_baseapi_request_no_url(self):
|
@@ -186,7 +186,7 @@ class TestBaseAPIEndpointArg(api_fakes.TestSession):
|
|
186
186
|
|
187
187
|
class TestBaseAPIArgs(api_fakes.TestSession):
|
188
188
|
def setUp(self):
|
189
|
-
super(
|
189
|
+
super().setUp()
|
190
190
|
self.api = api.BaseAPI(
|
191
191
|
session=self.sess,
|
192
192
|
endpoint=self.BASE_URL,
|
@@ -220,7 +220,7 @@ class TestBaseAPIArgs(api_fakes.TestSession):
|
|
220
220
|
|
221
221
|
class TestBaseAPICreate(api_fakes.TestSession):
|
222
222
|
def setUp(self):
|
223
|
-
super(
|
223
|
+
super().setUp()
|
224
224
|
self.api = api.BaseAPI(
|
225
225
|
session=self.sess,
|
226
226
|
endpoint=self.BASE_URL,
|
@@ -258,7 +258,7 @@ class TestBaseAPICreate(api_fakes.TestSession):
|
|
258
258
|
|
259
259
|
class TestBaseAPIFind(api_fakes.TestSession):
|
260
260
|
def setUp(self):
|
261
|
-
super(
|
261
|
+
super().setUp()
|
262
262
|
self.api = api.BaseAPI(
|
263
263
|
session=self.sess,
|
264
264
|
endpoint=self.BASE_URL,
|
@@ -452,7 +452,7 @@ class TestBaseAPIFind(api_fakes.TestSession):
|
|
452
452
|
|
453
453
|
class TestBaseAPIList(api_fakes.TestSession):
|
454
454
|
def setUp(self):
|
455
|
-
super(
|
455
|
+
super().setUp()
|
456
456
|
self.api = api.BaseAPI(
|
457
457
|
session=self.sess,
|
458
458
|
endpoint=self.BASE_URL,
|
osc_lib/tests/api/test_utils.py
CHANGED
@@ -104,7 +104,7 @@ class TestListDictColumn(utils.TestCase):
|
|
104
104
|
# OrderedDict is a subclass of dict and would inadvertently pass
|
105
105
|
self.assertEqual(type(col.machine_readable()), list) # noqa: H212
|
106
106
|
for x in col.machine_readable():
|
107
|
-
self.assertEqual(type(x), dict) # noqa:
|
107
|
+
self.assertEqual(type(x), dict) # noqa: H211
|
108
108
|
|
109
109
|
|
110
110
|
class TestSizeColumn(utils.TestCase):
|