diff options
Diffstat (limited to 'test')
259 files changed, 5347 insertions, 0 deletions
diff --git a/test/fulltest.sh b/test/fulltest.sh new file mode 100755 index 000000000..a62533915 --- /dev/null +++ b/test/fulltest.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +if [ $@ ] ; then + PYVERSIONS=$@ +else + PYVERSIONS="2.2 2.3 2.4" +fi + +for ver in $PYVERSIONS; do + echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" + echo `python$ver -V` + echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" + python$ver runtests.py + echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" + echo `python$ver -V` -OO + python$ver -OO runtests.py +done
\ No newline at end of file diff --git a/test/func_test.py b/test/func_test.py new file mode 100644 index 000000000..3de8891c8 --- /dev/null +++ b/test/func_test.py @@ -0,0 +1,193 @@ +# Copyright (c) 2002-2005 LOGILAB S.A. (Paris, FRANCE). +# http://www.logilab.fr/ -- mailto:contact@logilab.fr +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +"""functional/non regression tests for pylint""" + +__revision__ = '$Id: func_test.py,v 1.37 2005-12-28 14:58:22 syt Exp $' + +import unittest +import sys +import re +import new +from os import linesep +from os.path import exists + +from logilab.common import testlib + +from utils import get_tests_info, fix_path, TestReporter + +from pylint.lint import PyLinter +from pylint import checkers + +test_reporter = TestReporter() +linter = PyLinter() +linter.set_reporter(test_reporter) +linter.config.persistent = 0 +linter.quiet = 1 +checkers.initialize(linter) + +PY23 = sys.version_info >= (2, 3) +PY24 = sys.version_info >= (2, 4) + + +if linesep != '\n': + LINE_RGX = re.compile(linesep) + def ulines(string): + return LINE_RGX.sub('\n', string) +else: + def ulines(string): + return string + +INFO_TEST_RGX = re.compile('^func_i\d\d\d\d$') + +def exception_str(ex): + """function used to replace default __str__ method of exception instances""" + return 'in %s\n:: %s' % (ex.file, ', '.join(ex.args)) + +class LintTestUsingModule(testlib.TestCase): + + def test_functionality(self): + tocheck = ['input.'+self.module] + if self.depends: + tocheck += ['input.%s' % name.replace('.py', '') + for name, file in self.depends] + self._test(tocheck) + + def _test(self, tocheck): + if INFO_TEST_RGX.match(self.module): + linter.enable_message_category('I') + else: + linter.disable_message_category('I') + try: + linter.check(tocheck) + except Exception, ex: + # need finalization to restore a correct state + linter.reporter.finalize() + ex.file = tocheck + ex.__str__ = new.instancemethod(exception_str, ex, None) + raise + if self.module.startswith('func_noerror_'): + expected = '' + else: + output = open(self.output) + expected = output.read().strip() + output.close() + got = linter.reporter.finalize().strip() + try: + self.assertLinesEquals(got, expected) + except Exception, ex: + ex.file = tocheck + ex.__str__ = new.instancemethod(exception_str, ex, None) + raise # AssertionError('%s: %r\n!=\n%r\n\n%s' % (self.module, got, expected, ex)) + +class LintTestUsingFile(LintTestUsingModule): + + def test_functionality(self): + tocheck = ['input/' + self.module + '.py'] + if self.depends: + tocheck += ['input/%s' % name for name, file in self.depends] + self._test(tocheck) + + +class TestTests(unittest.TestCase): + """check that all testable messages have been checked""" + def test(self): + todo = linter._messages.keys() + for msg_id in test_reporter.message_ids.keys(): + todo.remove(msg_id) + todo.sort() + if PY23: + self.assertEqual(todo, ['E0503', 'F0002', 'F0202', 'F0321', 'I0001']) + else: + self.assertEqual(todo, ['F0002', 'F0202', 'F0321', 'I0001']) + + +def make_tests(filter_rgx): + """generate tests classes from test info + + return the list of generated test classes + """ + if filter_rgx: + is_to_run = re.compile(filter_rgx).match + else: + is_to_run = lambda x: 1 + tests = [] + for module_file, messages_file in get_tests_info('func_', '.py') + [('nonexistant', 'messages/nonexistant.txt')]: + # skip those tests with python >= 2.3 since py2.3 detects them by itself + if PY23 and module_file == "func_unknown_encoding.py": #"func_nonascii_noencoding.py"): + continue + if not PY24: + if module_file == "func_noerror_staticmethod_as_decorator.py" or \ + module_file.endswith('py24.py'): + continue + if not is_to_run(module_file): + continue + base = module_file.replace('func_', '').replace('.py', '') + dependancies = get_tests_info(base, '.py') + + class LintTestUsingModuleTC(LintTestUsingModule): + module = module_file.replace('.py', '') + output = messages_file + depends = dependancies or None + tests.append(LintTestUsingModuleTC) + + if MODULES_ONLY: + continue + + class LintTestUsingFileTC(LintTestUsingFile): + module = module_file.replace('.py', '') + output = exists(messages_file + '2') and (messages_file + '2') or messages_file + depends = dependancies or None + tests.append(LintTestUsingFileTC) + +## # special test for f0003 +## module_file, messages_file in get_tests_info('func_f0003', '.pyc') +## class LintTestSubclass(LintTest): +## module = module_file.replace('.pyc', '') +## output = messages_file +## depends = dependancies or None +## tests.append(LintTestSubclass) + + class LintBuiltinModuleTest(LintTestUsingModule): + output = 'messages/builtin_module.txt' + module = 'sys' + def test_functionality(self): + self._test(['sys']) + tests.append(LintBuiltinModuleTest) + + if not filter_rgx: + # test all features are tested :) + tests.append(TestTests) + + return tests + +FILTER_RGX = None +MODULES_ONLY = False + +def suite(): + return unittest.TestSuite([unittest.makeSuite(test) + for test in make_tests(FILTER_RGX)]) + +if __name__=='__main__': + if '-m' in sys.argv: + MODULES_ONLY = True + sys.argv.remove('-m') + + if len(sys.argv) > 1: + FILTER_RGX = sys.argv[1] + del sys.argv[1] + unittest.main(defaultTest='suite') + + diff --git a/test/func_test_sample_config.py b/test/func_test_sample_config.py new file mode 100644 index 000000000..a65482794 --- /dev/null +++ b/test/func_test_sample_config.py @@ -0,0 +1,30 @@ +# Copyright (c) 2002-2004 LOGILAB S.A. (Paris, FRANCE). +# http://www.logilab.fr/ -- mailto:contact@logilab.fr +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +"""functional tests using the sample configuration file, should behave exactly +as with the default configuration +""" +__revision__ = '$Id: func_test_sample_config.py,v 1.3 2005-04-15 10:40:24 syt Exp $' + +from func_test import * + +from os.path import join + +import pylint +sample_config = join(pylint.__path__[0], 'examples', 'pylintrc') +linter.load_file_configuration(sample_config) + +if __name__=='__main__': + unittest.main(defaultTest='suite') diff --git a/test/input/__init__.py b/test/input/__init__.py new file mode 100644 index 000000000..60e92b76c --- /dev/null +++ b/test/input/__init__.py @@ -0,0 +1 @@ +"""test""" diff --git a/test/input/func___future___import_not_first_stmt.py b/test/input/func___future___import_not_first_stmt.py new file mode 100644 index 000000000..2051a7b96 --- /dev/null +++ b/test/input/func___future___import_not_first_stmt.py @@ -0,0 +1,5 @@ +"""a docstring""" + +__revision__ = 1 +from __future__ import generators + diff --git a/test/input/func___name___access.py b/test/input/func___name___access.py new file mode 100644 index 000000000..25aed5cae --- /dev/null +++ b/test/input/func___name___access.py @@ -0,0 +1,21 @@ +# pylint: disable-msg=R0903,W0142 +"""test access to __name__ gives undefined member on new/old class instances +but not on new/old class object +""" + +__revision__ = 1 + +class Aaaa: + """old class""" + def __init__(self): + print self.__name__ + print self.__class__.__name__ +class NewClass(object): + """new class""" + + def __new__(cls, *args, **kwargs): + print 'new', cls.__name__ + return object.__new__(cls, *args, **kwargs) + + def __init__(self): + print 'init', self.__name__ diff --git a/test/input/func_attrs_definition_order.py b/test/input/func_attrs_definition_order.py new file mode 100644 index 000000000..eda02e13b --- /dev/null +++ b/test/input/func_attrs_definition_order.py @@ -0,0 +1,15 @@ +# pylint: disable-msg=R0903 +"""yo""" + +__revision__ = '$I$' + +class Aaaa: + """class with attributes defined in wrong order""" + def __init__(self): + var1 = self._var2 + self._var2 = 3 + print var1 + +class Bbbb(object): + """hop""" + __revision__ = __revision__ # no problemo marge diff --git a/test/input/func_bad_assigment_to_exception_var.py b/test/input/func_bad_assigment_to_exception_var.py new file mode 100644 index 000000000..b404cb351 --- /dev/null +++ b/test/input/func_bad_assigment_to_exception_var.py @@ -0,0 +1,31 @@ +# pylint:disable-msg=C0103 +"""ho ho ho""" +__revision__ = 'toto' + +import sys + +e = 1 +e2 = 'yo' +e3 = None +try: + raise e, 'toto' +except Exception, ex: + print ex + _, _, tb = sys.exc_info() + raise e2 + + +def func(): + """bla bla bla""" + raise e3 + +def reraise(): + """reraise a catched exception instance""" + try: + raise Exception() + except Exception, exc: + print exc + raise exc + +raise e3 + diff --git a/test/input/func_base_stmt_without_effect.py b/test/input/func_base_stmt_without_effect.py new file mode 100644 index 000000000..f282ff783 --- /dev/null +++ b/test/input/func_base_stmt_without_effect.py @@ -0,0 +1,15 @@ +""" + 'W0103': ('Statement seems to have no effect', + 'Used when a statement doesn\'t have (or at least seems to) \ + any effect.'), +""" + +__revision__ = '' + +__revision__ + +__revision__ <= 1 + +__revision__.lower() # ok + +[i for i in __revision__] # ko diff --git a/test/input/func_block_disable_msg.py b/test/input/func_block_disable_msg.py new file mode 100644 index 000000000..f82fbd58a --- /dev/null +++ b/test/input/func_block_disable_msg.py @@ -0,0 +1,87 @@ +"""pylint option block-disable-msg""" + +__revision__ = None + +class Foo(object): + """block-disable-msg test""" + + def __init__(self): + pass + + def meth1(self, arg): + """this issues a message""" + print self + + def meth2(self, arg): + """and this one not""" + # pylint: disable-msg=W0613 + print self\ + + "foo" + + def meth3(self): + """test one line disabling""" + # no error + print self.bla # pylint: disable-msg=E1101 + # error + print self.blop + + def meth4(self): + """test re-enabling""" + # pylint: disable-msg=E1101 + # no error + print self.bla + print self.blop + # pylint: enable-msg=E1101 + # error + print self.blip + + def meth5(self): + """test IF sub-block re-enabling""" + # pylint: disable-msg=E1101 + # no error + print self.bla + if self.blop: + # pylint: enable-msg=E1101 + # error + print self.blip + else: + # no error + print self.blip + # no error + print self.blip + + def meth6(self): + """test TRY/EXCEPT sub-block re-enabling""" + # pylint: disable-msg=E1101 + # no error + print self.bla + try: + # pylint: enable-msg=E1101 + # error + print self.blip + except UndefinedName: # pylint: disable-msg=E0602 + # no error + print self.blip + # no error + print self.blip + + def meth7(self): + """test one line block opening disabling""" + if self.blop: # pylint: disable-msg=E1101 + # error + print self.blip + else: + # error + print self.blip + # error + print self.blip + + + def meth8(self): + """test late disabling""" + # error + print self.blip + # pylint: disable-msg=E1101 + # no error + print self.bla + print self.blop diff --git a/test/input/func_class_members.py b/test/input/func_class_members.py new file mode 100644 index 000000000..8b2e969c2 --- /dev/null +++ b/test/input/func_class_members.py @@ -0,0 +1,31 @@ +# pylint: disable-msg=R0903 +"""test class members""" + +__revision__ = '' + +class MyClass: + """class docstring""" + + def __init__(self): + """init""" + self.correct = 1 + + def test(self): + """test""" + self.correct += 2 + self.incorrect += 2 + self.nonexistent1.truc() + self.nonexistent2[1] = 'hehe' + +class XYZMixin: + """access to undefined members should be ignored in mixin classes by + default + """ + def __init__(self): + print self.nonexistent + + +class NewClass(object): + """use object.__setattr__""" + def __init__(self): + self.__setattr__('toto', 'tutu') diff --git a/test/input/func_continue_not_in_loop.py b/test/input/func_continue_not_in_loop.py new file mode 100644 index 000000000..4186aa5fd --- /dev/null +++ b/test/input/func_continue_not_in_loop.py @@ -0,0 +1,14 @@ +"""this module produces a SyntaxError at execution time""" + +__revision__ = None + +def run(): + """simple function""" + if True: + continue + else: + break + +if __name__ == '__main__': + run() + diff --git a/test/input/func_dangerous_default.py b/test/input/func_dangerous_default.py new file mode 100644 index 000000000..0bf87278c --- /dev/null +++ b/test/input/func_dangerous_default.py @@ -0,0 +1,17 @@ +"""docstring""" + +__revision__ = '' + +HEHE = {} + +def function1(value = []): + """docstring""" + print value + +def function2(value = HEHE): + """docstring""" + print value + +def function3(value): + """docstring""" + print value diff --git a/test/input/func_docstring.py b/test/input/func_docstring.py new file mode 100644 index 000000000..7f2867292 --- /dev/null +++ b/test/input/func_docstring.py @@ -0,0 +1,48 @@ +# pylint: disable-msg=R0201 + +__revision__ = '' + +def function1(value): + # missing docstring + print value + +def function2(value): + """docstring""" + print value + +def function3(value): + """docstring""" + print value + +class AAAA: + # missing docstring + +## class BBBB: +## # missing docstring +## pass + +## class CCCC: +## """yeah !""" +## def method1(self): +## pass + +## def method2(self): +## """ yeah !""" +## pass + + def method1(self): + pass + + def method2(self): + """ yeah !""" + pass + + def __init__(self): + pass + +class DDDD(AAAA): + """yeah !""" + + def __init__(self): + AAAA.__init__(self) + diff --git a/test/input/func_dotted_ancestor.py b/test/input/func_dotted_ancestor.py new file mode 100644 index 000000000..2d2f571ee --- /dev/null +++ b/test/input/func_dotted_ancestor.py @@ -0,0 +1,11 @@ +"""bla""" + +__revision__ = 'yo' + + +from input import func_w0233 + +class Aaaa(func_w0233.AAAA): + """test dotted name in ancestors""" + def __init__(self): + func_w0233.AAAA.__init__(self) diff --git a/test/input/func_e0011.py b/test/input/func_e0011.py new file mode 100644 index 000000000..f2bb592cd --- /dev/null +++ b/test/input/func_e0011.py @@ -0,0 +1,5 @@ +# pylint:bouboule=1 +"""check unknown option +""" +__revision__ = 1 + diff --git a/test/input/func_e0012.py b/test/input/func_e0012.py new file mode 100644 index 000000000..11ef99fda --- /dev/null +++ b/test/input/func_e0012.py @@ -0,0 +1,5 @@ +# pylint:enable-msg=W04044 +"""check unknown option +""" +__revision__ = 1 + diff --git a/test/input/func_e0101.py b/test/input/func_e0101.py new file mode 100644 index 000000000..08e64028f --- /dev/null +++ b/test/input/func_e0101.py @@ -0,0 +1,11 @@ +# pylint: disable-msg=R0903 +"""test __init__ return +""" + +__revision__ = 'yo' + +class MyClass: + """dummy class""" + + def __init__(self): + return 1 diff --git a/test/input/func_e0203.py b/test/input/func_e0203.py new file mode 100644 index 000000000..d51de0de3 --- /dev/null +++ b/test/input/func_e0203.py @@ -0,0 +1,19 @@ +"""check for method without self as first argument +""" + +__revision__ = 0 + + +class Abcd: + """dummy class""" + def __init__(self): + pass + + def abcd(yoo): + """another test""" + + abcd = classmethod(abcd) + + def edf(self): + """justo ne more method""" + print 'yapudju in', self diff --git a/test/input/func_e0204.py b/test/input/func_e0204.py new file mode 100644 index 000000000..ecbc51c39 --- /dev/null +++ b/test/input/func_e0204.py @@ -0,0 +1,19 @@ +"""check for method without self as first argument +""" + +__revision__ = 0 + + +class Abcd: + """dummy class""" + + def __init__(truc): + """method without self""" + print 1 + + def abdc(yoo): + """another test""" + print yoo + def edf(self): + """just another method""" + print 'yapudju in', self diff --git a/test/input/func_e0205.py b/test/input/func_e0205.py new file mode 100644 index 000000000..2bb108998 --- /dev/null +++ b/test/input/func_e0205.py @@ -0,0 +1,17 @@ +# pylint: disable-msg=R0903 +"""check method hidding ancestor attribute +""" + +__revision__ = '' + +class Abcd: + """dummy""" + def __init__(self): + self.abcd = 1 + +class Cdef(Abcd): + """dummy""" + def abcd(self): + """test + """ + print self diff --git a/test/input/func_e0206.py b/test/input/func_e0206.py new file mode 100644 index 000000000..af32fd883 --- /dev/null +++ b/test/input/func_e0206.py @@ -0,0 +1,20 @@ +# pylint: disable-msg=R0903 +"""check for interface which are not classes""" + +__revision__ = None + +class Abcd: + """dummy""" + __implements__ = __revision__ + + def __init__(self): + self.attr = None + +class Cdef: + """dummy""" + __implements__ = (__revision__, Abcd) + + def __init__(self): + pass + + diff --git a/test/input/func_e0214.py b/test/input/func_e0214.py new file mode 100644 index 000000000..8a4ad323c --- /dev/null +++ b/test/input/func_e0214.py @@ -0,0 +1,18 @@ +"""mcs test""" + +__revision__ = 1 + +class MetaClass(type): + """a very intersting metaclass""" + def __new__(mcs, name, bases, cdict): + print mcs, name, bases, cdict + return type.__new__(mcs, name, bases, cdict) + + def whatever(self): + """should have mcs has first arg""" + print self + + def whatever_really(hop): + """could have anything has first arg""" + print hop + whatever_really = staticmethod(whatever_really) diff --git a/test/input/func_e0601.py b/test/input/func_e0601.py new file mode 100644 index 000000000..b8673df7f --- /dev/null +++ b/test/input/func_e0601.py @@ -0,0 +1,9 @@ +"""test local variable used before assigment +""" + +__revision__ = 0 + +def function(): + """dummy""" + print aaaa + aaaa = 1 diff --git a/test/input/func_empty_module.py b/test/input/func_empty_module.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/test/input/func_empty_module.py diff --git a/test/input/func_exceptions_raise_type_error.py b/test/input/func_exceptions_raise_type_error.py new file mode 100644 index 000000000..8c414b6be --- /dev/null +++ b/test/input/func_exceptions_raise_type_error.py @@ -0,0 +1,14 @@ +""" +'E0702': Raising an %s while only classes, instances or string are allowed + +Used when something which is neither a class, an instance or a string is +raised (i.e. a `TypeError` will be raised). +""" + +__revision__ = 1 + +if __revision__: + raise 1 + +if __revision__: + raise None diff --git a/test/input/func_f0001.py b/test/input/func_f0001.py new file mode 100644 index 000000000..af6de2409 --- /dev/null +++ b/test/input/func_f0001.py @@ -0,0 +1,4 @@ +"""test astng error +""" +import whatever +__revision__ = None diff --git a/test/input/func_f0401.py b/test/input/func_f0401.py new file mode 100644 index 000000000..f8443fa1f --- /dev/null +++ b/test/input/func_f0401.py @@ -0,0 +1,9 @@ +"""tset failed import +""" + +__revision__ = 0 + +def function(): + """yo""" + from tutu import toto + print toto diff --git a/test/input/func_fixme.py b/test/input/func_fixme.py new file mode 100644 index 000000000..0cfe2bd83 --- /dev/null +++ b/test/input/func_fixme.py @@ -0,0 +1,9 @@ +"""docstring""" + +__revision__ = '' + +# FIXME: beep + +def function(): + '''XXX:bop''' + diff --git a/test/input/func_format.py b/test/input/func_format.py new file mode 100644 index 000000000..da66d63ed --- /dev/null +++ b/test/input/func_format.py @@ -0,0 +1,61 @@ +# pylint:disable-msg=C0103,W0104 +"""Check format +""" +__revision__ = '' + +notpreceded= 1 +notfollowed =1 +notfollowed <=1 + +correct = 1 +correct >= 1 + +def func(arg, arg2): + """test named argument + """ + func(arg=arg+1, + arg2=arg2-arg) + +aaaa,bbbb = 1,2 +aaaa |= bbbb +aaaa &= bbbb + + +if aaaa: pass +else: + aaaa,bbbb = 1,2 + aaaa,bbbb = bbbb,aaaa + +bbbb = (1,2,3) + +aaaa = bbbb[1:] +aaaa = bbbb[:1] +aaaa = bbbb[:] + +aaaa = {aaaa:bbbb} + + +# allclose(x,y) uses |x-y|<ATOL+RTOL*|y| +"""docstring,should not match +isn't it:yes! +a=b +""" +aaaa = 'multiple lines\ +string,hehehe' + + +boo = 2 # allclose(x,y) uses |x-y|<ATOL+RTOL*|y| + +def other(funky): + """yo, test formatted result with indentation""" + funky= funky+2 + +html = """<option value="=">ist genau gleich</option> +yo+=4 +""" +html2 = """<option value='='>ist genau gleich</option> +yo+=4 +""" + +func('''<body>Hello +</body>''') diff --git a/test/input/func_globals.py b/test/input/func_globals.py new file mode 100644 index 000000000..f7e6c6536 --- /dev/null +++ b/test/input/func_globals.py @@ -0,0 +1,40 @@ +""" +'W0601': ('global variable %s undefined at the module level', + 'Used when a variable is defined through the "global" statement \ + but the variable is not defined in the module scope.'), +'W0602': ('Using global for %s but no assigment is done', + 'Used when a variable is defined through the "global" statement \ + but no assigment to this variable is done.'), +'W0603': ('Using the global statement', # W0121 + 'Used when you use the "global" statement to update a global \ + variable. PyLint just try to discourage this \ + usage. That doesn\'t mean you can not use it !'), +'W0604': ('Using the global statement at the module level', # W0103 + 'Used when you use the "global" statement at the module level \ + since it has no effect'), +""" + +__revision__ = '' + +CONSTANT = 1 + +def fix_contant(value): + """all this is ok, but try not using global ;)""" + global CONSTANT + print CONSTANT + CONSTANT = value +global CSTE # useless +print CSTE # ko + +def other(): + """global behaviour test""" + global HOP + print HOP # ko + +other() + + +def define_constant(): + """ok but somevar is not defined at the module scope""" + global somevar + somevar = 2 diff --git a/test/input/func_i0010.py b/test/input/func_i0010.py new file mode 100644 index 000000000..8b2f436b5 --- /dev/null +++ b/test/input/func_i0010.py @@ -0,0 +1,3 @@ +# pylint: disable-all +"""disable-all is not usable as an inline option""" +__revision__ = None diff --git a/test/input/func_i0011.py b/test/input/func_i0011.py new file mode 100644 index 000000000..d8202f30e --- /dev/null +++ b/test/input/func_i0011.py @@ -0,0 +1,5 @@ +# pylint:disable-msg=W0404 +"""check warning on local disabling +""" +__revision__ = 1 + diff --git a/test/input/func_i0012.py b/test/input/func_i0012.py new file mode 100644 index 000000000..bf521386b --- /dev/null +++ b/test/input/func_i0012.py @@ -0,0 +1,5 @@ +# pylint:enable-msg=W0404 +"""check warning on local enabling +""" +__revision__ = 1 + diff --git a/test/input/func_indent.py b/test/input/func_indent.py new file mode 100644 index 000000000..57aae6ea3 --- /dev/null +++ b/test/input/func_indent.py @@ -0,0 +1,22 @@ +"""docstring""" +__revision__ = '$Id: func_indent.py,v 1.4 2003-10-17 21:59:31 syt Exp $' + +def totoo(): + """docstring""" + print 'malindented' + +def tutuu(): + """docstring""" + print 'good indentation' + +def titii(): + """also malindented""" + +def tataa(kdict): + """blank line unindented""" + for key in [1, 2, 3]: + key = key.lower() + + if kdict.has_key(key): + del kdict[key] + diff --git a/test/input/func_init_vars.py b/test/input/func_init_vars.py new file mode 100644 index 000000000..9d8950526 --- /dev/null +++ b/test/input/func_init_vars.py @@ -0,0 +1,46 @@ +"""Checks that class variables are seen as inherited ! +""" + +__revision__ = '' + + +class MyClass: + """Inherits from nothing + """ + + def __init__(self): + self.var = {} + + def met(self): + """Checks that base_var is seen as defined outside '__init__' + """ + self.var[1] = 'one' + self.base_var = 'one' + print self.base_var, self.var + + def met2(self): + """dummy method""" + print self +class MySubClass(MyClass): + """Inherits from MyClass + """ + class_attr = 1 + + def __init__(self): + MyClass.__init__(self) + self.var2 = 2 + print self.__doc__ + print self.__dict__ + print self.__class__ + + def met2(self): + """Checks that var is seen as defined outside '__init__' + """ + self.var[1] = 'one' + self.var2 += 1 + print self.class_attr + +if __name__ == '__main__': + OBJ = MyClass() + OBJ.met() + diff --git a/test/input/func_interfaces.py b/test/input/func_interfaces.py new file mode 100644 index 000000000..5081476b7 --- /dev/null +++ b/test/input/func_interfaces.py @@ -0,0 +1,99 @@ +# pylint:disable-msg=R0201 +"""docstring""" +__revision__ = '' + +class Interface: + """base class for interfaces""" + +class IMachin(Interface): + """docstring""" + def truc(self): + """docstring""" + + def troc(self, argument): + """docstring""" + +class Correct1: + """docstring""" + __implements__ = IMachin + + def __init__(self): + pass + + def truc(self): + """docstring""" + pass + + def troc(self, argument): + """docstring""" + pass + +class Correct2: + """docstring""" + __implements__ = (IMachin,) + + def __init__(self): + pass + + def truc(self): + """docstring""" + pass + + def troc(self, argument): + """docstring""" + print argument + +class MissingMethod: + """docstring""" + __implements__ = IMachin, + + def __init__(self): + pass + + def troc(self, argument): + """docstring""" + print argument + + def other(self): + """docstring""" + +class BadArgument: + """docstring""" + __implements__ = (IMachin,) + + def __init__(self): + pass + + def truc(self): + """docstring""" + pass + + def troc(self): + """docstring""" + pass + +class InterfaceCantBeFound: + """docstring""" + __implements__ = undefined + + def __init__(self): + """only to make pylint happier""" + + def please(self): + """public method 1/2""" + + def besilent(self): + """public method 2/2""" + +class InterfaceCantBeFound2: + """docstring""" + __implements__ = BadArgument.__implements__ + Correct2.__implements__ + + def __init__(self): + """only to make pylint happier""" + + def please(self): + """public method 1/2""" + + def besilent(self): + """public method 2/2""" diff --git a/test/input/func_method_could_be_function.py b/test/input/func_method_could_be_function.py new file mode 100644 index 000000000..5988b6845 --- /dev/null +++ b/test/input/func_method_could_be_function.py @@ -0,0 +1,52 @@ +# pylint: disable-msg=R0903,R0922,W0232 +"""test detection of method which could be a function""" + +__revision__ = None + +class Toto(object): + """bla bal abl""" + + def __init__(self): + self.aaa = 2 + + def regular_method(self): + """this method is a real method since it access to self""" + self.function_method() + + def function_method(self): + """this method isn' a real method since it doesn't need self""" + print 'hello' + + +class Base: + """an abstract class""" + + def __init__(self): + self.aaa = 2 + + def check(self, arg): + """an abstract method, could not be a function""" + raise NotImplementedError + + +class Sub(Base): + """a concret class""" + + def check(self, arg): + """a concret method, could not be a function since it need + polymorphism benefits + """ + return arg == 0 + +class Super: + """same as before without abstract""" + x = 1 + def method(self): + """regular""" + print self.x + +class Sub1(Super): + """override method with need for self""" + def method(self): + """no i can not be a function""" + print 42 diff --git a/test/input/func_method_missing_self.py b/test/input/func_method_missing_self.py new file mode 100644 index 000000000..5bdbc6940 --- /dev/null +++ b/test/input/func_method_missing_self.py @@ -0,0 +1,25 @@ +"""Checks that missing self in method defs don't crash Pylint ! +""" + +__revision__ = '' + + +class MyClass: + """SimpleClass + """ + + def __init__(self): + self.var = "var" + + def met(): + """Checks that missing self dont crash Pylint ! + """ + + def correct(self): + """yo""" + self.var = "correct" + +if __name__ == '__main__': + OBJ = MyClass() + OBJ.met() + diff --git a/test/input/func_method_without_self_but_self_assignment.py b/test/input/func_method_without_self_but_self_assignment.py new file mode 100644 index 000000000..e39266c8f --- /dev/null +++ b/test/input/func_method_without_self_but_self_assignment.py @@ -0,0 +1,15 @@ +# pylint: disable-msg=R0903 +"""regression test: setup() leads to "unable to load module..." +""" + +__revision__ = 1 + +class Example: + """bla""" + + def __init__(self): + pass + + def setup(): + "setup without self" + self.foo = 1 diff --git a/test/input/func_nameerror_on_string_substitution.py b/test/input/func_nameerror_on_string_substitution.py new file mode 100644 index 000000000..be7b5c82a --- /dev/null +++ b/test/input/func_nameerror_on_string_substitution.py @@ -0,0 +1,8 @@ +"""pylint doesn't see the NameError in this module""" + +__revision__ = None + +MSG = "hello %s" % MSG + +MSG2 = ("hello %s" % + MSG2) diff --git a/test/input/func_names_imported_from_module.py b/test/input/func_names_imported_from_module.py new file mode 100644 index 000000000..caf738760 --- /dev/null +++ b/test/input/func_names_imported_from_module.py @@ -0,0 +1,31 @@ +#pylint: disable-msg=W0401,W0611 +"""check unexistant names imported are reported""" + +__revision__ = None + +import logilab.common.tutu +from logilab.common import toto +toto.yo() + +from logilab.common import modutils +modutils.nonexistant_function() +modutils.another.nonexistant.function() +print logilab.common.modutils.yo + +import sys +print >> sys.stdout, 'hello world' +print >> sys.stdoout, 'bye bye world' + + +import re +re.finditer('*', 'yo') + +from rie import * +from re import findiiter, compiile + +import os +os.environ.has_key('SOMEVAR') + +import exceptions +print exceptions.__dict__ +print exceptions.__dict__.get('Exception') diff --git a/test/input/func_newstyle___slots__.py b/test/input/func_newstyle___slots__.py new file mode 100644 index 000000000..78909c082 --- /dev/null +++ b/test/input/func_newstyle___slots__.py @@ -0,0 +1,17 @@ +# pylint: disable-msg=R0903 +"""test __slots__ on old style class""" + +__revision__ = 1 + +class OkOk(object): + """correct usage""" + __slots__ = ('a', 'b') + +class HaNonNonNon: + """bad usage""" + __slots__ = ('a', 'b') + + def __init__(self): + pass + +__slots__ = 'hop' # pfff diff --git a/test/input/func_newstyle_exceptions.py b/test/input/func_newstyle_exceptions.py new file mode 100644 index 000000000..9a9cccdc9 --- /dev/null +++ b/test/input/func_newstyle_exceptions.py @@ -0,0 +1,35 @@ +# pylint: disable-msg=C0103 +"""test pb with exceptions and old/new style classes""" + +__revision__ = 1 + +class OkException(Exception): + """bien bien bien""" + +class BofException: + """mouais""" + +class NewException(object): + """non !""" + +def fonctionOk(): + """raise""" + raise OkException('hop') + +def fonctionBof(): + """raise""" + raise BofException('hop') + +def fonctionNew(): + """raise""" + raise NewException() + +def fonctionBof2(): + """raise""" + raise BofException, 'hop' + +def fonctionNew2(): + """raise""" + raise NewException + + diff --git a/test/input/func_newstyle_property.py b/test/input/func_newstyle_property.py new file mode 100644 index 000000000..cdce8facf --- /dev/null +++ b/test/input/func_newstyle_property.py @@ -0,0 +1,19 @@ +# pylint: disable-msg=R0903 +"""test property on old style class""" + +__revision__ = 1 + +def getter(self): + """interesting""" + return self + +class OkOk(object): + """correct usage""" + method = property(getter, doc='hop') + +class HaNonNonNon: + """bad usage""" + method = property(getter, doc='hop') + + def __init__(self): + pass diff --git a/test/input/func_newstyle_super.py b/test/input/func_newstyle_super.py new file mode 100644 index 000000000..e84c908d3 --- /dev/null +++ b/test/input/func_newstyle_super.py @@ -0,0 +1,22 @@ +# pylint: disable-msg=R0903 +"""check use of super""" +__revision__ = None + +class Aaaa: + """old style""" + def hop(self): + """hop""" + super(Aaaa, self).hop() + + def __init__(self): + super(Aaaa, self).__init__() + +class NewAaaa(object): + """old style""" + def hop(self): + """hop""" + super(NewAaaa, self).hop() + + def __init__(self): + super(object, self).__init__() + diff --git a/test/input/func_noerror___future___import.py b/test/input/func_noerror___future___import.py new file mode 100644 index 000000000..5c77516ba --- /dev/null +++ b/test/input/func_noerror___future___import.py @@ -0,0 +1,5 @@ +"""a docstring""" + +from __future__ import generators + +__revision__ = 1 diff --git a/test/input/func_noerror___init___return_from_inner_function.py b/test/input/func_noerror___init___return_from_inner_function.py new file mode 100644 index 000000000..30b2671df --- /dev/null +++ b/test/input/func_noerror___init___return_from_inner_function.py @@ -0,0 +1,13 @@ +# pylint: disable-msg=R0903 +"""#10075""" + +__revision__ = 1 + +class Aaa: + """docstring""" + def __init__(self): + def inner_function(arg): + """inner docstring""" + return arg + 4 + self.func = inner_function + diff --git a/test/input/func_noerror_access_attr_before_def_false_positive.py b/test/input/func_noerror_access_attr_before_def_false_positive.py new file mode 100644 index 000000000..048d9384f --- /dev/null +++ b/test/input/func_noerror_access_attr_before_def_false_positive.py @@ -0,0 +1,100 @@ +#pylint: disable-msg=C0103,R0904,R0903,W0201 +""" +This module demonstrates a possible problem of pyLint with calling __init__ s +from inherited classes. +Initializations done there are not considered, which results in Error E0203 for +self.cookedq. +""" + +__revision__ = 'yo' + +import telnetlib + +class SeeTelnet(telnetlib.Telnet): + """ + Extension of telnetlib. + """ + + def __init__(self, host=None, port=0): + """ + Constructor. + When called without arguments, create an unconnected instance. + With a hostname argument, it connects the instance; a port + number is optional. + Parameter: + - host: IP address of the host + - port: Port number + """ + telnetlib.Telnet.__init__(self, host, port) + + def readUntilArray(self, matches, _=None): + """ + Read until a given string is encountered or until timeout. + ... + """ + self.process_rawq() + maxLength = 0 + index = -1 + for match in matches: + index += 1 + if len(match) > maxLength: + maxLength = len(match) + +class Base(object): + """bla bla""" + dougloup_papa = None + + def __init__(self): + self._var = False + +class Derived(Base): + """derived blabla""" + dougloup_moi = None + def Work(self): + """do something""" + # E0203 - Access to member '_var' before its definition + if self._var: + print "True" + else: + print "False" + self._var = True + + # E0203 - Access to member 'dougloup_papa' before its definition + if self.dougloup_papa: + print 'dougloup !' + self.dougloup_papa = True + # E0203 - Access to member 'dougloup_moi' before its definition + if self.dougloup_moi: + print 'dougloup !' + self.dougloup_moi = True + + +class QoSALConnection(object): + """blabla""" + + _the_instance = None + + def __new__(cls): + if cls._the_instance is None: + cls._the_instance = object.__new__(cls) + return cls._the_instance + + def __init__(self): + pass + +class DefinedOutsideInit: + """use_attr is seen as the method defining attr because its in + first position + """ + def __init__(self): + self.reset() + + def use_attr(self): + """use and set members""" + if self.attr: + print 'hop' + self.attr = 10 + + def reset(self): + """reset members""" + self.attr = 4 diff --git a/test/input/func_noerror_base_init_vars.py b/test/input/func_noerror_base_init_vars.py new file mode 100644 index 000000000..d83ebbc05 --- /dev/null +++ b/test/input/func_noerror_base_init_vars.py @@ -0,0 +1,36 @@ +# pylint:disable-msg=R0201 +"""Checks that class variables are seen as inherited ! +""" +__revision__ = '' + +class BaseClass: + """A simple base class + """ + + def __init__(self): + self.base_var = {} + + def met(self): + """yo""" + def meeting(self, with): + """ye""" + return with +class MyClass(BaseClass): + """Inherits from BaseClass + """ + + def __init__(self): + BaseClass.__init__(self) + self.var = {} + + def met(self): + """Checks that base_var is not seen as defined outsite '__init__' + """ + self.var[1] = 'one' + self.base_var[1] = 'one' + print self.base_var, self.var + +if __name__ == '__main__': + OBJ = MyClass() + OBJ.met() + diff --git a/test/input/func_noerror_builtin_module_test.py b/test/input/func_noerror_builtin_module_test.py new file mode 100644 index 000000000..4d6ba0aec --- /dev/null +++ b/test/input/func_noerror_builtin_module_test.py @@ -0,0 +1,11 @@ +"""test import from a builtin module""" + +__revision__ = None + +from math import log10 + +def log10_2(): + """bla bla bla""" + return log10(2) + + diff --git a/test/input/func_noerror_defined_and_used_on_same_line.py b/test/input/func_noerror_defined_and_used_on_same_line.py new file mode 100644 index 000000000..87d3180e4 --- /dev/null +++ b/test/input/func_noerror_defined_and_used_on_same_line.py @@ -0,0 +1,20 @@ +#pylint: disable-msg=C0111,C0321 +"""pylint complains about 'index' being used before definition""" + +__revision__ = None + +print [index + for index in range(10)] + + +FILTER_FUNC = lambda x: not x + +def func(xxx): return xxx + +def func2(xxx): return xxx + func2(1) + +import sys; print sys.exc_info( ) + +for i in range(10): print i + +j = 4; LAMB = lambda x: x+j diff --git a/test/input/func_noerror_defined_and_used_on_same_line_py24.py b/test/input/func_noerror_defined_and_used_on_same_line_py24.py new file mode 100644 index 000000000..8032a8f60 --- /dev/null +++ b/test/input/func_noerror_defined_and_used_on_same_line_py24.py @@ -0,0 +1,7 @@ +#pylint: disable-msg=C0111,C0321 +"""pylint complains about 'index' being used before definition""" + +__revision__ = None + +print (index + for index in range(10)) diff --git a/test/input/func_noerror_e1101_13784.py b/test/input/func_noerror_e1101_13784.py new file mode 100644 index 000000000..b247b4412 --- /dev/null +++ b/test/input/func_noerror_e1101_13784.py @@ -0,0 +1,15 @@ +"""cf #13784 +""" + +__revision__ = None + +def no_conjugate_member(magic_flag): + """should not raise E1101 on something.conjugate""" + if magic_flag: + something = 1.0 + else: + something = 1.0j + if isinstance(something, float): + return something + return something.conjugate() + diff --git a/test/input/func_noerror_e1101_but_getattr.py b/test/input/func_noerror_e1101_but_getattr.py new file mode 100644 index 000000000..143ddc06e --- /dev/null +++ b/test/input/func_noerror_e1101_but_getattr.py @@ -0,0 +1,23 @@ +"""don't want E1101 if __getattr__ is defined""" + +__revision__ = None + +class MyString: + """proxied string""" + + def __init__(self, string): + self.string = string + + def __getattr__(self, attr): + return getattr(self.string, attr) + + def lower(self): + """string.lower""" + return self.string.lower() + + def upper(self): + """string.upper""" + return self.string.upper() + +MYSTRING = MyString("abc") +print MYSTRING.title() diff --git a/test/input/func_noerror_encoding.py b/test/input/func_noerror_encoding.py new file mode 100644 index 000000000..2e945a5e4 --- /dev/null +++ b/test/input/func_noerror_encoding.py @@ -0,0 +1,6 @@ +# -*- coding: ISO-8859-1 -*- +""" check correct encoding declaration +""" + +__revision__ = 'éééé' + diff --git a/test/input/func_noerror_exception.py b/test/input/func_noerror_exception.py new file mode 100644 index 000000000..1c3d8b56a --- /dev/null +++ b/test/input/func_noerror_exception.py @@ -0,0 +1,7 @@ +""" module doc """ +__revision__ = '' + +class MyException(Exception): + """a custom exception with its *own* __init__ !!""" + def __init__(self, msg): + Exception.__init__(self, msg) diff --git a/test/input/func_noerror_indirect_interface.py b/test/input/func_noerror_indirect_interface.py new file mode 100644 index 000000000..2b240f970 --- /dev/null +++ b/test/input/func_noerror_indirect_interface.py @@ -0,0 +1,16 @@ +"""shows a bug where pylint can't find interfaces when they are +used indirectly. See input/indirect[123].py for details on the +setup""" + +__revision__ = None + +from input.indirect2 import AbstractToto + +class ConcreteToto(AbstractToto): + """abstract to implements an interface requiring machin to be defined""" + def __init__(self): + self.duh = 2 + + def machin(self): + """for ifacd""" + return self.helper()*2 diff --git a/test/input/func_noerror_inner_classes.py b/test/input/func_noerror_inner_classes.py new file mode 100644 index 000000000..a1a848dec --- /dev/null +++ b/test/input/func_noerror_inner_classes.py @@ -0,0 +1,33 @@ +# pylint: disable-msg=R0903 +"""Backend Base Classes for the schwelm user DB""" + +__revision__ = "alpha" + +class Aaa(object): + """docstring""" + def __init__(self): + self.__setattr__('a','b') + pass + + def one_public(self): + """docstring""" + pass + + def another_public(self): + """docstring""" + pass + +class Bbb(Aaa): + """docstring""" + pass + +class Ccc(Aaa): + """docstring""" + + class Ddd(Aaa): + """docstring""" + pass + + class Eee(Ddd): + """docstring""" + pass diff --git a/test/input/func_noerror_mcs_attr_access.py b/test/input/func_noerror_mcs_attr_access.py new file mode 100644 index 000000000..c42c0619e --- /dev/null +++ b/test/input/func_noerror_mcs_attr_access.py @@ -0,0 +1,20 @@ +# pylint: disable-msg=R0903 +"""test attribute access on metaclass""" + + +__revision__ = 'yo' + +class Meta(type): + """the meta class""" + def __init__(mcs, name, bases, dictionary): + super(Meta, mcs).__init__(name, bases, dictionary) + print mcs, mcs._meta_args + delattr(mcs, '_meta_args') + +class Test(object): + """metaclassed class""" + __metaclass__ = Meta + _meta_args = ('foo', 'bar') + + def __init__(self): + print '__init__', self diff --git a/test/input/func_noerror_nested_classes.py b/test/input/func_noerror_nested_classes.py new file mode 100644 index 000000000..96cd36654 --- /dev/null +++ b/test/input/func_noerror_nested_classes.py @@ -0,0 +1,18 @@ +# pylint: disable-msg=R0903 +"""crash test""" + +__revision__ = 1 + +class Temelekefe: + """gloubliboulga""" + + def __init__(self): + """nested class with function raise error""" + class Toto: + """toto nested class""" + def __init__(self): + self.attr = 2 + def toto_method(self): + """toto nested class method""" + print self + print 'error ?', self, Toto diff --git a/test/input/func_noerror_new_style_class.py b/test/input/func_noerror_new_style_class.py new file mode 100644 index 000000000..8c9ed4016 --- /dev/null +++ b/test/input/func_noerror_new_style_class.py @@ -0,0 +1,45 @@ +"""check builtin data descriptors such as mode and name attributes +on a file are correctly handler + +bug notified by Pierre Rouleau on 2005-04-24 +""" + +__revision__ = None + +class File(file): + """ Testing new-style class inheritance from file""" + + # + def __init__(self, name, mode="r", buffering=-1, verbose=False): + """Constructor""" + + self.was_modified = False + self.verbose = verbose + super(File, self).__init__(name, mode, buffering) + if self.verbose: + print "File %s is opened. The mode is: %s" % (self.name, +self.mode) + + # + def write(self, a_string): + """ Write a string to the file.""" + + super(File, self).write(a_string) + self.was_modified = True + + # + def writelines(self, sequence): + """ Write a sequence of strings to the file. """ + + super(File, self).writelines(sequence) + self.was_modified = True + + # + def close(self) : + """Close the file.""" + + if self.verbose: + print "Closing file %s" % self.name + + super(File, self).close() + self.was_modified = False diff --git a/test/input/func_noerror_object_as_class_attribute.py b/test/input/func_noerror_object_as_class_attribute.py new file mode 100644 index 000000000..6b442ea52 --- /dev/null +++ b/test/input/func_noerror_object_as_class_attribute.py @@ -0,0 +1,19 @@ +# pylint: disable-msg=R0903 +"""Test case for the problem described below : + - A class extends 'object' + - This class defines its own __init__() + * pylint will therefore check that baseclasses' init() + are called + - If this class defines an 'object' attribute, then pylint + will use this new definition when trying to retrieve + object.__init__() +""" + +__revision__ = None + +class Statement(object): + """ ... """ + def __init__(self): + pass + object = None + diff --git a/test/input/func_noerror_socket_member.py b/test/input/func_noerror_socket_member.py new file mode 100644 index 000000000..8c79ff579 --- /dev/null +++ b/test/input/func_noerror_socket_member.py @@ -0,0 +1,25 @@ +"""Testing Pylint with the socket module + +Pylint Problem +============== + +Version used: + + - Pylint 0.10.0 + - Logilab common 0.15.0 + - Logilab astng 0.15.1 + +False E1101 positive, line 23: + + Instance of '_socketobject' has no 'connect' member + +""" +__revision__ = None + +import socket + +if __name__ == "__main__": + + SCKT = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + SCKT.connect(('127.0.0.1', 80)) + SCKT.close() diff --git a/test/input/func_noerror_static_method.py b/test/input/func_noerror_static_method.py new file mode 100644 index 000000000..618496109 --- /dev/null +++ b/test/input/func_noerror_static_method.py @@ -0,0 +1,29 @@ +"""Checks if static / class methods works fine in Pylint +""" + +__revision__ = '' + +class MyClass: + """doc + """ + def __init__(self): + pass + + def static_met(var1, var2): + """This is a static method + """ + print var1, var2 + + def class_met(cls, var1): + """This is a class method + """ + print cls, var1 + + static_met = staticmethod(static_met) + class_met = classmethod(class_met) + +if __name__ == '__main__': + MyClass.static_met("var1","var2") + MyClass.class_met("var1") + + diff --git a/test/input/func_noerror_staticmethod_as_decorator.py b/test/input/func_noerror_staticmethod_as_decorator.py new file mode 100644 index 000000000..e5a44f26c --- /dev/null +++ b/test/input/func_noerror_staticmethod_as_decorator.py @@ -0,0 +1,35 @@ +# pylint: disable-msg=R0903 +"""test staticmethod and classmethod as decorator""" + +__revision__ = None + +class StaticMethod1(object): + """staticmethod test""" + def __init__(self): + pass + + @staticmethod + def do_work(): + "Working..." + + @staticmethod + def do_work_with_arg(job): + "Working on something" + print "Working on %s..." % job + + +class ClassMethod2(object): + """classmethod test""" + def __init__(self): + pass + + @classmethod + def do_work(cls): + "Working..." + + @classmethod + def do_work_with_arg(cls, job): + "Working on something" + print "Working on %s..." % job + + diff --git a/test/input/func_noerror_w0232.py b/test/input/func_noerror_w0232.py new file mode 100644 index 000000000..f4c4232a4 --- /dev/null +++ b/test/input/func_noerror_w0232.py @@ -0,0 +1,10 @@ +# pylint: disable-msg=R0903,R0923 +"""check interface and exception without __init__ doesn't print warnings +""" +__revision__ = '' + +class Interface: + """interface without docstring""" + +class MyError(Exception): + """exception without docstring""" diff --git a/test/input/func_nonascii_noencoding.py b/test/input/func_nonascii_noencoding.py new file mode 100644 index 000000000..1ba3578de --- /dev/null +++ b/test/input/func_nonascii_noencoding.py @@ -0,0 +1,5 @@ +"""test file with non ascii characters and no encoding declaration""" + +__revision__ = '' + +YOP = 'héhéhé' diff --git a/test/input/func_r0901.py b/test/input/func_r0901.py new file mode 100644 index 000000000..d30d2706f --- /dev/null +++ b/test/input/func_r0901.py @@ -0,0 +1,27 @@ +# pylint: disable-msg=W0232, R0903 +"""test max parents""" +__revision__ = None + +class Aaaa: + """yo""" +class Bbbb: + """yo""" +class Cccc: + """yo""" +class Dddd: + """yo""" +class Eeee: + """yo""" +class Ffff: + """yo""" +class Gggg: + """yo""" +class Hhhh: + """yo""" + +class Iiii(Aaaa, Bbbb, Cccc, Dddd, Eeee, Ffff, Gggg, Hhhh): + """yo""" + +class Jjjj(Iiii): + """yo""" + diff --git a/test/input/func_r0902.py b/test/input/func_r0902.py new file mode 100644 index 000000000..59d4100c5 --- /dev/null +++ b/test/input/func_r0902.py @@ -0,0 +1,28 @@ +# pylint: disable-msg=R0903 +"""test max instance attributes""" +__revision__ = None + +class Aaaa: + """yo""" + def __init__(self): + self.aaaa = 1 + self.bbbb = 2 + self.cccc = 3 + self.dddd = 4 + self.eeee = 5 + self.ffff = 6 + self.gggg = 7 + self.hhhh = 8 + self.iiii = 9 + self.jjjj = 10 + self._aaaa = 1 + self._bbbb = 2 + self._cccc = 3 + self._dddd = 4 + self._eeee = 5 + self._ffff = 6 + self._gggg = 7 + self._hhhh = 8 + self._iiii = 9 + self._jjjj = 10 + self.tomuch = None diff --git a/test/input/func_r0903.py b/test/input/func_r0903.py new file mode 100644 index 000000000..4c119299c --- /dev/null +++ b/test/input/func_r0903.py @@ -0,0 +1,13 @@ +"""test min methods""" +__revision__ = None + +class Aaaa: + """yo""" + def __init__(self): + pass + def meth1(self): + """hehehe""" + print self + def _dontcount(self): + """not public""" + print self diff --git a/test/input/func_r0904.py b/test/input/func_r0904.py new file mode 100644 index 000000000..abb4d06ea --- /dev/null +++ b/test/input/func_r0904.py @@ -0,0 +1,73 @@ +# pylint: disable-msg=R0201 +"""test max methods""" +__revision__ = None +class Aaaa: + """yo""" + def __init__(self): + pass + + def meth1(self): + """hehehe""" + + def meth2(self): + """hehehe""" + + def meth3(self): + """hehehe""" + + def meth4(self): + """hehehe""" + + def meth5(self): + """hehehe""" + + def meth6(self): + """hehehe""" + + def meth7(self): + """hehehe""" + + def meth8(self): + """hehehe""" + + def meth9(self): + """hehehe""" + + def meth10(self): + """hehehe""" + + def meth11(self): + """hehehe""" + + def meth12(self): + """hehehe""" + + def meth13(self): + """hehehe""" + + def meth14(self): + """hehehe""" + + def meth15(self): + """hehehe""" + + def meth16(self): + """hehehe""" + + def meth17(self): + """hehehe""" + + def meth18(self): + """hehehe""" + + def meth19(self): + """hehehe""" + + def meth20(self): + """hehehe""" + + def meth21(self): + """hehehe""" + + def _dontcount(self): + """not public""" diff --git a/test/input/func_r0921.py b/test/input/func_r0921.py new file mode 100644 index 000000000..b9f2de2ba --- /dev/null +++ b/test/input/func_r0921.py @@ -0,0 +1,15 @@ +"""test max methods""" +__revision__ = None + +class Aaaa: + """yo""" + def __init__(self): + pass + + def meth1(self): + """hehehe""" + raise NotImplementedError + + def meth2(self): + """hehehe""" + return 'Yo', self diff --git a/test/input/func_r0922.py b/test/input/func_r0922.py new file mode 100644 index 000000000..da7dfcf22 --- /dev/null +++ b/test/input/func_r0922.py @@ -0,0 +1,21 @@ +"""test max methods""" +__revision__ = None + +class Aaaa: + """yo""" + def __init__(self): + pass + + def meth1(self): + """hehehe""" + raise NotImplementedError + + def meth2(self): + """hehehe""" + return 'Yo', self + +class Bbbb(Aaaa): + """yeah""" + def meth1(self): + """hehehe bis""" + return "yeah", self diff --git a/test/input/func_r0923.py b/test/input/func_r0923.py new file mode 100644 index 000000000..8dacf1e44 --- /dev/null +++ b/test/input/func_r0923.py @@ -0,0 +1,32 @@ +"""test max methods""" +__revision__ = None + +from logilab.common.interface import Interface + +class IAaaa(Interface): + """yo""" + + def meth1(self): + """hehehe""" + +class IBbbb(Interface): + """yo""" + + def meth1(self): + """hehehe""" + +class Concret: + """implements IBbbb""" + __implements__ = IBbbb + + def __init__(self): + pass + + def meth1(self): + """hehehe""" + return "et hop", self + + def meth2(self): + """hehehe""" + return "et hop", self + diff --git a/test/input/func_reqattrs.py b/test/input/func_reqattrs.py new file mode 100644 index 000000000..fb1e2b648 --- /dev/null +++ b/test/input/func_reqattrs.py @@ -0,0 +1 @@ +"""docstring""" diff --git a/test/input/func_scope_regrtest.py b/test/input/func_scope_regrtest.py new file mode 100644 index 000000000..98dd8be49 --- /dev/null +++ b/test/input/func_scope_regrtest.py @@ -0,0 +1,15 @@ +# pylint: disable-msg=R0903,W0232 +"""check for scope problems""" + +__revision__ = None + +class Well(object): + """well""" + class Data: + """base hidden class""" + class Sub(Data): + """whaou, is Data found???""" + yo = Data() + def func(self): + """check Sub is not defined here""" + return Sub(), self diff --git a/test/input/func_syntax_error.py b/test/input/func_syntax_error.py new file mode 100644 index 000000000..43fa08752 --- /dev/null +++ b/test/input/func_syntax_error.py @@ -0,0 +1 @@ +def toto diff --git a/test/input/func_toolonglines.py b/test/input/func_toolonglines.py new file mode 100644 index 000000000..76a401874 --- /dev/null +++ b/test/input/func_toolonglines.py @@ -0,0 +1,4 @@ +########################################################################################## +""" that one is too long tooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo""" + +__revision__ = '' diff --git a/test/input/func_typecheck_callfunc_assigment.py b/test/input/func_typecheck_callfunc_assigment.py new file mode 100644 index 000000000..82130e347 --- /dev/null +++ b/test/input/func_typecheck_callfunc_assigment.py @@ -0,0 +1,56 @@ +# pylint: disable-msg=R0921 +"""check assigment to function call where the function doesn't return + + 'E1111': ('Assigning to function call which doesn\'t return', + 'Used when an assigment is done on a function call but the \ + infered function doesn\'t return anything.'), + 'W1111': ('Assigning to function call which only returns None', + 'Used when an assigment is done on a function call but the \ + infered function returns nothing but None.'), + +""" +from __future__ import generators +__revision__ = None + + +def func_no_return(): + """function without return""" + print 'dougloup' + +A = func_no_return() + + +def func_return_none(): + """function returning none""" + print 'dougloup' + return None + +A = func_return_none() + + +def func_return_none_and_smth(): + """function returning none and something else""" + print 'dougloup' + if __revision__: + return None + return 3 + +A = func_return_none_and_smth() + +def generator(): + """no problemo""" + yield __revision__ + +A = generator() + +class Abstract(object): + """bla bla""" + + def abstract_method(self): + """use to return something in concrete implementation""" + raise NotImplementedError + + def use_abstract(self): + """should not issue E1111""" + var = self.abstract_method() + print var diff --git a/test/input/func_typecheck_getattr.py b/test/input/func_typecheck_getattr.py new file mode 100644 index 000000000..dc5029247 --- /dev/null +++ b/test/input/func_typecheck_getattr.py @@ -0,0 +1,60 @@ +# pylint: disable-msg= +"""check getattr if inference succeed""" + +__revision__ = None + +class Provider: + """provide some attributes and method""" + cattr = 4 + def __init__(self): + self.attr = 4 + def method(self, val): + """impressive method""" + return self.attr * val + def hophop(self): + """hop method""" + print 'hop hop hop', self + + +class Client: + """use provider class""" + + def __init__(self): + self._prov = Provider() + self._prov_attr = Provider.cattr + self._prov_attr2 = Provider.cattribute + + def use_method(self): + """use provider's method""" + self._prov.hophop() + self._prov.hophophop() + + def use_attr(self): + """use provider's attr""" + print self._prov.attr + print self._prov.attribute + + def debug(self): + """print debug information""" + print self.__class__.__name__ + print self.__doc__ + print self.__dict__ + print self.__module__ + + def test_bt_types(self): + """test access to unexistant member of builtin types""" + lis = [] + lis.apppend(self) + dic = {} + dic.set(self) + tup = () + tup.append(self) + string = 'toto' + print string.loower() + uni = u'toto' + print uni.loower() + integer = 1 + print integer.whatever + +print object.__init__ +print property.__init__ diff --git a/test/input/func_typecheck_non_callable_call.py b/test/input/func_typecheck_non_callable_call.py new file mode 100644 index 000000000..75b122413 --- /dev/null +++ b/test/input/func_typecheck_non_callable_call.py @@ -0,0 +1,37 @@ +# pylint: disable-msg=R0903 +""" + 'E1102': ('%s is not callable', + 'Used when an object being called has been infered to a non \ + callable object'), +""" + +__revision__ = None + +__revision__() + +def correct(): + """callable object""" + return 1 + +__revision__ = correct() + +class Correct(object): + """callable object""" + +class MetaCorrect(object): + """callable object""" + def __call__(self): + return self + +INSTANCE = Correct() +CALLABLE_INSTANCE = MetaCorrect() +CORRECT = CALLABLE_INSTANCE() +INCORRECT = INSTANCE() +LIST = [] +INCORRECT = LIST() +DICT = {} +INCORRECT = DICT() +TUPLE = () +INCORRECT = TUPLE() +INT = 1 +INCORRECT = INT() diff --git a/test/input/func_undefined_var.py b/test/input/func_undefined_var.py new file mode 100644 index 000000000..316626058 --- /dev/null +++ b/test/input/func_undefined_var.py @@ -0,0 +1,26 @@ +"""test access to undefined variables""" + +__revision__ = '$Id:' + +DEFINED = 1 + +if DEFINED != 1: + if DEFINED in (unknown, DEFINED): + DEFINED += 1 + + +def in_method(var): + """method doc""" + var = nomoreknown + assert var + +DEFINED = {DEFINED:__revision__} +DEFINED[__revision__] = OTHER = 'move this is astng test' + +OTHER += '$' + +def bad_default(var, default=unknown2): + """function with defaut arg's value set to an unexistant name""" + print var, default + print xxxx + print xxxx #see story #1000 diff --git a/test/input/func_unknown_encoding.py b/test/input/func_unknown_encoding.py new file mode 100644 index 000000000..31deabdfb --- /dev/null +++ b/test/input/func_unknown_encoding.py @@ -0,0 +1,6 @@ +# -*- coding: IBO-8859-1 -*- +""" check correct unknown encoding declaration +""" + +__revision__ = 'éééé' + diff --git a/test/input/func_unreachable.py b/test/input/func_unreachable.py new file mode 100644 index 000000000..1cabce718 --- /dev/null +++ b/test/input/func_unreachable.py @@ -0,0 +1,22 @@ +"""docstring""" + +__revision__ = '' + +def func1(): + """docstring""" + return 1 + print 'unreachable' + +def func2(): + """docstring""" + while 1: + break + print 'unreachable' + +def func3(): + """docstring""" + for i in (1, 2, 3): + print i + continue + print 'unreachable' + diff --git a/test/input/func_use_for_or_listcomp_var.py b/test/input/func_use_for_or_listcomp_var.py new file mode 100644 index 000000000..b0db336d4 --- /dev/null +++ b/test/input/func_use_for_or_listcomp_var.py @@ -0,0 +1,21 @@ +"""test a warning is triggered when using for a lists comprehension variable""" + +__revision__ = 'yo' + +TEST_LC = [C for C in __revision__ if C.isalpha()] +print C # WARN +C = 4 +print C # this one shouldn't trigger any warning + +B = [B for B in __revision__ if B.isalpha()] +print B # nor this one + +for var1, var2 in TEST_LC: + var1 = var2 + 4 +print var1 # WARN + +for note in __revision__: + note.something() +for line in __revision__: + for note in line: + A = note.anotherthing() diff --git a/test/input/func_w0101.py b/test/input/func_w0101.py new file mode 100644 index 000000000..fe543aabe --- /dev/null +++ b/test/input/func_w0101.py @@ -0,0 +1,28 @@ +"""test max returns +""" + +__revision__ = '' + +def stupid_function(arg): + """reallly stupid function""" + if arg == 1: + return 1 + elif arg == 2: + return 2 + elif arg == 3: + return 3 + elif arg == 4: + return 4 + elif arg == 5: + return 5 + elif arg == 6: + return 6 + elif arg == 7: + return 7 + elif arg == 8: + return 8 + elif arg == 9: + return 9 + elif arg == 10: + return 10 + return None diff --git a/test/input/func_w0102.py b/test/input/func_w0102.py new file mode 100644 index 000000000..b096fffac --- /dev/null +++ b/test/input/func_w0102.py @@ -0,0 +1,53 @@ +# pylint: disable-msg=R0201 +"""docstring""" +__revision__ = '' + +class AAAA: + """docstring""" + def __init__(self): + pass + def method1(self): + """docstring""" + + def method2(self): + """docstring""" + + def method2(self): + """docstring""" + +class AAAA: + """docstring""" + def __init__(self): + pass + def yeah(self): + """hehehe""" + def yoo(self): + """yoo""" +def func1(): + """docstring""" + +def func2(): + """docstring""" + +def func2(): + """docstring""" + __revision__ = 1 + return __revision__ + +if __revision__: + def exclusive_func(): + "docstring" +else: + def exclusive_func(): + "docstring" + +try: + def exclusive_func2(): + "docstring" +except TypeError: + def exclusive_func2(): + "docstring" +else: + def exclusive_func2(): + "this one redefine the one defined line 42" + diff --git a/test/input/func_w0103.py b/test/input/func_w0103.py new file mode 100644 index 000000000..9417cb55c --- /dev/null +++ b/test/input/func_w0103.py @@ -0,0 +1,8 @@ +"""test max branch +""" + +__revision__ = '' + +def stupid_function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9): + """reallly stupid function""" + print arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 diff --git a/test/input/func_w0104.py b/test/input/func_w0104.py new file mode 100644 index 000000000..bddf00123 --- /dev/null +++ b/test/input/func_w0104.py @@ -0,0 +1,12 @@ +"""test max branch +""" + +__revision__ = '' + +def stupid_function(arg1, arg2, arg3, arg4, arg5): + """reallly stupid function""" + arg6, arg7, arg8, arg9 = arg1, arg2, arg3, arg4 + print arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 + loc1, loc2, loc3, loc4, loc5, loc6, loc7 = arg1, arg2, arg3, arg4, arg5, \ + arg6, arg7 + print loc1, loc2, loc3, loc4, loc5, loc6, loc7 diff --git a/test/input/func_w0105.py b/test/input/func_w0105.py new file mode 100644 index 000000000..430cfd4f3 --- /dev/null +++ b/test/input/func_w0105.py @@ -0,0 +1,62 @@ +"""test max branch +""" + +__revision__ = '' + +def stupid_function(arg): + """reallly stupid function""" + if arg == 1: + print 1 + elif arg == 2: + print 2 + elif arg == 3: + print 3 + elif arg == 4: + print 4 + elif arg == 5: + print 5 + elif arg == 6: + print 6 + elif arg == 7: + print 7 + elif arg == 8: + print 8 + elif arg == 9: + print 9 + elif arg == 10: + print 10 + elif arg < 1: + print 0 + print 100 + arg = 0 + for val in range(arg): + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val + print val diff --git a/test/input/func_w0109.py b/test/input/func_w0109.py new file mode 100644 index 000000000..ba7a679d2 --- /dev/null +++ b/test/input/func_w0109.py @@ -0,0 +1,7 @@ +"""test empty docstrings +""" + +__revision__ = '' + +def function(): + """""" diff --git a/test/input/func_w0110.py b/test/input/func_w0110.py new file mode 100644 index 000000000..c9d93115c --- /dev/null +++ b/test/input/func_w0110.py @@ -0,0 +1,10 @@ +"""test too short name +""" + +__revision__ = 1 + +A = None + +def a(): + """yo""" + pass diff --git a/test/input/func_w0111.py b/test/input/func_w0111.py new file mode 100644 index 000000000..f8ad440a3 --- /dev/null +++ b/test/input/func_w0111.py @@ -0,0 +1,10 @@ +"""test black listed name +""" + +__revision__ = 1 + +A = None + +def baz(): + """yo""" + pass diff --git a/test/input/func_w0112.py b/test/input/func_w0112.py new file mode 100644 index 000000000..5cd01ae34 --- /dev/null +++ b/test/input/func_w0112.py @@ -0,0 +1,37 @@ +"""test max branch +""" + +__revision__ = '' + +def stupid_function(arg): + """reallly stupid function""" + if arg == 1: + print 1 + elif arg == 2: + print 2 + elif arg == 3: + print 3 + elif arg == 4: + print 4 + elif arg == 5: + print 5 + elif arg == 6: + print 6 + elif arg == 7: + print 7 + elif arg == 8: + print 8 + elif arg == 9: + print 9 + elif arg == 10: + print 10 + else: + if arg < 1: + print 0 + else: + print 100 + arg = 0 + if arg: + print None + else: + print arg diff --git a/test/input/func_w0122.py b/test/input/func_w0122.py new file mode 100644 index 000000000..178c2521e --- /dev/null +++ b/test/input/func_w0122.py @@ -0,0 +1,13 @@ +"""test global statement""" + +__revision__ = 0 + +exec 'a = __revision__' +exec 'a = 1' in {} + +exec 'a = 1' in globals() + +def func(): + """exec in local scope""" + exec 'b = 1' + diff --git a/test/input/func_w0133.py b/test/input/func_w0133.py new file mode 100644 index 000000000..c0304ec3c --- /dev/null +++ b/test/input/func_w0133.py @@ -0,0 +1,54 @@ +# pylint: disable-msg=R0903,R0201 +"""test Invalid name""" + +__revision__ = 1 + +def Run(): + """method without any good name""" + class B: + """nested class should not be tested has a variable""" + def __init__(self): + pass + bBb = 1 + return A, bBb + +def run(): + """anothrer method without only good name""" + class Aaa: + """nested class should not be tested has a variable""" + def __init__(self): + pass + bbb = 1 + return Aaa(bbb) + +A = None + +def HOHOHOHO(): + """yo""" + HIHIHI = 1 + print HIHIHI + +class xyz: + """yo""" + def __init__(self): + pass + + def Youplapoum(self): + """bad method name""" + + +def nested_args(arg1, (arg21, arg22)): + """function with nested arguments""" + print arg1, arg21, arg22 + + +GOOD_CONST_NAME = '' +benpasceluila = 0 + +class Correct: + """yo""" + def __init__(self): + self.cava = 12 + self._Ca_va_Pas = None + +V = [WHAT_Ever_inListComp for WHAT_Ever_inListComp in GOOD_CONST_NAME] diff --git a/test/input/func_w0151.py b/test/input/func_w0151.py new file mode 100644 index 000000000..4c5544669 --- /dev/null +++ b/test/input/func_w0151.py @@ -0,0 +1,7 @@ +"""check black listed builtins +""" + +__revision__ = apply(map, (str, (1, 2, 3))) + +YYYYY = map(str, (1, 2, 3)) + diff --git a/test/input/func_w0152.py b/test/input/func_w0152.py new file mode 100644 index 000000000..5054d9072 --- /dev/null +++ b/test/input/func_w0152.py @@ -0,0 +1,14 @@ +"""check use of * or ** +""" + +from operator import add +__revision__ = reduce(*(add, (1, 2, 3))) + + +def func(arg1, arg2): + """magic function + """ + return arg2, arg1 + +MYDICT = {'arg1':2, 'arg2': 4} +func(**MYDICT) diff --git a/test/input/func_w0202.py b/test/input/func_w0202.py new file mode 100644 index 000000000..4d36d40da --- /dev/null +++ b/test/input/func_w0202.py @@ -0,0 +1,17 @@ +"""check static method with self or cls as first argument""" + +__revision__ = None + +class Abcd: + """dummy""" + + def method1(self): + """hehe""" + method1 = staticmethod(method1) + + def method2(cls): + """hehe""" + method2 = staticmethod(method2) + + def __init__(self): + pass diff --git a/test/input/func_w0205.py b/test/input/func_w0205.py new file mode 100644 index 000000000..277306ac2 --- /dev/null +++ b/test/input/func_w0205.py @@ -0,0 +1,24 @@ +"""check different signatures""" + +__revision__ = 0 + +class Abcd: + '''dummy''' + def __init__(self): + self.aarg = False + def abcd(self, aaa, bbbb=None): + """hehehe""" + print self, aaa, bbbb + def args(self): + """gaarrrggll""" + self.aarg = True + +class Cdef(Abcd): + """dummy""" + def __init__(self, aaa): + Abcd.__init__(self) + self.aaa = aaa + + def abcd(self, aaa=1, bbbb=None): + """hehehe""" + print self, aaa, bbbb diff --git a/test/input/func_w0223.py b/test/input/func_w0223.py new file mode 100644 index 000000000..369686218 --- /dev/null +++ b/test/input/func_w0223.py @@ -0,0 +1,27 @@ +# pylint: disable-msg=R0903,R0922 +"""test overriding of abstract method +""" + +__revision__ = '$Id: func_w0223.py,v 1.2 2004-09-29 08:35:13 syt Exp $' + +class Abstract: + """abstract class + """ + def aaaa(self): + """should be overriden in concrete class""" + raise NotImplementedError() + + + def bbbb(self): + """should be overriden in concrete class""" + raise NotImplementedError() + + def __init__(self): + pass + +class Concret(Abstract): + """concret class""" + + def aaaa(self): + """overidden form Abstract""" + print self diff --git a/test/input/func_w0231.py b/test/input/func_w0231.py new file mode 100644 index 000000000..3f592ec78 --- /dev/null +++ b/test/input/func_w0231.py @@ -0,0 +1,38 @@ +# pylint: disable-msg=R0903 +"""test for __init__ not called +""" + +__revision__ = '$Id: func_w0231.py,v 1.3 2004-09-29 08:35:13 syt Exp $' + +class AAAA: + """ancestor 1""" + + def __init__(self): + print 'init', self + +class BBBB: + """ancestor 2""" + + def __init__(self): + print 'init', self + +class CCCC: + """ancestor 3""" + + +class ZZZZ(AAAA, BBBB, CCCC): + """derived class""" + + def __init__(self): + AAAA.__init__(self) + +class NewStyleA(object): + """new style class""" + def __init__(self): + super(NewStyleA, self).__init__() + print 'init', self + +class NewStyleB(NewStyleA): + """derived new style class""" + def __init__(self): + super(NewStyleB, self).__init__() diff --git a/test/input/func_w0233.py b/test/input/func_w0233.py new file mode 100644 index 000000000..763ccf0aa --- /dev/null +++ b/test/input/func_w0233.py @@ -0,0 +1,19 @@ +# pylint: disable-msg=R0903 +"""test for call to __init__ from a non ancestor class +""" + +__revision__ = '$Id: func_w0233.py,v 1.2 2004-09-29 08:35:13 syt Exp $' + +class AAAA: + """ancestor 1""" + + def __init__(self): + print 'init', self + BBBB.__init__(self) + +class BBBB: + """ancestor 2""" + + def __init__(self): + print 'init', self + diff --git a/test/input/func_w0302.py b/test/input/func_w0302.py new file mode 100644 index 000000000..a78f479a6 --- /dev/null +++ b/test/input/func_w0302.py @@ -0,0 +1,1016 @@ +"""test too much line in modules +""" + +__revision__ = 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +ZERFZAER = 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +HEHEHE = 2 diff --git a/test/input/func_w0312.py b/test/input/func_w0312.py new file mode 100644 index 000000000..06a811023 --- /dev/null +++ b/test/input/func_w0312.py @@ -0,0 +1,11 @@ +"""test mixed tabs and spaces""" + +__revision__ = 1 + +def spaces_func(): + """yo""" + print "yo" + +def tab_func(): + """yo""" + print "yo" diff --git a/test/input/func_w0331.py b/test/input/func_w0331.py new file mode 100644 index 000000000..7e3452335 --- /dev/null +++ b/test/input/func_w0331.py @@ -0,0 +1,7 @@ +"""check use of <> +""" + +__revision__ = 1 + +if __revision__ <> 2: + __revision__ = 2 diff --git a/test/input/func_w0332.py b/test/input/func_w0332.py new file mode 100644 index 000000000..ff078efc5 --- /dev/null +++ b/test/input/func_w0332.py @@ -0,0 +1,4 @@ +"""check use of l as long int marker +""" + +__revision__ = 1l diff --git a/test/input/func_w0401.py b/test/input/func_w0401.py new file mode 100644 index 000000000..6b7a64b64 --- /dev/null +++ b/test/input/func_w0401.py @@ -0,0 +1,9 @@ +"""test cyclic import +""" +__revision__ = 0 + + +from input import w0401_cycle + +if __revision__: + print w0401_cycle diff --git a/test/input/func_w0402.py b/test/input/func_w0402.py new file mode 100644 index 000000000..53752db45 --- /dev/null +++ b/test/input/func_w0402.py @@ -0,0 +1,9 @@ +"""test wildard import +""" +__revision__ = 0 + +from input.func_fixme import * + +def abcd(): + """use imports""" + function() diff --git a/test/input/func_w0403.py b/test/input/func_w0403.py new file mode 100644 index 000000000..72fb79502 --- /dev/null +++ b/test/input/func_w0403.py @@ -0,0 +1,12 @@ +"""test deprecated module +""" + +__revision__ = 0 + + +if __revision__: + import Bastion + print Bastion + # false positive (#10061) + import stringfile + print stringfile diff --git a/test/input/func_w0404.py b/test/input/func_w0404.py new file mode 100644 index 000000000..fd38e6a58 --- /dev/null +++ b/test/input/func_w0404.py @@ -0,0 +1,10 @@ +"""test relative import +""" + +__revision__ = 0 + +import func_w0302 + +if __revision__: + print func_w0302 + diff --git a/test/input/func_w0405.py b/test/input/func_w0405.py new file mode 100644 index 000000000..745c615cb --- /dev/null +++ b/test/input/func_w0405.py @@ -0,0 +1,31 @@ +"""check reimport +""" + +__revision__ = 0 + +import os +from os.path import join, exists + +import os +import re as _re + +_re.match('yo', '.*') + +if __revision__: + print os + from os.path import exists + print join, exists + +def func(yooo): + """reimport in different scope""" + import os as ass + ass.remove(yooo) + import re + re.compile('.*') + +if 1: + import sys + print sys.modules +else: + print 'bla' + import sys diff --git a/test/input/func_w0406.py b/test/input/func_w0406.py new file mode 100644 index 000000000..e20508f5d --- /dev/null +++ b/test/input/func_w0406.py @@ -0,0 +1,9 @@ +"""test module importing itself +""" +__revision__ = 0 + +import func_w0406 + +if __revision__: + print func_w0406 + diff --git a/test/input/func_w0611.py b/test/input/func_w0611.py new file mode 100644 index 000000000..2c3796699 --- /dev/null +++ b/test/input/func_w0611.py @@ -0,0 +1,22 @@ +"""check unused import +""" +__revision__ = 1 +import os +import sys + +class NonRegr: + """???""" + def __init__(self): + print 'initialized' + + def sys(self): + """should not get sys from there...""" + print self, sys + + def dummy(self, truc): + """yo""" + return self, truc + + def blop(self): + """yo""" + print self, 'blip' diff --git a/test/input/func_w0612.py b/test/input/func_w0612.py new file mode 100644 index 000000000..43b551c4f --- /dev/null +++ b/test/input/func_w0612.py @@ -0,0 +1,8 @@ +"""test unused variable +""" + +__revision__ = 0 + +def function(): + """"yo""" + aaaa = 1 diff --git a/test/input/func_w0613.py b/test/input/func_w0613.py new file mode 100644 index 000000000..0725335e3 --- /dev/null +++ b/test/input/func_w0613.py @@ -0,0 +1,18 @@ +# pylint: disable-msg=R0903 +"""test unused argument +""" + +__revision__ = 1 + +def function(arg=1): + """ignore arg""" + + +class AAAA: + """dummy class""" + + def method(self, arg): + """dummy method""" + print self + def __init__(self): + pass diff --git a/test/input/func_w0622.py b/test/input/func_w0622.py new file mode 100644 index 000000000..ea9d1b2c0 --- /dev/null +++ b/test/input/func_w0622.py @@ -0,0 +1,11 @@ +# pylint: disable-msg=C0103 +"""test built-in redefinition +""" +__revision__ = 0 + +def function(): + """yo""" + type = 1 + print type + +map = {} diff --git a/test/input/func_w0701.py b/test/input/func_w0701.py new file mode 100644 index 000000000..9c1b7273c --- /dev/null +++ b/test/input/func_w0701.py @@ -0,0 +1,12 @@ +"""test string exception +""" + +__revision__ = '' + +def function1(): + """hehehe""" + raise "String Exception" + +def function2(): + """hehehe""" + raise 'exception', 'message' diff --git a/test/input/func_w0702.py b/test/input/func_w0702.py new file mode 100644 index 000000000..38a6417e0 --- /dev/null +++ b/test/input/func_w0702.py @@ -0,0 +1,17 @@ +"""check empty except statement +""" + +__revision__ = 0 + +if __revision__: + try: + print __revision__ + except: + print 'error' + +try: + __revision__ += 1 +except TypeError: + print 'error' +except Exception: + print 'error' diff --git a/test/input/func_w0703.py b/test/input/func_w0703.py new file mode 100644 index 000000000..4040540b5 --- /dev/null +++ b/test/input/func_w0703.py @@ -0,0 +1,9 @@ +"""check empty except statement +""" + +__revision__ = 0 + +try: + __revision__ += 1 +except Exception: + print 'error' diff --git a/test/input/func_w0704.py b/test/input/func_w0704.py new file mode 100644 index 000000000..e8c643284 --- /dev/null +++ b/test/input/func_w0704.py @@ -0,0 +1,16 @@ +"""test empty except +""" + +__revision__ = 1 + +try: + __revision__ += 1 +except TypeError: + pass + +try: + __revision__ += 1 +except TypeError: + pass +else: + __revision__ = None diff --git a/test/input/func_w0705.py b/test/input/func_w0705.py new file mode 100644 index 000000000..898e2b8f0 --- /dev/null +++ b/test/input/func_w0705.py @@ -0,0 +1,46 @@ +"""test misordered except +""" + +__revision__ = 1 + +try: + __revision__ += 1 +except Exception: + __revision__ = None +except TypeError: + __revision__ = None + +try: + __revision__ += 1 +except LookupError: + __revision__ = None +except IndexError: + __revision__ = None + +try: + __revision__ += 1 +except (LookupError, NameError): + __revision__ = None +except (IndexError, UnboundLocalError): + __revision__ = None + +try: + __revision__ += 1 +except: + pass +except Exception: + pass + +try: + __revision__ += 1 +except TypeError: + __revision__ = None +except: + __revision__ = None + +try: + __revision__ += 1 +except Exception: + pass +except: + pass diff --git a/test/input/func_w0801.py b/test/input/func_w0801.py new file mode 100644 index 000000000..cd386ff55 --- /dev/null +++ b/test/input/func_w0801.py @@ -0,0 +1,11 @@ +"""test code similarities +by defaut docstring are not considered +""" +__revision__ = 'id' +A = 2 +B = 3 +C = A + B +# need more than X lines to trigger the message +C *= 2 +A -= B +# all this should be detected diff --git a/test/input/func_wrong_encoding.py b/test/input/func_wrong_encoding.py new file mode 100644 index 000000000..267fa2c90 --- /dev/null +++ b/test/input/func_wrong_encoding.py @@ -0,0 +1,6 @@ +# -*- coding: UTF-8 -*- +""" check correct wrong encoding declaration +""" + +__revision__ = 'éééé' + diff --git a/test/input/indirect1.py b/test/input/indirect1.py new file mode 100644 index 000000000..eac6242b8 --- /dev/null +++ b/test/input/indirect1.py @@ -0,0 +1,4 @@ +class TotoInterface: + def machin(self): + raise NotImplementedError + diff --git a/test/input/indirect2.py b/test/input/indirect2.py new file mode 100644 index 000000000..6eefece60 --- /dev/null +++ b/test/input/indirect2.py @@ -0,0 +1,7 @@ +from indirect1 import TotoInterface + +class AbstractToto: + __implements__ = TotoInterface + + def helper(self): + return 'help' diff --git a/test/input/indirect3.py b/test/input/indirect3.py new file mode 100644 index 000000000..dac085398 --- /dev/null +++ b/test/input/indirect3.py @@ -0,0 +1,5 @@ +from indirect2 import AbstractToto + +class ConcreteToto(AbstractToto): + def machin(self): + return self.helper()*2 diff --git a/test/input/noext b/test/input/noext new file mode 100644 index 000000000..8aeda06d3 --- /dev/null +++ b/test/input/noext @@ -0,0 +1,4 @@ +#!/usr/bin/env python +"""a python file without .py extension""" + +__revision__ = None diff --git a/test/input/similar1 b/test/input/similar1 new file mode 100644 index 000000000..bc881871c --- /dev/null +++ b/test/input/similar1 @@ -0,0 +1,19 @@ +this file is used +to check the similar +command line tool + +see the similar2 file which is almost the +same file as this one. +more than 4 +identical lines should +be +detected + + +héhéhéh + + + + + +Yo ! diff --git a/test/input/similar2 b/test/input/similar2 new file mode 100644 index 000000000..56f9844fd --- /dev/null +++ b/test/input/similar2 @@ -0,0 +1,19 @@ +this file is used +to check the similar +command line tool + +see the similar1 file which is almost the +same file as this one. +more than 4 +identical lines should +be +detected + + +hohohoh + + + + + +Yo ! diff --git a/test/input/w0401_cycle.py b/test/input/w0401_cycle.py new file mode 100644 index 000000000..1fbf88060 --- /dev/null +++ b/test/input/w0401_cycle.py @@ -0,0 +1,9 @@ +"""w0401 dependancy +""" + +__revision__ = 0 + +import input.func_w0401 + +if __revision__: + print input diff --git a/test/input/w0801_same.py b/test/input/w0801_same.py new file mode 100644 index 000000000..cd386ff55 --- /dev/null +++ b/test/input/w0801_same.py @@ -0,0 +1,11 @@ +"""test code similarities +by defaut docstring are not considered +""" +__revision__ = 'id' +A = 2 +B = 3 +C = A + B +# need more than X lines to trigger the message +C *= 2 +A -= B +# all this should be detected diff --git a/test/messages/builtin_module.txt b/test/messages/builtin_module.txt new file mode 100644 index 000000000..88293186d --- /dev/null +++ b/test/messages/builtin_module.txt @@ -0,0 +1 @@ +F: 0: ignored builtin module sys diff --git a/test/messages/func___future___import_not_first_stmt.txt b/test/messages/func___future___import_not_first_stmt.txt new file mode 100644 index 000000000..ff96b5549 --- /dev/null +++ b/test/messages/func___future___import_not_first_stmt.txt @@ -0,0 +1 @@ +W: 4: __future__ import is not the first non docstring statement diff --git a/test/messages/func___name___access.txt b/test/messages/func___name___access.txt new file mode 100644 index 000000000..51aeeaa3d --- /dev/null +++ b/test/messages/func___name___access.txt @@ -0,0 +1,3 @@ +E: 11:Aaaa.__init__: Instance of 'Aaaa' has no '__name__' member +E: 21:NewClass.__init__: Instance of 'NewClass' has no '__name__' member + diff --git a/test/messages/func_attrs_definition_order.txt b/test/messages/func_attrs_definition_order.txt new file mode 100644 index 000000000..895c315fb --- /dev/null +++ b/test/messages/func_attrs_definition_order.txt @@ -0,0 +1 @@ +E: 9:Aaaa.__init__: Access to member '_var2' before its definition line 10 diff --git a/test/messages/func_bad_assigment_to_exception_var.txt b/test/messages/func_bad_assigment_to_exception_var.txt new file mode 100644 index 000000000..9b9bc027a --- /dev/null +++ b/test/messages/func_bad_assigment_to_exception_var.txt @@ -0,0 +1,5 @@ +W: 11: Identifier e used to raise an exception is assigned to 1 line 7 +W: 15: Identifier e2 used to raise an exception is assigned to 'yo' line 8 +W: 20:func: Identifier e3 used to raise an exception is assigned to None +W: 30: Identifier e3 used to raise an exception is assigned to None + diff --git a/test/messages/func_base_stmt_without_effect.txt b/test/messages/func_base_stmt_without_effect.txt new file mode 100644 index 000000000..b50fd8225 --- /dev/null +++ b/test/messages/func_base_stmt_without_effect.txt @@ -0,0 +1,3 @@ +W: 9: Statement seems to have no effect +W: 11: Statement seems to have no effect +W: 15: Statement seems to have no effect diff --git a/test/messages/func_block_disable_msg.txt b/test/messages/func_block_disable_msg.txt new file mode 100644 index 000000000..0019f0373 --- /dev/null +++ b/test/messages/func_block_disable_msg.txt @@ -0,0 +1,9 @@ +E: 26:Foo.meth3: Instance of 'Foo' has no 'blop' member +E: 36:Foo.meth4: Instance of 'Foo' has no 'blip' member +E: 46:Foo.meth5: Instance of 'Foo' has no 'blip' member +E: 61:Foo.meth6: Instance of 'Foo' has no 'blip' member +E: 72:Foo.meth7: Instance of 'Foo' has no 'blip' member +E: 75:Foo.meth7: Instance of 'Foo' has no 'blip' member +E: 77:Foo.meth7: Instance of 'Foo' has no 'blip' member +E: 83:Foo.meth8: Instance of 'Foo' has no 'blip' member +W: 11:Foo.meth1: Unused argument 'arg' diff --git a/test/messages/func_class_members.txt b/test/messages/func_class_members.txt new file mode 100644 index 000000000..ba2c639a7 --- /dev/null +++ b/test/messages/func_class_members.txt @@ -0,0 +1,3 @@ +E: 16:MyClass.test: Instance of 'MyClass' has no 'incorrect' member +E: 17:MyClass.test: Instance of 'MyClass' has no 'nonexistent1' member +E: 18:MyClass.test: Instance of 'MyClass' has no 'nonexistent2' member diff --git a/test/messages/func_continue_not_in_loop.txt b/test/messages/func_continue_not_in_loop.txt new file mode 100644 index 000000000..d3a318309 --- /dev/null +++ b/test/messages/func_continue_not_in_loop.txt @@ -0,0 +1,2 @@ +E: 8:run: 'continue' not properly in loop +E: 10:run: 'break' not properly in loop diff --git a/test/messages/func_dangerous_default.txt b/test/messages/func_dangerous_default.txt new file mode 100644 index 000000000..21d32e022 --- /dev/null +++ b/test/messages/func_dangerous_default.txt @@ -0,0 +1,2 @@ +W: 7:function1: Dangerous default value [] as argument +W: 11:function2: Dangerous default value HEHE ({}) as argument diff --git a/test/messages/func_docstring.txt b/test/messages/func_docstring.txt new file mode 100644 index 000000000..d37939207 --- /dev/null +++ b/test/messages/func_docstring.txt @@ -0,0 +1,4 @@ +C: 0: Missing docstring +C: 5:function1: Missing docstring +C: 17:AAAA: Missing docstring +C: 33:AAAA.method1: Missing docstring diff --git a/test/messages/func_dotted_ancestor.txt b/test/messages/func_dotted_ancestor.txt new file mode 100644 index 000000000..84247b86a --- /dev/null +++ b/test/messages/func_dotted_ancestor.txt @@ -0,0 +1 @@ +R: 8:Aaaa: Not enough public methods (0/2) diff --git a/test/messages/func_e0011.txt b/test/messages/func_e0011.txt new file mode 100644 index 000000000..55f07b1d4 --- /dev/null +++ b/test/messages/func_e0011.txt @@ -0,0 +1 @@ +E: 1: Unrecognized file option 'bouboule' diff --git a/test/messages/func_e0012.txt b/test/messages/func_e0012.txt new file mode 100644 index 000000000..a6d1b698c --- /dev/null +++ b/test/messages/func_e0012.txt @@ -0,0 +1 @@ +E: 1: Bad option value 'W04044' diff --git a/test/messages/func_e0101.txt b/test/messages/func_e0101.txt new file mode 100644 index 000000000..53d007d4a --- /dev/null +++ b/test/messages/func_e0101.txt @@ -0,0 +1 @@ +E: 10:MyClass.__init__: Explicit return in __init__ diff --git a/test/messages/func_e0203.txt b/test/messages/func_e0203.txt new file mode 100644 index 000000000..869cf22d8 --- /dev/null +++ b/test/messages/func_e0203.txt @@ -0,0 +1,2 @@ +C: 12:Abcd.abcd: Class method should have "cls" as first argument + diff --git a/test/messages/func_e0204.txt b/test/messages/func_e0204.txt new file mode 100644 index 000000000..8e05efea5 --- /dev/null +++ b/test/messages/func_e0204.txt @@ -0,0 +1,3 @@ +E: 10:Abcd.__init__: Method should have "self" as first argument +E: 14:Abcd.abdc: Method should have "self" as first argument + diff --git a/test/messages/func_e0205.txt b/test/messages/func_e0205.txt new file mode 100644 index 000000000..1adf408c8 --- /dev/null +++ b/test/messages/func_e0205.txt @@ -0,0 +1,2 @@ +E: 14:Cdef.abcd: An attribute inherited from Abcd hide this method + diff --git a/test/messages/func_e0206.txt b/test/messages/func_e0206.txt new file mode 100644 index 000000000..c15f841b7 --- /dev/null +++ b/test/messages/func_e0206.txt @@ -0,0 +1,3 @@ +E: 6:Abcd: Interface resolved to None is not a class +E: 13:Cdef: Interface resolved to None is not a class + diff --git a/test/messages/func_e0214.txt b/test/messages/func_e0214.txt new file mode 100644 index 000000000..e3fb5f5b7 --- /dev/null +++ b/test/messages/func_e0214.txt @@ -0,0 +1,2 @@ +C: 11:MetaClass.whatever: Metaclass method should have "mcs" as first argument + diff --git a/test/messages/func_e0601.txt b/test/messages/func_e0601.txt new file mode 100644 index 000000000..321c7316b --- /dev/null +++ b/test/messages/func_e0601.txt @@ -0,0 +1 @@ +E: 8:function: Using variable 'aaaa' before assignment diff --git a/test/messages/func_empty_module.txt b/test/messages/func_empty_module.txt new file mode 100644 index 000000000..2a8190d4a --- /dev/null +++ b/test/messages/func_empty_module.txt @@ -0,0 +1,2 @@ +C: 0: Missing docstring +C: 0: Missing required attribute "__revision__" diff --git a/test/messages/func_exceptions_raise_type_error.txt b/test/messages/func_exceptions_raise_type_error.txt new file mode 100644 index 000000000..8ac57782e --- /dev/null +++ b/test/messages/func_exceptions_raise_type_error.txt @@ -0,0 +1,2 @@ +E: 11: Raising int while only classes, instances or string are allowed +E: 14: Raising None while only classes, instances or string are allowed
\ No newline at end of file diff --git a/test/messages/func_f0001.txt b/test/messages/func_f0001.txt new file mode 100644 index 000000000..87c315d27 --- /dev/null +++ b/test/messages/func_f0001.txt @@ -0,0 +1 @@ +W: 3: Unused import whatever diff --git a/test/messages/func_f0401.txt b/test/messages/func_f0401.txt new file mode 100644 index 000000000..1ae5ea469 --- /dev/null +++ b/test/messages/func_f0401.txt @@ -0,0 +1,2 @@ +F: 8:function: Unable to import 'tutu.toto' (No module named tutu) + diff --git a/test/messages/func_fixme.txt b/test/messages/func_fixme.txt new file mode 100644 index 000000000..2544ce8f4 --- /dev/null +++ b/test/messages/func_fixme.txt @@ -0,0 +1,2 @@ +W: 5: FIXME: beep +W: 8: XXX:bop''' diff --git a/test/messages/func_format.txt b/test/messages/func_format.txt new file mode 100644 index 000000000..c87d01dcd --- /dev/null +++ b/test/messages/func_format.txt @@ -0,0 +1,25 @@ +C: 6: Operator not preceded by a space +notpreceded= 1 + ^ +C: 7: Operator not followed by a space +notfollowed =1 + ^ +C: 8: Operator not followed by a space +notfollowed <=1 + ^^ +C: 19: Comma not followed by a space +aaaa,bbbb = 1,2 + ^^ +C: 24: More than one statement on a single line +C: 26: Comma not followed by a space + aaaa,bbbb = 1,2 + ^^ +C: 27: Comma not followed by a space + aaaa,bbbb = bbbb,aaaa + ^^ +C: 29: Comma not followed by a space +bbbb = (1,2,3) + ^^ +C: 51:other: Operator not preceded by a space + funky= funky+2 + ^ diff --git a/test/messages/func_globals.txt b/test/messages/func_globals.txt new file mode 100644 index 000000000..40963f288 --- /dev/null +++ b/test/messages/func_globals.txt @@ -0,0 +1,6 @@ +E: 27: Undefined variable 'CSTE' +E: 32:other: Undefined variable 'HOP' +W: 23:fix_contant: Using the global statement +W: 26: Using the global statement at the module level +W: 31:other: Using global for 'HOP' but no assigment is done +W: 39:define_constant: Global variable 'somevar' undefined at the module level diff --git a/test/messages/func_i0010.txt b/test/messages/func_i0010.txt new file mode 100644 index 000000000..315f701f1 --- /dev/null +++ b/test/messages/func_i0010.txt @@ -0,0 +1 @@ +I: 1: Unable to consider inline option 'disable-all' diff --git a/test/messages/func_i0011.txt b/test/messages/func_i0011.txt new file mode 100644 index 000000000..e4d29751e --- /dev/null +++ b/test/messages/func_i0011.txt @@ -0,0 +1,2 @@ +I: 1: Locally disabling 'W0404' + diff --git a/test/messages/func_i0012.txt b/test/messages/func_i0012.txt new file mode 100644 index 000000000..0bb035c1d --- /dev/null +++ b/test/messages/func_i0012.txt @@ -0,0 +1,2 @@ +I: 1: Locally enabling 'W0404' + diff --git a/test/messages/func_indent.txt b/test/messages/func_indent.txt new file mode 100644 index 000000000..aa3645f49 --- /dev/null +++ b/test/messages/func_indent.txt @@ -0,0 +1,3 @@ +W: 5: Bad indentation. Found 1 spaces, expected 4 +W: 6: Bad indentation. Found 1 spaces, expected 4 +W: 13: Bad indentation. Found 5 spaces, expected 4 diff --git a/test/messages/func_init_vars.txt b/test/messages/func_init_vars.txt new file mode 100644 index 000000000..44ef6f314 --- /dev/null +++ b/test/messages/func_init_vars.txt @@ -0,0 +1 @@ +W: 18:MyClass.met: Attribute 'base_var' defined outside __init__ diff --git a/test/messages/func_interfaces.txt b/test/messages/func_interfaces.txt new file mode 100644 index 000000000..546acddca --- /dev/null +++ b/test/messages/func_interfaces.txt @@ -0,0 +1,5 @@ +E: 46:MissingMethod: Missing method 'truc' from IMachin interface +E: 77:InterfaceCantBeFound: Undefined variable 'undefined' +F: 77:InterfaceCantBeFound: failed to resolve interfaces implemented by InterfaceCantBeFound (undefined) +F: 90:InterfaceCantBeFound2: failed to resolve interfaces implemented by InterfaceCantBeFound2 ((BadArgument.__implements__) + (Correct2.__implements__)) +W: 71:BadArgument.troc: Arguments number differs from IMachin interface method diff --git a/test/messages/func_method_could_be_function.txt b/test/messages/func_method_could_be_function.txt new file mode 100644 index 000000000..1def89e7f --- /dev/null +++ b/test/messages/func_method_could_be_function.txt @@ -0,0 +1 @@ +R: 16:Toto.function_method: Method could be a function diff --git a/test/messages/func_method_missing_self.txt b/test/messages/func_method_missing_self.txt new file mode 100644 index 000000000..861871f44 --- /dev/null +++ b/test/messages/func_method_missing_self.txt @@ -0,0 +1 @@ +E: 14:MyClass.met: Method has no argument diff --git a/test/messages/func_method_without_self_but_self_assignment.txt b/test/messages/func_method_without_self_but_self_assignment.txt new file mode 100644 index 000000000..da5ee0234 --- /dev/null +++ b/test/messages/func_method_without_self_but_self_assignment.txt @@ -0,0 +1,2 @@ +E: 13:Example.setup: Method has no argument +E: 15:Example.setup: Undefined variable 'self' diff --git a/test/messages/func_nameerror_on_string_substitution.txt b/test/messages/func_nameerror_on_string_substitution.txt new file mode 100644 index 000000000..aab21024b --- /dev/null +++ b/test/messages/func_nameerror_on_string_substitution.txt @@ -0,0 +1,2 @@ +E: 5: Using variable 'MSG' before assignment +E: 8: Using variable 'MSG2' before assignment diff --git a/test/messages/func_names_imported_from_module.txt b/test/messages/func_names_imported_from_module.txt new file mode 100644 index 000000000..62b0344f2 --- /dev/null +++ b/test/messages/func_names_imported_from_module.txt @@ -0,0 +1,8 @@ +E: 6: No name 'tutu' in module 'logilab.common' +E: 7: No name 'toto' in module 'logilab.common' +E: 11: Module 'logilab.common.modutils' has no 'nonexistant_function' member +E: 12: Module 'logilab.common.modutils' has no 'another' member +E: 13: Module 'logilab.common.modutils' has no 'yo' member +E: 17: Module 'sys' has no 'stdoout' member +E: 24: No name 'compiile' in module 're' +E: 24: No name 'findiiter' in module 're' diff --git a/test/messages/func_newstyle___slots__.txt b/test/messages/func_newstyle___slots__.txt new file mode 100644 index 000000000..be6b8d10c --- /dev/null +++ b/test/messages/func_newstyle___slots__.txt @@ -0,0 +1 @@ +E: 10:HaNonNonNon: Use __slots__ on an old style class diff --git a/test/messages/func_newstyle_exceptions.txt b/test/messages/func_newstyle_exceptions.txt new file mode 100644 index 000000000..d92e3bf25 --- /dev/null +++ b/test/messages/func_newstyle_exceptions.txt @@ -0,0 +1,4 @@ +E: 25:fonctionNew: Raising a new style class +E: 33:fonctionNew2: Raising a new style class +W: 21:fonctionBof: Exception doesn't inherit from standard "Exception" class +W: 29:fonctionBof2: Exception doesn't inherit from standard "Exception" class diff --git a/test/messages/func_newstyle_property.txt b/test/messages/func_newstyle_property.txt new file mode 100644 index 000000000..f0ef26145 --- /dev/null +++ b/test/messages/func_newstyle_property.txt @@ -0,0 +1 @@ +W: 16:HaNonNonNon: Use of "property" on an old style class diff --git a/test/messages/func_newstyle_super.txt b/test/messages/func_newstyle_super.txt new file mode 100644 index 000000000..d0cdf78c2 --- /dev/null +++ b/test/messages/func_newstyle_super.txt @@ -0,0 +1,4 @@ +E: 7:Aaaa.hop: Use super on an old style class +E: 11:Aaaa.__init__: Use super on an old style class +E: 20:NewAaaa.__init__: Bad first argument 'object' given to super class + diff --git a/test/messages/func_nonascii_noencoding.txt b/test/messages/func_nonascii_noencoding.txt new file mode 100644 index 000000000..dd68a3c62 --- /dev/null +++ b/test/messages/func_nonascii_noencoding.txt @@ -0,0 +1 @@ +E: 1: Non ascii characters found but no encoding specified (PEP 263) diff --git a/test/messages/func_r0901.txt b/test/messages/func_r0901.txt new file mode 100644 index 000000000..d20460e22 --- /dev/null +++ b/test/messages/func_r0901.txt @@ -0,0 +1,2 @@ +R: 22:Iiii: Too many ancestors (8/7) +R: 25:Jjjj: Too many ancestors (9/7) diff --git a/test/messages/func_r0902.txt b/test/messages/func_r0902.txt new file mode 100644 index 000000000..5dcb66925 --- /dev/null +++ b/test/messages/func_r0902.txt @@ -0,0 +1 @@ +R: 5:Aaaa: Too many instance attributes (21/7) diff --git a/test/messages/func_r0903.txt b/test/messages/func_r0903.txt new file mode 100644 index 000000000..6ab8888cc --- /dev/null +++ b/test/messages/func_r0903.txt @@ -0,0 +1 @@ +R: 4:Aaaa: Not enough public methods (1/2) diff --git a/test/messages/func_r0904.txt b/test/messages/func_r0904.txt new file mode 100644 index 000000000..76baf721a --- /dev/null +++ b/test/messages/func_r0904.txt @@ -0,0 +1 @@ +R: 4:Aaaa: Too many public methods (21/20) diff --git a/test/messages/func_r0921.txt b/test/messages/func_r0921.txt new file mode 100644 index 000000000..7e9a44286 --- /dev/null +++ b/test/messages/func_r0921.txt @@ -0,0 +1 @@ +R: 4:Aaaa: Abstract class not referenced diff --git a/test/messages/func_r0922.txt b/test/messages/func_r0922.txt new file mode 100644 index 000000000..70319ee80 --- /dev/null +++ b/test/messages/func_r0922.txt @@ -0,0 +1 @@ +R: 4:Aaaa: Abstract class is only referenced 1 times diff --git a/test/messages/func_r0923.txt b/test/messages/func_r0923.txt new file mode 100644 index 000000000..11ee61d4b --- /dev/null +++ b/test/messages/func_r0923.txt @@ -0,0 +1 @@ +R: 6:IAaaa: Interface not implemented diff --git a/test/messages/func_reqattrs.txt b/test/messages/func_reqattrs.txt new file mode 100644 index 000000000..7e99095a4 --- /dev/null +++ b/test/messages/func_reqattrs.txt @@ -0,0 +1 @@ +C: 0: Missing required attribute "__revision__" diff --git a/test/messages/func_scope_regrtest.txt b/test/messages/func_scope_regrtest.txt new file mode 100644 index 000000000..27ae2079d --- /dev/null +++ b/test/messages/func_scope_regrtest.txt @@ -0,0 +1,2 @@ +E: 12:Well.Sub: Undefined variable 'Data' +E: 15:Well.func: Undefined variable 'Sub' diff --git a/test/messages/func_syntax_error.txt b/test/messages/func_syntax_error.txt new file mode 100644 index 000000000..deee535f2 --- /dev/null +++ b/test/messages/func_syntax_error.txt @@ -0,0 +1,2 @@ +E: 1: invalid syntax + diff --git a/test/messages/func_toolonglines.txt b/test/messages/func_toolonglines.txt new file mode 100644 index 000000000..29b16c695 --- /dev/null +++ b/test/messages/func_toolonglines.txt @@ -0,0 +1,2 @@ +C: 1: Line too long (90/80) +C: 2: Line too long (94/80) diff --git a/test/messages/func_typecheck_callfunc_assigment.txt b/test/messages/func_typecheck_callfunc_assigment.txt new file mode 100644 index 000000000..96ad43e4c --- /dev/null +++ b/test/messages/func_typecheck_callfunc_assigment.txt @@ -0,0 +1,2 @@ +E: 20: Assigning to function call which doesn't return +W: 28: Assigning to function call which only returns None diff --git a/test/messages/func_typecheck_getattr.txt b/test/messages/func_typecheck_getattr.txt new file mode 100644 index 000000000..6aa34d873 --- /dev/null +++ b/test/messages/func_typecheck_getattr.txt @@ -0,0 +1,9 @@ +E: 25:Client.__init__: Class 'Provider' has no 'cattribute' member +E: 30:Client.use_method: Instance of 'Provider' has no 'hophophop' member +E: 35:Client.use_attr: Instance of 'Provider' has no 'attribute' member +E: 47:Client.test_bt_types: Instance of 'list' has no 'apppend' member +E: 49:Client.test_bt_types: Instance of 'dict' has no 'set' member +E: 51:Client.test_bt_types: Instance of 'tuple' has no 'append' member +E: 53:Client.test_bt_types: Instance of 'str' has no 'loower' member +E: 55:Client.test_bt_types: Instance of 'unicode' has no 'loower' member +E: 57:Client.test_bt_types: Instance of 'int' has no 'whatever' member
\ No newline at end of file diff --git a/test/messages/func_typecheck_non_callable_call.txt b/test/messages/func_typecheck_non_callable_call.txt new file mode 100644 index 000000000..0218074ae --- /dev/null +++ b/test/messages/func_typecheck_non_callable_call.txt @@ -0,0 +1,6 @@ +E: 10: __revision__ is not callable +E: 29: INSTANCE is not callable +E: 31: LIST is not callable +E: 33: DICT is not callable +E: 35: TUPLE is not callable +E: 37: INT is not callable diff --git a/test/messages/func_undefined_var.txt b/test/messages/func_undefined_var.txt new file mode 100644 index 000000000..07666f774 --- /dev/null +++ b/test/messages/func_undefined_var.txt @@ -0,0 +1,5 @@ +E: 8: Undefined variable 'unknown' +E: 14:in_method: Undefined variable 'nomoreknown' +E: 22:bad_default: Undefined variable 'unknown2' +E: 25:bad_default: Undefined variable 'xxxx' +E: 26:bad_default: Undefined variable 'xxxx' diff --git a/test/messages/func_unknown_encoding.txt b/test/messages/func_unknown_encoding.txt new file mode 100644 index 000000000..648af39fc --- /dev/null +++ b/test/messages/func_unknown_encoding.txt @@ -0,0 +1 @@ +E: 1: Unknown encoding specified (IBO-8859-1) diff --git a/test/messages/func_unreachable.txt b/test/messages/func_unreachable.txt new file mode 100644 index 000000000..bb25be0d9 --- /dev/null +++ b/test/messages/func_unreachable.txt @@ -0,0 +1,3 @@ +W: 8:func1: Unreachable code +W: 14:func2: Unreachable code +W: 21:func3: Unreachable code diff --git a/test/messages/func_use_for_or_listcomp_var.txt b/test/messages/func_use_for_or_listcomp_var.txt new file mode 100644 index 000000000..14d61ad65 --- /dev/null +++ b/test/messages/func_use_for_or_listcomp_var.txt @@ -0,0 +1,3 @@ +W: 6: Using possibly undefined loop variable 'C' +W: 15: Using possibly undefined loop variable 'var1' + diff --git a/test/messages/func_w0101.txt b/test/messages/func_w0101.txt new file mode 100644 index 000000000..c42ec2ce9 --- /dev/null +++ b/test/messages/func_w0101.txt @@ -0,0 +1 @@ +R: 6:stupid_function: Too many return statements (11/6) diff --git a/test/messages/func_w0102.txt b/test/messages/func_w0102.txt new file mode 100644 index 000000000..40b619065 --- /dev/null +++ b/test/messages/func_w0102.txt @@ -0,0 +1,5 @@ +E: 15:AAAA.method2: method already defined line 12 +E: 18:AAAA: class already defined line 5 +E: 32:func2: function already defined line 29 +E: 51:exclusive_func2: function already defined line 45 +W: 34:func2: Redefining name '__revision__' from outer scope (line 3) diff --git a/test/messages/func_w0103.txt b/test/messages/func_w0103.txt new file mode 100644 index 000000000..0d6da4250 --- /dev/null +++ b/test/messages/func_w0103.txt @@ -0,0 +1 @@ +R: 6:stupid_function: Too many arguments (9/5) diff --git a/test/messages/func_w0104.txt b/test/messages/func_w0104.txt new file mode 100644 index 000000000..71f6f6229 --- /dev/null +++ b/test/messages/func_w0104.txt @@ -0,0 +1 @@ +R: 6:stupid_function: Too many local variables (16/15) diff --git a/test/messages/func_w0105.txt b/test/messages/func_w0105.txt new file mode 100644 index 000000000..d664dd499 --- /dev/null +++ b/test/messages/func_w0105.txt @@ -0,0 +1 @@ +R: 6:stupid_function: Too many statements (55/50) diff --git a/test/messages/func_w0109.txt b/test/messages/func_w0109.txt new file mode 100644 index 000000000..4685d382c --- /dev/null +++ b/test/messages/func_w0109.txt @@ -0,0 +1 @@ +C: 6:function: Empty docstring diff --git a/test/messages/func_w0110.txt b/test/messages/func_w0110.txt new file mode 100644 index 000000000..28f48aab0 --- /dev/null +++ b/test/messages/func_w0110.txt @@ -0,0 +1 @@ +C: 8:a: Invalid name "a" (should match [a-z_][a-z0-9_]{2,30}$) diff --git a/test/messages/func_w0111.txt b/test/messages/func_w0111.txt new file mode 100644 index 000000000..b2d794bf3 --- /dev/null +++ b/test/messages/func_w0111.txt @@ -0,0 +1 @@ +C: 8:baz: Black listed name "baz" diff --git a/test/messages/func_w0112.txt b/test/messages/func_w0112.txt new file mode 100644 index 000000000..19b2da5d0 --- /dev/null +++ b/test/messages/func_w0112.txt @@ -0,0 +1 @@ +R: 6:stupid_function: Too many branches (15/12) diff --git a/test/messages/func_w0122.txt b/test/messages/func_w0122.txt new file mode 100644 index 000000000..1522cac30 --- /dev/null +++ b/test/messages/func_w0122.txt @@ -0,0 +1,5 @@ +W: 5: Use of the exec statement +W: 6: Use of the exec statement +W: 8: Use of the exec statement +W: 12:func: Use of the exec statement + diff --git a/test/messages/func_w0133.txt b/test/messages/func_w0133.txt new file mode 100644 index 000000000..f2929ae83 --- /dev/null +++ b/test/messages/func_w0133.txt @@ -0,0 +1,9 @@ +C: 8:Run.B: Invalid name "B" (should match [A-Z_][a-zA-Z0-9]+$) +C: 12:Run: Invalid name "bBb" (should match [a-z_][a-z0-9_]{2,30}$) +C: 26:HOHOHOHO: Invalid name "HOHOHOHO" (should match [a-z_][a-z0-9_]{2,30}$) +C: 28:HOHOHOHO: Invalid name "HIHIHI" (should match [a-z_][a-z0-9_]{2,30}$) +C: 31:xyz: Invalid name "xyz" (should match [A-Z_][a-zA-Z0-9]+$) +C: 36:xyz.Youplapoum: Invalid name "Youplapoum" (should match [a-z_][a-z0-9_]{2,30}$) +C: 46: Invalid name "benpasceluila" (should match (([A-Z_][A-Z1-9_]*)|(__.*__))$) +C: 52:Correct.__init__: Invalid name "_Ca_va_Pas" (should match [a-z_][a-z0-9_]{2,30}$) +W: 8:Run.B: Unused variable 'B' diff --git a/test/messages/func_w0151.txt b/test/messages/func_w0151.txt new file mode 100644 index 000000000..dae33d9f9 --- /dev/null +++ b/test/messages/func_w0151.txt @@ -0,0 +1,2 @@ +W: 4: Used builtin function 'apply' +W: 6: Used builtin function 'map' diff --git a/test/messages/func_w0152.txt b/test/messages/func_w0152.txt new file mode 100644 index 000000000..ddf2d0ba6 --- /dev/null +++ b/test/messages/func_w0152.txt @@ -0,0 +1,3 @@ +W: 5: Used * or ** magic +W: 14: Used * or ** magic + diff --git a/test/messages/func_w0202.txt b/test/messages/func_w0202.txt new file mode 100644 index 000000000..d10e5bc89 --- /dev/null +++ b/test/messages/func_w0202.txt @@ -0,0 +1,3 @@ +W: 8:Abcd.method1: Static method with 'self' as first argument +W: 12:Abcd.method2: Static method with 'cls' as first argument + diff --git a/test/messages/func_w0205.txt b/test/messages/func_w0205.txt new file mode 100644 index 000000000..5edbd0a06 --- /dev/null +++ b/test/messages/func_w0205.txt @@ -0,0 +1,2 @@ +W: 22:Cdef.abcd: Signature differs from overriden method + diff --git a/test/messages/func_w0223.txt b/test/messages/func_w0223.txt new file mode 100644 index 000000000..ece889b23 --- /dev/null +++ b/test/messages/func_w0223.txt @@ -0,0 +1,2 @@ +W: 22:Concret: Method 'bbbb' is abstract in class 'Abstract' but is not overriden + diff --git a/test/messages/func_w0231.txt b/test/messages/func_w0231.txt new file mode 100644 index 000000000..84e176d87 --- /dev/null +++ b/test/messages/func_w0231.txt @@ -0,0 +1,2 @@ +W: 19:CCCC: Class has no __init__ method +W: 26:ZZZZ.__init__: __init__ method from base class 'BBBB' is not called diff --git a/test/messages/func_w0233.txt b/test/messages/func_w0233.txt new file mode 100644 index 000000000..9857aa688 --- /dev/null +++ b/test/messages/func_w0233.txt @@ -0,0 +1 @@ +W: 12:AAAA.__init__: __init__ method from a non direct base class 'BBBB' is called diff --git a/test/messages/func_w0302.txt b/test/messages/func_w0302.txt new file mode 100644 index 000000000..ae8a99f68 --- /dev/null +++ b/test/messages/func_w0302.txt @@ -0,0 +1,2 @@ +W: 0: Too many lines in module (1017) + diff --git a/test/messages/func_w0312.txt b/test/messages/func_w0312.txt new file mode 100644 index 000000000..917e8d0e2 --- /dev/null +++ b/test/messages/func_w0312.txt @@ -0,0 +1,2 @@ +W: 10: Found indentation with tabs instead of spaces +W: 11: Found indentation with tabs instead of spaces diff --git a/test/messages/func_w0331.txt b/test/messages/func_w0331.txt new file mode 100644 index 000000000..8134a320e --- /dev/null +++ b/test/messages/func_w0331.txt @@ -0,0 +1 @@ +W: 6: Use of the <> operator diff --git a/test/messages/func_w0332.txt b/test/messages/func_w0332.txt new file mode 100644 index 000000000..b8984ad05 --- /dev/null +++ b/test/messages/func_w0332.txt @@ -0,0 +1 @@ +W: 4: Use l as long integer identifier diff --git a/test/messages/func_w0401.txt b/test/messages/func_w0401.txt new file mode 100644 index 000000000..9463727f6 --- /dev/null +++ b/test/messages/func_w0401.txt @@ -0,0 +1,2 @@ +R: 0: Cyclic import (input.func_w0401 -> input.w0401_cycle) +W: 6: Redefining built-in 'input' diff --git a/test/messages/func_w0402.txt b/test/messages/func_w0402.txt new file mode 100644 index 000000000..cf06fc44f --- /dev/null +++ b/test/messages/func_w0402.txt @@ -0,0 +1,2 @@ +W: 5: Wildcard import input.func_fixme + diff --git a/test/messages/func_w0403.txt b/test/messages/func_w0403.txt new file mode 100644 index 000000000..ef511f79d --- /dev/null +++ b/test/messages/func_w0403.txt @@ -0,0 +1 @@ +W: 8: Uses of a deprecated module 'Bastion' diff --git a/test/messages/func_w0404.txt b/test/messages/func_w0404.txt new file mode 100644 index 000000000..311056d5b --- /dev/null +++ b/test/messages/func_w0404.txt @@ -0,0 +1 @@ +W: 6: Relative import 'func_w0302' diff --git a/test/messages/func_w0405.txt b/test/messages/func_w0405.txt new file mode 100644 index 000000000..9555dfd1c --- /dev/null +++ b/test/messages/func_w0405.txt @@ -0,0 +1,4 @@ +W: 9: Reimport 'os' (imported line 6) +W: 16: Reimport 'exists' (imported line 7) +W: 21:func: Reimport 'os' (imported line 6) +W: 23:func: Reimport 're' (imported line 10) diff --git a/test/messages/func_w0406.txt b/test/messages/func_w0406.txt new file mode 100644 index 000000000..a1440b92b --- /dev/null +++ b/test/messages/func_w0406.txt @@ -0,0 +1,2 @@ +W: 5: Module import itself +W: 5: Relative import 'func_w0406' diff --git a/test/messages/func_w0611.txt b/test/messages/func_w0611.txt new file mode 100644 index 000000000..10952da05 --- /dev/null +++ b/test/messages/func_w0611.txt @@ -0,0 +1 @@ +W: 4: Unused import os diff --git a/test/messages/func_w0612.txt b/test/messages/func_w0612.txt new file mode 100644 index 000000000..b2d9cbb83 --- /dev/null +++ b/test/messages/func_w0612.txt @@ -0,0 +1 @@ +W: 8:function: Unused variable 'aaaa' diff --git a/test/messages/func_w0613.txt b/test/messages/func_w0613.txt new file mode 100644 index 000000000..b658b540a --- /dev/null +++ b/test/messages/func_w0613.txt @@ -0,0 +1,2 @@ +W: 7:function: Unused argument 'arg' +W: 14:AAAA.method: Unused argument 'arg' diff --git a/test/messages/func_w0622.txt b/test/messages/func_w0622.txt new file mode 100644 index 000000000..719134726 --- /dev/null +++ b/test/messages/func_w0622.txt @@ -0,0 +1,2 @@ +W: 8:function: Redefining built-in 'type' +W: 11: Redefining built-in 'map' diff --git a/test/messages/func_w0701.txt b/test/messages/func_w0701.txt new file mode 100644 index 000000000..677443bec --- /dev/null +++ b/test/messages/func_w0701.txt @@ -0,0 +1,3 @@ +W: 8:function1: Raising a string exception +W: 12:function2: Raising a string exception + diff --git a/test/messages/func_w0702.txt b/test/messages/func_w0702.txt new file mode 100644 index 000000000..ab6d20a6b --- /dev/null +++ b/test/messages/func_w0702.txt @@ -0,0 +1 @@ +W: 10: No exception's type specified diff --git a/test/messages/func_w0703.txt b/test/messages/func_w0703.txt new file mode 100644 index 000000000..e37197af4 --- /dev/null +++ b/test/messages/func_w0703.txt @@ -0,0 +1 @@ +W: 8: Catch "Exception" diff --git a/test/messages/func_w0704.txt b/test/messages/func_w0704.txt new file mode 100644 index 000000000..1eca7949e --- /dev/null +++ b/test/messages/func_w0704.txt @@ -0,0 +1 @@ +W: 8: Except doesn't do anything diff --git a/test/messages/func_w0705.txt b/test/messages/func_w0705.txt new file mode 100644 index 000000000..303e73985 --- /dev/null +++ b/test/messages/func_w0705.txt @@ -0,0 +1,5 @@ +E: 10: Bad except clauses order (Exception is an ancestor class of TypeError) +E: 17: Bad except clauses order (LookupError is an ancestor class of IndexError) +E: 24: Bad except clauses order (LookupError is an ancestor class of IndexError) +E: 24: Bad except clauses order (NameError is an ancestor class of UnboundLocalError) +E: 27: Bad except clauses order (empty except clause should always appears last)
\ No newline at end of file diff --git a/test/messages/func_w0801.txt b/test/messages/func_w0801.txt new file mode 100644 index 000000000..c6ba23121 --- /dev/null +++ b/test/messages/func_w0801.txt @@ -0,0 +1,11 @@ +R: 0: Similar lines in 2 files +==input.func_w0801:3 +==input.w0801_same:3 +__revision__ = 'id' +A = 2 +B = 3 +C = A + B +# need more than X lines to trigger the message +C *= 2 +A -= B +# all this should be detected diff --git a/test/messages/func_wrong_encoding.txt b/test/messages/func_wrong_encoding.txt new file mode 100644 index 000000000..10123a189 --- /dev/null +++ b/test/messages/func_wrong_encoding.txt @@ -0,0 +1 @@ +E: 1: Wrong encoding specified (UTF-8) diff --git a/test/messages/nonexistant.txt b/test/messages/nonexistant.txt new file mode 100644 index 000000000..0ccfb570a --- /dev/null +++ b/test/messages/nonexistant.txt @@ -0,0 +1 @@ +F: 0: No module named nonexistant diff --git a/test/messages/nonexistant.txt2 b/test/messages/nonexistant.txt2 new file mode 100644 index 000000000..ffe19c546 --- /dev/null +++ b/test/messages/nonexistant.txt2 @@ -0,0 +1 @@ +F: 0: No module named input/nonexistant diff --git a/test/regrtest.py b/test/regrtest.py new file mode 100644 index 000000000..927ab48bc --- /dev/null +++ b/test/regrtest.py @@ -0,0 +1,131 @@ +# Copyright (c) 2005 LOGILAB S.A. (Paris, FRANCE). +# http://www.logilab.fr/ -- mailto:contact@logilab.fr +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +"""non regression tests for pylint, which requires a too specific configuration +to be incorporated in the automatic functionnal test framework +""" +__revision__ = '$Id: regrtest.py,v 1.12 2006-03-03 09:25:34 syt Exp $' + +import sys +import os +import unittest +from os.path import abspath, join + +from logilab.common import testlib + +from utils import TestReporter + +from pylint.lint import PyLinter +from pylint import checkers + +test_reporter = TestReporter() +linter = PyLinter() +linter.set_reporter(test_reporter) +linter.disable_message_category('I') +linter.config.persistent = 0 +linter.quiet = 1 +checkers.initialize(linter) + +sys.path.insert(1, abspath('regrtest_data')) + +class NonRegrTC(testlib.TestCase): + def setUp(self): + """call reporter.finalize() to cleanup + pending messages if a test finished badly + """ + linter.reporter.finalize() + + def test_package___path___manipulation(self): + linter.check('package.__init__') + got = linter.reporter.finalize().strip() + self.failUnlessEqual(got, '') + + def test_package___init___precedence(self): + linter.check('precedence_test') + got = linter.reporter.finalize().strip() + self.failUnlessEqual(got, '') + + def test_check_package___init__(self): + for variation in ('package.__init__', 'regrtest_data/package/__init__.py'): + linter.check(variation) + got = linter.reporter.finalize().strip() + checked = linter.stats['by_module'].keys() + self.failUnlessEqual(checked, ['package.__init__'], + '%s: %s' % (variation, checked)) + cwd = os.getcwd() + os.chdir('regrtest_data/package') + sys.path.insert(0, '') + try: + for variation in ('__init__', '__init__.py'): + linter.check(variation) + got = linter.reporter.finalize().strip() + checked = linter.stats['by_module'].keys() + self.failUnlessEqual(checked, ['__init__'], + '%s: %s' % (variation, checked)) + finally: + sys.path.pop(0) + os.chdir(cwd) + + def test_gtk_import(self): + try: + import gtk + except ImportError: + self.skip('test skipped: gtk is not available') + except RuntimeError: # RuntimeError when missing display + pass + linter.check('regrtest_data/pygtk_import.py') + got = linter.reporter.finalize().strip() + self.failUnlessEqual(got, '') + + + def test_numarray_import(self): + try: + import numarray + except ImportError: + self.skip('test skipped: numarray is not available') + linter.check('regrtest_data/numarray_import.py') + got = linter.reporter.finalize().strip() + self.failUnlessEqual(got, '') + + def test_socketerror_import(self): + linter.check('regrtest_data/socketerror_import.py') + got = linter.reporter.finalize().strip() + self.failUnlessEqual(got, '') + + def test_class__doc__usage(self): + linter.check('regrtest_data/classdoc_usage.py') + got = linter.reporter.finalize().strip() + self.failUnlessEqual(got, '') + + def test_package_import_relative_subpackage_no_attribute_error(self): + linter.check('import_package_subpackage_module') + got = linter.reporter.finalize().strip() + self.failUnlessEqual(got, '') + + def test_module_global_crash(self): + linter.check('regrtest_data/module_global.py') + got = linter.reporter.finalize().strip() + self.failUnlessEqual(got, '') + + def test_descriptor_crash(self): + for fname in os.listdir('regrtest_data'): + if fname.endswith('_crash.py'): + linter.check(join('regrtest_data', fname)) + linter.reporter.finalize().strip() + + +if __name__ == '__main__': + from logilab.common.testlib import unittest_main + unittest_main() diff --git a/test/regrtest_data/application_crash.py b/test/regrtest_data/application_crash.py new file mode 100644 index 000000000..6e6044aab --- /dev/null +++ b/test/regrtest_data/application_crash.py @@ -0,0 +1,12 @@ +class ErudiPublisher: + def __init__(self, config): + self.url_resolver = self.select_component('urlpublisher') + + def select_component(self, cid, *args, **kwargs): + try: + return self.select(self.registry_objects('components', cid), *args, **kwargs) + except NoSelectableObject: + return + + def main_publish(self, path, req): + ctrlid = self.url_resolver.process(req, path) diff --git a/test/regrtest_data/classdoc_usage.py b/test/regrtest_data/classdoc_usage.py new file mode 100644 index 000000000..ae8b9fe3f --- /dev/null +++ b/test/regrtest_data/classdoc_usage.py @@ -0,0 +1,17 @@ +"""ds""" + +__revision__ = None + +class SomeClass: + """cds""" + doc = __doc__ + + def __init__(self): + """only to make pylint happier""" + + def please(self): + """public method 1/2""" + + def besilent(self): + """public method 2/2""" + diff --git a/test/regrtest_data/descriptor_crash.py b/test/regrtest_data/descriptor_crash.py new file mode 100644 index 000000000..4b3adccde --- /dev/null +++ b/test/regrtest_data/descriptor_crash.py @@ -0,0 +1,20 @@ +# -*- coding: iso-8859-1 -*- + +import urllib + +class Page(object): + _urlOpen = staticmethod(urllib.urlopen) + + def getPage(self, url): + handle = self._urlOpen(url) + data = handle.read() + handle.close() + return data + #_getPage + +#Page + +if __name__ == "__main__": + import sys + p = Page() + print p.getPage(sys.argv[1]) diff --git a/test/regrtest_data/import_package_subpackage_module.py b/test/regrtest_data/import_package_subpackage_module.py new file mode 100644 index 000000000..b5fb219d1 --- /dev/null +++ b/test/regrtest_data/import_package_subpackage_module.py @@ -0,0 +1,49 @@ +# pylint: disable-msg=I0011,C0301,W0611 +"""I found some of my scripts trigger off an AttributeError in pylint +0.8.1 (with common 0.12.0 and astng 0.13.1). + +Traceback (most recent call last): + File "/usr/bin/pylint", line 4, in ? + lint.Run(sys.argv[1:]) + File "/usr/lib/python2.4/site-packages/pylint/lint.py", line 729, in __init__ + linter.check(args) + File "/usr/lib/python2.4/site-packages/pylint/lint.py", line 412, in check + self.check_file(filepath, modname, checkers) + File "/usr/lib/python2.4/site-packages/pylint/lint.py", line 426, in check_file + astng = self._check_file(filepath, modname, checkers) + File "/usr/lib/python2.4/site-packages/pylint/lint.py", line 450, in _check_file + self.check_astng_module(astng, checkers) + File "/usr/lib/python2.4/site-packages/pylint/lint.py", line 494, in check_astng_module + self.astng_events(astng, [checker for checker in checkers + File "/usr/lib/python2.4/site-packages/pylint/lint.py", line 511, in astng_events + self.astng_events(child, checkers, _reversed_checkers) + File "/usr/lib/python2.4/site-packages/pylint/lint.py", line 511, in astng_events + self.astng_events(child, checkers, _reversed_checkers) + File "/usr/lib/python2.4/site-packages/pylint/lint.py", line 508, in astng_events + checker.visit(astng) + File "/usr/lib/python2.4/site-packages/logilab/astng/utils.py", line 84, in visit + method(node) + File "/usr/lib/python2.4/site-packages/pylint/checkers/variables.py", line 295, in visit_import + self._check_module_attrs(node, module, name_parts[1:]) + File "/usr/lib/python2.4/site-packages/pylint/checkers/variables.py", line 357, in _check_module_attrs + self.add_message('E0611', args=(name, module.name), +AttributeError: Import instance has no attribute 'name' + + +You can reproduce it by: +(1) create package structure like the following: + +package/ + __init__.py + subpackage/ + __init__.py + module.py + +(2) in package/__init__.py write: + +import subpackage + +(3) run pylint with a script importing package.subpackage.module. +""" +__revision__ = '$Id: import_package_subpackage_module.py,v 1.1 2005-11-10 16:08:54 syt Exp $' +import package.subpackage.module diff --git a/test/regrtest_data/module_global.py b/test/regrtest_data/module_global.py new file mode 100644 index 000000000..54fd46d33 --- /dev/null +++ b/test/regrtest_data/module_global.py @@ -0,0 +1,7 @@ +# pylint: disable-msg=W0603,W0601,W0604,E0602,W0104 +"""was causing infinite recursion +""" +__revision__ = 1 + +global bar +bar.foo diff --git a/test/regrtest_data/numarray_import.py b/test/regrtest_data/numarray_import.py new file mode 100644 index 000000000..3f0be8b7b --- /dev/null +++ b/test/regrtest_data/numarray_import.py @@ -0,0 +1,7 @@ +"""#10077""" + +__revision__ = 1 + +from numarray import zeros + +zeros() diff --git a/test/regrtest_data/package/AudioTime.py b/test/regrtest_data/package/AudioTime.py new file mode 100644 index 000000000..a1fde9650 --- /dev/null +++ b/test/regrtest_data/package/AudioTime.py @@ -0,0 +1,3 @@ +"""test preceeded by the AudioTime class in __init__.py""" + +__revision__ = 0 diff --git a/test/regrtest_data/package/__init__.py b/test/regrtest_data/package/__init__.py new file mode 100644 index 000000000..9e1ebfa68 --- /dev/null +++ b/test/regrtest_data/package/__init__.py @@ -0,0 +1,14 @@ +# pylint: disable-msg=R0903,W0403 +"""package's __init__ file""" + +__revision__ = 0 + +# E0602 - Undefined variable '__path__' +__path__ += "folder" + +class AudioTime(object): + """test precedence over the AudioTime submodule""" + + DECIMAL = 3 + +import subpackage diff --git a/test/regrtest_data/package/subpackage/__init__.py b/test/regrtest_data/package/subpackage/__init__.py new file mode 100644 index 000000000..dc4782e6c --- /dev/null +++ b/test/regrtest_data/package/subpackage/__init__.py @@ -0,0 +1 @@ +"""package.subpackage""" diff --git a/test/regrtest_data/package/subpackage/module.py b/test/regrtest_data/package/subpackage/module.py new file mode 100644 index 000000000..4b7244ba0 --- /dev/null +++ b/test/regrtest_data/package/subpackage/module.py @@ -0,0 +1 @@ +"""package.subpackage.module""" diff --git a/test/regrtest_data/precedence_test.py b/test/regrtest_data/precedence_test.py new file mode 100644 index 000000000..087b5cf4d --- /dev/null +++ b/test/regrtest_data/precedence_test.py @@ -0,0 +1,21 @@ +""" + # package/__init__.py + class AudioTime(object): + DECIMAL = 3 + + # package/AudioTime.py + class AudioTime(object): + pass + + # test.py + from package import AudioTime + # E0611 - No name 'DECIMAL' in module 'AudioTime.AudioTime' + print AudioTime.DECIMAL + +""" + +__revision__ = 0 + +from package import AudioTime + +print AudioTime.DECIMAL diff --git a/test/regrtest_data/pygtk_import.py b/test/regrtest_data/pygtk_import.py new file mode 100644 index 000000000..4ac95606f --- /dev/null +++ b/test/regrtest_data/pygtk_import.py @@ -0,0 +1,14 @@ +#pylint: disable-msg=R0903,R0904 +"""#10026""" +__revision__ = 1 +from gtk import VBox +import gtk + +class FooButton(gtk.Button): + """extend gtk.Button""" + def extend(self): + """hop""" + print self + +print gtk.Button +print VBox diff --git a/test/regrtest_data/socketerror_import.py b/test/regrtest_data/socketerror_import.py new file mode 100644 index 000000000..37310cfa6 --- /dev/null +++ b/test/regrtest_data/socketerror_import.py @@ -0,0 +1,6 @@ +"""ds""" + +__revision__ = '$Id: socketerror_import.py,v 1.2 2005-12-28 14:58:22 syt Exp $' + +from socket import error +print error diff --git a/test/runtests.py b/test/runtests.py new file mode 100644 index 000000000..67d66367b --- /dev/null +++ b/test/runtests.py @@ -0,0 +1,5 @@ +from logilab.common.testlib import main + +if __name__ == '__main__': + import sys, os + main(os.path.dirname(sys.argv[0]) or '.') diff --git a/test/smoketest.py b/test/smoketest.py new file mode 100644 index 000000000..1954466c1 --- /dev/null +++ b/test/smoketest.py @@ -0,0 +1,74 @@ +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. + +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +""" Copyright (c) 2000-2003 LOGILAB S.A. (Paris, FRANCE). + http://www.logilab.fr/ -- mailto:contact@logilab.fr +""" + +__revision__ = "$Id: smoketest.py,v 1.6 2005-04-15 10:40:24 syt Exp $" + +import unittest +import sys +from cStringIO import StringIO + +from pylint.lint import Run +from pylint.reporters.text import TextReporter, TextReporter2, ColorizedTextReporter +from pylint.reporters.html import HTMLReporter + + +class LintSmokeTest(unittest.TestCase): + + def test1(self): + """make pylint checking itself""" + Run(['--include-ids=y', 'pylint'], reporter=TextReporter(StringIO()), quiet=1) + + def test2(self): + """make pylint checking itself""" + Run(['pylint.lint'], reporter=TextReporter2(StringIO()), quiet=1) + + def test3(self): + """make pylint checking itself""" + Run(['pylint.checkers'], reporter=HTMLReporter(StringIO()), quiet=1) + + def test4(self): + """make pylint checking itself""" + Run(['pylint.checkers'], reporter=ColorizedTextReporter(StringIO()), quiet=1) + + def test_generate_config_option(self): + """make pylint checking itself""" + sys.stdout = StringIO() + try: + self.assertRaises(SystemExit, Run, + ['--generate-rcfile'], + reporter=HTMLReporter(StringIO()), + quiet=1) + finally: + sys.stdout = sys.__stdout__ + + def test_help_message_option(self): + """make pylint checking itself""" + sys.stdout = StringIO() + try: + self.assertRaises(SystemExit, Run, + ['--help-msg', 'W0101'], + reporter=HTMLReporter(StringIO()), + quiet=1) + self.assertRaises(SystemExit, Run, + ['--help-msg', 'WX101'], + reporter=HTMLReporter(StringIO()), + quiet=1) + finally: + sys.stdout = sys.__stdout__ + + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_encoding.py b/test/test_encoding.py new file mode 100644 index 000000000..ca5b53fcf --- /dev/null +++ b/test/test_encoding.py @@ -0,0 +1,62 @@ +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +""" Copyright (c) 2003-2005 LOGILAB S.A. (Paris, FRANCE). + http://www.logilab.fr/ -- mailto:contact@logilab.fr + +Check source code is ascii only or has an encoding declaration (PEP 263) +""" + +__revision__ = '$Id: test_encoding.py,v 1.6 2005-11-02 09:22:04 syt Exp $' + +import unittest +import sys +from pylint.checkers.misc import guess_encoding + +class TestGuessEncoding(unittest.TestCase): + + def testEmacs(self): + e = guess_encoding('# -*- coding: UTF-8 -*-') + self.failUnlessEqual(e, 'UTF-8') + e = guess_encoding('# -*- coding:UTF-8 -*-') + self.failUnlessEqual(e, 'UTF-8') + e = guess_encoding(''' + ### -*- coding: ISO-8859-1 -*- + ''') + self.failUnlessEqual(e, 'ISO-8859-1') + e = guess_encoding(''' + + ### -*- coding: ISO-8859-1 -*- + ''') + self.failUnlessEqual(e, None) + + def testVim(self): + e = guess_encoding('# vim:fileencoding=UTF-8') + self.failUnlessEqual(e, 'UTF-8') + e = guess_encoding(''' + ### vim:fileencoding=ISO-8859-1 + ''') + self.failUnlessEqual(e, 'ISO-8859-1') + e = guess_encoding(''' + + ### vim:fileencoding= ISO-8859-1 + ''') + self.failUnlessEqual(e, None) + + def testUTF8(self): + e = guess_encoding('\xef\xbb\xbf any UTF-8 data') + self.failUnlessEqual(e, 'UTF-8') + e = guess_encoding(' any UTF-8 data \xef\xbb\xbf') + self.failUnlessEqual(e, None) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_format.py b/test/test_format.py new file mode 100644 index 000000000..94a499fa8 --- /dev/null +++ b/test/test_format.py @@ -0,0 +1,168 @@ +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +""" Copyright (c) 2000-2003 LOGILAB S.A. (Paris, FRANCE). + http://www.logilab.fr/ -- mailto:contact@logilab.fr + +Check format checker helper functions +""" + +__revision__ = '$Id: test_format.py,v 1.13 2005-11-02 09:22:06 syt Exp $' + +import unittest +import sys +import re +from os import linesep + +from pylint.checkers.format import * +from utils import TestReporter + +REPORTER = TestReporter() + +class StringRgxTest(unittest.TestCase): + """test the STRING_RGX regular expression""" + + def test_known_values_1(self): + self.assertEqual(STRING_RGX.sub('', '"yo"'), '') + + def test_known_values_2(self): + self.assertEqual(STRING_RGX.sub('', "'yo'"), '') + + def test_known_values_tq_1(self): + self.assertEqual(STRING_RGX.sub('', '"""yo"""'), '') + + def test_known_values_tq_2(self): + self.assertEqual(STRING_RGX.sub('', '"""yo\n'), '') + + def test_known_values_ta_1(self): + self.assertEqual(STRING_RGX.sub('', "'''yo'''"), '') + + def test_known_values_ta_2(self): + self.assertEqual(STRING_RGX.sub('', "'''yo\n"), '') + + def test_known_values_5(self): + self.assertEqual(STRING_RGX.sub('', r'"yo\"yo"'), '') + + def test_known_values_6(self): + self.assertEqual(STRING_RGX.sub('', r"'yo\'yo'"), '') + + def test_known_values_7(self): + self.assertEqual(STRING_RGX.sub('', '"yo"upi"yo"upi'), 'upiupi') + + def test_known_values_8(self): + self.assertEqual(STRING_RGX.sub('', "'yo\\'yo\\"), '') + + def test_known_values_9(self): + self.assertEqual(STRING_RGX.sub('', '"yoyo\\'), '') + + def test_known_values_10(self): + self.assertEqual(STRING_RGX.sub('', 'self.filterFunc = eval(\'lambda %s: %s\'%(\',\'.join(variables),formula),{},{})'), + 'self.filterFunc = eval(%(.join(variables),formula),{},{})') + + def test_known_values_11(self): + self.assertEqual(STRING_RGX.sub('', 'cond_list[index] = OLD_PROG.sub(r\'getattr(__old__,"\1")\',cond)'), + 'cond_list[index] = OLD_PROG.sub(r,cond)') + + +## def test_no_crash(self): +## crash_str = """wizardBmp = ('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\n', (115, 260), None)""" +## re.sub(SQSTRING_RGX, '', crash_str) +## re.sub(TQSTRING_RGX, '', crash_str) +## re.sub(SASTRING_RGX, '', crash_str) +## re.sub(TASTRING_RGX, '', crash_str) + + +if linesep != '\n': + LINE_RGX = re.compile(linesep) + def ulines(strings): + return strings[0], LINE_RGX.sub('\n', strings[1]) +else: + def ulines(strings): + return strings + +class ChecklineFunctionTest(unittest.TestCase): + """test the check_line method""" + + def test_known_values_opspace_1(self): + self.assertEqual(ulines(check_line('a=1', REPORTER)), ('C0322', 'a=1\n ^')) + + def test_known_values_opspace_2(self): + self.assertEqual(ulines(check_line('a= 1', REPORTER)), ('C0322', 'a= 1\n ^') ) + + def test_known_values_opspace_3(self): + self.assertEqual(ulines(check_line('a =1', REPORTER)), ('C0323', 'a =1\n ^')) + + def test_known_values_opspace_4(self): + self.assertEqual(check_line('f(a=1)', REPORTER), None) + + def test_known_values_opspace_4(self): + self.assertEqual(check_line('f(a=1)', REPORTER), None) + + +## def test_known_values_colonnl_1(self): +## self.assertEqual(check_line('if a: a = 1', REPORTER), +## ('W0321', 'if a: a = 1\n ^^^^^^^')) + +## def test_known_values_colonnl_2(self): +## self.assertEqual(check_line('a[:1]', REPORTER), None) + +## def test_known_values_colonnl_3(self): +## self.assertEqual(check_line('a[1:]', REPORTER), None) + +## def test_known_values_colonnl_4(self): +## self.assertEqual(check_line('a[1:2]', REPORTER), None) + +## def test_known_values_colonnl_5(self): +## self.assertEqual(check_line('def intersection(list1, list2):', REPORTER), None) + +## def test_known_values_colonnl_6(self): +## self.assertEqual(check_line('def intersection(list1, list2):\n', REPORTER), None) + +## def test_known_values_colonnl_7(self): +## self.assertEqual(check_line('if file[:pfx_len] == path:\n', REPORTER), None) + +## def test_known_values_colonnl_8(self): +## self.assertEqual(check_line('def intersection(list1, list2): pass\n', REPORTER), +## ('W0321', +## 'def intersection(list1, list2): pass\n ^^^^^^') ) + +## def test_known_values_colonnl_9(self): +## self.assertEqual(check_line('if file[:pfx_len[1]] == path:\n', REPORTER), None) + +## def test_known_values_colonnl_10(self): +## self.assertEqual(check_line('if file[pfx_len[1]] == path:\n', REPORTER), None) + + + def test_known_values_commaspace_1(self): + self.assertEqual(ulines(check_line('a, b = 1,2', REPORTER)), + ('C0324', 'a, b = 1,2\n ^^')) + + + def test_known_values_instring_1(self): + self.assertEqual(check_line('f("a=1")', REPORTER), None) + + def test_known_values_instring_2(self): + self.assertEqual(ulines(check_line('print >>1, ("a:1")', REPORTER)), + ('C0323', 'print >>1, ("a:1")\n ^')) + + def test_known_values_all_1(self): + self.assertEqual(ulines(check_line("self.filterFunc = eval('lambda %s: %s'%(','.join(variables),formula),{},{})", REPORTER)), + ('C0324', "self.filterFunc = eval('lambda %s: %s'%(','.join(variables),formula),{},{})\n ^^")) + + def test_known_values_tqstring(self): + self.assertEqual(check_line('print """<a="=")', REPORTER), None) + + def test_known_values_tastring(self): + self.assertEqual(check_line("print '''<a='=')", REPORTER), None) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_import_graph.py b/test/test_import_graph.py new file mode 100644 index 000000000..dd6446ead --- /dev/null +++ b/test/test_import_graph.py @@ -0,0 +1,63 @@ +import sys +import os +import unittest +from os.path import exists +from cStringIO import StringIO + +from pylint.checkers import initialize, imports +from pylint.lint import PyLinter + +from utils import TestReporter + +class DependenciesGraphTC(unittest.TestCase): + """test the imports graph function""" + + dest = 'dependencies_graph.dot' + def tearDown(self): + os.remove(self.dest) + + def test_dependencies_graph(self): + imports.dependencies_graph(self.dest, {'labas': ['hoho', 'yep'], + 'hoho': ['yep']}) + self.assertEquals(open(self.dest).read().strip(), + ''' +digraph g { +rankdir="LR" URL="." concentrate=false +edge[fontsize="10" ] +node[width="0" height="0" fontsize="12" fontcolor="black"] +"hoho" [ label="hoho" ]; +"yep" [ label="yep" ]; +"labas" [ label="labas" ]; +"yep" -> "hoho" [ ] ; +"hoho" -> "labas" [ ] ; +"yep" -> "labas" [ ] ; +} +'''.strip()) + +class ImportCheckerTC(unittest.TestCase): + def setUp(self): + self.linter = l = PyLinter(reporter=TestReporter()) + initialize(l) + l.disable_all_checkers() + + def test_checker_dep_graphs(self): + l = self.linter + l.global_set_option('persistent', False) + l.global_set_option('enable-imports', True) + l.global_set_option('import-graph', 'import.dot') + l.global_set_option('ext-import-graph', 'ext_import.dot') + l.global_set_option('int-import-graph', 'int_import.dot') + try: + l.check('input') + self.assert_(exists('import.dot')) + self.assert_(exists('ext_import.dot')) + self.assert_(exists('int_import.dot')) + finally: + for fname in ('import.dot', 'ext_import.dot', 'int_import.dot'): + try: + os.remove(fname) + except: + pass + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_similar.py b/test/test_similar.py new file mode 100644 index 000000000..457fafaed --- /dev/null +++ b/test/test_similar.py @@ -0,0 +1,56 @@ +import sys +import unittest +from cStringIO import StringIO + +from pylint.checkers import similar + + +class SimilarTC(unittest.TestCase): + """test the similar command line utility""" + def test(self): + sys.stdout = StringIO() + try: + similar.run(['--ignore-comments', 'input/similar1', 'input/similar2']) + output = sys.stdout.getvalue() + finally: + sys.stdout = sys.__stdout__ + self.assertEquals(output.strip(), """ +7 similar lines in 2 files +==input/similar1:5 +==input/similar2:5 + same file as this one. + more than 4 + identical lines should + be + detected + + +TOTAL lines=38 duplicates=7 percent=0.184210526316 +""".strip()) + + def test_help(self): + sys.stdout = StringIO() + try: + try: + similar.run(['--help']) + except SystemExit, ex: + self.assertEquals(ex.code, 0) + else: + self.fail() + finally: + sys.stdout = sys.__stdout__ + + def test_no_args(self): + sys.stdout = StringIO() + try: + try: + similar.run([]) + except SystemExit, ex: + self.assertEquals(ex.code, 1) + else: + self.fail() + finally: + sys.stdout = sys.__stdout__ + +if __name__ == '__main__': + unittest.main() diff --git a/test/unittest_checkers_utils.py b/test/unittest_checkers_utils.py new file mode 100644 index 000000000..380b4cd7f --- /dev/null +++ b/test/unittest_checkers_utils.py @@ -0,0 +1,49 @@ +# Copyright (c) 2003-2005 LOGILAB S.A. (Paris, FRANCE). +# http://www.logilab.fr/ -- mailto:contact@logilab.fr +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +"""test the pylint.checkers.utils module +""" + +__revision__ = '$Id: unittest_checkers_utils.py,v 1.6 2005-11-02 09:22:07 syt Exp $' + +import unittest +import sys + +from pylint.checkers import utils +try: + __builtins__.mybuiltin = 2 +except AttributeError: + __builtins__['mybuiltin'] = 2 + +class UtilsTC(unittest.TestCase): + +## def test_is_native_builtin(self): +## self.assertEquals(utils.is_native_builtin('min'), True) +## self.assertEquals(utils.is_native_builtin('__path__'), True) +## self.assertEquals(utils.is_native_builtin('__file__'), True) +## self.assertEquals(utils.is_native_builtin('whatever'), False) +## self.assertEquals(utils.is_native_builtin('mybuiltin'), False) + + def test_is_builtin(self): + self.assertEquals(utils.is_builtin('min'), True) + self.assertEquals(utils.is_builtin('__builtins__'), True) + self.assertEquals(utils.is_builtin('__path__'), False) + self.assertEquals(utils.is_builtin('__file__'), False) + self.assertEquals(utils.is_builtin('whatever'), False) + self.assertEquals(utils.is_builtin('mybuiltin'), False) + +if __name__ == '__main__': + unittest.main() + diff --git a/test/unittest_lint.py b/test/unittest_lint.py new file mode 100644 index 000000000..a71edee3c --- /dev/null +++ b/test/unittest_lint.py @@ -0,0 +1,268 @@ +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +""" Copyright (c) 2003-2005 LOGILAB S.A. (Paris, FRANCE). + http://www.logilab.fr/ -- mailto:contact@logilab.fr +""" + +__revision__ = '$Id: unittest_lint.py,v 1.16 2006-04-19 09:17:40 syt Exp $' + +import unittest +import sys +import os +import tempfile +from os.path import join +from cStringIO import StringIO + +from pylint.config import get_note_message +from pylint.lint import PyLinter, Run, sort_checkers, UnknownMessage +from pylint.utils import sort_msgs +from pylint import checkers + +class SortMessagesTC(unittest.TestCase): + + def test(self): + l = ['E0501', 'E0503', 'F0002', 'I0201', 'W0540', + 'R0202', 'F0203', 'R0220', 'W0321', 'I0001'] + self.assertEquals(sort_msgs(l), ['I0001', 'I0201', + 'R0202', 'R0220', + 'W0321', 'W0540', + 'E0501', 'E0503', + 'F0002', 'F0203']) + +try: + optimized = True + raise AssertionError +except AssertionError: + optimized = False + +class GetNoteMessageTC(unittest.TestCase): + def test(self): + msg = None + for note in range(-1, 11): + note_msg = get_note_message(note) + self.assertNotEquals(msg, note_msg) + msg = note_msg + if optimized: + self.assertRaises(AssertionError, get_note_message, 11) + +class RunTC(unittest.TestCase): + + def _test_run(self, args, exit_code=1, no_exit_fail=True): + sys.stdout = StringIO() + sys.sterr = StringIO() + try: + try: + Run(args, quiet=1) + except SystemExit, ex: + self.assertEquals(ex.code, exit_code) + else: + if no_exit_fail: + self.fail() + finally: + sys.stdout = sys.__stdout__ + sys.stderr = sys.__stderr__ + + def test_no_args(self): + self._test_run([], 1) + + def test_no_ext_file(self): + self._test_run([join('input', 'noext')], no_exit_fail=False) + + +class PyLinterTC(unittest.TestCase): + + def setUp(self): + self.linter = PyLinter() + self.linter.disable_message_category('I') + self.linter.config.persistent = 0 + # register checkers + checkers.initialize(self.linter) + + def test_disable_all(self): + self.linter.disable_all_checkers() + checkers = sort_checkers(self.linter._checkers, enabled_only=0) + self.assert_(len(checkers) > 1) + checkers = sort_checkers(self.linter._checkers, enabled_only=1) + self.assertEquals(checkers, [self.linter]) + + def test_message_help(self): + msg = self.linter.get_message_help('F0001') + expected = 'F0001:\n Used when an error occured preventing the analyzing of a module (unable to\n find it for instance). This message belongs to the master checker.' + self.assertEquals(' '.join(msg.splitlines()), ' '.join(expected.splitlines())) + self.assertRaises(UnknownMessage, self.linter.get_message_help, 'YB12') + + def test_enable_message(self): + linter = self.linter + linter.open() + linter.set_current_module('toto') + self.assert_(linter.is_message_enabled('W0101')) + self.assert_(linter.is_message_enabled('W0102')) + linter.disable_message('W0101', scope='package') + linter.disable_message('W0102', scope='module', line=1) + self.assert_(not linter.is_message_enabled('W0101')) + self.assert_(not linter.is_message_enabled('W0102', 1)) + linter.set_current_module('tutu') + self.assert_(not linter.is_message_enabled('W0101')) + self.assert_(linter.is_message_enabled('W0102')) + linter.enable_message('W0101', scope='package') + linter.enable_message('W0102', scope='module', line=1) + self.assert_(linter.is_message_enabled('W0101')) + self.assert_(linter.is_message_enabled('W0102', 1)) + + def test_enable_message_category(self): + linter = self.linter + linter.open() + linter.set_current_module('toto') + self.assert_(linter.is_message_enabled('W0101')) + self.assert_(linter.is_message_enabled('R0102')) + linter.disable_message_category('W', scope='package') + linter.disable_message_category('REFACTOR', scope='module') + self.assert_(not linter.is_message_enabled('W0101')) + self.assert_(not linter.is_message_enabled('R0102')) + linter.set_current_module('tutu') + self.assert_(not linter.is_message_enabled('W0101')) + self.assert_(linter.is_message_enabled('R0102')) + linter.enable_message_category('WARNING', scope='package') + linter.enable_message_category('R', scope='module') + self.assert_(linter.is_message_enabled('W0101')) + self.assert_(linter.is_message_enabled('R0102')) + + def test_enable_message_block(self): + linter = self.linter + linter.open() + filepath = join('input', 'func_block_disable_msg.py') + linter.set_current_module('func_block_disable_msg') + linter.process_module(open(filepath)) + orig_state = linter._module_msgs_state.copy() + linter._module_msgs_state = {} + linter.collect_block_lines(linter.get_astng(filepath, 'func_block_disable_msg'), orig_state) + # global (module level) + self.assert_(linter.is_message_enabled('W0613')) + self.assert_(linter.is_message_enabled('E1101')) + # meth1 + self.assert_(linter.is_message_enabled('W0613', 13)) + # meth2 + self.assert_(not linter.is_message_enabled('W0613', 18)) + # meth3 + self.assert_(not linter.is_message_enabled('E1101', 24)) + self.assert_(linter.is_message_enabled('E1101', 26)) + # meth4 + self.assert_(not linter.is_message_enabled('E1101', 32)) + self.assert_(linter.is_message_enabled('E1101', 36)) + # meth5 + self.assert_(not linter.is_message_enabled('E1101', 42)) + self.assert_(not linter.is_message_enabled('E1101', 43)) + self.assert_(linter.is_message_enabled('E1101', 46)) + self.assert_(not linter.is_message_enabled('E1101', 49)) + self.assert_(not linter.is_message_enabled('E1101', 51)) + # meth6 + self.assert_(not linter.is_message_enabled('E1101', 57)) + self.assert_(linter.is_message_enabled('E1101', 61)) + self.assert_(not linter.is_message_enabled('E1101', 64)) + self.assert_(not linter.is_message_enabled('E1101', 66)) + + self.assert_(linter.is_message_enabled('E0602', 57)) + self.assert_(linter.is_message_enabled('E0602', 61)) + self.assert_(not linter.is_message_enabled('E0602', 62)) + self.assert_(linter.is_message_enabled('E0602', 64)) + self.assert_(linter.is_message_enabled('E0602', 66)) + # meth7 + self.assert_(not linter.is_message_enabled('E1101', 70)) + self.assert_(linter.is_message_enabled('E1101', 72)) + self.assert_(linter.is_message_enabled('E1101', 75)) + self.assert_(linter.is_message_enabled('E1101', 77)) + + def test_list_messages(self): + sys.stdout = StringIO() + try: + # just invoke it, don't check the output + self.linter.list_messages() + finally: + sys.stdout = sys.__stdout__ + + def test_lint_ext_module_with_file_output(self): + self.linter.config.files_output = True + try: + self.linter.check('StringIO') + self.assert_(os.path.exists('pylint_StringIO.txt')) + self.assert_(os.path.exists('pylint_global.txt')) + finally: + try: + os.remove('pylint_StringIO.txt') + os.remove('pylint_global.txt') + except: + pass + + def test_enable_report(self): + self.assertEquals(self.linter.is_report_enabled('R0001'), True) + self.linter.disable_report('R0001') + self.assertEquals(self.linter.is_report_enabled('R0001'), False) + self.linter.enable_report('R0001') + self.assertEquals(self.linter.is_report_enabled('R0001'), True) + + def test_set_option_1(self): + linter = self.linter + linter.set_option('disable-msg', 'C0111,W0142') + self.assert_(not linter.is_message_enabled('C0111')) + self.assert_(not linter.is_message_enabled('W0142')) + self.assert_(linter.is_message_enabled('W0113')) + + def test_set_option_2(self): + linter = self.linter + linter.set_option('disable-msg', ('C0111', 'W0142') ) + self.assert_(not linter.is_message_enabled('C0111')) + self.assert_(not linter.is_message_enabled('W0142')) + self.assert_(linter.is_message_enabled('W0113')) + + +from pylint import config + +class ConfigTC(unittest.TestCase): + + def test_pylint_home(self): + uhome = os.path.expanduser('~') + if uhome == '~': + expected = '.pylint.d' + else: + expected = os.path.join(uhome, '.pylint.d') + self.assertEquals(config.PYLINT_HOME, expected) + + try: + pylintd = join(tempfile.gettempdir(), '.pylint.d') + os.environ['PYLINTHOME'] = pylintd + try: + reload(config) + self.assertEquals(config.PYLINT_HOME, pylintd) + finally: + try: + os.remove(pylintd) + except: + pass + finally: + del os.environ['PYLINTHOME'] + + def test_pylintrc(self): + try: + self.assertEquals(config.PYLINTRC, None) + os.environ['PYLINTRC'] = join(tempfile.gettempdir(), '.pylintrc') + reload(config) + self.assertEquals(config.PYLINTRC, None) + os.environ['PYLINTRC'] = '.' + reload(config) + self.assertEquals(config.PYLINTRC, None) + finally: + del os.environ['PYLINTRC'] + reload(config) + +if __name__ == '__main__': + unittest.main() diff --git a/test/utils.py b/test/utils.py new file mode 100644 index 000000000..06eb76e06 --- /dev/null +++ b/test/utils.py @@ -0,0 +1,66 @@ +"""some pylint test utilities +""" +from glob import glob +from os.path import join, abspath, dirname, basename +from cStringIO import StringIO + +from pylint.interfaces import IReporter +from pylint.reporters import BaseReporter + +PREFIX = abspath(dirname(__file__)) + +def fix_path(): + import sys + sys.path.insert(0, PREFIX) + +def get_tests_info(prefix=None, suffix=None): + pattern = '*' + if prefix: + pattern = prefix + pattern + if suffix: + pattern = pattern + suffix + result = [] + for file in glob(join(PREFIX, "input", pattern)): + infile = basename(file) + outfile = join(PREFIX, "messages", infile.replace(suffix, '.txt')) + result.append((infile, outfile)) + + return result + + +TITLE_UNDERLINES = ['', '=', '-', '.'] + +class TestReporter(BaseReporter): + """ store plain text messages + """ + + __implements____ = IReporter + + def __init__(self): + self.message_ids = {} + self.reset() + + def reset(self): + self.out = StringIO() + self.messages = [] + + def add_message(self, msg_id, location, msg): + """manage message of different type and in the context of path """ + fpath, module, object, line = location + self.message_ids[msg_id] = 1 + if object: + object = ':%s' % object + sigle = msg_id[0] + self.messages.append('%s:%3s%s: %s' % (sigle, line, object, msg)) + + def finalize(self): + self.messages.sort() + for msg in self.messages: + print >>self.out, msg + result = self.out.getvalue() + self.reset() + return result + + def display_results(self, layout): + """ignore layouts""" + |