From a110e483e8644ab73e69853ea11b6c4c6cfa04b6 Mon Sep 17 00:00:00 2001
From: Ryan Harper <ryan.harper@canonical.com>
Date: Wed, 6 Dec 2017 16:30:22 -0600
Subject: pylint: Update pylint to 1.7.1, run on tests/ and tools and fix
 complaints.

The motivation for this is that
 a.) 1.7.1 runs with python 3.6 (bionic)
 b.) we want to run pylint on tests/ and tools for the same reasons
     that we want to run it on cloudinit/

The changes are described below.
- Update tox.ini to invoke pylint v1.7.1.
- Modify .pylintrc generated-members ignore mocked object members (m_.*)
- Replace "dangerous" params defaulting to {}
- Fix up cloud_tests use of platforms
- Cast some instance objects to with dict()
- Handle python2.7 vs 3+ ConfigParser use of readfp (deprecated)
- Update use of assertEqual(<boolean>, value) to assert<Boolean>(value)
- replace depricated assertRegexp -> assertRegex
- Remove useless test-class calls to super class
- Assign class property accessors a result and use it
- Fix missing class member in CepkoResultTests
- Fix Cheetah test import
---
 tools/hacking.py   | 172 -----------------------------------------------------
 tools/make-mime.py |   2 +-
 tools/mock-meta.py |  45 +++++++-------
 3 files changed, 22 insertions(+), 197 deletions(-)
 delete mode 100755 tools/hacking.py

(limited to 'tools')

diff --git a/tools/hacking.py b/tools/hacking.py
deleted file mode 100755
index e6a05136..00000000
--- a/tools/hacking.py
+++ /dev/null
@@ -1,172 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012, Cloudscaling
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-"""cloudinit HACKING file compliance testing (based off of nova hacking.py)
-
-built on top of pep8.py
-"""
-
-import inspect
-import logging
-import re
-import sys
-
-import pep8
-
-# Don't need this for testing
-logging.disable('LOG')
-
-# N1xx comments
-# N2xx except
-# N3xx imports
-# N4xx docstrings
-# N[5-9]XX (future use)
-
-DOCSTRING_TRIPLE = ['"""', "'''"]
-VERBOSE_MISSING_IMPORT = False
-_missingImport = set([])
-
-
-def import_normalize(line):
-    # convert "from x import y" to "import x.y"
-    # handle "from x import y as z" to "import x.y as z"
-    split_line = line.split()
-    if (line.startswith("from ") and "," not in line and
-       split_line[2] == "import" and split_line[3] != "*" and
-       split_line[1] != "__future__" and
-       (len(split_line) == 4 or (len(split_line) == 6 and
-                                 split_line[4] == "as"))):
-        return "import %s.%s" % (split_line[1], split_line[3])
-    else:
-        return line
-
-
-def cloud_import_alphabetical(physical_line, line_number, lines):
-    """Check for imports in alphabetical order.
-
-    HACKING guide recommendation for imports:
-    imports in human alphabetical order
-    N306
-    """
-    # handle import x
-    # use .lower since capitalization shouldn't dictate order
-    split_line = import_normalize(physical_line.strip()).lower().split()
-    split_previous = import_normalize(lines[line_number - 2])
-    split_previous = split_previous.strip().lower().split()
-    # with or without "as y"
-    length = [2, 4]
-    if (len(split_line) in length and len(split_previous) in length and
-            split_line[0] == "import" and split_previous[0] == "import"):
-        if split_line[1] < split_previous[1]:
-            return (0, "N306: imports not in alphabetical order (%s, %s)"
-                    % (split_previous[1], split_line[1]))
-
-
-def cloud_docstring_start_space(physical_line):
-    """Check for docstring not start with space.
-
-    HACKING guide recommendation for docstring:
-    Docstring should not start with space
-    N401
-    """
-    pos = max([physical_line.find(i) for i in DOCSTRING_TRIPLE])  # start
-    if (pos != -1 and len(physical_line) > pos + 1):
-        if (physical_line[pos + 3] == ' '):
-            return (pos,
-                    "N401: one line docstring should not start with a space")
-
-
-def cloud_todo_format(physical_line):
-    """Check for 'TODO()'.
-
-    HACKING guide recommendation for TODO:
-    Include your name with TODOs as in "#TODO(termie)"
-    N101
-    """
-    pos = physical_line.find('TODO')
-    pos1 = physical_line.find('TODO(')
-    pos2 = physical_line.find('#')  # make sure it's a comment
-    if (pos != pos1 and pos2 >= 0 and pos2 < pos):
-        return pos, "N101: Use TODO(NAME)"
-
-
-def cloud_docstring_one_line(physical_line):
-    """Check one line docstring end.
-
-    HACKING guide recommendation for one line docstring:
-    A one line docstring looks like this and ends in a period.
-    N402
-    """
-    pos = max([physical_line.find(i) for i in DOCSTRING_TRIPLE])  # start
-    end = max([physical_line[-4:-1] == i for i in DOCSTRING_TRIPLE])  # end
-    if (pos != -1 and end and len(physical_line) > pos + 4):
-        if (physical_line[-5] != '.'):
-            return pos, "N402: one line docstring needs a period"
-
-
-def cloud_docstring_multiline_end(physical_line):
-    """Check multi line docstring end.
-
-    HACKING guide recommendation for docstring:
-    Docstring should end on a new line
-    N403
-    """
-    pos = max([physical_line.find(i) for i in DOCSTRING_TRIPLE])  # start
-    if (pos != -1 and len(physical_line) == pos):
-        print(physical_line)
-        if (physical_line[pos + 3] == ' '):
-            return (pos, "N403: multi line docstring end on new line")
-
-
-current_file = ""
-
-
-def readlines(filename):
-    """Record the current file being tested."""
-    pep8.current_file = filename
-    return open(filename).readlines()
-
-
-def add_cloud():
-    """Monkey patch pep8 for cloud-init guidelines.
-
-    Look for functions that start with cloud_
-    and add them to pep8 module.
-
-    Assumes you know how to write pep8.py checks
-    """
-    for name, function in globals().items():
-        if not inspect.isfunction(function):
-            continue
-        if name.startswith("cloud_"):
-            exec("pep8.%s = %s" % (name, name))
-
-
-if __name__ == "__main__":
-    # NOVA based 'hacking.py' error codes start with an N
-    pep8.ERRORCODE_REGEX = re.compile(r'[EWN]\d{3}')
-    add_cloud()
-    pep8.current_file = current_file
-    pep8.readlines = readlines
-    try:
-        pep8._main()
-    finally:
-        if len(_missingImport) > 0:
-            sys.stderr.write(
-                "%i imports missing in this test environment\n" %
-                len(_missingImport))
-
-# vi: ts=4 expandtab
diff --git a/tools/make-mime.py b/tools/make-mime.py
index f6a72044..d321479b 100755
--- a/tools/make-mime.py
+++ b/tools/make-mime.py
@@ -23,7 +23,7 @@ def file_content_type(text):
         filename, content_type = text.split(":", 1)
         return (open(filename, 'r'), filename, content_type.strip())
     except ValueError:
-        raise argparse.ArgumentError("Invalid value for %r" % (text))
+        raise argparse.ArgumentError(text, "Invalid value for %r" % (text))
 
 
 def main():
diff --git a/tools/mock-meta.py b/tools/mock-meta.py
index a5d14ab7..724f7fc4 100755
--- a/tools/mock-meta.py
+++ b/tools/mock-meta.py
@@ -17,6 +17,7 @@ Then:
   ec2metadata --instance-id
 """
 
+import argparse
 import functools
 import json
 import logging
@@ -27,8 +28,6 @@ import string
 import sys
 import yaml
 
-from optparse import OptionParser
-
 try:
     from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
     import httplib as hclient
@@ -415,29 +414,27 @@ def setup_logging(log_level, fmt='%(levelname)s: @%(name)s : %(message)s'):
 
 
 def extract_opts():
-    parser = OptionParser()
-    parser.add_option("-p", "--port", dest="port", action="store", type=int,
-                      default=80, metavar="PORT",
-                      help=("port from which to serve traffic"
-                            " (default: %default)"))
-    parser.add_option("-a", "--addr", dest="address", action="store", type=str,
-                      default='::', metavar="ADDRESS",
-                      help=("address from which to serve traffic"
-                            " (default: %default)"))
-    parser.add_option("-f", '--user-data-file', dest='user_data_file',
-                      action='store', metavar='FILE',
-                      help=("user data filename to serve back to"
-                            "incoming requests"))
-    (options, args) = parser.parse_args()
-    out = dict()
-    out['extra'] = args
-    out['port'] = options.port
-    out['user_data_file'] = None
-    out['address'] = options.address
-    if options.user_data_file:
-        if not os.path.isfile(options.user_data_file):
+    parser = argparse.ArgumentParser()
+    parser.add_argument("-p", "--port", dest="port", action="store", type=int,
+                        default=80, metavar="PORT",
+                        help=("port from which to serve traffic"
+                              " (default: %default)"))
+    parser.add_argument("-a", "--addr", dest="address", action="store",
+                        type=str, default='::', metavar="ADDRESS",
+                        help=("address from which to serve traffic"
+                              " (default: %default)"))
+    parser.add_argument("-f", '--user-data-file', dest='user_data_file',
+                        action='store', metavar='FILE',
+                        help=("user data filename to serve back to"
+                              "incoming requests"))
+    parser.add_argument('extra', nargs='*')
+    args = parser.parse_args()
+    out = {'port': args.port, 'address': args.address, 'extra': args.extra,
+           'user_data_file': None}
+    if args.user_data_file:
+        if not os.path.isfile(args.user_data_file):
             parser.error("Option -f specified a non-existent file")
-        with open(options.user_data_file, 'rb') as fh:
+        with open(args.user_data_file, 'rb') as fh:
             out['user_data_file'] = fh.read()
     return out
 
-- 
cgit v1.2.3