def test_autosummary_generate_content_for_module_imported_members(app): import autosummary_dummy_module template = Mock() generate_autosummary_content('autosummary_dummy_module', autosummary_dummy_module, None, template, None, True, app, False, {}) assert template.render.call_args[0][0] == 'module' context = template.render.call_args[0][1] assert context['members'] == [ 'CONSTANT1', 'CONSTANT2', 'Exc', 'Foo', 'Union', '_Baz', '_Exc', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_quux', 'bar', 'path', 'qux' ] assert context['functions'] == ['bar'] assert context['all_functions'] == ['_quux', 'bar'] assert context['classes'] == ['Foo'] assert context['all_classes'] == ['Foo', '_Baz'] assert context['exceptions'] == ['Exc'] assert context['all_exceptions'] == ['Exc', '_Exc'] assert context['attributes'] == ['CONSTANT1', 'qux'] assert context['all_attributes'] == ['CONSTANT1', 'qux'] assert context['fullname'] == 'autosummary_dummy_module' assert context['module'] == 'autosummary_dummy_module' assert context['objname'] == '' assert context['name'] == '' assert context['objtype'] == 'module'
def test_autosummary_generate_content_for_module___all__(app): import autosummary_dummy_module template = Mock() app.config.autosummary_ignore_module_all = False generate_autosummary_content('autosummary_dummy_module', autosummary_dummy_module, None, template, None, False, app, False, {}) assert template.render.call_args[0][0] == 'module' context = template.render.call_args[0][1] assert context['members'] == [ 'CONSTANT1', 'Exc', 'Foo', '_Baz', 'bar', 'qux', 'path' ] assert context['functions'] == ['bar'] assert context['all_functions'] == ['bar'] assert context['classes'] == ['Foo'] assert context['all_classes'] == ['Foo', '_Baz'] assert context['exceptions'] == ['Exc'] assert context['all_exceptions'] == ['Exc'] assert context['attributes'] == ['CONSTANT1', 'qux'] assert context['all_attributes'] == ['CONSTANT1', 'qux'] assert context['fullname'] == 'autosummary_dummy_module' assert context['module'] == 'autosummary_dummy_module' assert context['objname'] == '' assert context['name'] == '' assert context['objtype'] == 'module'
def create_documenter_from_template(autosummary, app, obj, parent, full_name): real_name = ".".join(full_name.split("::")) options = autosummary.options.copy() template_name = options.pop("template", None) if template_name is None: return original_create_documenter(autosummary, app, obj, parent, full_name) options.pop("toctree", None) options["imported_members"] = options.get("imported_members", False) options["recursive"] = options.get("recursive", False) context = {} context.update(app.config.autosummary_context) rendered = generate.generate_autosummary_content( real_name, obj, parent, template=generate.AutosummaryRenderer(app), template_name=template_name, app=app, context=context, **options, ) documenter_name, real_name = extract_documenter(rendered) doccls = app.registry.documenters.get(documenter_name) documenter = doccls(autosummary.bridge, real_name) return documenter
def test_autosummary_generate_content_for_module_skipped(app): import autosummary_dummy_module template = Mock() def skip_member(app, what, name, obj, skip, options): if name in ('Foo', 'bar', 'Exc'): return True app.connect('autodoc-skip-member', skip_member) generate_autosummary_content('autosummary_dummy_module', autosummary_dummy_module, None, template, None, False, app, False, {}) context = template.render.call_args[0][1] assert context['members'] == ['_Baz', '_Exc', '__builtins__', '__cached__', '__doc__', '__file__', '__name__', '__package__', '_quux', 'qux'] assert context['functions'] == [] assert context['classes'] == [] assert context['exceptions'] == []
def generate_docs( self, source_filenames: List[str], output_dir: str = None, suffix: str = ".rst", base_path: str = None, imported_members: bool = False, overwrite: bool = True, encoding: str = "utf-8", ) -> None: """ Generate and write stub files for objects defined in the :rst:dir:`automodapi` and :rst:dir:`automodsumm` directives. Parameters ---------- source_filenames : List[str] A list of all filenames for with the :rst:dir:`automodapi` and :rst:dir:`automodsumm` directives will be searched for. output_dir : `str` Directory for which the stub files will be written to. suffix : `str` (Default ``".rst"``) Suffix given to the written stub files. base_path : `str` The common base path for the filenames listed in ``source_filenames``. This is typically the source directory of the Sphinx application. imported_members : `bool` (Default `False`) Set `True` to include imported members in the stub file documentation for *module* object types. overwrite : `bool` (Default `True`) Will cause existing stub files to be overwritten. encoding : `str` (Default: ``"utf-8"``) Encoding for the written stub files. .. note:: Adapted from :func:`sphinx.ext.autosummary.generate.generate_autosummary_docs`. """ app = self.app _info = self.logger.info _warn = self.logger.warning showed_sources = list(sorted(source_filenames)) _info( __(f"[automodsumm] generating stub files for {len(showed_sources)} sources" )) if output_dir: _info(__(f"[automodsumm] writing to {output_dir}")) if base_path is not None: source_filenames = [ os.path.join(base_path, filename) for filename in source_filenames ] template = AutomodsummRenderer(app) # read items = self.find_in_files(source_filenames) # keep track of new files new_files = [] if app: filename_map = app.config.autosummary_filename_map else: filename_map = {} # write for entry in sorted(set(items), key=str): if entry.path is None: # The corresponding automodsumm:: directive did not have # a :toctree: option continue path = output_dir or os.path.abspath(entry.path) ensuredir(path) try: name, obj, parent, modname = import_by_name(entry.name) qualname = name.replace(modname + ".", "") except ImportError as e: try: # try to import as an instance attribute name, obj, parent, modname = import_ivar_by_name( entry.name) qualname = name.replace(modname + ".", "") except ImportError: _warn( __(f"[automodsumm] failed to import {entry.name}: {e}") ) continue context = {} if app: context.update(app.config.autosummary_context) content = generate_autosummary_content( name, obj, parent, template, entry.template, imported_members, app, entry.recursive, context, modname, qualname, ) filename = os.path.join(path, filename_map.get(name, name) + suffix) if os.path.isfile(filename): with open(filename, encoding=encoding) as f: old_content = f.read() if content == old_content: continue elif overwrite: # content has changed with open(filename, "w", encoding=encoding) as f: f.write(content) new_files.append(filename) else: with open(filename, "w", encoding=encoding) as f: f.write(content) new_files.append(filename) # descend recursively to new files if new_files: self.generate_docs( new_files, output_dir=output_dir, suffix=suffix, base_path=base_path, imported_members=imported_members, overwrite=overwrite, )