def containing(cls, identifier): """ Try to find the module that defines a name such as C{a.b.c} by trying to import C{a}, C{a.b}, and C{a.b.c}. @return: The name of the 'deepest' module (most commonly it would be C{a.b} in this example). @rtype: L{Module} """ # In the code below we catch "Exception" rather than just ImportError # or AttributeError since importing and __getattr__ing can raise other # exceptions. identifier = DottedIdentifier(identifier) try: module = ModuleHandle(identifier[:1]) result = module.module except Exception as e: raise ImportError(e) for part, prefix in zip(identifier, prefixes(identifier))[1:]: try: result = getattr(result, str(part)) except Exception: try: module = cls(prefix) result = module.module except Exception as e: raise ImportError(e) else: if isinstance(result, types.ModuleType): module = cls(result) logger.debug("Imported %r to get %r", module, identifier) return module
def check_xref(self, identifier, container): """ Check that ``identifier`` cross-references a proper symbol. Look in modules that we weren't explicitly asked to look in, if needed. """ if identifier in builtins.__dict__: return True def check_container(): if self.expanded_docindex.find(identifier, container) is not None: return True if isinstance(container, RoutineDoc): tcontainer = self.expanded_docindex.get_vardoc( container.canonical_name) doc = self.expanded_docindex.find(identifier, tcontainer) while (doc is not None and tcontainer not in (None, UNKNOWN) and tcontainer.overrides not in (None, UNKNOWN)): tcontainer = tcontainer.overrides doc = self.expanded_docindex.find(identifier, tcontainer) return doc is not None return False def check_defining_module(x): if x is None: return False defining_module_name = remove_epydoc_sym_suffix(str( x.defining_module.canonical_name)) if defining_module_name in ASSUME_MODULES_OK: return True if self.expanded_docindex.add_module(defining_module_name): if check_container(): return True return False if check_container(): return True if (isinstance(container, RoutineDoc) and identifier in container.all_args()): return True if check_defining_module(container): return True # If the user has imported foo.bar.baz as baz and now uses # ``baz.quux``, we need to add the module foo.bar.baz. for prefix in reversed(list(prefixes( DottedIdentifier(remove_epydoc_sym_suffix(identifier))))): if check_defining_module( self.docindex.find(str(prefix), container)): return True try: module = ModuleHandle.containing(identifier) except ImportError: pass else: if str(module.name) in ASSUME_MODULES_OK: return True if self.expanded_docindex.add_module(module): if check_container(): return True return False
def test_prefixes_1(): assert list(prefixes("abcd")) == ['a', 'ab', 'abc', 'abcd']