# a decorator to a function that, when called, adds it to a list, to be sequentially executed later

class After:
	committing = False
	def __init__(self, name):
	    self.name = name
	    self.queue = []
	def __call__(self,f):
		def wrapper(*a,**kw):
			if self.committing:
				return f(*a,**kw)
			self.queue.append([f,a,kw])
		return wrapper
	def commit(self):
		self.committing = True
		for f,a,kw in self.queue:
			#print(f.__name__,a,kw)
			f(*a,**kw)


def test():
	after = After("stuff")

	def a1():
		print('in a1')
		if b2():
			b3()
	def a2():
		print('in a2')
		if b4():
			b5()
	def b2():
		print("b2 can't be postponed, since a1 relies on it")
		return True
	@after
	def b3():
		print('b3 must come after all, but before b5')
	def b4():
		print("b4 can't be postponed, since a2 relies on it")
		return True
	@after
	def b5():
		print('b5 must come after all')

	a1()
	a2()
	after.commit()

if __name__ == '__main__':
    test()

afterward = After("afterward")
