At the Python (rather than CPython implementation) level, the explanation is “is is object identity not value equality, and there is no guarantee that equal integers share object identity.”
At the CPython level, you can explain it in terms of the particular range of small integers that are interned and thus are guaranteed within particular CPython versions to share object identity when they have value equality.
But just knowing that is identity and == is equality is mostly enough to use them correctly.