bee_python 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (503) hide show
  1. data/LICENSE +202 -0
  2. data/build/README +23 -0
  3. data/egg/egg/build.yml +70 -0
  4. data/egg/egg/ez_setup.py +280 -0
  5. data/egg/egg/script.py +12 -0
  6. data/egg/egg/setup.erb +11 -0
  7. data/egg/egg/suite.py +37 -0
  8. data/egg/egg/test.py +31 -0
  9. data/egg/egg.yml +69 -0
  10. data/egg/http/build.erb +53 -0
  11. data/egg/http/server.py +34 -0
  12. data/egg/http.yml +50 -0
  13. data/egg/mysql/mysql.py +43 -0
  14. data/egg/mysql.yml +44 -0
  15. data/egg/project/build.erb +77 -0
  16. data/egg/project/script.py +42 -0
  17. data/egg/project/test.py +31 -0
  18. data/egg/project.yml +59 -0
  19. data/egg/script/build.erb +35 -0
  20. data/egg/script/script.py +42 -0
  21. data/egg/script.yml +50 -0
  22. data/egg/soap/build.erb +52 -0
  23. data/egg/soap/client.py +18 -0
  24. data/egg/soap/server.py +30 -0
  25. data/egg/soap.yml +58 -0
  26. data/egg/source/source.py +42 -0
  27. data/egg/source.yml +47 -0
  28. data/egg/test/test.py +28 -0
  29. data/egg/test.yml +44 -0
  30. data/egg/xmlrpc/build.erb +52 -0
  31. data/egg/xmlrpc/client.py +22 -0
  32. data/egg/xmlrpc/server.py +24 -0
  33. data/egg/xmlrpc.yml +51 -0
  34. data/lib/bee_task_python.rb +390 -0
  35. data/test/build.yml +16 -0
  36. data/test/tc_bee_task_python.rb +27 -0
  37. data/test/test_build.rb +26 -0
  38. data/test/test_build_listener.rb +62 -0
  39. data/test/ts_bee_python.rb +26 -0
  40. data/tools/common/__init__.py +5 -0
  41. data/tools/common/common/__init__.py +140 -0
  42. data/tools/common/common/__pkginfo__.py +43 -0
  43. data/tools/common/common/adbh.py +35 -0
  44. data/tools/common/common/cache.py +114 -0
  45. data/tools/common/common/changelog.py +234 -0
  46. data/tools/common/common/clcommands.py +181 -0
  47. data/tools/common/common/cli.py +212 -0
  48. data/tools/common/common/compat.py +328 -0
  49. data/tools/common/common/configuration.py +1087 -0
  50. data/tools/common/common/contexts.py +58 -0
  51. data/tools/common/common/corbautils.py +117 -0
  52. data/tools/common/common/daemon.py +171 -0
  53. data/tools/common/common/date.py +279 -0
  54. data/tools/common/common/db.py +49 -0
  55. data/tools/common/common/dbf.py +229 -0
  56. data/tools/common/common/debugger.py +208 -0
  57. data/tools/common/common/decorators.py +190 -0
  58. data/tools/common/common/deprecation.py +118 -0
  59. data/tools/common/common/fileutils.py +409 -0
  60. data/tools/common/common/graph.py +259 -0
  61. data/tools/common/common/html.py +142 -0
  62. data/tools/common/common/interface.py +76 -0
  63. data/tools/common/common/logging_ext.py +166 -0
  64. data/tools/common/common/modutils.py +670 -0
  65. data/tools/common/common/optik_ext.py +383 -0
  66. data/tools/common/common/optparser.py +92 -0
  67. data/tools/common/common/pdf_ext.py +111 -0
  68. data/tools/common/common/proc.py +276 -0
  69. data/tools/common/common/pyro_ext.py +146 -0
  70. data/tools/common/common/pytest.py +754 -0
  71. data/tools/common/common/shellutils.py +383 -0
  72. data/tools/common/common/sphinx_ext.py +87 -0
  73. data/tools/common/common/sphinxutils.py +122 -0
  74. data/tools/common/common/sqlgen.py +31 -0
  75. data/tools/common/common/table.py +930 -0
  76. data/tools/common/common/tasksqueue.py +97 -0
  77. data/tools/common/common/test/__init__.py +1 -0
  78. data/tools/common/common/test/data/ChangeLog +184 -0
  79. data/tools/common/common/test/data/MyPyPa-0.1.0-py2.5.egg +0 -0
  80. data/tools/common/common/test/data/__init__.py +1 -0
  81. data/tools/common/common/test/data/content_differ_dir/NOTHING +0 -0
  82. data/tools/common/common/test/data/content_differ_dir/README +1 -0
  83. data/tools/common/common/test/data/content_differ_dir/subdir/coin +1 -0
  84. data/tools/common/common/test/data/content_differ_dir/subdir/toto.txt +53 -0
  85. data/tools/common/common/test/data/file_differ_dir/NOTHING +0 -0
  86. data/tools/common/common/test/data/file_differ_dir/README +1 -0
  87. data/tools/common/common/test/data/file_differ_dir/subdir/toto.txt +53 -0
  88. data/tools/common/common/test/data/file_differ_dir/subdirtwo/Hello +0 -0
  89. data/tools/common/common/test/data/find_test/__init__.py +0 -0
  90. data/tools/common/common/test/data/find_test/foo.txt +0 -0
  91. data/tools/common/common/test/data/find_test/module.py +0 -0
  92. data/tools/common/common/test/data/find_test/module2.py +0 -0
  93. data/tools/common/common/test/data/find_test/newlines.txt +0 -0
  94. data/tools/common/common/test/data/find_test/noendingnewline.py +0 -0
  95. data/tools/common/common/test/data/find_test/nonregr.py +0 -0
  96. data/tools/common/common/test/data/find_test/normal_file.txt +0 -0
  97. data/tools/common/common/test/data/find_test/spam.txt +0 -0
  98. data/tools/common/common/test/data/find_test/sub/doc.txt +0 -0
  99. data/tools/common/common/test/data/find_test/sub/momo.py +0 -0
  100. data/tools/common/common/test/data/find_test/test.ini +0 -0
  101. data/tools/common/common/test/data/find_test/test1.msg +0 -0
  102. data/tools/common/common/test/data/find_test/test2.msg +0 -0
  103. data/tools/common/common/test/data/find_test/write_protected_file.txt +0 -0
  104. data/tools/common/common/test/data/foo.txt +9 -0
  105. data/tools/common/common/test/data/module.py +88 -0
  106. data/tools/common/common/test/data/module2.py +77 -0
  107. data/tools/common/common/test/data/newlines.txt +3 -0
  108. data/tools/common/common/test/data/noendingnewline.py +36 -0
  109. data/tools/common/common/test/data/nonregr.py +14 -0
  110. data/tools/common/common/test/data/normal_file.txt +0 -0
  111. data/tools/common/common/test/data/reference_dir/NOTHING +0 -0
  112. data/tools/common/common/test/data/reference_dir/README +1 -0
  113. data/tools/common/common/test/data/reference_dir/subdir/coin +1 -0
  114. data/tools/common/common/test/data/reference_dir/subdir/toto.txt +53 -0
  115. data/tools/common/common/test/data/same_dir/NOTHING +0 -0
  116. data/tools/common/common/test/data/same_dir/README +1 -0
  117. data/tools/common/common/test/data/same_dir/subdir/coin +1 -0
  118. data/tools/common/common/test/data/same_dir/subdir/toto.txt +53 -0
  119. data/tools/common/common/test/data/spam.txt +9 -0
  120. data/tools/common/common/test/data/sub/doc.txt +1 -0
  121. data/tools/common/common/test/data/sub/momo.py +1 -0
  122. data/tools/common/common/test/data/subdir_differ_dir/NOTHING +0 -0
  123. data/tools/common/common/test/data/subdir_differ_dir/README +1 -0
  124. data/tools/common/common/test/data/subdir_differ_dir/subdir/coin +1 -0
  125. data/tools/common/common/test/data/subdir_differ_dir/subdir/toto.txt +53 -0
  126. data/tools/common/common/test/data/test.ini +20 -0
  127. data/tools/common/common/test/data/test1.msg +30 -0
  128. data/tools/common/common/test/data/test2.msg +42 -0
  129. data/tools/common/common/test/data/write_protected_file.txt +0 -0
  130. data/tools/common/common/test/foomod.py +17 -0
  131. data/tools/common/common/test/unittest_cache.py +129 -0
  132. data/tools/common/common/test/unittest_changelog.py +37 -0
  133. data/tools/common/common/test/unittest_compat.py +239 -0
  134. data/tools/common/common/test/unittest_configuration.py +348 -0
  135. data/tools/common/common/test/unittest_date.py +154 -0
  136. data/tools/common/common/test/unittest_decorators.py +62 -0
  137. data/tools/common/common/test/unittest_deprecation.py +76 -0
  138. data/tools/common/common/test/unittest_fileutils.py +133 -0
  139. data/tools/common/common/test/unittest_graph.py +50 -0
  140. data/tools/common/common/test/unittest_html.py +76 -0
  141. data/tools/common/common/test/unittest_interface.py +87 -0
  142. data/tools/common/common/test/unittest_modutils.py +244 -0
  143. data/tools/common/common/test/unittest_pytest.py +50 -0
  144. data/tools/common/common/test/unittest_shellutils.py +248 -0
  145. data/tools/common/common/test/unittest_table.py +448 -0
  146. data/tools/common/common/test/unittest_taskqueue.py +71 -0
  147. data/tools/common/common/test/unittest_testlib.py +956 -0
  148. data/tools/common/common/test/unittest_textutils.py +247 -0
  149. data/tools/common/common/test/unittest_tree.py +248 -0
  150. data/tools/common/common/test/unittest_umessage.py +55 -0
  151. data/tools/common/common/test/unittest_ureports_html.py +64 -0
  152. data/tools/common/common/test/unittest_ureports_text.py +105 -0
  153. data/tools/common/common/test/unittest_xmlutils.py +75 -0
  154. data/tools/common/common/test/utils.py +87 -0
  155. data/tools/common/common/testlib.py +1927 -0
  156. data/tools/common/common/textutils.py +476 -0
  157. data/tools/common/common/tree.py +372 -0
  158. data/tools/common/common/umessage.py +161 -0
  159. data/tools/common/common/ureports/__init__.py +174 -0
  160. data/tools/common/common/ureports/docbook_writer.py +139 -0
  161. data/tools/common/common/ureports/html_writer.py +131 -0
  162. data/tools/common/common/ureports/nodes.py +201 -0
  163. data/tools/common/common/ureports/text_writer.py +140 -0
  164. data/tools/common/common/vcgutils.py +216 -0
  165. data/tools/common/common/visitor.py +107 -0
  166. data/tools/common/common/xmlrpcutils.py +136 -0
  167. data/tools/common/common/xmlutils.py +61 -0
  168. data/tools/compile/compile.py +16 -0
  169. data/tools/coverage/coverage.py +602 -0
  170. data/tools/epydoc/__init__.py +227 -0
  171. data/tools/epydoc/__init__.pyc +0 -0
  172. data/tools/epydoc/apidoc.py +2203 -0
  173. data/tools/epydoc/apidoc.pyc +0 -0
  174. data/tools/epydoc/checker.py +349 -0
  175. data/tools/epydoc/checker.pyc +0 -0
  176. data/tools/epydoc/cli.py +1470 -0
  177. data/tools/epydoc/cli.pyc +0 -0
  178. data/tools/epydoc/compat.py +250 -0
  179. data/tools/epydoc/compat.pyc +0 -0
  180. data/tools/epydoc/docbuilder.py +1358 -0
  181. data/tools/epydoc/docbuilder.pyc +0 -0
  182. data/tools/epydoc/docintrospecter.py +1056 -0
  183. data/tools/epydoc/docintrospecter.pyc +0 -0
  184. data/tools/epydoc/docparser.py +2113 -0
  185. data/tools/epydoc/docparser.pyc +0 -0
  186. data/tools/epydoc/docstringparser.py +1111 -0
  187. data/tools/epydoc/docstringparser.pyc +0 -0
  188. data/tools/epydoc/docwriter/__init__.py +12 -0
  189. data/tools/epydoc/docwriter/__init__.pyc +0 -0
  190. data/tools/epydoc/docwriter/dotgraph.py +1351 -0
  191. data/tools/epydoc/docwriter/dotgraph.pyc +0 -0
  192. data/tools/epydoc/docwriter/html.py +3491 -0
  193. data/tools/epydoc/docwriter/html.pyc +0 -0
  194. data/tools/epydoc/docwriter/html_colorize.py +909 -0
  195. data/tools/epydoc/docwriter/html_colorize.pyc +0 -0
  196. data/tools/epydoc/docwriter/html_css.py +550 -0
  197. data/tools/epydoc/docwriter/html_css.pyc +0 -0
  198. data/tools/epydoc/docwriter/html_help.py +190 -0
  199. data/tools/epydoc/docwriter/html_help.pyc +0 -0
  200. data/tools/epydoc/docwriter/latex.py +1187 -0
  201. data/tools/epydoc/docwriter/latex.pyc +0 -0
  202. data/tools/epydoc/docwriter/plaintext.py +276 -0
  203. data/tools/epydoc/docwriter/plaintext.pyc +0 -0
  204. data/tools/epydoc/docwriter/xlink.py +505 -0
  205. data/tools/epydoc/docwriter/xlink.pyc +0 -0
  206. data/tools/epydoc/gui.py +1148 -0
  207. data/tools/epydoc/gui.pyc +0 -0
  208. data/tools/epydoc/log.py +204 -0
  209. data/tools/epydoc/log.pyc +0 -0
  210. data/tools/epydoc/markup/__init__.py +623 -0
  211. data/tools/epydoc/markup/__init__.pyc +0 -0
  212. data/tools/epydoc/markup/doctest.py +311 -0
  213. data/tools/epydoc/markup/doctest.pyc +0 -0
  214. data/tools/epydoc/markup/epytext.py +2116 -0
  215. data/tools/epydoc/markup/epytext.pyc +0 -0
  216. data/tools/epydoc/markup/javadoc.py +250 -0
  217. data/tools/epydoc/markup/javadoc.pyc +0 -0
  218. data/tools/epydoc/markup/plaintext.py +78 -0
  219. data/tools/epydoc/markup/plaintext.pyc +0 -0
  220. data/tools/epydoc/markup/pyval_repr.py +532 -0
  221. data/tools/epydoc/markup/pyval_repr.pyc +0 -0
  222. data/tools/epydoc/markup/restructuredtext.py +906 -0
  223. data/tools/epydoc/markup/restructuredtext.pyc +0 -0
  224. data/tools/epydoc/test/__init__.py +97 -0
  225. data/tools/epydoc/test/__init__.pyc +0 -0
  226. data/tools/epydoc/test/util.py +226 -0
  227. data/tools/epydoc/test/util.pyc +0 -0
  228. data/tools/epydoc/util.py +289 -0
  229. data/tools/epydoc/util.pyc +0 -0
  230. data/tools/logilab/logilab/__init__.py +5 -0
  231. data/tools/logilab/logilab/astng/__init__.py +82 -0
  232. data/tools/logilab/logilab/astng/__pkginfo__.py +76 -0
  233. data/tools/logilab/logilab/astng/_exceptions.py +64 -0
  234. data/tools/logilab/logilab/astng/_nodes_ast.py +667 -0
  235. data/tools/logilab/logilab/astng/_nodes_compiler.py +758 -0
  236. data/tools/logilab/logilab/astng/bases.py +608 -0
  237. data/tools/logilab/logilab/astng/builder.py +239 -0
  238. data/tools/logilab/logilab/astng/inference.py +426 -0
  239. data/tools/logilab/logilab/astng/inspector.py +289 -0
  240. data/tools/logilab/logilab/astng/manager.py +421 -0
  241. data/tools/logilab/logilab/astng/mixins.py +165 -0
  242. data/tools/logilab/logilab/astng/node_classes.py +848 -0
  243. data/tools/logilab/logilab/astng/nodes.py +85 -0
  244. data/tools/logilab/logilab/astng/nodes_as_string.py +389 -0
  245. data/tools/logilab/logilab/astng/patchcomptransformer.py +159 -0
  246. data/tools/logilab/logilab/astng/protocols.py +333 -0
  247. data/tools/logilab/logilab/astng/raw_building.py +212 -0
  248. data/tools/logilab/logilab/astng/rebuilder.py +307 -0
  249. data/tools/logilab/logilab/astng/scoped_nodes.py +951 -0
  250. data/tools/logilab/logilab/astng/test/__init__.py +19 -0
  251. data/tools/logilab/logilab/astng/test/data/MyPyPa-0.1.0-py2.5.egg +0 -0
  252. data/tools/logilab/logilab/astng/test/data/MyPyPa-0.1.0-py2.5.zip +0 -0
  253. data/tools/logilab/logilab/astng/test/data/SSL1/Connection1.py +33 -0
  254. data/tools/logilab/logilab/astng/test/data/SSL1/__init__.py +20 -0
  255. data/tools/logilab/logilab/astng/test/data/__init__.py +20 -0
  256. data/tools/logilab/logilab/astng/test/data/all.py +29 -0
  257. data/tools/logilab/logilab/astng/test/data/appl/__init__.py +23 -0
  258. data/tools/logilab/logilab/astng/test/data/appl/myConnection.py +30 -0
  259. data/tools/logilab/logilab/astng/test/data/format.py +34 -0
  260. data/tools/logilab/logilab/astng/test/data/module.py +90 -0
  261. data/tools/logilab/logilab/astng/test/data/module2.py +112 -0
  262. data/tools/logilab/logilab/astng/test/data/noendingnewline.py +57 -0
  263. data/tools/logilab/logilab/astng/test/data/nonregr.py +76 -0
  264. data/tools/logilab/logilab/astng/test/data/notall.py +28 -0
  265. data/tools/logilab/logilab/astng/test/data2/__init__.py +20 -0
  266. data/tools/logilab/logilab/astng/test/data2/clientmodule_test.py +51 -0
  267. data/tools/logilab/logilab/astng/test/data2/suppliermodule_test.py +32 -0
  268. data/tools/logilab/logilab/astng/test/regrtest.py +135 -0
  269. data/tools/logilab/logilab/astng/test/regrtest_data/absimport.py +22 -0
  270. data/tools/logilab/logilab/astng/test/regrtest_data/descriptor_crash.py +31 -0
  271. data/tools/logilab/logilab/astng/test/regrtest_data/import_package_subpackage_module.py +68 -0
  272. data/tools/logilab/logilab/astng/test/regrtest_data/package/__init__.py +24 -0
  273. data/tools/logilab/logilab/astng/test/regrtest_data/package/subpackage/__init__.py +20 -0
  274. data/tools/logilab/logilab/astng/test/regrtest_data/package/subpackage/module.py +20 -0
  275. data/tools/logilab/logilab/astng/test/unittest_builder.py +684 -0
  276. data/tools/logilab/logilab/astng/test/unittest_inference.py +1112 -0
  277. data/tools/logilab/logilab/astng/test/unittest_inspector.py +105 -0
  278. data/tools/logilab/logilab/astng/test/unittest_lookup.py +302 -0
  279. data/tools/logilab/logilab/astng/test/unittest_manager.py +98 -0
  280. data/tools/logilab/logilab/astng/test/unittest_nodes.py +302 -0
  281. data/tools/logilab/logilab/astng/test/unittest_scoped_nodes.py +501 -0
  282. data/tools/logilab/logilab/astng/test/unittest_utils.py +104 -0
  283. data/tools/logilab/logilab/astng/utils.py +342 -0
  284. data/tools/logilab/logilab/common/__init__.py +140 -0
  285. data/tools/logilab/logilab/common/__pkginfo__.py +43 -0
  286. data/tools/logilab/logilab/common/adbh.py +35 -0
  287. data/tools/logilab/logilab/common/cache.py +114 -0
  288. data/tools/logilab/logilab/common/changelog.py +234 -0
  289. data/tools/logilab/logilab/common/clcommands.py +181 -0
  290. data/tools/logilab/logilab/common/cli.py +212 -0
  291. data/tools/logilab/logilab/common/compat.py +328 -0
  292. data/tools/logilab/logilab/common/configuration.py +1087 -0
  293. data/tools/logilab/logilab/common/contexts.py +58 -0
  294. data/tools/logilab/logilab/common/corbautils.py +117 -0
  295. data/tools/logilab/logilab/common/daemon.py +171 -0
  296. data/tools/logilab/logilab/common/date.py +279 -0
  297. data/tools/logilab/logilab/common/db.py +49 -0
  298. data/tools/logilab/logilab/common/dbf.py +229 -0
  299. data/tools/logilab/logilab/common/debugger.py +208 -0
  300. data/tools/logilab/logilab/common/decorators.py +190 -0
  301. data/tools/logilab/logilab/common/deprecation.py +118 -0
  302. data/tools/logilab/logilab/common/fileutils.py +409 -0
  303. data/tools/logilab/logilab/common/graph.py +259 -0
  304. data/tools/logilab/logilab/common/html.py +142 -0
  305. data/tools/logilab/logilab/common/interface.py +76 -0
  306. data/tools/logilab/logilab/common/logging_ext.py +166 -0
  307. data/tools/logilab/logilab/common/modutils.py +670 -0
  308. data/tools/logilab/logilab/common/optik_ext.py +383 -0
  309. data/tools/logilab/logilab/common/optparser.py +92 -0
  310. data/tools/logilab/logilab/common/pdf_ext.py +111 -0
  311. data/tools/logilab/logilab/common/proc.py +276 -0
  312. data/tools/logilab/logilab/common/pyro_ext.py +146 -0
  313. data/tools/logilab/logilab/common/pytest.py +754 -0
  314. data/tools/logilab/logilab/common/shellutils.py +383 -0
  315. data/tools/logilab/logilab/common/sphinx_ext.py +87 -0
  316. data/tools/logilab/logilab/common/sphinxutils.py +122 -0
  317. data/tools/logilab/logilab/common/sqlgen.py +31 -0
  318. data/tools/logilab/logilab/common/table.py +930 -0
  319. data/tools/logilab/logilab/common/tasksqueue.py +97 -0
  320. data/tools/logilab/logilab/common/test/__init__.py +1 -0
  321. data/tools/logilab/logilab/common/test/data/ChangeLog +184 -0
  322. data/tools/logilab/logilab/common/test/data/MyPyPa-0.1.0-py2.5.egg +0 -0
  323. data/tools/logilab/logilab/common/test/data/__init__.py +1 -0
  324. data/tools/logilab/logilab/common/test/data/content_differ_dir/NOTHING +0 -0
  325. data/tools/logilab/logilab/common/test/data/content_differ_dir/README +1 -0
  326. data/tools/logilab/logilab/common/test/data/content_differ_dir/subdir/coin +1 -0
  327. data/tools/logilab/logilab/common/test/data/content_differ_dir/subdir/toto.txt +53 -0
  328. data/tools/logilab/logilab/common/test/data/file_differ_dir/NOTHING +0 -0
  329. data/tools/logilab/logilab/common/test/data/file_differ_dir/README +1 -0
  330. data/tools/logilab/logilab/common/test/data/file_differ_dir/subdir/toto.txt +53 -0
  331. data/tools/logilab/logilab/common/test/data/file_differ_dir/subdirtwo/Hello +0 -0
  332. data/tools/logilab/logilab/common/test/data/find_test/__init__.py +0 -0
  333. data/tools/logilab/logilab/common/test/data/find_test/foo.txt +0 -0
  334. data/tools/logilab/logilab/common/test/data/find_test/module.py +0 -0
  335. data/tools/logilab/logilab/common/test/data/find_test/module2.py +0 -0
  336. data/tools/logilab/logilab/common/test/data/find_test/newlines.txt +0 -0
  337. data/tools/logilab/logilab/common/test/data/find_test/noendingnewline.py +0 -0
  338. data/tools/logilab/logilab/common/test/data/find_test/nonregr.py +0 -0
  339. data/tools/logilab/logilab/common/test/data/find_test/normal_file.txt +0 -0
  340. data/tools/logilab/logilab/common/test/data/find_test/spam.txt +0 -0
  341. data/tools/logilab/logilab/common/test/data/find_test/sub/doc.txt +0 -0
  342. data/tools/logilab/logilab/common/test/data/find_test/sub/momo.py +0 -0
  343. data/tools/logilab/logilab/common/test/data/find_test/test.ini +0 -0
  344. data/tools/logilab/logilab/common/test/data/find_test/test1.msg +0 -0
  345. data/tools/logilab/logilab/common/test/data/find_test/test2.msg +0 -0
  346. data/tools/logilab/logilab/common/test/data/find_test/write_protected_file.txt +0 -0
  347. data/tools/logilab/logilab/common/test/data/foo.txt +9 -0
  348. data/tools/logilab/logilab/common/test/data/module.py +88 -0
  349. data/tools/logilab/logilab/common/test/data/module2.py +77 -0
  350. data/tools/logilab/logilab/common/test/data/newlines.txt +3 -0
  351. data/tools/logilab/logilab/common/test/data/noendingnewline.py +36 -0
  352. data/tools/logilab/logilab/common/test/data/nonregr.py +14 -0
  353. data/tools/logilab/logilab/common/test/data/normal_file.txt +0 -0
  354. data/tools/logilab/logilab/common/test/data/reference_dir/NOTHING +0 -0
  355. data/tools/logilab/logilab/common/test/data/reference_dir/README +1 -0
  356. data/tools/logilab/logilab/common/test/data/reference_dir/subdir/coin +1 -0
  357. data/tools/logilab/logilab/common/test/data/reference_dir/subdir/toto.txt +53 -0
  358. data/tools/logilab/logilab/common/test/data/same_dir/NOTHING +0 -0
  359. data/tools/logilab/logilab/common/test/data/same_dir/README +1 -0
  360. data/tools/logilab/logilab/common/test/data/same_dir/subdir/coin +1 -0
  361. data/tools/logilab/logilab/common/test/data/same_dir/subdir/toto.txt +53 -0
  362. data/tools/logilab/logilab/common/test/data/spam.txt +9 -0
  363. data/tools/logilab/logilab/common/test/data/sub/doc.txt +1 -0
  364. data/tools/logilab/logilab/common/test/data/sub/momo.py +1 -0
  365. data/tools/logilab/logilab/common/test/data/subdir_differ_dir/NOTHING +0 -0
  366. data/tools/logilab/logilab/common/test/data/subdir_differ_dir/README +1 -0
  367. data/tools/logilab/logilab/common/test/data/subdir_differ_dir/subdir/coin +1 -0
  368. data/tools/logilab/logilab/common/test/data/subdir_differ_dir/subdir/toto.txt +53 -0
  369. data/tools/logilab/logilab/common/test/data/test.ini +20 -0
  370. data/tools/logilab/logilab/common/test/data/test1.msg +30 -0
  371. data/tools/logilab/logilab/common/test/data/test2.msg +42 -0
  372. data/tools/logilab/logilab/common/test/data/write_protected_file.txt +0 -0
  373. data/tools/logilab/logilab/common/test/foomod.py +17 -0
  374. data/tools/logilab/logilab/common/test/unittest_cache.py +129 -0
  375. data/tools/logilab/logilab/common/test/unittest_changelog.py +37 -0
  376. data/tools/logilab/logilab/common/test/unittest_compat.py +239 -0
  377. data/tools/logilab/logilab/common/test/unittest_configuration.py +348 -0
  378. data/tools/logilab/logilab/common/test/unittest_date.py +154 -0
  379. data/tools/logilab/logilab/common/test/unittest_decorators.py +62 -0
  380. data/tools/logilab/logilab/common/test/unittest_deprecation.py +76 -0
  381. data/tools/logilab/logilab/common/test/unittest_fileutils.py +133 -0
  382. data/tools/logilab/logilab/common/test/unittest_graph.py +50 -0
  383. data/tools/logilab/logilab/common/test/unittest_html.py +76 -0
  384. data/tools/logilab/logilab/common/test/unittest_interface.py +87 -0
  385. data/tools/logilab/logilab/common/test/unittest_modutils.py +244 -0
  386. data/tools/logilab/logilab/common/test/unittest_pytest.py +50 -0
  387. data/tools/logilab/logilab/common/test/unittest_shellutils.py +248 -0
  388. data/tools/logilab/logilab/common/test/unittest_table.py +448 -0
  389. data/tools/logilab/logilab/common/test/unittest_taskqueue.py +71 -0
  390. data/tools/logilab/logilab/common/test/unittest_testlib.py +956 -0
  391. data/tools/logilab/logilab/common/test/unittest_textutils.py +247 -0
  392. data/tools/logilab/logilab/common/test/unittest_tree.py +248 -0
  393. data/tools/logilab/logilab/common/test/unittest_umessage.py +55 -0
  394. data/tools/logilab/logilab/common/test/unittest_ureports_html.py +64 -0
  395. data/tools/logilab/logilab/common/test/unittest_ureports_text.py +105 -0
  396. data/tools/logilab/logilab/common/test/unittest_xmlutils.py +75 -0
  397. data/tools/logilab/logilab/common/test/utils.py +87 -0
  398. data/tools/logilab/logilab/common/testlib.py +1927 -0
  399. data/tools/logilab/logilab/common/textutils.py +476 -0
  400. data/tools/logilab/logilab/common/tree.py +372 -0
  401. data/tools/logilab/logilab/common/umessage.py +161 -0
  402. data/tools/logilab/logilab/common/ureports/__init__.py +174 -0
  403. data/tools/logilab/logilab/common/ureports/docbook_writer.py +139 -0
  404. data/tools/logilab/logilab/common/ureports/html_writer.py +131 -0
  405. data/tools/logilab/logilab/common/ureports/nodes.py +201 -0
  406. data/tools/logilab/logilab/common/ureports/text_writer.py +140 -0
  407. data/tools/logilab/logilab/common/vcgutils.py +216 -0
  408. data/tools/logilab/logilab/common/visitor.py +107 -0
  409. data/tools/logilab/logilab/common/xmlrpcutils.py +136 -0
  410. data/tools/logilab/logilab/common/xmlutils.py +61 -0
  411. data/tools/pychecker/COPYRIGHT +31 -0
  412. data/tools/pychecker/ChangeLog +349 -0
  413. data/tools/pychecker/CodeChecks.py +1969 -0
  414. data/tools/pychecker/CodeChecks.pyc +0 -0
  415. data/tools/pychecker/CodeChecks.pyo +0 -0
  416. data/tools/pychecker/Config.py +475 -0
  417. data/tools/pychecker/Config.pyc +0 -0
  418. data/tools/pychecker/Config.pyo +0 -0
  419. data/tools/pychecker/KNOWN_BUGS +100 -0
  420. data/tools/pychecker/MAINTAINERS +81 -0
  421. data/tools/pychecker/NEWS +406 -0
  422. data/tools/pychecker/OP.py +131 -0
  423. data/tools/pychecker/OP.pyc +0 -0
  424. data/tools/pychecker/OP.pyo +0 -0
  425. data/tools/pychecker/OptionTypes.py +117 -0
  426. data/tools/pychecker/OptionTypes.pyc +0 -0
  427. data/tools/pychecker/OptionTypes.pyo +0 -0
  428. data/tools/pychecker/README +152 -0
  429. data/tools/pychecker/Stack.py +115 -0
  430. data/tools/pychecker/Stack.pyc +0 -0
  431. data/tools/pychecker/Stack.pyo +0 -0
  432. data/tools/pychecker/TODO +101 -0
  433. data/tools/pychecker/VERSION +1 -0
  434. data/tools/pychecker/Warning.py +50 -0
  435. data/tools/pychecker/Warning.pyc +0 -0
  436. data/tools/pychecker/Warning.pyo +0 -0
  437. data/tools/pychecker/__init__.py +17 -0
  438. data/tools/pychecker/__init__.pyc +0 -0
  439. data/tools/pychecker/__init__.pyo +0 -0
  440. data/tools/pychecker/checker.py +961 -0
  441. data/tools/pychecker/checker.pyc +0 -0
  442. data/tools/pychecker/checker.pyo +0 -0
  443. data/tools/pychecker/function.py +159 -0
  444. data/tools/pychecker/function.pyc +0 -0
  445. data/tools/pychecker/function.pyo +0 -0
  446. data/tools/pychecker/msgs.py +175 -0
  447. data/tools/pychecker/msgs.pyc +0 -0
  448. data/tools/pychecker/msgs.pyo +0 -0
  449. data/tools/pychecker/options.py +275 -0
  450. data/tools/pychecker/options.pyc +0 -0
  451. data/tools/pychecker/options.pyo +0 -0
  452. data/tools/pychecker/pcmodules.py +19 -0
  453. data/tools/pychecker/pcmodules.pyc +0 -0
  454. data/tools/pychecker/pcmodules.pyo +0 -0
  455. data/tools/pychecker/printer.py +47 -0
  456. data/tools/pychecker/printer.pyc +0 -0
  457. data/tools/pychecker/printer.pyo +0 -0
  458. data/tools/pychecker/python.py +427 -0
  459. data/tools/pychecker/python.pyc +0 -0
  460. data/tools/pychecker/python.pyo +0 -0
  461. data/tools/pychecker/utils.py +102 -0
  462. data/tools/pychecker/utils.pyc +0 -0
  463. data/tools/pychecker/utils.pyo +0 -0
  464. data/tools/pychecker/warn.py +778 -0
  465. data/tools/pychecker/warn.pyc +0 -0
  466. data/tools/pychecker/warn.pyo +0 -0
  467. data/tools/pylint2/pylint/__init__.py +16 -0
  468. data/tools/pylint2/pylint/__pkginfo__.py +67 -0
  469. data/tools/pylint2/pylint/checkers/__init__.py +155 -0
  470. data/tools/pylint2/pylint/checkers/base.py +749 -0
  471. data/tools/pylint2/pylint/checkers/classes.py +527 -0
  472. data/tools/pylint2/pylint/checkers/design_analysis.py +344 -0
  473. data/tools/pylint2/pylint/checkers/exceptions.py +183 -0
  474. data/tools/pylint2/pylint/checkers/format.py +367 -0
  475. data/tools/pylint2/pylint/checkers/imports.py +379 -0
  476. data/tools/pylint2/pylint/checkers/logging.py +98 -0
  477. data/tools/pylint2/pylint/checkers/misc.py +128 -0
  478. data/tools/pylint2/pylint/checkers/newstyle.py +107 -0
  479. data/tools/pylint2/pylint/checkers/raw_metrics.py +125 -0
  480. data/tools/pylint2/pylint/checkers/similar.py +333 -0
  481. data/tools/pylint2/pylint/checkers/string_format.py +239 -0
  482. data/tools/pylint2/pylint/checkers/typecheck.py +364 -0
  483. data/tools/pylint2/pylint/checkers/utils.py +208 -0
  484. data/tools/pylint2/pylint/checkers/variables.py +498 -0
  485. data/tools/pylint2/pylint/config.py +149 -0
  486. data/tools/pylint2/pylint/epylint.py +149 -0
  487. data/tools/pylint2/pylint/gui.py +433 -0
  488. data/tools/pylint2/pylint/interfaces.py +98 -0
  489. data/tools/pylint2/pylint/lint.py +914 -0
  490. data/tools/pylint2/pylint/pyreverse/__init__.py +5 -0
  491. data/tools/pylint2/pylint/pyreverse/diadefslib.py +229 -0
  492. data/tools/pylint2/pylint/pyreverse/diagrams.py +247 -0
  493. data/tools/pylint2/pylint/pyreverse/main.py +123 -0
  494. data/tools/pylint2/pylint/pyreverse/utils.py +131 -0
  495. data/tools/pylint2/pylint/pyreverse/writer.py +196 -0
  496. data/tools/pylint2/pylint/reporters/__init__.py +67 -0
  497. data/tools/pylint2/pylint/reporters/guireporter.py +36 -0
  498. data/tools/pylint2/pylint/reporters/html.py +69 -0
  499. data/tools/pylint2/pylint/reporters/text.py +156 -0
  500. data/tools/pylint2/pylint/utils.py +518 -0
  501. data/tools/pylint2/pylint.py +16 -0
  502. data/tools/test/suite.py +35 -0
  503. metadata +566 -0
@@ -0,0 +1,2203 @@
1
+ # epydoc -- API Documentation Classes
2
+ #
3
+ # Copyright (C) 2005 Edward Loper
4
+ # Author: Edward Loper <edloper@loper.org>
5
+ # URL: <http://epydoc.sf.net>
6
+ #
7
+ # $Id: apidoc.py,v 1.1 2009/11/26 13:20:35 casa Exp $
8
+
9
+ """
10
+ Classes for encoding API documentation about Python programs.
11
+ These classes are used as a common representation for combining
12
+ information derived from introspection and from parsing.
13
+
14
+ The API documentation for a Python program is encoded using a graph of
15
+ L{APIDoc} objects, each of which encodes information about a single
16
+ Python variable or value. C{APIDoc} has two direct subclasses:
17
+ L{VariableDoc}, for documenting variables; and L{ValueDoc}, for
18
+ documenting values. The C{ValueDoc} class is subclassed further, to
19
+ define the different pieces of information that should be recorded
20
+ about each value type:
21
+
22
+ G{classtree: APIDoc}
23
+
24
+ The distinction between variables and values is intentionally made
25
+ explicit. This allows us to distinguish information about a variable
26
+ itself (such as whether it should be considered 'public' in its
27
+ containing namespace) from information about the value it contains
28
+ (such as what type the value has). This distinction is also important
29
+ because several variables can contain the same value: each variable
30
+ should be described by a separate C{VariableDoc}; but we only need one
31
+ C{ValueDoc}, since they share a single value.
32
+
33
+ @todo: Add a cache to canonical name lookup?
34
+ """
35
+ __docformat__ = 'epytext en'
36
+
37
+ ######################################################################
38
+ ## Imports
39
+ ######################################################################
40
+
41
+ import types, re, os.path, pickle
42
+ from epydoc import log
43
+ import epydoc
44
+ import __builtin__
45
+ from epydoc.compat import * # Backwards compatibility
46
+ from epydoc.util import decode_with_backslashreplace, py_src_filename
47
+ import epydoc.markup.pyval_repr
48
+
49
+ ######################################################################
50
+ # Dotted Names
51
+ ######################################################################
52
+
53
+ class DottedName:
54
+ """
55
+ A sequence of identifiers, separated by periods, used to name a
56
+ Python variable, value, or argument. The identifiers that make up
57
+ a dotted name can be accessed using the indexing operator:
58
+
59
+ >>> name = DottedName('epydoc', 'api_doc', 'DottedName')
60
+ >>> print name
61
+ epydoc.apidoc.DottedName
62
+ >>> name[1]
63
+ 'api_doc'
64
+ """
65
+ UNREACHABLE = "??"
66
+ _IDENTIFIER_RE = re.compile("""(?x)
67
+ (%s | # UNREACHABLE marker, or..
68
+ (script-)? # Prefix: script (not a module)
69
+ \w+ # Identifier (yes, identifiers starting with a
70
+ # digit are allowed. See SF bug #1649347)
71
+ '?) # Suffix: submodule that is shadowed by a var
72
+ (-\d+)? # Suffix: unreachable vals with the same name
73
+ $"""
74
+ % re.escape(UNREACHABLE))
75
+
76
+ class InvalidDottedName(ValueError):
77
+ """
78
+ An exception raised by the DottedName constructor when one of
79
+ its arguments is not a valid dotted name.
80
+ """
81
+
82
+ _ok_identifiers = set()
83
+ """A cache of identifier strings that have been checked against
84
+ _IDENTIFIER_RE and found to be acceptable."""
85
+
86
+ def __init__(self, *pieces, **options):
87
+ """
88
+ Construct a new dotted name from the given sequence of pieces,
89
+ each of which can be either a C{string} or a C{DottedName}.
90
+ Each piece is divided into a sequence of identifiers, and
91
+ these sequences are combined together (in order) to form the
92
+ identifier sequence for the new C{DottedName}. If a piece
93
+ contains a string, then it is divided into substrings by
94
+ splitting on periods, and each substring is checked to see if
95
+ it is a valid identifier.
96
+
97
+ As an optimization, C{pieces} may also contain a single tuple
98
+ of values. In that case, that tuple will be used as the
99
+ C{DottedName}'s identifiers; it will I{not} be checked to
100
+ see if it's valid.
101
+
102
+ @kwparam strict: if true, then raise an L{InvalidDottedName}
103
+ if the given name is invalid.
104
+ """
105
+ if len(pieces) == 1 and isinstance(pieces[0], tuple):
106
+ self._identifiers = pieces[0] # Optimization
107
+ return
108
+ if len(pieces) == 0:
109
+ raise DottedName.InvalidDottedName('Empty DottedName')
110
+ self._identifiers = []
111
+ for piece in pieces:
112
+ if isinstance(piece, DottedName):
113
+ self._identifiers += piece._identifiers
114
+ elif isinstance(piece, basestring):
115
+ for subpiece in piece.split('.'):
116
+ if piece not in self._ok_identifiers:
117
+ if not self._IDENTIFIER_RE.match(subpiece):
118
+ if options.get('strict'):
119
+ raise DottedName.InvalidDottedName(
120
+ 'Bad identifier %r' % (piece,))
121
+ else:
122
+ log.warning("Identifier %r looks suspicious; "
123
+ "using it anyway." % piece)
124
+ self._ok_identifiers.add(piece)
125
+ self._identifiers.append(subpiece)
126
+ else:
127
+ raise TypeError('Bad identifier %r: expected '
128
+ 'DottedName or str' % (piece,))
129
+ self._identifiers = tuple(self._identifiers)
130
+
131
+ def __repr__(self):
132
+ idents = [`ident` for ident in self._identifiers]
133
+ return 'DottedName(' + ', '.join(idents) + ')'
134
+
135
+ def __str__(self):
136
+ """
137
+ Return the dotted name as a string formed by joining its
138
+ identifiers with periods:
139
+
140
+ >>> print DottedName('epydoc', 'api_doc', DottedName')
141
+ epydoc.apidoc.DottedName
142
+ """
143
+ return '.'.join(self._identifiers)
144
+
145
+ def __add__(self, other):
146
+ """
147
+ Return a new C{DottedName} whose identifier sequence is formed
148
+ by adding C{other}'s identifier sequence to C{self}'s.
149
+ """
150
+ if isinstance(other, (basestring, DottedName)):
151
+ return DottedName(self, other)
152
+ else:
153
+ return DottedName(self, *other)
154
+
155
+ def __radd__(self, other):
156
+ """
157
+ Return a new C{DottedName} whose identifier sequence is formed
158
+ by adding C{self}'s identifier sequence to C{other}'s.
159
+ """
160
+ if isinstance(other, (basestring, DottedName)):
161
+ return DottedName(other, self)
162
+ else:
163
+ return DottedName(*(list(other)+[self]))
164
+
165
+ def __getitem__(self, i):
166
+ """
167
+ Return the C{i}th identifier in this C{DottedName}. If C{i} is
168
+ a non-empty slice, then return a C{DottedName} built from the
169
+ identifiers selected by the slice. If C{i} is an empty slice,
170
+ return an empty list (since empty C{DottedName}s are not valid).
171
+ """
172
+ if isinstance(i, types.SliceType):
173
+ pieces = self._identifiers[i.start:i.stop]
174
+ if pieces: return DottedName(pieces)
175
+ else: return []
176
+ else:
177
+ return self._identifiers[i]
178
+
179
+ def __hash__(self):
180
+ return hash(self._identifiers)
181
+
182
+ def __cmp__(self, other):
183
+ """
184
+ Compare this dotted name to C{other}. Two dotted names are
185
+ considered equal if their identifier subsequences are equal.
186
+ Ordering between dotted names is lexicographic, in order of
187
+ identifier from left to right.
188
+ """
189
+ if not isinstance(other, DottedName):
190
+ return -1
191
+ return cmp(self._identifiers, other._identifiers)
192
+
193
+ def __len__(self):
194
+ """
195
+ Return the number of identifiers in this dotted name.
196
+ """
197
+ return len(self._identifiers)
198
+
199
+ def container(self):
200
+ """
201
+ Return the DottedName formed by removing the last identifier
202
+ from this dotted name's identifier sequence. If this dotted
203
+ name only has one name in its identifier sequence, return
204
+ C{None} instead.
205
+ """
206
+ if len(self._identifiers) == 1:
207
+ return None
208
+ else:
209
+ return DottedName(*self._identifiers[:-1])
210
+
211
+ def dominates(self, name, strict=False):
212
+ """
213
+ Return true if this dotted name is equal to a prefix of
214
+ C{name}. If C{strict} is true, then also require that
215
+ C{self!=name}.
216
+
217
+ >>> DottedName('a.b').dominates(DottedName('a.b.c.d'))
218
+ True
219
+ """
220
+ len_self = len(self._identifiers)
221
+ len_name = len(name._identifiers)
222
+
223
+ if (len_self > len_name) or (strict and len_self == len_name):
224
+ return False
225
+ # The following is redundant (the first clause is implied by
226
+ # the second), but is done as an optimization.
227
+ return ((self._identifiers[0] == name._identifiers[0]) and
228
+ self._identifiers == name._identifiers[:len_self])
229
+
230
+ def contextualize(self, context):
231
+ """
232
+ If C{self} and C{context} share a common ancestor, then return
233
+ a name for C{self}, relative to that ancestor. If they do not
234
+ share a common ancestor (or if C{context} is C{UNKNOWN}), then
235
+ simply return C{self}.
236
+
237
+ This is used to generate shorter versions of dotted names in
238
+ cases where users can infer the intended target from the
239
+ context.
240
+
241
+ @type context: L{DottedName}
242
+ @rtype: L{DottedName}
243
+ """
244
+ if context is UNKNOWN or not context or len(self) <= 1:
245
+ return self
246
+ if self[0] == context[0]:
247
+ return self[1:].contextualize(context[1:])
248
+ else:
249
+ return self
250
+
251
+ # Find the first index where self & context differ.
252
+ for i in range(min(len(context), len(self))):
253
+ if self._identifiers[i] != context._identifiers[i]:
254
+ first_difference = i
255
+ break
256
+ else:
257
+ first_difference = i+1
258
+
259
+ # Strip off anything before that index.
260
+ if first_difference == 0:
261
+ return self
262
+ elif first_difference == len(self):
263
+ return self[-1:]
264
+ else:
265
+ return self[first_difference:]
266
+
267
+ ######################################################################
268
+ # UNKNOWN Value
269
+ ######################################################################
270
+
271
+ class _Sentinel:
272
+ """
273
+ A unique value that won't compare equal to any other value. This
274
+ class is used to create L{UNKNOWN}.
275
+ """
276
+ def __init__(self, name):
277
+ self.name = name
278
+ def __repr__(self):
279
+ return '<%s>' % self.name
280
+ def __nonzero__(self):
281
+ raise ValueError('Sentinel value <%s> can not be used as a boolean' %
282
+ self.name)
283
+
284
+ UNKNOWN = _Sentinel('UNKNOWN')
285
+ """A special value used to indicate that a given piece of
286
+ information about an object is unknown. This is used as the
287
+ default value for all instance variables."""
288
+
289
+ ######################################################################
290
+ # API Documentation Objects: Abstract Base Classes
291
+ ######################################################################
292
+
293
+ class APIDoc(object):
294
+ """
295
+ API documentation information for a single element of a Python
296
+ program. C{APIDoc} itself is an abstract base class; subclasses
297
+ are used to specify what information should be recorded about each
298
+ type of program element. In particular, C{APIDoc} has two direct
299
+ subclasses, C{VariableDoc} for documenting variables and
300
+ C{ValueDoc} for documenting values; and the C{ValueDoc} class is
301
+ subclassed further for different value types.
302
+
303
+ Each C{APIDoc} subclass specifies the set of attributes that
304
+ should be used to record information about the corresponding
305
+ program element type. The default value for each attribute is
306
+ stored in the class; these default values can then be overridden
307
+ with instance variables. Most attributes use the special value
308
+ L{UNKNOWN} as their default value, to indicate that the correct
309
+ value for that attribute has not yet been determined. This makes
310
+ it easier to merge two C{APIDoc} objects that are documenting the
311
+ same element (in particular, to merge information about an element
312
+ that was derived from parsing with information that was derived
313
+ from introspection).
314
+
315
+ For all attributes with boolean values, use only the constants
316
+ C{True} and C{False} to designate true and false. In particular,
317
+ do I{not} use other values that evaluate as true or false, such as
318
+ C{2} or C{()}. This restriction makes it easier to handle
319
+ C{UNKNOWN} values. For example, to test if a boolean attribute is
320
+ C{True} or C{UNKNOWN}, use 'C{attrib in (True, UNKNOWN)}' or
321
+ 'C{attrib is not False}'.
322
+
323
+ Two C{APIDoc} objects describing the same object can be X{merged},
324
+ using the method L{merge_and_overwrite(other)}. After two
325
+ C{APIDoc}s are merged, any changes to one will be reflected in the
326
+ other. This is accomplished by setting the two C{APIDoc} objects
327
+ to use a shared instance dictionary. See the documentation for
328
+ L{merge_and_overwrite} for more information, and some important
329
+ caveats about hashing.
330
+ """
331
+ #{ Docstrings
332
+ docstring = UNKNOWN
333
+ """@ivar: The documented item's docstring.
334
+ @type: C{string} or C{None}"""
335
+
336
+ docstring_lineno = UNKNOWN
337
+ """@ivar: The line number on which the documented item's docstring
338
+ begins.
339
+ @type: C{int}"""
340
+ #} end of "docstrings" group
341
+
342
+ #{ Information Extracted from Docstrings
343
+ descr = UNKNOWN
344
+ """@ivar: A description of the documented item, extracted from its
345
+ docstring.
346
+ @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}"""
347
+
348
+ summary = UNKNOWN
349
+ """@ivar: A summary description of the documented item, extracted from
350
+ its docstring.
351
+ @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}"""
352
+
353
+ other_docs = UNKNOWN
354
+ """@ivar: A flag indicating if the entire L{docstring} body (except tags
355
+ if any) is entirely included in the L{summary}.
356
+ @type: C{bool}"""
357
+
358
+ metadata = UNKNOWN
359
+ """@ivar: Metadata about the documented item, extracted from fields in
360
+ its docstring. I{Currently} this is encoded as a list of tuples
361
+ C{(field, arg, descr)}. But that may change.
362
+ @type: C{(str, str, L{ParsedDocstring<markup.ParsedDocstring>})}"""
363
+
364
+ extra_docstring_fields = UNKNOWN
365
+ """@ivar: A list of new docstring fields tags that are defined by the
366
+ documented item's docstring. These new field tags can be used by
367
+ this item or by any item it contains.
368
+ @type: L{DocstringField <epydoc.docstringparser.DocstringField>}"""
369
+ #} end of "information extracted from docstrings" group
370
+
371
+ #{ Source Information
372
+ docs_extracted_by = UNKNOWN # 'parser' or 'introspecter' or 'both'
373
+ """@ivar: Information about where the information contained by this
374
+ C{APIDoc} came from. Can be one of C{'parser'},
375
+ C{'introspector'}, or C{'both'}.
376
+ @type: C{str}"""
377
+ #} end of "source information" group
378
+
379
+ def __init__(self, **kwargs):
380
+ """
381
+ Construct a new C{APIDoc} object. Keyword arguments may be
382
+ used to initialize the new C{APIDoc}'s attributes.
383
+
384
+ @raise TypeError: If a keyword argument is specified that does
385
+ not correspond to a valid attribute for this (sub)class of
386
+ C{APIDoc}.
387
+ """
388
+ if epydoc.DEBUG:
389
+ for key in kwargs:
390
+ if key[0] != '_' and not hasattr(self.__class__, key):
391
+ raise TypeError('%s got unexpected arg %r' %
392
+ (self.__class__.__name__, key))
393
+ self.__dict__.update(kwargs)
394
+
395
+ def _debug_setattr(self, attr, val):
396
+ """
397
+ Modify an C{APIDoc}'s attribute. This is used when
398
+ L{epydoc.DEBUG} is true, to make sure we don't accidentally
399
+ set any inappropriate attributes on C{APIDoc} objects.
400
+
401
+ @raise AttributeError: If C{attr} is not a valid attribute for
402
+ this (sub)class of C{APIDoc}. (C{attr} is considered a
403
+ valid attribute iff C{self.__class__} defines an attribute
404
+ with that name.)
405
+ """
406
+ # Don't intercept special assignments like __class__, or
407
+ # assignments to private variables.
408
+ if attr.startswith('_'):
409
+ return object.__setattr__(self, attr, val)
410
+ if not hasattr(self, attr):
411
+ raise AttributeError('%s does not define attribute %r' %
412
+ (self.__class__.__name__, attr))
413
+ self.__dict__[attr] = val
414
+
415
+ if epydoc.DEBUG:
416
+ __setattr__ = _debug_setattr
417
+
418
+ def __repr__(self):
419
+ return '<%s>' % self.__class__.__name__
420
+
421
+ def pp(self, doublespace=0, depth=5, exclude=(), include=()):
422
+ """
423
+ Return a pretty-printed string representation for the
424
+ information contained in this C{APIDoc}.
425
+ """
426
+ return pp_apidoc(self, doublespace, depth, exclude, include)
427
+ __str__ = pp
428
+
429
+ def specialize_to(self, cls):
430
+ """
431
+ Change C{self}'s class to C{cls}. C{cls} must be a subclass
432
+ of C{self}'s current class. For example, if a generic
433
+ C{ValueDoc} was created for a value, and it is determined that
434
+ the value is a routine, you can update its class with:
435
+
436
+ >>> valdoc.specialize_to(RoutineDoc)
437
+ """
438
+ if not issubclass(cls, self.__class__):
439
+ raise ValueError('Can not specialize to %r' % cls)
440
+ # Update the class.
441
+ self.__class__ = cls
442
+ # Update the class of any other apidoc's in the mergeset.
443
+ if self.__mergeset is not None:
444
+ for apidoc in self.__mergeset:
445
+ apidoc.__class__ = cls
446
+ # Re-initialize self, in case the subclass constructor does
447
+ # any special processing on its arguments.
448
+ self.__init__(**self.__dict__)
449
+
450
+ __has_been_hashed = False
451
+ """True iff L{self.__hash__()} has ever been called."""
452
+
453
+ def __hash__(self):
454
+ self.__has_been_hashed = True
455
+ return id(self.__dict__)
456
+
457
+ def __cmp__(self, other):
458
+ if not isinstance(other, APIDoc): return -1
459
+ if self.__dict__ is other.__dict__: return 0
460
+ name_cmp = cmp(self.canonical_name, other.canonical_name)
461
+ if name_cmp == 0: return -1
462
+ else: return name_cmp
463
+
464
+ def is_detailed(self):
465
+ """
466
+ Does this object deserve a box with extra details?
467
+
468
+ @return: True if the object needs extra details, else False.
469
+ @rtype: C{bool}
470
+ """
471
+ if self.other_docs is True:
472
+ return True
473
+
474
+ if self.metadata is not UNKNOWN:
475
+ return bool(self.metadata)
476
+
477
+ __mergeset = None
478
+ """The set of all C{APIDoc} objects that have been merged with
479
+ this C{APIDoc} (using L{merge_and_overwrite()}). Each C{APIDoc}
480
+ in this set shares a common instance dictionary (C{__dict__})."""
481
+
482
+ def merge_and_overwrite(self, other, ignore_hash_conflict=False):
483
+ """
484
+ Combine C{self} and C{other} into a X{merged object}, such
485
+ that any changes made to one will affect the other. Any
486
+ attributes that C{other} had before merging will be discarded.
487
+ This is accomplished by copying C{self.__dict__} over
488
+ C{other.__dict__} and C{self.__class__} over C{other.__class__}.
489
+
490
+ Care must be taken with this method, since it modifies the
491
+ hash value of C{other}. To help avoid the problems that this
492
+ can cause, C{merge_and_overwrite} will raise an exception if
493
+ C{other} has ever been hashed, unless C{ignore_hash_conflict}
494
+ is True. Note that adding C{other} to a dictionary, set, or
495
+ similar data structure will implicitly cause it to be hashed.
496
+ If you do set C{ignore_hash_conflict} to True, then any
497
+ existing data structures that rely on C{other}'s hash staying
498
+ constant may become corrupted.
499
+
500
+ @return: C{self}
501
+ @raise ValueError: If C{other} has ever been hashed.
502
+ """
503
+ # If we're already merged, then there's nothing to do.
504
+ if (self.__dict__ is other.__dict__ and
505
+ self.__class__ is other.__class__): return self
506
+
507
+ if other.__has_been_hashed and not ignore_hash_conflict:
508
+ raise ValueError("%r has already been hashed! Merging it "
509
+ "would cause its has value to change." % other)
510
+
511
+ # If other was itself already merged with anything,
512
+ # then we need to merge those too.
513
+ a,b = (self.__mergeset, other.__mergeset)
514
+ mergeset = (self.__mergeset or [self]) + (other.__mergeset or [other])
515
+ other.__dict__.clear()
516
+ for apidoc in mergeset:
517
+ #if apidoc is self: pass
518
+ apidoc.__class__ = self.__class__
519
+ apidoc.__dict__ = self.__dict__
520
+ self.__mergeset = mergeset
521
+ # Sanity chacks.
522
+ assert self in mergeset and other in mergeset
523
+ for apidoc in mergeset:
524
+ assert apidoc.__dict__ is self.__dict__
525
+ # Return self.
526
+ return self
527
+
528
+ def apidoc_links(self, **filters):
529
+ """
530
+ Return a list of all C{APIDoc}s that are directly linked from
531
+ this C{APIDoc} (i.e., are contained or pointed to by one or
532
+ more of this C{APIDoc}'s attributes.)
533
+
534
+ Keyword argument C{filters} can be used to selectively exclude
535
+ certain categories of attribute value. For example, using
536
+ C{includes=False} will exclude variables that were imported
537
+ from other modules; and C{subclasses=False} will exclude
538
+ subclasses. The filter categories currently supported by
539
+ epydoc are:
540
+ - C{imports}: Imported variables.
541
+ - C{packages}: Containing packages for modules.
542
+ - C{submodules}: Contained submodules for packages.
543
+ - C{bases}: Bases for classes.
544
+ - C{subclasses}: Subclasses for classes.
545
+ - C{variables}: All variables.
546
+ - C{private}: Private variables.
547
+ - C{overrides}: Points from class variables to the variables
548
+ they override. This filter is False by default.
549
+ """
550
+ return []
551
+
552
+ def reachable_valdocs(root, **filters):
553
+ """
554
+ Return a list of all C{ValueDoc}s that can be reached, directly or
555
+ indirectly from the given root list of C{ValueDoc}s.
556
+
557
+ @param filters: A set of filters that can be used to prevent
558
+ C{reachable_valdocs} from following specific link types when
559
+ looking for C{ValueDoc}s that can be reached from the root
560
+ set. See C{APIDoc.apidoc_links} for a more complete
561
+ description.
562
+ """
563
+ apidoc_queue = list(root)
564
+ val_set = set()
565
+ var_set = set()
566
+ while apidoc_queue:
567
+ api_doc = apidoc_queue.pop()
568
+ if isinstance(api_doc, ValueDoc):
569
+ val_set.add(api_doc)
570
+ else:
571
+ var_set.add(api_doc)
572
+ apidoc_queue.extend([v for v in api_doc.apidoc_links(**filters)
573
+ if v not in val_set and v not in var_set])
574
+ return val_set
575
+
576
+ ######################################################################
577
+ # Variable Documentation Objects
578
+ ######################################################################
579
+
580
+ class VariableDoc(APIDoc):
581
+ """
582
+ API documentation information about a single Python variable.
583
+
584
+ @note: The only time a C{VariableDoc} will have its own docstring
585
+ is if that variable was created using an assignment statement, and
586
+ that assignment statement had a docstring-comment or was followed
587
+ by a pseudo-docstring.
588
+ """
589
+ #{ Basic Variable Information
590
+ name = UNKNOWN
591
+ """@ivar: The name of this variable in its containing namespace.
592
+ @type: C{str}"""
593
+
594
+ container = UNKNOWN
595
+ """@ivar: API documentation for the namespace that contains this
596
+ variable.
597
+ @type: L{ValueDoc}"""
598
+
599
+ canonical_name = UNKNOWN
600
+ """@ivar: A dotted name that serves as a unique identifier for
601
+ this C{VariableDoc}. It should be formed by concatenating
602
+ the C{VariableDoc}'s C{container} with its C{name}.
603
+ @type: L{DottedName}"""
604
+
605
+ value = UNKNOWN
606
+ """@ivar: The API documentation for this variable's value.
607
+ @type: L{ValueDoc}"""
608
+ #}
609
+
610
+ #{ Information Extracted from Docstrings
611
+ type_descr = UNKNOWN
612
+ """@ivar: A description of the variable's expected type, extracted from
613
+ its docstring.
614
+ @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}"""
615
+ #} end of "information extracted from docstrings" group
616
+
617
+ #{ Information about Imported Variables
618
+ imported_from = UNKNOWN
619
+ """@ivar: The fully qualified dotted name of the variable that this
620
+ variable's value was imported from. This attribute should only
621
+ be defined if C{is_instvar} is true.
622
+ @type: L{DottedName}"""
623
+
624
+ is_imported = UNKNOWN
625
+ """@ivar: Was this variable's value imported from another module?
626
+ (Exception: variables that are explicitly included in __all__ have
627
+ C{is_imported} set to C{False}, even if they are in fact
628
+ imported.)
629
+ @type: C{bool}"""
630
+ #} end of "information about imported variables" group
631
+
632
+ #{ Information about Variables in Classes
633
+ is_instvar = UNKNOWN
634
+ """@ivar: If true, then this variable is an instance variable; if false,
635
+ then this variable is a class variable. This attribute should
636
+ only be defined if the containing namespace is a class
637
+ @type: C{bool}"""
638
+
639
+ overrides = UNKNOWN # [XXX] rename -- don't use a verb.
640
+ """@ivar: The API documentation for the variable that is overridden by
641
+ this variable. This attribute should only be defined if the
642
+ containing namespace is a class.
643
+ @type: L{VariableDoc}"""
644
+ #} end of "information about variables in classes" group
645
+
646
+ #{ Flags
647
+ is_alias = UNKNOWN
648
+ """@ivar: Is this variable an alias for another variable with the same
649
+ value? If so, then this variable will be dispreferred when
650
+ assigning canonical names.
651
+ @type: C{bool}"""
652
+
653
+ is_public = UNKNOWN
654
+ """@ivar: Is this variable part of its container's public API?
655
+ @type: C{bool}"""
656
+ #} end of "flags" group
657
+
658
+ def __init__(self, **kwargs):
659
+ APIDoc.__init__(self, **kwargs)
660
+ if self.is_public is UNKNOWN and self.name is not UNKNOWN:
661
+ self.is_public = (not self.name.startswith('_') or
662
+ self.name.endswith('_'))
663
+
664
+ def __repr__(self):
665
+ if self.canonical_name is not UNKNOWN:
666
+ return '<%s %s>' % (self.__class__.__name__, self.canonical_name)
667
+ if self.name is not UNKNOWN:
668
+ return '<%s %s>' % (self.__class__.__name__, self.name)
669
+ else:
670
+ return '<%s>' % self.__class__.__name__
671
+
672
+ def _get_defining_module(self):
673
+ if self.container is UNKNOWN:
674
+ return UNKNOWN
675
+ return self.container.defining_module
676
+ defining_module = property(_get_defining_module, doc="""
677
+ A read-only property that can be used to get the variable's
678
+ defining module. This is defined as the defining module
679
+ of the variable's container.""")
680
+
681
+ def apidoc_links(self, **filters):
682
+ # nb: overrides filter is *False* by default.
683
+ if (filters.get('overrides', False) and
684
+ (self.overrides not in (None, UNKNOWN))):
685
+ overrides = [self.overrides]
686
+ else:
687
+ overrides = []
688
+ if self.value in (None, UNKNOWN):
689
+ return []+overrides
690
+ else:
691
+ return [self.value]+overrides
692
+
693
+ def is_detailed(self):
694
+ pval = super(VariableDoc, self).is_detailed()
695
+ if pval or self.value in (None, UNKNOWN):
696
+ return pval
697
+
698
+ if (self.overrides not in (None, UNKNOWN) and
699
+ isinstance(self.value, RoutineDoc)):
700
+ return True
701
+
702
+ if isinstance(self.value, GenericValueDoc):
703
+ # [XX] This is a little hackish -- we assume that the
704
+ # summary lines will have SUMMARY_REPR_LINELEN chars,
705
+ # that len(name) of those will be taken up by the name,
706
+ # and that 3 of those will be taken up by " = " between
707
+ # the name & val. Note that if any docwriter uses a
708
+ # different formula for maxlen for this, then it will
709
+ # not get the right value for is_detailed().
710
+ maxlen = self.value.SUMMARY_REPR_LINELEN-3-len(self.name)
711
+ return (not self.value.summary_pyval_repr(maxlen).is_complete)
712
+ else:
713
+ return self.value.is_detailed()
714
+
715
+ ######################################################################
716
+ # Value Documentation Objects
717
+ ######################################################################
718
+
719
+ class ValueDoc(APIDoc):
720
+ """
721
+ API documentation information about a single Python value.
722
+ """
723
+ canonical_name = UNKNOWN
724
+ """@ivar: A dotted name that serves as a unique identifier for
725
+ this C{ValueDoc}'s value. If the value can be reached using a
726
+ single sequence of identifiers (given the appropriate imports),
727
+ then that sequence of identifiers is used as its canonical name.
728
+ If the value can be reached by multiple sequences of identifiers
729
+ (i.e., if it has multiple aliases), then one of those sequences of
730
+ identifiers is used. If the value cannot be reached by any
731
+ sequence of identifiers (e.g., if it was used as a base class but
732
+ then its variable was deleted), then its canonical name will start
733
+ with C{'??'}. If necessary, a dash followed by a number will be
734
+ appended to the end of a non-reachable identifier to make its
735
+ canonical name unique.
736
+
737
+ When possible, canonical names are chosen when new C{ValueDoc}s
738
+ are created. However, this is sometimes not possible. If a
739
+ canonical name can not be chosen when the C{ValueDoc} is created,
740
+ then one will be assigned by L{assign_canonical_names()
741
+ <docbuilder.assign_canonical_names>}.
742
+
743
+ @type: L{DottedName}"""
744
+
745
+ #{ Value Representation
746
+ pyval = UNKNOWN
747
+ """@ivar: A pointer to the actual Python object described by this
748
+ C{ValueDoc}. This is used to display the value (e.g., when
749
+ describing a variable.) Use L{pyval_repr()} to generate a
750
+ plaintext string representation of this value.
751
+ @type: Python object"""
752
+
753
+ parse_repr = UNKNOWN
754
+ """@ivar: A text representation of this value, extracted from
755
+ parsing its source code. This representation may not accurately
756
+ reflect the actual value (e.g., if the value was modified after
757
+ the initial assignment).
758
+ @type: C{unicode}"""
759
+
760
+ REPR_MAXLINES = 5
761
+ """@cvar: The maximum number of lines of text that should be
762
+ generated by L{pyval_repr()}. If the string representation does
763
+ not fit in this number of lines, an ellpsis marker (...) will
764
+ be placed at the end of the formatted representation."""
765
+
766
+ REPR_LINELEN = 75
767
+ """@cvar: The maximum number of characters for lines of text that
768
+ should be generated by L{pyval_repr()}. Any lines that exceed
769
+ this number of characters will be line-wrappped; The S{crarr}
770
+ symbol will be used to indicate that the line was wrapped."""
771
+
772
+ SUMMARY_REPR_LINELEN = 75
773
+ """@cvar: The maximum number of characters for the single-line
774
+ text representation generated by L{summary_pyval_repr()}. If
775
+ the value's representation does not fit in this number of
776
+ characters, an ellipsis marker (...) will be placed at the end
777
+ of the formatted representation."""
778
+
779
+ REPR_MIN_SCORE = 0
780
+ """@cvar: The minimum score that a value representation based on
781
+ L{pyval} should have in order to be used instead of L{parse_repr}
782
+ as the canonical representation for this C{ValueDoc}'s value.
783
+ @see: L{epydoc.markup.pyval_repr}"""
784
+ #} end of "value representation" group
785
+
786
+ #{ Context
787
+ defining_module = UNKNOWN
788
+ """@ivar: The documentation for the module that defines this
789
+ value. This is used, e.g., to lookup the appropriate markup
790
+ language for docstrings. For a C{ModuleDoc},
791
+ C{defining_module} should be C{self}.
792
+ @type: L{ModuleDoc}"""
793
+ #} end of "context group"
794
+
795
+ #{ Information about Imported Variables
796
+ proxy_for = None # [xx] in progress.
797
+ """@ivar: If C{proxy_for} is not None, then this value was
798
+ imported from another file. C{proxy_for} is the dotted name of
799
+ the variable that this value was imported from. If that
800
+ variable is documented, then its C{value} may contain more
801
+ complete API documentation about this value. The C{proxy_for}
802
+ attribute is used by the source code parser to link imported
803
+ values to their source values (in particular, for base
804
+ classes). When possible, these proxy C{ValueDoc}s are replaced
805
+ by the imported value's C{ValueDoc} by
806
+ L{link_imports()<docbuilder.link_imports>}.
807
+ @type: L{DottedName}"""
808
+ #} end of "information about imported variables" group
809
+
810
+ #: @ivar:
811
+ #: This is currently used to extract values from __all__, etc, in
812
+ #: the docparser module; maybe I should specialize
813
+ #: process_assignment and extract it there? Although, for __all__,
814
+ #: it's not clear where I'd put the value, since I just use it to
815
+ #: set private/public/imported attribs on other vars (that might not
816
+ #: exist yet at the time.)
817
+ toktree = UNKNOWN
818
+
819
+ def __repr__(self):
820
+ if self.canonical_name is not UNKNOWN:
821
+ return '<%s %s>' % (self.__class__.__name__, self.canonical_name)
822
+ else:
823
+ return '<%s %s>' % (self.__class__.__name__,
824
+ self.summary_pyval_repr().to_plaintext(None))
825
+
826
+ def __setstate__(self, state):
827
+ self.__dict__ = state
828
+
829
+ def __getstate__(self):
830
+ """
831
+ State serializer for the pickle module. This is necessary
832
+ because sometimes the C{pyval} attribute contains an
833
+ un-pickleable value.
834
+ """
835
+ # Construct our pickled dictionary. Maintain this dictionary
836
+ # as a private attribute, so we can reuse it later, since
837
+ # merged objects need to share a single dictionary.
838
+ if not hasattr(self, '_ValueDoc__pickle_state'):
839
+ # Make sure __pyval_repr & __summary_pyval_repr are cached:
840
+ self.pyval_repr(), self.summary_pyval_repr()
841
+ # Construct the dictionary; leave out 'pyval'.
842
+ self.__pickle_state = self.__dict__.copy()
843
+ self.__pickle_state['pyval'] = UNKNOWN
844
+
845
+ if not isinstance(self, GenericValueDoc):
846
+ assert self.__pickle_state != {}
847
+ # Return the pickle state.
848
+ return self.__pickle_state
849
+
850
+ #{ Value Representation
851
+ def pyval_repr(self):
852
+ """
853
+ Return a formatted representation of the Python object
854
+ described by this C{ValueDoc}. This representation may
855
+ include data from introspection or parsing, and is authorative
856
+ as 'the best way to represent a Python value.' Any lines that
857
+ go beyond L{REPR_LINELEN} characters will be wrapped; and if
858
+ the representation as a whole takes more than L{REPR_MAXLINES}
859
+ lines, then it will be truncated (with an ellipsis marker).
860
+ This function will never return L{UNKNOWN} or C{None}.
861
+
862
+ @rtype: L{ColorizedPyvalRepr}
863
+ """
864
+ # Use self.__pyval_repr to cache the result.
865
+ if not hasattr(self, '_ValueDoc__pyval_repr'):
866
+ self.__pyval_repr = epydoc.markup.pyval_repr.colorize_pyval(
867
+ self.pyval, self.parse_repr, self.REPR_MIN_SCORE,
868
+ self.REPR_LINELEN, self.REPR_MAXLINES, linebreakok=True)
869
+ return self.__pyval_repr
870
+
871
+ def summary_pyval_repr(self, max_len=None):
872
+ """
873
+ Return a single-line formatted representation of the Python
874
+ object described by this C{ValueDoc}. This representation may
875
+ include data from introspection or parsing, and is authorative
876
+ as 'the best way to summarize a Python value.' If the
877
+ representation takes more then L{SUMMARY_REPR_LINELEN}
878
+ characters, then it will be truncated (with an ellipsis
879
+ marker). This function will never return L{UNKNOWN} or
880
+ C{None}.
881
+
882
+ @rtype: L{ColorizedPyvalRepr}
883
+ """
884
+ # If max_len is specified, then do *not* cache the result.
885
+ if max_len is not None:
886
+ return epydoc.markup.pyval_repr.colorize_pyval(
887
+ self.pyval, self.parse_repr, self.REPR_MIN_SCORE,
888
+ max_len, maxlines=1, linebreakok=False)
889
+
890
+ # Use self.__summary_pyval_repr to cache the result.
891
+ if not hasattr(self, '_ValueDoc__summary_pyval_repr'):
892
+ self.__summary_pyval_repr = epydoc.markup.pyval_repr.colorize_pyval(
893
+ self.pyval, self.parse_repr, self.REPR_MIN_SCORE,
894
+ self.SUMMARY_REPR_LINELEN, maxlines=1, linebreakok=False)
895
+ return self.__summary_pyval_repr
896
+ #} end of "value representation" group
897
+
898
+ def apidoc_links(self, **filters):
899
+ return []
900
+
901
+ class GenericValueDoc(ValueDoc):
902
+ """
903
+ API documentation about a 'generic' value, i.e., one that does not
904
+ have its own docstring or any information other than its value and
905
+ parse representation. C{GenericValueDoc}s do not get assigned
906
+ cannonical names.
907
+ """
908
+ canonical_name = None
909
+
910
+ def is_detailed(self):
911
+ return (not self.summary_pyval_repr().is_complete)
912
+
913
+ class NamespaceDoc(ValueDoc):
914
+ """
915
+ API documentation information about a singe Python namespace
916
+ value. (I.e., a module or a class).
917
+ """
918
+ #{ Information about Variables
919
+ variables = UNKNOWN
920
+ """@ivar: The contents of the namespace, encoded as a
921
+ dictionary mapping from identifiers to C{VariableDoc}s. This
922
+ dictionary contains all names defined by the namespace,
923
+ including imported variables, aliased variables, and variables
924
+ inherited from base classes (once L{inherit_docs()
925
+ <epydoc.docbuilder.inherit_docs>} has added them).
926
+ @type: C{dict} from C{string} to L{VariableDoc}"""
927
+ sorted_variables = UNKNOWN
928
+ """@ivar: A list of all variables defined by this
929
+ namespace, in sorted order. The elements of this list should
930
+ exactly match the values of L{variables}. The sort order for
931
+ this list is defined as follows:
932
+ - Any variables listed in a C{@sort} docstring field are
933
+ listed in the order given by that field.
934
+ - These are followed by any variables that were found while
935
+ parsing the source code, in the order in which they were
936
+ defined in the source file.
937
+ - Finally, any remaining variables are listed in
938
+ alphabetical order.
939
+ @type: C{list} of L{VariableDoc}"""
940
+ sort_spec = UNKNOWN
941
+ """@ivar: The order in which variables should be listed,
942
+ encoded as a list of names. Any variables whose names are not
943
+ included in this list should be listed alphabetically,
944
+ following the variables that are included.
945
+ @type: C{list} of C{str}"""
946
+ group_specs = UNKNOWN
947
+ """@ivar: The groups that are defined by this namespace's
948
+ docstrings. C{group_specs} is encoded as an ordered list of
949
+ tuples C{(group_name, elt_names)}, where C{group_name} is the
950
+
951
+ name of a group and C{elt_names} is a list of element names in
952
+ that group. (An element can be a variable or a submodule.) A
953
+ '*' in an element name will match any string of characters.
954
+ @type: C{list} of C{(str,list)}"""
955
+ variable_groups = UNKNOWN
956
+ """@ivar: A dictionary specifying what group each
957
+ variable belongs to. The keys of the dictionary are group
958
+ names, and the values are lists of C{VariableDoc}s. The order
959
+ that groups should be listed in should be taken from
960
+ L{group_specs}.
961
+ @type: C{dict} from C{str} to C{list} of L{VariableDoc}"""
962
+ #} end of group "information about variables"
963
+
964
+ def __init__(self, **kwargs):
965
+ kwargs.setdefault('variables', {})
966
+ APIDoc.__init__(self, **kwargs)
967
+ assert self.variables is not UNKNOWN
968
+
969
+ def is_detailed(self):
970
+ return True
971
+
972
+ def apidoc_links(self, **filters):
973
+ variables = filters.get('variables', True)
974
+ imports = filters.get('imports', True)
975
+ private = filters.get('private', True)
976
+ if variables and imports and private:
977
+ return self.variables.values() # list the common case first.
978
+ elif not variables:
979
+ return []
980
+ elif not imports and not private:
981
+ return [v for v in self.variables.values() if
982
+ v.is_imported != True and v.is_public != False]
983
+ elif not private:
984
+ return [v for v in self.variables.values() if
985
+ v.is_public != False]
986
+ elif not imports:
987
+ return [v for v in self.variables.values() if
988
+ v.is_imported != True]
989
+ assert 0, 'this line should be unreachable'
990
+
991
+ def init_sorted_variables(self):
992
+ """
993
+ Initialize the L{sorted_variables} attribute, based on the
994
+ L{variables} and L{sort_spec} attributes. This should usually
995
+ be called after all variables have been added to C{variables}
996
+ (including any inherited variables for classes).
997
+ """
998
+ unsorted = self.variables.copy()
999
+ self.sorted_variables = []
1000
+
1001
+ # Add any variables that are listed in sort_spec
1002
+ if self.sort_spec is not UNKNOWN:
1003
+ unused_idents = set(self.sort_spec)
1004
+ for ident in self.sort_spec:
1005
+ if ident in unsorted:
1006
+ self.sorted_variables.append(unsorted.pop(ident))
1007
+ unused_idents.discard(ident)
1008
+ elif '*' in ident:
1009
+ regexp = re.compile('^%s$' % ident.replace('*', '(.*)'))
1010
+ # sort within matching group?
1011
+ for name, var_doc in unsorted.items():
1012
+ if regexp.match(name):
1013
+ self.sorted_variables.append(unsorted.pop(name))
1014
+ unused_idents.discard(ident)
1015
+ for ident in unused_idents:
1016
+ if ident not in ['__all__', '__docformat__', '__path__']:
1017
+ log.warning("@sort: %s.%s not found" %
1018
+ (self.canonical_name, ident))
1019
+
1020
+
1021
+ # Add any remaining variables in alphabetical order.
1022
+ var_docs = unsorted.items()
1023
+ var_docs.sort()
1024
+ for name, var_doc in var_docs:
1025
+ self.sorted_variables.append(var_doc)
1026
+
1027
+ def init_variable_groups(self):
1028
+ """
1029
+ Initialize the L{variable_groups} attribute, based on the
1030
+ L{sorted_variables} and L{group_specs} attributes.
1031
+ """
1032
+ if self.sorted_variables is UNKNOWN:
1033
+ self.init_sorted_variables()
1034
+ assert len(self.sorted_variables) == len(self.variables)
1035
+
1036
+ elts = [(v.name, v) for v in self.sorted_variables]
1037
+ self._unused_groups = dict([(n,set(i)) for (n,i) in self.group_specs])
1038
+ self.variable_groups = self._init_grouping(elts)
1039
+
1040
+ def group_names(self):
1041
+ """
1042
+ Return a list of the group names defined by this namespace, in
1043
+ the order in which they should be listed, with no duplicates.
1044
+ """
1045
+ name_list = ['']
1046
+ name_set = set()
1047
+ for name, spec in self.group_specs:
1048
+ if name not in name_set:
1049
+ name_set.add(name)
1050
+ name_list.append(name)
1051
+ return name_list
1052
+
1053
+ def _init_grouping(self, elts):
1054
+ """
1055
+ Divide a given a list of APIDoc objects into groups, as
1056
+ specified by L{self.group_specs}.
1057
+
1058
+ @param elts: A list of tuples C{(name, apidoc)}.
1059
+
1060
+ @return: A list of tuples C{(groupname, elts)}, where
1061
+ C{groupname} is the name of a group and C{elts} is a list of
1062
+ C{APIDoc}s in that group. The first tuple has name C{''}, and
1063
+ is used for ungrouped elements. The remaining tuples are
1064
+ listed in the order that they appear in C{self.group_specs}.
1065
+ Within each tuple, the elements are listed in the order that
1066
+ they appear in C{api_docs}.
1067
+ """
1068
+ # Make the common case fast.
1069
+ if len(self.group_specs) == 0:
1070
+ return {'': [elt[1] for elt in elts]}
1071
+
1072
+ ungrouped = set([elt_doc for (elt_name, elt_doc) in elts])
1073
+
1074
+ ungrouped = dict(elts)
1075
+ groups = {}
1076
+ for elt_name, elt_doc in elts:
1077
+ for (group_name, idents) in self.group_specs:
1078
+ group = groups.setdefault(group_name, [])
1079
+ unused_groups = self._unused_groups[group_name]
1080
+ for ident in idents:
1081
+ if re.match('^%s$' % ident.replace('*', '(.*)'), elt_name):
1082
+ unused_groups.discard(ident)
1083
+ if elt_name in ungrouped:
1084
+ group.append(ungrouped.pop(elt_name))
1085
+ else:
1086
+ log.warning("%s.%s in multiple groups" %
1087
+ (self.canonical_name, elt_name))
1088
+
1089
+ # Convert ungrouped from an unordered set to an ordered list.
1090
+ groups[''] = [elt_doc for (elt_name, elt_doc) in elts
1091
+ if elt_name in ungrouped]
1092
+ return groups
1093
+
1094
+ def report_unused_groups(self):
1095
+ """
1096
+ Issue a warning for any @group items that were not used by
1097
+ L{_init_grouping()}.
1098
+ """
1099
+ for (group, unused_idents) in self._unused_groups.items():
1100
+ for ident in unused_idents:
1101
+ log.warning("@group %s: %s.%s not found" %
1102
+ (group, self.canonical_name, ident))
1103
+
1104
+ class ModuleDoc(NamespaceDoc):
1105
+ """
1106
+ API documentation information about a single module.
1107
+ """
1108
+ #{ Information about the Module
1109
+ filename = UNKNOWN
1110
+ """@ivar: The name of the file that defines the module.
1111
+ @type: C{string}"""
1112
+ docformat = UNKNOWN
1113
+ """@ivar: The markup language used by docstrings in this module.
1114
+ @type: C{string}"""
1115
+ #{ Information about Submodules
1116
+ submodules = UNKNOWN
1117
+ """@ivar: Modules contained by this module (if this module
1118
+ is a package). (Note: on rare occasions, a module may have a
1119
+ submodule that is shadowed by a variable with the same name.)
1120
+ @type: C{list} of L{ModuleDoc}"""
1121
+ submodule_groups = UNKNOWN
1122
+ """@ivar: A dictionary specifying what group each
1123
+ submodule belongs to. The keys of the dictionary are group
1124
+ names, and the values are lists of C{ModuleDoc}s. The order
1125
+ that groups should be listed in should be taken from
1126
+ L{group_specs}.
1127
+ @type: C{dict} from C{str} to C{list} of L{ModuleDoc}"""
1128
+ #{ Information about Packages
1129
+ package = UNKNOWN
1130
+ """@ivar: API documentation for the module's containing package.
1131
+ @type: L{ModuleDoc}"""
1132
+ is_package = UNKNOWN
1133
+ """@ivar: True if this C{ModuleDoc} describes a package.
1134
+ @type: C{bool}"""
1135
+ path = UNKNOWN
1136
+ """@ivar: If this C{ModuleDoc} describes a package, then C{path}
1137
+ contains a list of directories that constitute its path (i.e.,
1138
+ the value of its C{__path__} variable).
1139
+ @type: C{list} of C{str}"""
1140
+ #{ Information about Imported Variables
1141
+ imports = UNKNOWN
1142
+ """@ivar: A list of the source names of variables imported into
1143
+ this module. This is used to construct import graphs.
1144
+ @type: C{list} of L{DottedName}"""
1145
+ #}
1146
+
1147
+ def apidoc_links(self, **filters):
1148
+ val_docs = NamespaceDoc.apidoc_links(self, **filters)
1149
+ if (filters.get('packages', True) and
1150
+ self.package not in (None, UNKNOWN)):
1151
+ val_docs.append(self.package)
1152
+ if (filters.get('submodules', True) and
1153
+ self.submodules not in (None, UNKNOWN)):
1154
+ val_docs += self.submodules
1155
+ return val_docs
1156
+
1157
+ def init_submodule_groups(self):
1158
+ """
1159
+ Initialize the L{submodule_groups} attribute, based on the
1160
+ L{submodules} and L{group_specs} attributes.
1161
+ """
1162
+ if self.submodules in (None, UNKNOWN):
1163
+ return
1164
+ self.submodules = sorted(self.submodules,
1165
+ key=lambda m:m.canonical_name)
1166
+ elts = [(m.canonical_name[-1], m) for m in self.submodules]
1167
+ self.submodule_groups = self._init_grouping(elts)
1168
+
1169
+ def select_variables(self, group=None, value_type=None, public=None,
1170
+ imported=None, detailed=None):
1171
+ """
1172
+ Return a specified subset of this module's L{sorted_variables}
1173
+ list. If C{value_type} is given, then only return variables
1174
+ whose values have the specified type. If C{group} is given,
1175
+ then only return variables that belong to the specified group.
1176
+
1177
+ @require: The L{sorted_variables}, L{variable_groups}, and
1178
+ L{submodule_groups} attributes must be initialized before
1179
+ this method can be used. See L{init_sorted_variables()},
1180
+ L{init_variable_groups()}, and L{init_submodule_groups()}.
1181
+
1182
+ @param value_type: A string specifying the value type for
1183
+ which variables should be returned. Valid values are:
1184
+ - 'class' - variables whose values are classes or types.
1185
+ - 'function' - variables whose values are functions.
1186
+ - 'other' - variables whose values are not classes,
1187
+ exceptions, types, or functions.
1188
+ @type value_type: C{string}
1189
+
1190
+ @param group: The name of the group for which variables should
1191
+ be returned. A complete list of the groups defined by
1192
+ this C{ModuleDoc} is available in the L{group_names}
1193
+ instance variable. The first element of this list is
1194
+ always the special group name C{''}, which is used for
1195
+ variables that do not belong to any group.
1196
+ @type group: C{string}
1197
+
1198
+ @param detailed: If True (False), return only the variables
1199
+ deserving (not deserving) a detailed informative box.
1200
+ If C{None}, don't care.
1201
+ @type detailed: C{bool}
1202
+ """
1203
+ if (self.sorted_variables is UNKNOWN or
1204
+ self.variable_groups is UNKNOWN):
1205
+ raise ValueError('sorted_variables and variable_groups '
1206
+ 'must be initialized first.')
1207
+
1208
+ if group is None: var_list = self.sorted_variables
1209
+ else:
1210
+ var_list = self.variable_groups.get(group, self.sorted_variables)
1211
+
1212
+ # Public/private filter (Count UNKNOWN as public)
1213
+ if public is True:
1214
+ var_list = [v for v in var_list if v.is_public is not False]
1215
+ elif public is False:
1216
+ var_list = [v for v in var_list if v.is_public is False]
1217
+
1218
+ # Imported filter (Count UNKNOWN as non-imported)
1219
+ if imported is True:
1220
+ var_list = [v for v in var_list if v.is_imported is True]
1221
+ elif imported is False:
1222
+ var_list = [v for v in var_list if v.is_imported is not True]
1223
+
1224
+ # Detailed filter
1225
+ if detailed is True:
1226
+ var_list = [v for v in var_list if v.is_detailed() is True]
1227
+ elif detailed is False:
1228
+ var_list = [v for v in var_list if v.is_detailed() is not True]
1229
+
1230
+ # [xx] Modules are not currently included in any of these
1231
+ # value types.
1232
+ if value_type is None:
1233
+ return var_list
1234
+ elif value_type == 'class':
1235
+ return [var_doc for var_doc in var_list
1236
+ if (isinstance(var_doc.value, ClassDoc))]
1237
+ elif value_type == 'function':
1238
+ return [var_doc for var_doc in var_list
1239
+ if isinstance(var_doc.value, RoutineDoc)]
1240
+ elif value_type == 'other':
1241
+ return [var_doc for var_doc in var_list
1242
+ if not isinstance(var_doc.value,
1243
+ (ClassDoc, RoutineDoc, ModuleDoc))]
1244
+ else:
1245
+ raise ValueError('Bad value type %r' % value_type)
1246
+
1247
+ class ClassDoc(NamespaceDoc):
1248
+ """
1249
+ API documentation information about a single class.
1250
+ """
1251
+ #{ Information about Base Classes
1252
+ bases = UNKNOWN
1253
+ """@ivar: API documentation for the class's base classes.
1254
+ @type: C{list} of L{ClassDoc}"""
1255
+ #{ Information about Subclasses
1256
+ subclasses = UNKNOWN
1257
+ """@ivar: API documentation for the class's known subclasses.
1258
+ @type: C{list} of L{ClassDoc}"""
1259
+ #}
1260
+
1261
+ def apidoc_links(self, **filters):
1262
+ val_docs = NamespaceDoc.apidoc_links(self, **filters)
1263
+ if (filters.get('bases', True) and
1264
+ self.bases not in (None, UNKNOWN)):
1265
+ val_docs += self.bases
1266
+ if (filters.get('subclasses', True) and
1267
+ self.subclasses not in (None, UNKNOWN)):
1268
+ val_docs += self.subclasses
1269
+ return val_docs
1270
+
1271
+ def is_type(self):
1272
+ if self.canonical_name == DottedName('type'): return True
1273
+ if self.bases is UNKNOWN: return False
1274
+ for base in self.bases:
1275
+ if isinstance(base, ClassDoc) and base.is_type():
1276
+ return True
1277
+ return False
1278
+
1279
+ def is_exception(self):
1280
+ if self.canonical_name == DottedName('Exception'): return True
1281
+ if self.bases is UNKNOWN: return False
1282
+ for base in self.bases:
1283
+ if isinstance(base, ClassDoc) and base.is_exception():
1284
+ return True
1285
+ return False
1286
+
1287
+ def is_newstyle_class(self):
1288
+ if self.canonical_name == DottedName('object'): return True
1289
+ if self.bases is UNKNOWN: return False
1290
+ for base in self.bases:
1291
+ if isinstance(base, ClassDoc) and base.is_newstyle_class():
1292
+ return True
1293
+ return False
1294
+
1295
+ def mro(self, warn_about_bad_bases=False):
1296
+ if self.is_newstyle_class():
1297
+ return self._c3_mro(warn_about_bad_bases)
1298
+ else:
1299
+ return self._dfs_bases([], set(), warn_about_bad_bases)
1300
+
1301
+ def _dfs_bases(self, mro, seen, warn_about_bad_bases):
1302
+ if self in seen: return mro
1303
+ mro.append(self)
1304
+ seen.add(self)
1305
+ if self.bases is not UNKNOWN:
1306
+ for base in self.bases:
1307
+ if isinstance(base, ClassDoc) and base.proxy_for is None:
1308
+ base._dfs_bases(mro, seen, warn_about_bad_bases)
1309
+ elif warn_about_bad_bases:
1310
+ self._report_bad_base(base)
1311
+ return mro
1312
+
1313
+ def _c3_mro(self, warn_about_bad_bases):
1314
+ """
1315
+ Compute the class precedence list (mro) according to C3.
1316
+ @seealso: U{http://www.python.org/2.3/mro.html}
1317
+ """
1318
+ bases = [base for base in self.bases if isinstance(base, ClassDoc)]
1319
+ if len(bases) != len(self.bases) and warn_about_bad_bases:
1320
+ for base in self.bases:
1321
+ if (not isinstance(base, ClassDoc) or
1322
+ base.proxy_for is not None):
1323
+ self._report_bad_base(base)
1324
+ w = [warn_about_bad_bases]*len(bases)
1325
+ return self._c3_merge([[self]] + map(ClassDoc._c3_mro, bases, w) +
1326
+ [list(bases)])
1327
+
1328
+ def _report_bad_base(self, base):
1329
+ if not isinstance(base, ClassDoc):
1330
+ if not isinstance(base, GenericValueDoc):
1331
+ base_name = base.canonical_name
1332
+ elif base.parse_repr is not UNKNOWN:
1333
+ base_name = base.parse_repr
1334
+ else:
1335
+ base_name = '%r' % base
1336
+ log.warning("%s's base %s is not a class" %
1337
+ (self.canonical_name, base_name))
1338
+ elif base.proxy_for is not None:
1339
+ log.warning("No information available for %s's base %s" %
1340
+ (self.canonical_name, base.proxy_for))
1341
+
1342
+ def _c3_merge(self, seqs):
1343
+ """
1344
+ Helper function for L{_c3_mro}.
1345
+ """
1346
+ res = []
1347
+ while 1:
1348
+ nonemptyseqs=[seq for seq in seqs if seq]
1349
+ if not nonemptyseqs: return res
1350
+ for seq in nonemptyseqs: # find merge candidates among seq heads
1351
+ cand = seq[0]
1352
+ nothead=[s for s in nonemptyseqs if cand in s[1:]]
1353
+ if nothead: cand=None #reject candidate
1354
+ else: break
1355
+ if not cand: raise "Inconsistent hierarchy"
1356
+ res.append(cand)
1357
+ for seq in nonemptyseqs: # remove cand
1358
+ if seq[0] == cand: del seq[0]
1359
+
1360
+ def select_variables(self, group=None, value_type=None, inherited=None,
1361
+ public=None, imported=None, detailed=None):
1362
+ """
1363
+ Return a specified subset of this class's L{sorted_variables}
1364
+ list. If C{value_type} is given, then only return variables
1365
+ whose values have the specified type. If C{group} is given,
1366
+ then only return variables that belong to the specified group.
1367
+ If C{inherited} is True, then only return inherited variables;
1368
+ if C{inherited} is False, then only return local variables.
1369
+
1370
+ @require: The L{sorted_variables} and L{variable_groups}
1371
+ attributes must be initialized before this method can be
1372
+ used. See L{init_sorted_variables()} and
1373
+ L{init_variable_groups()}.
1374
+
1375
+ @param value_type: A string specifying the value type for
1376
+ which variables should be returned. Valid values are:
1377
+ - 'instancemethod' - variables whose values are
1378
+ instance methods.
1379
+ - 'classmethod' - variables whose values are class
1380
+ methods.
1381
+ - 'staticmethod' - variables whose values are static
1382
+ methods.
1383
+ - 'properties' - variables whose values are properties.
1384
+ - 'class' - variables whose values are nested classes
1385
+ (including exceptions and types).
1386
+ - 'instancevariable' - instance variables. This includes
1387
+ any variables that are explicitly marked as instance
1388
+ variables with docstring fields; and variables with
1389
+ docstrings that are initialized in the constructor.
1390
+ - 'classvariable' - class variables. This includes any
1391
+ variables that are not included in any of the above
1392
+ categories.
1393
+ @type value_type: C{string}
1394
+
1395
+ @param group: The name of the group for which variables should
1396
+ be returned. A complete list of the groups defined by
1397
+ this C{ClassDoc} is available in the L{group_names}
1398
+ instance variable. The first element of this list is
1399
+ always the special group name C{''}, which is used for
1400
+ variables that do not belong to any group.
1401
+ @type group: C{string}
1402
+
1403
+ @param inherited: If C{None}, then return both inherited and
1404
+ local variables; if C{True}, then return only inherited
1405
+ variables; if C{False}, then return only local variables.
1406
+
1407
+ @param detailed: If True (False), return only the variables
1408
+ deserving (not deserving) a detailed informative box.
1409
+ If C{None}, don't care.
1410
+ @type detailed: C{bool}
1411
+ """
1412
+ if (self.sorted_variables is UNKNOWN or
1413
+ self.variable_groups is UNKNOWN):
1414
+ raise ValueError('sorted_variables and variable_groups '
1415
+ 'must be initialized first.')
1416
+
1417
+ if group is None: var_list = self.sorted_variables
1418
+ else: var_list = self.variable_groups[group]
1419
+
1420
+ # Public/private filter (Count UNKNOWN as public)
1421
+ if public is True:
1422
+ var_list = [v for v in var_list if v.is_public is not False]
1423
+ elif public is False:
1424
+ var_list = [v for v in var_list if v.is_public is False]
1425
+
1426
+ # Inherited filter (Count UNKNOWN as non-inherited)
1427
+ if inherited is None: pass
1428
+ elif inherited:
1429
+ var_list = [v for v in var_list if v.container != self]
1430
+ else:
1431
+ var_list = [v for v in var_list if v.container == self ]
1432
+
1433
+ # Imported filter (Count UNKNOWN as non-imported)
1434
+ if imported is True:
1435
+ var_list = [v for v in var_list if v.is_imported is True]
1436
+ elif imported is False:
1437
+ var_list = [v for v in var_list if v.is_imported is not True]
1438
+
1439
+ # Detailed filter
1440
+ if detailed is True:
1441
+ var_list = [v for v in var_list if v.is_detailed() is True]
1442
+ elif detailed is False:
1443
+ var_list = [v for v in var_list if v.is_detailed() is not True]
1444
+
1445
+ if value_type is None:
1446
+ return var_list
1447
+ elif value_type == 'method':
1448
+ return [var_doc for var_doc in var_list
1449
+ if (isinstance(var_doc.value, RoutineDoc) and
1450
+ var_doc.is_instvar in (False, UNKNOWN))]
1451
+ elif value_type == 'instancemethod':
1452
+ return [var_doc for var_doc in var_list
1453
+ if (isinstance(var_doc.value, RoutineDoc) and
1454
+ not isinstance(var_doc.value, ClassMethodDoc) and
1455
+ not isinstance(var_doc.value, StaticMethodDoc) and
1456
+ var_doc.is_instvar in (False, UNKNOWN))]
1457
+ elif value_type == 'classmethod':
1458
+ return [var_doc for var_doc in var_list
1459
+ if (isinstance(var_doc.value, ClassMethodDoc) and
1460
+ var_doc.is_instvar in (False, UNKNOWN))]
1461
+ elif value_type == 'staticmethod':
1462
+ return [var_doc for var_doc in var_list
1463
+ if (isinstance(var_doc.value, StaticMethodDoc) and
1464
+ var_doc.is_instvar in (False, UNKNOWN))]
1465
+ elif value_type == 'property':
1466
+ return [var_doc for var_doc in var_list
1467
+ if (isinstance(var_doc.value, PropertyDoc) and
1468
+ var_doc.is_instvar in (False, UNKNOWN))]
1469
+ elif value_type == 'class':
1470
+ return [var_doc for var_doc in var_list
1471
+ if (isinstance(var_doc.value, ClassDoc) and
1472
+ var_doc.is_instvar in (False, UNKNOWN))]
1473
+ elif value_type == 'instancevariable':
1474
+ return [var_doc for var_doc in var_list
1475
+ if var_doc.is_instvar is True]
1476
+ elif value_type == 'classvariable':
1477
+ return [var_doc for var_doc in var_list
1478
+ if (var_doc.is_instvar in (False, UNKNOWN) and
1479
+ not isinstance(var_doc.value,
1480
+ (RoutineDoc, ClassDoc, PropertyDoc)))]
1481
+ else:
1482
+ raise ValueError('Bad value type %r' % value_type)
1483
+
1484
+ class RoutineDoc(ValueDoc):
1485
+ """
1486
+ API documentation information about a single routine.
1487
+ """
1488
+ #{ Signature
1489
+ posargs = UNKNOWN
1490
+ """@ivar: The names of the routine's positional arguments.
1491
+ If an argument list contains \"unpacking\" arguments, then
1492
+ their names will be specified using nested lists. E.g., if
1493
+ a function's argument list is C{((x1,y1), (x2,y2))}, then
1494
+ posargs will be C{[['x1','y1'], ['x2','y2']]}.
1495
+ @type: C{list}"""
1496
+ posarg_defaults = UNKNOWN
1497
+ """@ivar: API documentation for the positional arguments'
1498
+ default values. This list has the same length as C{posargs}, and
1499
+ each element of C{posarg_defaults} describes the corresponding
1500
+ argument in C{posargs}. For positional arguments with no default,
1501
+ C{posargs_defaults} will contain None.
1502
+ @type: C{list} of C{ValueDoc} or C{None}"""
1503
+ vararg = UNKNOWN
1504
+ """@ivar: The name of the routine's vararg argument, or C{None} if
1505
+ it has no vararg argument.
1506
+ @type: C{string} or C{None}"""
1507
+ kwarg = UNKNOWN
1508
+ """@ivar: The name of the routine's keyword argument, or C{None} if
1509
+ it has no keyword argument.
1510
+ @type: C{string} or C{None}"""
1511
+ lineno = UNKNOWN # used to look up profiling info from pstats.
1512
+ """@ivar: The line number of the first line of the function's
1513
+ signature. For Python functions, this is equal to
1514
+ C{func.func_code.co_firstlineno}. The first line of a file
1515
+ is considered line 1.
1516
+ @type: C{int}"""
1517
+ #} end of "signature" group
1518
+
1519
+ #{ Decorators
1520
+ decorators = UNKNOWN
1521
+ """@ivar: A list of names of decorators that were applied to this
1522
+ routine, in the order that they are listed in the source code.
1523
+ (I.e., in the reverse of the order that they were applied in.)
1524
+ @type: C{list} of C{string}"""
1525
+ #} end of "decorators" group
1526
+
1527
+ #{ Information Extracted from Docstrings
1528
+ arg_descrs = UNKNOWN
1529
+ """@ivar: A list of descriptions of the routine's
1530
+ arguments. Each element of this list is a tuple C{(args,
1531
+ descr)}, where C{args} is a list of argument names; and
1532
+ C{descr} is a L{ParsedDocstring
1533
+ <epydoc.markup.ParsedDocstring>} describing the argument(s)
1534
+ specified by C{arg}.
1535
+ @type: C{list}"""
1536
+ arg_types = UNKNOWN
1537
+ """@ivar: Descriptions of the expected types for the
1538
+ routine's arguments, encoded as a dictionary mapping from
1539
+ argument names to type descriptions.
1540
+ @type: C{dict} from C{string} to L{ParsedDocstring
1541
+ <epydoc.markup.ParsedDocstring>}"""
1542
+ return_descr = UNKNOWN
1543
+ """@ivar: A description of the value returned by this routine.
1544
+ @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}"""
1545
+ return_type = UNKNOWN
1546
+ """@ivar: A description of expected type for the value
1547
+ returned by this routine.
1548
+ @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}"""
1549
+ exception_descrs = UNKNOWN
1550
+ """@ivar: A list of descriptions of exceptions
1551
+ that the routine might raise. Each element of this list is a
1552
+ tuple C{(exc, descr)}, where C{exc} is a string contianing the
1553
+ exception name; and C{descr} is a L{ParsedDocstring
1554
+ <epydoc.markup.ParsedDocstring>} describing the circumstances
1555
+ under which the exception specified by C{exc} is raised.
1556
+ @type: C{list}"""
1557
+ #} end of "information extracted from docstrings" group
1558
+ callgraph_uid = None
1559
+ """@ivar: L{DotGraph}.uid of the call graph for the function.
1560
+ @type: C{str}"""
1561
+
1562
+ def is_detailed(self):
1563
+ if super(RoutineDoc, self).is_detailed():
1564
+ return True
1565
+
1566
+ if self.arg_descrs not in (None, UNKNOWN) and self.arg_descrs:
1567
+ return True
1568
+
1569
+ if self.arg_types not in (None, UNKNOWN) and self.arg_types:
1570
+ return True
1571
+
1572
+ if self.return_descr not in (None, UNKNOWN):
1573
+ return True
1574
+
1575
+ if self.exception_descrs not in (None, UNKNOWN) and self.exception_descrs:
1576
+ return True
1577
+
1578
+ if (self.decorators not in (None, UNKNOWN)
1579
+ and [ d for d in self.decorators
1580
+ if d not in ('classmethod', 'staticmethod') ]):
1581
+ return True
1582
+
1583
+ return False
1584
+
1585
+ def all_args(self):
1586
+ """
1587
+ @return: A list of the names of all arguments (positional,
1588
+ vararg, and keyword), in order. If a positional argument
1589
+ consists of a tuple of names, then that tuple will be
1590
+ flattened.
1591
+ """
1592
+ if self.posargs is UNKNOWN:
1593
+ return UNKNOWN
1594
+
1595
+ all_args = _flatten(self.posargs)
1596
+ if self.vararg not in (None, UNKNOWN):
1597
+ all_args.append(self.vararg)
1598
+ if self.kwarg not in (None, UNKNOWN):
1599
+ all_args.append(self.kwarg)
1600
+ return all_args
1601
+
1602
+ def _flatten(lst, out=None):
1603
+ """
1604
+ Return a flattened version of C{lst}.
1605
+ """
1606
+ if out is None: out = []
1607
+ for elt in lst:
1608
+ if isinstance(elt, (list,tuple)):
1609
+ _flatten(elt, out)
1610
+ else:
1611
+ out.append(elt)
1612
+ return out
1613
+
1614
+ class ClassMethodDoc(RoutineDoc): pass
1615
+ class StaticMethodDoc(RoutineDoc): pass
1616
+
1617
+ class PropertyDoc(ValueDoc):
1618
+ """
1619
+ API documentation information about a single property.
1620
+ """
1621
+ #{ Property Access Functions
1622
+ fget = UNKNOWN
1623
+ """@ivar: API documentation for the property's get function.
1624
+ @type: L{RoutineDoc}"""
1625
+ fset = UNKNOWN
1626
+ """@ivar: API documentation for the property's set function.
1627
+ @type: L{RoutineDoc}"""
1628
+ fdel = UNKNOWN
1629
+ """@ivar: API documentation for the property's delete function.
1630
+ @type: L{RoutineDoc}"""
1631
+ #}
1632
+ #{ Information Extracted from Docstrings
1633
+ type_descr = UNKNOWN
1634
+ """@ivar: A description of the property's expected type, extracted
1635
+ from its docstring.
1636
+ @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}"""
1637
+ #} end of "information extracted from docstrings" group
1638
+
1639
+ def apidoc_links(self, **filters):
1640
+ val_docs = []
1641
+ if self.fget not in (None, UNKNOWN): val_docs.append(self.fget)
1642
+ if self.fset not in (None, UNKNOWN): val_docs.append(self.fset)
1643
+ if self.fdel not in (None, UNKNOWN): val_docs.append(self.fdel)
1644
+ return val_docs
1645
+
1646
+ def is_detailed(self):
1647
+ if super(PropertyDoc, self).is_detailed():
1648
+ return True
1649
+
1650
+ if self.fget not in (None, UNKNOWN) and self.fget.pyval is not None:
1651
+ return True
1652
+ if self.fset not in (None, UNKNOWN) and self.fset.pyval is not None:
1653
+ return True
1654
+ if self.fdel not in (None, UNKNOWN) and self.fdel.pyval is not None:
1655
+ return True
1656
+
1657
+ return False
1658
+
1659
+ ######################################################################
1660
+ ## Index
1661
+ ######################################################################
1662
+
1663
+ class DocIndex:
1664
+ """
1665
+ [xx] out of date.
1666
+
1667
+ An index that .. hmm... it *can't* be used to access some things,
1668
+ cuz they're not at the root level. Do I want to add them or what?
1669
+ And if so, then I have a sort of a new top level. hmm.. so
1670
+ basically the question is what to do with a name that's not in the
1671
+ root var's name space. 2 types:
1672
+ - entirely outside (eg os.path)
1673
+ - inside but not known (eg a submodule that we didn't look at?)
1674
+ - container of current thing not examined?
1675
+
1676
+ An index of all the C{APIDoc} objects that can be reached from a
1677
+ root set of C{ValueDoc}s.
1678
+
1679
+ The members of this index can be accessed by dotted name. In
1680
+ particular, C{DocIndex} defines two mappings, accessed via the
1681
+ L{get_vardoc()} and L{get_valdoc()} methods, which can be used to
1682
+ access C{VariableDoc}s or C{ValueDoc}s respectively by name. (Two
1683
+ separate mappings are necessary because a single name can be used
1684
+ to refer to both a variable and to the value contained by that
1685
+ variable.)
1686
+
1687
+ Additionally, the index defines two sets of C{ValueDoc}s:
1688
+ \"reachable C{ValueDoc}s\" and \"contained C{ValueDoc}s\". The
1689
+ X{reachable C{ValueDoc}s} are defined as the set of all
1690
+ C{ValueDoc}s that can be reached from the root set by following
1691
+ I{any} sequence of pointers to C{ValueDoc}s or C{VariableDoc}s.
1692
+ The X{contained C{ValueDoc}s} are defined as the set of all
1693
+ C{ValueDoc}s that can be reached from the root set by following
1694
+ only the C{ValueDoc} pointers defined by non-imported
1695
+ C{VariableDoc}s. For example, if the root set contains a module
1696
+ C{m}, then the contained C{ValueDoc}s includes the C{ValueDoc}s
1697
+ for any functions, variables, or classes defined in that module,
1698
+ as well as methods and variables defined in classes defined in the
1699
+ module. The reachable C{ValueDoc}s includes all of those
1700
+ C{ValueDoc}s, as well as C{ValueDoc}s for any values imported into
1701
+ the module, and base classes for classes defined in the module.
1702
+ """
1703
+
1704
+ def __init__(self, root):
1705
+ """
1706
+ Create a new documentation index, based on the given root set
1707
+ of C{ValueDoc}s. If any C{APIDoc}s reachable from the root
1708
+ set does not have a canonical name, then it will be assigned
1709
+ one. etc.
1710
+
1711
+ @param root: A list of C{ValueDoc}s.
1712
+ """
1713
+ for apidoc in root:
1714
+ if apidoc.canonical_name in (None, UNKNOWN):
1715
+ raise ValueError("All APIdocs passed to DocIndexer "
1716
+ "must already have canonical names.")
1717
+
1718
+ # Initialize the root items list. We sort them by length in
1719
+ # ascending order. (This ensures that variables will shadow
1720
+ # submodules when appropriate.)
1721
+ # When the elements name is the same, list in alphabetical order:
1722
+ # this is needed by the check for duplicates below.
1723
+ self.root = sorted(root,
1724
+ key=lambda d: (len(d.canonical_name), d.canonical_name))
1725
+ """The list of C{ValueDoc}s to document.
1726
+ @type: C{list}"""
1727
+
1728
+ # Drop duplicated modules
1729
+ # [xx] maybe what causes duplicates should be fixed instead.
1730
+ # If fixed, adjust the sort here above: sorting by names will not
1731
+ # be required anymore
1732
+ i = 1
1733
+ while i < len(self.root):
1734
+ if self.root[i-1] is self.root[i]:
1735
+ del self.root[i]
1736
+ else:
1737
+ i += 1
1738
+
1739
+ self.mlclasses = self._get_module_classes(self.root)
1740
+ """A mapping from class names to L{ClassDoc}. Contains
1741
+ classes defined at module level for modules in L{root}
1742
+ and which can be used as fallback by L{find()} if looking
1743
+ in containing namespaces fails.
1744
+ @type: C{dict} from C{str} to L{ClassDoc} or C{list}"""
1745
+
1746
+ self.callers = None
1747
+ """A dictionary mapping from C{RoutineDoc}s in this index
1748
+ to lists of C{RoutineDoc}s for the routine's callers.
1749
+ This dictionary is initialized by calling
1750
+ L{read_profiling_info()}.
1751
+ @type: C{list} of L{RoutineDoc}"""
1752
+
1753
+ self.callees = None
1754
+ """A dictionary mapping from C{RoutineDoc}s in this index
1755
+ to lists of C{RoutineDoc}s for the routine's callees.
1756
+ This dictionary is initialized by calling
1757
+ L{read_profiling_info()}.
1758
+ @type: C{list} of L{RoutineDoc}"""
1759
+
1760
+ self._funcid_to_doc = {}
1761
+ """A mapping from C{profile} function ids to corresponding
1762
+ C{APIDoc} objects. A function id is a tuple of the form
1763
+ C{(filename, lineno, funcname)}. This is used to update
1764
+ the L{callers} and L{callees} variables."""
1765
+
1766
+ self._container_cache = {}
1767
+ """A cache for the L{container()} method, to increase speed."""
1768
+
1769
+ self._get_cache = {}
1770
+ """A cache for the L{get_vardoc()} and L{get_valdoc()} methods,
1771
+ to increase speed."""
1772
+
1773
+ #////////////////////////////////////////////////////////////
1774
+ # Lookup methods
1775
+ #////////////////////////////////////////////////////////////
1776
+ # [xx]
1777
+ # Currently these only work for things reachable from the
1778
+ # root... :-/ I might want to change this so that imported
1779
+ # values can be accessed even if they're not contained.
1780
+ # Also, I might want canonical names to not start with ??
1781
+ # if the thing is a top-level imported module..?
1782
+
1783
+ def get_vardoc(self, name):
1784
+ """
1785
+ Return the C{VariableDoc} with the given name, or C{None} if this
1786
+ index does not contain a C{VariableDoc} with the given name.
1787
+ """
1788
+ var, val = self._get(name)
1789
+ return var
1790
+
1791
+ def get_valdoc(self, name):
1792
+ """
1793
+ Return the C{ValueDoc} with the given name, or C{None} if this
1794
+ index does not contain a C{ValueDoc} with the given name.
1795
+ """
1796
+ var, val = self._get(name)
1797
+ return val
1798
+
1799
+ def _get(self, name):
1800
+ """
1801
+ A helper function that's used to implement L{get_vardoc()}
1802
+ and L{get_valdoc()}.
1803
+ """
1804
+ # Convert name to a DottedName, if necessary.
1805
+ if not isinstance(name, DottedName):
1806
+ name = DottedName(name)
1807
+
1808
+ # Check if the result is cached.
1809
+ val = self._get_cache.get(name)
1810
+ if val is not None: return val
1811
+
1812
+ # Look for an element in the root set whose name is a prefix
1813
+ # of `name`. If we can't find one, then return None.
1814
+ for root_valdoc in self.root:
1815
+ if root_valdoc.canonical_name.dominates(name):
1816
+ # Starting at the root valdoc, walk down the variable/
1817
+ # submodule chain until we find the requested item.
1818
+ var_doc = None
1819
+ val_doc = root_valdoc
1820
+ for identifier in name[len(root_valdoc.canonical_name):]:
1821
+ if val_doc is None: break
1822
+ var_doc, val_doc = self._get_from(val_doc, identifier)
1823
+ else:
1824
+ # If we found it, then return.
1825
+ if var_doc is not None or val_doc is not None:
1826
+ self._get_cache[name] = (var_doc, val_doc)
1827
+ return var_doc, val_doc
1828
+
1829
+ # We didn't find it.
1830
+ self._get_cache[name] = (None, None)
1831
+ return None, None
1832
+
1833
+ def _get_from(self, val_doc, identifier):
1834
+ if isinstance(val_doc, NamespaceDoc):
1835
+ child_var = val_doc.variables.get(identifier)
1836
+ if child_var is not None:
1837
+ child_val = child_var.value
1838
+ if child_val is UNKNOWN: child_val = None
1839
+ return child_var, child_val
1840
+
1841
+ # If that fails, then see if it's a submodule.
1842
+ if (isinstance(val_doc, ModuleDoc) and
1843
+ val_doc.submodules is not UNKNOWN):
1844
+ for submodule in val_doc.submodules:
1845
+ if submodule.canonical_name[-1] == identifier:
1846
+ var_doc = None
1847
+ val_doc = submodule
1848
+ if val_doc is UNKNOWN: val_doc = None
1849
+ return var_doc, val_doc
1850
+
1851
+ return None, None
1852
+
1853
+ def find(self, name, context):
1854
+ """
1855
+ Look for an C{APIDoc} named C{name}, relative to C{context}.
1856
+ Return the C{APIDoc} if one is found; otherwise, return
1857
+ C{None}. C{find} looks in the following places, in order:
1858
+ - Function parameters (if one matches, return C{None})
1859
+ - All enclosing namespaces, from closest to furthest.
1860
+ - If C{name} starts with C{'self'}, then strip it off and
1861
+ look for the remaining part of the name using C{find}
1862
+ - Builtins
1863
+ - Parameter attributes
1864
+ - Classes at module level (if the name is not ambiguous)
1865
+
1866
+ @type name: C{str} or L{DottedName}
1867
+ @type context: L{APIDoc}
1868
+ """
1869
+ if isinstance(name, basestring):
1870
+ name = re.sub(r'\(.*\)$', '', name.strip())
1871
+ if re.match('^([a-zA-Z_]\w*)(\.[a-zA-Z_]\w*)*$', name):
1872
+ name = DottedName(name)
1873
+ else:
1874
+ return None
1875
+ elif not isinstance(name, DottedName):
1876
+ raise TypeError("'name' should be a string or DottedName")
1877
+
1878
+ if context is None or context.canonical_name is None:
1879
+ container_name = []
1880
+ else:
1881
+ container_name = context.canonical_name
1882
+
1883
+ # Check for the name in all containing namespaces, starting
1884
+ # with the closest one.
1885
+ for i in range(len(container_name), -1, -1):
1886
+ relative_name = container_name[:i]+name
1887
+ # Is `name` the absolute name of a documented value?
1888
+ # (excepting GenericValueDoc values.)
1889
+ val_doc = self.get_valdoc(relative_name)
1890
+ if (val_doc is not None and
1891
+ not isinstance(val_doc, GenericValueDoc)):
1892
+ return val_doc
1893
+ # Is `name` the absolute name of a documented variable?
1894
+ var_doc = self.get_vardoc(relative_name)
1895
+ if var_doc is not None: return var_doc
1896
+
1897
+ # If the name begins with 'self', then try stripping that off
1898
+ # and see if we can find the variable.
1899
+ if name[0] == 'self':
1900
+ doc = self.find('.'.join(name[1:]), context)
1901
+ if doc is not None: return doc
1902
+
1903
+ # Is it the name of a builtin?
1904
+ if len(name)==1 and hasattr(__builtin__, name[0]):
1905
+ return None
1906
+
1907
+ # Is it a parameter's name or an attribute of a parameter?
1908
+ if isinstance(context, RoutineDoc):
1909
+ all_args = context.all_args()
1910
+ if all_args is not UNKNOWN and name[0] in all_args:
1911
+ return None
1912
+
1913
+ # Is this an object directly contained by any module?
1914
+ doc = self.mlclasses.get(name[-1])
1915
+ if isinstance(doc, APIDoc):
1916
+ return doc
1917
+ elif isinstance(doc, list):
1918
+ log.warning("%s is an ambiguous name: it may be %s" % (
1919
+ name[-1],
1920
+ ", ".join([ "'%s'" % d.canonical_name for d in doc ])))
1921
+
1922
+ # Drop this item so that the warning is reported only once.
1923
+ # fail() will fail anyway.
1924
+ del self.mlclasses[name[-1]]
1925
+
1926
+ def _get_module_classes(self, docs):
1927
+ """
1928
+ Gather all the classes defined in a list of modules.
1929
+
1930
+ Very often people refers to classes only by class name,
1931
+ even if they are not imported in the namespace. Linking
1932
+ to such classes will fail if we look for them only in nested
1933
+ namespaces. Allow them to retrieve only by name.
1934
+
1935
+ @param docs: containers of the objects to collect
1936
+ @type docs: C{list} of C{APIDoc}
1937
+ @return: mapping from objects name to the object(s) with that name
1938
+ @rtype: C{dict} from C{str} to L{ClassDoc} or C{list}
1939
+ """
1940
+ classes = {}
1941
+ for doc in docs:
1942
+ if not isinstance(doc, ModuleDoc):
1943
+ continue
1944
+
1945
+ for var in doc.variables.values():
1946
+ if not isinstance(var.value, ClassDoc):
1947
+ continue
1948
+
1949
+ val = var.value
1950
+ if val in (None, UNKNOWN) or val.defining_module is not doc:
1951
+ continue
1952
+ if val.canonical_name in (None, UNKNOWN):
1953
+ continue
1954
+
1955
+ name = val.canonical_name[-1]
1956
+ vals = classes.get(name)
1957
+ if vals is None:
1958
+ classes[name] = val
1959
+ elif not isinstance(vals, list):
1960
+ classes[name] = [ vals, val ]
1961
+ else:
1962
+ vals.append(val)
1963
+
1964
+ return classes
1965
+
1966
+ #////////////////////////////////////////////////////////////
1967
+ # etc
1968
+ #////////////////////////////////////////////////////////////
1969
+
1970
+ def reachable_valdocs(self, **filters):
1971
+ """
1972
+ Return a list of all C{ValueDoc}s that can be reached,
1973
+ directly or indirectly from this C{DocIndex}'s root set.
1974
+
1975
+ @param filters: A set of filters that can be used to prevent
1976
+ C{reachable_valdocs} from following specific link types
1977
+ when looking for C{ValueDoc}s that can be reached from the
1978
+ root set. See C{APIDoc.apidoc_links} for a more complete
1979
+ description.
1980
+ """
1981
+ return reachable_valdocs(self.root, **filters)
1982
+
1983
+ def container(self, api_doc):
1984
+ """
1985
+ Return the C{ValueDoc} that contains the given C{APIDoc}, or
1986
+ C{None} if its container is not in the index.
1987
+ """
1988
+ # Check if the result is cached.
1989
+ val = self._container_cache.get(api_doc)
1990
+ if val is not None: return val
1991
+
1992
+ if isinstance(api_doc, GenericValueDoc):
1993
+ self._container_cache[api_doc] = None
1994
+ return None # [xx] unknown.
1995
+ if isinstance(api_doc, VariableDoc):
1996
+ self._container_cache[api_doc] = api_doc.container
1997
+ return api_doc.container
1998
+ if len(api_doc.canonical_name) == 1:
1999
+ self._container_cache[api_doc] = None
2000
+ return None
2001
+ elif isinstance(api_doc, ModuleDoc) and api_doc.package is not UNKNOWN:
2002
+ self._container_cache[api_doc] = api_doc.package
2003
+ return api_doc.package
2004
+ else:
2005
+ parent = self.get_valdoc(api_doc.canonical_name.container())
2006
+ self._container_cache[api_doc] = parent
2007
+ return parent
2008
+
2009
+ #////////////////////////////////////////////////////////////
2010
+ # Profiling information
2011
+ #////////////////////////////////////////////////////////////
2012
+
2013
+ def read_profiling_info(self, profile_stats):
2014
+ """
2015
+ Initialize the L{callers} and L{callees} variables, given a
2016
+ C{Stat} object from the C{pstats} module.
2017
+
2018
+ @warning: This method uses undocumented data structures inside
2019
+ of C{profile_stats}.
2020
+ """
2021
+ if self.callers is None: self.callers = {}
2022
+ if self.callees is None: self.callees = {}
2023
+
2024
+ # The Stat object encodes functions using `funcid`s, or
2025
+ # tuples of (filename, lineno, funcname). Create a mapping
2026
+ # from these `funcid`s to `RoutineDoc`s.
2027
+ self._update_funcid_to_doc(profile_stats)
2028
+
2029
+ for callee, (cc, nc, tt, ct, callers) in profile_stats.stats.items():
2030
+ callee = self._funcid_to_doc.get(callee)
2031
+ if callee is None: continue
2032
+ for caller in callers:
2033
+ caller = self._funcid_to_doc.get(caller)
2034
+ if caller is None: continue
2035
+ self.callers.setdefault(callee, []).append(caller)
2036
+ self.callees.setdefault(caller, []).append(callee)
2037
+
2038
+ def _update_funcid_to_doc(self, profile_stats):
2039
+ """
2040
+ Update the dictionary mapping from C{pstat.Stat} funciton ids to
2041
+ C{RoutineDoc}s. C{pstat.Stat} function ids are tuples of
2042
+ C{(filename, lineno, funcname)}.
2043
+ """
2044
+ # Maps (filename, lineno, funcname) -> RoutineDoc
2045
+ for val_doc in self.reachable_valdocs():
2046
+ # We only care about routines.
2047
+ if not isinstance(val_doc, RoutineDoc): continue
2048
+ # Get the filename from the defining module.
2049
+ module = val_doc.defining_module
2050
+ if module is UNKNOWN or module.filename is UNKNOWN: continue
2051
+ # Normalize the filename.
2052
+ filename = os.path.abspath(module.filename)
2053
+ try: filename = py_src_filename(filename)
2054
+ except: pass
2055
+ # Look up the stat_func_id
2056
+ funcid = (filename, val_doc.lineno, val_doc.canonical_name[-1])
2057
+ if funcid in profile_stats.stats:
2058
+ self._funcid_to_doc[funcid] = val_doc
2059
+
2060
+ ######################################################################
2061
+ ## Pretty Printing
2062
+ ######################################################################
2063
+
2064
+ def pp_apidoc(api_doc, doublespace=0, depth=5, exclude=(), include=(),
2065
+ backpointers=None):
2066
+ """
2067
+ @return: A multiline pretty-printed string representation for the
2068
+ given C{APIDoc}.
2069
+ @param doublespace: If true, then extra lines will be
2070
+ inserted to make the output more readable.
2071
+ @param depth: The maximum depth that pp_apidoc will descend
2072
+ into descendent VarDocs. To put no limit on
2073
+ depth, use C{depth=-1}.
2074
+ @param exclude: A list of names of attributes whose values should
2075
+ not be shown.
2076
+ @param backpointers: For internal use.
2077
+ """
2078
+ pyid = id(api_doc.__dict__)
2079
+ if backpointers is None: backpointers = {}
2080
+ if (hasattr(api_doc, 'canonical_name') and
2081
+ api_doc.canonical_name not in (None, UNKNOWN)):
2082
+ name = '%s for %s' % (api_doc.__class__.__name__,
2083
+ api_doc.canonical_name)
2084
+ elif getattr(api_doc, 'name', None) not in (UNKNOWN, None):
2085
+ if (getattr(api_doc, 'container', None) not in (UNKNOWN, None) and
2086
+ getattr(api_doc.container, 'canonical_name', None)
2087
+ not in (UNKNOWN, None)):
2088
+ name ='%s for %s' % (api_doc.__class__.__name__,
2089
+ api_doc.container.canonical_name+
2090
+ api_doc.name)
2091
+ else:
2092
+ name = '%s for %s' % (api_doc.__class__.__name__, api_doc.name)
2093
+ else:
2094
+ name = api_doc.__class__.__name__
2095
+
2096
+ if pyid in backpointers:
2097
+ return '%s [%s] (defined above)' % (name, backpointers[pyid])
2098
+
2099
+ if depth == 0:
2100
+ if hasattr(api_doc, 'name') and api_doc.name is not None:
2101
+ return '%s...' % api_doc.name
2102
+ else:
2103
+ return '...'
2104
+
2105
+ backpointers[pyid] = len(backpointers)
2106
+ s = '%s [%s]' % (name, backpointers[pyid])
2107
+
2108
+ # Only print non-empty fields:
2109
+ fields = [field for field in api_doc.__dict__.keys()
2110
+ if (field in include or
2111
+ (getattr(api_doc, field) is not UNKNOWN
2112
+ and field not in exclude))]
2113
+ if include:
2114
+ fields = [field for field in dir(api_doc)
2115
+ if field in include]
2116
+ else:
2117
+ fields = [field for field in api_doc.__dict__.keys()
2118
+ if (getattr(api_doc, field) is not UNKNOWN
2119
+ and field not in exclude)]
2120
+ fields.sort()
2121
+
2122
+ for field in fields:
2123
+ fieldval = getattr(api_doc, field)
2124
+ if doublespace: s += '\n |'
2125
+ s += '\n +- %s' % field
2126
+
2127
+ if (isinstance(fieldval, types.ListType) and
2128
+ len(fieldval)>0 and
2129
+ isinstance(fieldval[0], APIDoc)):
2130
+ s += _pp_list(api_doc, fieldval, doublespace, depth,
2131
+ exclude, include, backpointers,
2132
+ (field is fields[-1]))
2133
+ elif (isinstance(fieldval, types.DictType) and
2134
+ len(fieldval)>0 and
2135
+ isinstance(fieldval.values()[0], APIDoc)):
2136
+ s += _pp_dict(api_doc, fieldval, doublespace,
2137
+ depth, exclude, include, backpointers,
2138
+ (field is fields[-1]))
2139
+ elif isinstance(fieldval, APIDoc):
2140
+ s += _pp_apidoc(api_doc, fieldval, doublespace, depth,
2141
+ exclude, include, backpointers,
2142
+ (field is fields[-1]))
2143
+ else:
2144
+ s += ' = ' + _pp_val(api_doc, fieldval, doublespace,
2145
+ depth, exclude, include, backpointers)
2146
+
2147
+ return s
2148
+
2149
+ def _pp_list(api_doc, items, doublespace, depth, exclude, include,
2150
+ backpointers, is_last):
2151
+ line1 = (is_last and ' ') or '|'
2152
+ s = ''
2153
+ for item in items:
2154
+ line2 = ((item is items[-1]) and ' ') or '|'
2155
+ joiner = '\n %s %s ' % (line1, line2)
2156
+ if doublespace: s += '\n %s |' % line1
2157
+ s += '\n %s +- ' % line1
2158
+ valstr = _pp_val(api_doc, item, doublespace, depth, exclude, include,
2159
+ backpointers)
2160
+ s += joiner.join(valstr.split('\n'))
2161
+ return s
2162
+
2163
+ def _pp_dict(api_doc, dict, doublespace, depth, exclude, include,
2164
+ backpointers, is_last):
2165
+ items = dict.items()
2166
+ items.sort()
2167
+ line1 = (is_last and ' ') or '|'
2168
+ s = ''
2169
+ for item in items:
2170
+ line2 = ((item is items[-1]) and ' ') or '|'
2171
+ joiner = '\n %s %s ' % (line1, line2)
2172
+ if doublespace: s += '\n %s |' % line1
2173
+ s += '\n %s +- ' % line1
2174
+ valstr = _pp_val(api_doc, item[1], doublespace, depth, exclude,
2175
+ include, backpointers)
2176
+ s += joiner.join(('%s => %s' % (item[0], valstr)).split('\n'))
2177
+ return s
2178
+
2179
+ def _pp_apidoc(api_doc, val, doublespace, depth, exclude, include,
2180
+ backpointers, is_last):
2181
+ line1 = (is_last and ' ') or '|'
2182
+ s = ''
2183
+ if doublespace: s += '\n %s | ' % line1
2184
+ s += '\n %s +- ' % line1
2185
+ joiner = '\n %s ' % line1
2186
+ childstr = pp_apidoc(val, doublespace, depth-1, exclude,
2187
+ include, backpointers)
2188
+ return s + joiner.join(childstr.split('\n'))
2189
+
2190
+ def _pp_val(api_doc, val, doublespace, depth, exclude, include, backpointers):
2191
+ from epydoc import markup
2192
+ if isinstance(val, APIDoc):
2193
+ return pp_apidoc(val, doublespace, depth-1, exclude,
2194
+ include, backpointers)
2195
+ elif isinstance(val, markup.ParsedDocstring):
2196
+ valrepr = `val.to_plaintext(None)`
2197
+ if len(valrepr) < 40: return valrepr
2198
+ else: return valrepr[:37]+'...'
2199
+ else:
2200
+ valrepr = repr(val)
2201
+ if len(valrepr) < 40: return valrepr
2202
+ else: return valrepr[:37]+'...'
2203
+