def create_template_bridge(self): # type: () -> None """Return the template bridge configured.""" if self.config.template_bridge: self.templates = self.app.import_object( self.config.template_bridge, 'template_bridge setting')() else: from sphinx.jinja2glue import BuiltinTemplateLoader self.templates = BuiltinTemplateLoader()
def __init__(self, app): template_loader = BuiltinTemplateLoader() template_loader.init(app.builder) template_env = SandboxedEnvironment(loader=template_loader) template_env.filters['rst_escape'] = rst_escape_filter template_env.filters['underline'] = underline_filter template_env.filters['as_extlink'] = as_extlink_filter template_env.filters['prefixes'] = prefixes_filter template_env.filters['rst_link'] = rst_link_filter self.env = template_env self.templates = {}
def init(self, builder, *args, **kw): self.jinja2_fallback = BuiltinTemplateLoader() self.jinja2_fallback.init(builder, *args, **kw) builder.config.html_context['site_base'] = builder.config['site_base'] self.lookup = TemplateLookup( directories=builder.config.templates_path, imports=["from builder import util"], #format_errors=True, )
def __init__(self, builder: Builder, template_dir: str) -> None: loader = None # type: BaseLoader template_dirs = [os.path.join(package_dir, 'ext', 'autosummary', 'templates')] if builder is None: if template_dir: template_dirs.insert(0, template_dir) loader = FileSystemLoader(template_dirs) else: # allow the user to override the templates loader = BuiltinTemplateLoader() loader.init(builder, dirs=template_dirs) self.env = SandboxedEnvironment(loader=loader) self.env.filters['escape'] = rst.escape self.env.filters['e'] = rst.escape self.env.filters['underline'] = _underline
def _templates(builder): global _default_templates # Some builders have no templates manager at all, and some # have the attribute set to None. templates = getattr(builder, 'templates', None) if not templates: if not _default_templates: # Initialize default templates manager once _default_templates = BuiltinTemplateLoader() _default_templates.init(builder) templates = _default_templates return templates
def get_template_env(app): """ Get the template environment. .. note:: Template should be loaded as a package_data using :py:function:`pkgutil.get_data`, but because we want the user to override the default template we need to hook it to the Sphinx loader, and thus a file system approach is required as it is implemented like that. """ template_dir = [join(dirname(abspath(__file__)), 'templates')] template_loader = BuiltinTemplateLoader() template_loader.init(app.builder, dirs=template_dir) template_env = SandboxedEnvironment(loader=template_loader) template_env.filters['summary'] = filter_summary return template_env
def init(self, builder, *args, **kw): self.jinja2_fallback = BuiltinTemplateLoader() self.jinja2_fallback.init(builder, *args, **kw) builder.config.html_context['release_date'] = builder.config[ 'release_date'] builder.config.html_context['site_base'] = builder.config['site_base'] self.lookup = TemplateLookup( directories=builder.config.templates_path, #format_exceptions=True, imports=["from builder import util"]) if rtd: import urllib2 template_url = builder.config['site_base'] + "/docs_base.mako" template = urllib2.urlopen(template_url).read() self.lookup.put_string("/rtd_base.mako", template)
def init(self, builder, *args, **kw): self.jinja2_fallback = BuiltinTemplateLoader() self.jinja2_fallback.init(builder, *args, **kw) builder.config.html_context['release_date'] = \ builder.config['release_date'] protocol_agnostic = builder.config['site_base'] protocol_agnostic = re.sub("^https?://", "//", protocol_agnostic) builder.config.html_context['site_base'] = protocol_agnostic self.app = builder.app package_dir = os.path.abspath(os.path.dirname(__file__)) template_path = os.path.join( package_dir, 'themes', builder.config.html_theme) self.lookup = TemplateLookup( strict_undefined=True, directories=builder.config.templates_path + [ template_path ], # format_exceptions=True, imports=[ "from zzzeeksphinx import util" ] ) if rtd and builder.config['site_base']: import urllib2 if builder.config['site_adapter_template']: # remote site layout / startup files template_name = builder.config['site_adapter_template'] template = urllib2.urlopen( builder.config['site_base'] + "/" + template_name).read() self.lookup.put_string(template_name, template) py_name = builder.config['site_adapter_py'] if py_name: setup_ctx = urllib2.urlopen( builder.config['site_base'] + "/" + py_name).read() lcls = {} exec(setup_ctx, lcls) self.setup_ctx = lcls['setup_context']
def get_doc_object(obj, what=None, doc=None, config={}, builder=None): if what is None: if inspect.isclass(obj): what = "class" elif inspect.ismodule(obj): what = "module" elif isinstance(obj, Callable): what = "function" else: what = "object" if what == "class" and hasattr(obj, "run") and hasattr(obj, "audit"): what = "footing" template_dirs = [os.path.join(os.path.dirname(__file__), "templates")] if builder is not None: template_loader = BuiltinTemplateLoader() template_loader.init(builder, dirs=template_dirs) else: template_loader = FileSystemLoader(template_dirs) template_env = SandboxedEnvironment(loader=template_loader) config["template"] = template_env.get_template("footings_docstring.rst") if what == "footing": return SphinxFootingsDoc(obj, func_doc=SphinxFunctionDoc, doc=doc, config=config) elif what == "class": return SphinxClassDoc(obj, func_doc=SphinxFunctionDoc, doc=doc, config=config) elif what in ("function", "method"): return SphinxFunctionDoc(obj, doc=doc, config=config) else: if doc is None: doc = pydoc.getdoc(obj) return SphinxObjDoc(obj, doc, config=config)
def __init__(self, builder: Builder, template_dir: str) -> None: loader = None # type: BaseLoader template_dirs = [ os.path.join(package_dir, 'ext', 'autosummary', 'templates') ] if builder is None: if template_dir: template_dirs.insert(0, template_dir) loader = FileSystemLoader(template_dirs) else: # allow the user to override the templates loader = BuiltinTemplateLoader() loader.init(builder, dirs=template_dirs) self.env = SandboxedEnvironment(loader=loader) self.env.filters['escape'] = rst.escape self.env.filters['e'] = rst.escape self.env.filters['underline'] = _underline if builder: if builder.app.translator: self.env.add_extension("jinja2.ext.i18n") self.env.install_gettext_translations( builder.app.translator) # type: ignore
def copy_static_files(self): result = super(AbstractSlideBuilder, self).copy_static_files() # add context items for search function used in searchtools.js_t ctx = self.globalcontext.copy() ctx.update(self.indexer.context_for_searchtool()) from sphinx.jinja2glue import BuiltinTemplateLoader templateRenderer = BuiltinTemplateLoader() staticdir = os.path.join(self.outdir, '_static') for theme in self._additional_themes[1:]: themeentries = [ os.path.join(themepath, 'static') for themepath in theme.get_theme_dirs()[::-1] ] templateRenderer.init(self, dirs=themeentries) for entry in themeentries: copy_asset(entry, staticdir, context=ctx, renderer=templateRenderer) return result
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): 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 # skip base modules if name.endswith(".base"): 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 exclude_member(obj, name): if sys.skip_member(name, obj): return True live = getattr(obj, name) if inspect.isbuiltin(live): return True real_module = inspect.getmodule(live) if real_module is not None: if real_module.__name__ in ["ctypes", "unittest"]: return True c = getattr(obj, name) if inspect.isclass(c) or inspect.isfunction(c): if (c.__module__ != obj.__name__ + ".base" and c.__module__ != obj.__name__): return True return False def get_members(obj, typ, include_public=[]): items = [] for name in dir(obj): # skip_member if exclude_member(obj, name): continue try: documenter = get_documenter(safe_getattr(obj, name), obj) except AttributeError: continue if documenter.objtype == typ: items.append(name) elif typ == 'function' and documenter.objtype == 'boundmethod': items.append(name) public = [ x for x in items if x in include_public or not x.startswith('_') ] return public, items def def_members(obj, typ, include_public=[]): items = [] try: obj_dict = safe_getattr(obj, '__dict__') except AttributeError: return [] defined = obj_dict.keys() defined.sort() for name in defined: if exclude_member(obj, name): continue 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 def get_iattributes(obj): items = [] name = obj.__name__ obj_attr = dir(obj) analyzer = ModuleAnalyzer.for_module(obj.__module__) attr_docs = analyzer.find_attr_docs() for pair, doc in attr_docs.iteritems(): if name != pair[0]: continue if not pair[1] in obj_attr: items.append({ "name": pair[1], "doc": '\n '.join(doc) }) items.sort(key=lambda d: d["name"]) return items ns = {} if doc.objtype == 'module': ns['all_members'] = dir(obj) ns['classes'], ns['all_classes'] = \ get_members(obj, 'class') ns['functions'], ns['all_functions'] = \ get_members(obj, 'function') ns['exceptions'], ns['all_exceptions'] = \ get_members(obj, 'exception') ns['data'], ns['all_data'] = \ get_members(obj, 'data') documented = ns['classes'] + ns['functions'] + ns[ 'exceptions'] + ns['data'] if sys.all_submodules.has_key(obj.__name__): ns['submodules'] = sys.all_submodules[obj.__name__] # Hide base submodule if "base" in ns['submodules']: ns['submodules'].remove("base") documented += ns['submodules'] ns['members'] = ns['all_members'] try: obj_dict = safe_getattr(obj, '__dict__') except AttributeError: obj_dict = [] public = [x for x in obj_dict if not x.startswith('_')] for item in documented: if item in public: public.remove(item) public.sort() ns['members'] = public ns['constants'] = [ x for x in public #if not sys.skip_member(x, obj)] if not exclude_member(obj, x) ] elif doc.objtype == 'class': ns['members'] = dir(obj) ns['events'], ns['all_events'] = \ get_members(obj, 'event') ns['methods'], ns['all_methods'] = \ get_members(obj, 'method', ['__init__']) ns['attributes'], ns['all_attributes'] = \ get_members(obj, 'attribute') # Add instance attributes ns['iattributes'] = get_iattributes(obj) ns['def_events'] = def_members(obj, 'event') ns['def_methods'] = def_members(obj, 'method') ns['def_attributes'] = def_members(obj, 'attribute') # Constructor method special case if '__init__' in ns['methods']: ns['methods'].remove('__init__') if '__init__' in ns['def_methods']: ns['def_methods'].remove('__init__') ns['constructor'] = ['__init__'] else: ns['constructor'] = [] ns['inherited'] = [] for t in ['events', 'methods', 'attributes']: key = 'inh_' + t ns[key] = [] for item in ns[t]: if not item in ns['def_' + t]: ns['inherited'].append(item) ns[key].append(item) 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_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) # 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, 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: res = import_by_name(name) if len(res) == 3: name, obj, parent = res else: name, obj, parent, mod_name = res 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=[]): 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') ##Added, following four lines ns['data'], ns['all_data'] = \ get_members(obj, 'data') ns['attributes'], ns['all_attributes'] = \ get_members(obj, 'attribute') 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') ##NEW #Try to get stuff that's only in attributes if hasattr(obj, '__module__'): realmodule = obj.__module__ elif hasattr(parent, '__module__'): realmodule = parent.__module__ else: realmodule = None if realmodule: #Keyed by a tuple of (class name, attribute name) #Result is a list of docstrings docattrs = ModuleAnalyzer.for_module( realmodule).find_attr_docs() moreattrs = [ k[1] for k in docattrs.keys() if k[1] not in ns['all_attributes'] and k[0] == obj.__name__ ] ns['all_attributes'].extend(moreattrs) ns['attributes'].extend( [a for a in moreattrs if not a.startswith('_')]) ##END NEW 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', 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:] print('[autosummary] generating autosummary for: %s' % ', '.join(showed_sources)) if output_dir: print('[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) # keep track of new files new_files = [] 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: print('WARNING [autosummary] failed to import %r: %s' % (name, e), file=sys.stderr) continue fn = os.path.join(path, name + suffix).replace('::', '.') # skip it if it exists if os.path.isfile(fn): continue new_files.append(fn) if template_name is None: if obj.tag == 'compounddef' and obj.get('kind') == 'class': template_name = 'doxyclass.rst' else: raise NotImplementedError('No template for %s' % obj) with open(fn, 'w') as f: template = template_env.get_template(template_name) ns = {} if obj.tag == 'compounddef' and obj.get('kind') == 'class': ns['methods'] = [ e.text for e in obj.findall( './/sectiondef[@kind="public-func"]/memberdef[@kind="function"]/name' ) ] ns['enums'] = [ e.text for e in obj.findall( './/sectiondef[@kind="public-type"]/memberdef[@kind="enum"]/name' ) ] ns['objtype'] = 'class' else: raise NotImplementedError(obj) parts = name.split('::') 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['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, base_path=base_path, builder=builder, template_dir=template_dir)
def add_content(self, more_content, no_docstring=False): if self.doc_as_attr: super(GWpyClassDocumenter, self).add_content( more_content, no_docstring=no_docstring) else: name = safe_getattr(self.object, '__name__', None) if name: # create our own templating environment builder = self.env.app.builder or None template_dirs = [os.path.join(package_dir, 'ext', 'autosummary', 'templates')] if builder is not None: if builder.config.templates_path: template_dirs = (builder.config.templates_path + template_dirs) # allow the user to override the templates template_loader = BuiltinTemplateLoader() template_loader.init(builder, dirs=template_dirs) else: template_loader = FileSystemLoader(template_dirs) template_env = SandboxedEnvironment(loader=template_loader) template = template_env.get_template('autoclass/class.rst') 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 ns = {} config = self.env.app.config npconfig = dict( use_plots=config.numpydoc_use_plots, show_class_members=config.numpydoc_show_class_members) ns['docstring'] = SphinxClassDoc(self.object, config=npconfig) ns['members'] = vars(self.object) ns['methods'], ns['all_methods'] = get_members(self.object, 'method', ['__init__']) ns['attributes'], ns['all_attributes'] = get_members( self.object, 'attribute') parts = self.fullname.split('.') mod_name, obj_name = '.'.join(parts[:-1]), parts[-1] ns['fullname'] = name ns['module'] = mod_name ns['objname'] = obj_name ns['name'] = parts[-1] for line in template.render(**ns).split('\n'): if line not in [None, 'None']: self.add_line(line, '<autodoc>') self.doc_as_attr = True
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, 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 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 = 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=[]): items = [] for name in dir(obj): if sys.skip_member(name, obj): continue if typ in ['class', 'function']: c = getattr(obj, name) if inspect.isclass(c) or inspect.isfunction(c): if (c.__module__ != obj.__name__ + ".base" and c.__module__ != obj.__name__): continue 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 def_members(obj, typ, include_public=[]): items = [] try: obj_dict = safe_getattr(obj, '__dict__') except AttributeError: return [] defined = obj_dict.keys() defined.sort() for name in defined: if sys.skip_member(name, obj): continue 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 ns = {} if doc.objtype == 'module': ns['all_members'] = dir(obj) ns['classes'], ns['all_classes'] = \ get_members(obj, 'class') ns['functions'], ns['all_functions'] = \ get_members(obj, 'function') ns['exceptions'], ns['all_exceptions'] = \ get_members(obj, 'exception') if sys.all_submodules.has_key(obj.__name__): ns['submodules'] = sys.all_submodules[obj.__name__] ns['members'] = ns['all_members'] try: obj_dict = safe_getattr(obj, '__dict__') except AttributeError: obj_dict = [] public = [x for x in obj_dict if not x.startswith('_')] for item in ns['classes'] + ns['functions'] + ns['exceptions']: if item in public: public.remove(item) public.sort() ns['members'] = public ns['constants'] = [ x for x in public if not sys.skip_member(x, obj) ] elif doc.objtype == 'class': ns['members'] = dir(obj) ns['events'], ns['all_events'] = \ get_members(obj, 'event') ns['methods'], ns['all_methods'] = \ get_members(obj, 'method', ['__init__']) ns['attributes'], ns['all_attributes'] = \ get_members(obj, 'attribute') ns['def_events'] = def_members(obj, 'event') ns['def_methods'] = def_members(obj, 'method', ['__init__']) ns['def_attributes'] = def_members(obj, 'attribute') ns['inherited'] = [] for t in ['events', 'methods', 'attributes']: key = 'inh_' + t ns[key] = [] for item in ns[t]: if not item in ns['def_' + t]: ns['inherited'].append(item) ns[key].append(item) 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, 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] # create our own templating environment template_dirs = None # type: List[str] template_dirs = [os.path.join(package_dir, 'ext', 'autosummary', 'templates')] template_loader = None # type: Union[BuiltinTemplateLoader, FileSystemLoader] 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) 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(app, 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, 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'): 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, app=app)