/usr/share/pyshared/pydoctor/liveobjectchecker.py is in python-pydoctor 0.5b1+bzr603-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | """Extremely experimental code for augmenting pydoctor's data by introspection."""
from pydoctor import model, astbuilder
import types, sys, os, warnings, inspect
def loadModulesForSystem(system):
"""
Return a dictionary mapping model.Modules to real modules.
"""
result = {}
savepath = sys.path[:]
savefilters = warnings.filters[:]
mods = sys.modules.copy()
try:
sys.path[0:0] = [os.path.dirname(p) for p in system.packages]
#print sys.path
warnings.filterwarnings('ignore')
# this list found by the lovely hack of python -E -c "import sys; print sys.modules.keys()"
keeps = ['copy_reg', '__main__', 'site', '__builtin__',
'encodings', 'posixpath', 'encodings.codecs', 'os.path',
'_codecs', 'encodings.exceptions', 'stat', 'zipimport',
'warnings', 'encodings.types', 'UserDict', 'encodings.ascii',
'sys', 'codecs', 'readline', 'types', 'signal', 'linecache',
'posix', 'encodings.aliases', 'exceptions', 'os']
keeps = dict([(k, sys.modules[k]) for k in keeps if k in sys.modules])
sys.modules.clear()
sys.modules.update(keeps)
verbosity = system.options.verbosity
modlist = [system.allobjects[m]
for m in astbuilder.toposort([m.fullName() for m in system.objectsOfType(model.Module)],
system.importgraph)]
errcount = 0
for i, m in enumerate(modlist):
try:
realMod = __import__(m.fullName(), {}, {}, ['*'])
except ImportError, e:
errcount += 1
if verbosity > 0:
print "could not import", m.fullName(), e
except Exception, e:
errcount += 1
if verbosity > 0:
print "error importing", m.fullName(), e
else:
result[m] = realMod
print '\r', i+1-errcount, '/', len(modlist), 'modules imported',
print errcount, 'failed',
sys.stdout.flush()
print
finally:
sys.path[:] = savepath
warnings.filters[:] = savefilters
sys.modules.clear()
sys.modules.update(mods)
return result
_types = {}
def checker(*typs):
def _(func):
for typ in typs:
_types[typ] = func
return func
return _
@checker(types.MethodType)
def methChecker(builder, name, OBJ):
if OBJ.im_self is None:
return
f = builder.pushFunction(name, OBJ.__doc__)
if builder.system.options.verbosity > 0:
print '**meth**', builder.current, '*************'
try:
argspec = inspect.getargspec(OBJ)
if argspec[0]:
del argspec[0][0]
f.argspec = argspec
finally:
builder.popFunction()
@checker(types.TypeType, types.ClassType)
def typeChecker(builder, name, OBJ):
c = builder.current
mod = c
while not isinstance(mod, model.Module):
mod = mod.parent
if getattr(OBJ, '__module__', None) != mod.fullName() or getattr(OBJ, '__name__', None) != name:
return
cls = builder.pushClass(OBJ.__name__, OBJ.__doc__)
if builder.system.options.verbosity > 0:
print '**type**', builder.current, '*************'
try:
for BASE in OBJ.__bases__:
baseName = getattr(BASE, '__name__', '?')
fullName = getattr(BASE, '__module__', '?') + '.' + baseName
if baseName in mod._name2fullname:
cls.rawbases.append(baseName)
else:
cls.rawbases.append(fullName)
cls.bases.append(fullName)
baseObject = builder.system.objForFullName(fullName)
cls.baseobjects.append(baseObject)
if baseObject is not None:
baseObject.subclasses.append(cls)
for cls2 in builder.system.objectsOfType(model.Class):
if cls.fullName() in cls2.bases:
index = cls2.bases.index(cls.fullName())
assert cls2.baseobjects[index] is None
cls2.baseobjects[index] = cls
cls.subclasses.append(cls2)
checkDict(builder, OBJ.__dict__)
finally:
builder.popClass()
@checker(types.FunctionType)
def funcChecker(builder, name, OBJ):
if isinstance(builder.current, model.Class):
cls = builder.current
if name.startswith('_' + cls.name + '__'):
origname = name[len(cls.name) + 1:]
if origname in cls.contents:
return
f = builder.pushFunction(name, OBJ.__doc__)
if builder.system.options.verbosity > 0:
print '**func**', builder.current, '*************'
try:
argspec = inspect.getargspec(OBJ)
f.argspec = argspec
finally:
builder.popFunction()
def checkDict(builder, aDict):
c = builder.current
for name in aDict:
if name in ('__name__', '__doc__', '__file__', '__builtins__', '__module__'):
continue
if name in c.contents:
ob = aDict[name]
o = c.contents[name]
if hasattr(ob, '__dict__') and not isinstance(ob, types.FunctionType):
if builder.system.options.verbosity > 1:
print 'pushing', o
builder.push(o)
checkDict(builder, ob.__dict__)
builder.pop(o)
continue
if name in c._name2fullname:
continue
OBJ = aDict[name]
checker = _types.get(type(OBJ))
if checker is not None:
if builder.system.options.verbosity > 1:
print 'checking', name, 'in', c
checker(builder, name, OBJ)
def liveCheck(system, builder=None):
if builder is None:
builder = system.defaultBuilder(system)
realMods = loadModulesForSystem(system)
for m in realMods:
if builder.system.options.verbosity > 1:
print 'checking', m
builder.push(m)
checkDict(builder, realMods[m].__dict__)
builder.pop(m)
system.state = 'livechecked'
|