Update hacking for Focal

As per victoria cycle testing runtime and community goal[1]
we need to migrate upstream CI/CD to Ubuntu Focal(20.04).

This bumps hacking to 3.2.0 in order to work with focal, disabling W504
to align with neutron (W503 is enabled in this version)

Story: #2007865
Task: #40199

[1] https://governance.openstack.org/tc/goals/selected/victoria/migrate-ci-cd-jobs-to-ubuntu-focal.html

Change-Id: Ic7a6da941172aae6dc504eb377c3e94de4805a89
diff --git a/neutron_tempest_plugin/api/base.py b/neutron_tempest_plugin/api/base.py
index 1b02211..77bf5e8 100644
--- a/neutron_tempest_plugin/api/base.py
+++ b/neutron_tempest_plugin/api/base.py
@@ -478,7 +478,7 @@
         """
 
         if not cls.try_reserve_subnet_cidr(addr, **ipnetwork_kwargs):
-            raise ValueError('Subnet CIDR already reserved: %r'.format(
+            raise ValueError('Subnet CIDR already reserved: {0!r}'.format(
                 addr))
 
     @classmethod
diff --git a/neutron_tempest_plugin/bgpvpn/scenario/manager.py b/neutron_tempest_plugin/bgpvpn/scenario/manager.py
index 8a5f9f2..4ff1c0d 100644
--- a/neutron_tempest_plugin/bgpvpn/scenario/manager.py
+++ b/neutron_tempest_plugin/bgpvpn/scenario/manager.py
@@ -462,8 +462,8 @@
         port_map = [(p["id"], fxip["ip_address"])
                     for p in ports
                     for fxip in p["fixed_ips"]
-                    if netutils.is_valid_ipv4(fxip["ip_address"])
-                    and p['status'] in p_status]
+                    if netutils.is_valid_ipv4(fxip["ip_address"]) and
+                    p['status'] in p_status]
         inactive = [p for p in ports if p['status'] != 'ACTIVE']
         if inactive:
             LOG.warning("Instance has ports that are not ACTIVE: %s", inactive)
diff --git a/neutron_tempest_plugin/common/ip.py b/neutron_tempest_plugin/common/ip.py
index a286d6b..83cd3d9 100644
--- a/neutron_tempest_plugin/common/ip.py
+++ b/neutron_tempest_plugin/common/ip.py
@@ -295,7 +295,7 @@
     for address in list_ip_addresses(addresses=addresses, port=port):
         return address.device.name
 
-    msg = "Port %r fixed IPs not found on server.".format(port['id'])
+    msg = "Port {0!r} fixed IPs not found on server.".format(port['id'])
     raise ValueError(msg)
 
 
diff --git a/test-requirements.txt b/test-requirements.txt
index 6cbe947..bf1c626 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -2,7 +2,7 @@
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
 
-hacking<0.13,>=0.12.0 # Apache-2.0
+hacking>=3.2.0,<3.3.0 # Apache-2.0
 
 coverage!=4.4,>=4.0 # Apache-2.0
 flake8-import-order==0.12 # LGPLv3
diff --git a/tox.ini b/tox.ini
index 760cc47..eecd16e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -53,7 +53,8 @@
 # E128 continuation line under-indented for visual indent
 # E129 visually indented line with same indent as next logical line
 # N530 direct neutron imports not allowed
-ignore = E126,E128,E129,N530
+# W504 line break after binary operator
+ignore = E126,E128,E129,N530,W504
 # H106: Don't put vim configuration in source files
 # H203: Use assertIs(Not)None to check for None
 # H204: Use assert(Not)Equal to check for equality