def get_members(clazz, obj, typ): names = set() items = [] # the default dir for name in dir(obj): try: documenter = get_documenter(safe_getattr(obj, name), obj) except AttributeError: continue if documenter.objtype == typ and not name.startswith('_'): if name not in AutoCosmoSummary.exclude: items.append((clazz,name)) names.add(name) # keep track of method/attribute conflicts # the delegate dro for n in obj.dro: for name in dir(n): try: documenter = get_documenter(safe_getattr(n, name), n) except AttributeError: continue # dont do conflicts if name not in names: if documenter.objtype == typ and not name.startswith('_'): if name not in AutoCosmoSummary.exclude: x = "%s.%s" %(n.__module__, n.__name__) items.append((x,name)) names.add(name) return ['~%s.%s' %item for item in sorted(items, key=lambda x: x[1])]
def get_members (obj, typ): items = [ (name, get_methods_etc(getattr(obj, name))) for name in dir(obj) if get_documenter(getattr(obj, name), obj).objtype == typ ] return items
def get_members_class(obj, typ, include_public=[], include_base=False): """ typ = None -> all include_base -> include attrs that are from a base class """ items = [] # using dir gets all of the attributes, including the elements # from the base class, otherwise use __slots__ or __dict__ if include_base: names = dir(obj) else: if hasattr(obj, '__slots__'): names = tuple(getattr(obj, '__slots__')) else: names = getattr(obj, '__dict__').keys() for name in names: try: documenter = get_documenter(safe_getattr(obj, name), obj) except AttributeError: continue if typ is None or documenter.objtype == typ: items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items
def get_members(obj, typ, include_public=[]): items = [ name for name in dir(obj) if get_documenter(getattr(obj, name), obj).objtype == typ ] public = [x for x in items if x in include_public or not x.startswith('_')] return public, items
def get_members(obj, typ, include_public=[]): items = [] for name in dir(obj): try: if get_documenter(getattr(obj, name)).objtype == typ: items.append(name) except AttributeError: warn("[autosummary] problem accessing attribute " "'%s' in '%s'." % (name, obj)) public = [x for x in items if x in include_public or not x.startswith("_")] return public, items
def get_members(obj, typ, include_public=[]): items = [] for name in dir(obj): try: documenter = get_documenter(safe_getattr(obj, name), obj) except AttributeError: continue if documenter.objtype == typ: items.append(name) public = [x for x in items if x in include_public or not x.startswith("_")] return public, items
def get_members(obj, typ, include_public=None): if not include_public: include_public = [] items = [] for name in sorted(obj.__dict__.keys()):#dir(obj): try: documenter = get_documenter(AutoAutoSummary.app, safe_getattr(obj, name), obj) except AttributeError: continue if documenter.objtype in typ: items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items
def get_members(obj, typ, include_public=None): if not include_public: include_public = [] items = [] for name in dir(obj): try: documenter = get_documenter(app, safe_getattr(obj, name), obj) except AttributeError: continue if documenter.objtype == typ: items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items
def get_members(app, obj, typ, include_public=(), imported=False): items = [] for name in dir(obj): try: obj_name = safe_getattr(obj, name) try: documenter = get_documenter(app, obj_name, obj) except TypeError: documenter = get_documenter(obj_name, obj) except AttributeError: continue if documenter.objtype == typ: try: cond = imported or (obj_name.__module__ == obj.__name__) except AttributeError: cond = True if cond: items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items
def get_members_mod(obj, typ, include_public=[]): """ typ = None -> all """ items = [] for name in dir(obj): try: if SPHINX_LT_17: documenter = get_documenter( safe_getattr(obj, name), obj) else: documenter = get_documenter( app, safe_getattr(obj, name), obj) except AttributeError: continue if typ is None or documenter.objtype == typ: items.append(name) public = [ x for x in items if x in include_public or not x.startswith('_') ] return public, items
def get_members(doc, obj, typ, include_public=None, signal=False, enum=False): try: if not include_public: include_public = [] items = [] for name in dir(obj): if name not in obj.__dict__.keys(): continue try: chobj = safe_getattr(obj, name) documenter = get_documenter(doc.settings.env.app, chobj, obj) #cl = get_class_that_defined_method(chobj) #print(name, chobj.__qualname__, type(chobj), issubclass(chobj, Enum), documenter.objtype) if documenter.objtype == typ: if typ == 'attribute': if signal and type( chobj) != PyQt5.QtCore.pyqtSignal: continue if not signal and type( chobj) == PyQt5.QtCore.pyqtSignal: continue # skip monkey patched enums # the monkeypatched enums coming out of scoped enum inherit Enum # while the standard/old ones do not if hasattr(chobj, '__objclass__') and issubclass( chobj.__objclass__, Enum): continue elif typ == 'class': if enum: if not issubclass(chobj, Enum): continue if not enum and issubclass(chobj, Enum): continue items.append(name) except AttributeError: continue public = [ x for x in items if x in include_public or not x.startswith('_') ] return public, items except BaseException as e: print(str(e)) raise e
def run(self): module_name = str(self.arguments[0]) module = importlib.import_module(module_name) analyzer = ModuleAnalyzer.for_module(module_name) attr_docs = analyzer.find_attr_docs() with open(module.__file__) as module_file: symbols = symtable.symtable(module_file.read(), module.__file__, "exec") members = [] for name in dir(module): member = getattr(module, name) # Ignore private members if name.startswith("_"): continue # Ignore imported modules if isinstance(member, types.ModuleType): continue # Ignore members imported from other modules member_module_name = getattr(member, "__module__", None) if member_module_name is None: try: if symbols.lookup(name).is_imported(): continue except KeyError: continue else: if member_module_name != module_name: continue documenter = get_documenter(self.env.app, member, module) # Ignore data items that do not have docstrings if documenter.objtype == "data" and ("", name) not in attr_docs: continue members.append(name) # Sort members in the order they appear in source code tagorder = analyzer.tagorder members.sort(key=lambda name: tagorder.get(name, len(tagorder))) self.content = [f"{module_name}.{member}" for member in members] return super().run()
def get_members(app, obj, typ, include_public=None): if not include_public: include_public = [] items = [] for name in vars(obj): try: documenter = get_documenter(app, safe_getattr(obj, name), obj) except AttributeError: continue if documenter.objtype == typ: items.append(name) items.sort() public = [x for x in items if x in include_public or not x.startswith('_')] return public, items
def get_members(obj, typ, include_public=[]): # type: (Any, unicode, List[unicode]) -> Tuple[List[unicode], List[unicode]] items = [] # type: List[unicode] for name in dir(obj): try: documenter = get_documenter(safe_getattr(obj, name), obj) except AttributeError: continue if documenter.objtype == typ: items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items
def get_members(obj, typ, include_public=[]): items = [] for name in dir(obj): try: if get_documenter(getattr(obj, name)).objtype == typ: items.append(name) except AttributeError: warn("[autosummary] problem accessing attribute " "'%s' in '%s'." % (name, obj)) public = [ x for x in items if x in include_public or not x.startswith('_') ] return public, items
def get_members_class(obj, typ, include_public=[], include_base=False): """ typ = None -> all include_base -> include attrs that are from a base class """ items = [] # using dir gets all of the attributes, including the elements # from the base class, otherwise use __slots__ or __dict__ if include_base: names = dir(obj) else: if hasattr(obj, '__slots__'): names = tuple(getattr(obj, '__slots__')) else: names = getattr(obj, '__dict__').keys() for name in names: try: if SPHINX_LT_17: documenter = get_documenter( safe_getattr(obj, name), obj) else: documenter = get_documenter( app, safe_getattr(obj, name), obj) except AttributeError: continue if typ is None or documenter.objtype == typ: items.append(name) public = [ x for x in items if x in include_public or not x.startswith('_') ] return public, items
def get_members(obj, typ, include_public=[], imported=False): # type: (Any, unicode, List[unicode], bool) -> Tuple[List[unicode], List[unicode]] # NOQA items = [] # type: List[unicode] for name in dir(obj): try: value = safe_getattr(obj, name) except AttributeError: continue documenter = get_documenter(value, obj) if documenter.objtype == typ: if imported or getattr(value, '__module__', None) == obj.__name__: items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items
def get_public_members(obj, typ, include_public=[]): items = [] for name in dir(obj): attr = None try: attr = safe_getattr(obj, name) documenter = get_documenter(attr, obj) except AttributeError: continue attr_file = get_file(attr) if ((documenter.objtype == typ) and ((attr_file == get_file(obj)) or (attr_file is None)) and ((name in include_public) or not name.startswith('_'))): items.append(name) return items
def get_members(obj: Any, types: Set[str], include_public: List[str] = [], imported: bool = True) -> Tuple[List[str], List[str]]: items = [] # type: List[str] for name in dir(obj): try: value = safe_getattr(obj, name) except AttributeError: continue documenter = get_documenter(app, value, obj) if documenter.objtype in types: if imported or getattr(value, '__module__', None) == obj.__name__: # skip imported members if expected items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items
def get_members(obj, typ, include_public=[]): # type: (Any, unicode, List[unicode]) -> Tuple[List[unicode], List[unicode]] items = [] # type: List[unicode] for name in dir(obj): try: documenter = get_documenter(safe_getattr(obj, name), obj) except AttributeError: continue if documenter.objtype == typ: items.append(name) public = [ x for x in items if x in include_public or not x.startswith('_') ] return public, items
def get_members_mod(obj, typ, include_public=[]): """ typ = None -> all """ items = [] for name in dir(obj): try: documenter = get_documenter(safe_getattr(obj, name), obj) except AttributeError: continue if typ is None or documenter.objtype == typ: items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items
def get_members(obj, typ, include_public=[], imported=True): # type: (Any, unicode, List[unicode], bool) -> Tuple[List[unicode], List[unicode]] # NOQA items = [] # type: List[unicode] for name in dir(obj): try: value = safe_getattr(obj, name) except AttributeError: continue documenter = get_documenter(app, value, obj) if documenter.objtype == typ: if imported or getattr(value, '__module__', None) == obj.__name__: # skip imported members if expected items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items
def get_members_class(obj, typ, include_public=[], include_base=False): """ typ = None -> all include_base -> include attrs that are from a base class """ items = [] # using dir gets all of the attributes, including the elements # from the base class, otherwise use __slots__ or __dict__ if include_base: names = dir(obj) else: # Classes deriving from an ABC using the `abc` module will # have an empty `__slots__` attribute in Python 3, unless # other slots were declared along the inheritance chain. If # the ABC-derived class has empty slots, we'll use the # class `__dict__` instead. declares_slots = (hasattr(obj, '__slots__') and not (type(obj) is abc.ABCMeta and len(obj.__slots__) == 0)) if declares_slots: names = tuple(getattr(obj, '__slots__')) else: names = getattr(obj, '__dict__').keys() for name in names: try: documenter = get_documenter(app, safe_getattr(obj, name), obj) except AttributeError: continue if typ is None or documenter.objtype == typ: items.append(name) elif typ == 'attribute' and documenter.objtype == 'property': # In Sphinx 2.0 and above, properties have a separate # objtype, but we treat them the same here. items.append(name) public = [ x for x in items if x in include_public or not x.startswith('_') ] return public, items
def get_members(self, obj, typ, include_public=None): if not include_public: include_public = [] items = [] for name in obj.__dict__.keys(): try: documenter = get_documenter(obj=safe_getattr(obj, name), parent=obj, app=self.env.app) except AttributeError: continue if documenter.objtype == typ: items.append(name) public = [ x for x in items if x in include_public or not x.startswith('_') ] return public, items
def get_members(obj, typ, include_public=None): if not include_public: include_public = [] items = [] members = dir(obj) members.sort(key=AutoAutoSummary._customSort) for name in members: try: documenter = get_documenter(safe_getattr(obj, name), obj) except AttributeError: continue if documenter.objtype == typ: items.append(name) public = [ x for x in items if x in include_public or not x.startswith('_') ] return public, items
def get_members(obj, typ, include_public=()): __all__ = getattr(obj, '__all__', []) skip_all = not __all__ __all__ += include_public items = [] for name in dir(obj): try: documenter = get_documenter(safe_getattr(obj, name), obj) except AttributeError: continue if documenter.objtype == typ: items.append(name) public = [x for x in items if x in __all__ or skip_all and not x.startswith('_')] # only members with docstrings are considered public public = [x for x in public if safe_getattr(obj, x).__doc__] return public, items
def get_members(obj, typ, include_public=[]): items = [] for name in dir(obj): try: documenter = get_documenter( app, safe_getattr(obj, name), obj) except AttributeError: continue if documenter.objtype == typ: items.append(name) if hasattr(obj, "__all__"): public = [x for x in items if x in obj.__all__] else: public = [x for x in items if x in include_public or not x.startswith('_')] return public, items
def get_members(obj, typ, include_public=[]): items = [] want_all = self.options.inherited_members or \ self.options.members is ALL members = zip(*self.get_object_members(want_all)[1])[0] if self.options.exclude_members: members = [m for m in members if m not in self.options.exclude_members] for name in members: try: documenter = get_documenter(safe_getattr(obj, name), obj) except AttributeError: continue if documenter.objtype == typ: items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items
def get_members(obj, typ, include_public=[]): items = [] want_all = (self.options.inherited_members or self.options.members is ALL) members = zip(*self.get_object_members(want_all)[1])[0] if self.options.exclude_members: members = [m for m in members if m not in self.options.exclude_members] for name in members: try: documenter = get_documenter( safe_getattr(obj, name), obj) except AttributeError: continue if documenter.objtype == typ: items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items
def get_members(obj: Any, types: Set[str], include_public: List[str] = [], imported: bool = True) -> Tuple[List[str], List[str]]: items: List[str] = [] public: List[str] = [] all_members = get_all_members(obj) for name, value in all_members.items(): documenter = get_documenter(app, value, obj) if documenter.objtype in types: # skip imported members if expected if imported or getattr(value, '__module__', None) == obj.__name__: skipped = skip_member(value, name, documenter.objtype) if skipped is True: pass elif skipped is False: # show the member forcedly items.append(name) public.append(name) else: items.append(name) if name in include_public or not name.startswith('_'): # considers member as public public.append(name) return public, items
def _get_members(self, class_obj, member_type, include_in_public=None): """ Return class members of the specified type. class_obj: Class object. member_type: Member type ('method' or 'attribute'). include_in_public: set/list/tuple with member names that should be included in public members in addition to the public names (those starting without underscore). Returns: tuple(public_members, all_members): Names of the class members of the specified member type (public / all). """ try: app = self.state.document.settings.env.app except AttributeError: app = None if not include_in_public: include_in_public = [] all_members = [] for member_name in dir(class_obj): try: documenter = get_documenter( app, safe_getattr(class_obj, member_name), class_obj) except AttributeError: continue if documenter.objtype == member_type: all_members.append(member_name) public_members = [ x for x in all_members if x in include_in_public or not x.startswith('_') ] return public_members, all_members
def generate_autosummary_content(name: str, obj: Any, parent: Any, template: AutosummaryRenderer, template_name: str, imported_members: bool, app: Any, recursive: bool, context: Dict) -> str: doc = get_documenter(app, obj, parent) def skip_member(obj: Any, name: str, objtype: str) -> bool: try: return app.emit_firstresult('autodoc-skip-member', objtype, name, obj, False, {}) except Exception as exc: logger.warning(__('autosummary: failed to determine %r to be documented, ' 'the following exception was raised:\n%s'), name, exc, type='autosummary') return False def get_members(obj: Any, types: Set[str], include_public: List[str] = [], imported: bool = True) -> Tuple[List[str], List[str]]: items = [] # type: List[str] public = [] # type: List[str] for name in dir(obj): try: value = safe_getattr(obj, name) except AttributeError: continue documenter = get_documenter(app, value, obj) if documenter.objtype in types: # skip imported members if expected if imported or getattr(value, '__module__', None) == obj.__name__: skipped = skip_member(value, name, documenter.objtype) if skipped is True: pass elif skipped is False: # show the member forcedly items.append(name) public.append(name) else: items.append(name) if name in include_public or not name.startswith('_'): # considers member as public public.append(name) return public, items def get_modules(obj: Any) -> Tuple[List[str], List[str]]: items = [] # type: List[str] for _, modname, ispkg in pkgutil.iter_modules(obj.__path__): fullname = name + '.' + modname items.append(fullname) public = [x for x in items if not x.split('.')[-1].startswith('_')] return public, items ns = {} # type: Dict[str, Any] ns.update(context) if doc.objtype == 'module': ns['members'] = dir(obj) ns['functions'], ns['all_functions'] = \ get_members(obj, {'function'}, imported=imported_members) ns['classes'], ns['all_classes'] = \ get_members(obj, {'class'}, imported=imported_members) ns['exceptions'], ns['all_exceptions'] = \ get_members(obj, {'exception'}, imported=imported_members) ispackage = hasattr(obj, '__path__') if ispackage and recursive: ns['modules'], ns['all_modules'] = get_modules(obj) elif doc.objtype == 'class': ns['members'] = dir(obj) ns['inherited_members'] = \ set(dir(obj)) - set(obj.__dict__.keys()) ns['methods'], ns['all_methods'] = \ get_members(obj, {'method'}, ['__init__']) ns['attributes'], ns['all_attributes'] = \ get_members(obj, {'attribute', 'property'}) modname, qualname = split_full_qualified_name(name) if doc.objtype in ('method', 'attribute', 'property'): ns['class'] = qualname.rsplit(".", 1)[0] if doc.objtype in ('class',): shortname = qualname else: shortname = qualname.rsplit(".", 1)[-1] ns['fullname'] = name ns['module'] = modname ns['objname'] = qualname ns['name'] = shortname ns['objtype'] = doc.objtype ns['underline'] = len(name) * '=' if template_name: return template.render(template_name, ns) else: return template.render(doc.objtype, ns)
def _get_members(mod, typ=None, include_imported=False, as_refs=False, in__all__=False): """Get (filtered) public/total members of the module or package `mod`. Args: mod: object resulting from importing a module or package typ: filter on members. If None, include all members. If one of 'function', 'class', 'exception', 'data', only include members of the matching type include_imported: If True, also include members that are imports as_refs: If True, return ReST-formatted reference strings for all members, instead of just their names. In combinations with `include_imported` or `in__all__`, these link to the original location where the member is defined in__all__: If True, return only members that are in ``mod.__all__`` Returns: lists `public` and `items`. The lists contains the public and private + public members, as strings. Note: For data members, there is no way to tell whether they were imported or defined locally (without parsing the source code). A module may define one or both attributes __local_data__: list of names of data objects defined locally __imported_data__: dict of names to ReST-formatted references of where a data object originates If either one of these attributes is present, the member will be classified accordingly. Otherwise, it will be classified as local if it appeard in the __all__ list, or as imported otherwise """ roles = { 'function': 'func', 'module': 'mod', 'class': 'class', 'exception': 'exc', 'data': 'data' } # not included, because they cannot occur at modul level: # 'method': 'meth', 'attribute': 'attr', 'instanceattribute': 'attr' def check_typ(typ, mod, member): """Check if mod.member is of the desired typ""" documenter = get_documenter(member, mod) if typ is None: return True if typ == getattr(documenter, 'objtype', None): return True if hasattr(documenter, 'directivetype'): return roles[typ] == getattr(documenter, 'directivetype') def is_local(mod, member, name): """Check whether mod.member is defined locally in module mod""" if hasattr(member, '__module__'): return getattr(member, '__module__') == mod.__name__ else: # we take missing __module__ to mean the member is a data object if hasattr(mod, '__local_data__'): return name in getattr(mod, '__local_data__') if hasattr(mod, '__imported_data__'): return name not in getattr(mod, '__imported_data__') else: return name in getattr(mod, '__all__', []) if typ is not None and typ not in roles: raise ValueError("typ must be None or one of %s" % str(list(roles.keys()))) items = [] public = [] all_list = getattr(mod, '__all__', []) for name in dir(mod): try: member = safe_getattr(mod, name) except AttributeError: continue if check_typ(typ, mod, member): if in__all__ and name not in all_list: continue if include_imported or is_local(mod, member, name): if as_refs: documenter = get_documenter(member, mod) role = roles.get(documenter.objtype, 'obj') ref = _get_member_ref_str(name, obj=member, role=role, known_refs=getattr( mod, '__imported_data__', None)) items.append(ref) if not name.startswith('_'): public.append(ref) else: items.append(name) if not name.startswith('_'): public.append(name) return public, items
def generate_autosummary_content(name: str, obj: Any, parent: Any, template: AutosummaryRenderer, template_name: str, imported_members: bool, app: Any) -> str: doc = get_documenter(app, obj, parent) if template_name is None: template_name = 'autosummary/%s.rst' % doc.objtype if not template.exists(template_name): template_name = 'autosummary/base.rst' def skip_member(obj: Any, name: str, objtype: str) -> bool: try: return app.emit_firstresult('autodoc-skip-member', objtype, name, obj, False, {}) except Exception as exc: logger.warning(__('autosummary: failed to determine %r to be documented.' 'the following exception was raised:\n%s'), name, exc, type='autosummary') return False def get_members(obj: Any, types: Set[str], include_public: List[str] = [], imported: bool = True) -> Tuple[List[str], List[str]]: items = [] # type: List[str] public = [] # type: List[str] for name in dir(obj): try: value = safe_getattr(obj, name) except AttributeError: continue documenter = get_documenter(app, value, obj) if documenter.objtype in types: # skip imported members if expected if imported or getattr(value, '__module__', None) == obj.__name__: skipped = skip_member(value, name, documenter.objtype) if skipped is True: pass elif skipped is False: # show the member forcedly items.append(name) public.append(name) else: items.append(name) if name in include_public or not name.startswith('_'): # considers member as public public.append(name) return public, items ns = {} # type: Dict[str, Any] if doc.objtype == 'module': ns['members'] = dir(obj) ns['functions'], ns['all_functions'] = \ get_members(obj, {'function'}, imported=imported_members) ns['classes'], ns['all_classes'] = \ get_members(obj, {'class'}, imported=imported_members) ns['exceptions'], ns['all_exceptions'] = \ get_members(obj, {'exception'}, imported=imported_members) elif doc.objtype == 'class': ns['members'] = dir(obj) ns['inherited_members'] = \ set(dir(obj)) - set(obj.__dict__.keys()) ns['methods'], ns['all_methods'] = \ get_members(obj, {'method'}, ['__init__']) ns['attributes'], ns['all_attributes'] = \ get_members(obj, {'attribute', 'property'}) parts = name.split('.') if doc.objtype in ('method', 'attribute', 'property'): mod_name = '.'.join(parts[:-2]) cls_name = parts[-2] obj_name = '.'.join(parts[-2:]) ns['class'] = cls_name else: mod_name, obj_name = '.'.join(parts[:-1]), parts[-1] ns['fullname'] = name ns['module'] = mod_name ns['objname'] = obj_name ns['name'] = parts[-1] ns['objtype'] = doc.objtype ns['underline'] = len(name) * '=' return template.render(template_name, ns)
def generate_automodsumm_docs(lines, srcfn, suffix='.rst', warn=None, info=None, base_path=None, builder=None, template_dir=None): """ This function is adapted from `sphinx.ext.autosummary.generate.generate_autosummmary_docs` to generate source for the automodsumm directives that should be autosummarized. Unlike generate_autosummary_docs, this function is called one file at a time. """ import os from sphinx import package_dir from sphinx.jinja2glue import BuiltinTemplateLoader from sphinx.ext.autosummary import import_by_name, get_documenter from sphinx.ext.autosummary.generate import (find_autosummary_in_lines, _simple_info, _simple_warn) from sphinx.util.osutil import ensuredir from sphinx.util.inspect import safe_getattr from jinja2 import FileSystemLoader, TemplateNotFound from jinja2.sandbox import SandboxedEnvironment if info is None: info = _simple_info if warn is None: warn = _simple_warn #info('[automodsumm] generating automodsumm for: ' + srcfn) # create our own templating environment template_dirs = [os.path.join(package_dir, 'ext', 'autosummary', 'templates')] if builder is not None: # allow the user to override the templates template_loader = BuiltinTemplateLoader() template_loader.init(builder, dirs=template_dirs) else: if template_dir: template_dirs.insert(0, template_dir) template_loader = FileSystemLoader(template_dirs) template_env = SandboxedEnvironment(loader=template_loader) # read #items = find_autosummary_in_files(sources) items = find_autosummary_in_lines(lines, filename=srcfn) if len(items) > 0: msg = '[automodsumm] {1}: found {0} automodsumm entries to generate' info(msg.format(len(items), srcfn)) # gennms = [item[0] for item in items] # if len(gennms) > 20: # gennms = gennms[:10] + ['...'] + gennms[-10:] # info('[automodsumm] generating autosummary for: ' + ', '.join(gennms)) # remove possible duplicates items = dict([(item, True) for item in items]).keys() # keep track of new files new_files = [] # write for name, path, template_name in sorted(items): if path is None: # The corresponding autosummary:: directive did not have # a :toctree: option continue path = os.path.abspath(path) ensuredir(path) try: name, obj, parent = import_by_name(name) except ImportError, e: warn('[automodapi] failed to import %r: %s' % (name, e)) continue fn = os.path.join(path, name + suffix) # skip it if it exists if os.path.isfile(fn): continue new_files.append(fn) f = open(fn, 'w') try: doc = get_documenter(obj, parent) if template_name is not None: template = template_env.get_template(template_name) else: tmplstr = 'autosummary/%s.rst' try: template = template_env.get_template(tmplstr % doc.objtype) except TemplateNotFound: template = template_env.get_template(tmplstr % 'base') def get_members(obj, typ, include_public=[]): items = [] for name in dir(obj): try: documenter = get_documenter(safe_getattr(obj, name), obj) except AttributeError: continue if documenter.objtype == typ: items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items ns = {} if doc.objtype == 'module': ns['members'] = dir(obj) ns['functions'], ns['all_functions'] = \ get_members(obj, 'function') ns['classes'], ns['all_classes'] = \ get_members(obj, 'class') ns['exceptions'], ns['all_exceptions'] = \ get_members(obj, 'exception') elif doc.objtype == 'class': ns['members'] = dir(obj) ns['methods'], ns['all_methods'] = \ get_members(obj, 'method', ['__init__']) ns['attributes'], ns['all_attributes'] = \ get_members(obj, 'attribute') parts = name.split('.') if doc.objtype in ('method', 'attribute'): mod_name = '.'.join(parts[:-2]) cls_name = parts[-2] obj_name = '.'.join(parts[-2:]) ns['class'] = cls_name else: mod_name, obj_name = '.'.join(parts[:-1]), parts[-1] ns['fullname'] = name ns['module'] = mod_name ns['objname'] = obj_name ns['name'] = parts[-1] ns['objtype'] = doc.objtype ns['underline'] = len(name) * '=' rendered = template.render(**ns) f.write(rendered) finally: f.close()
def generate_autosummary_docs( sources, output_dir=None, suffix=".rst", warn=_simple_warn, info=_simple_info, base_path=None, builder=None, template_dir=None, ): showed_sources = list(sorted(sources)) if len(showed_sources) > 20: showed_sources = showed_sources[:10] + ["..."] + showed_sources[-10:] info("[autosummary] generating autosummary for: %s" % ", ".join(showed_sources)) if output_dir: info("[autosummary] writing to %s" % output_dir) if base_path is not None: sources = [os.path.join(base_path, filename) for filename in sources] # create our own templating environment template_dirs = [os.path.join(package_dir, "ext", "autosummary", "templates")] if builder is not None: # allow the user to override the templates template_loader = BuiltinTemplateLoader() template_loader.init(builder, dirs=template_dirs) else: if template_dir: template_dirs.insert(0, template_dir) template_loader = FileSystemLoader(template_dirs) template_env = SandboxedEnvironment(loader=template_loader) # read items = find_autosummary_in_files(sources) # keep track of new files new_files = [] # write for name, path, template_name in sorted(set(items), key=str): if path is None: # The corresponding autosummary:: directive did not have # a :toctree: option continue path = output_dir or os.path.abspath(path) ensuredir(path) try: name, obj, parent, mod_name = import_by_name(name) except ImportError as e: warn("[autosummary] failed to import %r: %s" % (name, e)) continue fn = os.path.join(path, name + suffix) # skip it if it exists if os.path.isfile(fn): continue new_files.append(fn) with open(fn, "w") as f: doc = get_documenter(obj, parent) if template_name is not None: template = template_env.get_template(template_name) else: try: template = template_env.get_template("autosummary/%s.rst" % doc.objtype) except TemplateNotFound: template = template_env.get_template("autosummary/base.rst") def get_members(obj, typ, include_public=[]): items = [] for name in dir(obj): try: documenter = get_documenter(safe_getattr(obj, name), obj) except AttributeError: continue if documenter.objtype == typ: items.append(name) public = [x for x in items if x in include_public or not x.startswith("_")] return public, items ns = {} if doc.objtype == "module": ns["members"] = dir(obj) ns["functions"], ns["all_functions"] = get_members(obj, "function") ns["classes"], ns["all_classes"] = get_members(obj, "class") ns["exceptions"], ns["all_exceptions"] = get_members(obj, "exception") elif doc.objtype == "class": ns["members"] = dir(obj) ns["methods"], ns["all_methods"] = get_members(obj, "method", ["__init__"]) ns["attributes"], ns["all_attributes"] = get_members(obj, "attribute") parts = name.split(".") if doc.objtype in ("method", "attribute"): mod_name = ".".join(parts[:-2]) cls_name = parts[-2] obj_name = ".".join(parts[-2:]) ns["class"] = cls_name else: mod_name, obj_name = ".".join(parts[:-1]), parts[-1] ns["fullname"] = name ns["module"] = mod_name ns["objname"] = obj_name ns["name"] = parts[-1] ns["objtype"] = doc.objtype ns["underline"] = len(name) * "=" rendered = template.render(**ns) f.write(rendered) # descend recursively to new files if new_files: generate_autosummary_docs( new_files, output_dir=output_dir, suffix=suffix, warn=warn, info=info, base_path=base_path, builder=builder, template_dir=template_dir, )
def generate_autosummary_content(name: str, obj: Any, parent: Any, template: AutosummaryRenderer, template_name: str, imported_members: bool, app: Any, recursive: bool, context: Dict, modname: str = None, qualname: str = None) -> str: doc = get_documenter(app, obj, parent) def skip_member(obj: Any, name: str, objtype: str) -> bool: try: return app.emit_firstresult('autodoc-skip-member', objtype, name, obj, False, {}) except Exception as exc: logger.warning(__( 'autosummary: failed to determine %r to be documented, ' 'the following exception was raised:\n%s'), name, exc, type='autosummary') return False def get_class_members(obj: Any) -> Dict[str, Any]: members = sphinx.ext.autodoc.get_class_members(obj, [qualname], safe_getattr) return {name: member.object for name, member in members.items()} def get_module_members(obj: Any) -> Dict[str, Any]: members = {} for name in members_of(obj, app.config): try: members[name] = safe_getattr(obj, name) except AttributeError: continue return members def get_all_members(obj: Any) -> Dict[str, Any]: if doc.objtype == "module": return get_module_members(obj) elif doc.objtype == "class": return get_class_members(obj) return {} def get_members(obj: Any, types: Set[str], include_public: List[str] = [], imported: bool = True) -> Tuple[List[str], List[str]]: items: List[str] = [] public: List[str] = [] all_members = get_all_members(obj) for name, value in all_members.items(): documenter = get_documenter(app, value, obj) if documenter.objtype in types: # skip imported members if expected if imported or getattr(value, '__module__', None) == obj.__name__: skipped = skip_member(value, name, documenter.objtype) if skipped is True: pass elif skipped is False: # show the member forcedly items.append(name) public.append(name) else: items.append(name) if name in include_public or not name.startswith('_'): # considers member as public public.append(name) return public, items def get_module_attrs(members: Any) -> Tuple[List[str], List[str]]: """Find module attributes with docstrings.""" attrs, public = [], [] try: analyzer = ModuleAnalyzer.for_module(name) attr_docs = analyzer.find_attr_docs() for namespace, attr_name in attr_docs: if namespace == '' and attr_name in members: attrs.append(attr_name) if not attr_name.startswith('_'): public.append(attr_name) except PycodeError: pass # give up if ModuleAnalyzer fails to parse code return public, attrs def get_modules(obj: Any) -> Tuple[List[str], List[str]]: items: List[str] = [] for _, modname, _ispkg in pkgutil.iter_modules(obj.__path__): fullname = name + '.' + modname try: module = import_module(fullname) if module and hasattr(module, '__sphinx_mock__'): continue except ImportError: pass items.append(fullname) public = [x for x in items if not x.split('.')[-1].startswith('_')] return public, items ns: Dict[str, Any] = {} ns.update(context) if doc.objtype == 'module': scanner = ModuleScanner(app, obj) ns['members'] = scanner.scan(imported_members) ns['functions'], ns['all_functions'] = \ get_members(obj, {'function'}, imported=imported_members) ns['classes'], ns['all_classes'] = \ get_members(obj, {'class'}, imported=imported_members) ns['exceptions'], ns['all_exceptions'] = \ get_members(obj, {'exception'}, imported=imported_members) ns['attributes'], ns['all_attributes'] = \ get_module_attrs(ns['members']) ispackage = hasattr(obj, '__path__') if ispackage and recursive: ns['modules'], ns['all_modules'] = get_modules(obj) elif doc.objtype == 'class': ns['members'] = dir(obj) ns['inherited_members'] = \ set(dir(obj)) - set(obj.__dict__.keys()) ns['methods'], ns['all_methods'] = \ get_members(obj, {'method'}, ['__init__']) ns['attributes'], ns['all_attributes'] = \ get_members(obj, {'attribute', 'property'}) if modname is None or qualname is None: modname, qualname = split_full_qualified_name(name) if doc.objtype in ('method', 'attribute', 'property'): ns['class'] = qualname.rsplit(".", 1)[0] if doc.objtype in ('class', ): shortname = qualname else: shortname = qualname.rsplit(".", 1)[-1] ns['fullname'] = name ns['module'] = modname ns['objname'] = qualname ns['name'] = shortname ns['objtype'] = doc.objtype ns['underline'] = len(name) * '=' if template_name: return template.render(template_name, ns) else: return template.render(doc.objtype, ns)
def generate_autosummary_docs(sources, output_dir=None, suffix='.rst', warn=_simple_warn, info=_simple_info, base_path=None, builder=None, template_dir=None, app=None): showed_sources = list(sorted(sources)) if len(showed_sources) > 20: showed_sources = showed_sources[:10] + ['...'] + showed_sources[-10:] info('[autosummary] generating autosummary for: %s' % ', '.join(showed_sources)) if output_dir: info('[autosummary] writing to %s' % output_dir) if base_path is not None: sources = [osp.join(base_path, filename) for filename in sources] # create our own templating environment template_dirs = [osp.join(package_dir, 'ext', 'autosummary', 'templates')] if builder is not None: # allow the user to override the templates template_loader = BuiltinTemplateLoader() template_loader.init(builder, dirs=template_dirs) else: if template_dir: template_dirs.insert(0, template_dir) template_loader = FileSystemLoader(template_dirs) template_env = SandboxedEnvironment(loader=template_loader) # read items = find_autosummary_in_files(sources) # remove possible duplicates items = list(dict([(item, True) for item in items]).keys()) # keep track of new files new_files = [] # write # noinspection PyTypeChecker for name, path, template_name in sorted(items, key=str): if path is None: # The corresponding autosummary:: directive did not have # a :toctree: option continue path = output_dir or osp.abspath(path) ensuredir(path) try: name, obj, parent, mod_name = import_by_name(name) except ImportError as e: warn('[autosummary] failed to import %r: %s' % (name, e)) continue fn = osp.join(path, name + suffix) # skip it if it exists if osp.isfile(fn): continue new_files.append(fn) f = open(fn, 'w') try: try: doc = get_documenter(app, obj, parent) except TypeError: doc = get_documenter(obj, parent) if template_name is not None: template = template_env.get_template(template_name) else: try: template = template_env.get_template('autosummary/%s.rst' % doc.objtype) except TemplateNotFound: template = template_env.get_template( 'autosummary/base.rst') ns = {} if doc.objtype == 'module': ns['members'] = dir(obj) ns['functions'], ns['all_functions'] = \ get_members(app, obj, 'function') ns['classes'], ns['all_classes'] = \ get_members(app, obj, 'class') ns['exceptions'], ns['all_exceptions'] = \ get_members(app, obj, 'exception') ns['data'], ns['all_data'] = \ get_members(app, obj, 'data', imported=True) ns['data'] = ', '.join(ns['data']) ns['all_data'] = ', '.join(ns['all_data']) ns['dispatchers'], ns['all_dispatchers'] = \ get_members(app, obj, 'dispatcher', imported=True) elif doc.objtype == 'class': ns['members'] = dir(obj) ns['methods'], ns['all_methods'] = \ get_members(app, obj, 'method', ['__init__'], True) ns['attributes'], ns['all_attributes'] = \ get_members(app, obj, 'attribute') parts = name.split('.') if doc.objtype in ('method', 'attribute'): mod_name = '.'.join(parts[:-2]) cls_name = parts[-2] obj_name = '.'.join(parts[-2:]) ns['class'] = cls_name else: mod_name, obj_name = '.'.join(parts[:-1]), parts[-1] ns['fullname'] = name ns['module'] = mod_name ns['objname'] = obj_name ns['name'] = parts[-1] ns['objtype'] = doc.objtype ns['underline'] = len(name) * '=' rendered = template.render(**ns) f.write(rendered) finally: f.close() # descend recursively to new files if new_files: generate_autosummary_docs(new_files, output_dir=output_dir, suffix=suffix, warn=warn, info=info, base_path=base_path, builder=builder, template_dir=template_dir, app=app)
def get_items(self, names): """Try to import the given names, and return a list of ``[(name, signature, summary_string, real_name), ...]``. """ from sphinx.ext.autosummary import (get_import_prefixes_from_env, import_by_name, get_documenter, mangle_signature) env = self.state.document.settings.env prefixes = get_import_prefixes_from_env(env) items = [] max_item_chars = 50 for name in names: display_name = name if name.startswith('~'): name = name[1:] display_name = name.split('.')[-1] try: import_by_name_values = import_by_name(name, prefixes=prefixes) except ImportError: self.warn('[astropyautosummary] failed to import %s' % name) items.append((name, '', '', name)) continue # to accommodate Sphinx v1.2.2 and v1.2.3 if len(import_by_name_values) == 3: real_name, obj, parent = import_by_name_values elif len(import_by_name_values) == 4: real_name, obj, parent, module_name = import_by_name_values # NB. using real_name here is important, since Documenters # handle module prefixes slightly differently documenter = get_documenter(obj, parent)(self, real_name) if not documenter.parse_name(): self.warn('[astropyautosummary] failed to parse name %s' % real_name) items.append((display_name, '', '', real_name)) continue if not documenter.import_object(): self.warn('[astropyautosummary] failed to import object %s' % real_name) items.append((display_name, '', '', real_name)) continue # -- Grab the signature sig = documenter.format_signature() if not sig: sig = '' else: max_chars = max(10, max_item_chars - len(display_name)) sig = mangle_signature(sig, max_chars=max_chars) sig = sig.replace('*', r'\*') # -- Grab the summary doc = list(documenter.process_doc(documenter.get_doc())) while doc and not doc[0].strip(): doc.pop(0) m = _itemsummrex.search(" ".join(doc).strip()) if m: summary = m.group(1).strip() elif doc: summary = doc[0].strip() else: summary = '' items.append((display_name, sig, summary, real_name)) return items
def get_items(self, names): """Try to import the given names, and return a list of ``[(name, signature, summary_string, real_name), ...]``. """ env = self.state.document.settings.env prefixes = get_import_prefixes_from_env(env) items = [] max_item_chars = 50 for name in names: display_name = name if name.startswith('~'): name = name[1:] display_name = name.split('.')[-1] try: real_name, obj, parent = import_by_name(name, prefixes=prefixes) except ImportError: self.warn('failed to import %s' % name) items.append((name, '', '', name)) continue # NB. using real_name here is important, since Documenters # handle module prefixes slightly differently documenter = get_documenter(obj, parent)(self, real_name) if not documenter.parse_name(): self.warn('failed to parse name %s' % real_name) items.append((display_name, '', '', real_name)) continue if not documenter.import_object(): self.warn('failed to import object %s' % real_name) items.append((display_name, '', '', real_name)) continue display_name = documenter.format_name() # -- Grab the signature sig = documenter.format_signature() if not sig: sig = '' else: max_chars = max(10, max_item_chars - len(display_name)) sig = mangle_signature(sig, max_chars=max_chars) sig = sig.replace('*', r'\*') # -- Grab the summary doc = list(documenter.process_doc(documenter.get_doc())) while doc and not doc[0].strip(): doc.pop(0) m = re.search(r"^([A-Z][^A-Z]*?\.\s)", " ".join(doc).strip()) if m: summary = m.group(1).strip() elif doc: summary = doc[0].strip() else: summary = '' items.append((display_name, sig, summary, real_name)) return items
def generate_autosummary_content(name: str, obj: Any, parent: Any, template: AutosummaryRenderer, template_name: str, imported_members: bool, app: Any) -> str: doc = get_documenter(app, obj, parent) if template_name is None: template_name = 'autosummary/%s.rst' % doc.objtype if not template.exists(template_name): template_name = 'autosummary/base.rst' def get_members(obj: Any, types: Set[str], include_public: List[str] = [], imported: bool = True) -> Tuple[List[str], List[str]]: items = [] # type: List[str] for name in dir(obj): try: value = safe_getattr(obj, name) except AttributeError: continue documenter = get_documenter(app, value, obj) if documenter.objtype in types: if imported or getattr(value, '__module__', None) == obj.__name__: # skip imported members if expected items.append(name) public = [ x for x in items if x in include_public or not x.startswith('_') ] return public, items ns = {} # type: Dict[str, Any] if doc.objtype == 'module': ns['members'] = dir(obj) ns['functions'], ns['all_functions'] = \ get_members(obj, {'function'}, imported=imported_members) ns['classes'], ns['all_classes'] = \ get_members(obj, {'class'}, imported=imported_members) ns['exceptions'], ns['all_exceptions'] = \ get_members(obj, {'exception'}, imported=imported_members) elif doc.objtype == 'class': ns['members'] = dir(obj) ns['inherited_members'] = \ set(dir(obj)) - set(obj.__dict__.keys()) ns['methods'], ns['all_methods'] = \ get_members(obj, {'method'}, ['__init__']) ns['attributes'], ns['all_attributes'] = \ get_members(obj, {'attribute', 'property'}) parts = name.split('.') if doc.objtype in ('method', 'attribute', 'property'): mod_name = '.'.join(parts[:-2]) cls_name = parts[-2] obj_name = '.'.join(parts[-2:]) ns['class'] = cls_name else: mod_name, obj_name = '.'.join(parts[:-1]), parts[-1] ns['fullname'] = name ns['module'] = mod_name ns['objname'] = obj_name ns['name'] = parts[-1] ns['objtype'] = doc.objtype ns['underline'] = len(name) * '=' return template.render(template_name, ns)
def generate_autosummary_docs(sources, output_dir=None, suffix='.rst', warn=_simple_warn, info=_simple_info, base_path=None, builder=None, template_dir=None, imported_members=False): # type: (List[unicode], unicode, unicode, Callable, Callable, unicode, Builder, unicode, bool) -> None # NOQA showed_sources = list(sorted(sources)) if len(showed_sources) > 20: showed_sources = showed_sources[:10] + ['...'] + showed_sources[-10:] info('[autosummary] generating autosummary for: %s' % ', '.join(showed_sources)) if output_dir: info('[autosummary] writing to %s' % output_dir) if base_path is not None: sources = [os.path.join(base_path, filename) for filename in sources] # create our own templating environment template_dirs = None # type: List[unicode] template_dirs = [os.path.join(package_dir, 'ext', 'autosummary', 'templates')] template_loader = None # type: BaseLoader if builder is not None: # allow the user to override the templates template_loader = BuiltinTemplateLoader() template_loader.init(builder, dirs=template_dirs) else: if template_dir: template_dirs.insert(0, template_dir) template_loader = FileSystemLoader(template_dirs) # type: ignore template_env = SandboxedEnvironment(loader=template_loader) template_env.filters['underline'] = _underline # replace the builtin html filters template_env.filters['escape'] = rst_escape template_env.filters['e'] = rst_escape # read items = find_autosummary_in_files(sources) # keep track of new files new_files = [] # write for name, path, template_name in sorted(set(items), key=str): if path is None: # The corresponding autosummary:: directive did not have # a :toctree: option continue path = output_dir or os.path.abspath(path) ensuredir(path) try: name, obj, parent, mod_name = import_by_name(name) except ImportError as e: warn('[autosummary] failed to import %r: %s' % (name, e)) continue fn = os.path.join(path, name + suffix) # skip it if it exists if os.path.isfile(fn): continue new_files.append(fn) with open(fn, 'w') as f: doc = get_documenter(obj, parent) if template_name is not None: template = template_env.get_template(template_name) else: try: template = template_env.get_template('autosummary/%s.rst' % doc.objtype) except TemplateNotFound: template = template_env.get_template('autosummary/base.rst') def get_members(obj, typ, include_public=[], imported=False): # type: (Any, unicode, List[unicode], bool) -> Tuple[List[unicode], List[unicode]] # NOQA items = [] # type: List[unicode] for name in dir(obj): try: value = safe_getattr(obj, name) except AttributeError: continue documenter = get_documenter(value, obj) if documenter.objtype == typ: if typ == 'method': items.append(name) elif imported or getattr(value, '__module__', None) == obj.__name__: # skip imported members if expected items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items ns = {} # type: Dict[unicode, Any] if doc.objtype == 'module': ns['members'] = dir(obj) ns['functions'], ns['all_functions'] = \ get_members(obj, 'function', imported=imported_members) ns['classes'], ns['all_classes'] = \ get_members(obj, 'class', imported=imported_members) ns['exceptions'], ns['all_exceptions'] = \ get_members(obj, 'exception', imported=imported_members) elif doc.objtype == 'class': ns['members'] = dir(obj) ns['methods'], ns['all_methods'] = \ get_members(obj, 'method', ['__init__'], imported=imported_members) ns['attributes'], ns['all_attributes'] = \ get_members(obj, 'attribute', imported=imported_members) parts = name.split('.') if doc.objtype in ('method', 'attribute'): mod_name = '.'.join(parts[:-2]) cls_name = parts[-2] obj_name = '.'.join(parts[-2:]) ns['class'] = cls_name else: mod_name, obj_name = '.'.join(parts[:-1]), parts[-1] ns['fullname'] = name ns['module'] = mod_name ns['objname'] = obj_name ns['name'] = parts[-1] ns['objtype'] = doc.objtype ns['underline'] = len(name) * '=' rendered = template.render(**ns) f.write(rendered) # type: ignore # descend recursively to new files if new_files: generate_autosummary_docs(new_files, output_dir=output_dir, suffix=suffix, warn=warn, info=info, base_path=base_path, builder=builder, template_dir=template_dir)
def generate_autosummary_docs(sources, output_dir=None, suffix='.rst', warn=_simple_warn, info=_simple_info, base_path=None, builder=None, template_dir=None): showed_sources = list(sorted(sources)) if len(showed_sources) > 20: showed_sources = showed_sources[:10] + ['...'] + showed_sources[-10:] info('[autosummary] generating autosummary for: %s' % ', '.join(showed_sources)) if output_dir: info('[autosummary] writing to %s' % output_dir) if base_path is not None: sources = [os.path.join(base_path, filename) for filename in sources] # create our own templating environment template_dirs = [os.path.join(package_dir, 'ext', 'autosummary', 'templates')] if builder is not None: # allow the user to override the templates template_loader = BuiltinTemplateLoader() template_loader.init(builder, dirs=template_dirs) else: if template_dir: template_dirs.insert(0, template_dir) template_loader = FileSystemLoader(template_dirs) template_env = SandboxedEnvironment(loader=template_loader) # read items = find_autosummary_in_files(sources) # remove possible duplicates items = list(dict([(item, True) for item in items]).keys()) # keep track of new files new_files = [] # write for name, path, template_name in sorted(items, key=str): if path is None: # The corresponding autosummary:: directive did not have # a :toctree: option continue path = output_dir or os.path.abspath(path) ensuredir(path) try: name, obj, parent = import_by_name(name) except ImportError as e: warn('[autosummary] failed to import %r: %s' % (name, e)) continue fn = os.path.join(path, name + suffix) # skip it if it exists if os.path.isfile(fn): continue new_files.append(fn) f = open(fn, 'w') try: doc = get_documenter(obj, parent) if template_name is not None: template = template_env.get_template(template_name) else: try: template = template_env.get_template('autosummary/%s.rst' % doc.objtype) except TemplateNotFound: template = template_env.get_template('autosummary/base.rst') def get_members(obj, typ, include_public=[]): items = [] for name in dir(obj): try: documenter = get_documenter(safe_getattr(obj, name), obj) except AttributeError: continue if documenter.objtype == typ: items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items ns = {} if doc.objtype == 'module': ns['members'] = dir(obj) ns['functions'], ns['all_functions'] = \ get_members(obj, 'function') ns['classes'], ns['all_classes'] = \ get_members(obj, 'class') ns['exceptions'], ns['all_exceptions'] = \ get_members(obj, 'exception') elif doc.objtype == 'class': ns['members'] = dir(obj) ns['methods'], ns['all_methods'] = \ get_members(obj, 'method', ['__init__']) ns['attributes'], ns['all_attributes'] = \ get_members(obj, 'attribute') parts = name.split('.') if doc.objtype in ('method', 'attribute'): mod_name = '.'.join(parts[:-2]) cls_name = parts[-2] obj_name = '.'.join(parts[-2:]) ns['class'] = cls_name else: mod_name, obj_name = '.'.join(parts[:-1]), parts[-1] ns['fullname'] = name ns['module'] = mod_name ns['objname'] = obj_name ns['name'] = parts[-1] ns['objtype'] = doc.objtype ns['underline'] = len(name) * '=' rendered = template.render(**ns) f.write(rendered) finally: f.close() # descend recursively to new files if new_files: generate_autosummary_docs(new_files, output_dir=output_dir, suffix=suffix, warn=warn, info=info, base_path=base_path, builder=builder, template_dir=template_dir)
def get_object_type(self, name: str, value: Any) -> str: return get_documenter(self.app, value, self.object).objtype
def generate_automodsumm_docs(lines, srcfn, suffix='.rst', warn=None, info=None, base_path=None, builder=None, template_dir=None): """ This function is adapted from `sphinx.ext.autosummary.generate.generate_autosummmary_docs` to generate source for the automodsumm directives that should be autosummarized. Unlike generate_autosummary_docs, this function is called one file at a time. """ from sphinx.jinja2glue import BuiltinTemplateLoader from sphinx.ext.autosummary import import_by_name, get_documenter from sphinx.ext.autosummary.generate import (find_autosummary_in_lines, _simple_info, _simple_warn) from sphinx.util.osutil import ensuredir from sphinx.util.inspect import safe_getattr from jinja2 import FileSystemLoader, TemplateNotFound from jinja2.sandbox import SandboxedEnvironment if info is None: info = _simple_info if warn is None: warn = _simple_warn #info('[automodsumm] generating automodsumm for: ' + srcfn) # Create our own templating environment - here we use Astropy's # templates rather than the default autosummary templates, in order to # allow docstrings to be shown for methods. template_dirs = [os.path.join(os.path.dirname(__file__), 'templates'), os.path.join(base_path, '_templates')] if builder is not None: # allow the user to override the templates template_loader = BuiltinTemplateLoader() template_loader.init(builder, dirs=template_dirs) else: if template_dir: template_dirs.insert(0, template_dir) template_loader = FileSystemLoader(template_dirs) template_env = SandboxedEnvironment(loader=template_loader) # read #items = find_autosummary_in_files(sources) items = find_autosummary_in_lines(lines, filename=srcfn) if len(items) > 0: msg = '[automodsumm] {1}: found {0} automodsumm entries to generate' info(msg.format(len(items), srcfn)) # gennms = [item[0] for item in items] # if len(gennms) > 20: # gennms = gennms[:10] + ['...'] + gennms[-10:] # info('[automodsumm] generating autosummary for: ' + ', '.join(gennms)) # remove possible duplicates items = dict([(item, True) for item in items]).keys() # keep track of new files new_files = [] # write for name, path, template_name in sorted(items): if path is None: # The corresponding autosummary:: directive did not have # a :toctree: option continue path = os.path.abspath(path) ensuredir(path) try: import_by_name_values = import_by_name(name) except ImportError as e: warn('[automodsumm] failed to import %r: %s' % (name, e)) continue # if block to accommodate Sphinx's v1.2.2 and v1.2.3 respectively if len(import_by_name_values) == 3: name, obj, parent = import_by_name_values elif len(import_by_name_values) == 4: name, obj, parent, module_name = import_by_name_values fn = os.path.join(path, name + suffix) # skip it if it exists if os.path.isfile(fn): continue new_files.append(fn) f = open(fn, 'w') try: doc = get_documenter(obj, parent) if template_name is not None: template = template_env.get_template(template_name) else: tmplstr = 'autosummary/%s.rst' try: template = template_env.get_template(tmplstr % doc.objtype) except TemplateNotFound: template = template_env.get_template(tmplstr % 'base') def get_members_mod(obj, typ, include_public=[]): """ typ = None -> all """ items = [] for name in dir(obj): try: documenter = get_documenter(safe_getattr(obj, name), obj) except AttributeError: continue if typ is None or documenter.objtype == typ: items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items def get_members_class(obj, typ, include_public=[], include_base=False): """ typ = None -> all include_base -> include attrs that are from a base class """ items = [] # using dir gets all of the attributes, including the elements # from the base class, otherwise use __slots__ or __dict__ if include_base: names = dir(obj) else: if hasattr(obj, '__slots__'): names = tuple(getattr(obj, '__slots__')) else: names = getattr(obj, '__dict__').keys() for name in names: try: documenter = get_documenter(safe_getattr(obj, name), obj) except AttributeError: continue if typ is None or documenter.objtype == typ: items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items ns = {} if doc.objtype == 'module': ns['members'] = get_members_mod(obj, None) ns['functions'], ns['all_functions'] = \ get_members_mod(obj, 'function') ns['classes'], ns['all_classes'] = \ get_members_mod(obj, 'class') ns['exceptions'], ns['all_exceptions'] = \ get_members_mod(obj, 'exception') elif doc.objtype == 'class': api_class_methods = ['__init__', '__call__'] ns['members'] = get_members_class(obj, None) ns['methods'], ns['all_methods'] = \ get_members_class(obj, 'method', api_class_methods) ns['attributes'], ns['all_attributes'] = \ get_members_class(obj, 'attribute') ns['methods'].sort() ns['attributes'].sort() parts = name.split('.') if doc.objtype in ('method', 'attribute'): mod_name = '.'.join(parts[:-2]) cls_name = parts[-2] obj_name = '.'.join(parts[-2:]) ns['class'] = cls_name else: mod_name, obj_name = '.'.join(parts[:-1]), parts[-1] ns['fullname'] = name ns['module'] = mod_name ns['objname'] = obj_name ns['name'] = parts[-1] ns['objtype'] = doc.objtype ns['underline'] = len(name) * '=' # We now check whether a file for reference footnotes exists for # the module being documented. We first check if the # current module is a file or a directory, as this will give a # different path for the reference file. For example, if # documenting astropy.wcs then the reference file is at # ../wcs/references.txt, while if we are documenting # astropy.config.logging_helper (which is at # astropy/config/logging_helper.py) then the reference file is set # to ../config/references.txt if '.' in mod_name: mod_name_dir = mod_name.replace('.', '/').split('/', 1)[1] else: mod_name_dir = mod_name if not os.path.isdir(os.path.join(base_path, mod_name_dir)) \ and os.path.isdir(os.path.join(base_path, mod_name_dir.rsplit('/', 1)[0])): mod_name_dir = mod_name_dir.rsplit('/', 1)[0] # We then have to check whether it exists, and if so, we pass it # to the template. if os.path.exists(os.path.join(base_path, mod_name_dir, 'references.txt')): # An important subtlety here is that the path we pass in has # to be relative to the file being generated, so we have to # figure out the right number of '..'s ndirsback = path.replace(base_path, '').count('/') ref_file_rel_segments = ['..'] * ndirsback ref_file_rel_segments.append(mod_name_dir) ref_file_rel_segments.append('references.txt') ns['referencefile'] = os.path.join(*ref_file_rel_segments) rendered = template.render(**ns) f.write(rendered) finally: f.close()
def generate_autosummary_docs(sources, output_dir=None, suffix='.rst', warn=_simple_warn, info=_simple_info, base_path=None, builder=None, template_dir=None): showed_sources = list(sorted(sources)) if len(showed_sources) > 20: showed_sources = showed_sources[:10] + ['...'] + showed_sources[-10:] info('[autosummary] generating autosummary for: %s' % ', '.join(showed_sources)) if output_dir: info('[autosummary] writing to %s' % output_dir) if base_path is not None: sources = [os.path.join(base_path, filename) for filename in sources] # create our own templating environment template_dirs = [ os.path.join(package_dir, 'ext', 'autosummary', 'templates') ] if builder is not None: # allow the user to override the templates template_loader = BuiltinTemplateLoader() template_loader.init(builder, dirs=template_dirs) else: if template_dir: template_dirs.insert(0, template_dir) template_loader = FileSystemLoader(template_dirs) template_env = SandboxedEnvironment(loader=template_loader) # read items = find_autosummary_in_files(sources) # keep track of new files new_files = [] # write for name, path, template_name in sorted(set(items), key=str): if path is None: # The corresponding autosummary:: directive did not have # a :toctree: option continue path = output_dir or os.path.abspath(path) ensuredir(path) try: name, obj, parent, mod_name = import_by_name(name) except ImportError as e: warn('[autosummary] failed to import %r: %s' % (name, e)) continue fn = os.path.join(path, name + suffix) # skip it if it exists if os.path.isfile(fn): continue new_files.append(fn) with open(fn, 'w') as f: doc = get_documenter(obj, parent) if template_name is not None: template = template_env.get_template(template_name) else: try: template = template_env.get_template('autosummary/%s.rst' % doc.objtype) except TemplateNotFound: template = template_env.get_template( 'autosummary/base.rst') def get_members(obj, typ, include_public=[], imported=False): items = [] for name in dir(obj): try: obj_name = safe_getattr(obj, name) documenter = get_documenter(obj_name, obj) except AttributeError: continue if documenter.objtype == typ: try: cond = (imported or obj_name.__module__ == obj.__name__) except AttributeError: cond = True if cond: items.append(name) public = [ x for x in items if x in include_public or not x.startswith('_') ] return public, items ns = {} if doc.objtype == 'module': ns['members'] = dir(obj) ns['functions'], ns['all_functions'] = \ get_members(obj, 'function') ns['classes'], ns['all_classes'] = \ get_members(obj, 'class') ns['exceptions'], ns['all_exceptions'] = \ get_members(obj, 'exception') elif doc.objtype == 'class': ns['members'] = dir(obj) ns['methods'], ns['all_methods'] = \ get_members(obj, 'method', ['__init__']) ns['attributes'], ns['all_attributes'] = \ get_members(obj, 'attribute') parts = name.split('.') if doc.objtype in ('method', 'attribute'): mod_name = '.'.join(parts[:-2]) cls_name = parts[-2] obj_name = '.'.join(parts[-2:]) ns['class'] = cls_name else: mod_name, obj_name = '.'.join(parts[:-1]), parts[-1] ns['fullname'] = name ns['module'] = mod_name ns['objname'] = obj_name ns['name'] = parts[-1] ns['objtype'] = doc.objtype ns['underline'] = len(name) * '=' rendered = template.render(**ns) f.write(rendered) # descend recursively to new files if new_files: generate_autosummary_docs(new_files, output_dir=output_dir, suffix=suffix, warn=warn, info=info, base_path=base_path, builder=builder, template_dir=template_dir)
def generate_autosummary_docs(sources, output_dir=None, suffix='.rst', warn=_simple_warn, info=_simple_info, base_path=None, builder=None, template_dir=None, imported_members=False, app=None): # type: (List[str], str, str, Callable, Callable, str, Builder, str, bool, Any) -> None showed_sources = list(sorted(sources)) if len(showed_sources) > 20: showed_sources = showed_sources[:10] + ['...'] + showed_sources[-10:] info(__('[autosummary] generating autosummary for: %s') % ', '.join(showed_sources)) if output_dir: info(__('[autosummary] writing to %s') % output_dir) if base_path is not None: sources = [os.path.join(base_path, filename) for filename in sources] template = AutosummaryRenderer(builder, template_dir) # read items = find_autosummary_in_files(sources) # keep track of new files new_files = [] # write for name, path, template_name in sorted(set(items), key=str): if path is None: # The corresponding autosummary:: directive did not have # a :toctree: option continue path = output_dir or os.path.abspath(path) ensuredir(path) try: name, obj, parent, mod_name = import_by_name(name) except ImportError as e: warn('[autosummary] failed to import %r: %s' % (name, e)) continue fn = os.path.join(path, name + suffix) # skip it if it exists if os.path.isfile(fn): continue new_files.append(fn) with open(fn, 'w') as f: doc = get_documenter(app, obj, parent) if template_name is None: template_name = 'autosummary/%s.rst' % doc.objtype if not template.exists(template_name): template_name = 'autosummary/base.rst' def get_members(obj, types, include_public=[], imported=True): # type: (Any, Set[str], List[str], bool) -> Tuple[List[str], List[str]] # NOQA items = [] # type: List[str] for name in dir(obj): try: value = safe_getattr(obj, name) except AttributeError: continue documenter = get_documenter(app, value, obj) if documenter.objtype in types: if imported or getattr(value, '__module__', None) == obj.__name__: # skip imported members if expected items.append(name) public = [x for x in items if x in include_public or not x.startswith('_')] return public, items ns = {} # type: Dict[str, Any] if doc.objtype == 'module': ns['members'] = dir(obj) ns['functions'], ns['all_functions'] = \ get_members(obj, {'function'}, imported=imported_members) ns['classes'], ns['all_classes'] = \ get_members(obj, {'class'}, imported=imported_members) ns['exceptions'], ns['all_exceptions'] = \ get_members(obj, {'exception'}, imported=imported_members) elif doc.objtype == 'class': ns['members'] = dir(obj) ns['inherited_members'] = \ set(dir(obj)) - set(obj.__dict__.keys()) ns['methods'], ns['all_methods'] = \ get_members(obj, {'method'}, ['__init__']) ns['attributes'], ns['all_attributes'] = \ get_members(obj, {'attribute', 'property'}) parts = name.split('.') if doc.objtype in ('method', 'attribute', 'property'): mod_name = '.'.join(parts[:-2]) cls_name = parts[-2] obj_name = '.'.join(parts[-2:]) ns['class'] = cls_name else: mod_name, obj_name = '.'.join(parts[:-1]), parts[-1] ns['fullname'] = name ns['module'] = mod_name ns['objname'] = obj_name ns['name'] = parts[-1] ns['objtype'] = doc.objtype ns['underline'] = len(name) * '=' rendered = template.render(template_name, ns) f.write(rendered) # descend recursively to new files if new_files: generate_autosummary_docs(new_files, output_dir=output_dir, suffix=suffix, warn=warn, info=info, base_path=base_path, builder=builder, template_dir=template_dir, app=app)