# Path: snakeguice/binder.py
# class Binder(object):
# 
#     def __init__(self, parent=None):
#         self._parent = parent or _EmptyBinder()
#         self._binding_map = {}
# 
#     def bind(self, _class, **kwargs):
#         key = Key(interface=_class, annotation=kwargs.get('annotated_with'))
# 
#         binding = Binding()
#         binding.key = key
#         binding.scope = kwargs.get('in_scope', scopes.NO_SCOPE)
# 
#         if key in self._binding_map:
#             raise errors.BindingError('baseclass %r already bound' % _class)
# 
#         if 'to' in kwargs:
#             if not isinstance(kwargs['to'], type):
#                 raise errors.BindingError("'to' requires a new-style class")
# 
#             binding.provider = providers.create_simple_provider(kwargs['to'])
# 
#         elif 'to_provider' in kwargs:
#             #TODO: add some validation
#             provider = kwargs['to_provider']
#             binding.provider = provider
# 
#         elif 'to_instance' in kwargs:
#             if not isinstance(kwargs['to_instance'], object):
#                 raise errors.BindingError(
#                     "'to_instance' requires an instance of a new-style class")
# 
#             provider = kwargs['to_instance']
#             binding.provider = providers.create_instance_provider(provider)
# 
#         self._binding_map[key] = binding
# 
#     def get_binding(self, key):
#         return self._binding_map.get(key) or self._parent.get_binding(key)
# 
#     def create_child(self):
#         return Binder(self)
# 
# class Key(object):
# 
#     def __init__(self, interface, annotation=None):
#         self._interface = interface
#         self._annotation = annotation
# 
#     def __hash__(self):
#         return hash((self._interface, self._annotation))
# 
#     def __eq__(self, other):
#         return (self._interface == other._interface and
#                 self._annotation == other._annotation)
# 
#     def __ne__(self, other):
#         return not self == other
# 
# Path: snakeguice/decorators.py
# class GuiceData(object):
# 
#     def __init__(self):
#         self.init = None
#         self.methods = {}
# 
#     @classmethod
#     def from_class(cls, target_class):
#         if '__guice__' not in target_class.__dict__:
#             guice_data = cls()
#             try:
#                 target_class.__guice__ = guice_data
#             except TypeError: # special case for builtin/extension types
#                 return guice_data
#         return target_class.__guice__
# 
#     @classmethod
#     def composite_from_class(cls, target_class):
#         composite_data = GuiceData()
#         for _cls in target_class.__mro__[-1::-1]:
#             data = GuiceData.from_class(_cls)
#             if data.init: # only the last class in the chain
#                 composite_data.init = data.init
#             for name, method in data.methods.items():
#                 composite_data.methods[name] = method
# 
#         return composite_data
# 
#     @classmethod
#     def from_class_dict(cls, class_dict):
#         if '__guice__' not in class_dict:
#             class_dict['__guice__'] = cls()
#         return class_dict['__guice__']
# 
# def inject(**kwargs):
# 
#     scope = kwargs.get('scope')
#     if 'scope' in kwargs:
#         del kwargs['scope']
# 
#     def _inject(func):
#         class_locals = enclosing_frame().f_locals
# 
#         guice_data = GuiceData.from_class_dict(class_locals)
# 
#         annotations = getattr(func, '__guice_annotations__', {})
# 
#         gmethod = dict((k, GuiceArg(v, annotations.get(k)))
#                        for k, v in kwargs.items())
# 
#         _validate_func_args(func, kwargs)
#         if func.__name__ == '__init__':
#             guice_data.init = gmethod
#         else:
#             guice_data.methods[func.__name__] = gmethod
# 
#         return func
# 
#     return _inject
# 
# Path: snakeguice/modules.py
# class ModuleAdapter(object):
#     """Adapts the simple and standard module interfaces to a common one."""
# 
#     def __init__(self, module, injector):
#         if hasattr(module, 'set_injector'):
#             module.set_injector(injector)
#         self._module = module
# 
#     def configure(self, binder):
#         if hasattr(self._module, 'run_configure'):
#             self._module.run_configure(binder)
#         else:
#             self._module.configure(binder)
# 
# Path: snakeguice/interfaces.py
# class Injector(object):
#     """An interface automatically bound to the current Injector instance."""


import inspect
import warnings
from snakeguice.binder import Binder, Key
from snakeguice.decorators import GuiceData as _GuiceData, inject
from snakeguice.modules import ModuleAdapter
from snakeguice.interfaces import Injector as IInjector

        key = Key(cls, annotation)
        binding = self._binder.get_binding(key)
        if binding:
            if isinstance(binding.provider, type):
                binding.provider = self.get_instance(binding.provider)
            provider = binding.scope.scope(key, binding.provider)
            if isinstance(provider, type):
                provider = self.get_instance(provider)
            return provider.get()
        else:
            instance = self.create_object(cls)
            return self.inject_members(instance)

    def create_child(self, modules):
        """Create a new injector that inherits the state from this injector.

        All bindings are inherited. In the future this may become closer to
        child injectors on google-guice.
        """
        binder = self._binder.create_child()
        return Injector(modules, binder=binder, stage=self._stage)

    def create_object(self, cls):
        if not hasattr(cls, '__mro__'):
            warnings.warn("can't create an instance of %r - no __mro__; "
                         "this legacy behavior will be removed in a future "
                          "version")
            return cls


# Path: snakeguice/binder.py
# class Binder(object):
# 
#     def __init__(self, parent=None):
#         self._parent = parent or _EmptyBinder()
#         self._binding_map = {}
# 
#     def bind(self, _class, **kwargs):
#         key = Key(interface=_class, annotation=kwargs.get('annotated_with'))
# 
#         binding = Binding()
#         binding.key = key
#         binding.scope = kwargs.get('in_scope', scopes.NO_SCOPE)
# 
#         if key in self._binding_map:
#             raise errors.BindingError('baseclass %r already bound' % _class)
# 
#         if 'to' in kwargs:
#             if not isinstance(kwargs['to'], type):
#                 raise errors.BindingError("'to' requires a new-style class")
# 
#             binding.provider = providers.create_simple_provider(kwargs['to'])
# 
#         elif 'to_provider' in kwargs:
#             #TODO: add some validation
#             provider = kwargs['to_provider']
#             binding.provider = provider
# 
#         elif 'to_instance' in kwargs:
#             if not isinstance(kwargs['to_instance'], object):
#                 raise errors.BindingError(
#                     "'to_instance' requires an instance of a new-style class")
# 
#             provider = kwargs['to_instance']
#             binding.provider = providers.create_instance_provider(provider)
# 
#         self._binding_map[key] = binding
# 
#     def get_binding(self, key):
#         return self._binding_map.get(key) or self._parent.get_binding(key)
# 
#     def create_child(self):
#         return Binder(self)
# 
# class Key(object):
# 
#     def __init__(self, interface, annotation=None):
#         self._interface = interface
#         self._annotation = annotation
# 
#     def __hash__(self):
#         return hash((self._interface, self._annotation))
# 
#     def __eq__(self, other):
#         return (self._interface == other._interface and
#                 self._annotation == other._annotation)
# 
#     def __ne__(self, other):
#         return not self == other
# 
# Path: snakeguice/decorators.py
# class GuiceData(object):
# 
#     def __init__(self):
#         self.init = None
#         self.methods = {}
# 
#     @classmethod
#     def from_class(cls, target_class):
#         if '__guice__' not in target_class.__dict__:
#             guice_data = cls()
#             try:
#                 target_class.__guice__ = guice_data
#             except TypeError: # special case for builtin/extension types
#                 return guice_data
#         return target_class.__guice__
# 
#     @classmethod
#     def composite_from_class(cls, target_class):
#         composite_data = GuiceData()
#         for _cls in target_class.__mro__[-1::-1]:
#             data = GuiceData.from_class(_cls)
#             if data.init: # only the last class in the chain
#                 composite_data.init = data.init
#             for name, method in data.methods.items():
#                 composite_data.methods[name] = method
# 
#         return composite_data
# 
#     @classmethod
#     def from_class_dict(cls, class_dict):
#         if '__guice__' not in class_dict:
#             class_dict['__guice__'] = cls()
#         return class_dict['__guice__']
# 
# def inject(**kwargs):
# 
#     scope = kwargs.get('scope')
#     if 'scope' in kwargs:
#         del kwargs['scope']
# 
#     def _inject(func):
#         class_locals = enclosing_frame().f_locals
# 
#         guice_data = GuiceData.from_class_dict(class_locals)
# 
#         annotations = getattr(func, '__guice_annotations__', {})
# 
#         gmethod = dict((k, GuiceArg(v, annotations.get(k)))
#                        for k, v in kwargs.items())
# 
#         _validate_func_args(func, kwargs)
#         if func.__name__ == '__init__':
#             guice_data.init = gmethod
#         else:
#             guice_data.methods[func.__name__] = gmethod
# 
#         return func
# 
#     return _inject
# 
# Path: snakeguice/modules.py
# class ModuleAdapter(object):
#     """Adapts the simple and standard module interfaces to a common one."""
# 
#     def __init__(self, module, injector):
#         if hasattr(module, 'set_injector'):
#             module.set_injector(injector)
#         self._module = module
# 
#     def configure(self, binder):
#         if hasattr(self._module, 'run_configure'):
#             self._module.run_configure(binder)
#         else:
#             self._module.configure(binder)
# 
# Path: snakeguice/interfaces.py
# class Injector(object):
#     """An interface automatically bound to the current Injector instance."""


# Path: snakeguice/injector.py
import inspect
import warnings
from snakeguice.binder import Binder, Key
from snakeguice.decorators import GuiceData as _GuiceData, inject
from snakeguice.modules import ModuleAdapter
from snakeguice.interfaces import Injector as IInjector


        key = Key(cls, annotation)
        binding = self._binder.get_binding(key)
        if binding:
            if isinstance(binding.provider, type):
                binding.provider = self.get_instance(binding.provider)
            provider = binding.scope.scope(key, binding.provider)
            if isinstance(provider, type):
                provider = self.get_instance(provider)
            return provider.get()
        else:
            instance = self.create_object(cls)
            return self.inject_members(instance)

    def create_child(self, modules):
        """Create a new injector that inherits the state from this injector.

        All bindings are inherited. In the future this may become closer to
        child injectors on google-guice.
        """
        binder = self._binder.create_child()
        return Injector(modules, binder=binder, stage=self._stage)

    def create_object(self, cls):
        if not hasattr(cls, '__mro__'):
            warnings.warn("can't create an instance of %r - no __mro__; "
                         "this legacy behavior will be removed in a future "
                          "version")
            return cls


        guice_data = _GuiceData.composite_from_class(cls)