is

Same object, not equal value — and the one right way to check for None.

Identity operatorPython 1.0+
Common call
if x is None:
Returns
bool — identity, not equality
Replaces
the None/True/False singleton checks
Watch out
never use is for numbers or strings — caching lies to you
aa — Left operand.type: Any · required is bb — Right operand.type: Any · required
→ bool

Operands

NameTypeRequiredDescription
aAnyyesLeft operand.
bAnyyesRight operand.

Return value

bool — True when a and b are the SAME object in memory — id(a) == id(b). Never overridable.

Common patterns

The None check
None is a singleton — identity is the correct and conventional test.
if result is None:
    handle_missing()
Sentinel objects
A private object() lets you distinguish "not passed" from any real value.
_MISSING = object()
def f(x=_MISSING):
    if x is _MISSING:
        ...

Examples

1. None check
x = None x is None
Returns
True
2. Equal but not identical
a = [1, 2] b = [1, 2] a is b
Returns
False
3. Same object
a = [1, 2] b = a a is b
Returns
True

Pitfalls

1. is on numbers works — until it does not
CPython caches small ints (-5..256) and some strings, so is "accidentally" succeeds in tests and fails in production.
Implementation detail
a = 256; b = 256; a is b   # True
a = 257; b = 257; a is b   # may be False!
SyntaxWarning in 3.8+ for literals
Fix
a == b
value comparison — always correct
2. == None instead of is None
A class can override __eq__ to answer anything — identity cannot be faked.
Overridable
if x == None:
depends on x.__eq__
Fix
if x is None:
always the singleton test

When to use

Use it
  • None / True / False singleton checks
  • Sentinel-object comparisons
  • Genuine same-object questions (aliasing checks)
Reach for something else
  • Value comparison of any kind → ==
  • Numbers and strings → never is

Notes

Complexity
O(1) — a pointer comparison
Return
bool
CPython impl
IS_OP opcode — compares object addresses, no dunder
Memory
No allocation
Thread-safe
Yes

FAQ

CPython interns some strings and small ints as an optimization, making separate literals share one object. It is an implementation detail — never rely on it.

History

3.8
SyntaxWarning added for `is` with int/str literals.