This commit is contained in:
enkore 2014-10-12 02:47:49 +02:00
parent b9662d62db
commit 9841cc65f8
4 changed files with 88 additions and 29 deletions

View File

@ -23,10 +23,11 @@ import mock
MOCK_MODULES = [
"alsaaudio",
"netifaces", "psutil",
"lxml", "lxml.html", "lxml.cssselect",
"lxml.html", "lxml.cssselect", "lxml",
"praw",
"gi.repository", "dbus",
"pywapi", "basiciw"
"gi.repository", "dbus.mainloop.glib", "dbus",
"pywapi", "basiciw",
"i3pystatus.pulseaudio.pulse"
]
for mod_name in MOCK_MODULES:

View File

@ -1,10 +1,15 @@
Module reference
================
.. The contents of this file are automatically extended in-memory by
the module_docs extension (see docs/module_docs.py).
Do not change the whitespace after the following directive.
Sincerely, your past self.
.. autogen:: i3pystatus Module
.. note:: List of all modules;
.. note:: List of all modules:
.. _mailbackends:
Mail Backends
-------------
.. autogen:: i3pystatus.mail SettingsBase
.. nothin'

View File

@ -1,9 +1,17 @@
import pkgutil
import importlib
import sphinx.application
from docutils.parsers.rst import Directive
from docutils.nodes import paragraph
from docutils.statemachine import StringList
import i3pystatus.core.settings
import i3pystatus.core.modules
from i3pystatus.core.imputil import ClassFinder
IGNORE_MODULES = ("__main__", "core")
def is_module(obj):
@ -12,7 +20,6 @@ def is_module(obj):
and not obj.__module__.startswith("i3pystatus.core.")
def process_docstring(app, what, name, obj, options, lines):
class Setting:
doc = ""
@ -51,8 +58,7 @@ def process_docstring(app, what, name, obj, options, lines):
return formatted
if is_module(obj):
if is_module(obj) and obj.settings:
lines.append(".. rubric:: Settings")
lines.append("")
@ -65,29 +71,76 @@ def process_signature(app, what, name, obj, options, signature, return_annotatio
return ("", return_annotation)
def source_read(app, docname, source):
ignore_modules = ("__main__", "mkdocs", "core")
def get_modules(path):
modules = []
for finder, modname, is_package in pkgutil.iter_modules(path):
if modname not in IGNORE_MODULES:
modules.append(get_module(finder, modname))
return modules
def get_modules(path):
modules = []
for finder, modname, is_pkg in pkgutil.iter_modules(path):
if modname not in ignore_modules:
modules.append("i3pystatus." + modname)
return modules
if docname == "i3pystatus":
modules = sorted(get_modules(i3pystatus.__path__))
def get_module(finder, modname):
fullname = "i3pystatus.{modname}".format(modname=modname)
return (modname, finder.find_loader(fullname)[0].load_module(fullname))
for mod in modules:
# sphinx seems to discard .append()ed items
source[0] += " * :py:class:`~{}`\n".format(mod)
for mod in modules:
source[0] += (".. automodule:: " + mod + "\n" +
" :members:\n\n")
def get_all(module_path, basecls):
mods = []
finder = ClassFinder(basecls)
for name, module in get_modules(module_path):
classes = finder.get_matching_classes(module)
found = []
for cls in classes:
if cls.__name__ not in found:
found.append(cls.__name__)
mods.append((module.__name__, cls.__name__))
return sorted(mods, key=lambda module: module[0])
def generate_automodules(path, basecls):
modules = get_all(path, basecls)
contents = []
for mod in modules:
contents.append(" * :py:mod:`~{}`".format(mod[0]))
contents.append("")
for mod in modules:
contents.append(".. automodule:: {}".format(mod[0]))
contents.append(" :members: {}\n".format(mod[1]))
return contents
class AutogenDirective(Directive):
required_arguments = 2
has_content = True
def run(self):
# Raise an error if the directive does not have contents.
self.assert_has_content()
modname = self.arguments[0]
modpath = importlib.import_module(modname).__path__
basecls = getattr(i3pystatus.core.modules, self.arguments[1])
contents = []
for e in self.content:
contents.append(e)
contents.append("")
contents.extend(generate_automodules(modpath, basecls))
node = paragraph()
self.state.nested_parse(StringList(contents), 0, node)
return [node]
def setup(app: sphinx.application.Sphinx):
app.connect("source-read", source_read)
app.add_directive("autogen", AutogenDirective)
app.connect("autodoc-process-docstring", process_docstring)
app.connect("autodoc-process-signature", process_signature)

View File

@ -17,7 +17,7 @@ class Mail(IntervalModule):
"""
Generic mail checker
The `backends` setting determines the backends to use.
The `backends` setting determines the backends to use. For available backends see :ref:`mailbackends`
"""
_endstring = """!!i3pystatus.mail!!"""