Transforms the provided class into an interned class.
        
        That is, initializing the class multiple times with the same arguments 
        (even if in a different order if using keyword arguments) should 
        always produce the same object, and __init__ should only be called the 
        first time for each unique set of arguments.
        
        This means that mutations will effectively be shared by all "instances" 
        of the class which shared initialization arguments. This might be 
        useful for storing metadata, for example.
        
            >>> class N(object):
            ...     def __init__(self, n):
            ...         self.n = n
            >>> N = intern(N)
            >>> five = N(5)
            >>> five2 = N(5)
            >>> five is five2
            True
            >>> five.is_odd = True
            >>> five2.is_odd
            True
            
        To enforce immutability of particular attributes, see the setonce 
        property modifier.
            
        The use of the term "intern" comes from the practice of string 
        interning used widely in programming languages, including Python. Look 
        it up.
        
        Can be used as a class decorator in Python 2.6+. Otherwise, use like 
        this:
        
            >>> class Test(object): pass
            >>> Test = intern(Test)
        
        .. Note:: Subclassing of intern classes with different __init__
                  arguments is tricky and probably should not be done if you 
                  don't understand precisely how this works.
                  
                  If you subclass with the same __init__ arguments (preferably
                  the same __init__) it will use the SAME pool. This can be used
                  to automate adding metadata as above, though you should 
                  probably just do that with a function.

        .. Note:: You can override the hash function used by providing a value
                  for __init__._intern__hash_function. This should take None
                  as the first argument (substituting for self) and then *args
                  and **kwargs (or your particular signature for __init__) and
                  produce a hash or hashable value.
                  
                  The default implementation is provided by fn_arg_hash_function
                  applied to __init__, or generic_arg_hash_function if that 
                  doesn't work.

def intern(cls_):
        """Transforms the provided class into an interned class.
        
        That is, initializing the class multiple times with the same arguments 
        (even if in a different order if using keyword arguments) should 
        always produce the same object, and __init__ should only be called the 
        first time for each unique set of arguments.
        
        This means that mutations will effectively be shared by all "instances" 
        of the class which shared initialization arguments. This might be 
        useful for storing metadata, for example.
        
            >>> class N(object):
            ...     def __init__(self, n):
            ...         self.n = n
            >>> N = intern(N)
            >>> five = N(5)
            >>> five2 = N(5)
            >>> five is five2
            True
            >>> five.is_odd = True
            >>> five2.is_odd
            True
            
        To enforce immutability of particular attributes, see the setonce 
        property modifier.
            
        The use of the term "intern" comes from the practice of string 
        interning used widely in programming languages, including Python. Look 
        it up.
        
        Can be used as a class decorator in Python 2.6+. Otherwise, use like 
        this:
        
            >>> class Test(object): pass
            >>> Test = intern(Test)
        
        .. Note:: Subclassing of intern classes with different __init__
                  arguments is tricky and probably should not be done if you 
                  don't understand precisely how this works.
                  
                  If you subclass with the same __init__ arguments (preferably
                  the same __init__) it will use the SAME pool. This can be used
                  to automate adding metadata as above, though you should 
                  probably just do that with a function.

        .. Note:: You can override the hash function used by providing a value
                  for __init__._intern__hash_function. This should take None
                  as the first argument (substituting for self) and then *args
                  and **kwargs (or your particular signature for __init__) and
                  produce a hash or hashable value.
                  
                  The default implementation is provided by fn_arg_hash_function
                  applied to __init__, or generic_arg_hash_function if that 
                  doesn't work.
        
        """
        cls_.__pool = { }
        
        __init__ = cls_.__init__
        try:
            __init__.__func__.__hash_function
        except AttributeError:
            try:
                __init__.__func__.__hash_function = \
                        fn_arg_hash_function(__init__)
            except (AttributeError, TypeError): pass
            
        # define an override for __new__ which looks in the cache first
        def __new__(cls, *args, **kwargs):
            """Override used by cypy.intern to cache instances of this class."""
            
            # check cache
            __init__ = cls.__init__
            try:
                hash_function = __init__.__func__.__hash_function
            except AttributeError:
                try:
                    hash_function = __init__.__func__.__hash_function = \
                                  fn_arg_hash_function(__init__)
                except (AttributeError, TypeError):
                    hash_function = generic_arg_hash_function
            
            try:
                # look-up object
                hash = hash_function(None, *args, **kwargs)  # none because self is not created yet
                obj = cls_.__pool[hash]
            except (TypeError, KeyError) as e:
                # if arguments not hashable or object not found, need to 
                # make a new object
                
                # restore the original new temporarily, if it existed
                orig_new = __new__.orig
                if orig_new is _NotDefined: del cls_.__new__
                else: cls_.__new__ = orig_new
                
                # create new object
                obj = cls(*args, **kwargs)
                
                # put it in ze pool
                if isinstance(e, KeyError):
                    cls_.__pool[hash] = obj
                
                # re-override __new__
                cls_.__new__ = __static_new__
                                
            # Return the instance but don't call __init__ since it was done 
            # when it was created the first time, see below for how this is 
            # done
            try: cls.__old_init = cls.__dict__['__init__']
            except KeyError: cls.__old_init = _NotDefined            
            cls.__init__ = _dummy_init
                
            return obj
            
        # save original __new__
        try: __new__.orig = staticmethod(cls_.__dict__['__new__'])
        except KeyError: 
            if cls_.__new__ is object.__new__:
                __new__.orig = _null_new
            else:
                __new__.orig = _NotDefined
        
        __static_new__ = staticmethod(__new__)
        cls_.__static_new__ = __static_new__
        cls_.__new__ = __static_new__
        return cls_