Why is it better to write `if a is None` instead of `if a == None`?

You missed an important singleton:

my_singleton = object()

Which is used in code that cannot use None for example.

That’s not a singleton. That’s a sentinel. Don’t misuse the term singleton for stuff that is clearly something else.

But yes, I should have explicitly mentioned it.

Had to think about this for a few moments.

If I need a sentiel I can use a number of things one of them being a singleton.
But I could also use the string "this is a sentinal value" with == but not is.
In the case of the sentinal value my_singleton (should be named my_sentienal) I can use is.

Two more that I’ve seen the docs call singletons: StopIteration and ().

Indeed. There are many ways of doing sentinels, and one option is a true singleton, another is a unique instance of object, a third is a special string (though the consequences of that are quite different), etc, etc.

Really? Which docs? StopIteration is an Exception subclass that you need to instantiate, in no way a singleton or even a sentinel object. () might be guaranteed by the CPython interpreter to be interned and could be considered a singleton in spirit (single member of the type tuple[()]), although ofcourse it shares it’s class with all other tuples and is therefore not really a singleton.

Just stumbled upon When can I rely on identity tests with the is operator? in the docs, which addresses what this topic is about and also …

… says (emphasis mine):

  1. Detecting optional arguments can be tricky when None is a valid input value. In those situations, you can create a singleton sentinel object guaranteed to be distinct from other objects. […] _sentinel = object()

It’s worth noting that the docs sometimes use “singleton” to mean “single-element tuple”. 3. Data model — Python 3.12.1 documentation This is unrelated to this use of the word and single-element tuples definitely shouldn’t be compared with is.

From that page:

I disagree with that definition and usage of singleton. For any object, there will only ever be one object that is that object… So using the definition spelt out there, any object is a singleton. I guess the docs are a bit imprecise here. Using class or type in that definition would make it more correct, but then they couldn’t call _sentinel a singleton.

Here:

The singletons None, Ellipsis and StopIteration

Here:

Disable all freelists except the empty tuple singleton.

Although this says contradicting things, search for “empty tuple” there. First it says “the empty tuple”, which means there is only one (otherwise it would say “an empty tuple”). Then it says “the constructor creates a new empty tuple” (which is wrong, at least in the 3.11 version where I checked now). Later it again says “the empty tuple” and then “An empty tuple”. This conflicting/wrong information should probably get fixed…

StopIteration is still not a singleton, the marshal docs are just lumping together two singletons and a special case that used to be necessary for generators: Why does marshal handle StopIteration? - #11 by storchaka It also loads a reference to the class, not an instances of that class. (in some sense all classes are singletons as the sole member of type[cls])

Yeah, the docs are clearly imprecise (and sometimes incorrect) in their usage of “singleton”.

That page also has a convenient list of actual singletons built into the language, None (or The Null Object) NotImplemented and Ellipsis.

Maybe instead of “singletons” it would be better to say “special objects”? StopIteration (the class) is definitely special, and that slight switch of terminology would remove the confusion.

If you mean the sections in “Other Built-in Types”, then that list includes a few other things.

I did not understood this part. I thought that a singleton is an object that, instead of being created new by the constructor, the constructor returns the same default instance.

What does that mean? Objects don’t return (well, unless they’re callable and you call them).

That definitely is a valid implementation of the singleton pattern. This is the case for None, for example - type(None)() is None - you can “construct” it as many times as you like, and you get back the same object. Same with ellipsis: type(...)() is ... or equivalently with the name Ellipsis. But that’s not the definition of a singleton, just one possible implementation.

Excuse me, but on Wikipedia that’s written that the singleton pattern is what you wrote:

the singleton pattern is a software design pattern that restricts the instantiation of a class to a singular instance.

Anyway, my question is about my ignorance about interning. Why an interned object can’t be defined as a singleton? Is it because its construction does not involve the use of a constructor?

A Singleton object is an instance of a singleton type. A singleton type only ever has one member/instance. Any further attempts to create another instance either fail or return this same instances. int is not a singleton type (you can create different instances). Neither is bool (True and False are different instances). NoneType is a singleton type and None therefore a singleton.

Note that you could implement the singleton pattern by making the constructor give the same instance, but you could also not allow construction at all and giving access to the instance by some other method.

See, for example, the first one in the same page that you were reading.

That’s clearly a misuse of terminology, though. Outside of the idiosyncratic Python use to mean a 1-element tuple, “singleton” is a property of the class, not of its instances - and indeed it’s the property of not being able to create more than the one already-existing instance. The very fact that we write _sentinel = object() and get a separate instance of object, shows that the object type is not singleton.