Skip to content

Commit

Permalink
Performance optimisations
Browse files Browse the repository at this point in the history
Renamed __instantiated to __instantiated__
  • Loading branch information
simoncoulton committed Feb 2, 2014
1 parent 1a016cb commit 61c7499
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 49 deletions.
5 changes: 0 additions & 5 deletions tests/watson/di/test_container.py
Expand Up @@ -59,11 +59,6 @@ def test_add_dict(self):
container.add('dep', dep)
assert container.get('dep') == dep

def test_definition_doesnt_exist(self):
with raises(KeyError):
container = IocContainer()
container.get('test')

def test_definition_item_doesnt_exist(self):
with raises(KeyError):
container = IocContainer({
Expand Down
2 changes: 1 addition & 1 deletion tests/watson/di/test_processors.py
Expand Up @@ -59,7 +59,7 @@ def test_invalid_processor(self):
processor('fake event')

def test_initialized_invalid_dependency(self):
with raises(NameError):
with raises(ImportError):
processor = processors.ConstructorInjection()
processor.container = IocContainer()
event = sample_event('tests.watson.di.support.DoesNotExist')
Expand Down
2 changes: 1 addition & 1 deletion watson/di/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
__version__ = '1.0.0'
__version__ = '1.0.1'


class ContainerAware(object):
Expand Down
35 changes: 16 additions & 19 deletions watson/di/container.py
Expand Up @@ -84,15 +84,15 @@ class IocContainer(EventDispatcherAware):
Attributes:
config (dict): A dict containing the definitions, params and processors.
__instantiated (dict): A cache of already instantiated dependencies.
__instantiated__ (dict): A cache of already instantiated dependencies.
"""
config = None
__instantiated = None
__instantiated__ = None

@property
def instantiated(self):
return self.__instantiated
return self.__instantiated__

@property
def params(self):
Expand All @@ -119,7 +119,7 @@ def __init__(self, config=None):
config (dict): A dict containing the params, definitions and processors.
"""
self.config = dict_deep_update(DEFAULTS, config or {})
self.__instantiated = {}
self.__instantiated__ = {}
for event, listeners in self.config['processors'].items():
for processor in listeners:
self.attach_processor(
Expand All @@ -139,13 +139,14 @@ def get(self, name):
mixed: The dependency
"""
definition = self.__find(name)
if name not in self.__instantiated \
or definition.get('type', 'singleton').lower() == 'prototype' \
or isinstance(self.__instantiated.get(name), FunctionType):
instantiated = self.__create_instance(name, definition)
self.__instantiated[name] = instantiated
if (name in self.__instantiated__
and definition.get('type', '').lower() == 'singleton'
and not isinstance(self.__instantiated__.get(name),
FunctionType)):
instantiated = self.__instantiated__[name]
else:
instantiated = self.__instantiated[name]
instantiated = self.__create_instance(name, definition)
self.__instantiated__[name] = instantiated
return instantiated

def add(self, name, item, type='singleton', **kwargs):
Expand All @@ -159,7 +160,7 @@ def add(self, name, item, type='singleton', **kwargs):
definition.update(**kwargs)
self.definitions[name] = definition
if not isinstance(item, str):
self.__instantiated[name] = item
self.__instantiated__[name] = item

def __contains__(self, dependency):
"""Returns whether or not a dependency is defined in the container.
Expand All @@ -177,15 +178,11 @@ def __find(self, name):
"""
definitions = self.definitions
if name not in definitions:
try:
load_definition_from_string(name)
self.add(name, name)
definitions = self.definitions
except:
raise KeyError('Dependency {} does not exist'.format(name))
if 'item' not in definitions[name]:
raise KeyError('item not specified in dependency definition')
self.add(name, name)
definitions = self.definitions
definition = definitions[name]
if 'item' not in definition:
raise KeyError('item not specified in dependency definition')
definition['type'] = definition.get('type', 'singleton').lower()
return definition

Expand Down
40 changes: 17 additions & 23 deletions watson/di/processors.py
Expand Up @@ -43,32 +43,26 @@ class ConstructorInjection(Base):

def __call__(self, event):
item = event.target['item']
instantiated = False
raw = None
if isinstance(item, FunctionType):
raw = item
imported_item = item
elif not isinstance(item, str):
initialized = item
instantiated = True
return item
else:
with ignored(ImportError, AttributeError):
raw = load_definition_from_string(item)
if not instantiated:
if not raw:
raise NameError(
'Cannot initialize dependency {0}, the module may not exist.'.format(item))
args, kwargs = [], {}
if isinstance(raw, FunctionType):
kwargs['container'] = self.container
init = event.target.get('init', {})
if isinstance(init, dict):
for key, val in init.items():
kwargs[key] = get_param_from_container(val, self.container)
elif isinstance(init, list):
for arg in init:
args.append(get_param_from_container(arg, self.container))
initialized = raw(*args, **kwargs)
return initialized
try:
imported_item = load_definition_from_string(item)
except Exception as exc:
raise ImportError('Cannot initialize dependency {0}, the module may not exist.'.format(item)) from exc
init = event.target.get('init', {})
args, kwargs = [], {}
if isinstance(imported_item, FunctionType):
kwargs['container'] = self.container
if isinstance(init, dict):
for key, val in init.items():
kwargs[key] = get_param_from_container(val, self.container)
elif isinstance(init, list):
for arg in init:
args.append(get_param_from_container(arg, self.container))
return imported_item(*args, **kwargs)


class SetterInjection(Base):
Expand Down

0 comments on commit 61c7499

Please sign in to comment.