@@ -66,6 +66,7 @@ class DynamicContainer(Container):
6666 self .provider_type = providers.Provider
6767 self .providers = {}
6868 self .overridden = tuple ()
69+ self .parent = None
6970 self .declarative_parent = None
7071 self .wired_to_modules = []
7172 self .wired_to_packages = []
@@ -92,6 +93,8 @@ class DynamicContainer(Container):
9293 for name, provider in providers.deepcopy(self .providers, memo).items():
9394 copied.set_provider(name, provider)
9495
96+ copied.parent = providers.deepcopy(self .parent, memo)
97+
9598 return copied
9699
97100 def __setattr__ (self , str name , object value ):
@@ -108,9 +111,16 @@ class DynamicContainer(Container):
108111
109112 :rtype: None
110113 """
111- if isinstance (value, providers.Provider) and not isinstance (value, providers.Self):
114+ if isinstance (value, providers.Provider) \
115+ and not isinstance (value, providers.Self) \
116+ and name != ' parent' :
112117 _check_provider_type(self , value)
118+
113119 self .providers[name] = value
120+
121+ if isinstance (value, providers.CHILD_PROVIDERS):
122+ value.assign_parent(self )
123+
114124 super (DynamicContainer, self ).__setattr__(name, value)
115125
116126 def __delattr__ (self , str name ):
@@ -295,6 +305,29 @@ class DynamicContainer(Container):
295305 for provider in self .traverse(types = [providers.BaseSingleton]):
296306 provider.reset()
297307
308+ def resolve_provider_name (self , provider ):
309+ """ Try to resolve provider name."""
310+ for provider_name, container_provider in self .providers.items():
311+ if container_provider is provider:
312+ return provider_name
313+ else :
314+ raise errors.Error(f' Can not resolve name for provider "{provider}"' )
315+
316+ @property
317+ def parent_name (self ):
318+ """ Return parent name."""
319+ if self .parent:
320+ return self .parent.parent_name
321+
322+ if self .declarative_parent:
323+ return self .declarative_parent.__name__
324+
325+ return None
326+
327+ def assign_parent (self , parent ):
328+ """ Assign parent."""
329+ self .parent = parent
330+
298331
299332class DeclarativeContainerMetaClass (type ):
300333 """ Declarative inversion of control container meta class."""
@@ -341,6 +374,10 @@ class DeclarativeContainerMetaClass(type):
341374 for provider in six.itervalues(cls .providers):
342375 _check_provider_type(cls , provider)
343376
377+ for provider in six.itervalues(cls .cls_providers):
378+ if isinstance (provider, providers.CHILD_PROVIDERS):
379+ provider.assign_parent(cls )
380+
344381 return cls
345382
346383 def __setattr__ (cls , str name , object value ):
@@ -359,6 +396,10 @@ class DeclarativeContainerMetaClass(type):
359396 """
360397 if isinstance (value, providers.Provider) and name != ' __self__' :
361398 _check_provider_type(cls , value)
399+
400+ if isinstance (value, providers.CHILD_PROVIDERS):
401+ value.assign_parent(cls )
402+
362403 cls .providers[name] = value
363404 cls .cls_providers[name] = value
364405 super (DeclarativeContainerMetaClass, cls ).__setattr__(name, value)
@@ -399,6 +440,19 @@ class DeclarativeContainerMetaClass(type):
399440 """ Return providers traversal generator."""
400441 yield from providers.traverse(* cls .providers.values(), types = types)
401442
443+ def resolve_provider_name (cls , provider ):
444+ """ Try to resolve provider name."""
445+ for provider_name, container_provider in cls .providers.items():
446+ if container_provider is provider:
447+ return provider_name
448+ else :
449+ raise errors.Error(f' Can not resolve name for provider "{provider}"' )
450+
451+ @property
452+ def parent_name (cls ):
453+ """ Return parent name."""
454+ return cls .__name__
455+
402456 @staticmethod
403457 def __fetch_self (attributes ):
404458 self = None
0 commit comments