From 00751f5ba72e1a229b2e18b0dd6682761e12f1e7 Mon Sep 17 00:00:00 2001 From: Alexey Stepanov Date: Wed, 30 Mar 2016 16:58:18 +0300 Subject: [PATCH] Pylint: python3 critical issues 1. Use print_function 2. from six.moves import xrange 3. iterate over generators 4. use six.moves blueprint fuel-qa-python3-compatibility Change-Id: Ie18305cc4c203f00913e58f734893368cabc7596 --- devops/error.py | 14 +++++------- devops/helpers/helpers.py | 40 ++++++++++++++++++---------------- devops/helpers/node_manager.py | 2 ++ devops/helpers/templates.py | 2 +- devops/models/base.py | 2 +- devops/models/node.py | 4 +++- devops/settings.py | 2 +- devops/shell.py | 9 ++++++-- devops/tests/test_manager.py | 1 + devops/tests/use_cases.py | 2 +- setup.py | 1 + 11 files changed, 45 insertions(+), 34 deletions(-) diff --git a/devops/error.py b/devops/error.py index e2ca27a0..9522689e 100644 --- a/devops/error.py +++ b/devops/error.py @@ -16,6 +16,7 @@ class DevopsError(Exception): def __init__(self, message): self.message = message + super(DevopsError, self).__init__() def __str__(self): return self.message @@ -30,13 +31,11 @@ class DevopsCalledProcessError(DevopsError): self.returncode = returncode self.cmd = command self.output = output - - def __str__(self): message = "Command '%s' returned non-zero exit status %s" % ( self.cmd, self.returncode) if self.output: - message += "\n%s" % '\n'.join(self.output) - return message + message += "\n{}".format('\n'.join(self.output)) + super(DevopsCalledProcessError, self).__init__(message) class DevopsNotImplementedError(DevopsError): @@ -46,10 +45,9 @@ class DevopsNotImplementedError(DevopsError): class DevopsEnvironmentError(DevopsError): def __init__(self, command): self.cmd = command - - def __str__(self): - message = "Command '{0}' is not found".format(self.cmd) - return message + super(DevopsEnvironmentError, self).__init__( + "Command '{0}' is not found".format(self.cmd) + ) class TimeoutError(DevopsError): diff --git a/devops/helpers/helpers.py b/devops/helpers/helpers.py index 50c21c4c..6bda2890 100644 --- a/devops/helpers/helpers.py +++ b/devops/helpers/helpers.py @@ -14,7 +14,6 @@ from __future__ import absolute_import -import httplib import json import logging import os @@ -23,10 +22,13 @@ import socket import ssl import stat import time -import urllib2 -import xmlrpclib import paramiko +# pylint: disable=import-error +from six.moves import http_client +from six.moves.urllib import request +from six.moves import xmlrpc_client +# pylint: enable=import-error from devops.error import AuthenticationError from devops.error import DevopsCalledProcessError @@ -40,8 +42,7 @@ from devops.settings import SSH_SLAVE_CREDENTIALS def get_free_port(): - ports = range(32000, 32100) - for port in ports: + for port in range(32000, 32100): if not tcp_ping('localhost', port): return port raise DevopsError('No free ports available') @@ -123,7 +124,7 @@ def _wait(raising_predicate, expected=Exception, interval=5, timeout=None): def http(host='localhost', port=80, method='GET', url='/', waited_code=200): try: - conn = httplib.HTTPConnection(str(host), int(port)) + conn = http_client.HTTPConnection(str(host), int(port)) conn.request(method, url) res = conn.getresponse() @@ -283,8 +284,9 @@ class SSHClient(object): @retry(count=3, delay=3) def connect(self): logging.debug( - "Connect to '%s:%s' as '%s:%s'" % ( - self.host, self.port, self.username, self.password)) + "Connect to '{host}:{port}' as '{user}:{passwd}'".format( + host=self.host, port=self.port, + user=self.username, passwd=self.password)) for private_key in self.private_keys: try: return self._ssh.connect( @@ -326,7 +328,7 @@ class SSHClient(object): for remote in remotes: cmd = "%s\n" % command if remote.sudo_mode: - cmd = 'sudo -S bash -c "%s"' % cmd.replace('"', '\\"') + cmd = 'sudo -S bash -c "{}"'.format(cmd.replace('"', '\\"')) chan = remote._ssh.get_transport().open_session() chan.exec_command(cmd) futures[remote] = chan @@ -338,7 +340,7 @@ class SSHClient(object): raise DevopsCalledProcessError(command, errors) def execute(self, command, verbose=False): - chan, stdin, stderr, stdout = self.execute_async(command) + chan, _, stderr, stdout = self.execute_async(command) result = { 'stdout': [], 'stderr': [], @@ -357,7 +359,7 @@ class SSHClient(object): return result def execute_async(self, command): - logging.debug("Executing command: '%s'" % command.rstrip()) + logging.debug("Executing command: '{}'".format(command.rstrip())) chan = self._ssh.get_transport().open_session() stdin = chan.makefile('wb') stdout = chan.makefile('rb') @@ -397,7 +399,7 @@ class SSHClient(object): self._sftp.put(source, target) return - for rootdir, subdirs, files in os.walk(source): + for rootdir, _, files in os.walk(source): targetdir = os.path.normpath( os.path.join( target, @@ -461,7 +463,7 @@ def ssh(*args, **kwargs): def xmlrpctoken(uri, login, password): - server = xmlrpclib.Server(uri) + server = xmlrpc_client.Server(uri) try: return server.login(login, password) except Exception: @@ -469,7 +471,7 @@ def xmlrpctoken(uri, login, password): def xmlrpcmethod(uri, method): - server = xmlrpclib.Server(uri) + server = xmlrpc_client.Server(uri) try: return getattr(server, method) except Exception: @@ -502,22 +504,22 @@ def get_nodes(admin_ip): url = "https://{}:8443".format(admin_ip) endpoint = '/api/nodes/' keystone_url = "http://{}:5000/v2.0/tokens".format(admin_ip) - tokens_request = urllib2.Request(keystone_url) + tokens_request = request.Request(keystone_url) tokens_request.add_header('Content-Type', 'application/json') tokens_request.add_data(auth_data) - tokens_response = urllib2.urlopen(tokens_request) + tokens_response = request.urlopen(tokens_request) tokens_dct = json.load(tokens_response) token = tokens_dct['access']['token']['id'] - nodes_request = urllib2.Request(url + endpoint) + nodes_request = request.Request(url + endpoint) nodes_request.add_header('X-Auth-Token', token) # pylint: disable=protected-access # Note: this API is accessible not on all Python 2.7 versions, # so use if-else if hasattr(ssl, '_create_unverified_context'): - nodes_response = urllib2.urlopen( + nodes_response = request.urlopen( nodes_request, context=ssl._create_unverified_context()) else: - nodes_response = urllib2.urlopen(nodes_request) + nodes_response = request.urlopen(nodes_request) # pylint: enable=protected-access nodes = json.load(nodes_response) return nodes diff --git a/devops/helpers/node_manager.py b/devops/helpers/node_manager.py index f444ebd4..32c3880e 100644 --- a/devops/helpers/node_manager.py +++ b/devops/helpers/node_manager.py @@ -12,6 +12,8 @@ # License for the specific language governing permissions and limitations # under the License. +from __future__ import print_function + from devops.helpers.helpers import get_admin_remote from devops.helpers.helpers import get_keys from devops.helpers.helpers import wait diff --git a/devops/helpers/templates.py b/devops/helpers/templates.py index 7bf008e6..ab39edcf 100644 --- a/devops/helpers/templates.py +++ b/devops/helpers/templates.py @@ -25,7 +25,7 @@ def yaml_template_load(config_file): raise ValueError( "Cannot load the environment template {0} : include file {1} " "doesn't exist.".format(config_file, file_name)) - with file(file_name) as inputfile: + with open(file_name) as inputfile: return yaml.load(inputfile) def yaml_get_env_variable(loader, node): diff --git a/devops/models/base.py b/devops/models/base.py index b5835479..51f432cf 100644 --- a/devops/models/base.py +++ b/devops/models/base.py @@ -22,7 +22,7 @@ from django.utils.importlib import import_module def choices(*args, **kwargs): defaults = {'max_length': 255, 'null': False} defaults.update(kwargs) - defaults.update(choices=zip(args, args)) + defaults.update(choices=dict(zip(args, args))) return models.CharField(**defaults) diff --git a/devops/models/node.py b/devops/models/node.py index a603cffb..4dd8fe58 100644 --- a/devops/models/node.py +++ b/devops/models/node.py @@ -12,6 +12,8 @@ # License for the specific language governing permissions and limitations # under the License. +from __future__ import print_function + import json from django.conf import settings @@ -458,7 +460,7 @@ class Node(DriverModel): 'cinder': 50 * 1024 ** 3, } - for diskname, capacity in disknames_capacity.iteritems(): + for diskname, capacity in disknames_capacity.items(): self.attach_disk(name=diskname, capacity=capacity, force_define=force_define) diff --git a/devops/settings.py b/devops/settings.py index 962733f0..bab2ce10 100644 --- a/devops/settings.py +++ b/devops/settings.py @@ -137,7 +137,7 @@ if MULTIPLE_NETWORKS: ADMIN_FORWARD = os.environ.get('ADMIN_FORWARD', 'nat') PUBLIC_FORWARD = os.environ.get('PUBLIC_FORWARD', 'nat') else: - NODEGROUPS = {} + NODEGROUPS = () FORWARD_DEFAULT = os.environ.get('FORWARD_DEFAULT', None) ADMIN_FORWARD = os.environ.get('ADMIN_FORWARD', FORWARD_DEFAULT or 'nat') PUBLIC_FORWARD = os.environ.get('PUBLIC_FORWARD', FORWARD_DEFAULT or 'nat') diff --git a/devops/shell.py b/devops/shell.py index 46727719..2a32e956 100644 --- a/devops/shell.py +++ b/devops/shell.py @@ -12,12 +12,17 @@ # License for the specific language governing permissions and limitations # under the License. +from __future__ import print_function + import argparse import collections import os import sys from netaddr import IPNetwork +# pylint: disable=redefined-builtin +from six.moves import xrange +# pylint: enable=redefined-builtin import tabulate import devops @@ -133,7 +138,7 @@ class Shell(object): def do_snapshot_delete(self): for node in self.env.get_nodes(): - snaps = map(lambda x: x.name, node.get_snapshots()) + snaps = [elem.name for elem in node.get_snapshots()] if self.snapshot_name in snaps: node.erase_snapshot(name=self.snapshot_name) @@ -278,7 +283,7 @@ class Shell(object): iso_path = self.params.iso_path iso_size = _get_file_size(iso_path) - if not (iso_size > 0): + if iso_size <= 0: print("Please, set correct ISO file") sys.exit(1) if networks is None: diff --git a/devops/tests/test_manager.py b/devops/tests/test_manager.py index 580a9b2e..f7ca0d3c 100644 --- a/devops/tests/test_manager.py +++ b/devops/tests/test_manager.py @@ -12,6 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. +from __future__ import print_function from django.test import TestCase import mock diff --git a/devops/tests/use_cases.py b/devops/tests/use_cases.py index 3a462846..54e5520e 100644 --- a/devops/tests/use_cases.py +++ b/devops/tests/use_cases.py @@ -32,7 +32,7 @@ class UseCases(unittest.TestCase): 'centos6.4-base.qcow2': '/tmp/centos6.4-base.qcow2', } - for name, vol in images_for_upload.iteritems(): + for name, vol in images_for_upload.items(): v = Volume.volume_create(name, _get_file_size(vol)) if not self.driver.volume_exists(v): self.driver.volume_define(v) diff --git a/setup.py b/setup.py index 2000c214..7a14bc55 100644 --- a/setup.py +++ b/setup.py @@ -48,5 +48,6 @@ setup( 'pytest-django >= 2.8.0', 'mock>=1.0.1', 'sphinx', + 'six' ] )