""" Construction of sentinel objects. Sentinel objects are used when you only care to check for object identity. """ import sys from textwrap import dedent def sentinel(name, doc=None): try: value = sentinel._cache[name] # memoized except KeyError: pass else: if doc == value.__doc__: return value raise ValueError(dedent( """\ New sentinel value %r conflicts with an existing sentinel of the same name. Old sentinel docstring: %r New sentinel docstring: %r Resolve this conflict by changing the name of one of the sentinels. """, ) % (name, value.__doc__, doc)) @object.__new__ # bind a single instance to the name 'Sentinel' class Sentinel(object): __doc__ = doc __slots__ = ('__weakref__',) __name__ = name def __new__(cls): raise TypeError('cannot create %r instances' % name) def __repr__(self): return 'sentinel(%r)' % name def __reduce__(self): return sentinel, (name, doc) def __deepcopy__(self, _memo): return self def __copy__(self): return self cls = type(Sentinel) try: # traverse up one frame to find the module where this is defined cls.__module__ = sys._getframe(1).f_globals['__name__'] except (ValueError, KeyError): # Couldn't get the name from the calling scope, just use None. cls.__module__ = None sentinel._cache[name] = Sentinel # cache result return Sentinel sentinel._cache = {}