summaryrefslogtreecommitdiff
path: root/tests/functional/s
diff options
context:
space:
mode:
authorPierre Sassoulas <pierre.sassoulas@gmail.com>2019-07-21 10:56:00 +0200
committerClaudiu Popa <pcmanticore@gmail.com>2019-09-10 11:20:16 +0200
commit997d9d1ec72fce84903da4784ac56fbe30e6da1e (patch)
tree9a0ddd3ba0975e045e408d9793cce096ecaeaa75 /tests/functional/s
parent676ec55ff9d8f10e52b740a57e4e62a3255d6709 (diff)
downloadpylint-git-997d9d1ec72fce84903da4784ac56fbe30e6da1e.tar.gz
[functional tests] Rename example_functional_tests.py => e/example_functional_tests.py
Permit to navigate in the functional tests easier.
Diffstat (limited to 'tests/functional/s')
-rw-r--r--tests/functional/s/self_assigning_variable.py20
-rw-r--r--tests/functional/s/self_assigning_variable.txt2
-rw-r--r--tests/functional/s/self_cls_assignment.py47
-rw-r--r--tests/functional/s/self_cls_assignment.txt4
-rw-r--r--tests/functional/s/signature_differs.py22
-rw-r--r--tests/functional/s/signature_differs.txt1
-rw-r--r--tests/functional/s/simplifiable_if_expression.py27
-rw-r--r--tests/functional/s/simplifiable_if_expression.txt4
-rw-r--r--tests/functional/s/simplifiable_if_statement.py146
-rw-r--r--tests/functional/s/simplifiable_if_statement.txt4
-rw-r--r--tests/functional/s/simplify_chained_comparison.py89
-rw-r--r--tests/functional/s/simplify_chained_comparison.txt18
-rw-r--r--tests/functional/s/singledispatch_functions.py76
-rw-r--r--tests/functional/s/singledispatch_functions.rc3
-rw-r--r--tests/functional/s/singledispatch_functions.txt5
-rw-r--r--tests/functional/s/singledispatch_functions_py3.py76
-rw-r--r--tests/functional/s/singledispatch_functions_py3.rc3
-rw-r--r--tests/functional/s/singledispatch_functions_py3.txt5
-rw-r--r--tests/functional/s/singleton_comparison.py15
-rw-r--r--tests/functional/s/singleton_comparison.txt8
-rw-r--r--tests/functional/s/slots_checks.py105
-rw-r--r--tests/functional/s/slots_checks.txt11
-rw-r--r--tests/functional/s/socketerror_import.py6
-rw-r--r--tests/functional/s/star_needs_assignment_target.py4
-rw-r--r--tests/functional/s/star_needs_assignment_target.rc2
-rw-r--r--tests/functional/s/star_needs_assignment_target.txt1
-rw-r--r--tests/functional/s/star_needs_assignment_target_py35.py15
-rw-r--r--tests/functional/s/star_needs_assignment_target_py35.rc2
-rw-r--r--tests/functional/s/star_needs_assignment_target_py35.txt1
-rw-r--r--tests/functional/s/statement_without_effect.py75
-rw-r--r--tests/functional/s/statement_without_effect.txt60
-rw-r--r--tests/functional/s/statement_without_effect_py36.py18
-rw-r--r--tests/functional/s/statement_without_effect_py36.rc2
-rw-r--r--tests/functional/s/statement_without_effect_py36.txt1
-rw-r--r--tests/functional/s/stop_iteration_inside_generator.py129
-rw-r--r--tests/functional/s/stop_iteration_inside_generator.rc2
-rw-r--r--tests/functional/s/stop_iteration_inside_generator.txt7
-rw-r--r--tests/functional/s/string_formatting.py188
-rw-r--r--tests/functional/s/string_formatting.txt41
-rw-r--r--tests/functional/s/string_formatting_disable.py1
-rw-r--r--tests/functional/s/string_formatting_disable.rc3
-rw-r--r--tests/functional/s/string_formatting_disable.txt1
-rw-r--r--tests/functional/s/string_formatting_failed_inference.py4
-rw-r--r--tests/functional/s/string_formatting_failed_inference_py35.py6
-rw-r--r--tests/functional/s/string_formatting_failed_inference_py35.rc2
-rw-r--r--tests/functional/s/string_formatting_py27.py22
-rw-r--r--tests/functional/s/string_formatting_py27.rc3
-rw-r--r--tests/functional/s/string_formatting_py27.txt15
-rw-r--r--tests/functional/s/string_formatting_py3.py21
-rw-r--r--tests/functional/s/string_formatting_py3.rc2
-rw-r--r--tests/functional/s/string_formatting_py3.txt2
-rw-r--r--tests/functional/s/subprocess_popen_preexec_fn.py11
-rw-r--r--tests/functional/s/subprocess_popen_preexec_fn.txt1
-rw-r--r--tests/functional/s/subprocess_run_check35.py6
-rw-r--r--tests/functional/s/subprocess_run_check35.rc2
-rw-r--r--tests/functional/s/subprocess_run_check35.txt1
-rw-r--r--tests/functional/s/super_checks.py125
-rw-r--r--tests/functional/s/super_checks.txt18
-rw-r--r--tests/functional/s/superfluous_parens.py19
-rw-r--r--tests/functional/s/superfluous_parens.txt5
-rw-r--r--tests/functional/s/suspicious_str_strip_call.py10
-rw-r--r--tests/functional/s/suspicious_str_strip_call.rc2
-rw-r--r--tests/functional/s/suspicious_str_strip_call.txt3
-rw-r--r--tests/functional/s/suspicious_str_strip_call_py3.py9
-rw-r--r--tests/functional/s/suspicious_str_strip_call_py3.rc2
-rw-r--r--tests/functional/s/suspicious_str_strip_call_py3.txt3
-rw-r--r--tests/functional/s/syntax_error.py1
-rw-r--r--tests/functional/s/syntax_error.rc1
-rw-r--r--tests/functional/s/syntax_error.txt1
-rw-r--r--tests/functional/s/syntax_error_jython.py1
-rw-r--r--tests/functional/s/syntax_error_jython.rc2
-rw-r--r--tests/functional/s/syntax_error_jython.txt1
-rw-r--r--tests/functional/s/sys_stream_regression_1004.py7
-rw-r--r--tests/functional/s/sys_stream_regression_1004.rc3
-rw-r--r--tests/functional/s/sys_stream_regression_1004.txt2
75 files changed, 1563 insertions, 0 deletions
diff --git a/tests/functional/s/self_assigning_variable.py b/tests/functional/s/self_assigning_variable.py
new file mode 100644
index 000000000..2c5148f63
--- /dev/null
+++ b/tests/functional/s/self_assigning_variable.py
@@ -0,0 +1,20 @@
+# pylint: disable=missing-docstring,too-few-public-methods
+# pylint: disable=unpacking-non-sequence,attribute-defined-outside-init,invalid-name
+
+class Class:
+ pass
+
+CLS = Class()
+FIRST = 1
+# Not enough values on the right hand side
+FIRST, SECOND = FIRST
+# Not enough values on the left hand side
+FIRST = FIRST, SECOND
+# Not equivalent to a self assignment
+FIRST = (FIRST, )
+# Not assigning to an attribute
+CLS.FIRST = FIRST
+# Not a name on the right hand side
+FIRST = Class()
+FIRST = FIRST # [self-assigning-variable]
+FIRST, SECOND = FIRST, CLS.FIRST # [self-assigning-variable]
diff --git a/tests/functional/s/self_assigning_variable.txt b/tests/functional/s/self_assigning_variable.txt
new file mode 100644
index 000000000..1787f1f47
--- /dev/null
+++ b/tests/functional/s/self_assigning_variable.txt
@@ -0,0 +1,2 @@
+self-assigning-variable:19::Assigning the same variable 'FIRST' to itself
+self-assigning-variable:20::Assigning the same variable 'FIRST' to itself
diff --git a/tests/functional/s/self_cls_assignment.py b/tests/functional/s/self_cls_assignment.py
new file mode 100644
index 000000000..4e63bb422
--- /dev/null
+++ b/tests/functional/s/self_cls_assignment.py
@@ -0,0 +1,47 @@
+"""Warning about assigning self/cls variable."""
+from __future__ import print_function
+# pylint: disable=too-few-public-methods, useless-object-inheritance
+
+class Foo(object):
+ """Class with methods that check for self/cls assignment"""
+
+ # pylint: disable=no-self-argument,no-self-use
+ def self_foo(bar_):
+ """Instance method, should warn for bar"""
+ bar_ = 10 # [self-cls-assignment]
+
+ # pylint: disable=no-self-use
+ def self_foofoo(self, lala):
+ """Instance method, should warn for self"""
+ self = lala # [self-cls-assignment]
+
+ @classmethod
+ def cls_foo(cls):
+ """Class method, should warn for cls"""
+ cls = 'tada' # [self-cls-assignment]
+
+ # pylint: disable=unused-argument
+ @staticmethod
+ def static_foo(lala):
+ """Static method, no warnings"""
+ lala = 10
+
+
+# pylint: disable=unused-argument
+def free_foo(bar_, lala):
+ """Free function, no warnings"""
+ bar_ = lala
+
+
+class TestNonLocal:
+ """Test class for nonlocal assignment of self"""
+
+ def function(self, param):
+ """This function uses nonlocal to reassign self"""
+
+ def _set_param(param):
+ nonlocal self
+ self = param # [self-cls-assignment]
+
+ _set_param(param)
+ return self
diff --git a/tests/functional/s/self_cls_assignment.txt b/tests/functional/s/self_cls_assignment.txt
new file mode 100644
index 000000000..42a90340c
--- /dev/null
+++ b/tests/functional/s/self_cls_assignment.txt
@@ -0,0 +1,4 @@
+self-cls-assignment:11:Foo.self_foo:Invalid assignment to bar_ in method
+self-cls-assignment:16:Foo.self_foofoo:Invalid assignment to self in method
+self-cls-assignment:21:Foo.cls_foo:Invalid assignment to cls in method
+self-cls-assignment:44:TestNonLocal.function._set_param:Invalid assignment to self in method
diff --git a/tests/functional/s/signature_differs.py b/tests/functional/s/signature_differs.py
new file mode 100644
index 000000000..920611fd0
--- /dev/null
+++ b/tests/functional/s/signature_differs.py
@@ -0,0 +1,22 @@
+# pylint: disable=too-few-public-methods, missing-docstring, no-self-use, useless-object-inheritance
+
+class Abcd(object):
+
+ def __init__(self):
+ self.aarg = False
+
+ def abcd(self, aaa=1, bbbb=None):
+ return aaa, bbbb
+
+ def args(self):
+ self.aarg = True
+
+
+class Cdef(Abcd):
+
+ def __init__(self, aaa):
+ Abcd.__init__(self)
+ self.aaa = aaa
+
+ def abcd(self, aaa, bbbb=None): # [signature-differs]
+ return aaa, bbbb
diff --git a/tests/functional/s/signature_differs.txt b/tests/functional/s/signature_differs.txt
new file mode 100644
index 000000000..a9985e5fc
--- /dev/null
+++ b/tests/functional/s/signature_differs.txt
@@ -0,0 +1 @@
+signature-differs:21:Cdef.abcd:Signature differs from overridden 'abcd' method
diff --git a/tests/functional/s/simplifiable_if_expression.py b/tests/functional/s/simplifiable_if_expression.py
new file mode 100644
index 000000000..bcfdf890b
--- /dev/null
+++ b/tests/functional/s/simplifiable_if_expression.py
@@ -0,0 +1,27 @@
+"""Test that some if expressions can be simplified."""
+
+# pylint: disable=missing-docstring, invalid-name
+
+
+def test_simplifiable_1(arg):
+ # Simple test that can be replaced by bool(arg)
+ return True if arg else False # [simplifiable-if-expression]
+
+def test_simplifiable_2(arg):
+ # Simple test that can be replaced by not arg
+ return False if arg else True # [simplifiable-if-expression]
+
+def test_simplifiable_3(arg):
+ # Simple test that can be replaced by arg == 1
+ return True if arg == 1 else False # [simplifiable-if-expression]
+
+def test_simplifiable_4(arg):
+ # Simple test that can be replaced by not (arg == 1)
+ return False if arg == 1 else True # [simplifiable-if-expression]
+
+def test_not_simplifiable(arg):
+ x = True if arg else True
+ y = 0 if arg else 1
+ t = False if arg != 1 else False
+ t2 = None if arg > 3 else False
+ return x, y, t, t2
diff --git a/tests/functional/s/simplifiable_if_expression.txt b/tests/functional/s/simplifiable_if_expression.txt
new file mode 100644
index 000000000..b35e08462
--- /dev/null
+++ b/tests/functional/s/simplifiable_if_expression.txt
@@ -0,0 +1,4 @@
+simplifiable-if-expression:8:test_simplifiable_1:The if expression can be replaced with 'bool(test)'
+simplifiable-if-expression:12:test_simplifiable_2:The if expression can be replaced with 'not test'
+simplifiable-if-expression:16:test_simplifiable_3:The if expression can be replaced with 'test'
+simplifiable-if-expression:20:test_simplifiable_4:The if expression can be replaced with 'not test' \ No newline at end of file
diff --git a/tests/functional/s/simplifiable_if_statement.py b/tests/functional/s/simplifiable_if_statement.py
new file mode 100644
index 000000000..4d4c8b5d4
--- /dev/null
+++ b/tests/functional/s/simplifiable_if_statement.py
@@ -0,0 +1,146 @@
+"""Test that some if statement tests can be simplified."""
+
+# pylint: disable=missing-docstring, invalid-name, no-else-return, arguments-out-of-order
+
+
+def test_simplifiable_1(arg):
+ # Simple test that can be replaced by bool(arg)
+ if arg: # [simplifiable-if-statement]
+ return True
+ else:
+ return False
+
+
+def test_simplifiable_2(arg, arg2):
+ # Can be reduced to bool(arg and not arg2)
+ if arg and not arg2: # [simplifiable-if-statement]
+ return True
+ else:
+ return False
+
+
+def test_simplifiable_3(arg, arg2):
+ # Can be reduced to bool(arg and not arg2)
+ if arg and not arg2: # [simplifiable-if-statement]
+ var = True
+ else:
+ var = False
+ return var
+
+
+def test_simplifiable_4(arg):
+ if arg:
+ var = True
+ else:
+ if arg == "arg1": # [simplifiable-if-statement]
+ return True
+ else:
+ return False
+ return var
+
+
+def test_not_necessarily_simplifiable_1(arg, arg2):
+ # Can be reduced to bool(not arg and not arg2) or to
+ # `not all(N)`, which is a bit harder to understand
+ # than `any(N)` when var should be False.
+ if arg or arg2:
+ var = False
+ else:
+ var = True
+ return var
+
+
+def test_not_necessarily_simplifiabile_2(arg):
+ # This could theoretically be reduced to `not arg or arg > 3`
+ # but the net result is that now the condition is harder to understand,
+ # because it requires understanding of an extra clause:
+ # * first, there is the negation of truthness with `not arg`
+ # * the second clause is `arg > 3`, which occurs when arg has a
+ # a truth value, but it implies that `arg > 3` is equivalent
+ # with `arg and arg > 3`, which means that the user must
+ # think about this assumption when evaluating `arg > 3`.
+ # The original form is easier to grasp.
+ if arg and arg <= 3:
+ return False
+ else:
+ return True
+
+
+def test_not_simplifiable_3(arg):
+ if arg:
+ test_not_necessarily_simplifiabile_2(arg)
+ test_not_necessarily_simplifiable_1(arg, arg)
+ return False
+ else:
+ if arg < 3:
+ test_simplifiable_3(arg, 42)
+ return True
+
+
+def test_not_simplifiable_4(arg):
+ # Not interested in multiple elifs
+ if arg == "any":
+ return True
+ elif test_not_simplifiable_3(arg) == arg:
+ return True
+ else:
+ return False
+
+
+def test_not_simplifiable_5(arg):
+ # Different actions in each branch
+ if arg == "any":
+ return True
+ else:
+ var = 42
+ return var
+
+
+def test_not_simplifiable_6(arg):
+ # Different actions in each branch
+ if arg == "any":
+ var = 42
+ else:
+ return True
+ return var
+
+def test_not_simplifiable_7(arg):
+ # Returning something different
+ if arg == "any":
+ return 4
+ else:
+ return 5
+
+
+def test_not_simplifiable_8(arg):
+ # Only one of the branch returns something boolean
+ if arg == "any":
+ return True
+ else:
+ return 0
+
+
+def test_not_simplifiable_9():
+ # Not the same targets
+ first = True
+ second = 1
+ third = [1]
+ fourth = False
+ fifth = False
+
+ if first and second in third:
+ fourth = True
+ else:
+ fifth = True
+ return fourth + fifth
+
+
+def test_not_simplifiable_10():
+ # Subscripts are not considered
+ object_type = 'read'
+ filter_kwargs = {}
+ if object_type == 'read':
+ filter_kwargs['a'] = True
+ else:
+ filter_kwargs['b'] = True
+ return filter_kwargs
diff --git a/tests/functional/s/simplifiable_if_statement.txt b/tests/functional/s/simplifiable_if_statement.txt
new file mode 100644
index 000000000..1c5110908
--- /dev/null
+++ b/tests/functional/s/simplifiable_if_statement.txt
@@ -0,0 +1,4 @@
+simplifiable-if-statement:8:test_simplifiable_1:The if statement can be replaced with 'return bool(test)'
+simplifiable-if-statement:16:test_simplifiable_2:The if statement can be replaced with 'return bool(test)'
+simplifiable-if-statement:24:test_simplifiable_3:The if statement can be replaced with 'var = bool(test)'
+simplifiable-if-statement:35:test_simplifiable_4:The if statement can be replaced with 'return bool(test)'
diff --git a/tests/functional/s/simplify_chained_comparison.py b/tests/functional/s/simplify_chained_comparison.py
new file mode 100644
index 000000000..4be9fbe3d
--- /dev/null
+++ b/tests/functional/s/simplify_chained_comparison.py
@@ -0,0 +1,89 @@
+"""Test that some boolean expression statement tests can be simplified."""
+
+# pylint: disable=missing-docstring, invalid-name, no-else-return, too-many-branches
+
+
+def test_simplify_chained_comparison_1():
+ a = 1
+ b = 2
+ c = 3
+ return a < b and b < c # [chained-comparison]
+
+
+def test_simplify_chained_comparison_2():
+ a = 1
+ return a < 10 and a > 1 # [chained-comparison]
+
+
+def test_simplify_chained_comparison_3():
+ a = 1
+ b = 2
+ c = 3
+ d = 4
+ if a < 10 and a > 1: # [chained-comparison]
+ pass
+ elif a > 1 and a < 10: # [chained-comparison]
+ pass
+ elif a > 1 and a <= 10: # [chained-comparison]
+ pass
+ elif a > 1 and a < 10 and b == 2: # [chained-comparison]
+ pass
+ elif a > 1 and c == b and a < 10: # [chained-comparison]
+ pass
+ elif a > 100 and c == b and a < 10: # [chained-comparison]
+ # In this comparison we are not checking whether left bound is actually
+ # lower than right bound or not.
+ pass
+ elif a < b and b < c: # [chained-comparison]
+ pass
+ elif a > b and b > c: # [chained-comparison]
+ pass
+ elif a < b and a == 1 and b < c: # [chained-comparison]
+ pass
+ elif a < b and b < c and c == 786: # [chained-comparison]
+ pass
+ elif a < b and b < 0 and c == 786: # [chained-comparison]
+ pass
+ elif a < b and c == 786 and b < 0: # [chained-comparison]
+ pass
+ elif c == 786 and b < 0 and a < b: # [chained-comparison]
+ pass
+ elif a < b < c and c < d: # [chained-comparison]
+ pass
+ elif b < c < d and a < b: # [chained-comparison]
+ pass
+ elif a < b < c and a < b and b < c: # [chained-comparison]
+ pass
+
+
+def test_not_simplify_chained_comparison_1():
+ a = 1
+ b = 2
+ c = 3
+ d = 4
+ if a < 10 and b > 1:
+ pass
+ elif a > 1 and b < 10:
+ pass
+ elif a > 1 and a == 10:
+ pass
+ elif a == 1 and b == 2:
+ pass
+ elif a > 1 and a > 10:
+ pass
+ elif a < 100 and a < 10:
+ pass
+ elif a < b and a < c:
+ pass
+ elif a < b and a == 1 and a < c:
+ pass
+ elif a < b and a < c and c == 786:
+ pass
+ elif a < b < c and b < d:
+ pass
+ elif a < b < c and a < d:
+ pass
+ elif b < c < d and a < c:
+ pass
+ elif b < c < d and a < d:
+ pass
diff --git a/tests/functional/s/simplify_chained_comparison.txt b/tests/functional/s/simplify_chained_comparison.txt
new file mode 100644
index 000000000..3107e60cb
--- /dev/null
+++ b/tests/functional/s/simplify_chained_comparison.txt
@@ -0,0 +1,18 @@
+chained-comparison:10:test_simplify_chained_comparison_1:Simplify chained comparison between the operands
+chained-comparison:15:test_simplify_chained_comparison_2:Simplify chained comparison between the operands
+chained-comparison:23:test_simplify_chained_comparison_3:Simplify chained comparison between the operands
+chained-comparison:25:test_simplify_chained_comparison_3:Simplify chained comparison between the operands
+chained-comparison:27:test_simplify_chained_comparison_3:Simplify chained comparison between the operands
+chained-comparison:29:test_simplify_chained_comparison_3:Simplify chained comparison between the operands
+chained-comparison:31:test_simplify_chained_comparison_3:Simplify chained comparison between the operands
+chained-comparison:33:test_simplify_chained_comparison_3:Simplify chained comparison between the operands
+chained-comparison:37:test_simplify_chained_comparison_3:Simplify chained comparison between the operands
+chained-comparison:39:test_simplify_chained_comparison_3:Simplify chained comparison between the operands
+chained-comparison:41:test_simplify_chained_comparison_3:Simplify chained comparison between the operands
+chained-comparison:43:test_simplify_chained_comparison_3:Simplify chained comparison between the operands
+chained-comparison:45:test_simplify_chained_comparison_3:Simplify chained comparison between the operands
+chained-comparison:47:test_simplify_chained_comparison_3:Simplify chained comparison between the operands
+chained-comparison:49:test_simplify_chained_comparison_3:Simplify chained comparison between the operands
+chained-comparison:51:test_simplify_chained_comparison_3:Simplify chained comparison between the operands
+chained-comparison:53:test_simplify_chained_comparison_3:Simplify chained comparison between the operands
+chained-comparison:55:test_simplify_chained_comparison_3:Simplify chained comparison between the operands
diff --git a/tests/functional/s/singledispatch_functions.py b/tests/functional/s/singledispatch_functions.py
new file mode 100644
index 000000000..cfd4d873c
--- /dev/null
+++ b/tests/functional/s/singledispatch_functions.py
@@ -0,0 +1,76 @@
+# pylint: disable=missing-docstring,import-error,unused-import,assignment-from-no-return
+# pylint: disable=invalid-name, too-few-public-methods, useless-object-inheritance
+from __future__ import print_function
+from UNINFERABLE import uninferable_func
+
+try:
+ from functools import singledispatch
+except ImportError:
+ from singledispatch import singledispatch
+
+my_single_dispatch = singledispatch
+
+
+class FakeSingleDispatch(object):
+
+ @staticmethod
+ def register(function):
+ return function
+
+ def __call__(self, function):
+ return function
+
+fake_singledispatch_decorator = FakeSingleDispatch()
+
+@singledispatch
+def func(arg):
+ return arg
+
+
+@func.register(str)
+def _(arg):
+ return 42
+
+
+@func.register(float)
+@func.register(int)
+def _(arg):
+ return 42
+
+
+@my_single_dispatch
+def func2(arg):
+ return arg
+
+
+@func2.register(int)
+def _(arg):
+ return 42
+
+
+@singledispatch
+def with_extra_arg(arg, verbose=False):
+ if verbose:
+ print(arg)
+ return arg
+
+
+@with_extra_arg.register(str)
+def _(arg, verbose=False):
+ unused = 42 # [unused-variable]
+ return arg[::-1]
+
+
+@fake_singledispatch_decorator
+def not_single_dispatch(arg): # [unused-argument]
+ return 'not yet implemented'
+
+
+@fake_singledispatch_decorator.register(str)
+def bad_single_dispatch(arg): # [unused-argument]
+ return 42
+
+
+@fake_singledispatch_decorator.register(str)
+def bad_single_dispatch(arg): # [unused-argument, function-redefined]
+ return 24
diff --git a/tests/functional/s/singledispatch_functions.rc b/tests/functional/s/singledispatch_functions.rc
new file mode 100644
index 000000000..fc795dc6d
--- /dev/null
+++ b/tests/functional/s/singledispatch_functions.rc
@@ -0,0 +1,3 @@
+[testoptions]
+;http://bugs.python.org/issue10445
+max_pyver=3.0
diff --git a/tests/functional/s/singledispatch_functions.txt b/tests/functional/s/singledispatch_functions.txt
new file mode 100644
index 000000000..568f41b31
--- /dev/null
+++ b/tests/functional/s/singledispatch_functions.txt
@@ -0,0 +1,5 @@
+unused-variable:60:_:Unused variable 'unused'
+unused-argument:65:not_single_dispatch:Unused argument 'arg'
+unused-argument:70:bad_single_dispatch:Unused argument 'arg'
+function-redefined:75:bad_single_dispatch:function already defined line 70
+unused-argument:75:bad_single_dispatch:Unused argument 'arg' \ No newline at end of file
diff --git a/tests/functional/s/singledispatch_functions_py3.py b/tests/functional/s/singledispatch_functions_py3.py
new file mode 100644
index 000000000..cfd4d873c
--- /dev/null
+++ b/tests/functional/s/singledispatch_functions_py3.py
@@ -0,0 +1,76 @@
+# pylint: disable=missing-docstring,import-error,unused-import,assignment-from-no-return
+# pylint: disable=invalid-name, too-few-public-methods, useless-object-inheritance
+from __future__ import print_function
+from UNINFERABLE import uninferable_func
+
+try:
+ from functools import singledispatch
+except ImportError:
+ from singledispatch import singledispatch
+
+my_single_dispatch = singledispatch
+
+
+class FakeSingleDispatch(object):
+
+ @staticmethod
+ def register(function):
+ return function
+
+ def __call__(self, function):
+ return function
+
+fake_singledispatch_decorator = FakeSingleDispatch()
+
+@singledispatch
+def func(arg):
+ return arg
+
+
+@func.register(str)
+def _(arg):
+ return 42
+
+
+@func.register(float)
+@func.register(int)
+def _(arg):
+ return 42
+
+
+@my_single_dispatch
+def func2(arg):
+ return arg
+
+
+@func2.register(int)
+def _(arg):
+ return 42
+
+
+@singledispatch
+def with_extra_arg(arg, verbose=False):
+ if verbose:
+ print(arg)
+ return arg
+
+
+@with_extra_arg.register(str)
+def _(arg, verbose=False):
+ unused = 42 # [unused-variable]
+ return arg[::-1]
+
+
+@fake_singledispatch_decorator
+def not_single_dispatch(arg): # [unused-argument]
+ return 'not yet implemented'
+
+
+@fake_singledispatch_decorator.register(str)
+def bad_single_dispatch(arg): # [unused-argument]
+ return 42
+
+
+@fake_singledispatch_decorator.register(str)
+def bad_single_dispatch(arg): # [unused-argument, function-redefined]
+ return 24
diff --git a/tests/functional/s/singledispatch_functions_py3.rc b/tests/functional/s/singledispatch_functions_py3.rc
new file mode 100644
index 000000000..d43f6c339
--- /dev/null
+++ b/tests/functional/s/singledispatch_functions_py3.rc
@@ -0,0 +1,3 @@
+[testoptions]
+;http://bugs.python.org/issue10445
+min_pyver=3.4
diff --git a/tests/functional/s/singledispatch_functions_py3.txt b/tests/functional/s/singledispatch_functions_py3.txt
new file mode 100644
index 000000000..568f41b31
--- /dev/null
+++ b/tests/functional/s/singledispatch_functions_py3.txt
@@ -0,0 +1,5 @@
+unused-variable:60:_:Unused variable 'unused'
+unused-argument:65:not_single_dispatch:Unused argument 'arg'
+unused-argument:70:bad_single_dispatch:Unused argument 'arg'
+function-redefined:75:bad_single_dispatch:function already defined line 70
+unused-argument:75:bad_single_dispatch:Unused argument 'arg' \ No newline at end of file
diff --git a/tests/functional/s/singleton_comparison.py b/tests/functional/s/singleton_comparison.py
new file mode 100644
index 000000000..9a28c0e2e
--- /dev/null
+++ b/tests/functional/s/singleton_comparison.py
@@ -0,0 +1,15 @@
+# pylint: disable=missing-docstring, invalid-name, misplaced-comparison-constant,literal-comparison, comparison-with-itself
+x = 42
+a = x is None
+b = x == None # [singleton-comparison]
+c = x == True # [singleton-comparison]
+d = x == False # [singleton-comparison]
+e = True == True # [singleton-comparison]
+f = x is 1
+g = 123 is "123"
+h = None is x
+i = None == x # [singleton-comparison]
+
+j = x != True # [singleton-comparison]
+j1 = x != False # [singleton-comparison]
+j2 = x != None # [singleton-comparison]
diff --git a/tests/functional/s/singleton_comparison.txt b/tests/functional/s/singleton_comparison.txt
new file mode 100644
index 000000000..533d71f63
--- /dev/null
+++ b/tests/functional/s/singleton_comparison.txt
@@ -0,0 +1,8 @@
+singleton-comparison:4::Comparison to None should be 'expr is None'
+singleton-comparison:5::Comparison to True should be just 'expr'
+singleton-comparison:6::Comparison to False should be 'not expr'
+singleton-comparison:7::Comparison to True should be just 'expr'
+singleton-comparison:11::Comparison to None should be 'expr is None'
+singleton-comparison:13::Comparison to True should be just 'not expr'
+singleton-comparison:14::Comparison to False should be 'expr'
+singleton-comparison:15::Comparison to None should be 'expr is not None'
diff --git a/tests/functional/s/slots_checks.py b/tests/functional/s/slots_checks.py
new file mode 100644
index 000000000..64a439f33
--- /dev/null
+++ b/tests/functional/s/slots_checks.py
@@ -0,0 +1,105 @@
+""" Checks that classes uses valid __slots__ """
+
+# pylint: disable=too-few-public-methods, missing-docstring, no-absolute-import, useless-object-inheritance
+# pylint: disable=using-constant-test, wrong-import-position, no-else-return, line-too-long
+from collections import deque
+
+def func():
+ if True:
+ return ("a", "b", "c")
+ else:
+ return [str(var) for var in range(3)]
+
+
+class NotIterable(object):
+ def __iter_(self):
+ """ do nothing """
+
+class Good(object):
+ __slots__ = ()
+
+class SecondGood(object):
+ __slots__ = []
+
+class ThirdGood(object):
+ __slots__ = ['a']
+
+class FourthGood(object):
+ __slots__ = ('a%s' % i for i in range(10))
+
+class FifthGood(object):
+ __slots__ = deque(["a", "b", "c"])
+
+class SixthGood(object):
+ __slots__ = {"a": "b", "c": "d"}
+
+class Bad(object): # [invalid-slots]
+ __slots__ = list
+
+class SecondBad(object): # [invalid-slots]
+ __slots__ = 1
+
+class ThirdBad(object):
+ __slots__ = ('a', 2) # [invalid-slots-object]
+
+class FourthBad(object): # [invalid-slots]
+ __slots__ = NotIterable()
+
+class FifthBad(object):
+ __slots__ = ("a", "b", "") # [invalid-slots-object]
+
+class SixthBad(object): # [single-string-used-for-slots]
+ __slots__ = "a"
+
+class SeventhBad(object): # [single-string-used-for-slots]
+ __slots__ = ('foo')
+
+class EighthBad(object): # [single-string-used-for-slots]
+ __slots__ = deque.__name__
+
+class PotentiallyGood(object):
+ __slots__ = func()
+
+class PotentiallySecondGood(object):
+ __slots__ = ('a', deque.__name__)
+
+
+import six
+
+
+class Metaclass(type):
+
+ def __iter__(cls):
+ for value in range(10):
+ yield str(value)
+
+
+@six.add_metaclass(Metaclass)
+class IterableClass(object):
+ pass
+
+class PotentiallyThirdGood(object):
+ __slots__ = IterableClass
+
+class PotentiallyFourthGood(object):
+ __slots__ = Good.__slots__
+
+
+class ValueInSlotConflict(object):
+ __slots__ = ('first', 'second', 'third', 'fourth') # [class-variable-slots-conflict, class-variable-slots-conflict, class-variable-slots-conflict]
+ first = None
+
+ @property
+ def third(self):
+ return 42
+
+ def fourth(self):
+ return self.third
+
+
+class Parent(object):
+ first = 42
+
+
+class ChildNotAffectedByValueInSlot(Parent):
+ __slots__ = ('first', )
diff --git a/tests/functional/s/slots_checks.txt b/tests/functional/s/slots_checks.txt
new file mode 100644
index 000000000..b3d71afcc
--- /dev/null
+++ b/tests/functional/s/slots_checks.txt
@@ -0,0 +1,11 @@
+invalid-slots:36:Bad:Invalid __slots__ object
+invalid-slots:39:SecondBad:Invalid __slots__ object
+invalid-slots-object:43:ThirdBad:Invalid object '2' in __slots__, must contain only non empty strings
+invalid-slots:45:FourthBad:Invalid __slots__ object
+invalid-slots-object:49:FifthBad:"Invalid object ""''"" in __slots__, must contain only non empty strings"
+single-string-used-for-slots:51:SixthBad:Class __slots__ should be a non-string iterable
+single-string-used-for-slots:54:SeventhBad:Class __slots__ should be a non-string iterable
+single-string-used-for-slots:57:EighthBad:Class __slots__ should be a non-string iterable
+class-variable-slots-conflict:89:ValueInSlotConflict:Value 'first' in slots conflicts with class variable
+class-variable-slots-conflict:89:ValueInSlotConflict:Value 'fourth' in slots conflicts with class variable
+class-variable-slots-conflict:89:ValueInSlotConflict:Value 'third' in slots conflicts with class variable
diff --git a/tests/functional/s/socketerror_import.py b/tests/functional/s/socketerror_import.py
new file mode 100644
index 000000000..df5de2957
--- /dev/null
+++ b/tests/functional/s/socketerror_import.py
@@ -0,0 +1,6 @@
+"""ds"""
+from __future__ import absolute_import, print_function
+from socket import error
+__revision__ = '$Id: socketerror_import.py,v 1.2 2005-12-28 14:58:22 syt Exp $'
+
+print(error)
diff --git a/tests/functional/s/star_needs_assignment_target.py b/tests/functional/s/star_needs_assignment_target.py
new file mode 100644
index 000000000..5421c226b
--- /dev/null
+++ b/tests/functional/s/star_needs_assignment_target.py
@@ -0,0 +1,4 @@
+"""Test for a = *b"""
+
+FIRST = *[1, 2] # [star-needs-assignment-target]
+*THIRD, FOURTH = [1, 2, 3,]
diff --git a/tests/functional/s/star_needs_assignment_target.rc b/tests/functional/s/star_needs_assignment_target.rc
new file mode 100644
index 000000000..c093be204
--- /dev/null
+++ b/tests/functional/s/star_needs_assignment_target.rc
@@ -0,0 +1,2 @@
+[testoptions]
+min_pyver=3.0
diff --git a/tests/functional/s/star_needs_assignment_target.txt b/tests/functional/s/star_needs_assignment_target.txt
new file mode 100644
index 000000000..b66975c97
--- /dev/null
+++ b/tests/functional/s/star_needs_assignment_target.txt
@@ -0,0 +1 @@
+star-needs-assignment-target:3::Can use starred expression only in assignment target
diff --git a/tests/functional/s/star_needs_assignment_target_py35.py b/tests/functional/s/star_needs_assignment_target_py35.py
new file mode 100644
index 000000000..fb5eea86a
--- /dev/null
+++ b/tests/functional/s/star_needs_assignment_target_py35.py
@@ -0,0 +1,15 @@
+"""
+Test PEP 0448 -- Additional Unpacking Generalizations
+https://www.python.org/dev/peps/pep-0448/
+"""
+
+# pylint: disable=superfluous-parens, unnecessary-comprehension
+
+UNPACK_TUPLE = (*range(4), 4)
+UNPACK_LIST = [*range(4), 4]
+UNPACK_SET = {*range(4), 4}
+UNPACK_DICT = {'a': 1, **{'b': '2'}}
+UNPACK_DICT2 = {**UNPACK_DICT, "x": 1, "y": 2}
+UNPACK_DICT3 = {**{'a': 1}, 'a': 2, **{'a': 3}}
+
+UNPACK_IN_COMP = {elem for elem in (*range(10))} # [star-needs-assignment-target]
diff --git a/tests/functional/s/star_needs_assignment_target_py35.rc b/tests/functional/s/star_needs_assignment_target_py35.rc
new file mode 100644
index 000000000..71de8b630
--- /dev/null
+++ b/tests/functional/s/star_needs_assignment_target_py35.rc
@@ -0,0 +1,2 @@
+[testoptions]
+min_pyver=3.5
diff --git a/tests/functional/s/star_needs_assignment_target_py35.txt b/tests/functional/s/star_needs_assignment_target_py35.txt
new file mode 100644
index 000000000..07770523b
--- /dev/null
+++ b/tests/functional/s/star_needs_assignment_target_py35.txt
@@ -0,0 +1 @@
+star-needs-assignment-target:15::Can use starred expression only in assignment target \ No newline at end of file
diff --git a/tests/functional/s/statement_without_effect.py b/tests/functional/s/statement_without_effect.py
new file mode 100644
index 000000000..bac4f6795
--- /dev/null
+++ b/tests/functional/s/statement_without_effect.py
@@ -0,0 +1,75 @@
+"""Test for statements without effects."""
+# pylint: disable=too-few-public-methods, useless-object-inheritance, unnecessary-comprehension
+
+# +1:[pointless-string-statement]
+"""inline doc string should use a separated message"""
+
+__revision__ = ''
+
+__revision__ # [pointless-statement]
+
+__revision__ <= 1 # [pointless-statement]
+
+__revision__.lower()
+
+[i for i in __revision__] # [pointless-statement]
+
+# +1:[pointless-string-statement]
+"""inline doc string should use a separated message"""
+
+
+__revision__.lower(); # [unnecessary-semicolon]
+
+list() and tuple() # [expression-not-assigned]
+
+def to_be():
+ """return 42"""
+ return "42"
+
+ANSWER = to_be() # ok
+ANSWER == to_be() # [expression-not-assigned]
+
+to_be() or not to_be() # [expression-not-assigned]
+to_be().title # [expression-not-assigned]
+
+GOOD_ATTRIBUTE_DOCSTRING = 42
+"""Module level attribute docstring is fine. """
+
+class ClassLevelAttributeTest(object):
+ """ test attribute docstrings. """
+
+ good_attribute_docstring = 24
+ """ class level attribute docstring is fine either. """
+ second_good_attribute_docstring = 42
+ # Comments are good.
+
+ # empty lines are good, too.
+ """ Still a valid class level attribute docstring. """
+
+ def __init__(self):
+ self.attr = 42
+ """ Good attribute docstring """
+ attr = 24
+ """ Still a good __init__ level attribute docstring. """
+ val = 0
+ for val in range(42):
+ val += attr
+ # +1:[pointless-string-statement]
+ """ Invalid attribute docstring """
+ self.val = val
+
+ def test(self):
+ """ invalid attribute docstrings here. """
+ self.val = 42
+ # +1:[pointless-string-statement]
+ """ this is an invalid attribute docstring. """
+
+
+def ellipsis():
+ """Test that an Ellipsis as a body does not trigger the error"""
+ ...
+
+
+class EllipsisBody:
+ """Test that an Ellipsis as a body does not trigger the error"""
+ ...
diff --git a/tests/functional/s/statement_without_effect.txt b/tests/functional/s/statement_without_effect.txt
new file mode 100644
index 000000000..bda6eaea9
--- /dev/null
+++ b/tests/functional/s/statement_without_effect.txt
@@ -0,0 +1,60 @@
+pointless-string-statement:5::String statement has no effect
+pointless-statement:6::"""Statement seems to have no effect
+""
+"
+pointless-statement:8::"""Statement seems to have no effect
+""
+"
+pointless-statement:9::Statement seems to have no effect
+pointless-statement:11::Statement seems to have no effect
+pointless-statement:12::"""Statement seems to have no effect
+""
+"
+pointless-statement:15::Statement seems to have no effect
+pointless-string-statement:15::"""String statement has no effect
+""
+"
+unnecessary-semicolon:17::"""Unnecessary semicolon
+""
+"
+pointless-string-statement:18::String statement has no effect
+unnecessary-semicolon:18::"""Unnecessary semicolon
+""
+"
+expression-not-assigned:19::"""Expression """"list() and tuple()"""" is assigned to nothing
+""
+"
+expression-not-assigned:20::"""Expression """"list() and tuple()"""" is assigned to nothing
+""
+"
+unnecessary-semicolon:21::Unnecessary semicolon
+expression-not-assigned:23::"Expression ""list() and tuple()"" is assigned to nothing"
+expression-not-assigned:26::"""Expression """"ANSWER == to_be()"""" is assigned to nothing
+""
+"
+expression-not-assigned:27::"""Expression """"ANSWER == to_be()"""" is assigned to nothing
+""
+"
+expression-not-assigned:28::"""Expression """"to_be() or not to_be()"""" is assigned to nothing
+""
+"
+expression-not-assigned:29::"""Expression """"to_be() or not to_be()"""" is assigned to nothing
+""
+"
+expression-not-assigned:30::"Expression ""ANSWER == to_be()"" is assigned to nothing"
+expression-not-assigned:32::"Expression ""to_be() or not to_be()"" is assigned to nothing"
+expression-not-assigned:33::"Expression ""to_be().title"" is assigned to nothing"
+pointless-string-statement:54:ClassLevelAttributeTest.__init__:"""String statement has no effect
+""
+"
+pointless-string-statement:55:ClassLevelAttributeTest.__init__:"""String statement has no effect
+""
+"
+pointless-string-statement:58:ClassLevelAttributeTest.__init__:String statement has no effect
+pointless-string-statement:61:ClassLevelAttributeTest.test:"""String statement has no effect
+""
+"
+pointless-string-statement:62:ClassLevelAttributeTest.test:"""String statement has no effect
+""
+"
+pointless-string-statement:65:ClassLevelAttributeTest.test:String statement has no effect
diff --git a/tests/functional/s/statement_without_effect_py36.py b/tests/functional/s/statement_without_effect_py36.py
new file mode 100644
index 000000000..59745ce2b
--- /dev/null
+++ b/tests/functional/s/statement_without_effect_py36.py
@@ -0,0 +1,18 @@
+"""Test for statements without effects."""
+# pylint: disable=too-few-public-methods, useless-object-inheritance
+
+
+class ClassLevelAttributeTest(object):
+ """ test attribute docstrings. """
+
+ some_variable: int = 42
+ """Data docstring"""
+
+ some_other_variable: int = 42
+ """Data docstring"""
+
+ def func(self):
+ """Some Empty Docstring"""
+
+ # +1: [pointless-string-statement]
+ """useless"""
diff --git a/tests/functional/s/statement_without_effect_py36.rc b/tests/functional/s/statement_without_effect_py36.rc
new file mode 100644
index 000000000..0ba2b6333
--- /dev/null
+++ b/tests/functional/s/statement_without_effect_py36.rc
@@ -0,0 +1,2 @@
+[testoptions]
+min_pyver=3.6
diff --git a/tests/functional/s/statement_without_effect_py36.txt b/tests/functional/s/statement_without_effect_py36.txt
new file mode 100644
index 000000000..6b782923b
--- /dev/null
+++ b/tests/functional/s/statement_without_effect_py36.txt
@@ -0,0 +1 @@
+pointless-string-statement:18:ClassLevelAttributeTest:String statement has no effect \ No newline at end of file
diff --git a/tests/functional/s/stop_iteration_inside_generator.py b/tests/functional/s/stop_iteration_inside_generator.py
new file mode 100644
index 000000000..a51f2d3e7
--- /dev/null
+++ b/tests/functional/s/stop_iteration_inside_generator.py
@@ -0,0 +1,129 @@
+"""
+Test that no StopIteration is raised inside a generator
+"""
+# pylint: disable=missing-docstring,invalid-name,import-error, try-except-raise, wrong-import-position
+import asyncio
+
+class RebornStopIteration(StopIteration):
+ """
+ A class inheriting from StopIteration exception
+ """
+
+# This one is ok
+def gen_ok():
+ yield 1
+ yield 2
+ yield 3
+
+# pylint should warn about this one
+# because of a direct raising of StopIteration inside generator
+def gen_stopiter():
+ yield 1
+ yield 2
+ yield 3
+ raise StopIteration # [stop-iteration-return]
+
+# pylint should warn about this one
+# because of a direct raising of an exception inheriting from StopIteration inside generator
+def gen_stopiterchild():
+ yield 1
+ yield 2
+ yield 3
+ raise RebornStopIteration # [stop-iteration-return]
+
+# pylint should warn here
+# because of the possibility that next raises a StopIteration exception
+def gen_next_raises_stopiter():
+ g = gen_ok()
+ while True:
+ yield next(g) # [stop-iteration-return]
+
+# This one is the same as gen_next_raises_stopiter
+# but is ok because the next function is inside
+# a try/except block handling StopIteration
+def gen_next_inside_try_except():
+ g = gen_ok()
+ while True:
+ try:
+ yield next(g)
+ except StopIteration:
+ return
+
+# This one is the same as gen_next_inside_try_except
+# but is not ok because the next function is inside
+# a try/except block that don't handle StopIteration
+def gen_next_inside_wrong_try_except():
+ g = gen_ok()
+ while True:
+ try:
+ yield next(g) # [stop-iteration-return]
+ except ValueError:
+ return
+
+# This one is the same as gen_next_inside_try_except
+# but is not ok because the next function is inside
+# a try/except block that handle StopIteration but reraise it
+def gen_next_inside_wrong_try_except2():
+ g = gen_ok()
+ while True:
+ try:
+ yield next(g)
+ except StopIteration:
+ raise StopIteration # [stop-iteration-return]
+
+# Those two last are ok
+def gen_in_for():
+ for el in gen_ok():
+ yield el
+
+def gen_yield_from():
+ yield from gen_ok()
+
+
+def gen_dont_crash_on_no_exception():
+ g = gen_ok()
+ while True:
+ try:
+ yield next(g) # [stop-iteration-return]
+ except ValueError:
+ raise
+
+
+def gen_dont_crash_on_uninferable():
+ # https://github.com/PyCQA/pylint/issues/1779
+ yield from iter()
+ raise asyncio.TimeoutError()
+
+
+# https://github.com/PyCQA/pylint/issues/1830
+def gen_next_with_sentinel():
+ yield next([], 42) # No bad return
+
+
+from itertools import count
+
+# https://github.com/PyCQA/pylint/issues/2158
+def generator_using_next():
+ counter = count()
+ number = next(counter)
+ yield number * 2
+
+
+# pylint: disable=no-self-use,too-few-public-methods
+class SomeClassWithNext:
+ def next(self):
+ return iter([1, 2, 3])
+ def some_gen(self):
+ for value in self.next():
+ yield value
+
+
+SomeClassWithNext().some_gen()
+
+
+def something_invalid():
+ raise Exception('cannot iterate this')
+
+
+def invalid_object_passed_to_next():
+ yield next(something_invalid()) # [stop-iteration-return]
diff --git a/tests/functional/s/stop_iteration_inside_generator.rc b/tests/functional/s/stop_iteration_inside_generator.rc
new file mode 100644
index 000000000..c093be204
--- /dev/null
+++ b/tests/functional/s/stop_iteration_inside_generator.rc
@@ -0,0 +1,2 @@
+[testoptions]
+min_pyver=3.0
diff --git a/tests/functional/s/stop_iteration_inside_generator.txt b/tests/functional/s/stop_iteration_inside_generator.txt
new file mode 100644
index 000000000..107d563b6
--- /dev/null
+++ b/tests/functional/s/stop_iteration_inside_generator.txt
@@ -0,0 +1,7 @@
+stop-iteration-return:24:gen_stopiter:Do not raise StopIteration in generator, use return statement instead
+stop-iteration-return:32:gen_stopiterchild:Do not raise StopIteration in generator, use return statement instead
+stop-iteration-return:39:gen_next_raises_stopiter:Do not raise StopIteration in generator, use return statement instead
+stop-iteration-return:59:gen_next_inside_wrong_try_except:Do not raise StopIteration in generator, use return statement instead
+stop-iteration-return:72:gen_next_inside_wrong_try_except2:Do not raise StopIteration in generator, use return statement instead
+stop-iteration-return:87:gen_dont_crash_on_no_exception:Do not raise StopIteration in generator, use return statement instead
+stop-iteration-return:129:invalid_object_passed_to_next:Do not raise StopIteration in generator, use return statement instead
diff --git a/tests/functional/s/string_formatting.py b/tests/functional/s/string_formatting.py
new file mode 100644
index 000000000..7e60d9fd9
--- /dev/null
+++ b/tests/functional/s/string_formatting.py
@@ -0,0 +1,188 @@
+"""test for Python 3 string formatting error
+"""
+# pylint: disable=too-few-public-methods, import-error, unused-argument, line-too-long, no-absolute-import, useless-object-inheritance
+import os
+from missing import Missing
+
+__revision__ = 1
+
+class Custom(object):
+ """ Has a __getattr__ """
+ def __getattr__(self, _):
+ return self
+
+class Test(object):
+ """ test format attribute access """
+ custom = Custom()
+ ids = [1, 2, 3, [4, 5, 6]]
+
+class Getitem(object):
+ """ test custom getitem for lookup access """
+ def __getitem__(self, index):
+ return 42
+
+class ReturnYes(object):
+ """ can't be properly infered """
+ missing = Missing()
+
+def log(message, message_type="error"):
+ """ Test """
+ return message
+
+def print_good():
+ """ Good format strings """
+ "{0} {1}".format(1, 2)
+ "{0!r:20}".format("Hello")
+ "{!r:20}".format("Hello")
+ "{a!r:20}".format(a="Hello")
+ "{pid}".format(pid=os.getpid())
+ str("{}").format(2)
+ "{0.missing.length}".format(ReturnYes())
+ "{1.missing.length}".format(ReturnYes())
+ "{a.ids[3][1]}".format(a=Test())
+ "{a[0][0]}".format(a=[[1]])
+ "{[0][0]}".format({0: {0: 1}})
+ "{a.test}".format(a=Custom())
+ "{a.__len__}".format(a=[])
+ "{a.ids.__len__}".format(a=Test())
+ "{a[0]}".format(a=Getitem())
+ "{a[0][0]}".format(a=[Getitem()])
+ "{[0][0]}".format(["test"])
+ # these are skipped
+ "{0} {1}".format(*[1, 2])
+ "{a} {b}".format(**{'a': 1, 'b': 2})
+ "{a}".format(a=Missing())
+
+def pprint_bad():
+ """Test string format """
+ "{{}}".format(1) # [too-many-format-args]
+ "{} {".format() # [bad-format-string]
+ "{} }".format() # [bad-format-string]
+ "{0} {}".format(1, 2) # [format-combined-specification]
+ # +1: [missing-format-argument-key, unused-format-string-argument]
+ "{a} {b}".format(a=1, c=2)
+ "{} {a}".format(1, 2) # [missing-format-argument-key]
+ "{} {}".format(1) # [too-few-format-args]
+ "{} {}".format(1, 2, 3) # [too-many-format-args]
+ # +1: [missing-format-argument-key,missing-format-argument-key,missing-format-argument-key]
+ "{a} {b} {c}".format()
+ "{} {}".format(a=1, b=2) # [too-few-format-args]
+ # +1: [missing-format-argument-key, missing-format-argument-key]
+ "{a} {b}".format(1, 2)
+ "{0} {1} {a}".format(1, 2, 3) # [missing-format-argument-key]
+ # +1: [missing-format-attribute]
+ "{a.ids.__len__.length}".format(a=Test())
+ "{a.ids[3][400]}".format(a=Test()) # [invalid-format-index]
+ "{a.ids[3]['string']}".format(a=Test()) # [invalid-format-index]
+ "{[0][1]}".format(["a"]) # [invalid-format-index]
+ "{[0][0]}".format(((1, ))) # [invalid-format-index]
+ # +1: [missing-format-argument-key, unused-format-string-argument]
+ "{b[0]}".format(a=23)
+ "{a[0]}".format(a=object) # [invalid-format-index]
+ log("{}".format(2, "info")) # [too-many-format-args]
+ "{0.missing}".format(2) # [missing-format-attribute]
+ "{0} {1} {2}".format(1, 2) # [too-few-format-args]
+ "{0} {1}".format(1, 2, 3) # [too-many-format-args]
+ "{0} {a}".format(a=4) # [too-few-format-args]
+ "{[0]} {}".format([4]) # [too-few-format-args]
+ "{[0]} {}".format([4], 5, 6) # [too-many-format-args]
+
+def good_issue288(*args, **kwargs):
+ """ Test that using kwargs does not emit a false
+ positive.
+ """
+ 'Hello John Doe {0[0]}'.format(args)
+ 'Hello {0[name]}'.format(kwargs)
+
+def good_issue287():
+ """ Test that the string format checker skips
+ format nodes which don't have a string as a parent
+ (but a subscript, name etc).
+ """
+ name = 'qwerty'
+ ret = {'comment': ''}
+ ret['comment'] = 'MySQL grant {0} is set to be revoked'
+ ret['comment'] = ret['comment'].format(name)
+ return ret, name
+
+def nested_issue294():
+ """ Test nested format fields. """
+ '{0:>{1}}'.format(42, 24)
+ '{0:{a[1]}} {a}'.format(1, a=[1, 2])
+ '{:>{}}'.format(42, 24)
+ '{0:>{1}}'.format(42) # [too-few-format-args]
+ '{0:>{1}}'.format(42, 24, 54) # [too-many-format-args]
+ '{0:{a[1]}}'.format(1) # [missing-format-argument-key]
+ '{0:{a.x}}'.format(1, a=2) # [missing-format-attribute]
+
+def issue310():
+ """ Test a regression using duplicate manual position arguments. """
+ '{0} {1} {0}'.format(1, 2)
+ '{0} {1} {0}'.format(1) # [too-few-format-args]
+
+def issue322():
+ """ Test a regression using mixed manual position arguments
+ and attribute access arguments.
+ """
+ '{0}{1[FOO]}'.format(123, {'FOO': 456})
+ '{0}{1[FOO]}'.format(123, {'FOO': 456}, 321) # [too-many-format-args]
+ '{0}{1[FOO]}'.format(123) # [too-few-format-args]
+
+def issue338():
+ """
+ Check that using a namedtuple subclass doesn't crash when
+ trying to infer EmptyNodes (resulted after mocking the
+ members of namedtuples).
+ """
+ from collections import namedtuple
+
+ class Crash(namedtuple("C", "foo bar")):
+ """ Looking for attributes in __str__ will crash,
+ because EmptyNodes can't be infered.
+ """
+ def __str__(self):
+ return "{0.foo}: {0.bar}".format(self)
+ return Crash
+
+def issue351():
+ """
+ Check that the format method can be assigned to a variable, ie:
+ """
+ fmt = 'test {} {}'.format
+ fmt('arg1') # [too-few-format-args]
+ fmt('arg1', 'arg2')
+ fmt('arg1', 'arg2', 'arg3') # [too-many-format-args]
+
+def issue373():
+ """
+ Ignore any object coming from an argument.
+ """
+ class SomeClass(object):
+ """ empty docstring. """
+ def __init__(self, opts=None):
+ self.opts = opts
+
+ def dunc(self, arg):
+ """Don't try to analyze this."""
+ return "A{0}{1}".format(arg, self.opts)
+
+ def func(self):
+ """Don't try to analyze the following string."""
+ return 'AAA{0[iface]}BBB{0[port]}'.format(self.opts)
+
+ return SomeClass
+
+def issue_463():
+ """
+ Mix positional arguments, `{0}`, with positional
+ arguments with attribute access, `{0.__x__}`.
+ """
+ data = "{0.__class__.__name__}: {0}".format(42)
+ data2 = "{0[0]}: {0}".format([1])
+ return (data, data2)
+
+
+def avoid_empty_attribute():
+ """The following string is invalid, avoid crashing."""
+
+ return "There are {.:2f} undiscovered errors.".format(1) # [bad-format-string]
diff --git a/tests/functional/s/string_formatting.txt b/tests/functional/s/string_formatting.txt
new file mode 100644
index 000000000..9801de1a7
--- /dev/null
+++ b/tests/functional/s/string_formatting.txt
@@ -0,0 +1,41 @@
+too-many-format-args:58:pprint_bad:Too many arguments for format string
+bad-format-string:59:pprint_bad:Invalid format string
+bad-format-string:60:pprint_bad:Invalid format string
+format-combined-specification:61:pprint_bad:Format string contains both automatic field numbering and manual field specification
+missing-format-argument-key:63:pprint_bad:Missing keyword argument 'b' for format string
+unused-format-string-argument:63:pprint_bad:Unused format argument 'c'
+missing-format-argument-key:64:pprint_bad:Missing keyword argument 'a' for format string
+too-few-format-args:65:pprint_bad:Not enough arguments for format string
+too-many-format-args:66:pprint_bad:Too many arguments for format string
+missing-format-argument-key:68:pprint_bad:Missing keyword argument 'a' for format string
+missing-format-argument-key:68:pprint_bad:Missing keyword argument 'b' for format string
+missing-format-argument-key:68:pprint_bad:Missing keyword argument 'c' for format string
+too-few-format-args:69:pprint_bad:Not enough arguments for format string
+missing-format-argument-key:71:pprint_bad:Missing keyword argument 'a' for format string
+missing-format-argument-key:71:pprint_bad:Missing keyword argument 'b' for format string
+missing-format-argument-key:72:pprint_bad:Missing keyword argument 'a' for format string
+missing-format-attribute:74:pprint_bad:Missing format attribute 'length' in format specifier 'a.ids.__len__.length'
+invalid-format-index:75:pprint_bad:Using invalid lookup key 400 in format specifier 'a.ids[3][400]'
+invalid-format-index:76:pprint_bad:"Using invalid lookup key ""'string'"" in format specifier 'a.ids[3][""\'string\'""]'"
+invalid-format-index:77:pprint_bad:Using invalid lookup key 1 in format specifier '0[0][1]'
+invalid-format-index:78:pprint_bad:Using invalid lookup key 0 in format specifier '0[0][0]'
+missing-format-argument-key:80:pprint_bad:Missing keyword argument 'b' for format string
+unused-format-string-argument:80:pprint_bad:Unused format argument 'a'
+invalid-format-index:81:pprint_bad:Using invalid lookup key 0 in format specifier 'a[0]'
+too-many-format-args:82:pprint_bad:Too many arguments for format string
+missing-format-attribute:83:pprint_bad:Missing format attribute 'missing' in format specifier '0.missing'
+too-few-format-args:84:pprint_bad:Not enough arguments for format string
+too-many-format-args:85:pprint_bad:Too many arguments for format string
+too-few-format-args:86:pprint_bad:Not enough arguments for format string
+too-few-format-args:87:pprint_bad:Not enough arguments for format string
+too-many-format-args:88:pprint_bad:Too many arguments for format string
+too-few-format-args:113:nested_issue294:Not enough arguments for format string
+too-many-format-args:114:nested_issue294:Too many arguments for format string
+missing-format-argument-key:115:nested_issue294:Missing keyword argument 'a' for format string
+missing-format-attribute:116:nested_issue294:Missing format attribute 'x' in format specifier 'a.x'
+too-few-format-args:121:issue310:Not enough arguments for format string
+too-many-format-args:128:issue322:Too many arguments for format string
+too-few-format-args:129:issue322:Not enough arguments for format string
+too-few-format-args:152:issue351:Not enough arguments for format string
+too-many-format-args:154:issue351:Too many arguments for format string
+bad-format-string:188:avoid_empty_attribute:Invalid format string \ No newline at end of file
diff --git a/tests/functional/s/string_formatting_disable.py b/tests/functional/s/string_formatting_disable.py
new file mode 100644
index 000000000..096c84734
--- /dev/null
+++ b/tests/functional/s/string_formatting_disable.py
@@ -0,0 +1 @@
+"a {} {".format(1) # [bad-format-string] \ No newline at end of file
diff --git a/tests/functional/s/string_formatting_disable.rc b/tests/functional/s/string_formatting_disable.rc
new file mode 100644
index 000000000..0193339de
--- /dev/null
+++ b/tests/functional/s/string_formatting_disable.rc
@@ -0,0 +1,3 @@
+[Messages Control]
+disable=all
+enable=bad-format-string
diff --git a/tests/functional/s/string_formatting_disable.txt b/tests/functional/s/string_formatting_disable.txt
new file mode 100644
index 000000000..2c8f6db59
--- /dev/null
+++ b/tests/functional/s/string_formatting_disable.txt
@@ -0,0 +1 @@
+bad-format-string:1::Invalid format string \ No newline at end of file
diff --git a/tests/functional/s/string_formatting_failed_inference.py b/tests/functional/s/string_formatting_failed_inference.py
new file mode 100644
index 000000000..c5add58c8
--- /dev/null
+++ b/tests/functional/s/string_formatting_failed_inference.py
@@ -0,0 +1,4 @@
+""" Testing string format with a failed inference. This should not crash. """
+# pylint: disable=using-constant-test
+import collections
+"{dict[0]}".format(dict=collections.defaultdict(int))
diff --git a/tests/functional/s/string_formatting_failed_inference_py35.py b/tests/functional/s/string_formatting_failed_inference_py35.py
new file mode 100644
index 000000000..a511ff80e
--- /dev/null
+++ b/tests/functional/s/string_formatting_failed_inference_py35.py
@@ -0,0 +1,6 @@
+""" Testing string format with a failed inference. This should not crash. """
+# pylint: disable=using-constant-test
+import collections
+"{dict[0]}".format(dict=collections.defaultdict(int))
+
+COMMENT = "message %s %s %s" % (0, *(1 if "cond" else 2,) * 2)
diff --git a/tests/functional/s/string_formatting_failed_inference_py35.rc b/tests/functional/s/string_formatting_failed_inference_py35.rc
new file mode 100644
index 000000000..71de8b630
--- /dev/null
+++ b/tests/functional/s/string_formatting_failed_inference_py35.rc
@@ -0,0 +1,2 @@
+[testoptions]
+min_pyver=3.5
diff --git a/tests/functional/s/string_formatting_py27.py b/tests/functional/s/string_formatting_py27.py
new file mode 100644
index 000000000..eab042c07
--- /dev/null
+++ b/tests/functional/s/string_formatting_py27.py
@@ -0,0 +1,22 @@
+"""test for Python 2 string formatting error
+"""
+from __future__ import unicode_literals
+# pylint: disable=line-too-long
+__revision__ = 1
+
+def pprint_bad():
+ """Test string format """
+ "{{}}".format(1) # [too-many-format-args]
+ "{} {".format() # [bad-format-string]
+ "{} }".format() # [bad-format-string]
+ "{0} {}".format(1, 2) # [format-combined-specification]
+ # +1: [missing-format-argument-key, unused-format-string-argument]
+ "{a} {b}".format(a=1, c=2)
+ "{} {a}".format(1, 2) # [missing-format-argument-key]
+ "{} {}".format(1) # [too-few-format-args]
+ "{} {}".format(1, 2, 3) # [too-many-format-args]
+ # +1: [missing-format-argument-key,missing-format-argument-key,missing-format-argument-key]
+ "{a} {b} {c}".format()
+ "{} {}".format(a=1, b=2) # [too-few-format-args]
+ # +1: [missing-format-argument-key, missing-format-argument-key]
+ "{a} {b}".format(1, 2)
diff --git a/tests/functional/s/string_formatting_py27.rc b/tests/functional/s/string_formatting_py27.rc
new file mode 100644
index 000000000..80170b777
--- /dev/null
+++ b/tests/functional/s/string_formatting_py27.rc
@@ -0,0 +1,3 @@
+[testoptions]
+min_pyver=2.7
+max_pyver=3.0 \ No newline at end of file
diff --git a/tests/functional/s/string_formatting_py27.txt b/tests/functional/s/string_formatting_py27.txt
new file mode 100644
index 000000000..47f21ded0
--- /dev/null
+++ b/tests/functional/s/string_formatting_py27.txt
@@ -0,0 +1,15 @@
+too-many-format-args:9:pprint_bad:Too many arguments for format string
+bad-format-string:10:pprint_bad:Invalid format string
+bad-format-string:11:pprint_bad:Invalid format string
+format-combined-specification:12:pprint_bad:Format string contains both automatic field numbering and manual field specification
+missing-format-argument-key:14:pprint_bad:Missing keyword argument u'b' for format string
+unused-format-string-argument:14:pprint_bad:Unused format argument 'c'
+missing-format-argument-key:15:pprint_bad:Missing keyword argument u'a' for format string
+too-few-format-args:16:pprint_bad:Not enough arguments for format string
+too-many-format-args:17:pprint_bad:Too many arguments for format string
+missing-format-argument-key:19:pprint_bad:Missing keyword argument u'a' for format string
+missing-format-argument-key:19:pprint_bad:Missing keyword argument u'b' for format string
+missing-format-argument-key:19:pprint_bad:Missing keyword argument u'c' for format string
+too-few-format-args:20:pprint_bad:Not enough arguments for format string
+missing-format-argument-key:22:pprint_bad:Missing keyword argument u'a' for format string
+missing-format-argument-key:22:pprint_bad:Missing keyword argument u'b' for format string
diff --git a/tests/functional/s/string_formatting_py3.py b/tests/functional/s/string_formatting_py3.py
new file mode 100644
index 000000000..c27e9719e
--- /dev/null
+++ b/tests/functional/s/string_formatting_py3.py
@@ -0,0 +1,21 @@
+# pylint: disable=missing-docstring,import-error
+
+
+def issue_957_good():
+ meat = ['spam', 'ham']
+ print('%s%s%s' % ('eggs', *meat))
+
+
+def issue_957_bad1():
+ meat = ['spam', 'ham', 'monty python']
+ print('%s%s%s' % ('eggs', *meat)) # [too-many-format-args]
+
+
+def issue_957_bad2():
+ meat = ['spam']
+ print('%s%s%s' % ('eggs', *meat)) # [too-few-format-args]
+
+
+def issue_957_uninferable():
+ from butchery import meat
+ print('%s%s%s' % ('eggs', *meat))
diff --git a/tests/functional/s/string_formatting_py3.rc b/tests/functional/s/string_formatting_py3.rc
new file mode 100644
index 000000000..a2ab06c50
--- /dev/null
+++ b/tests/functional/s/string_formatting_py3.rc
@@ -0,0 +1,2 @@
+[testoptions]
+min_pyver=3.0 \ No newline at end of file
diff --git a/tests/functional/s/string_formatting_py3.txt b/tests/functional/s/string_formatting_py3.txt
new file mode 100644
index 000000000..45975899a
--- /dev/null
+++ b/tests/functional/s/string_formatting_py3.txt
@@ -0,0 +1,2 @@
+too-many-format-args:11:issue_957_bad1:Too many arguments for format string
+too-few-format-args:16:issue_957_bad2:Not enough arguments for format string
diff --git a/tests/functional/s/subprocess_popen_preexec_fn.py b/tests/functional/s/subprocess_popen_preexec_fn.py
new file mode 100644
index 000000000..e785abc76
--- /dev/null
+++ b/tests/functional/s/subprocess_popen_preexec_fn.py
@@ -0,0 +1,11 @@
+# pylint: disable=blacklisted-name,no-value-for-parameter,missing-docstring
+
+import subprocess
+
+def foo():
+ pass
+
+
+subprocess.Popen(preexec_fn=foo) # [subprocess-popen-preexec-fn]
+
+subprocess.Popen()
diff --git a/tests/functional/s/subprocess_popen_preexec_fn.txt b/tests/functional/s/subprocess_popen_preexec_fn.txt
new file mode 100644
index 000000000..cd237a442
--- /dev/null
+++ b/tests/functional/s/subprocess_popen_preexec_fn.txt
@@ -0,0 +1 @@
+subprocess-popen-preexec-fn:9::Using preexec_fn keyword which may be unsafe in the presence of threads
diff --git a/tests/functional/s/subprocess_run_check35.py b/tests/functional/s/subprocess_run_check35.py
new file mode 100644
index 000000000..f123fb20d
--- /dev/null
+++ b/tests/functional/s/subprocess_run_check35.py
@@ -0,0 +1,6 @@
+# pylint: disable=blacklisted-name,no-value-for-parameter,missing-docstring
+
+import subprocess
+
+
+subprocess.run() # [subprocess-run-check]
diff --git a/tests/functional/s/subprocess_run_check35.rc b/tests/functional/s/subprocess_run_check35.rc
new file mode 100644
index 000000000..71de8b630
--- /dev/null
+++ b/tests/functional/s/subprocess_run_check35.rc
@@ -0,0 +1,2 @@
+[testoptions]
+min_pyver=3.5
diff --git a/tests/functional/s/subprocess_run_check35.txt b/tests/functional/s/subprocess_run_check35.txt
new file mode 100644
index 000000000..31e5dbfc1
--- /dev/null
+++ b/tests/functional/s/subprocess_run_check35.txt
@@ -0,0 +1 @@
+subprocess-run-check:6::Using subprocess.run without explicitly set `check` is not recommended.
diff --git a/tests/functional/s/super_checks.py b/tests/functional/s/super_checks.py
new file mode 100644
index 000000000..3888488fe
--- /dev/null
+++ b/tests/functional/s/super_checks.py
@@ -0,0 +1,125 @@
+# pylint: disable=too-few-public-methods,import-error, no-absolute-import,missing-docstring, useless-object-inheritance
+# pylint: disable=useless-super-delegation,wrong-import-position,invalid-name, wrong-import-order
+
+from unknown import Missing
+
+class Aaaa:
+ """old style"""
+ def hop(self):
+ """hop"""
+ super(Aaaa, self).hop() # >=3.0:[no-member]
+
+ def __init__(self):
+ super(Aaaa, self).__init__()
+
+class NewAaaa(object):
+ """old style"""
+ def hop(self):
+ """hop"""
+ super(NewAaaa, self).hop() # [no-member]
+
+ def __init__(self):
+ super(Aaaa, self).__init__() # [bad-super-call]
+
+class Py3kAaaa(NewAaaa):
+ """new style"""
+ def __init__(self):
+ super().__init__() # <3.0:[missing-super-argument]
+
+class Py3kWrongSuper(Py3kAaaa):
+ """new style"""
+ def __init__(self):
+ super(NewAaaa, self).__init__() # [bad-super-call]
+
+class WrongNameRegression(Py3kAaaa):
+ """ test a regression with the message """
+ def __init__(self):
+ super(Missing, self).__init__() # [bad-super-call]
+
+class Getattr(object):
+ """ crash """
+ name = NewAaaa
+
+class CrashSuper(object):
+ """ test a crash with this checker """
+ def __init__(self):
+ super(Getattr.name, self).__init__() # [bad-super-call]
+
+class Empty(object):
+ """Just an empty class."""
+
+class SuperDifferentScope(object):
+ """Don'emit bad-super-call when the super call is in another scope.
+ For reference, see https://bitbucket.org/logilab/pylint/issue/403.
+ """
+ @staticmethod
+ def test():
+ """Test that a bad-super-call is not emitted for this case."""
+ class FalsePositive(Empty):
+ """The following super is in another scope than `test`."""
+ def __init__(self, arg):
+ super(FalsePositive, self).__init__(arg)
+ super(object, 1).__init__() # [bad-super-call]
+
+
+class UnknownBases(Missing):
+ """Don't emit if we don't know all the bases."""
+ def __init__(self):
+ super(UnknownBases, self).__init__()
+ super(UnknownBases, self).test()
+ super(Missing, self).test() # [bad-super-call]
+
+
+# Test that we are detecting proper super errors.
+
+class BaseClass(object):
+
+ not_a_method = 42
+
+ def function(self, param):
+ return param + self.not_a_method
+
+ def __getattr__(self, attr):
+ return attr
+
+
+class InvalidSuperChecks(BaseClass):
+
+ def __init__(self):
+ super(InvalidSuperChecks, self).not_a_method() # [not-callable]
+ super(InvalidSuperChecks, self).attribute_error() # [no-member]
+ super(InvalidSuperChecks, self).function(42)
+ super(InvalidSuperChecks, self).function() # [no-value-for-parameter]
+ super(InvalidSuperChecks, self).function(42, 24, 24) # [too-many-function-args]
+ # +1: [unexpected-keyword-arg,no-value-for-parameter]
+ super(InvalidSuperChecks, self).function(lala=42)
+ # Even though BaseClass has a __getattr__, that won't
+ # be called.
+ super(InvalidSuperChecks, self).attribute_error() # [no-member]
+
+
+
+# Regression for PyCQA/pylint/issues/773
+import subprocess
+
+# The problem was related to astroid not filtering statements
+# at scope level properly, basically not doing strong updates.
+try:
+ TimeoutExpired = subprocess.TimeoutExpired
+except AttributeError:
+ class TimeoutExpired(subprocess.CalledProcessError):
+ def __init__(self):
+ returncode = -1
+ self.timeout = -1
+ super(TimeoutExpired, self).__init__(returncode)
+
+
+class SuperWithType(object):
+ """type(self) may lead to recursion loop in derived classes"""
+ def __init__(self):
+ super(type(self), self).__init__() # [bad-super-call]
+
+class SuperWithSelfClass(object):
+ """self.__class__ may lead to recursion loop in derived classes"""
+ def __init__(self):
+ super(self.__class__, self).__init__() # [bad-super-call]
diff --git a/tests/functional/s/super_checks.txt b/tests/functional/s/super_checks.txt
new file mode 100644
index 000000000..4911a6c86
--- /dev/null
+++ b/tests/functional/s/super_checks.txt
@@ -0,0 +1,18 @@
+no-member:10:Aaaa.hop:Super of 'Aaaa' has no 'hop' member:INFERENCE
+no-member:19:NewAaaa.hop:Super of 'NewAaaa' has no 'hop' member:INFERENCE
+bad-super-call:22:NewAaaa.__init__:Bad first argument 'Aaaa' given to super()
+missing-super-argument:27:Py3kAaaa.__init__:Missing argument to super()
+bad-super-call:32:Py3kWrongSuper.__init__:Bad first argument 'NewAaaa' given to super()
+bad-super-call:37:WrongNameRegression.__init__:Bad first argument 'Missing' given to super()
+bad-super-call:46:CrashSuper.__init__:Bad first argument 'NewAaaa' given to super()
+bad-super-call:62:SuperDifferentScope.test:Bad first argument 'object' given to super()
+bad-super-call:70:UnknownBases.__init__:Bad first argument 'Missing' given to super()
+not-callable:89:InvalidSuperChecks.__init__:super(InvalidSuperChecks, self).not_a_method is not callable
+no-member:90:InvalidSuperChecks.__init__:Super of 'InvalidSuperChecks' has no 'attribute_error' member:INFERENCE
+no-value-for-parameter:92:InvalidSuperChecks.__init__:No value for argument 'param' in method call
+too-many-function-args:93:InvalidSuperChecks.__init__:Too many positional arguments for method call
+no-value-for-parameter:95:InvalidSuperChecks.__init__:No value for argument 'param' in method call
+unexpected-keyword-arg:95:InvalidSuperChecks.__init__:Unexpected keyword argument 'lala' in method call
+no-member:98:InvalidSuperChecks.__init__:Super of 'InvalidSuperChecks' has no 'attribute_error' member:INFERENCE
+bad-super-call:120:SuperWithType.__init__:Bad first argument 'type' given to super()
+bad-super-call:125:SuperWithSelfClass.__init__:Bad first argument 'self.__class__' given to super()
diff --git a/tests/functional/s/superfluous_parens.py b/tests/functional/s/superfluous_parens.py
new file mode 100644
index 000000000..13418cd78
--- /dev/null
+++ b/tests/functional/s/superfluous_parens.py
@@ -0,0 +1,19 @@
+"""Test the superfluous-parens warning."""
+from __future__ import print_function
+# pylint: disable=unneeded-not
+i = 3
+if (i == 5): # [superfluous-parens]
+ pass
+if not (i == 5): # [superfluous-parens]
+ pass
+if not (3 or 5):
+ pass
+for (x) in (1, 2, 3): # [superfluous-parens]
+ print(x)
+if (1) in (1, 2, 3): # [superfluous-parens]
+ pass
+if (1, 2) in (1, 2, 3):
+ pass
+DICT = {'a': 1, 'b': 2}
+del(DICT['b']) # [superfluous-parens]
+del DICT['a']
diff --git a/tests/functional/s/superfluous_parens.txt b/tests/functional/s/superfluous_parens.txt
new file mode 100644
index 000000000..57e1019c3
--- /dev/null
+++ b/tests/functional/s/superfluous_parens.txt
@@ -0,0 +1,5 @@
+superfluous-parens:5::Unnecessary parens after 'if' keyword
+superfluous-parens:7::Unnecessary parens after 'not' keyword
+superfluous-parens:11::Unnecessary parens after 'for' keyword
+superfluous-parens:13::Unnecessary parens after 'if' keyword
+superfluous-parens:18::Unnecessary parens after 'del' keyword
diff --git a/tests/functional/s/suspicious_str_strip_call.py b/tests/functional/s/suspicious_str_strip_call.py
new file mode 100644
index 000000000..bc3a27c27
--- /dev/null
+++ b/tests/functional/s/suspicious_str_strip_call.py
@@ -0,0 +1,10 @@
+"""Suspicious str.strip calls."""
+__revision__ = 1
+
+''.strip('yo')
+''.strip()
+
+u''.strip('http://') # [bad-str-strip-call]
+u''.lstrip('http://') # [bad-str-strip-call]
+b''.rstrip('http://') # [bad-str-strip-call]
+"some_sensible_string".strip(None) # Don't crash
diff --git a/tests/functional/s/suspicious_str_strip_call.rc b/tests/functional/s/suspicious_str_strip_call.rc
new file mode 100644
index 000000000..a65023393
--- /dev/null
+++ b/tests/functional/s/suspicious_str_strip_call.rc
@@ -0,0 +1,2 @@
+[testoptions]
+max_pyver=3.0
diff --git a/tests/functional/s/suspicious_str_strip_call.txt b/tests/functional/s/suspicious_str_strip_call.txt
new file mode 100644
index 000000000..ad714cc6b
--- /dev/null
+++ b/tests/functional/s/suspicious_str_strip_call.txt
@@ -0,0 +1,3 @@
+bad-str-strip-call:7::Suspicious argument in unicode.strip call
+bad-str-strip-call:8::Suspicious argument in unicode.lstrip call
+bad-str-strip-call:9::Suspicious argument in str.rstrip call
diff --git a/tests/functional/s/suspicious_str_strip_call_py3.py b/tests/functional/s/suspicious_str_strip_call_py3.py
new file mode 100644
index 000000000..e859f25f8
--- /dev/null
+++ b/tests/functional/s/suspicious_str_strip_call_py3.py
@@ -0,0 +1,9 @@
+"""Suspicious str.strip calls."""
+__revision__ = 1
+
+''.strip('yo')
+''.strip()
+
+u''.strip('http://') # [bad-str-strip-call]
+u''.lstrip('http://') # [bad-str-strip-call]
+b''.rstrip('http://') # [bad-str-strip-call]
diff --git a/tests/functional/s/suspicious_str_strip_call_py3.rc b/tests/functional/s/suspicious_str_strip_call_py3.rc
new file mode 100644
index 000000000..c093be204
--- /dev/null
+++ b/tests/functional/s/suspicious_str_strip_call_py3.rc
@@ -0,0 +1,2 @@
+[testoptions]
+min_pyver=3.0
diff --git a/tests/functional/s/suspicious_str_strip_call_py3.txt b/tests/functional/s/suspicious_str_strip_call_py3.txt
new file mode 100644
index 000000000..81f32cf4e
--- /dev/null
+++ b/tests/functional/s/suspicious_str_strip_call_py3.txt
@@ -0,0 +1,3 @@
+bad-str-strip-call:7::Suspicious argument in str.strip call
+bad-str-strip-call:8::Suspicious argument in str.lstrip call
+bad-str-strip-call:9::Suspicious argument in bytes.rstrip call
diff --git a/tests/functional/s/syntax_error.py b/tests/functional/s/syntax_error.py
new file mode 100644
index 000000000..c93df6b05
--- /dev/null
+++ b/tests/functional/s/syntax_error.py
@@ -0,0 +1 @@
+def toto # [syntax-error]
diff --git a/tests/functional/s/syntax_error.rc b/tests/functional/s/syntax_error.rc
new file mode 100644
index 000000000..58b5a9413
--- /dev/null
+++ b/tests/functional/s/syntax_error.rc
@@ -0,0 +1 @@
+[testoptions]
diff --git a/tests/functional/s/syntax_error.txt b/tests/functional/s/syntax_error.txt
new file mode 100644
index 000000000..f14ae39dd
--- /dev/null
+++ b/tests/functional/s/syntax_error.txt
@@ -0,0 +1 @@
+syntax-error:1::invalid syntax (<unknown>, line 1) \ No newline at end of file
diff --git a/tests/functional/s/syntax_error_jython.py b/tests/functional/s/syntax_error_jython.py
new file mode 100644
index 000000000..c93df6b05
--- /dev/null
+++ b/tests/functional/s/syntax_error_jython.py
@@ -0,0 +1 @@
+def toto # [syntax-error]
diff --git a/tests/functional/s/syntax_error_jython.rc b/tests/functional/s/syntax_error_jython.rc
new file mode 100644
index 000000000..29bd3facf
--- /dev/null
+++ b/tests/functional/s/syntax_error_jython.rc
@@ -0,0 +1,2 @@
+[testoptions]
+except_implementations=CPython, PyPy
diff --git a/tests/functional/s/syntax_error_jython.txt b/tests/functional/s/syntax_error_jython.txt
new file mode 100644
index 000000000..e532aece7
--- /dev/null
+++ b/tests/functional/s/syntax_error_jython.txt
@@ -0,0 +1 @@
+syntax-error:1::"mismatched input '\n\n\n\n' expecting LPAREN" \ No newline at end of file
diff --git a/tests/functional/s/sys_stream_regression_1004.py b/tests/functional/s/sys_stream_regression_1004.py
new file mode 100644
index 000000000..c0391859d
--- /dev/null
+++ b/tests/functional/s/sys_stream_regression_1004.py
@@ -0,0 +1,7 @@
+'''Regression for issue https://github.com/PyCQA/pylint/issues/1004'''
+# pylint: disable=missing-docstring, pointless-statement
+
+import sys
+sys.__stdout__.buffer.write('test')
+sys.__stdout__.buff # [no-member]
+sys.__stdout__.buffer.write1 # [no-member]
diff --git a/tests/functional/s/sys_stream_regression_1004.rc b/tests/functional/s/sys_stream_regression_1004.rc
new file mode 100644
index 000000000..182fae81c
--- /dev/null
+++ b/tests/functional/s/sys_stream_regression_1004.rc
@@ -0,0 +1,3 @@
+[testoptions]
+min_pyver=3.5
+except_implementations=PyPy \ No newline at end of file
diff --git a/tests/functional/s/sys_stream_regression_1004.txt b/tests/functional/s/sys_stream_regression_1004.txt
new file mode 100644
index 000000000..b68af46fa
--- /dev/null
+++ b/tests/functional/s/sys_stream_regression_1004.txt
@@ -0,0 +1,2 @@
+no-member:6::Instance of 'TextIOWrapper' has no 'buff' member:INFERENCE
+no-member:7::Instance of 'BufferedWriter' has no 'write1' member; maybe 'write'?:INFERENCE \ No newline at end of file