def find_autosummary_in_docstring(name, module=None, filename=None): """Find out what items are documented in the given object's docstring. See `find_autosummary_in_lines`. """ try: real_name, obj, parent = import_by_name(name) lines = pydoc.getdoc(obj).splitlines() return find_autosummary_in_lines(lines, module=name, filename=filename) except AttributeError: pass except ImportError, e: print "Failed to import '%s': %s" % (name, e)
def get_documented_in_docstring(name, module=None, filename=None): """ Find out what items are documented in the given object's docstring. See `get_documented_in_lines`. """ try: obj, real_name = import_by_name(name) lines = pydoc.getdoc(obj).splitlines() return get_documented_in_lines(lines, module=name, filename=filename) except AttributeError: pass except ImportError as e: print("Failed to import '%s': %s" % (name, e)) return {}
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(os.path.dirname(__file__), '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, extensions=["jinja2.ext.do"]) # read items = find_autosummary_in_files(sources) # 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 = 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) # XXX: patch start! if typ in ('function', 'class', 'exception'): items = [name for name in items if getattr(obj, name).__module__ == obj.__name__] elif typ == 'attribute': items = [name for name in items if not hasattr(getattr(obj, name), '__call__')] public = [x for x in items if not x.startswith('_') or x.endswith('__')] # XXX: patch end! 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 main(): p = optparse.OptionParser(__doc__.strip()) p.add_option("-p", "--phantom", action="store", type="string", dest="phantom", default=None, help="Phantom import modules from a file") p.add_option("-o", "--output-dir", action="store", type="string", dest="output_dir", default=None, help=("Write all output files to the given directory (instead " "of writing them as specified in the autosummary:: " "directives)")) options, args = p.parse_args() if len(args) == 0: p.error("wrong number of arguments") if options.phantom and os.path.isfile(options.phantom): import_phantom_module(options.phantom) # read names = {} for name, loc in get_documented(args).items(): for (filename, sec_title, keyword, toctree) in loc: if toctree is not None: path = os.path.join(os.path.dirname(filename), toctree) names[name] = os.path.abspath(path) # write for name, path in sorted(names.items()): if options.output_dir is not None: path = options.output_dir if not os.path.isdir(path): os.makedirs(path) try: obj, name = import_by_name(name) except ImportError, e: print "Failed to import '%s': %s" % (name, e) continue fn = os.path.join(path, '%s.rst' % name) if os.path.exists(fn): # skip continue f = open(fn, 'w') try: f.write('%s\n%s\n\n' % (name, '='*len(name))) if inspect.isclass(obj): if issubclass(obj, Exception): f.write(format_modulemember(name, 'autoexception')) else: f.write(format_modulemember(name, 'autoclass')) elif inspect.ismodule(obj): f.write(format_modulemember(name, 'automodule')) elif inspect.ismethod(obj) or inspect.ismethoddescriptor(obj): f.write(format_classmember(name, 'automethod')) elif callable(obj): f.write(format_modulemember(name, 'autofunction')) elif hasattr(obj, '__get__'): f.write(format_classmember(name, 'autoattribute')) else: f.write(format_modulemember(name, 'autofunction')) 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(os.path.dirname(__file__), '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): 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=[]): # XXX: whole function is a patch! if typ in ('function', 'class', 'exception'): # modules seem to work items = [ name for name in dir(obj) if get_documenter( getattr(obj, name), obj).objtype == typ ] items = [ name for name in items if getattr(obj, name).__module__ == obj.__name__ ] elif typ == 'method': # filter methods (__call__) which are defined within this # class (im_class) # Exclude also those methods inherited from another # class. items = [ name for name in dir(obj) if hasattr(getattr(obj, name), '__call__') and hasattr( getattr(obj, name), 'im_class') and inspect. getmodule(obj) is inspect.getmodule(getattr(obj, name)) ] #print getattr(getattr(obj, curItem), 'im_class') elif typ == 'attribute': # attribute # Exclude those attributes inherited from another # class. items = [ name for name in dir(obj) if not hasattr(getattr(obj, name), '__call__') and inspect.getmodule(obj) is inspect.getmodule( getattr(obj, name)) ] public = [ x for x in items if not x.startswith('_') or x.endswith('__') ] 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 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(os.path.dirname(__file__), "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, extensions=["jinja2.ext.do"]) # read items = find_autosummary_in_files(sources) # 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 = output_dir or os.path.abspath(path) ensuredir(path) try: name, obj, parent = import_by_name(name) except ImportError, 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=[]): # XXX: whole function is a patch! if typ in ("function", "class", "exception"): # modules seem to work items = [name for name in dir(obj) if get_documenter(getattr(obj, name), obj).objtype == typ] items = [name for name in items if getattr(obj, name).__module__ == obj.__name__] elif typ == "method": # filter methods (__call__) which are defined within this # class (im_class) items = [ name for name in dir(obj) if hasattr(getattr(obj, name), "__call__") and hasattr(getattr(obj, name), "im_class") ] elif typ == "attribute": # attribute items = [name for name in dir(obj) if not hasattr(getattr(obj, name), "__call__")] public = [x for x in items if not x.startswith("_") or x.endswith("__")] 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()