# Path: web/core/compat.py

# 
# Path: web/core/context.py
# class Context(MutableMapping):
# 	"""An attribute access dictionary, of a kind.
# 	
# 	This utility class is used to cooperatively construct the ApplicationContext (and subsequent RequestContext)
# 	from the contributions of multiple extensions. The concept of "promotion to a class" is needed in order to enable
# 	the use of descriptor protocol attributes; without promotion the protocol would not be utilized.
# 	"""
# 	
# 	# M-Morty! We're, *belch*, gonna have to go in deep, Morty!  Elbow deep!
# 	def _promote(self, name, instantiate=True):
# 		"""Create a new subclass of Context which incorporates instance attributes and new descriptors.
# 		
# 		This promotes an instance and its instance attributes up to being a class with class attributes, then
# 		returns an instance of that class.
# 		"""
# 		
# 		metaclass = type(self.__class__)
# 		contents = self.__dict__.copy()
# 		cls = metaclass(str(name), (self.__class__, ), contents)
# 		
# 		if instantiate:
# 			return cls()
# 		
# 		return cls
# 	
# 	def __init__(self, **kw):
# 		"""Construct a new Context instance.
# 		
# 		All keyword arguments are applied to the instance as attributes through direct assignment to `__dict__`.
# 		"""
# 		self.__dict__.update(kw)
# 		super(Context, self).__init__()
# 	
# 	def __len__(self):
# 		"""Get a list of the public data attributes."""
# 		return len([i for i in (set(dir(self)) - self._STANDARD_ATTRS) if i[0] != '_'])
# 	
# 	def __iter__(self):
# 		"""Iterate all valid (public) attributes/keys."""
# 		return (i for i in (set(dir(self)) - self._STANDARD_ATTRS) if i[0] != '_')
# 	
# 	def __getitem__(self, name):
# 		"""Retrieve an attribute through dictionary access."""
# 		try:
# 			return getattr(self, name)
# 		except AttributeError:
# 			pass
# 		
# 		# We do this here to avoid Python 3's nested exception support.
# 		raise KeyError(name)
# 	
# 	def __setitem__(self, name, value):
# 		"""Assign an attribute through dictionary access."""
# 		setattr(self, name, value)
# 	
# 	def __delitem__(self, name):
# 		"""Delete an attribute through dictionary access."""
# 		try:
# 			return delattr(self, name)
# 		except AttributeError:
# 			pass
# 		
# 		# We do this here to avoid Python 3's nested exception support.
# 		raise KeyError(name)


from marrow.package.host import ExtensionManager
from .compat import items
from .context import Context
			if name[0] == '-':
				name = name[1:]
				inverse.add(name)
			
			signals[name] = []
		
		# Populate the initial set of signals from our own.
		for signal in self.SIGNALS: add_signal(signal)
		
		# Populate additional signals and general metadata provided by registered extensions.
		for ext in all:
			self.feature.update(getattr(ext, 'provides', []))  # Enable those flags.
			for signal in getattr(ext, 'signals', []): add_signal(signal)  # And those callbacks.
		
		# Prepare the callback cache.
		
		for ext in all:
			for signal in signals:  # Attach any callbacks that might exist.
				handler = getattr(ext, signal, None)
				if handler: signals[signal].append(handler)
			
			if hasattr(ext, '__call__'):  # This one is aliased; the extension itself is treated as WSGI middleware.
				signals['middleware'].append(ext)
		
		# Certain operations act as a stack, i.e. "before" are executed in dependency order, but "after" are executed
		# in reverse dependency order.  This is also the case with "mutate" (incoming) and "transform" (outgoing).
		for signal in inverse:
			signals[signal].reverse()
		
		# Transform the signal lists into tuples to compact them.

# Path: web/core/compat.py

# 
# Path: web/core/context.py
# class Context(MutableMapping):
# 	"""An attribute access dictionary, of a kind.
# 	
# 	This utility class is used to cooperatively construct the ApplicationContext (and subsequent RequestContext)
# 	from the contributions of multiple extensions. The concept of "promotion to a class" is needed in order to enable
# 	the use of descriptor protocol attributes; without promotion the protocol would not be utilized.
# 	"""
# 	
# 	# M-Morty! We're, *belch*, gonna have to go in deep, Morty!  Elbow deep!
# 	def _promote(self, name, instantiate=True):
# 		"""Create a new subclass of Context which incorporates instance attributes and new descriptors.
# 		
# 		This promotes an instance and its instance attributes up to being a class with class attributes, then
# 		returns an instance of that class.
# 		"""
# 		
# 		metaclass = type(self.__class__)
# 		contents = self.__dict__.copy()
# 		cls = metaclass(str(name), (self.__class__, ), contents)
# 		
# 		if instantiate:
# 			return cls()
# 		
# 		return cls
# 	
# 	def __init__(self, **kw):
# 		"""Construct a new Context instance.
# 		
# 		All keyword arguments are applied to the instance as attributes through direct assignment to `__dict__`.
# 		"""
# 		self.__dict__.update(kw)
# 		super(Context, self).__init__()
# 	
# 	def __len__(self):
# 		"""Get a list of the public data attributes."""
# 		return len([i for i in (set(dir(self)) - self._STANDARD_ATTRS) if i[0] != '_'])
# 	
# 	def __iter__(self):
# 		"""Iterate all valid (public) attributes/keys."""
# 		return (i for i in (set(dir(self)) - self._STANDARD_ATTRS) if i[0] != '_')
# 	
# 	def __getitem__(self, name):
# 		"""Retrieve an attribute through dictionary access."""
# 		try:
# 			return getattr(self, name)
# 		except AttributeError:
# 			pass
# 		
# 		# We do this here to avoid Python 3's nested exception support.
# 		raise KeyError(name)
# 	
# 	def __setitem__(self, name, value):
# 		"""Assign an attribute through dictionary access."""
# 		setattr(self, name, value)
# 	
# 	def __delitem__(self, name):
# 		"""Delete an attribute through dictionary access."""
# 		try:
# 			return delattr(self, name)
# 		except AttributeError:
# 			pass
# 		
# 		# We do this here to avoid Python 3's nested exception support.
# 		raise KeyError(name)


# Path: web/core/extension.py
from marrow.package.host import ExtensionManager
from .compat import items
from .context import Context

			if name[0] == '-':
				name = name[1:]
				inverse.add(name)
			
			signals[name] = []
		
		# Populate the initial set of signals from our own.
		for signal in self.SIGNALS: add_signal(signal)
		
		# Populate additional signals and general metadata provided by registered extensions.
		for ext in all:
			self.feature.update(getattr(ext, 'provides', []))  # Enable those flags.
			for signal in getattr(ext, 'signals', []): add_signal(signal)  # And those callbacks.
		
		# Prepare the callback cache.
		
		for ext in all:
			for signal in signals:  # Attach any callbacks that might exist.
				handler = getattr(ext, signal, None)
				if handler: signals[signal].append(handler)
			
			if hasattr(ext, '__call__'):  # This one is aliased; the extension itself is treated as WSGI middleware.
				signals['middleware'].append(ext)
		
		# Certain operations act as a stack, i.e. "before" are executed in dependency order, but "after" are executed
		# in reverse dependency order.  This is also the case with "mutate" (incoming) and "transform" (outgoing).
		for signal in inverse:
			signals[signal].reverse()
		
		# Transform the signal lists into tuples to compact them.

		self.signal = Context(**{k: tuple(v) for k, v in items(signals)})