From 9be0a750a909f8a9e83ee6dcfba7707d8747df8f Mon Sep 17 00:00:00 2001
From: Dmitry Tantsur <dtantsur@protonmail.com>
Date: Mon, 30 Mar 2020 11:17:16 +0200
Subject: [PATCH] Bump hacking to 3.0.0

The new version enables a lot of standard flake8 checks, so a few
fixes are required. W503 is disabled as it conflicts with W504
and the latter seems to be preferred nowadays.

Change-Id: I7c66f18be46af73a47919deef1f38c1f1d3cc741
---
 ironicclient/common/apiclient/exceptions.py | 12 ++++----
 ironicclient/common/http.py                 | 33 +++++++++++----------
 ironicclient/exc.py                         | 21 ++++++-------
 ironicclient/tests/unit/osc/fakes.py        |  4 +--
 ironicclient/tests/unit/v1/test_driver.py   |  8 ++---
 ironicclient/tests/unit/v1/test_node.py     | 21 ++++++-------
 ironicclient/v1/node.py                     |  4 +--
 lower-constraints.txt                       |  2 +-
 test-requirements.txt                       |  2 +-
 tox.ini                                     |  2 +-
 10 files changed, 56 insertions(+), 53 deletions(-)

diff --git a/ironicclient/common/apiclient/exceptions.py b/ironicclient/common/apiclient/exceptions.py
index 2ae9bf67e..10bca538e 100644
--- a/ironicclient/common/apiclient/exceptions.py
+++ b/ironicclient/common/apiclient/exceptions.py
@@ -444,10 +444,10 @@ def from_response(response, method, url):
             if isinstance(body, dict):
                 error = body.get(list(body)[0])
                 if isinstance(error, dict):
-                    kwargs["message"] = (error.get("message") or
-                                         error.get("faultstring"))
-                    kwargs["details"] = (error.get("details") or
-                                         str(body))
+                    kwargs["message"] = (error.get("message")
+                                         or error.get("faultstring"))
+                    kwargs["details"] = (error.get("details")
+                                         or str(body))
     elif content_type.startswith("text/"):
         kwargs["details"] = getattr(response, 'text', '')
 
@@ -458,8 +458,8 @@ def from_response(response, method, url):
         if response.status_code >= http_client.INTERNAL_SERVER_ERROR:
             cls = HttpServerError
         # 4XX status codes are client request errors
-        elif (http_client.BAD_REQUEST <= response.status_code <
-                http_client.INTERNAL_SERVER_ERROR):
+        elif (http_client.BAD_REQUEST <= response.status_code
+              < http_client.INTERNAL_SERVER_ERROR):
             cls = HTTPClientError
         else:
             cls = HttpError
diff --git a/ironicclient/common/http.py b/ironicclient/common/http.py
index 6e1fb6db3..eeef1475f 100644
--- a/ironicclient/common/http.py
+++ b/ironicclient/common/http.py
@@ -104,9 +104,9 @@ class VersionNegotiationMixin(object):
         :param resp: The response object from http request
         """
         def _query_server(conn):
-            if (self.os_ironic_api_version and
-                    not isinstance(self.os_ironic_api_version, list) and
-                    self.os_ironic_api_version != 'latest'):
+            if (self.os_ironic_api_version
+                    and not isinstance(self.os_ironic_api_version, list)
+                    and self.os_ironic_api_version != 'latest'):
                 base_version = ("/v%s" %
                                 str(self.os_ironic_api_version).split('.')[0])
             else:
@@ -119,8 +119,8 @@ class VersionNegotiationMixin(object):
 
         version_overridden = False
 
-        if (resp and hasattr(resp, 'request') and
-                hasattr(resp.request, 'headers')):
+        if (resp and hasattr(resp, 'request')
+                and hasattr(resp.request, 'headers')):
             orig_hdr = resp.request.headers
             # Get the version of the client's last request and fallback
             # to the default for things like unit tests to not cause
@@ -129,8 +129,8 @@ class VersionNegotiationMixin(object):
                                        self.os_ironic_api_version)
         else:
             req_api_ver = self.os_ironic_api_version
-        if (resp and req_api_ver != self.os_ironic_api_version and
-                self.api_version_select_state == 'negotiated'):
+        if (resp and req_api_ver != self.os_ironic_api_version
+                and self.api_version_select_state == 'negotiated'):
             # If we have a non-standard api version on the request,
             # but we think we've negotiated, then the call was overridden.
             # We should report the error with the called version
@@ -173,10 +173,10 @@ class VersionNegotiationMixin(object):
         # be supported by the requested version.
         # TODO(TheJulia): We should break this method into several parts,
         # such as a sanity check/error method.
-        if ((self.api_version_select_state == 'user' and
-                not self._must_negotiate_version()) or
-                (self.api_version_select_state == 'negotiated' and
-                    version_overridden)):
+        if ((self.api_version_select_state == 'user'
+             and not self._must_negotiate_version())
+                or (self.api_version_select_state == 'negotiated'
+                    and version_overridden)):
             raise exc.UnsupportedVersion(textwrap.fill(
                 _("Requested API version %(req)s is not supported by the "
                   "server, client, or the requested operation is not "
@@ -263,9 +263,10 @@ class VersionNegotiationMixin(object):
         raise NotImplementedError()
 
     def _must_negotiate_version(self):
-        return (self.api_version_select_state == 'user' and
-                (self.os_ironic_api_version == 'latest' or
-                 isinstance(self.os_ironic_api_version, list)))
+        return (self.api_version_select_state == 'user'
+                and (self.os_ironic_api_version == 'latest'
+                     or isinstance(self.os_ironic_api_version, list)))
+
 
 _RETRY_EXCEPTIONS = (exc.Conflict, exc.ServiceUnavailable,
                      exc.ConnectionRefused, kexc.RetriableConnectionFailure)
@@ -398,8 +399,8 @@ class SessionClient(VersionNegotiationMixin, adapter.LegacyJsonAdapter):
         body = resp.content
         content_type = resp.headers.get('content-type', None)
         status = resp.status_code
-        if (status in (http_client.NO_CONTENT, http_client.RESET_CONTENT) or
-                content_type is None):
+        if (status in (http_client.NO_CONTENT, http_client.RESET_CONTENT)
+                or content_type is None):
             return resp, list()
         if 'application/json' in content_type:
             try:
diff --git a/ironicclient/exc.py b/ironicclient/exc.py
index 85caf0138..594fa1725 100644
--- a/ironicclient/exc.py
+++ b/ironicclient/exc.py
@@ -16,31 +16,32 @@ from ironicclient.common.apiclient.exceptions import *  # noqa
 
 # NOTE(akurilin): This alias is left here since v.0.1.3 to support backwards
 # compatibility.
-InvalidEndpoint = EndpointException
-CommunicationError = ConnectionRefused
-HTTPBadRequest = BadRequest
-HTTPInternalServerError = InternalServerError
-HTTPNotFound = NotFound
-HTTPServiceUnavailable = ServiceUnavailable
+InvalidEndpoint = exceptions.EndpointException
+CommunicationError = exceptions.ConnectionRefused
+HTTPBadRequest = exceptions.BadRequest
+HTTPInternalServerError = exceptions.InternalServerError
+HTTPNotFound = exceptions.NotFound
+HTTPServiceUnavailable = exceptions.ServiceUnavailable
 
 
-class AmbiguousAuthSystem(ClientException):
+class AmbiguousAuthSystem(exceptions.ClientException):
     """Could not obtain token and endpoint using provided credentials."""
     pass
 
+
 # Alias for backwards compatibility
 AmbigiousAuthSystem = AmbiguousAuthSystem
 
 
-class InvalidAttribute(ClientException):
+class InvalidAttribute(exceptions.ClientException):
     pass
 
 
-class StateTransitionFailed(ClientException):
+class StateTransitionFailed(exceptions.ClientException):
     """Failed to reach a requested provision state."""
 
 
-class StateTransitionTimeout(ClientException):
+class StateTransitionTimeout(exceptions.ClientException):
     """Timed out while waiting for a requested provision state."""
 
 
diff --git a/ironicclient/tests/unit/osc/fakes.py b/ironicclient/tests/unit/osc/fakes.py
index 76d77e60d..512904ce8 100644
--- a/ironicclient/tests/unit/osc/fakes.py
+++ b/ironicclient/tests/unit/osc/fakes.py
@@ -55,7 +55,7 @@ class FakeResource(object):
             setattr(self, k, v)
 
     def __repr__(self):
-        reprkeys = sorted(k for k in self.__dict__.keys() if k[0] != '_' and
-                          k != 'manager')
+        reprkeys = sorted(k for k in self.__dict__.keys()
+                          if k[0] != '_' and k != 'manager')
         info = ", ".join("%s=%s" % (k, getattr(self, k)) for k in reprkeys)
         return "<%s %s>" % (self.__class__.__name__, info)
diff --git a/ironicclient/tests/unit/v1/test_driver.py b/ironicclient/tests/unit/v1/test_driver.py
index a5996f792..8ef102360 100644
--- a/ironicclient/tests/unit/v1/test_driver.py
+++ b/ironicclient/tests/unit/v1/test_driver.py
@@ -172,7 +172,7 @@ class DriverManagerTest(testtools.TestCase):
             'driver_name': 'driver_name',
             'method': 'method',
             'args': vendor_passthru_args
-            }
+        }
 
         final_path = 'driver_name/vendor_passthru/method'
         for http_method in ('POST', 'PUT', 'PATCH'):
@@ -189,7 +189,7 @@ class DriverManagerTest(testtools.TestCase):
             'driver_name': 'driver_name',
             'method': 'method',
             'http_method': 'GET',
-            }
+        }
 
         final_path = 'driver_name/vendor_passthru/method'
         self.mgr.vendor_passthru(**kwargs)
@@ -201,7 +201,7 @@ class DriverManagerTest(testtools.TestCase):
             'driver_name': 'driver_name',
             'method': 'method',
             'http_method': 'DELETE',
-            }
+        }
 
         final_path = 'driver_name/vendor_passthru/method'
         self.mgr.vendor_passthru(**kwargs)
@@ -213,7 +213,7 @@ class DriverManagerTest(testtools.TestCase):
             'driver_name': 'driver_name',
             'method': 'method',
             'http_method': 'UNKNOWN',
-            }
+        }
         self.assertRaises(exc.InvalidAttribute, self.mgr.vendor_passthru,
                           **kwargs)
 
diff --git a/ironicclient/tests/unit/v1/test_node.py b/ironicclient/tests/unit/v1/test_node.py
index 448cd2214..8b0eab3ab 100644
--- a/ironicclient/tests/unit/v1/test_node.py
+++ b/ironicclient/tests/unit/v1/test_node.py
@@ -367,7 +367,8 @@ fake_responses = {
             {},
             {"connectors": [CONNECTOR]},
         ),
-    },    '/v1/nodes/%s/volume/targets' % NODE1['uuid']:
+    },
+    '/v1/nodes/%s/volume/targets' % NODE1['uuid']:
     {
         'GET': (
             {},
@@ -1594,7 +1595,7 @@ class NodeManagerTest(testtools.TestCase):
             'node_id': 'node_uuid',
             'method': 'method',
             'args': vendor_passthru_args
-            }
+        }
 
         final_path = 'node_uuid/vendor_passthru/method'
         for http_method in ('POST', 'PUT', 'PATCH'):
@@ -1611,7 +1612,7 @@ class NodeManagerTest(testtools.TestCase):
             'node_id': 'node_uuid',
             'method': 'method',
             'http_method': 'GET',
-            }
+        }
 
         final_path = 'node_uuid/vendor_passthru/method'
         self.mgr.vendor_passthru(**kwargs)
@@ -1623,7 +1624,7 @@ class NodeManagerTest(testtools.TestCase):
             'node_id': 'node_uuid',
             'method': 'method',
             'http_method': 'DELETE',
-            }
+        }
 
         final_path = 'node_uuid/vendor_passthru/method'
         self.mgr.vendor_passthru(**kwargs)
@@ -1635,7 +1636,7 @@ class NodeManagerTest(testtools.TestCase):
             'node_id': 'node_uuid',
             'method': 'method',
             'http_method': 'UNKNOWN',
-            }
+        }
         self.assertRaises(exc.InvalidAttribute, self.mgr.vendor_passthru,
                           **kwargs)
 
@@ -1643,7 +1644,7 @@ class NodeManagerTest(testtools.TestCase):
     def test_vif_list(self, _list_mock):
         kwargs = {
             'node_ident': NODE1['uuid'],
-            }
+        }
 
         final_path = '/v1/nodes/%s/vifs' % NODE1['uuid']
         self.mgr.vif_list(**kwargs)
@@ -1654,7 +1655,7 @@ class NodeManagerTest(testtools.TestCase):
         kwargs = {
             'node_ident': NODE1['uuid'],
             'vif_id': 'vif_id',
-            }
+        }
 
         final_path = '%s/vifs' % NODE1['uuid']
         self.mgr.vif_attach(**kwargs)
@@ -1667,7 +1668,7 @@ class NodeManagerTest(testtools.TestCase):
             'node_ident': NODE1['uuid'],
             'vif_id': 'vif_id',
             'foo': 'bar',
-            }
+        }
 
         final_path = '%s/vifs' % NODE1['uuid']
         self.mgr.vif_attach(**kwargs)
@@ -1682,7 +1683,7 @@ class NodeManagerTest(testtools.TestCase):
             'node_ident': NODE1['uuid'],
             'vif_id': 'vif_id',
             'id': 'bar',
-            }
+        }
         self.assertRaises(
             exc.InvalidAttribute,
             self.mgr.vif_attach, **kwargs)
@@ -1692,7 +1693,7 @@ class NodeManagerTest(testtools.TestCase):
         kwargs = {
             'node_ident': NODE1['uuid'],
             'vif_id': 'vif_id',
-            }
+        }
 
         final_path = '%s/vifs/vif_id' % NODE1['uuid']
         self.mgr.vif_detach(**kwargs)
diff --git a/ironicclient/v1/node.py b/ironicclient/v1/node.py
index 57d5d2a50..6f7077821 100644
--- a/ironicclient/v1/node.py
+++ b/ironicclient/v1/node.py
@@ -711,8 +711,8 @@ class NodeManager(base.CreateManager):
                 return
 
             # Note that if expected_state == 'error' we still succeed
-            if (node.provision_state == 'error' or
-                    node.provision_state.endswith(' failed')):
+            if (node.provision_state == 'error'
+                    or node.provision_state.endswith(' failed')):
                 raise exc.StateTransitionFailed(
                     _('Node %(node)s failed to reach state %(state)s. '
                       'It\'s in state %(actual)s, and has error: %(error)s') %
diff --git a/lower-constraints.txt b/lower-constraints.txt
index 5f9da80eb..bc2dbc6dc 100644
--- a/lower-constraints.txt
+++ b/lower-constraints.txt
@@ -21,7 +21,7 @@ fasteners==0.7.0
 fixtures==3.0.0
 flake8==2.5.5
 future==0.16.0
-hacking==1.0.0
+hacking==3.0.0
 idna==2.6
 imagesize==0.7.1
 iso8601==0.1.11
diff --git a/test-requirements.txt b/test-requirements.txt
index 5e868e850..b1a8602da 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,7 +1,7 @@
 # The order of packages is significant, because pip processes them in the order
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
-hacking>=1.0.0,<1.1.0 # Apache-2.0
+hacking>=3.0.0,<3.1.0 # Apache-2.0
 coverage!=4.4,>=4.0 # Apache-2.0
 doc8>=0.6.0 # Apache-2.0
 fixtures>=3.0.0 # Apache-2.0/BSD
diff --git a/tox.ini b/tox.ini
index 1238328fe..3b3a322c2 100644
--- a/tox.ini
+++ b/tox.ini
@@ -72,7 +72,7 @@ commands =
   make -C doc/build/pdf
 
 [flake8]
-ignore =
+ignore = W503
 exclude = .venv,.git,.tox,dist,doc,*lib/python*,*egg,build,tools
 # [H106] Don't put vim configuration in source files.
 # [H203] Use assertIs(Not)None to check for None.