2 Copyright (c) 2019 Intel Corporation
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
17 # pylint: disable=protected-access
20 class ProvidedWrapper:
21 def __init__(self, provided):
22 self.provided = provided
25 class UnresolvedDependencyException(ValueError):
27 def __init__(self, provider, missing_dependencies) -> None:
29 self.provider = provider
30 self.missing_dependencies = missing_dependencies
31 self.message = "Unresolved dependencies ({}) for provider {}".format(
32 ", ".join(self.missing_dependencies), self.provider
36 def get_opts(options):
39 options: options object.
41 args (tuple): positional options.
42 kwargs (map): keyword arguments.
45 if isinstance(options, tuple):
46 if len(options) == 2 and isinstance(options[-1], dict):
47 args, kwargs = options
51 elif isinstance(options, dict):
52 args, kwargs = (), options
54 raise ValueError("Options object expected to be either pair of (args, kwargs) or only args/kwargs")
61 __provider_type__ = None
65 def provide(cls, provider, *args, **kwargs):
66 root_provider = cls.resolve(provider)
67 return root_provider(*args, **kwargs)
70 def resolve(cls, name):
71 if name not in cls.providers:
72 raise ValueError("Requested provider not registered")
73 return cls.providers[name]
76 class ClassProviderMeta(type):
77 def __new__(mcs, name, bases, attrs, **kwargs):
78 cls = super().__new__(mcs, name, bases, attrs)
79 # do not create container for abstract provider
80 if '_is_base_provider' in attrs:
83 assert issubclass(cls, ClassProvider), "Do not use metaclass directly"
84 if '__provider_type__' in attrs:
87 cls.register_provider(cls)
92 class ClassProvider(BaseProvider, metaclass=ClassProviderMeta):
93 _is_base_provider = True
96 def get_provider_name(cls):
97 return getattr(cls, '__provider__', cls.__name__)
100 def register_provider(cls, provider):
101 provider_name = cls.get_provider_name()
102 if not provider_name:
104 cls.providers[provider_name] = provider
107 def provide(service):
108 return ProvidedWrapper(service)