Skip to content

Commit

Permalink
Fix crash in refactoring checker when calling bound lambda
Browse files Browse the repository at this point in the history
Fixes:
```
  File "sources/pylint/pylint/checkers/refactoring/refactoring_checker.py", line 2094, in _is_function_def_never_returning
    and node.returns
        ^^^^^^^^^^^^
  File "sources/pylint/.venv/lib/python3.11/site-packages/astroid/bases.py", line 138, in __getattr__
    return getattr(self._proxied, name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'Lambda' object has no attribute 'returns'
```

Crash is reproducible if you have something like this:

```python
class C:
    eq = lambda self, y: self == y
```

As a workaround, use a normal function instead of a lambda.

Closes #9865
  • Loading branch information
Hnasar authored and jacobtylerwalls committed Aug 11, 2024
1 parent 466c671 commit b78deb6
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 8 deletions.
3 changes: 3 additions & 0 deletions doc/whatsnew/fragments/9865.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fix crash in refactoring checker when calling a lambda bound as a method.

Closes #9865
18 changes: 10 additions & 8 deletions pylint/checkers/refactoring/refactoring_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -2089,15 +2089,17 @@ def _is_function_def_never_returning(
return True
except (TypeError, AttributeError):
pass

try:
returns: nodes.NodeNG | None = node.returns
except AttributeError:
return False # the BoundMethod proxy may be a lambda without a returns

return (
isinstance(node, (nodes.FunctionDef, astroid.BoundMethod))
and node.returns
and (
isinstance(node.returns, nodes.Attribute)
and node.returns.attrname in {"NoReturn", "Never"}
or isinstance(node.returns, nodes.Name)
and node.returns.name in {"NoReturn", "Never"}
)
isinstance(returns, nodes.Attribute)
and returns.attrname in {"NoReturn", "Never"}
or isinstance(returns, nodes.Name)
and returns.name in {"NoReturn", "Never"}
)

def _check_return_at_the_end(self, node: nodes.FunctionDef) -> None:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""Regression for https://github.com/pylint-dev/pylint/issues/9865."""
# pylint: disable=missing-docstring,too-few-public-methods,unnecessary-lambda-assignment
class C:
eq = lambda self, y: self == y

def test_lambda_method():
ret = C().eq(1)
return ret

0 comments on commit b78deb6

Please sign in to comment.