#classlock.py

from threading import Lock
def lock_class(methodnames, lockfactory):
	return lambda cls:make_threadsafe(cls, methodnames, lockfactory)

def lock_method(method):
	if getattr(method,'__is_locked',False):
		raise TypeError("Method %r is already locked!" %method)

def locked_method(self, *args, **kwargs):
	with self._lock:
		return method(self, *args, **kwargs)

	locked_method.__name__= '%s(%s)'% ('lock_method',method.__name__)
	locked_method.__is_locked=True
	return locked_method

def make_threadsafe(cls, methodnames,lockfactory):
	init=cls.__init__
	def newinit(self, *args,**kwargs):
		init(self, *args,**kwargs)
		self._lock= lockfactory()
	cls.__init__= newinit

	for methodname in methodnames:
		oldmethod- getattr(cls, methodname)
		newmethod= lock_method(oldmethod)
		setattr(cls, methodnmae, newmethod)
	return cls

@lock_class(['add','remove'],Lock)
class ClassDecoratorLockedSet(set):
	@lock_method 
	# if you double-lock a method, a type error is raised
	print("This section of our code would be thread safe")