False positive `C901` thrown for outer function in closure
- Dominant language
- Rust
- Stars
- 49.6k
- Forks
- 2.4k
- Avg merge
- 2d 1h
- Merged PRs (30d)
- 458
Description
Please see this snippet:
```python
from functools import wraps
def wrapper(f):
@wraps(f)
def wrapped_f(*args, **kwargs):
if 1 == 1:
pass
if 1 == 1:
pass
if 1 == 1:
pass
return f(*args, **kwargs)
return wrapped_f
```
And the below `pyproject.toml`
```toml
[tool.ruff.mccabe]
max-complexity = 3
[tool.flake8]
max-complexity = 3
```
With `ruff==0.0.265` will print:
```bash
> ruff --select=C901 a.py
a.py:4:5: C901 `wrapper` is too complex (5 > 3)
a.py:6:9: C901 `wrapped_f` is too complex (4 > 3)
Found 2 errors.
> flake8 a.py
a.py:4:1: C901 'wrapper' is too complex (5)
```
The 2nd error about `wrapped_f` if correct, as its cyclomatic complexity is above 3. However, I think the 1st error about the `wrapper` (outer) function is a false positive, as it has a cyclomatic complexity ≤ 3.
In other words, I think `ruff` has a false positive `C901` for closures, only the inner should throw.
For what it's worth, `flake8==6.0.0` does not have this false positive, but I think they mark the extra complexity in the wrong place (at `wrapper`, not `wrapped_f`).
Contributor guide
Research direction
Start by reproducing the C901 result from the provided Python closure snippet with Ruff 0.0.265, then compare it with flake8's result. Trace the complexity calculation for the outer and inner functions; done means only `wrapped_f` reports C901 while `wrapper` does not when the configured limit is 3.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, rust
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100