summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcpopa <devnull@localhost>2013-07-25 09:52:27 +0300
committercpopa <devnull@localhost>2013-07-25 09:52:27 +0300
commit3d1c7835e6737fab5d1c2826804412fa12863aa0 (patch)
treeedf300ac7c01cd114b53df1ea392d14eae54d890
parent1c8db4963638b5382cee2fc6c8c949d2f2b06974 (diff)
parenta5e8fd05669d8e74e7242ea52f20faaa8c800291 (diff)
downloadpylint-3d1c7835e6737fab5d1c2826804412fa12863aa0.tar.gz
Merge with default.
-rw-r--r--ChangeLog42
-rw-r--r--checkers/newstyle.py18
-rw-r--r--checkers/typecheck.py26
-rw-r--r--lint.py2
-rw-r--r--test/input/func_kwoa_py30.py12
-rw-r--r--test/input/func_missing_super_argument_py20.py9
-rw-r--r--test/input/func_newstyle_super.py9
-rw-r--r--test/messages/func_kwoa_py30.txt5
-rw-r--r--test/messages/func_missing_super_argument_py20.txt2
-rw-r--r--test/messages/func_newstyle_super.txt4
-rw-r--r--test/messages/func_newstyle_super_py30.txt5
11 files changed, 121 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index b0b7465..b6e7eb2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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))
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:
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