diff --git a/sphinx_automodapi/automodsumm.py b/sphinx_automodapi/automodsumm.py index 7ff388b..83794f4 100644 --- a/sphinx_automodapi/automodsumm.py +++ b/sphinx_automodapi/automodsumm.py @@ -46,6 +46,12 @@ in the generated documentation. The flags ``:inherited-members:`` or ``:no-inherited-members:`` allows overrriding this global setting. + * ``:sort:`` + If the module contains ``__all__``, sort the module's objects + alphabetically (if ``__all__`` is not present, the objects are found + using `dir`, which always gives a sorted list). + + This extension also adds three sphinx configuration options: * ``automodsumm_writereprocessed`` @@ -95,13 +101,22 @@ class members that are inherited from a base class. This value can be from sphinx.util import logging from sphinx.ext.autosummary import Autosummary -from sphinx.ext.inheritance_diagram import InheritanceDiagram, InheritanceGraph, try_import +from sphinx.ext.inheritance_diagram import ( + InheritanceDiagram, + InheritanceGraph, + try_import, +) from docutils.parsers.rst.directives import flag from .utils import find_mod_objs, cleanup_whitespace -__all__ = ['Automoddiagram', 'Automodsumm', 'automodsumm_to_autosummary_lines', - 'generate_automodsumm_docs', 'process_automodsumm_generation'] +__all__ = [ + "Automoddiagram", + "Automodsumm", + "automodsumm_to_autosummary_lines", + "generate_automodsumm_docs", + "process_automodsumm_generation", +] logger = logging.getLogger(__name__) @@ -113,7 +128,7 @@ def _str_list_converter(argument): if argument is None: return [] else: - return [s.strip() for s in argument.split(',')] + return [s.strip() for s in argument.split(",")] class Automodsumm(Autosummary): @@ -122,15 +137,15 @@ class Automodsumm(Autosummary): final_argument_whitespace = False has_content = False option_spec = dict(Autosummary.option_spec) - option_spec['functions-only'] = flag - option_spec['classes-only'] = flag - option_spec['variables-only'] = flag - option_spec['skip'] = _str_list_converter - option_spec['allowed-package-names'] = _str_list_converter - option_spec['inherited-members'] = flag - option_spec['no-inherited-members'] = flag - option_spec['noindex'] = flag - option_spec['sort'] = flag + option_spec["functions-only"] = flag + option_spec["classes-only"] = flag + option_spec["variables-only"] = flag + option_spec["skip"] = _str_list_converter + option_spec["allowed-package-names"] = _str_list_converter + option_spec["inherited-members"] = flag + option_spec["no-inherited-members"] = flag + option_spec["noindex"] = flag + option_spec["sort"] = flag def run(self): env = self.state.document.settings.env @@ -139,7 +154,7 @@ def run(self): nodelist = [] try: - localnames, fqns, objs = find_mod_objs(modname, sort='sort' in self.options) + localnames, fqns, objs = find_mod_objs(modname, sort="sort" in self.options) except ImportError: logger.warning("Couldn't import module " + modname) return [] @@ -147,25 +162,30 @@ def run(self): try: # set self.content to trick the autosummary internals. # Be sure to respect functions-only and classes-only. - funconly = 'functions-only' in self.options - clsonly = 'classes-only' in self.options - varonly = 'variables-only' in self.options + funconly = "functions-only" in self.options + clsonly = "classes-only" in self.options + varonly = "variables-only" in self.options if [clsonly, funconly, varonly].count(True) > 1: - logger.warning('more than one of "functions-only", "classes-only", ' - 'or "variables-only" defined. Ignoring.') + logger.warning( + 'more than one of "functions-only", "classes-only", ' + 'or "variables-only" defined. Ignoring.' + ) clsonly = funconly = varonly = False skipnames = [] - if 'skip' in self.options: - option_skipnames = set(self.options['skip']) + if "skip" in self.options: + option_skipnames = set(self.options["skip"]) for lnm in localnames: if lnm in option_skipnames: option_skipnames.remove(lnm) skipnames.append(lnm) if len(option_skipnames) > 0: - logger.warning('Tried to skip objects {objs} in module {mod}, ' - 'but they were not present. Ignoring.' - .format(objs=option_skipnames, mod=modname)) + logger.warning( + "Tried to skip objects {objs} in module {mod}, " + "but they were not present. Ignoring.".format( + objs=option_skipnames, mod=modname + ) + ) if funconly: cont = [] @@ -180,8 +200,9 @@ def run(self): elif varonly: cont = [] for nm, obj in zip(localnames, objs): - if nm not in skipnames and not (inspect.isclass(obj) or - inspect.isroutine(obj)): + if nm not in skipnames and not ( + inspect.isclass(obj) or inspect.isroutine(obj) + ): cont.append(nm) else: cont = [nm for nm in localnames if nm not in skipnames] @@ -191,8 +212,8 @@ def run(self): # for some reason, even though ``currentmodule`` is substituted in, # sphinx doesn't necessarily recognize this fact. So we just force # it internally, and that seems to fix things - env.temp_data['py:module'] = modname - env.ref_context['py:module'] = modname + env.temp_data["py:module"] = modname + env.ref_context["py:module"] = modname # can't use super because Sphinx/docutils has trouble return # super(Autosummary,self).run() @@ -204,22 +225,21 @@ def run(self): def get_items(self, names): try: - self.bridge.genopt['imported-members'] = True + self.bridge.genopt["imported-members"] = True except AttributeError: # Sphinx < 4.0 - self.genopt['imported-members'] = True + self.genopt["imported-members"] = True return Autosummary.get_items(self, names) # <-------------------automod-diagram stuff-----------------------------------> class Automoddiagram(InheritanceDiagram): - option_spec = dict(InheritanceDiagram.option_spec) - option_spec['allowed-package-names'] = _str_list_converter - option_spec['skip'] = _str_list_converter + option_spec["allowed-package-names"] = _str_list_converter + option_spec["skip"] = _str_list_converter def run(self): try: - ols = self.options.get('allowed-package-names', []) + ols = self.options.get("allowed-package-names", []) ols = True if len(ols) == 0 else ols # if none are given, assume only local nms, objs = find_mod_objs(self.arguments[0], onlylocals=ols)[1:] @@ -228,12 +248,11 @@ def run(self): return [] # Check if some classes should be skipped - skip = self.options.get('skip', []) + skip = self.options.get("skip", []) clsnms = [] for n, o in zip(nms, objs): - - if n.split('.')[-1] in skip: + if n.split(".")[-1] in skip: continue if inspect.isclass(o): @@ -242,7 +261,7 @@ def run(self): oldargs = self.arguments try: if len(clsnms) > 0: - self.arguments = [' '.join(clsnms)] + self.arguments = [" ".join(clsnms)] return InheritanceDiagram.run(self) finally: self.arguments = oldargs @@ -262,14 +281,25 @@ def run(self): old_generate_dot = InheritanceGraph.generate_dot -def patched_generate_dot(self, name, urls={}, env=None, - graph_attrs={}, node_attrs={}, edge_attrs={}): +def patched_generate_dot( + self, name, urls={}, env=None, graph_attrs={}, node_attrs={}, edge_attrs={} +): # Make a new mapping dictionary that uses class full names by importing each # class documented name - fullname_urls = {self.class_name(try_import(name), 0, None): url - for name, url in urls.items() if try_import(name) is not None} - return old_generate_dot(self, name, urls=fullname_urls, env=env, - graph_attrs=graph_attrs, node_attrs=node_attrs, edge_attrs=edge_attrs) + fullname_urls = { + self.class_name(try_import(name), 0, None): url + for name, url in urls.items() + if try_import(name) is not None + } + return old_generate_dot( + self, + name, + urls=fullname_urls, + env=env, + graph_attrs=graph_attrs, + node_attrs=node_attrs, + edge_attrs=edge_attrs, + ) InheritanceGraph.generate_dot = patched_generate_dot @@ -291,29 +321,34 @@ def process_automodsumm_generation(app): liness.append(lines) if app.config.automodsumm_writereprocessed: if lines: # empty list means no automodsumm entry is in the file - outfn = os.path.join(app.srcdir, sfn) + '.automodsumm' - with open(outfn, 'w', encoding='utf8') as f: + outfn = os.path.join(app.srcdir, sfn) + ".automodsumm" + with open(outfn, "w", encoding="utf8") as f: for l in lines: # noqa: E741 f.write(l) - f.write('\n') + f.write("\n") for sfn, lines in zip(filestosearch, liness): if len(lines) > 0: generate_automodsumm_docs( - lines, sfn, app=app, builder=app.builder, + lines, + sfn, + app=app, + builder=app.builder, base_path=app.srcdir, inherited_members=app.config.automodsumm_inherited_members, - included_members=app.config.automodsumm_included_members) + included_members=app.config.automodsumm_included_members, + ) # _automodsummrex = re.compile(r'^(\s*)\.\. automodsumm::\s*([A-Za-z0-9_.]+)\s*' # r'\n\1(\s*)(\S|$)', re.MULTILINE) -_lineendrex = r'(?:\n|$)' -_hdrex = r'^\n?(\s*)\.\. automodsumm::\s*(\S+)\s*' + _lineendrex -_oprex1 = r'(?:\1(\s+)\S.*' + _lineendrex + ')' -_oprex2 = r'(?:\1\4\S.*' + _lineendrex + ')' -_automodsummrex = re.compile(_hdrex + '(' + _oprex1 + '?' + _oprex2 + '*)', - re.MULTILINE) +_lineendrex = r"(?:\n|$)" +_hdrex = r"^\n?(\s*)\.\. automodsumm::\s*(\S+)\s*" + _lineendrex +_oprex1 = r"(?:\1(\s+)\S.*" + _lineendrex + ")" +_oprex2 = r"(?:\1\4\S.*" + _lineendrex + ")" +_automodsummrex = re.compile( + _hdrex + "(" + _oprex1 + "?" + _oprex2 + "*)", re.MULTILINE +) def automodsumm_to_autosummary_lines(fn, app): @@ -346,7 +381,7 @@ def automodsumm_to_autosummary_lines(fn, app): fullfn = os.path.join(app.builder.env.srcdir, fn) - with open(fullfn, encoding='utf8') as fr: + with open(fullfn, encoding="utf8") as fr: # Note: we use __name__ here instead of just writing the module name in # case this extension is bundled into another package from . import automodapi @@ -360,7 +395,9 @@ def automodsumm_to_autosummary_lines(fn, app): # Must do the automodapi on the source to get the automodsumm # that might be in there docname = os.path.splitext(fn)[0] - filestr = automodapi.automodapi_replace(fr.read(), app, True, docname, False) + filestr = automodapi.automodapi_replace( + fr.read(), app, True, docname, False + ) else: filestr = fr.read() @@ -377,50 +414,56 @@ def automodsumm_to_autosummary_lines(fn, app): newlines = [] # loop over all automodsumms in this document - for i, (i1, i2, modnm, ops, rem) in enumerate(zip(indent1s, indent2s, mods, - opssecs, remainders)): - allindent = i1 + (' ' if i2 is None else i2) + for i, (i1, i2, modnm, ops, rem) in enumerate( + zip(indent1s, indent2s, mods, opssecs, remainders) + ): + allindent = i1 + (" " if i2 is None else i2) - # filter out functions-only, classes-only, and ariables-only + # filter out functions-only, classes-only, variables-only, and sort # options if present. - oplines = ops.split('\n') + oplines = ops.split("\n") toskip = [] allowedpkgnms = [] - funcsonly = clssonly = varsonly = False + funcsonly = clssonly = varsonly = sort = False for i, ln in reversed(list(enumerate(oplines))): - if ':functions-only:' in ln: + if ":functions-only:" in ln: funcsonly = True del oplines[i] - if ':classes-only:' in ln: + if ":classes-only:" in ln: clssonly = True del oplines[i] - if ':variables-only:' in ln: + if ":variables-only:" in ln: varsonly = True del oplines[i] - if ':skip:' in ln: - toskip.extend(_str_list_converter(ln.replace(':skip:', ''))) + if ":skip:" in ln: + toskip.extend(_str_list_converter(ln.replace(":skip:", ""))) + del oplines[i] + if ":allowed-package-names:" in ln: + allowedpkgnms.extend( + _str_list_converter(ln.replace(":allowed-package-names:", "")) + ) del oplines[i] - if ':allowed-package-names:' in ln: - allowedpkgnms.extend(_str_list_converter(ln.replace(':allowed-package-names:', ''))) + if ":sort:" in ln: + sort = True del oplines[i] if [funcsonly, clssonly, varsonly].count(True) > 1: - msg = ('Defined more than one of functions-only, classes-only, ' - 'and variables-only. Skipping this directive.') - lnnum = sum([spl[j].count('\n') for j in range(i * 5 + 1)]) - logger.warning('[automodsumm] ' + msg, (fn, lnnum)) + msg = ( + "Defined more than one of functions-only, classes-only, " + "and variables-only. Skipping this directive." + ) + lnnum = sum([spl[j].count("\n") for j in range(i * 5 + 1)]) + logger.warning("[automodsumm] " + msg, (fn, lnnum)) continue # Use the currentmodule directive so we can just put the local names # in the autosummary table. Note that this doesn't always seem to # actually "take" in Sphinx's eyes, so in `Automodsumm.run`, we have to # force it internally, as well. - newlines.extend([i1 + '.. currentmodule:: ' + modnm, - '', - '.. autosummary::']) + newlines.extend([i1 + ".. currentmodule:: " + modnm, "", ".. autosummary::"]) newlines.extend(oplines) ols = True if len(allowedpkgnms) == 0 else allowedpkgnms - for nm, fqn, obj in zip(*find_mod_objs(modnm, onlylocals=ols)): + for nm, fqn, obj in zip(*find_mod_objs(modnm, onlylocals=ols, sort=sort)): if nm in toskip: continue if funcsonly and not inspect.isroutine(obj): @@ -432,16 +475,22 @@ def automodsumm_to_autosummary_lines(fn, app): newlines.append(allindent + nm) # add one newline at the end of the autosummary block - newlines.append('') + newlines.append("") return newlines -def generate_automodsumm_docs(lines, srcfn, app=None, suffix='.rst', - base_path=None, builder=None, - template_dir=None, - inherited_members=False, - included_members=('__init__', '__call__')): +def generate_automodsumm_docs( + lines, + srcfn, + app=None, + suffix=".rst", + base_path=None, + builder=None, + template_dir=None, + inherited_members=False, + included_members=("__init__", "__call__"), +): """ This function is adapted from `sphinx.ext.autosummary.generate.generate_autosummmary_docs` to @@ -457,13 +506,17 @@ def generate_automodsumm_docs(lines, srcfn, app=None, suffix='.rst', from jinja2 import FileSystemLoader, TemplateNotFound from jinja2.sandbox import SandboxedEnvironment - from .utils import find_autosummary_in_lines_for_automodsumm as find_autosummary_in_lines + from .utils import ( + find_autosummary_in_lines_for_automodsumm as find_autosummary_in_lines, + ) # 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')] + 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() @@ -478,13 +531,13 @@ def generate_automodsumm_docs(lines, srcfn, app=None, suffix='.rst', # 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' + msg = "[automodsumm] {1}: found {0} automodsumm entries to generate" logger.info(msg.format(len(items), srcfn)) -# gennms = [item[0] for item in items] -# if len(gennms) > 20: -# gennms = gennms[:10] + ['...'] + gennms[-10:] -# logger.info('[automodsumm] generating autosummary for: ' + ', '.join(gennms)) + # gennms = [item[0] for item in items] + # if len(gennms) > 20: + # gennms = gennms[:10] + ['...'] + gennms[-10:] + # logger.info('[automodsumm] generating autosummary for: ' + ', '.join(gennms)) # remove possible duplicates items = list(set(items)) @@ -494,7 +547,6 @@ def generate_automodsumm_docs(lines, srcfn, app=None, suffix='.rst', # write for name, path, template_name, inherited_mem, noindex in sorted(items): - if path is None: # The corresponding autosummary:: directive did not have # a :toctree: option @@ -506,7 +558,7 @@ def generate_automodsumm_docs(lines, srcfn, app=None, suffix='.rst', try: import_by_name_values = import_by_name(name) except ImportError as e: - logger.warning('[automodsumm] failed to import %r: %s' % (name, e)) + logger.warning("[automodsumm] failed to import %r: %s" % (name, e)) continue # if block to accommodate Sphinx's v1.2.2 and v1.2.3 respectively @@ -523,20 +575,19 @@ def generate_automodsumm_docs(lines, srcfn, app=None, suffix='.rst', new_files.append(fn) - f = open(fn, 'w', encoding='utf8') + f = open(fn, "w", encoding="utf8") try: - doc = get_documenter(app, obj, parent) if template_name is not None: template = template_env.get_template(template_name) else: - tmplstr = 'autosummary_core/%s.rst' + tmplstr = "autosummary_core/%s.rst" try: template = template_env.get_template(tmplstr % doc.objtype) except TemplateNotFound: - template = template_env.get_template(tmplstr % 'base') + template = template_env.get_template(tmplstr % "base") def get_members_mod(obj, typ, include_public=[]): """ @@ -550,12 +601,12 @@ def get_members_mod(obj, typ, include_public=[]): 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('_')] + 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): + def get_members_class(obj, typ, include_public=[], include_base=False): """ typ = None -> all include_base -> include attrs that are from a base class @@ -567,7 +618,7 @@ def get_members_class(obj, typ, include_public=[], if include_base: names = dir(obj) else: - names = getattr(obj, '__dict__').keys() + names = getattr(obj, "__dict__").keys() for name in names: try: @@ -576,25 +627,25 @@ def get_members_class(obj, typ, include_public=[], continue if typ is None or documenter.objtype == typ: items.append(name) - elif typ == 'attribute' and documenter.objtype == 'property': + elif typ == "attribute" and documenter.objtype == "property": # In Sphinx 2.0 and above, properties have a separate # objtype, but we treat them the same here. items.append(name) - public = [x for x in items - if x in include_public or not x.startswith('_')] + 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': + 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": if inherited_mem is not None: # option set in this specifc directive include_base = inherited_mem @@ -602,34 +653,33 @@ def get_members_class(obj, typ, include_public=[], # use default value include_base = inherited_members - ns['members'] = get_members_class(obj, None, - include_base=include_base) - ns['methods'], ns['all_methods'] = \ - get_members_class(obj, 'method', included_members, - include_base=include_base) - ns['attributes'], ns['all_attributes'] = \ - get_members_class(obj, 'attribute', - include_base=include_base) - ns['methods'].sort() - ns['attributes'].sort() - - parts = name.split('.') - if doc.objtype in ('method', 'attribute'): - mod_name = '.'.join(parts[:-2]) + ns["members"] = get_members_class(obj, None, include_base=include_base) + ns["methods"], ns["all_methods"] = get_members_class( + obj, "method", included_members, include_base=include_base + ) + ns["attributes"], ns["all_attributes"] = get_members_class( + obj, "attribute", include_base=include_base + ) + 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 + obj_name = ".".join(parts[-2:]) + ns["class"] = cls_name else: - mod_name, obj_name = '.'.join(parts[:-1]), parts[-1] + mod_name, obj_name = ".".join(parts[:-1]), parts[-1] - ns['noindex'] = noindex - ns['fullname'] = name - ns['module'] = mod_name - ns['objname'] = obj_name - ns['name'] = parts[-1] + ns["noindex"] = noindex + ns["fullname"] = name + ns["module"] = mod_name + ns["objname"] = obj_name + ns["name"] = parts[-1] - ns['objtype'] = doc.objtype - ns['underline'] = len(obj_name) * '=' + ns["objtype"] = doc.objtype + ns["underline"] = len(obj_name) * "=" # We now check whether a file for reference footnotes exists for # the module being documented. We first check if the @@ -640,26 +690,31 @@ def get_members_class(obj, typ, include_public=[], # 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.split('.', 1)[1].replace('.', os.sep) + if "." in mod_name: + mod_name_dir = mod_name.split(".", 1)[1].replace(".", os.sep) 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(os.sep, 1)[0]))): + 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(os.sep, 1)[0]) + ): mod_name_dir = mod_name_dir.rsplit(os.sep, 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')): + 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(str(base_path), '').count(os.sep) - ref_file_rel_segments = ['..'] * ndirsback + ndirsback = path.replace(str(base_path), "").count(os.sep) + 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).replace(os.sep, '/') + ref_file_rel_segments.append("references.txt") + ns["referencefile"] = os.path.join(*ref_file_rel_segments).replace( + os.sep, "/" + ) rendered = template.render(**ns) f.write(cleanup_whitespace(rendered)) @@ -668,24 +723,24 @@ def get_members_class(obj, typ, include_public=[], def setup(app): - # need autodoc fixes # Note: we use __name__ here instead of just writing the module name in # case this extension is bundled into another package from . import autodoc_enhancements + app.setup_extension(autodoc_enhancements.__name__) # need inheritance-diagram for automod-diagram - app.setup_extension('sphinx.ext.inheritance_diagram') + app.setup_extension("sphinx.ext.inheritance_diagram") - app.add_directive('automod-diagram', Automoddiagram) - app.add_directive('automodsumm', Automodsumm) - app.connect('builder-inited', process_automodsumm_generation) + app.add_directive("automod-diagram", Automoddiagram) + app.add_directive("automodsumm", Automodsumm) + app.connect("builder-inited", process_automodsumm_generation) - app.add_config_value('automodsumm_writereprocessed', False, True) - app.add_config_value('automodsumm_inherited_members', False, 'env') + app.add_config_value("automodsumm_writereprocessed", False, True) + app.add_config_value("automodsumm_inherited_members", False, "env") app.add_config_value( - 'automodsumm_included_members', ['__init__', '__call__'], 'env') + "automodsumm_included_members", ["__init__", "__call__"], "env" + ) - return {'parallel_read_safe': True, - 'parallel_write_safe': True} + return {"parallel_read_safe": True, "parallel_write_safe": True} diff --git a/sphinx_automodapi/tests/test_automodsumm.py b/sphinx_automodapi/tests/test_automodsumm.py index e755139..3922faa 100644 --- a/sphinx_automodapi/tests/test_automodsumm.py +++ b/sphinx_automodapi/tests/test_automodsumm.py @@ -205,6 +205,14 @@ def test_ams_cython(tmpdir, cython_testpackage): # noqa # ============================================================================= +CLASS_RST = """ +:orphan: + +.. currentmodule:: {mod} + +.. autoclass:: {cls} +""".strip() + sorted_str = """ Before @@ -229,7 +237,11 @@ def test_sort(tmpdir): with open(tmpdir.join("index.rst").strpath, "w") as f: f.write(sorted_str) - write_api_files_to_tmpdir(tmpdir) + apidir = tmpdir.mkdir('api') + mod = 'sphinx_automodapi.tests.example_module.classes' + for cls in "Spam", "Egg": + with open(apidir.join(f'{mod}.{cls}.rst').strpath, 'w') as f: + f.write(CLASS_RST.format(mod=mod, cls=cls)) run_sphinx_in_tmpdir(tmpdir)