Are classobjects singleton in python?
Question: If we have `x = type(a)` and `x == y`, does it necessarily imply that `x is
y`?

Here is a counter-example, but it's a cheat:

    
    
    >>> class BrokenEq(type):
    ...     def __eq__(cls, other):
    ...         return True
    ...     
    >>> class A(metaclass=BrokenEq):
    ...     pass
    ... 
    >>> a = A()
    >>> x = type(a)
    >>> x == A, x is A
    (True, True)
    >>> x == BrokenEq, x is BrokenEq
    (True, False)
    

And I could not create a counterexample like this:

    
    
    >>> A1 = type('A', (), {})
    >>> A2 = type('A', (), {})
    >>> a = A1()
    >>> x = type(a)
    >>> x == A1, x is A1
    (True, True)
    >>> x == A2, x is A2
    (False, False)
    

To clarify my question - _without overriding equality_ operators to do
something insane, is it possible for a class to exist at two different memory
locations or does the import system somehow prevent this?

If so, how can we demonstrate this behavior - for example, doing weird things
with [reload](https://docs.python.org/2/library/functions.html#reload) or
`__import__`?

If not, is that guaranteed by the language or documented anywhere?

* * *

**Epilogue** :

    
    
    # thing.py
    class A:
        pass
    

Finally, this is what clarified the real behaviour for me (and it's supporting
the claims in Blckknght answer)

    
    
    >>> import sys
    >>> from thing import A
    >>> a = A()
    >>> isinstance(a, A), type(a) == A, type(a) is A
    (True, True, True)
    >>> del sys.modules['thing']
    >>> from thing import A
    >>> isinstance(a, A), type(a) == A, type(a) is A
    (False, False, False)
    

So, although code that uses
[`importlib.reload`](https://docs.python.org/3/library/importlib.html?highlight=reload#importlib.reload)
could break type checking by class identity, it will also break `isinstance`
anyway.


Answer: No, there's no way to create two class objects that compare equal without
being identical, except by messing around with metaclass `__eq__` methods.

This behavior though is not something unique to classes. It's the default
behavior for any object without an `__eq__` method defined in its class. The
behavior is inherited from `object`, which is the base class for all other
(new-style) classes. It's only overridden for builtin types that have some
other semantic for equality (e.g. container types which compare their
contents) and for custom classes that define an `__eq__` operator of their
own.

As for getting two different refernces to the same class at different memory
locations, that's not really possible due to Python's object semantics. The
memory location of the object _is_ its identity (in cpython at least). Another
class with identical contents can exist somewhere else, but like in your `A1`
and `A2` example, it's going to be seen as a different object by all Python
logic.

