Problem solving · should-tier · asked at Amazon, Apple, Google, Meta, Microsoft, Netflix

is vs ==

easydebugging

Problem

A request pipeline reads an optional header to decide whether to run in replay or dry-run mode, and elsewhere checks whether a caller-supplied timeout is the default:

DEFAULT_TIMEOUT_MS = 5000


def parse_mode(headers: dict[str, str]) -> str:
    mode = headers.get("X-Mode")
    if mode is "replay":
        return "replay"
    if mode is "dryrun":
        return "dryrun"
    return "normal"


def uses_default_timeout(timeout_ms: int) -> bool:
    return timeout_ms is 5000

The unit tests, which call parse_mode({"X-Mode": "replay"}) and uses_default_timeout(5000), pass. In production the X-Mode header is always ignored, and a metric that counts requests using the default timeout reads zero even though most callers never set one. CI logs contain SyntaxWarning: "is" with 'str' literal. Did you mean "=="? which nobody looked at. Explain, including why the tests pass, and fix.

Examples

  • parse_mode({"X-Mode": "replay"}) from the test file → "replay". Passes, because the literal "replay" in the test and the literal "replay" in the function are the same interned object in CPython.
  • parse_mode({"X-Mode": "replay"}) where the value was decoded from a network buffer → "normal". It is an equal but distinct string object, so is is False.
  • uses_default_timeout(5000) → True; uses_default_timeout(int("5000")) → False. Both are the integer 5000, but only one of them is the same object as the literal in the function body.

Hints

  1. What question does is ask about two objects? What question does == ask?
  2. CPython caches small integers (−5 to 256) and interns some strings at compile time. Which values in this snippet fall into those categories, and which do not?
  3. When is is the right operator? Think about None and sentinel objects.

Last reviewed 8 September 2026