Fixes a crash when an __init__ method in a base class has been created by assignment rather than direct function definition. Closes #110853

authortmarek@google.com
changesetf2f6586d2400
branchstable
phasepublic
hiddenno
parent revision#2096899a1443 pylint-gui: Bind F5 to the run button. Closes #110839
child revision#2dc4a9def934 backport stable, #275c7b353f10 erroneous W0212 (access to protected member) on super call. Closes #115580
files modified by this revision
ChangeLog
checkers/classes.py
test/input/func_w0231.py
test/messages/func_w0231.txt
# HG changeset patch
# User tmarek@google.com
# Date 1352726554 -3600
# Mon Nov 12 14:22:34 2012 +0100
# Branch stable
# Node ID f2f6586d2400f80fab95c474f5123c081a44fa49
# Parent 2096899a1443bcbe3bb11dcb4d35975a4e16e45e
Fixes a crash when an __init__ method in a base class has been created by assignment rather than direct function definition. Closes #110853

diff --git a/ChangeLog b/ChangeLog
@@ -1,16 +1,20 @@
1  ChangeLog for PyLint
2  ====================
3 
4  --
5 +    * #110853: Fix a crash when an __init__ method in a base class has been
6 +      created by assignment rather than direct function definition. (patch by
7 +      Torsten Marek)
8 +
9      * #110838: fix pylint-gui crash when include-ids is activated (patch by
10        Omega Weapon)
11 
12      * #110839: bind <F5> to Run button in pylint-gui
13 
14 
diff --git a/checkers/classes.py b/checkers/classes.py
@@ -635,12 +635,12 @@
15      the queried method, and so that should/may be called from the method node
16      """
17      to_call = {}
18      for base_node in klass_node.ancestors(recurs=False):
19          try:
20 -            to_call[base_node] = base_node.local_attr(method)[-1]
21 -        except astng.NotFoundError:
22 +            to_call[base_node] = base_node.igetattr(method).next()
23 +        except astng.InferenceError:
24              continue
25      return to_call
26 
27 
28  def node_method(node, method_name):
diff --git a/test/input/func_w0231.py b/test/input/func_w0231.py
@@ -35,14 +35,26 @@
29  class NewStyleB(NewStyleA):
30      """derived new style class"""
31      def __init__(self):
32          super(NewStyleB, self).__init__()
33 
34 -
35  class NoInit(object):
36      """No __init__ defined"""
37 
38  class Init(NoInit):
39      """Don't complain for not calling the super __init__"""
40 
41      def __init__(self, arg):
42          self.arg = arg
43 +
44 +class NewStyleC(object):
45 +    """__init__ defined by assignemnt."""
46 +    def xx_init(self):
47 +        """Initializer."""
48 +        pass
49 +
50 +    __init__ = xx_init
51 +
52 +class AssignedInit(NewStyleC):
53 +    """No init called."""
54 +    def __init__(self):
55 +        self.arg = 0
diff --git a/test/messages/func_w0231.txt b/test/messages/func_w0231.txt
@@ -1,2 +1,3 @@
56  W: 19:CCCC: Class has no __init__ method
57  W: 26:ZZZZ.__init__: __init__ method from base class 'BBBB' is not called
58 +W: 59:AssignedInit.__init__: __init__ method from base class 'NewStyleC' is not called