diff options
author | cpopa <devnull@localhost> | 2013-07-25 09:52:27 +0300 |
---|---|---|
committer | cpopa <devnull@localhost> | 2013-07-25 09:52:27 +0300 |
commit | 3d1c7835e6737fab5d1c2826804412fa12863aa0 (patch) | |
tree | edf300ac7c01cd114b53df1ea392d14eae54d890 | |
parent | 1c8db4963638b5382cee2fc6c8c949d2f2b06974 (diff) | |
parent | a5e8fd05669d8e74e7242ea52f20faaa8c800291 (diff) | |
download | pylint-3d1c7835e6737fab5d1c2826804412fa12863aa0.tar.gz |
Merge with default.
-rw-r--r-- | ChangeLog | 42 | ||||
-rw-r--r-- | checkers/newstyle.py | 18 | ||||
-rw-r--r-- | checkers/typecheck.py | 26 | ||||
-rw-r--r-- | lint.py | 2 | ||||
-rw-r--r-- | test/input/func_kwoa_py30.py | 12 | ||||
-rw-r--r-- | test/input/func_missing_super_argument_py20.py | 9 | ||||
-rw-r--r-- | test/input/func_newstyle_super.py | 9 | ||||
-rw-r--r-- | test/messages/func_kwoa_py30.txt | 5 | ||||
-rw-r--r-- | test/messages/func_missing_super_argument_py20.txt | 2 | ||||
-rw-r--r-- | test/messages/func_newstyle_super.txt | 4 | ||||
-rw-r--r-- | test/messages/func_newstyle_super_py30.txt | 5 |
11 files changed, 121 insertions, 13 deletions
@@ -2,58 +2,82 @@ ChangeLog for Pylint ==================== -- + * bitbucket #16: fix False positive E1003 on Python 3 for argument-less super() * Added a new warning missing-final-newline (C0304) for files missing the final newline. + * Methods that are decorated as properties are now treated as attributes for the purposes of name checking. + * Names of derived instance class member are not checked any more. + * Names in global statements are now checked against the regular expression for constants. + * For toplevel name assignment, the class name regex will be used if pylint can detect that value on the right-hand side is a class (like collections.namedtuple()). + + * Simplified invalid-name message + * Added a new warning invalid-encoded-data (W0512) for files that contain data that cannot be decoded with the specified or default encoding. + * New warning bad-open-mode (W1501) for calls to open (or file) that specify invalid open modes (Original implementation by Sasha Issayev). + * New warning old-style-class (C1001) for classes that do not have any base class. + * Add new name type 'class_attribute' for attributes defined in class scope. By default, allow both const and variable names. + * New warning trailing-whitespace (C0303) that warns about trailing whitespace. - * Trailing whitespace does not count towards the line length - limit anymore, since there is a dedicated warning for it. + * Added a new warning unpacking-in-except (W0712) about unpacking exceptions in handlers, which is unsupported in Python 3. + * Add a configuration option for missing-docstring to optionally exempt short functions/methods/classes from the check. + * Add the type of the offending node to missing-docstring and empty-docstring. + * New utility classes for per-checker unittests in testutils.py + * Do not warn about redefinitions of variables that match the dummy regex. + * Do not treat all variables starting with _ as dummy variables, only _ itself. - * Make the line-too-long warning configurable by - adding a regex for lines for with the length limit should - not be enforced + + * Make the line-too-long warning configurable by adding a regex for lines + for with the length limit should not be enforced + * Do not warn about a long line if a pylint disable option brings it above the length limit + * Do not flag names in nested with statements as undefined. + * Added a new warning 'old-raise-syntax' for the deprecated syntax raise Exception, args - * astng has been renamed astroid - * bitbucket #6: put back documentation in source distribution - * fix spelling of max-branchs option, now max-branches + + * Support for PEP 3102 and new missing-kwoa (E1125) message for missing + mandatory keyword argument (logilab.org's #107788) + + * Fix spelling of max-branchs option, now max-branches * Added a new base class and interface for checkers that work on the tokens rather than the syntax, and only tokenize the input file once. - * simplified invalid-name message + + * Follow astng renaming toastroid + + * bitbucket #6: put back documentation in source distribution * bitbucket #15: epylint shouldn't hang anymore when there is a large output on pylint'stderr diff --git a/checkers/newstyle.py b/checkers/newstyle.py index bc8aeca..9524080 100644 --- a/checkers/newstyle.py +++ b/checkers/newstyle.py @@ -15,6 +15,7 @@ # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. """check for new / old style related problems """ +import sys import astroid @@ -33,6 +34,10 @@ MSGS = { 'bad-super-call', 'Used when another argument than the current class is given as \ first argument of the super builtin.'), + 'E1004': ('Missing argument to super()', + 'missing-super-argument', + 'Used when the super builtin didn\'t receive an \ + argument on Python 2'), 'W1001': ('Use of "property" on an old style class', 'property-on-old-class', 'Used when PyLint detect the use of the builtin "property" \ @@ -85,7 +90,7 @@ class NewStyleConflictChecker(BaseChecker): if name == 'property': self.add_message('W1001', node=node) - @check_messages('E1002', 'E1003') + @check_messages('E1002', 'E1003', 'E1004') def visit_function(self, node): """check use of super""" # ignore actual functions or method within a new style class @@ -106,14 +111,23 @@ class NewStyleConflictChecker(BaseChecker): self.add_message('E1002', node=node) else: # super first arg should be the class + if not call.args and sys.version_info[0] == 3: + # unless Python 3 + continue + try: supcls = (call.args and call.args[0].infer().next() or None) except astroid.InferenceError: continue + + if supcls is None and sys.version_info[0] == 2: + self.add_message('missing-super-argument', node=call) + continue + if klass is not supcls: supcls = getattr(supcls, 'name', supcls) - self.add_message('E1003', node=node, args=supcls) + self.add_message('E1003', node=call, args=(supcls, )) def register(linter): diff --git a/checkers/typecheck.py b/checkers/typecheck.py index 2c78459..6988359 100644 --- a/checkers/typecheck.py +++ b/checkers/typecheck.py @@ -69,6 +69,11 @@ MSGS = { 'Used when a function call would result in assigning multiple \ values to a function parameter, one value from a positional \ argument and one from a keyword argument.'), + 'E1125': ('Missing mandatory keyword argument %r', + 'missing-kwoa', + 'Used when a function call doesn\'t pass a mandatory \ + keyword-only argument.', + {'minversion': (3, 0)}), } class TypeChecker(BaseChecker): @@ -316,6 +321,15 @@ accessed. Python regular expressions are accepted.'} defval = None parameters.append([(name, defval), False]) + kwparams = {} + for i, arg in enumerate(called.args.kwonlyargs): + if isinstance(arg, astroid.Keyword): + name = arg.arg + else: + assert isinstance(arg, astroid.AssName) + name = arg.name + kwparams[name] = [called.args.kw_defaults[i], False] + # Match the supplied arguments against the function parameters. # 1. Match the positional arguments. @@ -340,6 +354,12 @@ accessed. Python regular expressions are accepted.'} self.add_message('E1124', node=node, args=keyword) else: parameters[i][1] = True + elif keyword in kwparams: + if kwparams[keyword][1]: # XXX is that even possible? + # Duplicate definition of function parameter. + self.add_message('E1124', node=node, args=keyword) + else: + kwparams[keyword][1] = True elif called.args.kwarg is not None: # The keyword argument gets assigned to the **kwargs parameter. pass @@ -384,6 +404,12 @@ accessed. Python regular expressions are accepted.'} display_name = repr(name) self.add_message('E1120', node=node, args=display_name) + for name in kwparams: + defval, assigned = kwparams[name] + if defval is None and not assigned: + self.add_message('E1125', node=node, args=name) + + def register(linter): """required method to auto register this checker """ linter.register_checker(TypeChecker(linter)) @@ -646,7 +646,7 @@ This is used by the global evaluation report (RP0004).'}), def get_astroid(self, filepath, modname): """return a astroid representation for a module""" try: - return MANAGER.astroid_from_file(filepath, modname, source=True) + return MANAGER.ast_from_file(filepath, modname, source=True) except SyntaxError, ex: self.add_message('E0001', line=ex.lineno, args=ex.msg) except AstroidBuildingException, ex: diff --git a/test/input/func_kwoa_py30.py b/test/input/func_kwoa_py30.py new file mode 100644 index 0000000..4be5302 --- /dev/null +++ b/test/input/func_kwoa_py30.py @@ -0,0 +1,12 @@ +# pylint: disable=C0121, C0102 +'''A little testscript for PEP 3102 and pylint''' +def function(*, foo): + '''A function for testing''' + print(foo) + +function(foo=1) + +foo = 1 +function(foo) + +function(1) diff --git a/test/input/func_missing_super_argument_py20.py b/test/input/func_missing_super_argument_py20.py new file mode 100644 index 0000000..ec20857 --- /dev/null +++ b/test/input/func_missing_super_argument_py20.py @@ -0,0 +1,9 @@ +"""Check missing super argument for Python 2""" + +__revision__ = 0 + +class MyClass(object): + """ New style class """ + def __init__(self): + super().__init__() +
\ No newline at end of file diff --git a/test/input/func_newstyle_super.py b/test/input/func_newstyle_super.py index a3e5245..fdba69c 100644 --- a/test/input/func_newstyle_super.py +++ b/test/input/func_newstyle_super.py @@ -20,3 +20,12 @@ class NewAaaa(object): def __init__(self): super(object, self).__init__() +class Py3kAaaa(NewAaaa): + """new style""" + def __init__(self): + super().__init__() + +class Py3kWrongSuper(Py3kAaaa): + """new style""" + def __init__(self): + super(NewAaaa, self).__init__() diff --git a/test/messages/func_kwoa_py30.txt b/test/messages/func_kwoa_py30.txt new file mode 100644 index 0000000..5ccdf00 --- /dev/null +++ b/test/messages/func_kwoa_py30.txt @@ -0,0 +1,5 @@ +E: 10: Missing mandatory keyword argument 'foo' +E: 10: Too many positional arguments for function call +E: 12: Missing mandatory keyword argument 'foo' +E: 12: Too many positional arguments for function call +W: 3:function: Redefining name 'foo' from outer scope (line 9) diff --git a/test/messages/func_missing_super_argument_py20.txt b/test/messages/func_missing_super_argument_py20.txt new file mode 100644 index 0000000..28d8a46 --- /dev/null +++ b/test/messages/func_missing_super_argument_py20.txt @@ -0,0 +1,2 @@ +E: 8:MyClass.__init__: Missing argument to super()
+R: 5:MyClass: Too few public methods (0/2)
\ No newline at end of file diff --git a/test/messages/func_newstyle_super.txt b/test/messages/func_newstyle_super.txt index 15799b9..27ac3c3 100644 --- a/test/messages/func_newstyle_super.txt +++ b/test/messages/func_newstyle_super.txt @@ -1,5 +1,7 @@ C: 5:Aaaa: Old-style class defined. E: 7:Aaaa.hop: Use of super on an old style class E: 11:Aaaa.__init__: Use of super on an old style class -E: 20:NewAaaa.__init__: Bad first argument 'object' given to super class +E: 21:NewAaaa.__init__: Bad first argument 'object' given to super class +E: 26:Py3kAaaa.__init__: Missing argument to super() +E: 31:Py3kWrongSuper.__init__: Bad first argument 'NewAaaa' given to super class diff --git a/test/messages/func_newstyle_super_py30.txt b/test/messages/func_newstyle_super_py30.txt new file mode 100644 index 0000000..48ff5a4 --- /dev/null +++ b/test/messages/func_newstyle_super_py30.txt @@ -0,0 +1,5 @@ +C: 5:Aaaa: Old-style class defined. +E: 7:Aaaa.hop: Use of super on an old style class +E: 11:Aaaa.__init__: Use of super on an old style class +E: 21:NewAaaa.__init__: Bad first argument 'object' given to super class +E: 31:Py3kWrongSuper.__init__: Bad first argument 'NewAaaa' given to super class |