Skip to content

Instantly share code, notes, and snippets.

@adoc
Last active August 29, 2015 13:57
Show Gist options
  • Save adoc/9588060 to your computer and use it in GitHub Desktop.
Save adoc/9588060 to your computer and use it in GitHub Desktop.
safedict: A threadsafe dict-like object.
"""
"""
import threading
__all__ = ('SafeDict', )
class SafeDict:
"""A threadsafe dict-like object.
Simply access like a dict"
>>> t = SafeDict()
>>> t['foo'] = 'bar'
>>> t['foo']
bar
>>> t.get('boo', false)
false
"""
# TODO: use *args for construction to pass a dict.
__registry = {}
def __init__(self, default_types={}, get_ident=threading.get_ident):
""""""
self.__get_ident = get_ident
self.__default_types = default_types
@property
def thread_id(self):
"""Executes the thread id function and returns the result."""
return self.__get_ident()
@property
def registry(self):
""" """
try:
return self.__registry[self.thread_id]
except KeyError:
reg = self.__registry[self.thread_id] = {}
return reg
def __contains__(self, key):
return key in self.registry
def __delitem__(self, key):
del self.registry[key]
def __getitem__(self, key):
try:
return self.registry[key]
except KeyError:
if key in self.__default_types.keys():
reg = self.registry[key] = self.__default_types[key]()
return reg
else:
raise KeyError("'%s' was not found in safedict or in `default_types`." % key)
def __setitem__(self, key, val):
self.registry[key] = val
'''
try:
registry = self.__registry[key]
except KeyError:
# default_type = self.__default_types.get(key) or dict
registry = self.__registry[key] = {}
registry[self.thread_id] = val'''
#def get(self, key, *args):
"""Mimics a dict.get (I think)"""
'''
try:
item = self[key]
except KeyError:
if args:
return args[0]
else:
return None
else:
return item'''
#def set(self, key, val):
"""This seems too simple, but okay!"""
'''
self[key] = val'''
# TESTS
import unittest
import threading
threadfunc = lambda func: threading.Thread(target=func)
class SafeDictTests(unittest.TestCase):
""" """
def test_empty(self):
registry = SafeDict()
self.assertRaises(KeyError, lambda: registry['foo'])
def test_set_get(self):
registry = SafeDict()
def do(key, val):
registry.set(key, val)
self.assertEqual(registry.get(key), val)
threads = (threadfunc(lambda: do('foo', 'bar')),
threadfunc(lambda: do('foo', 'bar')),
threadfunc(lambda: do('boo', True)),
threadfunc(lambda: do('boo', 'boop')))
def threadstart(t):
t.start()
t.join()
map(threadstart, threads)
def test_inner_registry(self):
registry = SafeDict()
def assign(key, val):
registry[key] = val
t1 = threadfunc(lambda: assign('foo', 'bar'))
t2 = threadfunc(lambda: assign('bip', True))
# Fire threads.
t1.start()
t2.start()
# Wait for threads to finish!
t1.join()
t2.join()
self.assertEqual(registry._SafeDict__registry,
{'foo': {t1._ident: 'bar'},
'bip': {t2._ident: True}})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment