Skip to content

TypeError exception when method named "format" replaces itself with different method #3686

@BlankSpruce

Description

@BlankSpruce

Steps to reproduce

  1. Create a file with following class in either of these two variants:
class Foo:
    def _format(self):
        pass

    def format(self):
        self.format = self._format
        self.format()

or

class Foo:
    def _format(self):
        pass

    def format(self):
        self.format = self._format
        self._format()
  1. Run pylint on such file.

Current behavior

$ pylint reproduce.py
************* Module reproduce
reproduce.py:1:0: C0114: Missing module docstring (missing-module-docstring)
reproduce.py:1:0: C0115: Missing class docstring (missing-class-docstring)
reproduce.py:2:4: R0201: Method could be a function (no-self-use)
reproduce.py:5:4: C0116: Missing function or method docstring (missing-function-docstring)
Traceback (most recent call last):
  File "/home/foobar/.local/bin/pylint", line 8, in <module>
    sys.exit(run_pylint())
  File "/home/foobar/.local/lib/python3.8/site-packages/pylint/__init__.py", line 22, in run_pylint
    PylintRun(sys.argv[1:])
  File "/home/foobar/.local/lib/python3.8/site-packages/pylint/lint/run.py", line 344, in __init__
    linter.check(args)
  File "/home/foobar/.local/lib/python3.8/site-packages/pylint/lint/pylinter.py", line 870, in check
    self._check_files(
  File "/home/foobar/.local/lib/python3.8/site-packages/pylint/lint/pylinter.py", line 904, in _check_files
    self._check_file(get_ast, check_astroid_module, name, filepath, modname)
  File "/home/foobar/.local/lib/python3.8/site-packages/pylint/lint/pylinter.py", line 930, in _check_file
    check_astroid_module(ast_node)
  File "/home/foobar/.local/lib/python3.8/site-packages/pylint/lint/pylinter.py", line 1062, in check_astroid_module
    retval = self._check_astroid_module(
  File "/home/foobar/.local/lib/python3.8/site-packages/pylint/lint/pylinter.py", line 1107, in _check_astroid_module
    walker.walk(ast_node)
  File "/home/foobar/.local/lib/python3.8/site-packages/pylint/utils/ast_walker.py", line 75, in walk
    self.walk(child)
  File "/home/foobar/.local/lib/python3.8/site-packages/pylint/utils/ast_walker.py", line 75, in walk
    self.walk(child)
  File "/home/foobar/.local/lib/python3.8/site-packages/pylint/utils/ast_walker.py", line 72, in walk
    callback(astroid)
  File "/home/foobar/.local/lib/python3.8/site-packages/pylint/checkers/classes.py", line 992, in visit_functiondef
    for obj in ancestor.lookup(node.name)[1]:
  File "/home/foobar/.local/lib/python3.8/site-packages/astroid/node_classes.py", line 1067, in lookup
    return self.scope().scope_lookup(self, name)
  File "/home/foobar/.local/lib/python3.8/site-packages/astroid/scoped_nodes.py", line 2239, in scope_lookup
    return frame._scope_lookup(node, name, offset)
  File "/home/foobar/.local/lib/python3.8/site-packages/astroid/scoped_nodes.py", line 209, in _scope_lookup
    return pscope.scope_lookup(node, name)
  File "/home/foobar/.local/lib/python3.8/site-packages/astroid/scoped_nodes.py", line 514, in scope_lookup
    return self._scope_lookup(node, name, offset)
  File "/home/foobar/.local/lib/python3.8/site-packages/astroid/scoped_nodes.py", line 198, in _scope_lookup
    stmts = node._filter_stmts(self.locals[name], self, offset)
  File "/home/foobar/.local/lib/python3.8/site-packages/astroid/node_classes.py", line 1155, in _filter_stmts
    if stmt.fromlineno > mylineno > 0:
TypeError: '>' not supported between instances of 'NoneType' and 'int'

Expected behavior

$ pylint reproduce.py
************* Module reproduce
reproduce.py:1:0: C0114: Missing module docstring (missing-module-docstring)
reproduce.py:1:0: C0115: Missing class docstring (missing-class-docstring)
reproduce.py:5:4: C0116: Missing function or method docstring (missing-function-docstring)
reproduce.py:5:4: E0202: An attribute defined in reproduce line 6 hides this method (method-hidden)
reproduce.py:1:0: R0903: Too few public methods (1/2) (too-few-public-methods)

----------------------------------------------------------------------
Your code has been rated at -11.67/10 (previous run: -11.67/10, +0.00)

Additional info

The issue isn't reproduced if replaced method has different name:

class Foo:
    def _format(self):
        pass

    def definitely_not_a_format(self):
        self.definitely_not_a_format = self._format
        self.definitely_not_a_format()

or it doesn't replace itself:

class Foo:
    def _format(self):
        pass

    def format(self):
        self._format()

pylint --version output

pylint 2.5.3
astroid 2.4.0
Python 3.8.3 (default, May 17 2020, 18:15:42)
[GCC 10.1.0]

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions