Searches for the underlying module behind the name to some python object. Returns the module and the object name (original name with module part removed).
(obj_name: str)
| 234 | # ------------------------------------------------------------------------------------------ |
| 235 | |
| 236 | def get_module_from_obj_name(obj_name: str) -> Tuple[types.ModuleType, str]: |
| 237 | """Searches for the underlying module behind the name to some python object. |
| 238 | Returns the module and the object name (original name with module part removed).""" |
| 239 | |
| 240 | # allow convenience shorthands, substitute them by full names |
| 241 | obj_name = re.sub("^np.", "numpy.", obj_name) |
| 242 | obj_name = re.sub("^tf.", "tensorflow.", obj_name) |
| 243 | |
| 244 | # list alternatives for (module_name, local_obj_name) |
| 245 | parts = obj_name.split(".") |
| 246 | name_pairs = [(".".join(parts[:i]), ".".join(parts[i:])) for i in range(len(parts), 0, -1)] |
| 247 | |
| 248 | # try each alternative in turn |
| 249 | for module_name, local_obj_name in name_pairs: |
| 250 | try: |
| 251 | module = importlib.import_module(module_name) # may raise ImportError |
| 252 | get_obj_from_module(module, local_obj_name) # may raise AttributeError |
| 253 | return module, local_obj_name |
| 254 | except: |
| 255 | pass |
| 256 | |
| 257 | # maybe some of the modules themselves contain errors? |
| 258 | for module_name, _local_obj_name in name_pairs: |
| 259 | try: |
| 260 | importlib.import_module(module_name) # may raise ImportError |
| 261 | except ImportError: |
| 262 | if not str(sys.exc_info()[1]).startswith("No module named '" + module_name + "'"): |
| 263 | raise |
| 264 | |
| 265 | # maybe the requested attribute is missing? |
| 266 | for module_name, local_obj_name in name_pairs: |
| 267 | try: |
| 268 | module = importlib.import_module(module_name) # may raise ImportError |
| 269 | get_obj_from_module(module, local_obj_name) # may raise AttributeError |
| 270 | except ImportError: |
| 271 | pass |
| 272 | |
| 273 | # we are out of luck, but we have no idea why |
| 274 | raise ImportError(obj_name) |
| 275 | |
| 276 | |
| 277 | def get_obj_from_module(module: types.ModuleType, obj_name: str) -> Any: |
no test coverage detected