summaryrefslogtreecommitdiff
path: root/tests/functional/s/super/super_checks.py
blob: 050fd3c81fa519f1611e9316fc59775827f4afd8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# pylint: disable=too-few-public-methods,import-error, missing-docstring
# pylint: disable=useless-super-delegation,wrong-import-position,invalid-name, wrong-import-order
# pylint: disable=super-with-arguments
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:
    """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__()

class WrongNameRegression(Py3kAaaa):
    """ test a regression with the message """
    def __init__(self):
        super(Missing, self).__init__()  # [bad-super-call]

class Getattr:
    """ crash """
    name = NewAaaa

class CrashSuper:
    """ test a crash with this checker """
    def __init__(self):
        super(Getattr.name, self).__init__()  # [bad-super-call]

class Empty:
    """Just an empty class."""

class SuperDifferentScope:
    """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__()


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:

    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:
    """type(self) may lead to recursion loop in derived classes"""
    def __init__(self):
        super(type(self), self).__init__() # [bad-super-call]

class SuperWithSelfClass:
    """self.__class__ may lead to recursion loop in derived classes"""
    def __init__(self):
        super(self.__class__, self).__init__() # [bad-super-call]


# Reported in https://github.com/PyCQA/pylint/issues/2903
class Parent:
    def method(self):
        print()


class Child(Parent):
    def method(self):
        print("Child")
        super().method()

class Niece(Parent):
    def method(self):
        print("Niece")
        super().method()

class GrandChild(Child):
    def method(self):
        print("Grandchild")
        super(GrandChild, self).method()
        super(Child, self).method()
        super(Niece, self).method()  # [bad-super-call]


# Reported in https://github.com/PyCQA/pylint/issues/4922
class AlabamaCousin(Child, Niece):
    def method(self):
        print("AlabamaCousin")
        super(Child, self).method()