def generate_func_autodoc(app, func, add_title=True): ad = AutoDirective( name="autofunc", arguments=[FULL_NAMES[func]], options={"noindex": True}, content=StringList([], items=[]), lineno=0, content_offset=1, block_text="", state=None, state_machine=None, ) ad.env = BuildEnvironment(app) ad.genopt = Options(noindex=True) ad.filename_set = set() ad.result = ViewList() documenter = FunctionDocumenter(ad, ad.arguments[0]) documenter.generate(all_members=True) title = 'Parameter Grids' with open(OUTPUT_FILES[func], "a") as fid: if add_title: fid.write(title + '\n') fid.write(''.join(['='] * len(title)) + '\n') for line in ad.result: fid.write(line + "\n")
def can_document_member(cls, member, membername, isattr, parent): if not FunctionDocumenter.can_document_member(member, membername, isattr, parent): return False if member.__doc__ is not None and yaml_sig_re.match(member.__doc__): return True return False
def can_document_member(cls, member, membername, isattr, parent): can = FunctionDocumenter.can_document_member(member, membername, isattr, parent) # bound methods plus = isinstance(parent, ModuleDocumenter) and inspect.ismethod(member) return can or plus
def import_object(self): ret = _FunctionDocumenter.import_object(self) if not ret: return ret obj = self.parent.__dict__.get(self.object_name) if iscoroutinefunction(obj): self.directivetype = 'coroutine' self.member_order = _FunctionDocumenter.member_order + 2 return ret
def generate_func_autodoc(app, func): ad = AutoDirective(name='autofunc', arguments=[FULL_NAMES[func]], options={'noindex': True}, content=StringList([], items=[]), lineno=0, content_offset=1, block_text='', state=None, state_machine=None) ad.env = BuildEnvironment(app) ad.genopt = Options(noindex=True) ad.filename_set = set() ad.result = ViewList() documenter = FunctionDocumenter(ad, ad.arguments[0]) documenter.generate(all_members=True) with open(OUTPUT_FILES[func], 'a') as fid: for line in ad.result: fid.write(line + '\n')
def test_generate(): def assert_warns(warn_str, objtype, name, **kw): inst = AutoDirective._registry[objtype](directive, name) inst.generate(**kw) assert len(directive.result) == 0, directive.result assert len(_warnings) == 1, _warnings assert warn_str in _warnings[0], _warnings del _warnings[:] def assert_works(objtype, name, **kw): inst = AutoDirective._registry[objtype](directive, name) inst.generate(**kw) assert directive.result # print '\n'.join(directive.result) assert len(_warnings) == 0, _warnings del directive.result[:] def assert_processes(items, objtype, name, **kw): del processed_docstrings[:] del processed_signatures[:] assert_works(objtype, name, **kw) assert set(processed_docstrings) | set(processed_signatures) == set( items) def assert_result_contains(item, objtype, name, **kw): inst = AutoDirective._registry[objtype](directive, name) inst.generate(**kw) # print '\n'.join(directive.result) assert len(_warnings) == 0, _warnings assert item in directive.result del directive.result[:] def assert_order(items, objtype, name, member_order, **kw): inst = AutoDirective._registry[objtype](directive, name) inst.options.member_order = member_order inst.generate(**kw) assert len(_warnings) == 0, _warnings items = list(reversed(items)) lineiter = iter(directive.result) # for line in directive.result: # if line.strip(): # print repr(line) while items: item = items.pop() for line in lineiter: if line == item: break else: # ran out of items! assert False, ('item %r not found in result or not in the ' ' correct order' % item) del directive.result[:] options.members = [] # no module found? assert_warns("import for autodocumenting 'foobar'", 'function', 'foobar', more_content=None) # importing assert_warns("failed to import module 'test_foobar'", 'module', 'test_foobar', more_content=None) # attributes missing assert_warns("failed to import function 'foobar' from module 'util'", 'function', 'util.foobar', more_content=None) # method missing assert_warns( "failed to import method 'Class.foobar' from module 'target';", 'method', 'target.Class.foobar', more_content=None) # test auto and given content mixing directive.env.ref_context['py:module'] = 'target' assert_result_contains(' Function.', 'method', 'Class.meth') add_content = ViewList() add_content.append('Content.', '', 0) assert_result_contains(' Function.', 'method', 'Class.meth', more_content=add_content) assert_result_contains(' Content.', 'method', 'Class.meth', more_content=add_content) # test check_module inst = FunctionDocumenter(directive, 'add_documenter') inst.generate(check_module=True) assert len(directive.result) == 0 # assert that exceptions can be documented assert_works('exception', 'target.CustomEx', all_members=True) assert_works('exception', 'target.CustomEx') # test diverse inclusion settings for members should = [('class', 'target.Class')] assert_processes(should, 'class', 'Class') should.extend([('method', 'target.Class.meth')]) options.members = ['meth'] options.exclude_members = set(['excludemeth']) assert_processes(should, 'class', 'Class') should.extend([ ('attribute', 'target.Class.prop'), ('attribute', 'target.Class.descr'), ('attribute', 'target.Class.attr'), ('attribute', 'target.Class.docattr'), ('attribute', 'target.Class.udocattr'), ('attribute', 'target.Class.mdocattr'), ('attribute', 'target.Class.inst_attr_comment'), ('attribute', 'target.Class.inst_attr_inline'), ('attribute', 'target.Class.inst_attr_string'), ('method', 'target.Class.moore'), ]) options.members = ALL assert_processes(should, 'class', 'Class') options.undoc_members = True should.extend((('attribute', 'target.Class.skipattr'), ('method', 'target.Class.undocmeth'), ('method', 'target.Class.roger'))) assert_processes(should, 'class', 'Class') options.inherited_members = True should.append(('method', 'target.Class.inheritedmeth')) assert_processes(should, 'class', 'Class') # test special members options.special_members = ['__special1__'] should.append(('method', 'target.Class.__special1__')) assert_processes(should, 'class', 'Class') options.special_members = ALL should.append(('method', 'target.Class.__special2__')) assert_processes(should, 'class', 'Class') options.special_members = False options.members = [] # test module flags assert_result_contains('.. py:module:: target', 'module', 'target') options.synopsis = 'Synopsis' assert_result_contains(' :synopsis: Synopsis', 'module', 'target') options.deprecated = True assert_result_contains(' :deprecated:', 'module', 'target') options.platform = 'Platform' assert_result_contains(' :platform: Platform', 'module', 'target') # test if __all__ is respected for modules options.members = ALL assert_result_contains('.. py:class:: Class(arg)', 'module', 'target') try: assert_result_contains('.. py:exception:: CustomEx', 'module', 'target') except AssertionError: pass else: assert False, 'documented CustomEx which is not in __all__' # test ignore-module-all options.ignore_module_all = True assert_result_contains('.. py:class:: Class(arg)', 'module', 'target') assert_result_contains('.. py:exception:: CustomEx', 'module', 'target') # test noindex flag options.members = [] options.noindex = True assert_result_contains(' :noindex:', 'module', 'target') assert_result_contains(' :noindex:', 'class', 'Base') # okay, now let's get serious about mixing Python and C signature stuff assert_result_contains('.. py:class:: CustomDict', 'class', 'CustomDict', all_members=True) # test inner class handling assert_processes([('class', 'target.Outer'), ('class', 'target.Outer.Inner'), ('method', 'target.Outer.Inner.meth')], 'class', 'Outer', all_members=True) # test descriptor docstrings assert_result_contains(' Descriptor instance docstring.', 'attribute', 'target.Class.descr') # test generation for C modules (which have no source file) directive.env.ref_context['py:module'] = 'time' assert_processes([('function', 'time.asctime')], 'function', 'asctime') assert_processes([('function', 'time.asctime')], 'function', 'asctime') # test autodoc_member_order == 'source' directive.env.ref_context['py:module'] = 'target' options.private_members = True if PY3: roger_line = ' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)' else: roger_line = ' .. py:classmethod:: Class.roger(a, e=5, f=6)' assert_order([ '.. py:class:: Class(arg)', ' .. py:attribute:: Class.descr', ' .. py:method:: Class.meth()', ' .. py:method:: Class.undocmeth()', ' .. py:attribute:: Class.attr', ' .. py:attribute:: Class.prop', ' .. py:attribute:: Class.docattr', ' .. py:attribute:: Class.udocattr', ' .. py:attribute:: Class.mdocattr', roger_line, ' .. py:classmethod:: Class.moore(a, e, f) -> happiness', ' .. py:attribute:: Class.inst_attr_comment', ' .. py:attribute:: Class.inst_attr_string', ' .. py:attribute:: Class._private_inst_attr', ' .. py:method:: Class.inheritedmeth()', ], 'class', 'Class', member_order='bysource', all_members=True) del directive.env.ref_context['py:module'] # test attribute initialized to class instance from other module directive.env.temp_data['autodoc:class'] = 'target.Class' assert_result_contains(u' should be documented as well - s\xfc\xdf', 'attribute', 'mdocattr') del directive.env.temp_data['autodoc:class'] # test autodoc_docstring_signature assert_result_contains( '.. py:method:: DocstringSig.meth(FOO, BAR=1) -> BAZ', 'method', 'target.DocstringSig.meth') assert_result_contains(' rest of docstring', 'method', 'target.DocstringSig.meth') assert_result_contains('.. py:method:: DocstringSig.meth2()', 'method', 'target.DocstringSig.meth2') assert_result_contains(' indented line', 'method', 'target.DocstringSig.meth2') assert_result_contains( '.. py:classmethod:: Class.moore(a, e, f) -> happiness', 'method', 'target.Class.moore') # test new attribute documenter behavior directive.env.ref_context['py:module'] = 'target' options.undoc_members = True assert_processes([ ('class', 'target.AttCls'), ('attribute', 'target.AttCls.a1'), ('attribute', 'target.AttCls.a2'), ], 'class', 'AttCls') assert_result_contains(' :annotation: = hello world', 'attribute', 'AttCls.a1') assert_result_contains(' :annotation: = None', 'attribute', 'AttCls.a2') # test explicit members with instance attributes del directive.env.temp_data['autodoc:class'] del directive.env.temp_data['autodoc:module'] directive.env.ref_context['py:module'] = 'target' options.inherited_members = False options.undoc_members = False options.members = ALL assert_processes([ ('class', 'target.InstAttCls'), ('attribute', 'target.InstAttCls.ca1'), ('attribute', 'target.InstAttCls.ca2'), ('attribute', 'target.InstAttCls.ca3'), ('attribute', 'target.InstAttCls.ia1'), ('attribute', 'target.InstAttCls.ia2'), ], 'class', 'InstAttCls') del directive.env.temp_data['autodoc:class'] del directive.env.temp_data['autodoc:module'] options.members = ['ca1', 'ia1'] assert_processes([ ('class', 'target.InstAttCls'), ('attribute', 'target.InstAttCls.ca1'), ('attribute', 'target.InstAttCls.ia1'), ], 'class', 'InstAttCls') del directive.env.temp_data['autodoc:class'] del directive.env.temp_data['autodoc:module'] del directive.env.ref_context['py:module'] # test members with enum attributes directive.env.ref_context['py:module'] = 'target' options.inherited_members = False options.undoc_members = False options.members = ALL assert_processes([ ('class', 'target.EnumCls'), ('attribute', 'target.EnumCls.val1'), ('attribute', 'target.EnumCls.val2'), ('attribute', 'target.EnumCls.val3'), ], 'class', 'EnumCls') assert_result_contains(' :annotation: = 12', 'attribute', 'EnumCls.val1') assert_result_contains(' :annotation: = 23', 'attribute', 'EnumCls.val2') assert_result_contains(' :annotation: = 34', 'attribute', 'EnumCls.val3') del directive.env.temp_data['autodoc:class'] del directive.env.temp_data['autodoc:module'] # test descriptor class documentation options.members = ['CustomDataDescriptor', 'CustomDataDescriptor2'] assert_result_contains('.. py:class:: CustomDataDescriptor(doc)', 'module', 'target') assert_result_contains(' .. py:method:: CustomDataDescriptor.meth()', 'module', 'target') assert_result_contains('.. py:class:: CustomDataDescriptor2(doc)', 'module', 'target') # test mocked module imports options.members = ['TestAutodoc'] options.undoc_members = False assert_result_contains('.. py:class:: TestAutodoc', 'module', 'autodoc_missing_imports') assert_result_contains(' .. py:method:: TestAutodoc.decoratedMethod()', 'module', 'autodoc_missing_imports') options.members = ['decoratedFunction'] assert_result_contains('.. py:function:: decoratedFunction()', 'module', 'autodoc_missing_imports')
def test_generate(): def assert_warns(warn_str, objtype, name, **kw): inst = AutoDirective._registry[objtype](directive, name) inst.generate(**kw) assert len(directive.result) == 0, directive.result assert len(_warnings) == 1, _warnings assert warn_str in _warnings[0], _warnings del _warnings[:] def assert_works(objtype, name, **kw): inst = AutoDirective._registry[objtype](directive, name) inst.generate(**kw) assert directive.result # print '\n'.join(directive.result) assert len(_warnings) == 0, _warnings del directive.result[:] def assert_processes(items, objtype, name, **kw): del processed_docstrings[:] del processed_signatures[:] assert_works(objtype, name, **kw) assert set(processed_docstrings) | set(processed_signatures) == set(items) def assert_result_contains(item, objtype, name, **kw): inst = AutoDirective._registry[objtype](directive, name) inst.generate(**kw) # print '\n'.join(directive.result) assert len(_warnings) == 0, _warnings assert item in directive.result del directive.result[:] def assert_order(items, objtype, name, member_order, **kw): inst = AutoDirective._registry[objtype](directive, name) inst.options.member_order = member_order inst.generate(**kw) assert len(_warnings) == 0, _warnings items = list(reversed(items)) lineiter = iter(directive.result) # for line in directive.result: # if line.strip(): # print repr(line) while items: item = items.pop() for line in lineiter: if line == item: break else: # ran out of items! assert False, "item %r not found in result or not in the " " correct order" % item del directive.result[:] options.members = [] # no module found? assert_warns("import for autodocumenting 'foobar'", "function", "foobar", more_content=None) # importing assert_warns("import/find module 'test_foobar'", "module", "test_foobar", more_content=None) # attributes missing assert_warns("import/find function 'util.foobar'", "function", "util.foobar", more_content=None) # test auto and given content mixing directive.env.temp_data["py:module"] = "test_autodoc" assert_result_contains(" Function.", "method", "Class.meth") add_content = ViewList() add_content.append("Content.", "", 0) assert_result_contains(" Function.", "method", "Class.meth", more_content=add_content) assert_result_contains(" Content.", "method", "Class.meth", more_content=add_content) # test check_module inst = FunctionDocumenter(directive, "raises") inst.generate(check_module=True) assert len(directive.result) == 0 # assert that exceptions can be documented assert_works("exception", "test_autodoc.CustomEx", all_members=True) assert_works("exception", "test_autodoc.CustomEx") # test diverse inclusion settings for members should = [("class", "test_autodoc.Class")] assert_processes(should, "class", "Class") should.extend([("method", "test_autodoc.Class.meth")]) options.members = ["meth"] options.exclude_members = set(["excludemeth"]) assert_processes(should, "class", "Class") should.extend( [ ("attribute", "test_autodoc.Class.prop"), ("attribute", "test_autodoc.Class.descr"), ("attribute", "test_autodoc.Class.attr"), ("attribute", "test_autodoc.Class.docattr"), ("attribute", "test_autodoc.Class.udocattr"), ("attribute", "test_autodoc.Class.mdocattr"), ("attribute", "test_autodoc.Class.inst_attr_comment"), ("attribute", "test_autodoc.Class.inst_attr_inline"), ("attribute", "test_autodoc.Class.inst_attr_string"), ("method", "test_autodoc.Class.moore"), ] ) options.members = ALL assert_processes(should, "class", "Class") options.undoc_members = True should.extend( ( ("attribute", "test_autodoc.Class.skipattr"), ("method", "test_autodoc.Class.undocmeth"), ("method", "test_autodoc.Class.roger"), ) ) assert_processes(should, "class", "Class") options.inherited_members = True should.append(("method", "test_autodoc.Class.inheritedmeth")) assert_processes(should, "class", "Class") options.members = [] # test module flags assert_result_contains(".. py:module:: test_autodoc", "module", "test_autodoc") options.synopsis = "Synopsis" assert_result_contains(" :synopsis: Synopsis", "module", "test_autodoc") options.deprecated = True assert_result_contains(" :deprecated:", "module", "test_autodoc") options.platform = "Platform" assert_result_contains(" :platform: Platform", "module", "test_autodoc") # test if __all__ is respected for modules options.members = ALL assert_result_contains(".. py:class:: Class(arg)", "module", "test_autodoc") try: assert_result_contains(".. py:exception:: CustomEx", "module", "test_autodoc") except AssertionError: pass else: assert False, "documented CustomEx which is not in __all__" # test noindex flag options.members = [] options.noindex = True assert_result_contains(" :noindex:", "module", "test_autodoc") assert_result_contains(" :noindex:", "class", "Base") # okay, now let's get serious about mixing Python and C signature stuff assert_result_contains(".. py:class:: CustomDict", "class", "CustomDict", all_members=True) # test inner class handling assert_processes( [ ("class", "test_autodoc.Outer"), ("class", "test_autodoc.Outer.Inner"), ("method", "test_autodoc.Outer.Inner.meth"), ], "class", "Outer", all_members=True, ) # test descriptor docstrings assert_result_contains(" Descriptor instance docstring.", "attribute", "test_autodoc.Class.descr") # test generation for C modules (which have no source file) directive.env.temp_data["py:module"] = "time" assert_processes([("function", "time.asctime")], "function", "asctime") assert_processes([("function", "time.asctime")], "function", "asctime") # test autodoc_member_order == 'source' directive.env.temp_data["py:module"] = "test_autodoc" assert_order( [ ".. py:class:: Class(arg)", " .. py:attribute:: Class.descr", " .. py:method:: Class.meth()", " .. py:method:: Class.undocmeth()", " .. py:attribute:: Class.attr", " .. py:attribute:: Class.prop", " .. py:attribute:: Class.docattr", " .. py:attribute:: Class.udocattr", " .. py:attribute:: Class.mdocattr", " .. py:classmethod:: Class.roger(a, e=5, f=6)", " .. py:classmethod:: Class.moore(a, e, f) -> happiness", " .. py:attribute:: Class.inst_attr_comment", " .. py:attribute:: Class.inst_attr_string", " .. py:method:: Class.inheritedmeth()", ], "class", "Class", member_order="bysource", all_members=True, ) del directive.env.temp_data["py:module"] # test attribute initialized to class instance from other module directive.env.temp_data["autodoc:class"] = "test_autodoc.Class" assert_result_contains(u" should be documented as well - s\xfc\xdf", "attribute", "mdocattr") del directive.env.temp_data["autodoc:class"] # test autodoc_docstring_signature assert_result_contains( ".. py:method:: DocstringSig.meth(FOO, BAR=1) -> BAZ", "method", "test_autodoc.DocstringSig.meth" ) assert_result_contains(" rest of docstring", "method", "test_autodoc.DocstringSig.meth") assert_result_contains( ".. py:classmethod:: Class.moore(a, e, f) -> happiness", "method", "test_autodoc.Class.moore" ) # test new attribute documenter behavior directive.env.temp_data["py:module"] = "test_autodoc" options.undoc_members = True assert_processes( [ ("class", "test_autodoc.AttCls"), ("attribute", "test_autodoc.AttCls.a1"), ("attribute", "test_autodoc.AttCls.a2"), ], "class", "AttCls", ) assert_result_contains(" :annotation: = hello world", "attribute", "AttCls.a1") assert_result_contains(" :annotation: = None", "attribute", "AttCls.a2")
def test_generate(): def assert_warns(warn_str, objtype, name, **kw): inst = AutoDirective._registry[objtype](directive, name) inst.generate(**kw) assert len(directive.result) == 0, directive.result assert len(_warnings) == 1, _warnings assert warn_str in _warnings[0], _warnings del _warnings[:] def assert_works(objtype, name, **kw): inst = AutoDirective._registry[objtype](directive, name) inst.generate(**kw) assert directive.result # print '\n'.join(directive.result) assert len(_warnings) == 0, _warnings del directive.result[:] def assert_processes(items, objtype, name, **kw): del processed_docstrings[:] del processed_signatures[:] assert_works(objtype, name, **kw) assert set(processed_docstrings) | set(processed_signatures) == set(items) def assert_result_contains(item, objtype, name, **kw): inst = AutoDirective._registry[objtype](directive, name) inst.generate(**kw) # print '\n'.join(directive.result) assert len(_warnings) == 0, _warnings assert item in directive.result del directive.result[:] def assert_order(items, objtype, name, member_order, **kw): inst = AutoDirective._registry[objtype](directive, name) inst.options.member_order = member_order inst.generate(**kw) assert len(_warnings) == 0, _warnings items = list(reversed(items)) lineiter = iter(directive.result) # for line in directive.result: # if line.strip(): # print repr(line) while items: item = items.pop() for line in lineiter: if line == item: break else: # ran out of items! assert False, ('item %r not found in result or not in the ' ' correct order' % item) del directive.result[:] options.members = [] # no module found? assert_warns("import for autodocumenting 'foobar'", 'function', 'foobar', more_content=None) # importing assert_warns("failed to import module 'test_foobar'", 'module', 'test_foobar', more_content=None) # attributes missing assert_warns("failed to import function 'foobar' from module 'util'", 'function', 'util.foobar', more_content=None) # method missing assert_warns("failed to import method 'Class.foobar' from module 'test_autodoc';", 'method', 'test_autodoc.Class.foobar', more_content=None) # test auto and given content mixing directive.env.ref_context['py:module'] = 'test_autodoc' assert_result_contains(' Function.', 'method', 'Class.meth') add_content = ViewList() add_content.append('Content.', '', 0) assert_result_contains(' Function.', 'method', 'Class.meth', more_content=add_content) assert_result_contains(' Content.', 'method', 'Class.meth', more_content=add_content) # test check_module inst = FunctionDocumenter(directive, 'add_documenter') inst.generate(check_module=True) assert len(directive.result) == 0 # assert that exceptions can be documented assert_works('exception', 'test_autodoc.CustomEx', all_members=True) assert_works('exception', 'test_autodoc.CustomEx') # test diverse inclusion settings for members should = [('class', 'test_autodoc.Class')] assert_processes(should, 'class', 'Class') should.extend([('method', 'test_autodoc.Class.meth')]) options.members = ['meth'] options.exclude_members = set(['excludemeth']) assert_processes(should, 'class', 'Class') should.extend([('attribute', 'test_autodoc.Class.prop'), ('attribute', 'test_autodoc.Class.descr'), ('attribute', 'test_autodoc.Class.attr'), ('attribute', 'test_autodoc.Class.docattr'), ('attribute', 'test_autodoc.Class.udocattr'), ('attribute', 'test_autodoc.Class.mdocattr'), ('attribute', 'test_autodoc.Class.inst_attr_comment'), ('attribute', 'test_autodoc.Class.inst_attr_inline'), ('attribute', 'test_autodoc.Class.inst_attr_string'), ('method', 'test_autodoc.Class.moore'), ]) options.members = ALL assert_processes(should, 'class', 'Class') options.undoc_members = True should.extend((('attribute', 'test_autodoc.Class.skipattr'), ('method', 'test_autodoc.Class.undocmeth'), ('method', 'test_autodoc.Class.roger'))) assert_processes(should, 'class', 'Class') options.inherited_members = True should.append(('method', 'test_autodoc.Class.inheritedmeth')) assert_processes(should, 'class', 'Class') # test special members options.special_members = ['__special1__'] should.append(('method', 'test_autodoc.Class.__special1__')) assert_processes(should, 'class', 'Class') options.special_members = ALL should.append(('method', 'test_autodoc.Class.__special2__')) assert_processes(should, 'class', 'Class') options.special_members = False options.members = [] # test module flags assert_result_contains('.. py:module:: test_autodoc', 'module', 'test_autodoc') options.synopsis = 'Synopsis' assert_result_contains(' :synopsis: Synopsis', 'module', 'test_autodoc') options.deprecated = True assert_result_contains(' :deprecated:', 'module', 'test_autodoc') options.platform = 'Platform' assert_result_contains(' :platform: Platform', 'module', 'test_autodoc') # test if __all__ is respected for modules options.members = ALL assert_result_contains('.. py:class:: Class(arg)', 'module', 'test_autodoc') try: assert_result_contains('.. py:exception:: CustomEx', 'module', 'test_autodoc') except AssertionError: pass else: assert False, 'documented CustomEx which is not in __all__' # test noindex flag options.members = [] options.noindex = True assert_result_contains(' :noindex:', 'module', 'test_autodoc') assert_result_contains(' :noindex:', 'class', 'Base') # okay, now let's get serious about mixing Python and C signature stuff assert_result_contains('.. py:class:: CustomDict', 'class', 'CustomDict', all_members=True) # test inner class handling assert_processes([('class', 'test_autodoc.Outer'), ('class', 'test_autodoc.Outer.Inner'), ('method', 'test_autodoc.Outer.Inner.meth')], 'class', 'Outer', all_members=True) # test descriptor docstrings assert_result_contains(' Descriptor instance docstring.', 'attribute', 'test_autodoc.Class.descr') # test generation for C modules (which have no source file) directive.env.ref_context['py:module'] = 'time' assert_processes([('function', 'time.asctime')], 'function', 'asctime') assert_processes([('function', 'time.asctime')], 'function', 'asctime') # test autodoc_member_order == 'source' directive.env.ref_context['py:module'] = 'test_autodoc' if PY3: roger_line = ' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)' else: roger_line = ' .. py:classmethod:: Class.roger(a, e=5, f=6)' assert_order(['.. py:class:: Class(arg)', ' .. py:attribute:: Class.descr', ' .. py:method:: Class.meth()', ' .. py:method:: Class.undocmeth()', ' .. py:attribute:: Class.attr', ' .. py:attribute:: Class.prop', ' .. py:attribute:: Class.docattr', ' .. py:attribute:: Class.udocattr', ' .. py:attribute:: Class.mdocattr', roger_line, ' .. py:classmethod:: Class.moore(a, e, f) -> happiness', ' .. py:attribute:: Class.inst_attr_comment', ' .. py:attribute:: Class.inst_attr_string', ' .. py:method:: Class.inheritedmeth()', ], 'class', 'Class', member_order='bysource', all_members=True) del directive.env.ref_context['py:module'] # test attribute initialized to class instance from other module directive.env.temp_data['autodoc:class'] = 'test_autodoc.Class' assert_result_contains(u' should be documented as well - s\xfc\xdf', 'attribute', 'mdocattr') del directive.env.temp_data['autodoc:class'] # test autodoc_docstring_signature assert_result_contains( '.. py:method:: DocstringSig.meth(FOO, BAR=1) -> BAZ', 'method', 'test_autodoc.DocstringSig.meth') assert_result_contains( ' rest of docstring', 'method', 'test_autodoc.DocstringSig.meth') assert_result_contains( '.. py:method:: DocstringSig.meth2()', 'method', 'test_autodoc.DocstringSig.meth2') assert_result_contains( ' indented line', 'method', 'test_autodoc.DocstringSig.meth2') assert_result_contains( '.. py:classmethod:: Class.moore(a, e, f) -> happiness', 'method', 'test_autodoc.Class.moore') # test new attribute documenter behavior directive.env.ref_context['py:module'] = 'test_autodoc' options.undoc_members = True assert_processes([('class', 'test_autodoc.AttCls'), ('attribute', 'test_autodoc.AttCls.a1'), ('attribute', 'test_autodoc.AttCls.a2'), ], 'class', 'AttCls') assert_result_contains( ' :annotation: = hello world', 'attribute', 'AttCls.a1') assert_result_contains( ' :annotation: = None', 'attribute', 'AttCls.a2') # test explicit members with instance attributes del directive.env.temp_data['autodoc:class'] del directive.env.temp_data['autodoc:module'] directive.env.ref_context['py:module'] = 'test_autodoc' options.inherited_members = False options.undoc_members = False options.members = ALL assert_processes([ ('class', 'test_autodoc.InstAttCls'), ('attribute', 'test_autodoc.InstAttCls.ca1'), ('attribute', 'test_autodoc.InstAttCls.ca2'), ('attribute', 'test_autodoc.InstAttCls.ca3'), ('attribute', 'test_autodoc.InstAttCls.ia1'), ('attribute', 'test_autodoc.InstAttCls.ia2'), ], 'class', 'InstAttCls') del directive.env.temp_data['autodoc:class'] del directive.env.temp_data['autodoc:module'] options.members = ['ca1', 'ia1'] assert_processes([ ('class', 'test_autodoc.InstAttCls'), ('attribute', 'test_autodoc.InstAttCls.ca1'), ('attribute', 'test_autodoc.InstAttCls.ia1'), ], 'class', 'InstAttCls') del directive.env.temp_data['autodoc:class'] del directive.env.temp_data['autodoc:module'] del directive.env.ref_context['py:module'] # test members with enum attributes directive.env.ref_context['py:module'] = 'test_autodoc' options.inherited_members = False options.undoc_members = False options.members = ALL assert_processes([ ('class', 'test_autodoc.EnumCls'), ('attribute', 'test_autodoc.EnumCls.val1'), ('attribute', 'test_autodoc.EnumCls.val2'), ('attribute', 'test_autodoc.EnumCls.val3'), ], 'class', 'EnumCls') assert_result_contains( ' :annotation: = 12', 'attribute', 'EnumCls.val1') assert_result_contains( ' :annotation: = 23', 'attribute', 'EnumCls.val2') assert_result_contains( ' :annotation: = 34', 'attribute', 'EnumCls.val3') del directive.env.temp_data['autodoc:class'] del directive.env.temp_data['autodoc:module'] # test descriptor class documentation options.members = ['CustomDataDescriptor', 'CustomDataDescriptor2'] assert_result_contains('.. py:class:: CustomDataDescriptor(doc)', 'module', 'test_autodoc') assert_result_contains(' .. py:method:: CustomDataDescriptor.meth()', 'module', 'test_autodoc') assert_result_contains('.. py:class:: CustomDataDescriptor2(doc)', 'module', 'test_autodoc') # test mocked module imports options.members = ['TestAutodoc'] options.undoc_members = False assert_result_contains('.. py:class:: TestAutodoc', 'module', 'autodoc_missing_imports') assert_result_contains(' .. py:method:: TestAutodoc.decoratedMethod()', 'module', 'autodoc_missing_imports') options.members = ['decoratedFunction'] assert_result_contains('.. py:function:: decoratedFunction()', 'module', 'autodoc_missing_imports')
def test_generate(): def assert_warns(warn_str, objtype, name, **kw): inst = AutoDirective._registry[objtype](directive, name) inst.generate(**kw) assert len(directive.result) == 0, directive.result assert len(_warnings) == 1, _warnings assert warn_str in _warnings[0], _warnings del _warnings[:] def assert_works(objtype, name, **kw): inst = AutoDirective._registry[objtype](directive, name) inst.generate(**kw) assert directive.result assert len(_warnings) == 0, _warnings del directive.result[:] def assert_processes(items, objtype, name, **kw): del processed_docstrings[:] del processed_signatures[:] assert_works(objtype, name, **kw) assert set(processed_docstrings) | set(processed_signatures) == \ set(items) def assert_result_contains(item, objtype, name, **kw): inst = AutoDirective._registry[objtype](directive, name) inst.generate(**kw) #print '\n'.join(directive.result) assert len(_warnings) == 0, _warnings assert item in directive.result del directive.result[:] options.members = [] # no module found? assert_warns("import for autodocumenting 'foobar'", 'function', 'foobar', more_content=None) # importing assert_warns("import/find module 'test_foobar'", 'module', 'test_foobar', more_content=None) # attributes missing assert_warns("import/find function 'util.foobar'", 'function', 'util.foobar', more_content=None) # test auto and given content mixing directive.env.currmodule = 'test_autodoc' assert_result_contains(' Function.', 'method', 'Class.meth') add_content = ViewList() add_content.append('Content.', '', 0) assert_result_contains(' Function.', 'method', 'Class.meth', more_content=add_content) assert_result_contains(' Content.', 'method', 'Class.meth', more_content=add_content) # test check_module inst = FunctionDocumenter(directive, 'raises') inst.generate(check_module=True) assert len(directive.result) == 0 # assert that exceptions can be documented assert_works('exception', 'test_autodoc.CustomEx', all_members=True) assert_works('exception', 'test_autodoc.CustomEx') # test diverse inclusion settings for members should = [('class', 'test_autodoc.Class')] assert_processes(should, 'class', 'Class') should.extend([('method', 'test_autodoc.Class.meth')]) options.members = ['meth'] options.exclude_members = set(['excludemeth']) assert_processes(should, 'class', 'Class') should.extend([('attribute', 'test_autodoc.Class.prop'), ('attribute', 'test_autodoc.Class.attr'), ('attribute', 'test_autodoc.Class.docattr'), ('attribute', 'test_autodoc.Class.udocattr')]) options.members = ALL assert_processes(should, 'class', 'Class') options.undoc_members = True should.append(('method', 'test_autodoc.Class.undocmeth')) assert_processes(should, 'class', 'Class') options.inherited_members = True should.append(('method', 'test_autodoc.Class.inheritedmeth')) assert_processes(should, 'class', 'Class') options.members = [] # test module flags assert_result_contains('.. module:: test_autodoc', 'module', 'test_autodoc') options.synopsis = 'Synopsis' assert_result_contains(' :synopsis: Synopsis', 'module', 'test_autodoc') options.deprecated = True assert_result_contains(' :deprecated:', 'module', 'test_autodoc') options.platform = 'Platform' assert_result_contains(' :platform: Platform', 'module', 'test_autodoc') # test if __all__ is respected for modules options.members = ALL assert_result_contains('.. class:: Class', 'module', 'test_autodoc') try: assert_result_contains('.. exception:: CustomEx', 'module', 'test_autodoc') except AssertionError: pass else: assert False, 'documented CustomEx which is not in __all__' # test noindex flag options.members = [] options.noindex = True assert_result_contains(' :noindex:', 'module', 'test_autodoc') assert_result_contains(' :noindex:', 'class', 'Base') # okay, now let's get serious about mixing Python and C signature stuff assert_result_contains('.. class:: CustomDict', 'class', 'CustomDict', all_members=True) # test inner class handling assert_processes([('class', 'test_autodoc.Outer'), ('class', 'test_autodoc.Outer.Inner'), ('method', 'test_autodoc.Outer.Inner.meth')], 'class', 'Outer', all_members=True) # test generation for C modules (which have no source file) directive.env.currmodule = 'time' assert_processes([('function', 'time.asctime')], 'function', 'asctime') assert_processes([('function', 'time.asctime')], 'function', 'asctime')
def test_generate(): logging.setup(app, app._status, app._warning) def assert_warns(warn_str, objtype, name, **kw): inst = app.registry.documenters[objtype](directive, name) inst.generate(**kw) assert len(directive.result) == 0, directive.result assert warn_str in app._warning.getvalue() app._warning.truncate(0) def assert_works(objtype, name, **kw): inst = app.registry.documenters[objtype](directive, name) inst.generate(**kw) assert directive.result # print '\n'.join(directive.result) assert app._warning.getvalue() == '' del directive.result[:] def assert_processes(items, objtype, name, **kw): del processed_docstrings[:] del processed_signatures[:] assert_works(objtype, name, **kw) assert set(processed_docstrings) | set(processed_signatures) == set( items) def assert_result_contains(item, objtype, name, **kw): inst = app.registry.documenters[objtype](directive, name) inst.generate(**kw) # print '\n'.join(directive.result) assert app._warning.getvalue() == '' assert item in directive.result del directive.result[:] def assert_order(items, objtype, name, member_order, **kw): inst = app.registry.documenters[objtype](directive, name) inst.options.member_order = member_order inst.generate(**kw) assert app._warning.getvalue() == '' items = list(reversed(items)) lineiter = iter(directive.result) # for line in directive.result: # if line.strip(): # print repr(line) while items: item = items.pop() for line in lineiter: if line == item: break else: # ran out of items! assert False, ('item %r not found in result or not in the ' ' correct order' % item) del directive.result[:] options.members = [] # no module found? assert_warns("import for autodocumenting 'foobar'", 'function', 'foobar', more_content=None) # importing assert_warns("failed to import module 'test_foobar'", 'module', 'test_foobar', more_content=None) # attributes missing assert_warns("failed to import function 'foobar' from module 'util'", 'function', 'util.foobar', more_content=None) # method missing assert_warns( "failed to import method 'Class.foobar' from module 'test_autodoc_py35';", 'method', 'test_autodoc_py35.Class.foobar', more_content=None) # test auto and given content mixing directive.env.ref_context['py:module'] = 'test_autodoc_py35' assert_result_contains(' Function.', 'method', 'Class.meth') add_content = ViewList() add_content.append('Content.', '', 0) assert_result_contains(' Function.', 'method', 'Class.meth', more_content=add_content) assert_result_contains(' Content.', 'method', 'Class.meth', more_content=add_content) # test check_module inst = FunctionDocumenter(directive, 'add_documenter') inst.generate(check_module=True) assert len(directive.result) == 0 # assert that exceptions can be documented assert_works('exception', 'test_autodoc_py35.CustomEx', all_members=True) assert_works('exception', 'test_autodoc_py35.CustomEx') # test diverse inclusion settings for members should = [('class', 'test_autodoc_py35.Class')] assert_processes(should, 'class', 'Class') should.extend([('method', 'test_autodoc_py35.Class.meth')]) options.members = ['meth'] options.exclude_members = set(['excludemeth']) assert_processes(should, 'class', 'Class') should.extend([ ('attribute', 'test_autodoc_py35.Class.prop'), ('attribute', 'test_autodoc_py35.Class.descr'), ('attribute', 'test_autodoc_py35.Class.attr'), ('attribute', 'test_autodoc_py35.Class.docattr'), ('attribute', 'test_autodoc_py35.Class.udocattr'), ('attribute', 'test_autodoc_py35.Class.mdocattr'), ('attribute', 'test_autodoc_py35.Class.inst_attr_comment'), ('attribute', 'test_autodoc_py35.Class.inst_attr_inline'), ('attribute', 'test_autodoc_py35.Class.inst_attr_string'), ('method', 'test_autodoc_py35.Class.moore'), ]) if six.PY3 and sys.version_info[:2] >= (3, 5): should.extend([ ('method', 'test_autodoc_py35.Class.do_coroutine'), ]) options.members = ALL assert_processes(should, 'class', 'Class') options.undoc_members = True should.extend((('attribute', 'test_autodoc_py35.Class.skipattr'), ('method', 'test_autodoc_py35.Class.undocmeth'), ('method', 'test_autodoc_py35.Class.roger'))) assert_processes(should, 'class', 'Class') options.inherited_members = True should.append(('method', 'test_autodoc_py35.Class.inheritedmeth')) assert_processes(should, 'class', 'Class') # test special members options.special_members = ['__special1__'] should.append(('method', 'test_autodoc_py35.Class.__special1__')) assert_processes(should, 'class', 'Class') options.special_members = ALL should.append(('method', 'test_autodoc_py35.Class.__special2__')) assert_processes(should, 'class', 'Class') options.special_members = False
def can_document_member(cls, member, membername, isattr, parent): can = FunctionDocumenter.can_document_member( member, membername, isattr, parent) # bound methods plus = isinstance(parent, ModuleDocumenter) and inspect.ismethod(member) return can or plus
def test_generate(): logging.setup(app, app._status, app._warning) def assert_warns(warn_str, objtype, name, **kw): inst = app.registry.documenters[objtype](directive, name) inst.generate(**kw) assert len(directive.result) == 0, directive.result assert warn_str in app._warning.getvalue() app._warning.truncate(0) def assert_works(objtype, name, **kw): inst = app.registry.documenters[objtype](directive, name) inst.generate(**kw) assert directive.result # print '\n'.join(directive.result) assert app._warning.getvalue() == '' del directive.result[:] def assert_processes(items, objtype, name, **kw): del processed_docstrings[:] del processed_signatures[:] assert_works(objtype, name, **kw) assert set(processed_docstrings) | set(processed_signatures) == set(items) def assert_result_contains(item, objtype, name, **kw): inst = app.registry.documenters[objtype](directive, name) inst.generate(**kw) # print '\n'.join(directive.result) assert app._warning.getvalue() == '' assert item in directive.result del directive.result[:] def assert_order(items, objtype, name, member_order, **kw): inst = app.registry.documenters[objtype](directive, name) inst.options.member_order = member_order inst.generate(**kw) assert app._warning.getvalue() == '' items = list(reversed(items)) lineiter = iter(directive.result) # for line in directive.result: # if line.strip(): # print repr(line) while items: item = items.pop() for line in lineiter: if line == item: break else: # ran out of items! assert False, ('item %r not found in result or not in the ' ' correct order' % item) del directive.result[:] options.members = [] # no module found? assert_warns("import for autodocumenting 'foobar'", 'function', 'foobar', more_content=None) # importing assert_warns("failed to import module 'test_foobar'", 'module', 'test_foobar', more_content=None) # attributes missing assert_warns("failed to import function 'foobar' from module 'util'", 'function', 'util.foobar', more_content=None) # method missing assert_warns("failed to import method 'Class.foobar' from module 'test_autodoc_py35';", 'method', 'test_autodoc_py35.Class.foobar', more_content=None) # test auto and given content mixing directive.env.ref_context['py:module'] = 'test_autodoc_py35' assert_result_contains(' Function.', 'method', 'Class.meth') add_content = ViewList() add_content.append('Content.', '', 0) assert_result_contains(' Function.', 'method', 'Class.meth', more_content=add_content) assert_result_contains(' Content.', 'method', 'Class.meth', more_content=add_content) # test check_module inst = FunctionDocumenter(directive, 'add_documenter') inst.generate(check_module=True) assert len(directive.result) == 0 # assert that exceptions can be documented assert_works('exception', 'test_autodoc_py35.CustomEx', all_members=True) assert_works('exception', 'test_autodoc_py35.CustomEx') # test diverse inclusion settings for members should = [('class', 'test_autodoc_py35.Class')] assert_processes(should, 'class', 'Class') should.extend([('method', 'test_autodoc_py35.Class.meth')]) options.members = ['meth'] options.exclude_members = set(['excludemeth']) assert_processes(should, 'class', 'Class') should.extend([('attribute', 'test_autodoc_py35.Class.prop'), ('attribute', 'test_autodoc_py35.Class.descr'), ('attribute', 'test_autodoc_py35.Class.attr'), ('attribute', 'test_autodoc_py35.Class.docattr'), ('attribute', 'test_autodoc_py35.Class.udocattr'), ('attribute', 'test_autodoc_py35.Class.mdocattr'), ('attribute', 'test_autodoc_py35.Class.inst_attr_comment'), ('attribute', 'test_autodoc_py35.Class.inst_attr_inline'), ('attribute', 'test_autodoc_py35.Class.inst_attr_string'), ('method', 'test_autodoc_py35.Class.moore'), ]) if six.PY3 and sys.version_info[:2] >= (3, 5): should.extend([ ('method', 'test_autodoc_py35.Class.do_coroutine'), ]) options.members = ALL assert_processes(should, 'class', 'Class') options.undoc_members = True should.extend((('attribute', 'test_autodoc_py35.Class.skipattr'), ('method', 'test_autodoc_py35.Class.undocmeth'), ('method', 'test_autodoc_py35.Class.roger'))) assert_processes(should, 'class', 'Class') options.inherited_members = True should.append(('method', 'test_autodoc_py35.Class.inheritedmeth')) assert_processes(should, 'class', 'Class') # test special members options.special_members = ['__special1__'] should.append(('method', 'test_autodoc_py35.Class.__special1__')) assert_processes(should, 'class', 'Class') options.special_members = ALL should.append(('method', 'test_autodoc_py35.Class.__special2__')) assert_processes(should, 'class', 'Class') options.special_members = False
def test_generate(): def assert_warns(warn_str, objtype, name, **kw): inst = AutoDirective._registry[objtype](directive, name) inst.generate(**kw) assert len(directive.result) == 0, directive.result assert len(_warnings) == 1, _warnings assert warn_str in _warnings[0], _warnings del _warnings[:] def assert_works(objtype, name, **kw): inst = AutoDirective._registry[objtype](directive, name) inst.generate(**kw) assert directive.result # print '\n'.join(directive.result) assert len(_warnings) == 0, _warnings del directive.result[:] def assert_processes(items, objtype, name, **kw): del processed_docstrings[:] del processed_signatures[:] assert_works(objtype, name, **kw) assert set(processed_docstrings) | set(processed_signatures) == set(items) def assert_result_contains(item, objtype, name, **kw): inst = AutoDirective._registry[objtype](directive, name) inst.generate(**kw) # print '\n'.join(directive.result) assert len(_warnings) == 0, _warnings assert item in directive.result del directive.result[:] def assert_order(items, objtype, name, member_order, **kw): inst = AutoDirective._registry[objtype](directive, name) inst.options.member_order = member_order inst.generate(**kw) assert len(_warnings) == 0, _warnings items = list(reversed(items)) lineiter = iter(directive.result) # for line in directive.result: # if line.strip(): # print repr(line) while items: item = items.pop() for line in lineiter: if line == item: break else: # ran out of items! assert False, "item %r not found in result or not in the " " correct order" % item del directive.result[:] options.members = [] # no module found? assert_warns("import for autodocumenting 'foobar'", "function", "foobar", more_content=None) # importing assert_warns("failed to import module 'test_foobar'", "module", "test_foobar", more_content=None) # attributes missing assert_warns("failed to import function 'foobar' from module 'util'", "function", "util.foobar", more_content=None) # method missing assert_warns( "failed to import method 'Class.foobar' from module 'test_autodoc_py35';", "method", "test_autodoc_py35.Class.foobar", more_content=None, ) # test auto and given content mixing directive.env.ref_context["py:module"] = "test_autodoc_py35" assert_result_contains(" Function.", "method", "Class.meth") add_content = ViewList() add_content.append("Content.", "", 0) assert_result_contains(" Function.", "method", "Class.meth", more_content=add_content) assert_result_contains(" Content.", "method", "Class.meth", more_content=add_content) # test check_module inst = FunctionDocumenter(directive, "raises") inst.generate(check_module=True) assert len(directive.result) == 0 # assert that exceptions can be documented assert_works("exception", "test_autodoc_py35.CustomEx", all_members=True) assert_works("exception", "test_autodoc_py35.CustomEx") # test diverse inclusion settings for members should = [("class", "test_autodoc_py35.Class")] assert_processes(should, "class", "Class") should.extend([("method", "test_autodoc_py35.Class.meth")]) options.members = ["meth"] options.exclude_members = set(["excludemeth"]) assert_processes(should, "class", "Class") should.extend( [ ("attribute", "test_autodoc_py35.Class.prop"), ("attribute", "test_autodoc_py35.Class.descr"), ("attribute", "test_autodoc_py35.Class.attr"), ("attribute", "test_autodoc_py35.Class.docattr"), ("attribute", "test_autodoc_py35.Class.udocattr"), ("attribute", "test_autodoc_py35.Class.mdocattr"), ("attribute", "test_autodoc_py35.Class.inst_attr_comment"), ("attribute", "test_autodoc_py35.Class.inst_attr_inline"), ("attribute", "test_autodoc_py35.Class.inst_attr_string"), ("method", "test_autodoc_py35.Class.moore"), ] ) if six.PY3 and sys.version_info[:2] >= (3, 5): should.extend([("method", "test_autodoc_py35.Class.do_coroutine")]) options.members = ALL assert_processes(should, "class", "Class") options.undoc_members = True should.extend( ( ("attribute", "test_autodoc_py35.Class.skipattr"), ("method", "test_autodoc_py35.Class.undocmeth"), ("method", "test_autodoc_py35.Class.roger"), ) ) assert_processes(should, "class", "Class") options.inherited_members = True should.append(("method", "test_autodoc_py35.Class.inheritedmeth")) assert_processes(should, "class", "Class") # test special members options.special_members = ["__special1__"] should.append(("method", "test_autodoc_py35.Class.__special1__")) assert_processes(should, "class", "Class") options.special_members = ALL should.append(("method", "test_autodoc_py35.Class.__special2__")) assert_processes(should, "class", "Class") options.special_members = False