vFW and vDNS support added to azure-plugin
[multicloud/azure.git] / azure / aria / aria-extension-cloudify / src / aria / aria / utils / imports.py
1 # Licensed to the Apache Software Foundation (ASF) under one or more
2 # contributor license agreements.  See the NOTICE file distributed with
3 # this work for additional information regarding copyright ownership.
4 # The ASF licenses this file to You under the Apache License, Version 2.0
5 # (the "License"); you may not use this file except in compliance with
6 # the License.  You may obtain a copy of the License at
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
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.
15
16 """
17 Utilities for dynamically loading Python code.
18 """
19
20 import pkgutil
21 import importlib
22
23
24 def import_fullname(name, paths=None):
25     """
26     Imports a variable or class based on a full name, optionally searching for it in the paths.
27     """
28     paths = paths or []
29     if name is None:
30         return None
31
32     def do_import(name):
33         if name and ('.' in name):
34             module_name, name = name.rsplit('.', 1)
35             return getattr(__import__(module_name, fromlist=[name], level=0), name)
36         else:
37             raise ImportError('import not found: %s' % name)
38
39     try:
40         return do_import(name)
41     except ImportError:
42         for path in paths:
43             try:
44                 return do_import('%s.%s' % (path, name))
45             except Exception as e:
46                 raise ImportError('cannot import %s, because %s' % (name, e))
47
48     raise ImportError('import not found: %s' % name)
49
50
51 def import_modules(name):
52     """
53     Imports a module and all its sub-modules, recursively. Relies on modules defining a ``MODULES``
54     attribute listing their sub-module names.
55     """
56
57     module = __import__(name, fromlist=['MODULES'], level=0)
58     if hasattr(module, 'MODULES'):
59         for module_ in module.MODULES:
60             import_modules('%s.%s' % (name, module_))
61
62
63 # TODO merge with import_fullname
64 def load_attribute(attribute_path):
65     """
66     Dynamically load an attribute based on the path to it. E.g.
67     ``some_package.some_module.some_attribute``, will load ``some_attribute`` from the
68     ``some_package.some_module`` module.
69     """
70     module_name, attribute_name = attribute_path.rsplit('.', 1)
71     try:
72         module = importlib.import_module(module_name)
73         return getattr(module, attribute_name)
74     except ImportError:
75         # TODO: handle
76         raise
77     except AttributeError:
78         # TODO: handle
79         raise
80
81
82 def iter_modules():
83     # apparently pkgutil had some issues in python 2.6. Accessing any root level directories
84     # failed. and it got the entire process of importing fail. Since we only need any
85     # aria_extension related loading, in the meantime we could try to import only those
86     # (and assume they are not located at the root level.
87     # [In python 2.7 it does actually ignore any OSError].
88     yielded = {}
89     for importer in pkgutil.iter_importers():
90         try:
91             for module_name, ispkg in pkgutil.iter_importer_modules(importer):
92                 if module_name not in yielded:
93                     yielded[module_name] = True
94                     yield importer, module_name, ispkg
95         except OSError:
96             pass