Skip to content

single-item-membership-test (FURB171) should be marked unsafe #20255

@dscorbett

Description

@dscorbett

Summary

single-item-membership-test (FURB171) can change behavior in two ways. First, in tries both is and ==, whereas the fix is just ==, which changes behavior for values like NaN. There is no way to know in general which values it is safe for, although it would be possible for this rule to safely special-case certain expressions like str and number literals. Second, in returns a bool whereas == can return anything. The current fix is only safe in boolean contexts like a bool argument or an if condition. Otherwise, the fix should be marked unsafe or the fix should wrap the expression in a bool call (or use the not operator, in the negated case). Example:

$ cat >furb171.py <<'# EOF'
import numpy as np
print(np.nan in [np.nan])
print(np.zeros(1) in [np.zeros(1)])
# EOF

$ python furb171.py
True
True

$ ruff --isolated check furb171.py --select FURB171 --preview --fix
Found 2 errors (2 fixed, 0 remaining).

$ cat furb171.py
import numpy as np
print(np.nan == np.nan)
print(np.zeros(1) == np.zeros(1))

$ python furb171.py
False
[ True]

When the container is a string literal and the fix is currently marked safe, that’s fine. This is only an issue for list, tuple, set, and frozenset.

Version

ruff 0.12.12 (c6516e9 2025-09-04)

Metadata

Metadata

Assignees

Labels

fixesRelated to suggested fixes for violationspreviewRelated to preview mode features

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions