3 # You need to run python2.5 with this, because python2.4 has some weird
4 # Exception hierarchy classes that causes Exceptions to be ignored by this
12 from inspect
import isclass
as _isclass
16 from inspect
import ismethod
as _ismethod
17 if _ismethod(x
) or isinstance(x
, (types
.MethodType
, types
.FunctionType
,
18 types
.UnboundMethodType
)) or str(type(x
)) in [
19 "<type 'classmethod'>", "<type 'staticmethod'>"]:
24 def get_method_name(x
):
25 if hasattr(x
, "__name__"):
27 # This is a static method, don't know how to read the name.
30 def get_method_args(x
):
31 from inspect
import getsource
36 s
= s
[s
.find("("):s
.find(":")]
41 from inspect
import getdoc
as _getdoc
50 def generate_doc(self
, module
, outdir
="/tmp/", importpath
= ""):
52 Takes the "module" string and generates a rst for this module.
54 modules is just the name, like "sympy", i.e. without a path.
57 print "Generating API documentation ... (this may take a while)"
58 sys
.path
.insert(0, importpath
)
59 m
= __import__(module
)
60 self
.main_module
= module
63 for x
in self
.modules
:
64 if x
.startswith(module
):
65 f
= open(outdir
+x
+".txt", "w")
66 f
.write(self
.modules
[x
])
67 print "API generated in %s." % (outdir
)
70 def handle_module(self
, mod
):
72 if mname
in self
.modules
:
73 # we already handled this module
75 self
.modules
[mname
] = ""
77 # if you want to get the top level modules without "sympy.", uncomment
79 #if mname.startswith(self.main_module):
80 # #strip the "sympy.":
81 # s = ".. module:: %s\n\n" % mname[len(self.main_module)+1:]
83 # s = ".. module:: %s\n\n" % mname
85 s
= "=" * len(mname
) + "\n"
87 s
+= "=" * len(mname
) + "\n" + "\n"
89 s
+= ".. module:: %s\n\n" % mname
90 if hasattr(mod
, __file__
):
91 s
+= "filename: %s\n" % mod
.__file
__
92 for x
in mod
.__dict
__.values():
93 if isinstance(x
, types
.ModuleType
):
97 elif isinstance(x
, (int, float, str, list, dict)):
100 elif str(type(x
)) == "<type 'classobj'>":
103 elif hasattr(x
, "__class__"):
104 s
+= self
.handle_class(x
)
106 print " Ignored:", type(x
), x
107 self
.modules
[mod
.__name
__] = s
109 def handle_class(self
, cls
):
110 if hasattr(cls
, "__name__"):
111 s
= "\n.. class:: %s\n" % cls
.__name
__
115 # Uncomment this to generate class docstrings too:
116 # unfortunately, sphinx fails to read them, so we need to fix sympy
123 if hasattr(cls
, "__dict__"):
124 for x
in cls
.__dict
__.values():
125 if isinstance(x
, types
.ModuleType
):
126 self
.handle_module(x
)
127 elif str(type(x
)) == "<type 'classobj'>":
133 s
+= self
.handle_method(x
)
134 elif str(type(x
)) == "<type 'property'>":
136 elif isinstance(x
, (int, float, str, list, tuple, dict)):
139 elif hasattr(x
, "__class__"):
140 # ignore nested classes
143 print " Ignored in class:", type(x
), x
147 def handle_method(self
, m
):
148 mname
= get_method_name(m
)
152 s
= "\n.. method:: %s%s\n\n" % (mname
, get_method_args(m
))
159 Parser().generate_doc("sympy", importpath
= "..", outdir
="api/modules/")