import sys import types from pydoc import safeimport, resolve, ErrorDuringImport from pkgutil import iter_modules from elpy import compat # Types we want to recurse into (nodes). CONTAINER_TYPES = (type, types.ModuleType) # Types of attributes we can get documentation for (leaves). PYDOC_TYPES = (type, types.FunctionType, types.BuiltinFunctionType, types.BuiltinMethodType, types.MethodType, types.ModuleType) if not compat.PYTHON3: # pragma: nocover # Python 2 old style classes CONTAINER_TYPES = tuple(list(CONTAINER_TYPES) + [types.ClassType]) PYDOC_TYPES = tuple(list(PYDOC_TYPES) + [types.ClassType]) def get_pydoc_completions(modulename): """Get possible completions for modulename for pydoc. Returns a list of possible values to be passed to pydoc. """ modulename = compat.ensure_not_unicode(modulename) modulename = modulename.rstrip(".") if modulename == "": return sorted(get_modules()) candidates = get_completions(modulename) if candidates: return sorted(candidates) needle = modulename if "." in needle: modulename, part = needle.rsplit(".", 1) candidates = get_completions(modulename) else: candidates = get_modules() return sorted(candidate for candidate in candidates if candidate.startswith(needle)) def get_completions(modulename): modules = set("{0}.{1}".format(modulename, module) for module in get_modules(modulename)) try: module, name = resolve(modulename) except ImportError: return modules if isinstance(module, CONTAINER_TYPES): modules.update("{0}.{1}".format(modulename, name) for name in dir(module) if not name.startswith("_") and isinstance(getattr(module, name), PYDOC_TYPES)) return modules def get_modules(modulename=None): """Return a list of modules and packages under modulename. If modulename is not given, return a list of all top level modules and packages. """ modulename = compat.ensure_not_unicode(modulename) if not modulename: try: return ([modname for (importer, modname, ispkg) in iter_modules() if not modname.startswith("_")] + list(sys.builtin_module_names)) except OSError: # Bug in Python 2.6, see #275 return list(sys.builtin_module_names) try: module = safeimport(modulename) except ErrorDuringImport: return [] if module is None: return [] if hasattr(module, "__path__"): return [modname for (importer, modname, ispkg) in iter_modules(module.__path__) if not modname.startswith("_")] return []