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).

Integers, bytes, floats, strings, frozensets and tuples should not be compared with identity operators because the result may not be as expected. If you need to compare these types you should use instead equality operators == or !=.

The CPython interpreter caches certain builtin values for integers, bytes, floats, strings, frozensets and tuples. For example, the literal 1 will create the same object as int("1"), which means that 1 is int("1") is True. However this works only by chance as other integer values are not cached, for example int("1000") is 1000 will always be False. This behavior is not part of Python language specification and could vary between interpreters. CPython 3.8 even warns about comparing literals using identity operators.

The only case where using the "is" operator with a cached type is ok is with "interned" strings. Note however that interned strings don't necessarily have the same identity as string literals.

This rule raises an issue when at least one operand of an identity operator:

Noncompliant Code Example

def literal_comparison(param):
    param is 2000  # Noncompliant

literal_comparison(2000)  # will return True
literal_comparison(int("2000"))  # will return False

() is tuple()  # Noncompliant. Always True
(1,) is tuple([1])  # Noncompliant. Always False

from sys import intern

with open("test.txt") as f:  # test.txt contains "blabla\n"
    text = f.read()
intern(text) is "blabla\n"  # Noncompliant. Always False

Compliant Solution

def literal_comparison(param):
    param == 2000

literal_comparison(2000)  # will return True
literal_comparison(int("2000"))  # will return True

() == tuple()  # Always True
(1,) == tuple([1])  # Always True

from sys import intern

with open("tmp/test.txt") as f:  # test.txt contains "blabla\n"
    text = f.read()
intern(text) is intern("blabla\n")  # Always True

See