logilab-astng #5571 Crash on module-level @staticmethod/@classmethod [resolved]

Maarten reported:

When running pylint on this program:

def f():

I get the following exception trace:

Traceback (most recent call last):
 File "/usr/bin/pylint", line 4, in <module>
 File "/usr/lib/python2.5/site-packages/pylint/lint.py", line 901, in __init__
 File "/usr/lib/python2.5/site-packages/pylint/lint.py", line 492, in check
   self.check_astng_module(astng, checkers)
 File "/usr/lib/python2.5/site-packages/pylint/lint.py", line 602, in check_astng_module
   if implements(checker, IASTNGChecker)])
 File "/usr/lib/python2.5/site-packages/pylint/lint.py", line 619, in astng_events
   self.astng_events(child, checkers, _reversed_checkers)
 File "/usr/lib/python2.5/site-packages/pylint/lint.py", line 619, in astng_events
   self.astng_events(child, checkers, _reversed_checkers)
 File "/usr/lib/python2.5/site-packages/pylint/lint.py", line 616, in astng_events
 File "/usr/lib/python2.5/site-packages/logilab/astng/utils.py", line 84, in visit
 File "/usr/lib/python2.5/site-packages/pylint/checkers/classes.py", line 206, in visit_function
   self._check_first_arg_for_type(node, klass.type == 'metaclass')
AttributeError: Module instance has no attribute 'type'

Although it is a bit unusual to have a static method at the module level, the Python interpreter accepts it.

The same crash happens on @classmethod when used at the model level.

I had a look at checkers/classes.py to see if fixing it would be easy, but it wasn't clear to me what the proper approach would be:

  • let is_method() should return False in cases like this
  • don't assume that a method's parent is always a class

As a quick fix, I settled on the latter:

klass_type = getattr(klass, 'type', None) # "klass" might not be a class

And replace "klass.type" by "klass_type", once in checkers/classes.py and once in checkers/variables.py.

appeared in<not specified>
done in0.17.4
load left0.000
closed by<not specified>