From 246757e9f37266c95e9a51b478673c473f6afa2c Mon Sep 17 00:00:00 2001 From: cpopa Date: Tue, 16 Jul 2013 00:51:37 +0300 Subject: Fix false positive E1003 on Python 3 for argument-less super(). --- checkers/newstyle.py | 7 ++++++- test/messages/func_newstyle_super.txt | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/checkers/newstyle.py b/checkers/newstyle.py index bc8aeca..a773b12 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 @@ -106,6 +107,10 @@ 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) @@ -113,7 +118,7 @@ class NewStyleConflictChecker(BaseChecker): 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/test/messages/func_newstyle_super.txt b/test/messages/func_newstyle_super.txt index 15799b9..d979808 100644 --- a/test/messages/func_newstyle_super.txt +++ b/test/messages/func_newstyle_super.txt @@ -1,5 +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: 20:NewAaaa.__init__: Bad first argument 'object' given to super class +E: 21:NewAaaa.__init__: Bad first argument 'object' given to super class -- cgit v1.2.1 From d5aeced1a0d446978e80bc11066ecbf25c272a8f Mon Sep 17 00:00:00 2001 From: cpopa Date: Wed, 17 Jul 2013 16:44:22 +0300 Subject: Update tests and changelog. --- ChangeLog | 1 + test/input/func_newstyle_super.py | 9 +++++++++ test/messages/func_newstyle_super.txt | 2 ++ test/messages/func_newstyle_super_py30.txt | 5 +++++ 4 files changed, 17 insertions(+) create mode 100644 test/messages/func_newstyle_super_py30.txt diff --git a/ChangeLog b/ChangeLog index b0b7465..4aa5e15 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,7 @@ 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 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_newstyle_super.txt b/test/messages/func_newstyle_super.txt index d979808..0de78ba 100644 --- a/test/messages/func_newstyle_super.txt +++ b/test/messages/func_newstyle_super.txt @@ -2,4 +2,6 @@ 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: 26:Py3kAaaa.__init__: Bad first argument None given to super class +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 -- cgit v1.2.1 From b8c6056432c20bcfe9bec9a55731185d49d387ea Mon Sep 17 00:00:00 2001 From: Julien Cristau Date: Thu, 18 Jul 2013 23:05:00 +0200 Subject: Check py3k keyword-only arguments Take them into account when matching call sites versus function definitions. Closes #107788 --- checkers/typecheck.py | 26 ++++++++++++++++++++++++++ test/input/func_kwoa_py30.py | 12 ++++++++++++ test/messages/func_kwoa_py30.txt | 5 +++++ 3 files changed, 43 insertions(+) create mode 100644 test/input/func_kwoa_py30.py create mode 100644 test/messages/func_kwoa_py30.txt 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)) 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/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) -- cgit v1.2.1 From c02b06a015f3615ed30c80ef92aa421c2b7f0fad Mon Sep 17 00:00:00 2001 From: Sylvain Th?nault Date: Thu, 18 Jul 2013 23:04:30 +0200 Subject: ChangeLog update and cleanups --- ChangeLog | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index b0b7465..d580de3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,56 +4,79 @@ ChangeLog for Pylint -- * 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 -- cgit v1.2.1 From e3676f04a42ad256854e2d3e1df61c5f9ec62a47 Mon Sep 17 00:00:00 2001 From: Sylvain Th?nault Date: Wed, 24 Jul 2013 08:55:23 +0200 Subject: update method renamed in astroid --- lint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lint.py b/lint.py index 52ec61c..e98c281 100644 --- a/lint.py +++ b/lint.py @@ -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: -- cgit v1.2.1 From 2c6d7cc0fdb706a59d782694cb0bbabd440de66b Mon Sep 17 00:00:00 2001 From: cpopa Date: Wed, 24 Jul 2013 11:23:16 +0300 Subject: Add missing-super-argument message for argumentless super on Python 2.X. --- checkers/newstyle.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/checkers/newstyle.py b/checkers/newstyle.py index a773b12..3b7acb7 100644 --- a/checkers/newstyle.py +++ b/checkers/newstyle.py @@ -34,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" \ @@ -86,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 @@ -117,8 +121,13 @@ class NewStyleConflictChecker(BaseChecker): except astroid.InferenceError: continue if klass is not supcls: - supcls = getattr(supcls, 'name', supcls) - self.add_message('E1003', node=call, args=(supcls, )) + if supcls is None and sys.version_info[0] == 2: + self.add_message('E1004', node=call) + else: + supcls = getattr(supcls, 'name', supcls) + self.add_message('E1003', + node=call, + args=(supcls, )) def register(linter): -- cgit v1.2.1 From d70ca951ae2dda2b1587ba462826736a39ac2d08 Mon Sep 17 00:00:00 2001 From: cpopa Date: Wed, 24 Jul 2013 11:24:43 +0300 Subject: Prefer the symbolic name. --- checkers/newstyle.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/checkers/newstyle.py b/checkers/newstyle.py index 3b7acb7..6433b12 100644 --- a/checkers/newstyle.py +++ b/checkers/newstyle.py @@ -122,7 +122,8 @@ class NewStyleConflictChecker(BaseChecker): continue if klass is not supcls: if supcls is None and sys.version_info[0] == 2: - self.add_message('E1004', node=call) + self.add_message('missing-super-argument', + node=call) else: supcls = getattr(supcls, 'name', supcls) self.add_message('E1003', -- cgit v1.2.1 From 98a350d53674590bc0cdaaeebea229a52a95a3cf Mon Sep 17 00:00:00 2001 From: cpopa Date: Wed, 24 Jul 2013 11:26:18 +0300 Subject: Cleanup. --- checkers/newstyle.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/checkers/newstyle.py b/checkers/newstyle.py index 6433b12..9524080 100644 --- a/checkers/newstyle.py +++ b/checkers/newstyle.py @@ -120,15 +120,14 @@ class NewStyleConflictChecker(BaseChecker): 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: - if supcls is None and sys.version_info[0] == 2: - self.add_message('missing-super-argument', - node=call) - else: - supcls = getattr(supcls, 'name', supcls) - self.add_message('E1003', - node=call, - args=(supcls, )) + supcls = getattr(supcls, 'name', supcls) + self.add_message('E1003', node=call, args=(supcls, )) def register(linter): -- cgit v1.2.1 From 698f597f6687a13225af5c675085442195390d7e Mon Sep 17 00:00:00 2001 From: cpopa Date: Wed, 24 Jul 2013 11:46:42 +0300 Subject: Change test message. --- test/messages/func_newstyle_super.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/messages/func_newstyle_super.txt b/test/messages/func_newstyle_super.txt index 0de78ba..27ac3c3 100644 --- a/test/messages/func_newstyle_super.txt +++ b/test/messages/func_newstyle_super.txt @@ -2,6 +2,6 @@ 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: 26:Py3kAaaa.__init__: Bad first argument None given to super class +E: 26:Py3kAaaa.__init__: Missing argument to super() E: 31:Py3kWrongSuper.__init__: Bad first argument 'NewAaaa' given to super class -- cgit v1.2.1 From 51923fc78ecf957a7fff2e3001c53f7a8c98994d Mon Sep 17 00:00:00 2001 From: cpopa Date: Wed, 24 Jul 2013 11:47:08 +0300 Subject: Add functional test for missing super argument message. --- test/input/func_missing_super_argument_py20.py | 9 +++++++++ test/messages/func_missing_super_argument_py20.txt | 2 ++ 2 files changed, 11 insertions(+) create mode 100644 test/input/func_missing_super_argument_py20.py create mode 100644 test/messages/func_missing_super_argument_py20.txt 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/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 -- cgit v1.2.1