[devscripts] 02/03: Update Python unittests to support pylint 1.8
Benjamin Drung
bdrung at moszumanska.debian.org
Sun Feb 4 22:45:11 UTC 2018
This is an automated email from the git hooks/post-receive script.
bdrung pushed a commit to branch master
in repository devscripts.
commit 6f363da04bfe27cb7376764e62d636b3588e6157
Author: Benjamin Drung <bdrung at debian.org>
Date: Sun Feb 4 21:10:00 2018 +0100
Update Python unittests to support pylint 1.8
Import latest version from https://github.com/bdrung/snippets
Also raise the maximum line length for pylint to 99 (flake8 already has this
value set).
Signed-off-by: Benjamin Drung <bdrung at debian.org>
---
scripts/devscripts/test/__init__.py | 64 +++++++++++++++++--------
scripts/devscripts/test/pylint.conf | 35 ++++++++++++--
scripts/devscripts/test/test_pylint.py | 88 +++++++++++++++++-----------------
scripts/setup.py | 2 +-
4 files changed, 121 insertions(+), 68 deletions(-)
diff --git a/scripts/devscripts/test/__init__.py b/scripts/devscripts/test/__init__.py
index 3de1e9e..f8769fd 100644
--- a/scripts/devscripts/test/__init__.py
+++ b/scripts/devscripts/test/__init__.py
@@ -1,26 +1,21 @@
-# Test suite for devscripts
-#
-# Copyright (C) 2010, Stefano Rivera <stefanor at ubuntu.com>
+# Copyright (C) 2017, Benjamin Drung <benjamin.drung at profitbricks.com>
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-# PERFORMANCE OF THIS SOFTWARE.
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+import inspect
import os
import sys
-
-if sys.version_info < (2, 7):
- import unittest2 as unittest
-else:
- import unittest
+import unittest
SCRIPTS = [
"debdiff-apply",
@@ -31,8 +26,37 @@ SCRIPTS = [
]
-def discover():
- # import __main__ triggers code re-execution
- __main__ = sys.modules['__main__']
- setupDir = os.path.abspath(os.path.dirname(__main__.__file__))
- return unittest.defaultTestLoader.discover(setupDir)
+def get_source_files():
+ """Return a list of sources files/directories (to check with flake8/pylint)"""
+ modules = ["devscripts"]
+ py_files = ["setup.py"]
+
+ files = []
+ for code_file in SCRIPTS + modules + py_files:
+ is_script = code_file in SCRIPTS
+ if not os.path.exists(code_file):
+ # The alternative path is needed for Debian's pybuild
+ alternative = os.path.join(os.environ.get("OLDPWD", ""), code_file)
+ code_file = alternative if os.path.exists(alternative) else code_file
+ if is_script:
+ with open(code_file, "rb") as script_file:
+ shebang = script_file.readline().decode("utf-8")
+ if ((sys.version_info[0] == 3 and "python3" in shebang) or
+ ("python" in shebang and "python3" not in shebang)):
+ files.append(code_file)
+ else:
+ files.append(code_file)
+ return files
+
+
+def unittest_verbosity():
+ """Return the verbosity setting of the currently running unittest
+ program, or None if none is running.
+ """
+ frame = inspect.currentframe()
+ while frame:
+ self = frame.f_locals.get("self")
+ if isinstance(self, unittest.TestProgram):
+ return self.verbosity
+ frame = frame.f_back
+ return None
diff --git a/scripts/devscripts/test/pylint.conf b/scripts/devscripts/test/pylint.conf
index 984e234..67634b8 100644
--- a/scripts/devscripts/test/pylint.conf
+++ b/scripts/devscripts/test/pylint.conf
@@ -1,20 +1,47 @@
+[MESSAGES CONTROL]
+
+# Disable the message, report, category or checker with the given id(s). You
+# can either give multiple identifiers separated by comma (,) or put this
+# option multiple times (only on the command line, not in the configuration
+# file where it should appear only once).You can also use "--disable=all" to
+# disable everything first and then reenable specific checks. For example, if
+# you want to run only the similarities checker, you can use "--disable=all
+# --enable=similarities". If you want to run only the classes checker, but have
+# no Warning level messages displayed, use"--disable=all --enable=classes
+# --disable=W"
+disable=fixme,invalid-name,locally-disabled,missing-docstring
+
+
+[REPORTS]
+
+# Tells whether to display a full report or only the messages
+reports=no
+
+
[TYPECHECK]
# List of classes names for which member attributes should not be checked
# (useful for classes with attributes dynamically set).
-# lpapicache classes, urlparse
-ignored-classes=Launchpad,BaseWrapper,PersonTeam,Distribution,Consumer,Credentials,ParseResult
+ignored-classes=apt_pkg,magic
+
[FORMAT]
# Maximum number of characters on a single line.
-max-line-length=80
+max-line-length=99
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
# tab).
indent-string=' '
+
[BASIC]
# Allow variables called e, f, lp
-good-names=i,j,k,ex,Run,_,e,f,lp
+good-names=i,j,k,ex,Run,_,e,f,lp,fp
+
+
+[SIMILARITIES]
+
+# Minimum lines number of a similarity.
+min-similarity-lines=5
diff --git a/scripts/devscripts/test/test_pylint.py b/scripts/devscripts/test/test_pylint.py
index 591dfe0..6576df9 100644
--- a/scripts/devscripts/test/test_pylint.py
+++ b/scripts/devscripts/test/test_pylint.py
@@ -1,6 +1,5 @@
-# test_pylint.py - Run pylint in errors-only mode.
-#
-# Copyright (C) 2010, Stefano Rivera <stefanor at ubuntu.com>
+# Copyright (C) 2010, Stefano Rivera <stefanor at debian.org>
+# Copyright (C) 2017-2018, Benjamin Drung <bdrung at debian.org>
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -14,57 +13,60 @@
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
+"""test_pylint.py - Run pylint"""
+
+import os
import re
import subprocess
+import sys
import unittest
-from . import SCRIPTS
+from . import get_source_files, unittest_verbosity
-WHITELIST = [re.compile(': %s$' % x) for x in (
- # Wildcard import:
- r"No name '\w+Error' in module 'launchpadlib\.errors'",
- # https://www.logilab.org/ticket/51250:
- r"Module 'hashlib' has no '(md5|sha(1|224|256|384|512))' member",
- # mox:
- r"Instance of '.+' has no '(WithSideEffects|MultipleTimes|AndReturn)' "
- r"member",
-)]
+CONFIG = os.path.join(os.path.dirname(__file__), "pylint.conf")
class PylintTestCase(unittest.TestCase):
+ """
+ This unittest class provides a test that runs the pylint code check
+ on the Python source code. The list of source files is provided by
+ the get_source_files() function and pylint is purely configured via
+ a config file.
+ """
+
def test_pylint(self):
- "Test: Run pylint on Python source code"
- files = ['devscripts']
- for script in SCRIPTS:
- f = open(script, 'r', encoding='utf-8')
- if 'python' in f.readline():
- files.append(script)
- f.close()
- cmd = ['pylint3', '--rcfile=devscripts/test/pylint.conf', '-E',
- '--include-ids=y', '--'] + files
- process = subprocess.Popen(cmd, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE, close_fds=True)
+ """Test: Run pylint on Python source code"""
+ with open("/proc/self/cmdline", "r") as cmdline_file:
+ python_binary = cmdline_file.read().split("\0")[0]
+ cmd = [python_binary, "-m", "pylint", "--rcfile=" + CONFIG, "--"] + get_source_files()
+ env = os.environ.copy()
+ env["PYLINTHOME"] = ".pylint.d"
+ if unittest_verbosity() >= 2:
+ sys.stderr.write("Running following command:\n{}\n".format(" ".join(cmd)))
+ process = subprocess.Popen(cmd, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+ close_fds=True)
out, err = process.communicate()
- if err != '':
- raise unittest.SkipTest('pylint crashed :/')
- filtered_out = []
- detected_in = ''
- # pylint: disable=E1103
- for line in out.splitlines():
- # pylint: enable=E1103
- if line.startswith('************* '):
- detected_in = line
- continue
+ if process.returncode != 0:
+ # Strip trailing summary (introduced in pylint 1.7). This summary might look like:
+ #
+ # ------------------------------------
+ # Your code has been rated at 10.00/10
+ #
+ out = re.sub("^(-+|Your code has been rated at .*)$", "", out.decode(),
+ flags=re.MULTILINE).rstrip()
- for reg_exp in WHITELIST:
- if reg_exp.search(line):
- break
- else:
- filtered_out.append(detected_in)
- filtered_out.append(line)
+ # Strip logging of used config file (introduced in pylint 1.8)
+ err = re.sub("^Using config file .*\n", "", err.decode()).rstrip()
- self.assertEqual(filtered_out, [],
- "pylint found errors.\n"
- "Filtered Output:\n" + '\n'.join(filtered_out))
+ msgs = []
+ if err:
+ msgs.append("pylint exited with code {} and has unexpected output on stderr:\n{}"
+ .format(process.returncode, err))
+ if out:
+ msgs.append("pylint found issues:\n{}".format(out))
+ if not msgs:
+ msgs.append("pylint exited with code {} and has no output on stdout or stderr."
+ .format(process.returncode))
+ self.fail("\n".join(msgs))
diff --git a/scripts/setup.py b/scripts/setup.py
index b0e7bd2..5908616 100755
--- a/scripts/setup.py
+++ b/scripts/setup.py
@@ -25,5 +25,5 @@ if __name__ == '__main__':
version=get_version(),
scripts=SCRIPTS,
packages=['devscripts', 'devscripts/test'],
- test_suite='devscripts.test.discover',
+ test_suite='devscripts.test',
)
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/collab-maint/devscripts.git
More information about the devscripts-devel
mailing list