
Inline adoc files when they are included exactly once. Also fix language tags because this inlining gives us better information on what language the code is written in.
86 lines
2.4 KiB
Plaintext
86 lines
2.4 KiB
Plaintext
== 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++``. To avoid this problem the identity operator could be replaced with an equality operator (== or !=), which will use ``++__eq__++`` or ``++__ne__++`` methods under the hood.
|
|
|
|
|
|
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.
|
|
|
|
|
|
=== Noncompliant code example
|
|
|
|
[source,python]
|
|
----
|
|
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
|
|
|
|
[source,python]
|
|
----
|
|
def func(param):
|
|
param == {1: 2}
|
|
param != {1, 2, 3}
|
|
param == [1, 2, 3]
|
|
|
|
param == dict(a=1)
|
|
|
|
mylist = []
|
|
param == mylist
|
|
----
|
|
|
|
|
|
== Resources
|
|
|
|
* https://adamj.eu/tech/2020/01/21/why-does-python-3-8-syntaxwarning-for-is-literal/[Why does Python 3.8 log a SyntaxWarning for 'is' with literals?] - Adam Johnson
|
|
* https://treyhunner.com/2019/03/unique-and-sentinel-values-in-python/#Equality_vs_identity[Equality vs identity] - Trey Hunner
|
|
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
|
|
'''
|
|
== Implementation Specification
|
|
(visible only on this page)
|
|
|
|
=== Message
|
|
|
|
* Replace this "is" operator with "==".
|
|
* Replace this "is not" operator with "!=".
|
|
|
|
|
|
=== Highlighting
|
|
|
|
Primary: the "is" or "is not" operator.
|
|
|
|
|
|
Secondar(y|ies):
|
|
|
|
If the new object is passed via a variable
|
|
|
|
* location1: the assigned value
|
|
* message1: "This expression creates a new object every time."
|
|
|
|
|
|
'''
|
|
== Comments And Links
|
|
(visible only on this page)
|
|
|
|
=== is related to: S5914
|
|
|
|
endif::env-github,rspecator-view[]
|