Skip to content

Instantly share code, notes, and snippets.

@QuantumGhost
Created August 15, 2017 04:10
Show Gist options
  • Save QuantumGhost/8181e7993a17cdc0bcd08c9b9ebcc941 to your computer and use it in GitHub Desktop.
Save QuantumGhost/8181e7993a17cdc0bcd08c9b9ebcc941 to your computer and use it in GitHub Desktop.
class Symbol:
__registry = {}
__lock = Lock()
__slots__ = ('name',)
def __new__(cls, name):
instance = cls.__registry.get(name)
if not instance:
with cls.__lock:
# A classical double-checked lock pattern.
# the second check is necessary
# considering the following procedure:
# t1 calls new
# t2 calls new
# t1 check registry, found symbol not exist
# t2 check registry, found symbol not exist
# t1 acquires lock, creating symbol
# t2 waits for lock
# t1 create symbol and store it in registry
# t2 acquire lock, create symbol and store it in registry
# now two symbols with same name are created, we're in trouble.
instance = cls.__registry.get(name)
if instance:
return instance
instance = super().__new__(cls)
instance.name = name
cls.__registry[name] = instance
return instance
def __init__(self, name):
self.name = name
def __eq__(self, other):
return id(self) == id(other)
def __hash__(self):
return hash(self.name)
def __str__(self):
return "Symbol({})".format(self.name)
def __repr__(self):
return 'Symbol("{}")'.format(self.name)
def __getnewargs__(self):
return self.name,
STOP = Symbol('stop')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment