diff --git a/404main b/404main index eae6d26..ab268a5 100755 --- a/404main +++ b/404main @@ -95,7 +95,9 @@ def find_main(cache, pack): got_src = True break if got_src: + # pylint: disable=E1101 for deptype, all_deps in src_records.build_depends.iteritems(): + # pylint: enable=E1101 for or_deps in all_deps: base_deps = [] for (name, ver, op) in or_deps: diff --git a/debian/changelog b/debian/changelog index dce2376..1f26a8f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -21,6 +21,7 @@ ubuntu-dev-tools (0.109) UNRELEASED; urgency=low - 404main, merge-changelog, pull-debian-debdiff, pull-debian-source, pull-revu-source: + Return 0 after showing help. + - Run pylint on Python source code. * ubuntutools/common.py: Remove https_proxy unsetting code, working around LP: #94130. * edit-patch: Don't let cat error through if debian/source/format doesn't @@ -50,7 +51,7 @@ ubuntu-dev-tools (0.109) UNRELEASED; urgency=low * add "add-patch" that provides the non-interactive version of edit-patch - -- Stefano Rivera Sun, 26 Dec 2010 20:14:54 +0200 + -- Stefano Rivera Sun, 26 Dec 2010 21:56:07 +0200 ubuntu-dev-tools (0.108) experimental; urgency=low diff --git a/debian/control b/debian/control index 2113287..89c9ee7 100644 --- a/debian/control +++ b/debian/control @@ -12,6 +12,7 @@ Build-Depends: dctrl-tools, libapt-pkg-perl, libwww-perl, lsb-release, + pylint, python-all (>= 2.6.5-13~), python-apt (>= 0.7.93~), python-debian (>= 0.1.15), diff --git a/dgetlp b/dgetlp index ce51086..16bde9d 100755 --- a/dgetlp +++ b/dgetlp @@ -34,7 +34,7 @@ import hashlib import subprocess import GnuPGInterface from cStringIO import StringIO -from email import FeedParser +from email.feedparser import FeedParser Usage = u"""Usage: %prog [-d|(-v|-q)] @@ -75,7 +75,7 @@ def Unsign(data): return plain def getEntries(data): - parser = FeedParser.FeedParser() + parser = FeedParser() parser.feed(data) return parser.close() diff --git a/manage-credentials b/manage-credentials index d24bee0..94da717 100755 --- a/manage-credentials +++ b/manage-credentials @@ -80,7 +80,7 @@ class CmdOptions(OptionParser): elif options.level.upper() in LEVEL.values(): options.level = options.level.upper() else: - self.error("Unknown access-level '%s', level must be in %s" %(options.level, self.LEVEL)) + self.error("Unknown access-level '%s', level must be in %s" %(options.level, LEVEL)) return tool, options def create_credentials(options): diff --git a/ubuntutools/lp/lpapicache.py b/ubuntutools/lp/lpapicache.py index e5bf441..0e44e92 100644 --- a/ubuntutools/lp/lpapicache.py +++ b/ubuntutools/lp/lpapicache.py @@ -51,7 +51,7 @@ __all__ = [ _POCKETS = ('Release', 'Security', 'Updates', 'Proposed', 'Backports') -class Launchpad(object): +class _Launchpad(object): '''Singleton for LP API access.''' def login(self, service=service): @@ -81,7 +81,7 @@ class Launchpad(object): def __call__(self): return self -Launchpad = Launchpad() +Launchpad = _Launchpad() class MetaWrapper(type): diff --git a/ubuntutools/test/pylint.conf b/ubuntutools/test/pylint.conf new file mode 100644 index 0000000..890de6e --- /dev/null +++ b/ubuntutools/test/pylint.conf @@ -0,0 +1,14 @@ +[TYPECHECK] + +# List of classes names for which member attributes should not be checked +# (useful for classes with attributes dynamically set). +ignored-classes=Launchpad,BaseWrapper,PersonTeam,Distribution,Consumer,Credentials + +[FORMAT] + +# Maximum number of characters on a single line. +max-line-length=80 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' diff --git a/ubuntutools/test/test_pylint.py b/ubuntutools/test/test_pylint.py new file mode 100644 index 0000000..9d21d7c --- /dev/null +++ b/ubuntutools/test/test_pylint.py @@ -0,0 +1,65 @@ +# test_pylint.py - Run pylint in errors-only mode. +# +# Copyright (C) 2010, Stefano Rivera +# +# 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. + +import re +import subprocess + +import setup +from ubuntutools.test import unittest + +WHITELIST = [re.compile(': %s$' % x) for x in ( + # Wildcard import: + r"No name '\w+Error' in module 'launchpadlib\.errors'", + # http://www.logilab.org/ticket/51250: + r"Module 'hashlib' has no '(md5|sha(1|224|256|384|512))' member", +)] + +class PylintTestCase(unittest.TestCase): + def test_pylint(self): + "Test: Run pylint on Python source code" + files = ['ubuntutools'] + for script in setup.scripts: + f = open(script, 'r') + if 'python' in f.readline(): + files.append(script) + f.close() + p = subprocess.Popen(['pylint', '--rcfile=ubuntutools/test/pylint.conf', + '-E', '--include-ids=y', '--'] + files, + stdout=subprocess.PIPE, stderr=subprocess.PIPE, + close_fds=True) + + out, err = p.communicate() + self.assertEqual(err, '') + + filtered_out = [] + detected_in = '' + # pylint: disable=E1103 + for line in out.splitlines(): + # pylint: enable=E1103 + if line.startswith('************* '): + detected_in = line + continue + + for r in WHITELIST: + if r.search(line): + break + else: + filtered_out.append(detected_in) + filtered_out.append(line) + + self.assertEqual(filtered_out, [], + "pylint found errors.\n" + "Filtered Output:\n" + '\n'.join(filtered_out))