diff --git a/.pylintrc b/.pylintrc index 0fe3b56a..c4feb6a1 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 88136bba..fcacf67c 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 065ded9b..1edbd1be 100644 --- a/tobiko/actors/_actor.py +++ b/tobiko/actors/_actor.py @@ -32,6 +32,7 @@ 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 611c3115..165367db 100644 --- a/tobiko/actors/_proxy.py +++ b/tobiko/actors/_proxy.py @@ -76,6 +76,7 @@ def _handle_call(self, method: typing.Callable, *args, **kwargs) \ 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 @@ def _is_proxy_method(cls, obj) -> bool: 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 f5fd5087..20c89c0d 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 c8971516..f432c544 100644 --- a/tobiko/common/_fixture.py +++ b/tobiko/common/_fixture.py @@ -500,8 +500,7 @@ def get_fixture(self, 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 6bcb9dff..91231fa9 100644 --- a/tobiko/docker/_client.py +++ b/tobiko/docker/_client.py @@ -233,6 +233,7 @@ def __init__(self, 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 b4711f64..6d6f0b70 100644 --- a/tobiko/openstack/glance/_image.py +++ b/tobiko/openstack/glance/_image.py @@ -361,6 +361,7 @@ def __init__(self, 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 29b91a3c..5bc57ff4 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 19a81b36..4188645e 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 6049cbc8..c04d3102 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 fd908f2f..07b3ed1d 100644 --- a/tobiko/shell/ss.py +++ b/tobiko/shell/ss.py @@ -77,8 +77,7 @@ def __len__(self): 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 ac417cd1..b68baff7 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 8673d3d5..e7e86476 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 c99ccb52..dd319d05 100644 --- a/tobiko/tests/functional/openstack/test_topology.py +++ b/tobiko/tests/functional/openstack/test_topology.py @@ -26,7 +26,7 @@ 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 @@ @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 @@ def test_compute_group(self): 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 @@ def test_list_openstack_topology_with_hostnames(self): 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 @@ def test_list_nodes_processes(self): 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 @@ def test_list_nodes_processes(self): # 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 @@ def test_list_nodes_processes(self): # 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 @@ def test_list_nodes_processes(self): @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 @@ def selected_hostames(self, hostnames: typing.Iterable[str] = None) -> \ 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 @@ def test_get_hosts_namespaces_with_hostnames(self): 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 23950ab5..b7e9c679 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 @@ @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 57318449..3b0645c3 100644 --- a/tobiko/tests/sanity/containers/test_containers.py +++ b/tobiko/tests/sanity/containers/test_containers.py @@ -218,6 +218,8 @@ def test_equal_containers_state(self, expected_containers_list=None, 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 @@ def test_equal_containers_state(self, expected_containers_list=None, 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 b14ec8db..28d0ff5e 100644 --- a/tobiko/tests/unit/test_exception.py +++ b/tobiko/tests/unit/test_exception.py @@ -111,6 +111,8 @@ def _test_check_is_valid_type_when_invalid(self, obj, *valid_types): 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 29eb5e41..cfaef97c 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 (