From 859ce180cb150ecd4aec872d41e3c0e174ec2f2b Mon Sep 17 00:00:00 2001 From: Omer Date: Fri, 31 May 2024 13:51:47 +0200 Subject: [PATCH] Upgrade pylint version So far, tobiko was using old pylint version. As we would like to replace the upper constraints that we use, we have to upgrade pylint to avoid some conflicts. This patch aspires to implement that. Depends-On: https://review.opendev.org/c/x/devstack-plugin-tobiko/+/921834 Change-Id: I630ec0edaf930d3bdd3eaeacd55ffebc203a5763 --- .pylintrc | 4 -- linters-requirements.txt | 2 +- tobiko/actors/_actor.py | 1 + tobiko/actors/_proxy.py | 2 + tobiko/common/_background.py | 3 ++ tobiko/common/_fixture.py | 3 +- tobiko/docker/_client.py | 1 + tobiko/openstack/glance/_image.py | 1 + tobiko/openstack/tests/_neutron.py | 2 +- tobiko/podified/containers.py | 1 + tobiko/shell/ip.py | 1 + tobiko/shell/ss.py | 6 +-- tobiko/shell/ssh/_forward.py | 2 +- .../tests/faults/containers/container_ops.py | 3 +- .../functional/openstack/test_topology.py | 47 ++++++++++--------- .../functional/podified/test_topology.py | 4 +- .../sanity/containers/test_containers.py | 4 ++ tobiko/tests/unit/test_exception.py | 2 + tobiko/tripleo/containers.py | 1 + 19 files changed, 51 insertions(+), 39 deletions(-) diff --git a/.pylintrc b/.pylintrc index 0fe3b56ae..c4feb6a1e 100644 --- a/.pylintrc +++ b/.pylintrc @@ -129,7 +129,6 @@ disable=invalid-name, c-extension-no-member, literal-comparison, comparison-with-itself, - no-self-use, no-classmethod-decorator, no-staticmethod-decorator, useless-object-inheritance, @@ -187,7 +186,6 @@ disable=invalid-name, broad-except, redundant-u-string-prefix, unspecified-encoding, - dict-values-not-iterating, # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option @@ -313,7 +311,6 @@ enable=syntax-error, unnecessary-pass, unnecessary-lambda, duplicate-key, - assign-to-new-keyword, useless-else-on-loop, exec-used, eval-used, @@ -334,7 +331,6 @@ enable=syntax-error, signature-differs, abstract-method, super-init-not-called, - no-init, non-parent-init-called, useless-super-delegation, invalid-overridden-method, diff --git a/linters-requirements.txt b/linters-requirements.txt index 88136bbac..fcacf67cd 100644 --- a/linters-requirements.txt +++ b/linters-requirements.txt @@ -1,4 +1,4 @@ # pep8 and flake8 requirements pre-commit >= 2.16.0 # MIT -pylint===2.12.2 # GPL2 +pylint>=2.5.3 # GPL2 diff --git a/tobiko/actors/_actor.py b/tobiko/actors/_actor.py index 065ded9bd..1edbd1beb 100644 --- a/tobiko/actors/_actor.py +++ b/tobiko/actors/_actor.py @@ -32,6 +32,7 @@ from tobiko.actors import _request A = typing.TypeVar('A', bound='ActorBase') +# pylint: disable=inherit-non-class class ActorRef(_proxy.CallProxyBase, _proxy.Generic[A]): _actor_class: typing.Type[A] diff --git a/tobiko/actors/_proxy.py b/tobiko/actors/_proxy.py index 611c31150..165367dbc 100644 --- a/tobiko/actors/_proxy.py +++ b/tobiko/actors/_proxy.py @@ -76,6 +76,7 @@ class CallHandler(abc.ABC): raise NotImplementedError +# pylint: disable=inherit-non-class class CallProxyBase(CallHandler, Generic[P], abc.ABC): def __class_getitem__(cls, item: typing.Type[P]): @@ -92,6 +93,7 @@ class CallProxyBase(CallHandler, Generic[P], abc.ABC): return is_public_abstract_method(obj) +# pylint: disable=inherit-non-class class CallProxy(CallProxyBase, Generic[P]): def __init__(self, handle_call: typing.Callable): diff --git a/tobiko/common/_background.py b/tobiko/common/_background.py index f5fd5087c..20c89c0d9 100644 --- a/tobiko/common/_background.py +++ b/tobiko/common/_background.py @@ -251,6 +251,7 @@ def read_pid_file(pid_file: str) -> typing.Tuple[int, ...]: with fd: for line_number, line in enumerate(fd.readlines(), start=1): line = line.strip() + pid = None if line: try: pid = int(line.rstrip()) @@ -258,6 +259,8 @@ def read_pid_file(pid_file: str) -> typing.Tuple[int, ...]: LOG.exception(f"{pid_file}:{line_number}: value is " f"not an integer ({line}).") continue + if not pid: + continue pids.append(pid) return tuple(pids) diff --git a/tobiko/common/_fixture.py b/tobiko/common/_fixture.py index c89715164..f432c544f 100644 --- a/tobiko/common/_fixture.py +++ b/tobiko/common/_fixture.py @@ -500,8 +500,7 @@ class FixtureManager: self.fixtures[name] = fixture return fixture - @staticmethod - def init_fixture(obj: typing.Union[typing.Type[F], F], + def init_fixture(self, obj: typing.Union[typing.Type[F], F], name: str, fixture_id: typing.Any, **kwargs) -> F: diff --git a/tobiko/docker/_client.py b/tobiko/docker/_client.py index 6bcb9dffb..91231fa97 100644 --- a/tobiko/docker/_client.py +++ b/tobiko/docker/_client.py @@ -233,6 +233,7 @@ class UnixHTTPConnection(unixconn.UnixHTTPConnection): sudo=False): self.ssh_client = ssh_client self.sudo = sudo + self.sock = None super(UnixHTTPConnection, self).__init__(base_url=base_url, unix_socket=unix_socket, timeout=timeout) diff --git a/tobiko/openstack/glance/_image.py b/tobiko/openstack/glance/_image.py index b4711f645..6d6f0b700 100644 --- a/tobiko/openstack/glance/_image.py +++ b/tobiko/openstack/glance/_image.py @@ -361,6 +361,7 @@ class URLGlanceImageFixture(FileGlanceImageFixture): tobiko.check_valid_type(image_url, str) def get_image_file(self, image_file: str): + # pylint: disable=missing-timeout http_request = requests.get(self.image_url, stream=True) expected_size = int(http_request.headers.get('content-length', 0)) chunks = http_request.iter_content(chunk_size=io.DEFAULT_BUFFER_SIZE) diff --git a/tobiko/openstack/tests/_neutron.py b/tobiko/openstack/tests/_neutron.py index 29b91a3cd..5bc57ff46 100644 --- a/tobiko/openstack/tests/_neutron.py +++ b/tobiko/openstack/tests/_neutron.py @@ -248,7 +248,7 @@ def parse_ips_from_db_connections(con_str): try: addr = netaddr.IPAddress(tmp_addr.strip('][')) except ValueError as ex: - msg = 'Invalid IP address "{}" in "{}"'.format(addr, con_str) + msg = 'Invalid IP address "{}" in "{}"'.format(tmp_addr, con_str) LOG.error(msg) raise InvalidDBConnString(message=msg) from ex addrs.append(addr) diff --git a/tobiko/podified/containers.py b/tobiko/podified/containers.py index 19a81b363..4188645e1 100644 --- a/tobiko/podified/containers.py +++ b/tobiko/podified/containers.py @@ -298,6 +298,7 @@ def assert_equal_containers_state(expected_containers_list=None, second time it creates a current containers states list and compares them, they must be identical""" + expected_containers_list_df = [] # if we have a file or an explicit variable use that , otherwise create # and return if recreate_expected or ( diff --git a/tobiko/shell/ip.py b/tobiko/shell/ip.py index 6049cbc8a..c04d3102a 100644 --- a/tobiko/shell/ip.py +++ b/tobiko/shell/ip.py @@ -93,6 +93,7 @@ def find_ip_address(ip_version: int = None, def parse_ip_address(text: str) -> typing.Tuple[netaddr.IPAddress, int]: + address = text if '/' in text: # Remove netmask prefix length address, prefix_len_text = text.split('/', 1) diff --git a/tobiko/shell/ss.py b/tobiko/shell/ss.py index fd908f2f2..07b3ed1dd 100644 --- a/tobiko/shell/ss.py +++ b/tobiko/shell/ss.py @@ -77,8 +77,7 @@ class SockHeader(): return len(self.header) def __iter__(self): - for elem in self.header: - yield elem + yield from self.header class SockLine(str): @@ -118,6 +117,7 @@ def _ss(params: str = '', **execute_params) -> typing.List[SockData]: execute_params.update({'sudo': True}) sockets = [] + headers = None if table_header: # Predefined header might be necessary if the command is expected to # be executed in any kind of environments. Old versrions of `ss` @@ -143,7 +143,7 @@ def _ss(params: str = '', parsed_header = True continue sock_info = SockLine(line.strip()) - if parser: + if parser and headers: try: sockets.append(parser(headers, sock_info)) except ValueError as ex: diff --git a/tobiko/shell/ssh/_forward.py b/tobiko/shell/ssh/_forward.py index ac417cd18..b68baff72 100644 --- a/tobiko/shell/ssh/_forward.py +++ b/tobiko/shell/ssh/_forward.py @@ -297,7 +297,7 @@ def binding_address(url): def binding_url(address): if isinstance(address, tuple): try: - hostname, = address + hostname, port = address except ValueError: hostname, port = address return 'tcp://{hostname}:{port}'.format(hostname=hostname, diff --git a/tobiko/tests/faults/containers/container_ops.py b/tobiko/tests/faults/containers/container_ops.py index 8673d3d53..e7e86476e 100644 --- a/tobiko/tests/faults/containers/container_ops.py +++ b/tobiko/tests/faults/containers/container_ops.py @@ -372,8 +372,7 @@ def rotate_logs(node): containers = get_filtered_node_containers(node, ['logrotate.*', ]) if not containers: tobiko.skip_test('No logrotate container has been found') - else: - container = containers[0] + container = containers[0] sh.execute(f'docker exec -u root {container} logrotate ' '-f /etc/logrotate-crond.conf', ssh_client=node.ssh_client, sudo=True) diff --git a/tobiko/tests/functional/openstack/test_topology.py b/tobiko/tests/functional/openstack/test_topology.py index c99ccb529..dd319d05a 100644 --- a/tobiko/tests/functional/openstack/test_topology.py +++ b/tobiko/tests/functional/openstack/test_topology.py @@ -26,7 +26,7 @@ import tobiko from tobiko.openstack import keystone from tobiko.openstack import neutron from tobiko.openstack import nova -from tobiko.openstack import topology +from tobiko.openstack import topology as osp_topology from tobiko.shell import ping from tobiko.shell import sh @@ -37,17 +37,18 @@ PatternType = type(re.compile(r'')) @keystone.skip_unless_has_keystone_credentials() class OpenStackTopologyTest(testtools.TestCase): - expected_group: topology.OpenstackGroupNamesType = None + expected_group: osp_topology.OpenstackGroupNamesType = None @property - def topology(self) -> topology.OpenStackTopology: - return topology.get_openstack_topology() + def topology(self) -> osp_topology.OpenStackTopology: + return osp_topology.get_openstack_topology() def test_get_openstack_topology(self): topology_class = type(self.topology) - topo = topology.get_openstack_topology(topology_class=topology_class) + topo = osp_topology.get_openstack_topology( + topology_class=topology_class) self.assertIs(topo, self.topology) - self.assertIsInstance(topo, topology.OpenStackTopology) + self.assertIsInstance(topo, osp_topology.OpenStackTopology) def test_ping_node(self): for node in self.topology.nodes: @@ -80,7 +81,7 @@ class OpenStackTopologyTest(testtools.TestCase): self.assertIn(node, nodes) def test_list_openstack_topology(self, group=None, hostnames=None): - nodes = topology.list_openstack_nodes( + nodes = osp_topology.list_openstack_nodes( topology=self.topology, group=group, hostnames=hostnames) self.assertTrue(set(nodes).issubset(set(self.topology.nodes))) self.assertEqual(len(set(nodes)), len(nodes), @@ -136,7 +137,7 @@ class OpenStackTopologyTest(testtools.TestCase): self.assertEqual(expected_nodes, actual_nodes) def test_list_nodes_processes(self): - node = random.choice(topology.list_openstack_nodes( + node = random.choice(osp_topology.list_openstack_nodes( group=self.expected_group)) filename = sh.execute( 'mktemp', ssh_client=node.ssh_client).stdout.strip() @@ -147,7 +148,7 @@ class OpenStackTopologyTest(testtools.TestCase): ssh_client=node.ssh_client) # Process isn't listed before creation - processes = topology.list_nodes_processes( + processes = osp_topology.list_nodes_processes( command_line=command_line, hostnames=[node.hostname]) self.assertEqual([], processes, @@ -156,7 +157,7 @@ class OpenStackTopologyTest(testtools.TestCase): # Process is listed after creation process.execute() self.addCleanup(process.kill) - processes = topology.list_nodes_processes( + processes = osp_topology.list_nodes_processes( command_line=command_line, hostnames=[node.hostname]) self.assertEqual(command_line, processes.unique.command_line) @@ -165,7 +166,7 @@ class OpenStackTopologyTest(testtools.TestCase): # Process isn't listed after kill processes.unique.kill() for attempt in tobiko.retry(timeout=30., interval=5.): - processes = topology.list_nodes_processes( + processes = osp_topology.list_nodes_processes( command_line=command_line, hostnames=[node.hostname]) if not processes: @@ -175,9 +176,9 @@ class OpenStackTopologyTest(testtools.TestCase): @neutron.skip_unless_is_ovs() def test_l3_agent_mode(self): - for node in topology.list_openstack_nodes( + for node in osp_topology.list_openstack_nodes( group=['controller', 'compute', 'overcloud']): - assert isinstance(node, topology.OpenStackTopologyNode) + assert isinstance(node, osp_topology.OpenStackTopologyNode) self.assertEqual( neutron.get_l3_agent_mode( l3_agent_conf_path=node.l3_agent_conf_path, @@ -195,7 +196,7 @@ class HostsNamespaceTest(testtools.TestCase): @property def all_hostnames(self) -> typing.List[str]: - nodes = topology.list_openstack_nodes() + nodes = osp_topology.list_openstack_nodes() return sorted(node.hostname for node in nodes) def selected_hostames(self, hostnames: typing.Iterable[str] = None) -> \ @@ -207,7 +208,7 @@ class HostsNamespaceTest(testtools.TestCase): def test_get_hosts_namespaces(self, hostnames: typing.Iterable[str] = None): - namespaces = topology.get_hosts_namespaces(hostnames=hostnames) + namespaces = osp_topology.get_hosts_namespaces(hostnames=hostnames) self.assertIsInstance(namespaces, dict) for namespace, _hostnames in namespaces.items(): self.assertIsInstance(namespace, str) @@ -221,31 +222,31 @@ class HostsNamespaceTest(testtools.TestCase): def test_assert_namespace_in_hosts(self, hostnames: typing.Iterable[str] = None): - namespaces = topology.get_hosts_namespaces(hostnames=hostnames) + namespaces = osp_topology.get_hosts_namespaces(hostnames=hostnames) for namespace, hostnames in namespaces.items(): - topology.assert_namespace_in_hosts(namespace, - hostnames=hostnames) + osp_topology.assert_namespace_in_hosts(namespace, + hostnames=hostnames) def test_assert_namespace_in_hosts_with_hostnames(self): self.test_assert_namespace_in_hosts(hostnames=self.all_hostnames[:1]) def test_assert_namespaces_in_host_failure(self): self.assertRaises(self.failureException, - topology.assert_namespace_in_hosts, + osp_topology.assert_namespace_in_hosts, '') def test_assert_namespace_not_in_hosts( self, hostnames: typing.Iterable[str] = None): - topology.assert_namespace_not_in_hosts('', - hostnames=hostnames) + osp_topology.assert_namespace_not_in_hosts('', + hostnames=hostnames) def test_assert_namespace_not_in_hosts_with_hostnames(self): self.test_assert_namespace_not_in_hosts( hostnames=self.all_hostnames[:1]) def test_assert_namespace_not_in_hosts_failure(self): - namespaces = topology.get_hosts_namespaces() + namespaces = osp_topology.get_hosts_namespaces() for namespace in namespaces: self.assertRaises(self.failureException, - topology.assert_namespace_not_in_hosts, + osp_topology.assert_namespace_not_in_hosts, namespace) diff --git a/tobiko/tests/functional/podified/test_topology.py b/tobiko/tests/functional/podified/test_topology.py index 23950ab50..b7e9c6797 100644 --- a/tobiko/tests/functional/podified/test_topology.py +++ b/tobiko/tests/functional/podified/test_topology.py @@ -16,7 +16,7 @@ from __future__ import absolute_import import tobiko -from tobiko.openstack import topology +from tobiko.openstack import topology as osp_topology from tobiko.shell import ping from tobiko.shell import sh from tobiko.tests.functional.openstack import test_topology @@ -26,7 +26,7 @@ from tobiko import podified @podified.skip_if_not_podified class PodifiedTopologyTest(test_topology.OpenStackTopologyTest): - expected_group: topology.OpenstackGroupNamesType = 'compute' + expected_group: osp_topology.OpenstackGroupNamesType = 'compute' @property def topology(self) -> podified.PodifiedTopology: diff --git a/tobiko/tests/sanity/containers/test_containers.py b/tobiko/tests/sanity/containers/test_containers.py index 573184492..3b0645c36 100644 --- a/tobiko/tests/sanity/containers/test_containers.py +++ b/tobiko/tests/sanity/containers/test_containers.py @@ -218,6 +218,8 @@ class TripleoContainersHealthTest(BaseContainersHealtTest): containers' states: ~/expected_containers_list_df.csv' second time it creates a current containers states list and compares them, they must be identical""" + + expected_containers_list_df = [] # if we have a file or an explicit variable use that , # otherwise create and return if recreate_expected or (not (expected_containers_list or @@ -358,6 +360,8 @@ class PodifiedContainersHealthTest(BaseContainersHealtTest): containers' states: ~/expected_containers_list_df.csv' second time it creates a current containers states list and compares them, they must be identical""" + + expected_containers_list_df = [] # if we have a file or an explicit variable use that , # otherwise create and return if recreate_expected or (not (expected_containers_list or diff --git a/tobiko/tests/unit/test_exception.py b/tobiko/tests/unit/test_exception.py index b14ec8db4..28d0ff5ec 100644 --- a/tobiko/tests/unit/test_exception.py +++ b/tobiko/tests/unit/test_exception.py @@ -111,6 +111,8 @@ class TestCheckValidType(unit.TobikoUnitTest): class TestExcInfo(unit.TobikoUnitTest): def test_exc_info(self): + exc_type, exc_value, traceback = None, None, None + exc_info = None try: raise RuntimeError('some error') except RuntimeError: diff --git a/tobiko/tripleo/containers.py b/tobiko/tripleo/containers.py index 29eb5e41a..cfaef97c7 100644 --- a/tobiko/tripleo/containers.py +++ b/tobiko/tripleo/containers.py @@ -521,6 +521,7 @@ def assert_equal_containers_state(expected_containers_list=None, second time it creates a current containers states list and compares them, they must be identical""" + expected_containers_list_df = [] # if we have a file or an explicit variable use that , otherwise create # and return if recreate_expected or (