mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-05-14 12:47:22 -04:00
2f14107999
Supply a little default docstring for __init__ Don't document __repr__, __str__, __getstate__, ...
182 lines
6.6 KiB
Python
182 lines
6.6 KiB
Python
"""
|
|
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, include_all_classes=False):
|
|
super(ObjectDoc, self).__init__(obj)
|
|
self.isclass = isinstance(obj, types.ClassType) or isinstance(obj, types.TypeType)
|
|
self.name= obj.__name__
|
|
self.include_all_classes = include_all_classes
|
|
functions = functions
|
|
classes= classes
|
|
|
|
if not self.isclass:
|
|
if not include_all_classes and 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 self._is_private_name(getattr(obj,x).__name__)
|
|
]
|
|
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 (self.include_all_classes or not self._is_private_name(getattr(obj,x).__name__))
|
|
]
|
|
classes = list(set(classes))
|
|
if sort:
|
|
classes.sort(lambda a, b: cmp(a.__name__.replace('_', ''), b.__name__.replace('_', '')))
|
|
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 self._is_private_name(getattr(obj,x).__name__))
|
|
] +
|
|
[(x, getattr(obj, x)) for x in obj.__dict__.keys() if _is_property(getattr(obj,x))
|
|
and
|
|
not self._is_private_name(x)
|
|
]
|
|
)
|
|
functions.sort(_method_sort)
|
|
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:
|
|
for func in functions:
|
|
self.functions.append(FunctionDoc(func))
|
|
else:
|
|
for func in functions:
|
|
if isinstance(func, types.FunctionType):
|
|
self.functions.append(MethodDoc(func, self))
|
|
elif isinstance(func, tuple):
|
|
self.functions.append(PropertyDoc(func[0], func[1]))
|
|
|
|
self.classes = []
|
|
for class_ in classes:
|
|
self.classes.append(ObjectDoc(class_))
|
|
|
|
def _is_private_name(self, name):
|
|
if name in ('__weakref__', '__repr__','__str__', '__unicode__',
|
|
'__getstate__', '__setstate__', '__reduce__',
|
|
'__reduce_ex__', '__hash__'):
|
|
return True
|
|
elif re.match(r'^__.*__$', name):
|
|
return False
|
|
elif name.startswith('_'):
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
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)
|
|
|
|
def _is_property(elem):
|
|
return isinstance(elem, property) or (hasattr(elem, '__get__') and hasattr(elem, '__set__'))
|
|
|
|
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 = func.__name__
|
|
self.link = func.__name__
|
|
self.doc = func.__doc__
|
|
def accept_visitor(self, visitor):
|
|
visitor.visit_function(self)
|
|
|
|
class MethodDoc(FunctionDoc):
|
|
def __init__(self, func, owner):
|
|
super(MethodDoc, self).__init__(func)
|
|
if self.name == '__init__' and not self.doc:
|
|
self.doc = "Construct a new ``%s``." % owner.name
|
|
|
|
class PropertyDoc(AbstractDoc):
|
|
def __init__(self, name, prop):
|
|
super(PropertyDoc, self).__init__(prop)
|
|
self.doc = prop.__doc__
|
|
self.name = name
|
|
self.link = name
|
|
def accept_visitor(self, visitor):
|
|
visitor.visit_property(self)
|
|
|
|
def _method_sort(fna, fnb):
|
|
a = getattr(fna, '__name__', None) or fna[0]
|
|
b = getattr(fnb, '__name__', None) or fnb[0]
|
|
|
|
if a == '__init__': return -1
|
|
if b == '__init__': return 1
|
|
|
|
a_u = a.startswith('__') and a.endswith('__')
|
|
b_u = b.startswith('__') and b.endswith('__')
|
|
|
|
if a_u and not b_u: return 1
|
|
if b_u and not a_u: return -1
|
|
|
|
return cmp(a, b)
|