osc-lib 3.1.0__tar.gz → 3.2.0__tar.gz

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.
Files changed (125) hide show
  1. {osc-lib-3.1.0 → osc-lib-3.2.0}/.coveragerc +1 -0
  2. {osc-lib-3.1.0 → osc-lib-3.2.0}/.pre-commit-config.yaml +11 -14
  3. {osc-lib-3.1.0 → osc-lib-3.2.0}/AUTHORS +1 -0
  4. {osc-lib-3.1.0 → osc-lib-3.2.0}/ChangeLog +11 -0
  5. {osc-lib-3.1.0 → osc-lib-3.2.0}/PKG-INFO +1 -1
  6. {osc-lib-3.1.0 → osc-lib-3.2.0}/doc/source/conf.py +0 -1
  7. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/api/api.py +5 -4
  8. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/api/auth.py +3 -4
  9. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/cli/client_config.py +10 -9
  10. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/cli/parseractions.py +20 -20
  11. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/clientmanager.py +4 -4
  12. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/command/command.py +2 -2
  13. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/exceptions.py +1 -1
  14. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/logs.py +1 -1
  15. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/shell.py +12 -15
  16. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/api/fakes.py +1 -1
  17. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/api/test_api.py +5 -5
  18. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/api/test_utils.py +1 -1
  19. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/cli/test_client_config.py +1 -1
  20. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/cli/test_format_columns.py +1 -1
  21. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/cli/test_parseractions.py +48 -100
  22. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/command/test_timing.py +2 -2
  23. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/fakes.py +10 -10
  24. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/test_clientmanager.py +1 -1
  25. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/test_logs.py +2 -2
  26. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/test_shell.py +6 -6
  27. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/utils/__init__.py +7 -7
  28. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/utils/test_utils.py +3 -3
  29. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/utils/__init__.py +4 -4
  30. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/utils/columns.py +11 -8
  31. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib.egg-info/PKG-INFO +1 -1
  32. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib.egg-info/SOURCES.txt +2 -0
  33. osc-lib-3.2.0/osc_lib.egg-info/pbr.json +1 -0
  34. osc-lib-3.2.0/pyproject.toml +9 -0
  35. osc-lib-3.2.0/releasenotes/source/2024.2.rst +6 -0
  36. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/conf.py +0 -1
  37. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/index.rst +1 -0
  38. {osc-lib-3.1.0 → osc-lib-3.2.0}/tox.ini +5 -12
  39. osc-lib-3.1.0/osc_lib.egg-info/pbr.json +0 -1
  40. {osc-lib-3.1.0 → osc-lib-3.2.0}/.git-ignore-blame-revs +0 -0
  41. {osc-lib-3.1.0 → osc-lib-3.2.0}/.mailmap +0 -0
  42. {osc-lib-3.1.0 → osc-lib-3.2.0}/.stestr.conf +0 -0
  43. {osc-lib-3.1.0 → osc-lib-3.2.0}/.zuul.yaml +0 -0
  44. {osc-lib-3.1.0 → osc-lib-3.2.0}/HACKING.rst +0 -0
  45. {osc-lib-3.1.0 → osc-lib-3.2.0}/LICENSE +0 -0
  46. {osc-lib-3.1.0 → osc-lib-3.2.0}/README.rst +0 -0
  47. {osc-lib-3.1.0 → osc-lib-3.2.0}/doc/Makefile +0 -0
  48. {osc-lib-3.1.0 → osc-lib-3.2.0}/doc/ext/__init__.py +0 -0
  49. {osc-lib-3.1.0 → osc-lib-3.2.0}/doc/ext/apidoc.py +0 -0
  50. {osc-lib-3.1.0 → osc-lib-3.2.0}/doc/requirements.txt +0 -0
  51. {osc-lib-3.1.0 → osc-lib-3.2.0}/doc/source/contributor/index.rst +0 -0
  52. {osc-lib-3.1.0 → osc-lib-3.2.0}/doc/source/index.rst +0 -0
  53. {osc-lib-3.1.0 → osc-lib-3.2.0}/doc/source/reference/index.rst +0 -0
  54. {osc-lib-3.1.0 → osc-lib-3.2.0}/doc/source/user/change_log.rst +0 -0
  55. {osc-lib-3.1.0 → osc-lib-3.2.0}/doc/source/user/index.rst +0 -0
  56. {osc-lib-3.1.0 → osc-lib-3.2.0}/doc/source/user/transition.rst +0 -0
  57. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/__init__.py +0 -0
  58. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/api/__init__.py +0 -0
  59. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/api/utils.py +0 -0
  60. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/cli/__init__.py +0 -0
  61. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/cli/format_columns.py +0 -0
  62. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/cli/identity.py +0 -0
  63. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/command/__init__.py +0 -0
  64. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/command/commandmanager.py +0 -0
  65. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/command/timing.py +0 -0
  66. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/i18n.py +0 -0
  67. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/__init__.py +0 -0
  68. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/api/__init__.py +0 -0
  69. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/cli/__init__.py +0 -0
  70. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/cli/test_identity.py +0 -0
  71. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/command/__init__.py +0 -0
  72. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/command/test_command.py +0 -0
  73. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/utils/test_columns.py +0 -0
  74. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/tests/utils/test_tags.py +0 -0
  75. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/utils/tags.py +0 -0
  76. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib/version.py +0 -0
  77. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib.egg-info/dependency_links.txt +0 -0
  78. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib.egg-info/not-zip-safe +0 -0
  79. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib.egg-info/requires.txt +0 -0
  80. {osc-lib-3.1.0 → osc-lib-3.2.0}/osc_lib.egg-info/top_level.txt +0 -0
  81. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/.placeholder +0 -0
  82. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/1.0-summary-47dcce446d6a512b.yaml +0 -0
  83. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/add-KeyValueAppendAction-class-f830e71152d6b91e.yaml +0 -0
  84. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/add-MultiKeyValueCommaAction-class-01dd254a287d70d2.yaml +0 -0
  85. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/add-size-column-5424c40af74688df.yaml +0 -0
  86. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/add_sdk_utils-d0c338eba682f2c8.yaml +0 -0
  87. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/arg-precedence-1ba9fd6929650830.yaml +0 -0
  88. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/auth-type-none-d96760912605f822.yaml +0 -0
  89. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/bug-1558690-1528b637f2c0a449.yaml +0 -0
  90. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/bug-1630822-mask-password-on-debug-20dcdf1c54e84fa1.yaml +0 -0
  91. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/bug-2004898-686577a07e791051.yaml +0 -0
  92. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/bug-2006480-436489d39643e76c.yaml +0 -0
  93. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/direct-openstacksdk-535a179f3c645cc0.yaml +0 -0
  94. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/drop-py2-support-60c93244107d5778.yaml +0 -0
  95. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/find-project-203bf867619c557e.yaml +0 -0
  96. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/keystone-to-keystone-9b2e55b051775322.yaml +0 -0
  97. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/none-auth-cli-48ab0e48d4852941.yaml +0 -0
  98. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/os-profile-as-environment-variable-a5e232e9ca7c5171.yaml +0 -0
  99. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/remove-babel-50abc5b548455bb2.yaml +0 -0
  100. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/remove-group-subclass-82134e6915c7c782.yaml +0 -0
  101. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/save-results-4473cb5731c0c763.yaml +0 -0
  102. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/notes/shell-argv-decode-cdc13dc0c4ec07af.yaml +0 -0
  103. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/2023.1.rst +0 -0
  104. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/2023.2.rst +0 -0
  105. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/2024.1.rst +0 -0
  106. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/_static/.placeholder +0 -0
  107. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/_templates/.placeholder +0 -0
  108. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/newton.rst +0 -0
  109. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/ocata.rst +0 -0
  110. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/pike.rst +0 -0
  111. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/queens.rst +0 -0
  112. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/rocky.rst +0 -0
  113. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/stein.rst +0 -0
  114. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/train.rst +0 -0
  115. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/unreleased.rst +0 -0
  116. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/ussuri.rst +0 -0
  117. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/victoria.rst +0 -0
  118. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/wallaby.rst +0 -0
  119. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/xena.rst +0 -0
  120. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/yoga.rst +0 -0
  121. {osc-lib-3.1.0 → osc-lib-3.2.0}/releasenotes/source/zed.rst +0 -0
  122. {osc-lib-3.1.0 → osc-lib-3.2.0}/requirements.txt +0 -0
  123. {osc-lib-3.1.0 → osc-lib-3.2.0}/setup.cfg +0 -0
  124. {osc-lib-3.1.0 → osc-lib-3.2.0}/setup.py +0 -0
  125. {osc-lib-3.1.0 → osc-lib-3.2.0}/test-requirements.txt +0 -0
@@ -1,6 +1,7 @@
1
1
  [run]
2
2
  branch = True
3
3
  source = osc_lib
4
+ omit = osc_lib/tests/*
4
5
 
5
6
  [report]
6
7
  ignore_errors = True
@@ -4,7 +4,7 @@ default_language_version:
4
4
  python: python3
5
5
  repos:
6
6
  - repo: https://github.com/pre-commit/pre-commit-hooks
7
- rev: v4.4.0
7
+ rev: v4.6.0
8
8
  hooks:
9
9
  - id: trailing-whitespace
10
10
  - id: mixed-line-ending
@@ -18,22 +18,19 @@ repos:
18
18
  files: .*\.(yaml|yml)$
19
19
  exclude: '^zuul.d/.*$'
20
20
  - repo: https://github.com/PyCQA/doc8
21
- rev: v1.1.1
21
+ rev: v1.1.2
22
22
  hooks:
23
23
  - id: doc8
24
- - repo: https://github.com/psf/black
25
- rev: 23.7.0
24
+ - repo: https://github.com/astral-sh/ruff-pre-commit
25
+ rev: v0.6.4
26
26
  hooks:
27
- - id: black
28
- args: ['-S', '-l', '79']
29
- - repo: local
27
+ - id: ruff
28
+ args: ['--fix', '--unsafe-fixes']
29
+ - id: ruff-format
30
+ - repo: https://opendev.org/openstack/hacking
31
+ rev: 7.0.0
30
32
  hooks:
31
- - id: flake8
32
- name: flake8
33
+ - id: hacking
33
34
  additional_dependencies:
34
- - hacking>=6.0.1,<6.1.0
35
- - flake8-import-order>=0.18.2,<0.19.0
36
- language: python
37
- entry: flake8
38
- files: '^.*\.py$'
35
+ - flake8-import-order~=0.18.2
39
36
  exclude: '^(doc|releasenotes|tools)/.*$'
@@ -107,6 +107,7 @@ OpenStack Release Bot <infra-root@openstack.org>
107
107
  Paul Belanger <paul.belanger@polybeacon.com>
108
108
  Qiu Yu <qiuyu@ebaysf.com>
109
109
  Rabi Mishra <ramishra@redhat.com>
110
+ Radoslaw Smigielski <rsmigiel@redhat.com>
110
111
  Reedip <reedip14@gmail.com>
111
112
  Riccardo Pittau <elfosardo@gmail.com>
112
113
  Richard Theis <rtheis@us.ibm.com>
@@ -1,11 +1,22 @@
1
1
  CHANGES
2
2
  =======
3
3
 
4
+ 3.2.0
5
+ -----
6
+
7
+ * ruff: Enable pyupgrade rules
8
+ * pre-commit: Migrate from black to ruff format
9
+ * pre-commit: Migrate from flake8 to ruff
10
+ * parseactions: Use ArgumentError, not ArgumentTypeError
11
+ * Update master for stable/2024.2
12
+ * Exclude tests directory from coverage calculation
13
+
4
14
  3.1.0
5
15
  -----
6
16
 
7
17
  * Drop dependency on simplejson
8
18
  * reno: Update master for unmaintained/zed
19
+ * Fix log level, remove unnecessary debug
9
20
  * Update master for stable/2024.1
10
21
  * reno: Update master for unmaintained/xena
11
22
  * reno: Update master for unmaintained/wallaby
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 1.2
2
2
  Name: osc-lib
3
- Version: 3.1.0
3
+ Version: 3.2.0
4
4
  Summary: OpenStackClient Library
5
5
  Home-page: https://docs.openstack.org/osc-lib/latest/
6
6
  Author: OpenStack
@@ -1,4 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
1
  #
3
2
  # OpenStack Command Line Client documentation build configuration file, created
4
3
  # by sphinx-quickstart on Wed May 16 12:05:58 2012.
@@ -12,6 +12,7 @@
12
12
  #
13
13
 
14
14
  """Base API Library"""
15
+
15
16
  from keystoneauth1 import exceptions as ksa_exceptions
16
17
  from keystoneauth1 import session as ksa_session
17
18
  import requests
@@ -20,7 +21,7 @@ from osc_lib import exceptions
20
21
  from osc_lib.i18n import _
21
22
 
22
23
 
23
- class BaseAPI(object):
24
+ class BaseAPI:
24
25
  """Base API wrapper for keystoneauth1.session.Session
25
26
 
26
27
  Encapsulate the translation between keystoneauth1.session.Session
@@ -57,7 +58,7 @@ class BaseAPI(object):
57
58
  Keyword arguments passed to keystoneauth1.session.Session().
58
59
  """
59
60
 
60
- super(BaseAPI, self).__init__()
61
+ super().__init__()
61
62
 
62
63
  # Create a keystoneauth1.session.Session if one is not supplied
63
64
  if not session:
@@ -173,7 +174,7 @@ class BaseAPI(object):
173
174
  body=None,
174
175
  detailed=False,
175
176
  headers=None,
176
- **params
177
+ **params,
177
178
  ):
178
179
  """Return a list of resources
179
180
 
@@ -362,7 +363,7 @@ class BaseAPI(object):
362
363
  try:
363
364
  ret = self._request(
364
365
  'GET',
365
- "/%s/%s" % (path, value),
366
+ f"/{path}/{value}",
366
367
  headers=headers,
367
368
  ).json()
368
369
  if isinstance(ret, dict):
@@ -59,9 +59,8 @@ def get_options_list():
59
59
  # TODO(mhu) simplistic approach, would be better to only add
60
60
  # help texts if they vary from one auth plugin to another
61
61
  # also the text rendering is ugly in the CLI ...
62
- OPTIONS_LIST[os_name]['help'] += 'With %s: %s\n' % (
63
- plugin_name,
64
- o.help,
62
+ OPTIONS_LIST[os_name]['help'] += (
63
+ f'With {plugin_name}: {o.help}\n'
65
64
  )
66
65
  return OPTIONS_LIST
67
66
 
@@ -177,7 +176,7 @@ def build_auth_plugins_option_parser(parser):
177
176
  if 'tenant' not in o:
178
177
  parser.add_argument(
179
178
  '--os-' + o,
180
- metavar='<auth-%s>' % o,
179
+ metavar=f'<auth-{o}>',
181
180
  dest=o.replace('-', '_'),
182
181
  default=envs.get(
183
182
  OPTIONS_LIST[o]['env'],
@@ -56,7 +56,7 @@ class OSC_Config(config.OpenStackConfig):
56
56
  if not config.get('auth_type', None):
57
57
  config['auth_type'] = 'password'
58
58
 
59
- LOG.debug("Auth plugin %s selected" % config['auth_type'])
59
+ LOG.debug("Auth plugin {} selected".format(config['auth_type']))
60
60
  return config
61
61
 
62
62
  def _auth_v2_arguments(self, config):
@@ -94,14 +94,15 @@ class OSC_Config(config.OpenStackConfig):
94
94
  if config['auth'].pop(prop, None) is not None:
95
95
  if config.get('cloud'):
96
96
  LOG.warning(
97
- "Ignoring domain related config %s for %s"
98
- "because identity API version is 2.0"
99
- % (prop, config['cloud'])
97
+ "Ignoring domain related config {} for {}"
98
+ "because identity API version is 2.0".format(
99
+ prop, config['cloud']
100
+ )
100
101
  )
101
102
  else:
102
103
  LOG.warning(
103
- "Ignoring domain related config %s because"
104
- " identity API version is 2.0" % prop
104
+ f"Ignoring domain related config {prop} because"
105
+ " identity API version is 2.0"
105
106
  )
106
107
  return config
107
108
 
@@ -204,9 +205,9 @@ class OSC_Config(config.OpenStackConfig):
204
205
  # Prefer the plugin configuration dest value if the value's key
205
206
  # is marked as depreciated.
206
207
  if p_opt.dest is None:
207
- config['auth'][
208
- p_opt.name.replace('-', '_')
209
- ] = winning_value
208
+ config['auth'][p_opt.name.replace('-', '_')] = (
209
+ winning_value
210
+ )
210
211
  else:
211
212
  config['auth'][p_opt.dest] = winning_value
212
213
 
@@ -37,12 +37,12 @@ class KeyValueAction(argparse.Action):
37
37
  # NOTE(qtang): Prevent null key setting in property
38
38
  if '' == values_list[0]:
39
39
  msg = _("Property key must be specified: %s")
40
- raise argparse.ArgumentTypeError(msg % str(values))
40
+ raise argparse.ArgumentError(self, msg % str(values))
41
41
  else:
42
42
  getattr(namespace, self.dest, {}).update([values_list])
43
43
  else:
44
44
  msg = _("Expected 'key=value' type, but got: %s")
45
- raise argparse.ArgumentTypeError(msg % str(values))
45
+ raise argparse.ArgumentError(self, msg % str(values))
46
46
 
47
47
 
48
48
  class KeyValueAppendAction(argparse.Action):
@@ -62,7 +62,7 @@ class KeyValueAppendAction(argparse.Action):
62
62
  # NOTE(qtang): Prevent null key setting in property
63
63
  if '' == key:
64
64
  msg = _("Property key must be specified: %s")
65
- raise argparse.ArgumentTypeError(msg % str(values))
65
+ raise argparse.ArgumentError(self, msg % str(values))
66
66
 
67
67
  dest = getattr(namespace, self.dest)
68
68
  if key in dest:
@@ -71,7 +71,7 @@ class KeyValueAppendAction(argparse.Action):
71
71
  dest[key] = [value]
72
72
  else:
73
73
  msg = _("Expected 'key=value' type, but got: %s")
74
- raise argparse.ArgumentTypeError(msg % str(values))
74
+ raise argparse.ArgumentError(self, msg % str(values))
75
75
 
76
76
 
77
77
  class MultiKeyValueAction(argparse.Action):
@@ -91,7 +91,7 @@ class MultiKeyValueAction(argparse.Action):
91
91
  nargs=None,
92
92
  required_keys=None,
93
93
  optional_keys=None,
94
- **kwargs
94
+ **kwargs,
95
95
  ):
96
96
  """Initialize the action object, and parse customized options
97
97
 
@@ -106,9 +106,7 @@ class MultiKeyValueAction(argparse.Action):
106
106
  msg = _("Parameter 'nargs' is not allowed, but got %s")
107
107
  raise ValueError(msg % nargs)
108
108
 
109
- super(MultiKeyValueAction, self).__init__(
110
- option_strings, dest, **kwargs
111
- )
109
+ super().__init__(option_strings, dest, **kwargs)
112
110
 
113
111
  # required_keys: A list of keys that is required. None by default.
114
112
  if required_keys and not isinstance(required_keys, list):
@@ -136,12 +134,13 @@ class MultiKeyValueAction(argparse.Action):
136
134
  "Invalid keys %(invalid_keys)s specified.\n"
137
135
  "Valid keys are: %(valid_keys)s"
138
136
  )
139
- raise argparse.ArgumentTypeError(
137
+ raise argparse.ArgumentError(
138
+ self,
140
139
  msg
141
140
  % {
142
141
  'invalid_keys': ', '.join(invalid_keys),
143
142
  'valid_keys': ', '.join(valid_keys),
144
- }
143
+ },
145
144
  )
146
145
 
147
146
  if self.required_keys:
@@ -151,12 +150,13 @@ class MultiKeyValueAction(argparse.Action):
151
150
  "Missing required keys %(missing_keys)s.\n"
152
151
  "Required keys are: %(required_keys)s"
153
152
  )
154
- raise argparse.ArgumentTypeError(
153
+ raise argparse.ArgumentError(
154
+ self,
155
155
  msg
156
156
  % {
157
157
  'missing_keys': ', '.join(missing_keys),
158
158
  'required_keys': ', '.join(self.required_keys),
159
- }
159
+ },
160
160
  )
161
161
 
162
162
  def __call__(self, parser, namespace, values, metavar=None):
@@ -166,20 +166,20 @@ class MultiKeyValueAction(argparse.Action):
166
166
 
167
167
  params = {}
168
168
  for kv in values.split(','):
169
- # Add value if an assignment else raise ArgumentTypeError
169
+ # Add value if an assignment else raise ArgumentError
170
170
  if '=' in kv:
171
171
  kv_list = kv.split('=', 1)
172
172
  # NOTE(qtang): Prevent null key setting in property
173
173
  if '' == kv_list[0]:
174
174
  msg = _("Each property key must be specified: %s")
175
- raise argparse.ArgumentTypeError(msg % str(kv))
175
+ raise argparse.ArgumentError(self, msg % str(kv))
176
176
  else:
177
177
  params.update([kv_list])
178
178
  else:
179
179
  msg = _(
180
180
  "Expected comma separated 'key=value' pairs, but got: %s"
181
181
  )
182
- raise argparse.ArgumentTypeError(msg % str(kv))
182
+ raise argparse.ArgumentError(self, msg % str(kv))
183
183
 
184
184
  # Check key validation
185
185
  self.validate_keys(list(params))
@@ -209,13 +209,13 @@ class MultiKeyValueCommaAction(MultiKeyValueAction):
209
209
  params = {}
210
210
  key = ''
211
211
  for kv in values.split(','):
212
- # Add value if an assignment else raise ArgumentTypeError
212
+ # Add value if an assignment else raise ArgumentError
213
213
  if '=' in kv:
214
214
  kv_list = kv.split('=', 1)
215
215
  # NOTE(qtang): Prevent null key setting in property
216
216
  if '' == kv_list[0]:
217
217
  msg = _("A key must be specified before '=': %s")
218
- raise argparse.ArgumentTypeError(msg % str(kv))
218
+ raise argparse.ArgumentError(self, msg % str(kv))
219
219
  else:
220
220
  params.update([kv_list])
221
221
  key = kv_list[0]
@@ -224,10 +224,10 @@ class MultiKeyValueCommaAction(MultiKeyValueAction):
224
224
  # means the current value is a part of the previous
225
225
  # key=value pair, so append it.
226
226
  try:
227
- params[key] = "%s,%s" % (params[key], kv)
227
+ params[key] = f"{params[key]},{kv}"
228
228
  except KeyError:
229
229
  msg = _("A key=value pair is required: %s")
230
- raise argparse.ArgumentTypeError(msg % str(kv))
230
+ raise argparse.ArgumentError(self, msg % str(kv))
231
231
 
232
232
  # Check key validation
233
233
  self.validate_keys(list(params))
@@ -284,4 +284,4 @@ class NonNegativeAction(argparse.Action):
284
284
  setattr(namespace, self.dest, values)
285
285
  else:
286
286
  msg = _("%s expected a non-negative integer")
287
- raise argparse.ArgumentTypeError(msg % str(option_string))
287
+ raise argparse.ArgumentError(self, msg % str(option_string))
@@ -31,7 +31,7 @@ LOG = logging.getLogger(__name__)
31
31
  PLUGIN_MODULES = []
32
32
 
33
33
 
34
- class ClientCache(object):
34
+ class ClientCache:
35
35
  """Descriptor class for caching created client handles."""
36
36
 
37
37
  def __init__(self, factory):
@@ -50,7 +50,7 @@ class ClientCache(object):
50
50
  return self._handle
51
51
 
52
52
 
53
- class ClientManager(object):
53
+ class ClientManager:
54
54
  """Manages access to API clients, including authentication."""
55
55
 
56
56
  # NOTE(dtroyer): Keep around the auth required state of the _current_
@@ -150,7 +150,7 @@ class ClientManager(object):
150
150
  ) and not self._cli_options.auth.get('password'):
151
151
  self._cli_options.auth['password'] = self._pw_callback()
152
152
 
153
- LOG.info('Using auth plugin: %s', self.auth_plugin_name)
153
+ LOG.debug('Using auth plugin: %s', self.auth_plugin_name)
154
154
  LOG.debug(
155
155
  'Using parameters %s',
156
156
  strutils.mask_password(self._cli_options.auth),
@@ -209,7 +209,7 @@ class ClientManager(object):
209
209
  return self._auth_ref
210
210
 
211
211
  def _override_for(self, service_type):
212
- key = '%s_endpoint_override' % service_type.replace('-', '_')
212
+ key = '{}_endpoint_override'.format(service_type.replace('-', '_'))
213
213
  return self._cli_options.config.get(key)
214
214
 
215
215
  def is_service_available(self, service_type):
@@ -29,13 +29,13 @@ class CommandMeta(abc.ABCMeta):
29
29
  cls_dict['log'] = logging.getLogger(
30
30
  cls_dict['__module__'] + '.' + name
31
31
  )
32
- return super(CommandMeta, mcs).__new__(mcs, name, bases, cls_dict)
32
+ return super().__new__(mcs, name, bases, cls_dict)
33
33
 
34
34
 
35
35
  class Command(command.Command, metaclass=CommandMeta):
36
36
  def run(self, parsed_args):
37
37
  self.log.debug('run(%s)', parsed_args)
38
- return super(Command, self).run(parsed_args)
38
+ return super().run(parsed_args)
39
39
 
40
40
  def validate_os_beta_command_enabled(self):
41
41
  if not self.app.options.os_beta_command:
@@ -68,7 +68,7 @@ class ClientException(Exception):
68
68
  self.details = details
69
69
 
70
70
  def __str__(self):
71
- return "%s (HTTP %s)" % (self.message, self.code)
71
+ return f"{self.message} (HTTP {self.code})"
72
72
 
73
73
 
74
74
  class BadRequest(ClientException):
@@ -114,7 +114,7 @@ class _FileFormatter(logging.Formatter):
114
114
  logging.Formatter.__init__(self, self.fmt, self._LOG_DATE_FORMAT)
115
115
 
116
116
 
117
- class LogConfigurator(object):
117
+ class LogConfigurator:
118
118
  _CONSOLE_MESSAGE_FORMAT = '%(message)s'
119
119
 
120
120
  def __init__(self, options):
@@ -107,7 +107,7 @@ class OpenStackShell(app.App):
107
107
  else:
108
108
  cm = command_manager
109
109
 
110
- super(OpenStackShell, self).__init__(
110
+ super().__init__(
111
111
  description=__doc__.strip(),
112
112
  version=version,
113
113
  command_manager=cm,
@@ -134,7 +134,7 @@ class OpenStackShell(app.App):
134
134
  ret_val = 1
135
135
  self.command_options = argv
136
136
  try:
137
- ret_val = super(OpenStackShell, self).run(argv)
137
+ ret_val = super().run(argv)
138
138
  return ret_val
139
139
  except Exception as e:
140
140
  if not logging.getLogger('').handlers:
@@ -147,7 +147,7 @@ class OpenStackShell(app.App):
147
147
  return ret_val
148
148
 
149
149
  finally:
150
- self.log.info("END return value: %s", ret_val)
150
+ self.log.debug("END return value: %s", ret_val)
151
151
 
152
152
  def init_profile(self):
153
153
  self.do_profile = osprofiler_profiler and self.options.profile
@@ -165,20 +165,19 @@ class OpenStackShell(app.App):
165
165
  # printed. In fact we can define custom log level here with value
166
166
  # bigger than most big default one (CRITICAL) or something like
167
167
  # that (PROFILE = 60 for instance), but not sure we need it here.
168
- self.log.warning("Trace ID: %s" % trace_id)
168
+ self.log.warning(f"Trace ID: {trace_id}")
169
169
  self.log.warning(
170
- "Short trace ID "
171
- "for OpenTracing-based drivers: %s" % short_id
170
+ "Short trace ID " f"for OpenTracing-based drivers: {short_id}"
172
171
  )
173
172
  self.log.warning(
174
173
  "Display trace data with command:\n"
175
- "osprofiler trace show --html %s " % trace_id
174
+ f"osprofiler trace show --html {trace_id} "
176
175
  )
177
176
 
178
177
  def run_subcommand(self, argv):
179
178
  self.init_profile()
180
179
  try:
181
- ret_value = super(OpenStackShell, self).run_subcommand(argv)
180
+ ret_value = super().run_subcommand(argv)
182
181
  finally:
183
182
  self.close_profile()
184
183
  return ret_value
@@ -186,15 +185,13 @@ class OpenStackShell(app.App):
186
185
  def interact(self):
187
186
  self.init_profile()
188
187
  try:
189
- ret_value = super(OpenStackShell, self).interact()
188
+ ret_value = super().interact()
190
189
  finally:
191
190
  self.close_profile()
192
191
  return ret_value
193
192
 
194
193
  def build_option_parser(self, description, version):
195
- parser = super(OpenStackShell, self).build_option_parser(
196
- description, version
197
- )
194
+ parser = super().build_option_parser(description, version)
198
195
 
199
196
  # service token auth argument
200
197
  parser.add_argument(
@@ -416,7 +413,7 @@ class OpenStackShell(app.App):
416
413
  """
417
414
 
418
415
  # Parent __init__ parses argv into self.options
419
- super(OpenStackShell, self).initialize_app(argv)
416
+ super().initialize_app(argv)
420
417
  self.log.info(
421
418
  "START with options: %s",
422
419
  strutils.mask_password(" ".join(self.command_options)),
@@ -435,7 +432,7 @@ class OpenStackShell(app.App):
435
432
  'auth_type': self._auth_type,
436
433
  },
437
434
  )
438
- except (IOError, OSError) as e:
435
+ except OSError as e:
439
436
  self.log.critical("Could not read clouds.yaml configuration file")
440
437
  self.print_help_if_requested()
441
438
  raise e
@@ -478,7 +475,7 @@ class OpenStackShell(app.App):
478
475
 
479
476
  def prepare_to_run_command(self, cmd):
480
477
  """Set up auth and API versions"""
481
- self.log.info(
478
+ self.log.debug(
482
479
  'command: %s -> %s.%s (auth=%s)',
483
480
  getattr(cmd, 'cmd_name', '<none>'),
484
481
  cmd.__class__.__module__,
@@ -50,6 +50,6 @@ class TestSession(utils.TestCase):
50
50
  BASE_URL = 'https://api.example.com:1234/test'
51
51
 
52
52
  def setUp(self):
53
- super(TestSession, self).setUp()
53
+ super().setUp()
54
54
  self.sess = session.Session()
55
55
  self.requests_mock = self.useFixture(fixture.Fixture())
@@ -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(TestBaseAPIDefault, self).setUp()
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(TestBaseAPIArgs, self).setUp()
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(TestBaseAPICreate, self).setUp()
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(TestBaseAPIFind, self).setUp()
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(TestBaseAPIList, self).setUp()
455
+ super().setUp()
456
456
  self.api = api.BaseAPI(
457
457
  session=self.sess,
458
458
  endpoint=self.BASE_URL,
@@ -24,7 +24,7 @@ class TestBaseAPIFilter(api_fakes.TestSession):
24
24
  """The filters can be tested independently"""
25
25
 
26
26
  def setUp(self):
27
- super(TestBaseAPIFilter, self).setUp()
27
+ super().setUp()
28
28
  self.api = api.BaseAPI(
29
29
  session=self.sess,
30
30
  endpoint=self.BASE_URL,
@@ -17,7 +17,7 @@ from osc_lib.tests import utils
17
17
 
18
18
  class TestOSCConfig(utils.TestCase):
19
19
  def setUp(self):
20
- super(TestOSCConfig, self).setUp()
20
+ super().setUp()
21
21
 
22
22
  self.cloud = client_config.OSC_Config()
23
23
 
@@ -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: H212
107
+ self.assertEqual(type(x), dict) # noqa: H211
108
108
 
109
109
 
110
110
  class TestSizeColumn(utils.TestCase):