def test__pdoc__dict(self): module = pdoc.import_module(EXAMPLE_MODULE) with patch.object(module, '__pdoc__', {'B': False}): mod = pdoc.Module(module) pdoc.link_inheritance() self.assertIn('A', mod.doc) self.assertNotIn('B', mod.doc) with patch.object(module, '__pdoc__', {'B.__init__': False}): mod = pdoc.Module(module) pdoc.link_inheritance() self.assertIn('B', mod.doc) self.assertNotIn('__init__', mod.doc['B'].doc) self.assertIsInstance(mod.find_ident('B.__init__'), pdoc.External)
def test_url(self): mod = pdoc.Module(pdoc.import_module(EXAMPLE_MODULE)) pdoc.link_inheritance() c = mod.doc['D'] self.assertEqual(c.url(), 'example_pkg/index.html#example_pkg.D') self.assertEqual(c.url(link_prefix='/'), '/example_pkg/index.html#example_pkg.D') self.assertEqual(c.url(relative_to=c.module), '#example_pkg.D') self.assertEqual(c.url(top_ancestor=True), 'example_pkg/index.html#example_pkg.B') f = c.doc['overridden'] self.assertEqual(f.url(), 'example_pkg/index.html#example_pkg.D.overridden') self.assertEqual(f.url(link_prefix='/'), '/example_pkg/index.html#example_pkg.D.overridden') self.assertEqual(f.url(relative_to=c.module), '#example_pkg.D.overridden') self.assertEqual(f.url(top_ancestor=1), 'example_pkg/index.html#example_pkg.B.overridden')
def test_inherits(self): module = pdoc.Module(EXAMPLE_MODULE) pdoc.link_inheritance() a = module.doc['A'] b = module.doc['B'] self.assertEqual(b.doc['inherited'].inherits, a.doc['inherited']) self.assertEqual(b.doc['overridden_same_docstring'].inherits, a.doc['overridden_same_docstring']) self.assertEqual(b.doc['overridden'].inherits, None) c = module.doc['C'] d = module.doc['D'] self.assertEqual(d.doc['overridden'].inherits, c.doc['overridden']) self.assertEqual(c.doc['overridden'].inherits, b.doc['overridden'])
def test_pdoc3(): modules = ["test_pdoc3_docstring_parser"] context = pdoc.Context() modules = [pdoc.Module(mod, context=context) for mod in modules] pdoc.link_inheritance(context) # for module in modules: for function in module.functions(): na = function.name mo = function.module ob = function.obj do = function.docstring ih = function.inherits fd = function.funcdef() pa = function.params(annotate=True) ra = function.return_annotation() pass html = module.html()
def __init__(self, path, destination, name="docs", templates=None): """Set notes templates. Initialize `pdoc` linker. Parameters ---------- path : pathlib.Path path to directory containing `.py` files with notes templates : pathlib.Path or None, optional path to directory containing customized templates which will be used to create `html` notes (default is `None`) """ self.destination = destination self.name = name self.set_templates(templates) context = pdoc.Context() source = str(path / destination.name) self.module = pdoc.Module(source, context=context) pdoc.link_inheritance(context)
def test_refname(self): mod = EXAMPLE_MODULE + '.' + 'subpkg' module = pdoc.Module(mod) var = module.doc['var'] cls = module.doc['B'] nested_cls = cls.doc['C'] cls_var = cls.doc['var'] method = cls.doc['f'] self.assertEqual(pdoc.External('foo').refname, 'foo') self.assertEqual(module.refname, mod) self.assertEqual(var.refname, mod + '.var') self.assertEqual(cls.refname, mod + '.B') self.assertEqual(nested_cls.refname, mod + '.B.C') self.assertEqual(cls_var.refname, mod + '.B.var') self.assertEqual(method.refname, mod + '.B.f') # Inherited method's refname points to class' implicit copy pdoc.link_inheritance() self.assertEqual(cls.doc['inherited'].refname, mod + '.B.inherited')
def _api_modules(): def _recursive_htmls(mod): yield mod.name, mod.html() for submod in mod.submodules(): yield from _recursive_htmls(submod) modules = ["pyatv"] context = pdoc.Context() modules = [ pdoc.Module(mod, context=context, docfilter=_filter_func) for mod in modules ] pdoc.link_inheritance(context) for mod in modules: for module_name, html in _recursive_htmls(mod): splitted = module_name.split(".") splitted[-1] = splitted[-1] + ".html" output_file = os.path.join("docs", "api", *splitted) yield output_file, html
def test_link_inheritance(self): mod = pdoc.Module(pdoc.import_module(EXAMPLE_MODULE)) with warnings.catch_warnings(record=True) as w: pdoc.link_inheritance() pdoc.link_inheritance() self.assertFalse(w) mod._is_inheritance_linked = False with self.assertWarns(UserWarning): pdoc.link_inheritance() # Test inheritance across modules pdoc.reset() mod = pdoc.Module(pdoc.import_module(EXAMPLE_MODULE + '._test_linking')) pdoc.link_inheritance() a = mod.doc['a'].doc['A'] b = mod.doc['b'].doc['B'] c = mod.doc['b'].doc['c'].doc['C'] self.assertEqual(b.inherits, a) self.assertEqual(b.doc['a'].inherits, a.doc['a']) self.assertEqual(b.doc['c'].inherits, c.doc['c'])
def test_link_inheritance(self): mod = pdoc.Module(EXAMPLE_MODULE) with warnings.catch_warnings(record=True) as w: pdoc.link_inheritance() pdoc.link_inheritance() self.assertFalse(w) mod._is_inheritance_linked = False with self.assertWarns(UserWarning): pdoc.link_inheritance() # Test inheritance across modules pdoc.reset() mod = pdoc.Module(EXAMPLE_MODULE + '._test_linking') pdoc.link_inheritance() a = mod.doc['a'].doc['A'] b = mod.doc['b'].doc['B'] c = mod.doc['b'].doc['c'].doc['C'] self.assertEqual(b.doc['a'].inherits, a.doc['a']) self.assertEqual(b.doc['c'].inherits, c.doc['c']) # While classes do inherit from superclasses, they just shouldn't always # say so, because public classes do want to be exposed and linked to self.assertNotEqual(b.inherits, a)
def test__pdoc__dict(self): module = pdoc.import_module(EXAMPLE_MODULE) with patch.object(module, '__pdoc__', {'B': False}): mod = pdoc.Module(module) pdoc.link_inheritance() self.assertIn('A', mod.doc) self.assertNotIn('B', mod.doc) with patch.object(module, '__pdoc__', {'B.f': False}): mod = pdoc.Module(module) pdoc.link_inheritance() self.assertIn('B', mod.doc) self.assertNotIn('f', mod.doc['B'].doc) self.assertIsInstance(mod.find_ident('B.f'), pdoc.External) # GH-125: https://github.com/pdoc3/pdoc/issues/125 with patch.object(module, '__pdoc__', {'B.inherited': False}): mod = pdoc.Module(module) pdoc.link_inheritance() self.assertNotIn('inherited', mod.doc['B'].doc)
def test__pdoc__invalid_value(self): module = pdoc.import_module(EXAMPLE_MODULE) with patch.object(module, '__pdoc__', {'B': 1}), \ self.assertRaises(ValueError): pdoc.Module(module) pdoc.link_inheritance()
def main(_args=None): """ Command-line entry point """ global args args = _args or parser.parse_args() warnings.simplefilter("once", DeprecationWarning) if args.close_stdin: sys.stdin.close() if (args.html or args.http) and not args.output_dir: args.output_dir = 'html' if args.html_dir: _warn_deprecated('--html-dir', '--output-dir') args.output_dir = args.html_dir if args.overwrite: _warn_deprecated('--overwrite', '--force') args.force = args.overwrite template_config = {} for config_str in args.config: try: key, value = config_str.split('=', 1) value = ast.literal_eval(value) template_config[key] = value except Exception: raise ValueError( 'Error evaluating --config statement "{}". ' 'Make sure string values are quoted?' .format(config_str) ) if args.html_no_source: _warn_deprecated('--html-no-source', '-c show_source_code=False', True) template_config['show_source_code'] = False if args.link_prefix: _warn_deprecated('--link-prefix', '-c link_prefix="foo"', True) template_config['link_prefix'] = args.link_prefix if args.external_links: _warn_deprecated('--external-links') template_config['external_links'] = True if args.template_dir is not None: if not path.isdir(args.template_dir): print('Error: Template dir {!r} is not a directory'.format(args.template_dir), file=sys.stderr) sys.exit(1) pdoc.tpl_lookup.directories.insert(0, args.template_dir) # Support loading modules specified as python paths relative to cwd sys.path.append(os.getcwd()) # Virtual environment handling for pdoc script run from system site try: venv_dir = os.environ['VIRTUAL_ENV'] except KeyError: pass # pdoc was not invoked while in a virtual environment else: from distutils.sysconfig import get_python_lib sys.path.append(get_python_lib(prefix=venv_dir)) if args.http: template_config['link_prefix'] = "/" # Run the HTTP server. _WebDoc.args = args # Pass params to HTTPServer xP _WebDoc.template_config = template_config host, _, port = args.http.partition(':') host = host or DEFAULT_HOST port = int(port or DEFAULT_PORT) print('Starting pdoc server on {}:{}'.format(host, port), file=sys.stderr) httpd = HTTPServer((host, port), _WebDoc) print("pdoc server ready at http://%s:%d" % (host, port), file=sys.stderr) # Allow tests to perform `pdoc.cli._httpd.shutdown()` global _httpd _httpd = httpd try: httpd.serve_forever() finally: httpd.server_close() sys.exit(0) docfilter = None if args.filter and args.filter.strip(): def docfilter(obj, _filters=args.filter.strip().split(',')): return any(f in obj.refname or isinstance(obj, pdoc.Class) and f in obj.doc for f in _filters) modules = [pdoc.Module(module, docfilter=docfilter, skip_errors=args.skip_errors) for module in args.modules] pdoc.link_inheritance() if args.pdf: _print_pdf(modules, **template_config) print(""" PDF-ready markdown written to standard output. ^^^^^^^^^^^^^^^ Convert this file to PDF using e.g. Pandoc: pandoc --metadata=title:"MyProject Documentation" \\ --toc --toc-depth=4 --from=markdown+abbreviations \\ --pdf-engine=xelatex --variable=mainfont:"DejaVu Sans" \\ --output=pdf.pdf pdf.md or using Python-Markdown and Chrome/Chromium/WkHtmlToPDF: markdown_py --extension=meta \\ --extension=abbr \\ --extension=attr_list \\ --extension=def_list \\ --extension=fenced_code \\ --extension=footnotes \\ --extension=tables \\ --extension=admonition \\ --extension=smarty \\ --extension=toc \\ pdf.md > pdf.html chromium --headless --disable-gpu --print-to-pdf=pdf.pdf pdf.html wkhtmltopdf --encoding utf8 -s A4 --print-media-type pdf.html pdf.pdf or similar, at your own discretion.""", file=sys.stderr) sys.exit(0) for module in modules: if args.html: _quit_if_exists(module, ext='.html') recursive_write_files(module, ext='.html', **template_config) elif args.output_dir: # Generate text files _quit_if_exists(module, ext='.md') recursive_write_files(module, ext='.md', **template_config) else: sys.stdout.write(module.text(**template_config)) # Two blank lines between two modules' texts sys.stdout.write(os.linesep * (1 + 2 * int(module != modules[-1])))
def main(_args=None): """ Command-line entry point """ global args args = _args or parser.parse_args() # We close stdin because some modules, upon import, are not very polite # and block on stdin. sys.stdin.close() if args.template_dir is not None: if not path.isdir(args.template_dir): print('Error: Template dir {!r} is not a directory'.format( args.template_dir), file=sys.stderr) sys.exit(1) pdoc.tpl_lookup.directories.insert(0, args.template_dir) if args.http: args.html = True args.external_links = True args.overwrite = True args.link_prefix = "/" # Run the HTTP server. WebDoc.args = args # Pass params to HTTPServer xP host, _, port = args.http.partition(':') host = host or DEFAULT_HOST port = int(port or DEFAULT_PORT) print('Starting pdoc server on {}:{}'.format(host, port), file=sys.stderr) httpd = HTTPServer((host, port), WebDoc) print("pdoc server ready at http://%s:%d" % (host, port), file=sys.stderr) # Allow tests to perform `pdoc.cli._httpd.shutdown()` global _httpd _httpd = httpd try: httpd.serve_forever() finally: httpd.server_close() sys.exit(0) docfilter = None if args.filter and args.filter.strip(): def docfilter(obj, _filters=args.filter.strip().split(',')): return any(f in obj.refname or isinstance(obj, pdoc.Class) and f in obj.doc for f in _filters) # Support loading modules specified as python paths relative to cwd sys.path.append(os.getcwd()) modules = [ pdoc.Module(pdoc.import_module(module), docfilter=docfilter) for module in args.modules ] pdoc.link_inheritance() for module in modules: if args.html: _quit_if_exists(module) write_html_files(module) else: sys.stdout.write(module.text()) # Two blank lines between two modules' texts sys.stdout.write(os.linesep * (1 + 2 * int(module != modules[-1])))
pdoc.tpl_lookup.directories.insert(0, './templates') ctx = pdoc.Context() cmod = pdoc.Module(clingo, context=ctx) amod = pdoc.Module(clingo.ast, supermodule=cmod, context=ctx) xmod = parse_aux() cmod.doc["Application"] = pdoc.Class("Application", cmod, xmod.Application) cmod.doc["Observer"] = pdoc.Class("Observer", cmod, xmod.Observer) cmod.doc["Propagator"] = pdoc.Class("Propagator", cmod, xmod.Propagator) cmod.doc["ast"] = amod cmod.doc["__version__"] = pdoc.Variable("__version__", cmod, "__version__: str\n\nVersion of the clingo module (`'{}'`).".format(clingo.__version__)) cmod.doc["Infimum"] = pdoc.Variable("Infimum", cmod, '''Infimum: Symbol\n\nRepresents a symbol of type `clingo.SymbolType.Infimum`.''') cmod.doc["Supremum"] = pdoc.Variable("Supremum", cmod, '''Supremum: Symbol\n\nRepresents a symbol of type `clingo.SymbolType.Supremum`.''') pdoc.link_inheritance(ctx) prefix = "../clingo/python-api/{}".format(".".join(clingo.__version__.split(".")[:2])) cprefix = "../clingo/python-api/current" os.makedirs("{}/ast".format(prefix), exist_ok=True) os.makedirs("{}/ast".format(cprefix), exist_ok=True) cmod_html = cmod.html(external_links=True) amod_html = amod.html(external_links=True) open("{}/index.html".format(prefix), "w").write(cmod_html) open("{}/ast/index.html".format(prefix), "w").write(amod_html) open("{}/index.html".format(cprefix), "w").write(cmod_html.replace("clingo/python-api/5.4", "clingo/python-api/current")) open("{}/ast/index.html".format(cprefix), "w").write(amod_html.replace("clingo/python-api/5.4", "clingo/python-api/current"))
def main(_args=None): """ Command-line entry point """ global args args = _args or parser.parse_args() warnings.simplefilter("once", DeprecationWarning) if args.close_stdin: sys.stdin.close() if (args.html or args.http) and not args.output_dir: args.output_dir = 'html' if args.html_dir: _warn_deprecated('--html-dir', '--output-dir') args.output_dir = args.html_dir if args.overwrite: _warn_deprecated('--overwrite', '--force') args.force = args.overwrite template_config = {} for config_str in args.config: try: key, value = config_str.split('=', 1) value = ast.literal_eval(value) template_config[key] = value except Exception: raise ValueError( f'Error evaluating --config statement "{config_str}". ' 'Make sure string values are quoted?') if args.html_no_source: _warn_deprecated('--html-no-source', '-c show_source_code=False', True) template_config['show_source_code'] = False if args.link_prefix: _warn_deprecated('--link-prefix', '-c link_prefix="foo"', True) template_config['link_prefix'] = args.link_prefix if args.external_links: _warn_deprecated('--external-links') template_config['external_links'] = True if args.template_dir is not None: if not path.isdir(args.template_dir): print( f'Error: Template dir {args.template_dir!r} is not a directory', file=sys.stderr) sys.exit(1) pdoc.tpl_lookup.directories.insert(0, args.template_dir) # Support loading modules specified as python paths relative to cwd sys.path.append(os.getcwd()) # Virtual environment handling for pdoc script run from system site try: venv_dir = os.environ['VIRTUAL_ENV'] except KeyError: pass # pdoc was not invoked while in a virtual environment else: from glob import glob from distutils.sysconfig import get_python_lib libdir = get_python_lib(prefix=venv_dir) sys.path.append(libdir) # Resolve egg-links from `setup.py develop` or `pip install -e` # XXX: Welcome a more canonical approach for pth in glob(path.join(libdir, '*.egg-link')): try: with open(pth) as f: sys.path.append(path.join(libdir, f.readline().rstrip())) except IOError: warn(f'Invalid egg-link in venv: {pth!r}') if args.http: template_config['link_prefix'] = "/" # Run the HTTP server. _WebDoc.args = args # Pass params to HTTPServer xP _WebDoc.template_config = template_config host, _, port = args.http.partition(':') host = host or DEFAULT_HOST port = int(port or DEFAULT_PORT) print(f'Starting pdoc server on {host}:{port}', file=sys.stderr) httpd = HTTPServer((host, port), _WebDoc) print(f"pdoc server ready at http://{host}:{port}", file=sys.stderr) # Allow tests to perform `pdoc.cli._httpd.shutdown()` global _httpd _httpd = httpd try: httpd.serve_forever() finally: httpd.server_close() sys.exit(0) docfilter = None if args.filter and args.filter.strip(): def docfilter(obj, _filters=args.filter.strip().split(',')): return any(f in obj.refname or isinstance(obj, pdoc.Class) and f in obj.doc for f in _filters) modules = [ pdoc.Module(module, docfilter=docfilter, skip_errors=args.skip_errors) for module in args.modules ] pdoc.link_inheritance() if args.pdf: _print_pdf(modules, **template_config) import textwrap PANDOC_CMD = textwrap.indent(_PANDOC_COMMAND, ' ') print(f""" PDF-ready markdown written to standard output. ^^^^^^^^^^^^^^^ Convert this file to PDF using e.g. Pandoc: {PANDOC_CMD} or using Python-Markdown and Chrome/Chromium/WkHtmlToPDF: markdown_py --extension=meta \\ --extension=abbr \\ --extension=attr_list \\ --extension=def_list \\ --extension=fenced_code \\ --extension=footnotes \\ --extension=tables \\ --extension=admonition \\ --extension=smarty \\ --extension=toc \\ pdf.md > pdf.html chromium --headless --disable-gpu --print-to-pdf=pdf.pdf pdf.html wkhtmltopdf --encoding utf8 -s A4 --print-media-type pdf.html pdf.pdf or similar, at your own discretion.""", file=sys.stderr) sys.exit(0) for module in modules: if args.html: _quit_if_exists(module, ext='.html') recursive_write_files(module, ext='.html', **template_config) elif args.output_dir: # Generate text files _quit_if_exists(module, ext='.md') recursive_write_files(module, ext='.md', **template_config) else: sys.stdout.write(module.text(**template_config)) # Two blank lines between two modules' texts sys.stdout.write(os.linesep * (1 + 2 * int(module != modules[-1]))) lunr_config = pdoc._get_config(**template_config).get('lunr_search') if lunr_config is not None: _generate_lunr_search(modules, lunr_config.get("index_docstrings", True), template_config)
"""scrapli.docs.generate""" import pdoc from pdoc import _render_template, tpl_lookup context = pdoc.Context() module = pdoc.Module("scrapli", context=context) pdoc.link_inheritance(context) tpl_lookup.directories.insert(0, "docs/generate") doc_map = { "scrapli.driver.base.base_driver": {"path": "driver/base/base_driver", "content": None}, "scrapli.driver.base.sync_driver": {"path": "driver/base/sync_driver", "content": None}, "scrapli.driver.base.async_driver": {"path": "driver/base/async_driver", "content": None}, "scrapli.driver.generic.base_driver": {"path": "driver/generic/base_driver", "content": None}, "scrapli.driver.generic.sync_driver": {"path": "driver/generic/sync_driver", "content": None}, "scrapli.driver.generic.async_driver": {"path": "driver/generic/async_driver", "content": None}, "scrapli.driver.network.base_driver": {"path": "driver/network/base_driver", "content": None}, "scrapli.driver.network.sync_driver": {"path": "driver/network/sync_driver", "content": None}, "scrapli.driver.network.async_driver": {"path": "driver/network/async_driver", "content": None}, "scrapli.driver.core.arista_eos.base_driver": { "path": "driver/core/arista_eos/base_driver", "content": None, }, "scrapli.driver.core.arista_eos.sync_driver": { "path": "driver/core/arista_eos/sync_driver", "content": None, }, "scrapli.driver.core.arista_eos.async_driver": { "path": "driver/core/arista_eos/async_driver", "content": None, },
def load_toplevel(toplevel_name): context = pdoc.Context() toplevel = pdoc.Module(toplevel_name, context=context) pdoc.link_inheritance(context) return toplevel