Skip to content

Commit

Permalink
Fix crash in refactoring checker when calling bound lambda (#9867)
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

(cherry picked from commit b78deb6)

Co-authored-by: Hashem Nasarat <hashem@hudson-trading.com>
  • Loading branch information
jacobtylerwalls and Hnasar authored Aug 11, 2024
1 parent 7d1626c commit f1925f4
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 7 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
19 changes: 12 additions & 7 deletions pylint/checkers/refactoring/refactoring_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -2083,13 +2083,18 @@ def _is_function_def_never_returning(
Returns:
bool: True if the function never returns, False otherwise.
"""
if isinstance(node, (nodes.FunctionDef, astroid.BoundMethod)) and node.returns:
return (
isinstance(node.returns, nodes.Attribute)
and node.returns.attrname == "NoReturn"
or isinstance(node.returns, nodes.Name)
and node.returns.name == "NoReturn"
)
if isinstance(node, (nodes.FunctionDef, astroid.BoundMethod)):
try:
returns: nodes.NodeNG | None = node.returns
except AttributeError:
return False # the BoundMethod proxy may be a lambda without a returns
if returns is not None:
return (
isinstance(returns, nodes.Attribute)
and returns.attrname == "NoReturn"
or isinstance(returns, nodes.Name)
and returns.name == "NoReturn"
)
try:
return node.qname() in self._never_returning_functions
except (TypeError, AttributeError):
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 f1925f4

Please sign in to comment.