summaryrefslogtreecommitdiff
path: root/doc/build/lib/docstring.py
blob: b4ddcff4ef3fc5a59189002dfad77356d78ecafb (plain)
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
"""
defines a pickleable, recursive "generated python documentation" datastructure.
"""

import re, types, string, inspect

allobjects = {}

class AbstractDoc(object):
    def __init__(self, obj):
        allobjects[id(obj)] = self
        self.id = id(obj)
        self.allobjects = allobjects
        self.toc_path = None
        
class ObjectDoc(AbstractDoc):
    def __init__(self, obj, functions=None, classes=None):
        super(ObjectDoc, self).__init__(obj)
        self.isclass = isinstance(obj, types.ClassType) or isinstance(obj, types.TypeType)
        self.name= obj.__name__
        functions = functions
        classes= classes
        
        if not self.isclass:
            if hasattr(obj, '__all__'):
                objects = obj.__all__
                sort = True
            else:
                objects = obj.__dict__.keys()
                sort = True
            if functions is None:
                functions = [getattr(obj, x, None) 
                    for x in objects 
                    if getattr(obj,x,None) is not None and 
                        (isinstance(getattr(obj,x), types.FunctionType))
                        and not getattr(obj,x).__name__[0] == '_'
                    ]
                if sort:
                    functions.sort(lambda a, b: cmp(a.__name__, b.__name__))
            if classes is None:
                classes = [getattr(obj, x, None) for x in objects 
                    if getattr(obj,x,None) is not None and 
                        (isinstance(getattr(obj,x), types.TypeType) 
                        or isinstance(getattr(obj,x), types.ClassType))
                        and not getattr(obj,x).__name__[0] == '_'
                    ]
                if sort:
                    classes.sort(lambda a, b: cmp(a.__name__, b.__name__))
        else:
            if functions is None:
                functions = (
                    [getattr(obj, x).im_func for x in obj.__dict__.keys() if isinstance(getattr(obj,x), types.MethodType) 
                    and 
                    (getattr(obj, x).__name__ == '__init__' or not getattr(obj,x).__name__[0] == '_')
                    ] + 
                    [(x, getattr(obj, x)) for x in obj.__dict__.keys() if isinstance(getattr(obj,x), property) 
                    and 
                    not x[0] == '_'
                    ]
                 )
                functions.sort(lambda a, b: cmp(getattr(a, '__name__', None) or a[0], getattr(b, '__name__', None) or b[0] ))
            if classes is None:
                classes = []
        
        if self.isclass:
            self.description = "class " + self.name
            self.classname = self.name
            if hasattr(obj, '__mro__'):
                l = []
                mro = list(obj.__mro__[1:])
                mro.reverse()
                for x in mro:
                    for y in x.__mro__[1:]:
                        if y in l:
                            del l[l.index(y)]
                    l.insert(0, x)
                self.description += "(" + string.join([x.__name__ for x in l], ',') + ")"
                self._inherits = [(id(x), x.__name__) for x in l]
            else:
                self._inherits = []
        else:
            self.description = "module " + self.name

        self.doc = obj.__doc__

        self.functions = []
        if not self.isclass and len(functions):
            for func in functions:
                self.functions.append(FunctionDoc(func))
        else:
            if len(functions):
                for func in functions:
                    if isinstance(func, types.FunctionType):
                        self.functions.append(FunctionDoc(func))
                    elif isinstance(func, tuple):
                        self.functions.append(PropertyDoc(func[0], func[1]))
                        
        self.classes = []
        for class_ in classes:
            self.classes.append(ObjectDoc(class_))
            
    def _get_inherits(self):
        for item in self._inherits:
            if item[0] in self.allobjects:
                yield self.allobjects[item[0]]
            else:
                yield item[1]
    inherits = property(_get_inherits)
    def accept_visitor(self, visitor):
        visitor.visit_object(self)

class FunctionDoc(AbstractDoc):
    def __init__(self, func):
        super(FunctionDoc, self).__init__(func)
        argspec = inspect.getargspec(func)
        argnames = argspec[0]
        varargs = argspec[1]
        varkw = argspec[2]
        defaults = argspec[3] or ()
        argstrings = []
        for i in range(0, len(argnames)):
            if i >= len(argnames) - len(defaults):
                argstrings.append("%s=%s" % (argnames[i], repr(defaults[i - (len(argnames) - len(defaults))])))
            else:
                argstrings.append(argnames[i])
        if varargs is not None:
           argstrings.append("*%s" % varargs)
        if varkw is not None:
           argstrings.append("**%s" % varkw)
        self.argstrings = self.arglist = argstrings
        self.name = "def " + func.__name__
        self.link = func.__name__
        self.doc = func.__doc__
    def accept_visitor(self, visitor):
        visitor.visit_function(self)

class PropertyDoc(AbstractDoc):
    def __init__(self, name, prop):
        super(PropertyDoc, self).__init__(prop)
        self.doc = prop.__doc__
        self.name = name + " = property()"
        self.link = name
    def accept_visitor(self, visitor):
        visitor.visit_property(self)