diff --git a/objects/catalog.py b/objects/catalog.py index c0f28435..c589dbe9 100644 --- a/objects/catalog.py +++ b/objects/catalog.py @@ -7,6 +7,8 @@ class AbstractCatalog(object): """Abstract object provides catalog.""" + __slots__ = ('__used_providers__',) + def __init__(self, *used_providers): """Initializer.""" self.__used_providers__ = set(used_providers) diff --git a/objects/injections.py b/objects/injections.py index a039243e..63bdbf8d 100644 --- a/objects/injections.py +++ b/objects/injections.py @@ -1,10 +1,15 @@ """Injections module.""" +from .utils import is_provider + class Injection(object): """Base injection class.""" + __IS_OBJECTS_INJECTION__ = True + __slots__ = ('__IS_OBJECTS_INJECTION__', 'name', 'injectable') + def __init__(self, name, injectable): """Initializer.""" self.name = name @@ -13,7 +18,7 @@ class Injection(object): @property def value(self): """Return injectable value.""" - if hasattr(self.injectable, '__is_objects_provider__'): + if is_provider(self.injectable): return self.injectable() return self.injectable @@ -22,12 +27,21 @@ class InitArg(Injection): """Init argument injection.""" + __IS_OBJECTS_INIT_ARG_INJECTION__ = True + __slots__ = ('__IS_OBJECTS_INIT_ARG_INJECTION__',) + class Attribute(Injection): """Attribute injection.""" + __IS_OBJECTS_ATTRIBUTE_INJECTION__ = True + __slots__ = ('__IS_OBJECTS_ATTRIBUTE_INJECTION__',) + class Method(Injection): """Method injection.""" + + __IS_OBJECTS_METHOD_INJECTION__ = True + __slots__ = ('__IS_OBJECTS_METHOD_INJECTION__',) diff --git a/objects/providers.py b/objects/providers.py index 85b19c4a..31a1e1e6 100644 --- a/objects/providers.py +++ b/objects/providers.py @@ -2,18 +2,18 @@ from collections import Iterable -from .injections import Injection -from .injections import InitArg -from .injections import Attribute -from .injections import Method +from .utils import is_injection +from .utils import is_init_arg_injection +from .utils import is_attribute_injection +from .utils import is_method_injection class Provider(object): """Base provider class.""" - __is_objects_provider__ = True - __overridden_by__ = list() + __IS_OBJECTS_PROVIDER__ = True + __slots__ = ('__IS_OBJECTS_PROVIDER__', '__overridden_by__',) def __init__(self): """Initializer.""" @@ -36,6 +36,8 @@ class ProviderDelegate(Provider): """Provider's delegate.""" + __slots__ = ('delegated',) + def __init__(self, delegated): """Initializer. @@ -56,12 +58,14 @@ class NewInstance(Provider): New instance providers will create and return new instance on every call. """ + __slots__ = ('provides', 'init_args', 'attributes', 'methods') + def __init__(self, provides, *injections): """Initializer.""" self.provides = provides - self.init_injections = _fetch_injections(injections, InitArg) - self.attribute_injections = _fetch_injections(injections, Attribute) - self.method_injections = _fetch_injections(injections, Method) + self.init_args = tuple(filter(is_init_arg_injection, injections)) + self.attributes = tuple(filter(is_attribute_injection, injections)) + self.methods = tuple(filter(is_method_injection, injections)) super(NewInstance, self).__init__() def __call__(self, *args, **kwargs): @@ -70,17 +74,17 @@ class NewInstance(Provider): return self.__overridden_by__[-1].__call__(*args, **kwargs) init_injections = dict(((injection.name, injection.value) - for injection in self.init_injections)) + for injection in self.init_args)) init_injections.update(kwargs) instance = self.provides(*args, **init_injections) - if not self.attribute_injections: - for injection in self.attribute_injections: + if not self.attributes: + for injection in self.attributes: setattr(instance, injection.name, injection.value) - if not self.method_injections: - for injection in self.method_injections: + if not self.methods: + for injection in self.methods: getattr(instance, injection.name)(injection.value) return instance @@ -93,6 +97,8 @@ class Singleton(NewInstance): Singleton provider will create instance once and return it on every call. """ + __slots__ = ('instance',) + def __init__(self, *args, **kwargs): """Initializer.""" self.instance = None @@ -117,6 +123,8 @@ class Scoped(Singleton): on every call. """ + __slots__ = ('is_in_scope',) + def __init__(self, *args, **kwargs): """Initializer.""" self.is_in_scope = None @@ -153,6 +161,8 @@ class ExternalDependency(Provider): """External dependency provider.""" + __slots__ = ('instance_of', 'dependency') + def __init__(self, instance_of): """Initializer.""" if not isinstance(instance_of, Iterable): @@ -190,6 +200,8 @@ class _StaticProvider(Provider): it got on input. """ + __slots__ = ('provides',) + def __init__(self, provides): """Initializer.""" self.provides = provides @@ -230,10 +242,12 @@ class Callable(Provider): dependencies injections. """ + __slots__ = ('calls', 'injections') + def __init__(self, calls, *injections): """Initializer.""" self.calls = calls - self.injections = _fetch_injections(injections, Injection) + self.injections = tuple(filter(is_injection, injections)) super(Callable, self).__init__() def __call__(self, *args, **kwargs): @@ -256,6 +270,8 @@ class Config(Provider): deferred config objects for all undefined attribute calls. """ + __slots__ = ('value',) + def __init__(self, value=None): """Initializer.""" if not value: @@ -288,6 +304,8 @@ class _DeferredConfig(Provider): Deferred config providers provide an value from the root config object. """ + __slots__ = ('paths', 'root_config') + def __init__(self, paths, root_config): """Initializer.""" self.paths = paths @@ -302,10 +320,3 @@ class _DeferredConfig(Provider): def __call__(self, *args, **kwargs): """Return provided instance.""" return self.root_config(self.paths) - - -def _fetch_injections(injections, injection_type): - """Fetch injections of injection type from list.""" - return tuple([injection - for injection in injections - if isinstance(injection, injection_type)]) diff --git a/objects/utils.py b/objects/utils.py new file mode 100644 index 00000000..c8a3f877 --- /dev/null +++ b/objects/utils.py @@ -0,0 +1,26 @@ +"""Utils module.""" + + +def is_provider(instance): + """Check if instance is provider instance.""" + return hasattr(instance, '__IS_OBJECTS_PROVIDER__') + + +def is_injection(instance): + """Check if instance is injection instance.""" + return hasattr(instance, '__IS_OBJECTS_INJECTION__') + + +def is_init_arg_injection(instance): + """Check if instance is init arg injection instance.""" + return hasattr(instance, '__IS_OBJECTS_INIT_ARG_INJECTION__') + + +def is_attribute_injection(instance): + """Check if instance is attribute injection instance.""" + return hasattr(instance, '__IS_OBJECTS_ATTRIBUTE_INJECTION__') + + +def is_method_injection(instance): + """Check if instance is method injection instance.""" + return hasattr(instance, '__IS_OBJECTS_METHOD_INJECTION__')