1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
import re
def autodoc_skip_member(app, what, name, obj, skip, options):
if what == 'class' and skip and \
name in ('__init__', '__eq__', '__ne__', '__lt__',
'__le__', '__call__') and \
obj.__doc__:
return False
else:
return skip
_convert_modname = {
"sqlalchemy.sql.sqltypes": "sqlalchemy.types",
"sqlalchemy.sql.type_api": "sqlalchemy.types",
"sqlalchemy.sql.schema": "sqlalchemy.schema",
"sqlalchemy.sql.elements": "sqlalchemy.sql.expression",
"sqlalchemy.sql.selectable": "sqlalchemy.sql.expression",
"sqlalchemy.sql.dml": "sqlalchemy.sql.expression",
"sqlalchemy.sql.ddl": "sqlalchemy.schema",
"sqlalchemy.sql.base": "sqlalchemy.sql.expression"
}
_convert_modname_w_class = {
("sqlalchemy.engine.interfaces", "Connectable"): "sqlalchemy.engine"
}
def _adjust_rendered_mod_name(modname, objname):
if modname in _convert_modname:
return _convert_modname[modname]
elif (modname, objname) in _convert_modname_w_class:
return _convert_modname_w_class[(modname, objname)]
else:
return modname
# im sure this is in the app somewhere, but I don't really
# know where, so we're doing it here.
_track_autodoced = {}
_inherited_names = set()
def autodoc_process_docstring(app, what, name, obj, options, lines):
if what == "class":
_track_autodoced[name] = obj
# need to translate module names for bases, others
# as we document lots of symbols in namespace modules
# outside of their source
bases = []
for base in obj.__bases__:
if base is not object:
bases.append(":class:`%s.%s`" % (
_adjust_rendered_mod_name(base.__module__, base.__name__),
base.__name__))
if bases:
lines[:0] = [
"Bases: %s" % (", ".join(bases)),
""
]
elif what in ("attribute", "method") and \
options.get("inherited-members"):
m = re.match(r'(.*?)\.([\w_]+)$', name)
if m:
clsname, attrname = m.group(1, 2)
if clsname in _track_autodoced:
cls = _track_autodoced[clsname]
for supercls in cls.__mro__:
if attrname in supercls.__dict__:
break
if supercls is not cls:
_inherited_names.add("%s.%s" % (supercls.__module__, supercls.__name__))
_inherited_names.add("%s.%s.%s" % (supercls.__module__, supercls.__name__, attrname))
lines[:0] = [
".. container:: inherited_member",
"",
" *inherited from the* :%s:`~%s.%s.%s` *%s of* :class:`~%s.%s`" % (
"attr" if what == "attribute"
else "meth",
_adjust_rendered_mod_name(supercls.__module__, supercls.__name__),
supercls.__name__,
attrname,
what,
_adjust_rendered_mod_name(supercls.__module__, supercls.__name__),
supercls.__name__
),
""
]
def missing_reference(app, env, node, contnode):
if node.attributes['reftarget'] in _inherited_names:
return node.children[0]
else:
return None
def setup(app):
app.connect('autodoc-skip-member', autodoc_skip_member)
app.connect('autodoc-process-docstring', autodoc_process_docstring)
app.connect('missing-reference', missing_reference)
|