org.sonar.l10n.py.rules.python.S5796.html Maven / Gradle / Ivy
This rule raises an issue when at least one operand of an identity operator is a new object which has been created just for this check.
Why is this an issue?
Identity operators is
and is not
check if the same object is on both sides, i.e. a is b
returns
True
if id(a) == id(b)
.
When a new object is created, it will have its own identity. Thus, if an object is created and used only in an identity check, it is not possible
for the other operand to be the same object. The comparison is always False
or always True
depending on the operator used,
is
or is not
.
This rule raises an issue when at least one operand of an identity operator is a new object which has been created just for this check, i.e.:
- When it is a dict, list or set literal.
- When it is a call to
dict
, set
, list
or complex
built-in functions.
- When such a new object is assigned to only one variable and this variable is used in an identity check.
How to fix it
Whenever using a newly created object in a comparison, the identity operator should be replaced with the equality operator (==
or
!=
), which will use __eq__
or __ne__
methods under the hood.
Code examples
Noncompliant code example
def func(param):
param is {1: 2} # Noncompliant: always False
param is not {1, 2, 3} # Noncompliant: always True
param is [1, 2, 3] # Noncompliant: always False
param is dict(a=1) # Noncompliant: always False
mylist = [] # mylist is assigned a new object
param is mylist # Noncompliant: always False
Compliant solution
def func(param):
param == {1: 2}
param != {1, 2, 3}
param == [1, 2, 3]
param == dict(a=1)
mylist = []
param == mylist
Resources
Articles & blog posts
- Why does Python 3.8 log a SyntaxWarning for 'is'
with literals? - Adam Johnson
- Equality vs identity - Trey Hunner