def server(path='/'):
    try:
        account = g.account
        application = g.account.application
        # prepare the jinja environment. This is used for regular routes 
        # and special handlers such as 404
        template_lookup = {t.key: t.jinja2 for t in application.templates}
        loader = DictLoader(template_lookup)
        jinja_env = SandboxedEnvironment(
            extensions=['application.app.pyjade.ext.jinja.PyJadeExtension'],
            loader=loader)
        
        # default helper utils
        path = PathUtil(request.environ)
        get = GetUtil(request)
        static = StaticUtil()

        # load template data. 404 can also use these
        template_data = {}
        template_data['path'] = path
        template_data['get'] = get
        template_data['cms'] = cms
        template_data['static'] = static
        template_data['deployment'] = config.TEMPLATE_GLOBAL_DEPLOYMENT
        template_data['markdown'] = service.markdown

        template_content = {}
        for content in application.static_contents:
            template_content.update(content.data)
        template_data['content'] = template_content

        # find the route with werkzeug
        url_map = Map()
        for route in application.routes:
            # skip non string rules like 404. These should be handled by exceptions
            if not route.rule.isnumeric():
                url_map.add(Rule(route.rule, endpoint=route.template_name))
        urls = url_map.bind_to_environ(request.environ)
        endpoint, args = urls.match()
        template_data['path'].add_placeholders(args)

        app_template = jinja_env.get_template(endpoint)
        page_content = app_template.render(**template_data)
        app.record_transfer(page_content)
        return page_content

    except NotFound as e:
        # find the template for a 404 handler if specified
        for route in application.routes:
            if route.rule == '404':
                app_template = jinja_env.get_template(route.template_name)
                not_found_page = app_template.render(**template_data)
                app.record_transfer(not_found_page)
                return not_found_page, 404
        return '404', 404

    except Exception as e:
        return '500 internal error', 500
Exemple #2
0
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'

    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('nlcpydoc_docstring.rst')

    if 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)
Exemple #3
0
class RenderHelper:
    def __init__(self, sr_name: str = None, base_dir: Path = None) -> None:
        if base_dir is None:
            base_dir = Path(os.path.dirname(os.path.realpath(__file__)))
        template_dirs = [str(base_dir / 'templates/')]
        if sr_name:
            template_dirs.insert(0, str(base_dir / 'templates' / sr_name.lower()))
        self.env = SandboxedEnvironment(loader=FileSystemLoader(template_dirs))
        self.load_filters()

    def try_render(self, template_file, ctx):
        try:
            return self.render(template_file, ctx)
        except Exception:
            traceback.print_exc()

    def render(self, template_file, ctx, **kwargs):
        ctx.update(kwargs)
        template = self.env.get_template(template_file)
        return template.render(**ctx)

    def load_filters(self):
        self.env.filters['team_sr'] = team_sr
        self.env.filters['format_date'] = format_date
        self.env.filters['short_channel'] = short_channel
        self.env.filters['passer_rating'] = pr_filter
        self.env.filters['position'] = pos_filter
Exemple #4
0
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, collections.Callable):
            what = 'function'
        else:
            what = 'object'

    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('numpydoc_docstring.rst')

    if 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)
Exemple #5
0
class DocWriter:
    """
    Write module documentation source, using the same template format
    as `sphinx.ext.autosummary
    <www.sphinx-doc.org/en/stable/ext/autosummary.html>`__.
    """

    def __init__(self, outpath, tmpltpath):
        """
        Parameters
        ----------
        outpath : string
          Directory path for RST output files
        tmpltpath : string
          Directory path for autosummary template files
        """

        self.outpath = outpath
        self.template_loader = FileSystemLoader(tmpltpath)
        self.template_env = SandboxedEnvironment(loader=self.template_loader)
        self.template_env.filters['underline'] = _underline
        self.template_env.filters['escape'] = rst_escape
        self.template_env.filters['e'] = rst_escape
        self.template = self.template_env.get_template('module.rst')


    def write(self, module):
        """
        Write the RST source document for generating the docs for
        a specified module.

        Parameters
        ----------
        module : module object
          Module for which member list is to be generated
        """

        modname = module.__name__

        # Based on code in generate_autosummary_docs in https://git.io/fxpJS
        ns = {}
        ns['members'] = dir(module)
        ns['functions'] = list(map(lambda x: x.__name__,
                                   get_module_functions(module)))
        ns['classes'] = list(map(lambda x: x.__name__,
                                 get_module_classes(module)))
        ns['exceptions'] = list(map(lambda x: x.__name__,
                                    get_module_exceptions(module)))
        ns['fullname'] = modname
        ns['module'] = modname
        ns['objname'] = modname
        ns['name'] = modname.split('.')[-1]
        ns['objtype'] = 'module'
        ns['underline'] = len(modname) * '='
        rndr = self.template.render(**ns)

        rstfile = os.path.join(self.outpath, modname + '.rst')
        with open(rstfile, 'w') as f:
            f.write(rndr)
 def load_config(self, config):
     self.use_plots = config.get('use_plots', False)
     self.class_members_toctree = config.get('class_members_toctree', True)
     self.template = config.get('template', None)
     if self.template is None:
         template_dirs = [os.path.join(os.path.dirname(__file__), 'templates')]
         template_loader = FileSystemLoader(template_dirs)
         template_env = SandboxedEnvironment(loader=template_loader)
         self.template = template_env.get_template('numpydoc_docstring.rst')
Exemple #7
0
def main ():
    loader = FileSystemLoader([".templates"])
    env = SandboxedEnvironment(loader=loader)

    done_files = []

    for orig_module in auto.modules:
        output = orig_module + ".rst"

        f = open(output, "w")

        try:
            mod_base = orig_module.split(".")[-1]
            module = __import__(orig_module, fromlist=mod_base)

            def get_methods_etc (obj):
                if not hasattr(obj, "__dict__"):
                    return ""

                obj_dict = getattr(obj, "__dict__")
                return ", ".join(set(obj_dict.keys()))

            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

            ns = {}
            ns['members'] = dir(module)
            ns['functions'] = get_members(module, 'function')
            ns['classes'] = get_members(module, 'class')
            ns['exceptions'] = get_members(module, 'exception')
            ns['name'] = mod_base
            ns['fullname'] = orig_module
            ns['name_underline'] = "=" * len(mod_base)
            ns['fullname_underline'] = "=" * len(orig_module)
            ns['mod_underline'] = "=" * (len(mod_base) + len(":mod:``"))

            template = env.get_template("module.rst")
            rendered = template.render(**ns)
            f.write(rendered)
        finally:
            f.close()
            done_files.append(output)

    summary_template = open("summary.rst.template").read()
    modules = ""

    for module in done_files:
        modules += "    %s\n" % module

    f = open("summary.rst", "w")
    f.write(summary_template % {"files": modules})
    f.close()
Exemple #8
0
class BaseRenderer(object):
    def __init__(self, loader=None):
        self.env = SandboxedEnvironment(loader=loader)
        self.env.filters['repr'] = repr

    def render(self, template_name, context):
        return self.env.get_template(template_name).render(context)

    def render_string(self, source, context):
        return self.env.from_string(source).render(context)
Exemple #9
0
class BaseRenderer(object):
    def __init__(self, loader=None):
        self.env = SandboxedEnvironment(loader=loader)
        self.env.filters['repr'] = repr

    def render(self, template_name, context):
        return self.env.get_template(template_name).render(context)

    def render_string(self, source, context):
        return self.env.from_string(source).render(context)
Exemple #10
0
class BaseRenderer:
    def __init__(self, loader: BaseLoader = None) -> None:
        self.env = SandboxedEnvironment(loader=loader, extensions=['jinja2.ext.i18n'])
        self.env.filters['repr'] = repr
        self.env.install_gettext_translations(get_translator())

    def render(self, template_name: str, context: Dict) -> str:
        return self.env.get_template(template_name).render(context)

    def render_string(self, source: str, context: Dict) -> str:
        return self.env.from_string(source).render(context)
Exemple #11
0
class AutosummaryRenderer:
    """A helper class for rendering."""
    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 exists(self, template_name: str) -> bool:
        """Check if template file exists."""
        try:
            self.env.get_template(template_name)
            return True
        except TemplateNotFound:
            return False

    def render(self, template_name: str, context: Dict) -> str:
        """Render a template file."""
        return self.env.get_template(template_name).render(context)
Exemple #12
0
 def _render_files(self, template_args, output_dir):
     env = SandboxedEnvironment(
         loader=FileSystemLoader(self.template_dir),
         extensions=[],
     )
     try:
         for template in self.template_files():
             output_str = env.get_template(template).render(template_args)
             output_file = output_dir + "/" + template.rstrip(".j2")
             with open(output_file, "w+") as f:
                 f.write(output_str)
     except TemplateSyntaxError as e:
         print("[{}:{}] {} ".format(e.filename, e.lineno, e.message))
         sys.exit(1)
Exemple #13
0
class BaseRenderer(object):
    def __init__(self, loader=None):
        # type: (BaseLoader) -> None
        self.env = SandboxedEnvironment(loader=loader, extensions=['jinja2.ext.i18n'])
        self.env.filters['repr'] = repr
        self.env.install_gettext_translations(get_translator())  # type: ignore

    def render(self, template_name, context):
        # type: (unicode, Dict) -> unicode
        return self.env.get_template(template_name).render(context)

    def render_string(self, source, context):
        # type: (unicode, Dict) -> unicode
        return self.env.from_string(source).render(context)
Exemple #14
0
class BaseRenderer(object):
    def __init__(self, loader=None):
        # type: (BaseLoader) -> None
        self.env = SandboxedEnvironment(loader=loader, extensions=['jinja2.ext.i18n'])
        self.env.filters['repr'] = repr
        self.env.install_gettext_translations(get_translator())  # type: ignore

    def render(self, template_name, context):
        # type: (unicode, Dict) -> unicode
        return self.env.get_template(template_name).render(context)

    def render_string(self, source, context):
        # type: (unicode, Dict) -> unicode
        return self.env.from_string(source).render(context)
Exemple #15
0
 def _render_files(self, template_args, output_dir):
     env = SandboxedEnvironment(
         loader=FileSystemLoader(self.template_dir),
         extensions=[],
     )
     try:
         for template in self.template_files():
             output_str = env.get_template(template).render(template_args)
             output_file = output_dir + "/" + template.rstrip(".j2")
             with open(output_file, "w+") as f:
                 f.write(output_str)
     except TemplateSyntaxError as e:
         print("[{}:{}] {} ".format(e.filename, e.lineno, e.message))
         sys.exit(1)
Exemple #16
0
 def load_config(self, config):
     self.use_plots = config.get('use_plots', False)
     self.use_blockquotes = config.get('use_blockquotes', False)
     self.class_members_toctree = config.get('class_members_toctree', True)
     self.attributes_as_param_list = config.get('attributes_as_param_list', True)
     self.xref_param_type = config.get('xref_param_type', False)
     self.xref_aliases = config.get('xref_aliases', dict())
     self.xref_ignore = config.get('xref_ignore', set())
     self.template = config.get('template', None)
     if self.template is None:
         template_dirs = [os.path.join(os.path.dirname(__file__), 'templates')]
         template_loader = FileSystemLoader(template_dirs)
         template_env = SandboxedEnvironment(loader=template_loader)
         self.template = template_env.get_template('numpydoc_docstring.rst')
Exemple #17
0
 def load_config(self, config):
     self.use_plots = config.get('use_plots', False)
     self.use_blockquotes = config.get('use_blockquotes', False)
     self.class_members_toctree = config.get('class_members_toctree', True)
     self.attributes_as_param_list = config.get('attributes_as_param_list', True)
     self.xref_param_type = config.get('xref_param_type', False)
     self.xref_aliases = config.get('xref_aliases', dict())
     self.xref_ignore = config.get('xref_ignore', set())
     self.template = config.get('template', None)
     if self.template is None:
         template_dirs = [os.path.join(os.path.dirname(__file__), 'templates')]
         template_loader = FileSystemLoader(template_dirs)
         template_env = SandboxedEnvironment(loader=template_loader)
         self.template = template_env.get_template('numpydoc_docstring.rst')
Exemple #18
0
def _get_template(template_path:str):

    # Create a template loader which looks in the correct folders, for
    # reference see 'sphinx.ext.autosummary.AutosummaryRenderer.__init__()'
    templates_path = os.path.join(
        os.path.abspath(os.path.dirname(__file__)), '..', '_templates',
    )
    loader = SphinxFileSystemLoader(templates_path)
    env = SandboxedEnvironment(loader=loader)

    try:
        return env.get_template(template_path)
    except TemplateNotFound:
        logger.error("Could not find templates for instruments.")
        raise
Exemple #19
0
 def load_config(self, config):
     self.use_plots = config.get("use_plots", False)
     self.use_blockquotes = config.get("use_blockquotes", False)
     self.class_members_toctree = config.get("class_members_toctree", True)
     self.attributes_as_param_list = config.get("attributes_as_param_list",
                                                True)
     self.xref_param_type = config.get("xref_param_type", False)
     self.xref_aliases = config.get("xref_aliases", dict())
     self.xref_ignore = config.get("xref_ignore", set())
     self.template = config.get("template", None)
     if self.template is None:
         template_dirs = [
             os.path.join(os.path.dirname(__file__), "templates")
         ]
         template_loader = FileSystemLoader(template_dirs)
         template_env = SandboxedEnvironment(loader=template_loader)
         self.template = template_env.get_template("footings_docstring.rst")
Exemple #20
0
def create_module_file(package, module, opts):
    # type: (unicode, unicode, Any) -> None
    """Generate RST for a top-level module (i.e., not part of a package)"""
    if not opts.noheadings:
        text = format_heading(1, '%s module' % module)
    else:
        text = ''
    # text += format_heading(2, ':mod:`%s` Module' % module)
    text += format_directive(module, package)

    if opts.templates:
        template_loader = FileSystemLoader(opts.templates)
        template_env = SandboxedEnvironment(loader=template_loader)
        try:
            mod_ns = _get_mod_ns(name=module,
                                 fullname=module,
                                 includeprivate=opts.includeprivate)
            template = template_env.get_template('module.rst')
            text = template.render(**mod_ns)
        except ImportError as e:
            _warn('failed to import %r: %s' % (module, e))
    write_file(makename(package, module), text, opts)
Exemple #21
0
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)
Exemple #22
0
    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
Exemple #23
0
def create_package_file(root, master_package, subroot, py_files, opts, subs,
                        is_namespace):
    # type: (unicode, unicode, unicode, List[unicode], Any, List[unicode], bool) -> None
    """Build the text of the file and write the file."""

    use_templates = False
    fullname = makename(master_package, subroot)

    if opts.templates:
        use_templates = True
        template_loader = FileSystemLoader(opts.templates)
        template_env = SandboxedEnvironment(loader=template_loader)

    text = format_heading(
        1, ('%s package' if not is_namespace else "%s namespace") % fullname)

    if opts.modulefirst and not is_namespace:
        text += format_directive(subroot, master_package)
        text += '\n'

    # build a list of directories that are szvpackages (contain an INITPY file)
    subs = [sub for sub in subs if path.isfile(path.join(root, sub, INITPY))]
    # if there are some package directories, add a TOC for theses subpackages
    if subs:
        text += format_heading(2, 'Subpackages')
        text += '.. toctree::\n\n'
        for sub in subs:
            text += '    %s.%s\n' % (makename(master_package, subroot), sub)
        text += '\n'

    submods = [
        path.splitext(sub)[0] for sub in py_files
        if not shall_skip(path.join(root, sub), opts) and sub != INITPY
    ]

    if use_templates:
        try:
            package_ns = _get_mod_ns(name=subroot,
                                     fullname=fullname,
                                     includeprivate=opts.includeprivate)
            package_ns['subpackages'] = subs
            package_ns['submodules'] = submods
        except ImportError as e:
            _warn('failed to import %r: %s' % (fullname, e))

    if submods:
        text += format_heading(2, 'Submodules')
        if opts.separatemodules:
            text += '.. toctree::\n\n'
            for submod in submods:
                modfile = makename(master_package, makename(subroot, submod))
                text += '   %s\n' % modfile

                # generate separate file for this module
                if not opts.noheadings:
                    filetext = format_heading(1, '%s module' % modfile)
                else:
                    filetext = ''
                filetext += format_directive(makename(subroot, submod),
                                             master_package)
                if use_templates:
                    try:
                        mod_ns = _get_mod_ns(
                            name=submod,
                            fullname=modfile,
                            includeprivate=opts.includeprivate)
                        template = template_env.get_template('module.rst')
                        add_get_members_to_template_env(
                            template_env, modfile, opts)
                        filetext = template.render(**mod_ns)
                    except ImportError as e:
                        _warn('failed to import %r: %s' % (modfile, e))
                write_file(modfile, filetext, opts)
        else:
            for submod in submods:
                modfile = makename(master_package, makename(subroot, submod))
                if not opts.noheadings:
                    text += format_heading(2, '%s module' % modfile)
                text += format_directive(makename(subroot, submod),
                                         master_package)
                text += '\n'
        text += '\n'

    if use_templates:
        template = template_env.get_template('package.rst')
        add_get_members_to_template_env(template_env, fullname, opts)
        text = template.render(**package_ns)
    else:
        if not opts.modulefirst and not is_namespace:
            text += format_heading(2, 'Module contents')
            text += format_directive(subroot, master_package)

    write_file(makename(master_package, subroot), text, opts)
Exemple #24
0
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()
Exemple #25
0
class BuiltinTemplateLoader(TemplateBridge, BaseLoader):
    """
    Interfaces the rendering environment of jinja2 for use in Sphinx.
    """

    # TemplateBridge interface

    def init(self, builder: "Builder", theme: Theme = None, dirs: List[str] = None) -> None:
        # create a chain of paths to search
        if theme:
            # the theme's own dir and its bases' dirs
            pathchain = theme.get_theme_dirs()
            # the loader dirs: pathchain + the parent directories for all themes
            loaderchain = pathchain + [path.join(p, '..') for p in pathchain]
        elif dirs:
            pathchain = list(dirs)
            loaderchain = list(dirs)
        else:
            pathchain = []
            loaderchain = []

        # prepend explicit template paths
        self.templatepathlen = len(builder.config.templates_path)
        if builder.config.templates_path:
            cfg_templates_path = [path.join(builder.confdir, tp)
                                  for tp in builder.config.templates_path]
            pathchain[0:0] = cfg_templates_path
            loaderchain[0:0] = cfg_templates_path

        # store it for use in newest_template_mtime
        self.pathchain = pathchain

        # make the paths into loaders
        self.loaders = [SphinxFileSystemLoader(x) for x in loaderchain]

        use_i18n = builder.app.translator is not None
        extensions = ['jinja2.ext.i18n'] if use_i18n else []
        self.environment = SandboxedEnvironment(loader=self,
                                                extensions=extensions)
        self.environment.filters['tobool'] = _tobool
        self.environment.filters['toint'] = _toint
        self.environment.filters['todim'] = _todim
        self.environment.filters['slice_index'] = _slice_index
        self.environment.globals['debug'] = contextfunction(pformat)
        self.environment.globals['warning'] = warning
        self.environment.globals['accesskey'] = contextfunction(accesskey)
        self.environment.globals['idgen'] = idgen
        if use_i18n:
            self.environment.install_gettext_translations(builder.app.translator)  # type: ignore  # NOQA

    def render(self, template: str, context: Dict) -> str:  # type: ignore
        return self.environment.get_template(template).render(context)

    def render_string(self, source: str, context: Dict) -> str:
        return self.environment.from_string(source).render(context)

    def newest_template_mtime(self) -> float:
        return max(mtimes_of_files(self.pathchain, '.html'))

    # Loader interface

    def get_source(self, environment: Environment, template: str) -> Tuple[str, str, Callable]:
        loaders = self.loaders
        # exclamation mark starts search from theme
        if template.startswith('!'):
            loaders = loaders[self.templatepathlen:]
            template = template[1:]
        for loader in loaders:
            try:
                return loader.get_source(environment, template)
            except TemplateNotFound:
                pass
        raise TemplateNotFound(template)
Exemple #26
0
class BuiltinTemplateLoader(TemplateBridge, BaseLoader):
    """
    Interfaces the rendering environment of jinja2 for use in Sphinx.
    """

    # TemplateBridge interface

    def init(self, builder, theme=None, dirs=None):
        # create a chain of paths to search
        if theme:
            # the theme's own dir and its bases' dirs
            chain = theme.get_dirchain()
            # then the theme parent paths
            chain.extend(theme.themepath)
        elif dirs:
            chain = list(dirs)
        else:
            chain = []

        # prepend explicit template paths
        self.templatepathlen = len(builder.config.templates_path)
        if builder.config.templates_path:
            chain[0:0] = [
                path.join(builder.confdir, tp)
                for tp in builder.config.templates_path
            ]

        # store it for use in newest_template_mtime
        self.pathchain = chain

        # make the paths into loaders
        self.loaders = map(SphinxFileSystemLoader, chain)

        use_i18n = builder.app.translator is not None
        extensions = use_i18n and ['jinja2.ext.i18n'] or []
        self.environment = SandboxedEnvironment(loader=self,
                                                extensions=extensions)
        self.environment.filters['tobool'] = _tobool
        self.environment.filters['toint'] = _toint
        self.environment.globals['debug'] = contextfunction(pformat)
        self.environment.globals['accesskey'] = contextfunction(accesskey)
        self.environment.globals['idgen'] = idgen
        if use_i18n:
            self.environment.install_gettext_translations(
                builder.app.translator)

    def render(self, template, context):
        return self.environment.get_template(template).render(context)

    def render_string(self, source, context):
        return self.environment.from_string(source).render(context)

    def newest_template_mtime(self):
        return max(mtimes_of_files(self.pathchain, '.html'))

    # Loader interface

    def get_source(self, environment, template):
        loaders = self.loaders
        # exclamation mark starts search from theme
        if template.startswith('!'):
            loaders = loaders[self.templatepathlen:]
            template = template[1:]
        for loader in loaders:
            try:
                return loader.get_source(environment, template)
            except TemplateNotFound:
                pass
        raise TemplateNotFound(template)
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)
Exemple #28
0
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,
        )
Exemple #29
0
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)
Exemple #30
0
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)
Exemple #31
0
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)
Exemple #32
0
    def __init__(self, worker, config, path):
        """
        :param worker: The router worker controller within this Web service is started.
        :type worker: crossbar.worker.router.RouterController

        :param config: The Web service configuration item.
        :type config: dict
        """
        resource.Resource.__init__(self)
        self._worker = worker
        self._config = config
        self._session_cache = {}

        self._realm_name = config.get('wamp', {}).get('realm', None)
        self._authrole = config.get('wamp', {}).get('authrole', 'anonymous')
        self._service_agent = worker.realm_by_name(self._realm_name).session

        #   TODO:
        #       We need to lookup the credentials for the current user based on the pre-established
        #       HTTP session cookie, this will establish the 'authrole' the user is running as.
        #       This 'authrole' can then be used to authorize the back-end topic call.
        #   QUESTION:
        #       Does the topic need the authid, if so, how do we pass it?
        #
        #   This is our default (anonymous) session for unauthenticated users
        #
        router = worker._router_factory.get(self._realm_name)
        self._default_session = ApplicationSession(
            ComponentConfig(realm=self._realm_name, extra=None))
        worker._router_session_factory.add(self._default_session,
                                           router,
                                           authrole=self._authrole)

        # Setup Jinja2 to point to our templates folder or a package resource
        #
        templates_config = config.get("templates")

        if type(templates_config) == str:
            # resolve specified template directory path relative to node directory
            templates_dir = os.path.abspath(
                os.path.join(self._worker.config.extra.cbdir,
                             templates_config))
            templates_source = 'directory'

        elif type(templates_config) == dict:

            # in case we got a dict, that must contain "package" and "resource" attributes
            if 'package' not in templates_config:
                raise ApplicationError(
                    'crossbar.error.invalid_configuration',
                    'missing attribute "resource" in WAP web service configuration'
                )

            if 'resource' not in templates_config:
                raise ApplicationError(
                    'crossbar.error.invalid_configuration',
                    'missing attribute "resource" in WAP web service configuration'
                )

            try:
                importlib.import_module(templates_config['package'])
            except ImportError as e:
                emsg = 'Could not import resource {} from package {}: {}'.format(
                    templates_config['resource'], templates_config['package'],
                    e)
                raise ApplicationError('crossbar.error.invalid_configuration',
                                       emsg)
            else:
                try:
                    # resolve template directory from package resource
                    templates_dir = os.path.abspath(
                        pkg_resources.resource_filename(
                            templates_config['package'],
                            templates_config['resource']))
                except Exception as e:
                    emsg = 'Could not import resource {} from package {}: {}'.format(
                        templates_config['resource'],
                        templates_config['package'], e)
                    raise ApplicationError(
                        'crossbar.error.invalid_configuration', emsg)

            templates_source = 'package'
        else:
            raise ApplicationError(
                'crossbar.error.invalid_configuration',
                'invalid type "{}" for attribute "templates" in WAP web service configuration'
                .format(type(templates_config)))

        if config.get('sandbox', True):
            # The sandboxed environment. It works like the regular environment but tells the compiler to
            # generate sandboxed code.
            # https://jinja.palletsprojects.com/en/2.11.x/sandbox/#jinja2.sandbox.SandboxedEnvironment
            env = SandboxedEnvironment(loader=FileSystemLoader(templates_dir),
                                       autoescape=True)
        else:
            env = Environment(loader=FileSystemLoader(templates_dir),
                              autoescape=True)

        self.log.info(
            'WapResource created (realm="{realm}", authrole="{authrole}", templates_dir="{templates_dir}", templates_source="{templates_source}", jinja2_env={jinja2_env})',
            realm=hlid(self._realm_name),
            authrole=hlid(self._authrole),
            templates_dir=hlid(templates_dir),
            templates_source=hlid(templates_source),
            jinja2_env=hltype(env.__class__))

        # http://werkzeug.pocoo.org/docs/dev/routing/#werkzeug.routing.Map
        map = Map()

        # Add all our routes into 'map', note each route endpoint is a tuple of the
        # topic to call, and the template to use when rendering the results.
        for route in config.get('routes', {}):

            # compute full absolute URL of route to be added - ending in Werkzeug/Routes URL pattern
            rpath = route['path']
            _rp = []
            if path != '/':
                _rp.append(path)
            if rpath != '/':
                _rp.append(rpath)
            route_url = '/' + '/'.join(_rp)
            route_methods = [route.get('method')]

            # note the WAMP procedure to call and the Jinja2 template to render as HTTP response
            route_endpoint = (route['call'], env.get_template(route['render']))
            map.add(
                Rule(route_url, methods=route_methods,
                     endpoint=route_endpoint))
            self.log.info(
                'WapResource route added (url={route_url}, methods={route_methods}, endpoint={route_endpoint})',
                route_url=hlid(route_url),
                route_methods=hlid(route_methods),
                route_endpoint=route_endpoint)

        # http://werkzeug.pocoo.org/docs/dev/routing/#werkzeug.routing.MapAdapter
        # http://werkzeug.pocoo.org/docs/dev/routing/#werkzeug.routing.MapAdapter.match
        self._map_adapter = map.bind('/')
Exemple #33
0
    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
Exemple #34
0
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

        # 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)

        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 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)
        finally:
            f.close()
Exemple #35
0
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()
Exemple #36
0
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)
Exemple #37
0
class VarnishConfig:
    """Configuration of Varnish server is done through this class.

    Args and Attributes:
        site_name (str): The name of the site config to change.
        transaction (instance, optional): ConfigTransaction Instance
        search_path (list): List of already searched paths.
    """
    def __init__(self, site_name=None, transaction=None):
        self.site_name = site_name
        self.transaction = transaction
        self.search_path = []

    @staticmethod
    def varnish_is_installed():
        try:
            run_cmd("which varnishd", _log, silent=True)
        except OSError:
            return False
        return True

    def _lazy_load_template(self, search_path=None):
        if not search_path:
            search_path = [jinja_config_varnish_base_dir()]

        if self.search_path == search_path:
            return

        (hostname_short, hostname_full) = _get_hostname_short_and_full()

        self.env = SandboxedEnvironment(
            line_statement_prefix=None,
            trim_blocks=True,
            lstrip_blocks=True,
            loader=jinja2.FileSystemLoader(search_path),
            undefined=StrictUndefined,
            extensions=["jinja2.ext.do"])
        self.env.filters["flatten_to_set"] = flatten_to_set
        self.env.filters["parse_url"] = parse_url
        self.env.filters["dns_query"] = dns_query
        self.env.filters["underscore_url"] = underscore_url
        self.env.filters["wildcard_to_regex"] = wildcard_to_regex
        self.env.filters["custom_backend_name"] = custom_backend_name
        self.env.filters["process_custom_vcl"] = process_custom_vcl
        self.env.filters["netmask_bits"] = netmask_bits
        self.env.globals["global_var_get"] = global_var_get
        self.env.globals["global_var_set"] = global_var_set
        self.env.globals["HOSTNAME_FULL"] = hostname_full
        self.env.globals["HOSTNAME_SHORT"] = hostname_short
        self.varn_template = self.env.get_template("varnish.jinja")
        _log.LOGD("Loaded Varnish template:", self.varn_template.filename)

        _log.LOGD("Loading vars schema")
        self.input_vars_schema = json.loads(
            _generate_schema("varnish", search_path))

        self.search_path = search_path

    def gather_template_files(self, search_path=None):
        self._lazy_load_template(search_path)
        files = {
            "varnish.jinja":
            self.env.loader.get_source(self.env, "varnish.jinja")[0],
            "varnish.vars.schema":
            json.dumps(self.input_vars_schema, indent=2)
        }
        return files

    @_varnish_write_command
    def write_template_files(self, files):
        self.transaction.run(lambda: _write_template_files(
            files, jinja_config_varnish_base_dir()))

    @_varnish_write_command
    def write_config_file(self, search_path=None):
        """Read all JSON config files in /etc/varnish/sites, merge them into a large JSON and
        regenerate the Varnish VCL from a template, then tell Varnish to reload the config.
        """
        def do_write():
            sites = []

            _log.LOGI("Loading input vars from JSON")
            # TODO: we need to replace path to variable outside this class
            fnames = sorted([
                "%ssites/%s.json" %
                (script_configs.VARNISH_PATH_CONFIG, _(dom))
                for dom in NginxConfig.get_all_active_domains()
            ])
            _log.LOGI("  -> files: ", fnames)

            for fname in fnames:
                with open(fname) as f:
                    site = json.load(
                        f, object_pairs_hook=dict_raise_on_duplicates)
                    sites.append(site)

            input_vars = {"sites": sites}
            # _log.LOGD(json.dumps(input_vars, indent=2))

            self._lazy_load_template(search_path)
            jsch.validate(input_vars,
                          self.input_vars_schema,
                          format_checker=jsch.FormatChecker())
            cfg = self.varn_template.render(input_vars)

            # _log.LOGI("Generated VCL:", cfg)

            cfg = cfg.replace('\r', '\n')
            cfg = cfg.replace('\n\n', '\n')
            cfg = cfg.replace('\n\n', '\n')

            conf_file_name = os.path.join(script_configs.VARNISH_PATH,
                                          "revsw.vcl")

            with open(conf_file_name + ".tmp", "w") as f:
                f.write(cfg)

            # # re-formatting Varnish config file:
            # run_cmd("cat %(INPUT)s.tmp | %(CONFIG_PATH)sbin/conf_files_formatter.sh >
            # %(OUTPUT)s && mv %(INPUT)s.tmp %(TMP_PATH)s" % \
            #         {
            #             "INPUT": conf_file_name, "OUTPUT": conf_file_name,
            #             "TMP_PATH": script_configs.TMP_PATH, "CONFIG_PATH": script_configs.CONFIG_PATH
            #         },
            #         _log, "re-formatting %s file" % conf_file_name
            #         )
            # # .
            # TODO: remove it after test
            run_cmd(
                "cp %(INPUT)s.tmp %(OUTPUT)s && mv %(INPUT)s.tmp %(TMP_PATH)s"
                % {
                    "INPUT": conf_file_name,
                    "OUTPUT": conf_file_name,
                    "TMP_PATH": script_configs.TMP_PATH,
                    "CONFIG_PATH": script_configs.CONFIG_PATH
                }, _log, "re-formatting %s file" % conf_file_name)

        self.transaction.run(do_write)

    def load_site_config(self):
        """Loads varnish site configuration in JSON object"""
        with open(self.site_config_path()) as f:
            site = json.load(f, object_pairs_hook=dict_raise_on_duplicates)
        return site

    def site_config_path(self):
        if not self.site_name:
            raise AssertionError(
                "'site_config_path' requires the site name but the object is global"
            )
        return "%ssites/%s.json" % (script_configs.VARNISH_PATH_CONFIG,
                                    self.site_name)

    def remove_site(self):
        self.transaction.run(
            lambda: run_cmd("rm -f %s" % self.site_config_path(), _log,
                            "Removing Varnish config"))

    @_varnish_write_command
    def config_site(self, config):
        def do_add():
            cfg_dir = os.path.dirname(self.site_config_path())
            if not os.path.exists(cfg_dir):
                run_cmd("mkdir -p %s" % cfg_dir, _log,
                        "Creating Varnish config dir")
            with open(self.site_config_path(), "w") as f:
                json.dump(config, f, indent=2)

        self.transaction.run(do_add)

    @staticmethod
    def _extract_domain_locations_from_vcl():
        domain_locations = []
        with open(os.path.join(script_configs.VARNISH_PATH, "revsw.vcl"),
                  "rt") as f:
            begin_re = re.compile(r"^\s*# BEGIN SITE\s+'(.+)'$")
            end_re = re.compile(r"^\s*# END SITE\s+'(.+)'$")

            curr_site = None
            curr_begin_line = 0
            line_no = 1
            for l in f:
                m = begin_re.match(l)
                if m:
                    if curr_site:
                        raise SyntaxError(
                            "Found 'BEGIN SITE' inside another 'BEGIN SITE' at line %d"
                            % line_no)
                    curr_site = m.group(1)
                    curr_begin_line = line_no
                else:
                    m = end_re.match(l)
                    if m:
                        if not curr_site:
                            raise SyntaxError(
                                "Found 'END SITE' without matching 'BEGIN SITE' at line %d"
                                % line_no)
                        domain_locations.append({
                            "start": curr_begin_line,
                            "end": line_no,
                            "domain": curr_site
                        })
                        curr_site = None
                line_no += 1
        return domain_locations

    @staticmethod
    def _find_domain_for_vcl_line(domain_locations, line_no):
        left = 0
        right = len(domain_locations)
        while left < right:
            idx = left + (right - left) / 2
            dom = domain_locations[idx]
            if dom["start"] <= line_no:
                if line_no <= dom["end"]:
                    return dom["domain"]
                else:
                    left = idx + 1
            else:
                right = idx
        return None

    @staticmethod
    def get_error_domains(stderr):
        err_domains = set()
        domain_locations = VarnishConfig._extract_domain_locations_from_vcl()
        line_col_re = re.compile(r"^\('input' Line (\d+) Pos (\d+)\)")
        for l in stderr.split("\n"):
            m = line_col_re.match(l)
            if m:
                domain = VarnishConfig._find_domain_for_vcl_line(
                    domain_locations, int(m.group(1)))
                if domain:
                    err_domains.add(domain)
        return err_domains
Exemple #38
0
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()
Exemple #39
0
    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()
Exemple #40
0
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)
Exemple #41
0
class BuiltinTemplateLoader(TemplateBridge, BaseLoader):
    """
    Interfaces the rendering environment of jinja2 for use in Sphinx.
    """

    # TemplateBridge interface

    def init(self, builder, theme=None, dirs=None):
        # type: (Builder, Theme, List[unicode]) -> None
        # create a chain of paths to search
        if theme:
            # the theme's own dir and its bases' dirs
            pathchain = theme.get_theme_dirs()
            # the loader dirs: pathchain + the parent directories for all themes
            loaderchain = pathchain + [path.join(p, '..') for p in pathchain]
        elif dirs:
            pathchain = list(dirs)
            loaderchain = list(dirs)
        else:
            pathchain = []
            loaderchain = []

        # prepend explicit template paths
        self.templatepathlen = len(builder.config.templates_path)
        if builder.config.templates_path:
            cfg_templates_path = [path.join(builder.confdir, tp)
                                  for tp in builder.config.templates_path]
            pathchain[0:0] = cfg_templates_path
            loaderchain[0:0] = cfg_templates_path

        # store it for use in newest_template_mtime
        self.pathchain = pathchain

        # make the paths into loaders
        self.loaders = [SphinxFileSystemLoader(x) for x in loaderchain]

        use_i18n = builder.app.translator is not None
        extensions = use_i18n and ['jinja2.ext.i18n'] or []
        self.environment = SandboxedEnvironment(loader=self,
                                                extensions=extensions)
        self.environment.filters['tobool'] = _tobool
        self.environment.filters['toint'] = _toint
        self.environment.filters['todim'] = _todim
        self.environment.filters['slice_index'] = _slice_index
        self.environment.globals['debug'] = contextfunction(pformat)
        self.environment.globals['warning'] = warning
        self.environment.globals['accesskey'] = contextfunction(accesskey)
        self.environment.globals['idgen'] = idgen
        if use_i18n:
            self.environment.install_gettext_translations(builder.app.translator)  # type: ignore  # NOQA

    def render(self, template, context):  # type: ignore
        # type: (unicode, Dict) -> unicode
        return self.environment.get_template(template).render(context)

    def render_string(self, source, context):
        # type: (unicode, Dict) -> unicode
        return self.environment.from_string(source).render(context)

    def newest_template_mtime(self):
        # type: () -> float
        return max(mtimes_of_files(self.pathchain, '.html'))

    # Loader interface

    def get_source(self, environment, template):
        # type: (Environment, unicode) -> Tuple[unicode, unicode, Callable]
        loaders = self.loaders
        # exclamation mark starts search from theme
        if template.startswith('!'):
            loaders = loaders[self.templatepathlen:]
            template = template[1:]
        for loader in loaders:
            try:
                return loader.get_source(environment, template)
            except TemplateNotFound:
                pass
        raise TemplateNotFound(template)
Exemple #42
0
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()
Exemple #43
0
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)
Exemple #44
0
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)
Exemple #45
0
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)
Exemple #46
0
class AutosummaryRenderer:
    """A helper class for rendering."""
    def __init__(self,
                 app: Union[Builder, Sphinx],
                 template_dir: str = None) -> None:
        if isinstance(app, Builder):
            warnings.warn(
                'The first argument for AutosummaryRenderer has been '
                'changed to Sphinx object',
                RemovedInSphinx50Warning,
                stacklevel=2)
        if template_dir:
            warnings.warn(
                'template_dir argument for AutosummaryRenderer is deprecated.',
                RemovedInSphinx50Warning,
                stacklevel=2)

        system_templates_path = [
            os.path.join(package_dir, 'ext', 'autosummary', 'templates')
        ]
        loader = SphinxTemplateLoader(app.srcdir, app.config.templates_path,
                                      system_templates_path)

        self.env = SandboxedEnvironment(loader=loader)
        self.env.filters['escape'] = rst.escape
        self.env.filters['e'] = rst.escape
        self.env.filters['underline'] = _underline

        if isinstance(app, (Sphinx, DummyApplication)):
            if app.translator:
                self.env.add_extension("jinja2.ext.i18n")
                self.env.install_gettext_translations(app.translator)
        elif isinstance(app, Builder):
            if app.app.translator:
                self.env.add_extension("jinja2.ext.i18n")
                self.env.install_gettext_translations(app.app.translator)

    def exists(self, template_name: str) -> bool:
        """Check if template file exists."""
        warnings.warn('AutosummaryRenderer.exists() is deprecated.',
                      RemovedInSphinx50Warning,
                      stacklevel=2)
        try:
            self.env.get_template(template_name)
            return True
        except TemplateNotFound:
            return False

    def render(self, template_name: str, context: Dict) -> str:
        """Render a template file."""
        try:
            template = self.env.get_template(template_name)
        except TemplateNotFound:
            try:
                # objtype is given as template_name
                template = self.env.get_template('autosummary/%s.rst' %
                                                 template_name)
            except TemplateNotFound:
                # fallback to base.rst
                template = self.env.get_template('autosummary/base.rst')

        return template.render(context)
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)
Exemple #48
0
class BuiltinTemplateLoader(TemplateBridge, BaseLoader):
    """
    Interfaces the rendering environment of jinja2 for use in Sphinx.
    """

    # TemplateBridge interface

    def init(self, builder, theme=None, dirs=None):
        # create a chain of paths to search
        if theme:
            # the theme's own dir and its bases' dirs
            chain = theme.get_dirchain()
            # then the theme parent paths
            chain.extend(theme.themepath)
        elif dirs:
            chain = list(dirs)
        else:
            chain = []

        # prepend explicit template paths
        self.templatepathlen = len(builder.config.templates_path)
        if builder.config.templates_path:
            chain[0:0] = [path.join(builder.confdir, tp)
                          for tp in builder.config.templates_path]

        # store it for use in newest_template_mtime
        self.pathchain = chain

        # make the paths into loaders
        self.loaders = map(SphinxFileSystemLoader, chain)

        use_i18n = builder.app.translator is not None
        extensions = use_i18n and ['jinja2.ext.i18n'] or []
        self.environment = SandboxedEnvironment(loader=self,
                                                extensions=extensions)
        self.environment.filters['tobool'] = _tobool
        self.environment.filters['toint'] = _toint
        self.environment.globals['debug'] = contextfunction(pformat)
        self.environment.globals['accesskey'] = contextfunction(accesskey)
        self.environment.globals['idgen'] = idgen
        if use_i18n:
            self.environment.install_gettext_translations(
                builder.app.translator)

    def render(self, template, context):
        return self.environment.get_template(template).render(context)

    def render_string(self, source, context):
        return self.environment.from_string(source).render(context)

    def newest_template_mtime(self):
        return max(mtimes_of_files(self.pathchain, '.html'))

    # Loader interface

    def get_source(self, environment, template):
        loaders = self.loaders
        # exclamation mark starts search from theme
        if template.startswith('!'):
            loaders = loaders[self.templatepathlen:]
            template = template[1:]
        for loader in loaders:
            try:
                return loader.get_source(environment, template)
            except TemplateNotFound:
                pass
        raise TemplateNotFound(template)
Exemple #49
0
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()