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,1111 @@
1
+ # epydoc -- Docstring processing
2
+ #
3
+ # Copyright (C) 2005 Edward Loper
4
+ # Author: Edward Loper <edloper@loper.org>
5
+ # URL: <http://epydoc.sf.net>
6
+ #
7
+ # $Id: docstringparser.py,v 1.1 2009/11/26 13:20:41 casa Exp $
8
+
9
+ """
10
+ Parse docstrings and handle any fields it defines, such as C{@type}
11
+ and C{@author}. Fields are used to describe specific information
12
+ about an object. There are two classes of fields: X{simple fields}
13
+ and X{special fields}.
14
+
15
+ Simple fields are fields that get stored directly in an C{APIDoc}'s
16
+ metadata dictionary, without any special processing. The set of
17
+ simple fields is defined by the list L{STANDARD_FIELDS}, whose
18
+ elements are L{DocstringField}s.
19
+
20
+ Special fields are fields that perform some sort of processing on the
21
+ C{APIDoc}, or add information to attributes other than the metadata
22
+ dictionary. Special fields are are handled by field handler
23
+ functions, which are registered using L{register_field_handler}.
24
+ """
25
+ __docformat__ = 'epytext en'
26
+
27
+
28
+ ######################################################################
29
+ ## Imports
30
+ ######################################################################
31
+
32
+ import re, sys
33
+ from epydoc import markup
34
+ from epydoc.markup import epytext
35
+ from epydoc.apidoc import *
36
+ from epydoc.docintrospecter import introspect_docstring_lineno
37
+ from epydoc.util import py_src_filename
38
+ from epydoc import log
39
+ import epydoc.docparser
40
+ import __builtin__, exceptions
41
+
42
+ ######################################################################
43
+ # Docstring Fields
44
+ ######################################################################
45
+
46
+ class DocstringField:
47
+ """
48
+ A simple docstring field, which can be used to describe specific
49
+ information about an object, such as its author or its version.
50
+ Simple docstring fields are fields that take no arguments, and
51
+ are displayed as simple sections.
52
+
53
+ @ivar tags: The set of tags that can be used to identify this
54
+ field.
55
+ @ivar singular: The label that should be used to identify this
56
+ field in the output, if the field contains one value.
57
+ @ivar plural: The label that should be used to identify this
58
+ field in the output, if the field contains multiple values.
59
+ @ivar short: If true, then multiple values should be combined
60
+ into a single comma-delimited list. If false, then
61
+ multiple values should be listed separately in a bulleted
62
+ list.
63
+ @ivar multivalue: If true, then multiple values may be given
64
+ for this field; if false, then this field can only take a
65
+ single value, and a warning should be issued if it is
66
+ redefined.
67
+ @ivar takes_arg: If true, then this field expects an argument;
68
+ and a separate field section will be constructed for each
69
+ argument value. The label (and plural label) should include
70
+ a '%s' to mark where the argument's string rep should be
71
+ added.
72
+ """
73
+ def __init__(self, tags, label, plural=None,
74
+ short=0, multivalue=1, takes_arg=0,
75
+ varnames=None):
76
+ if type(tags) in (list, tuple):
77
+ self.tags = tuple(tags)
78
+ elif type(tags) is str:
79
+ self.tags = (tags,)
80
+ else: raise TypeError('Bad tags: %s' % tags)
81
+ self.singular = label
82
+ if plural is None: self.plural = label
83
+ else: self.plural = plural
84
+ self.multivalue = multivalue
85
+ self.short = short
86
+ self.takes_arg = takes_arg
87
+ self.varnames = varnames or []
88
+
89
+ def __cmp__(self, other):
90
+ if not isinstance(other, DocstringField): return -1
91
+ return cmp(self.tags, other.tags)
92
+
93
+ def __hash__(self):
94
+ return hash(self.tags)
95
+
96
+ def __repr__(self):
97
+ return '<Field: %s>' % self.tags[0]
98
+
99
+ STANDARD_FIELDS = [
100
+ #: A list of the standard simple fields accepted by epydoc. This
101
+ #: list can be augmented at run-time by a docstring with the special
102
+ #: C{@deffield} field. The order in which fields are listed here
103
+ #: determines the order in which they will be displayed in the
104
+ #: output.
105
+
106
+ # If it's deprecated, put that first.
107
+ DocstringField(['deprecated', 'depreciated'],
108
+ 'Deprecated', multivalue=0, varnames=['__deprecated__']),
109
+
110
+ # Status info
111
+ DocstringField(['version'], 'Version', multivalue=0,
112
+ varnames=['__version__']),
113
+ DocstringField(['date'], 'Date', multivalue=0,
114
+ varnames=['__date__']),
115
+ DocstringField(['status'], 'Status', multivalue=0),
116
+
117
+ # Bibliographic Info
118
+ DocstringField(['author', 'authors'], 'Author', 'Authors', short=1,
119
+ varnames=['__author__', '__authors__']),
120
+ DocstringField(['contact'], 'Contact', 'Contacts', short=1,
121
+ varnames=['__contact__']),
122
+ DocstringField(['organization', 'org'],
123
+ 'Organization', 'Organizations'),
124
+ DocstringField(['copyright', '(c)'], 'Copyright', multivalue=0,
125
+ varnames=['__copyright__']),
126
+ DocstringField(['license'], 'License', multivalue=0,
127
+ varnames=['__license__']),
128
+
129
+ # Various warnings etc.
130
+ DocstringField(['bug'], 'Bug', 'Bugs'),
131
+ DocstringField(['warning', 'warn'], 'Warning', 'Warnings'),
132
+ DocstringField(['attention'], 'Attention'),
133
+ DocstringField(['note'], 'Note', 'Notes'),
134
+
135
+ # Formal conditions
136
+ DocstringField(['requires', 'require', 'requirement'], 'Requires'),
137
+ DocstringField(['precondition', 'precond'],
138
+ 'Precondition', 'Preconditions'),
139
+ DocstringField(['postcondition', 'postcond'],
140
+ 'Postcondition', 'Postconditions'),
141
+ DocstringField(['invariant'], 'Invariant'),
142
+
143
+ # When was it introduced (version # or date)
144
+ DocstringField(['since'], 'Since', multivalue=0),
145
+
146
+ # Changes made
147
+ DocstringField(['change', 'changed'], 'Change Log'),
148
+
149
+ # Crossreferences
150
+ DocstringField(['see', 'seealso'], 'See Also', short=1),
151
+
152
+ # Future Work
153
+ DocstringField(['todo'], 'To Do', takes_arg=True),
154
+
155
+ # Permissions (used by zope-based projects)
156
+ DocstringField(['permission', 'permissions'], 'Permission', 'Permissions')
157
+ ]
158
+
159
+ ######################################################################
160
+ #{ Docstring Parsing
161
+ ######################################################################
162
+
163
+ DEFAULT_DOCFORMAT = 'epytext'
164
+ """The name of the default markup languge used to process docstrings."""
165
+
166
+ # [xx] keep track of which ones we've already done, in case we're
167
+ # asked to process one twice? e.g., for @include we might have to
168
+ # parse the included docstring earlier than we might otherwise..??
169
+
170
+ def parse_docstring(api_doc, docindex, suppress_warnings=[]):
171
+ """
172
+ Process the given C{APIDoc}'s docstring. In particular, populate
173
+ the C{APIDoc}'s C{descr} and C{summary} attributes, and add any
174
+ information provided by fields in the docstring.
175
+
176
+ @param docindex: A DocIndex, used to find the containing
177
+ module (to look up the docformat); and to find any
178
+ user docfields defined by containing objects.
179
+ @param suppress_warnings: A set of objects for which docstring
180
+ warnings should be suppressed.
181
+ """
182
+ if api_doc.metadata is not UNKNOWN:
183
+ if not (isinstance(api_doc, RoutineDoc)
184
+ and api_doc.canonical_name[-1] == '__init__'):
185
+ log.debug("%s's docstring processed twice" %
186
+ api_doc.canonical_name)
187
+ return
188
+
189
+ initialize_api_doc(api_doc)
190
+
191
+ # If there's no docstring, then check for special variables (e.g.,
192
+ # __version__), and then return -- there's nothing else to do.
193
+ if (api_doc.docstring in (None, UNKNOWN)):
194
+ if isinstance(api_doc, NamespaceDoc):
195
+ for field in STANDARD_FIELDS + user_docfields(api_doc, docindex):
196
+ add_metadata_from_var(api_doc, field)
197
+ return
198
+
199
+ # Remove leading indentation from the docstring.
200
+ api_doc.docstring = unindent_docstring(api_doc.docstring)
201
+
202
+ # Decide which docformat is used by this module.
203
+ docformat = get_docformat(api_doc, docindex)
204
+
205
+ # A list of markup errors from parsing.
206
+ parse_errors = []
207
+
208
+ # Extract a signature from the docstring, if it has one. This
209
+ # overrides any signature we got via introspection/parsing.
210
+ if isinstance(api_doc, RoutineDoc):
211
+ parse_function_signature(api_doc, None, docformat, parse_errors)
212
+
213
+ # Parse the docstring. Any errors encountered are stored as
214
+ # `ParseError` objects in the errors list.
215
+ parsed_docstring = markup.parse(api_doc.docstring, docformat,
216
+ parse_errors)
217
+
218
+ # Divide the docstring into a description and a list of
219
+ # fields.
220
+ descr, fields = parsed_docstring.split_fields(parse_errors)
221
+ api_doc.descr = descr
222
+
223
+ field_warnings = []
224
+
225
+ # Handle the constructor fields that have been defined in the class
226
+ # docstring. This code assumes that a class docstring is parsed before
227
+ # the same class __init__ docstring.
228
+ if isinstance(api_doc, ClassDoc):
229
+
230
+ # Parse ahead the __init__ docstring for this class
231
+ initvar = api_doc.variables.get('__init__')
232
+ if initvar and isinstance(initvar.value, RoutineDoc):
233
+ init_api_doc = initvar.value
234
+ parse_docstring(init_api_doc, docindex, suppress_warnings)
235
+
236
+ parse_function_signature(init_api_doc, api_doc,
237
+ docformat, parse_errors)
238
+ init_fields = split_init_fields(fields, field_warnings)
239
+
240
+ # Process fields
241
+ for field in init_fields:
242
+ try:
243
+ process_field(init_api_doc, docindex, field.tag(),
244
+ field.arg(), field.body())
245
+ except ValueError, e: field_warnings.append(str(e))
246
+
247
+ # Process fields
248
+ for field in fields:
249
+ try:
250
+ process_field(api_doc, docindex, field.tag(),
251
+ field.arg(), field.body())
252
+ except ValueError, e: field_warnings.append(str(e))
253
+
254
+ # Check to make sure that all type parameters correspond to
255
+ # some documented parameter.
256
+ check_type_fields(api_doc, field_warnings)
257
+
258
+ # Check for special variables (e.g., __version__)
259
+ if isinstance(api_doc, NamespaceDoc):
260
+ for field in STANDARD_FIELDS + user_docfields(api_doc, docindex):
261
+ add_metadata_from_var(api_doc, field)
262
+
263
+ # Extract a summary
264
+ if api_doc.summary is None and api_doc.descr is not None:
265
+ api_doc.summary, api_doc.other_docs = api_doc.descr.summary()
266
+
267
+ # If the summary is empty, but the return field is not, then use
268
+ # the return field to generate a summary description.
269
+ if (isinstance(api_doc, RoutineDoc) and api_doc.summary is None and
270
+ api_doc.return_descr is not None):
271
+ s, o = api_doc.return_descr.summary()
272
+ api_doc.summary = RETURN_PDS + s
273
+ api_doc.other_docs = o
274
+
275
+ # [XX] Make sure we don't have types/param descrs for unknown
276
+ # vars/params?
277
+
278
+ # Report any errors that occured
279
+ if api_doc in suppress_warnings:
280
+ if parse_errors or field_warnings:
281
+ log.info("Suppressing docstring warnings for %s, since it "
282
+ "is not included in the documented set." %
283
+ api_doc.canonical_name)
284
+ else:
285
+ report_errors(api_doc, docindex, parse_errors, field_warnings)
286
+
287
+ def add_metadata_from_var(api_doc, field):
288
+ for varname in field.varnames:
289
+ # Check if api_doc has a variable w/ the given name.
290
+ if varname not in api_doc.variables: continue
291
+
292
+ # Check moved here from before the for loop because we expect to
293
+ # reach rarely this point. The loop below is to be performed more than
294
+ # once only for fields with more than one varname, which currently is
295
+ # only 'author'.
296
+ for md in api_doc.metadata:
297
+ if field == md[0]:
298
+ return # We already have a value for this metadata.
299
+
300
+ var_doc = api_doc.variables[varname]
301
+ if var_doc.value is UNKNOWN: continue
302
+ val_doc = var_doc.value
303
+ value = []
304
+
305
+ # Try extracting the value from the pyval.
306
+ ok_types = (basestring, int, float, bool, type(None))
307
+ if val_doc.pyval is not UNKNOWN:
308
+ if isinstance(val_doc.pyval, ok_types):
309
+ value = [val_doc.pyval]
310
+ elif field.multivalue:
311
+ if isinstance(val_doc.pyval, (tuple, list)):
312
+ for elt in val_doc.pyval:
313
+ if not isinstance(elt, ok_types): break
314
+ else:
315
+ value = list(val_doc.pyval)
316
+
317
+ # Try extracting the value from the parse tree.
318
+ elif val_doc.toktree is not UNKNOWN:
319
+ try: value = [epydoc.docparser.parse_string(val_doc.toktree)]
320
+ except KeyboardInterrupt: raise
321
+ except: pass
322
+ if field.multivalue and not value:
323
+ try: value = epydoc.docparser.parse_string_list(val_doc.toktree)
324
+ except KeyboardInterrupt: raise
325
+ except: raise
326
+
327
+ # Add any values that we found.
328
+ for elt in value:
329
+ if isinstance(elt, str):
330
+ elt = decode_with_backslashreplace(elt)
331
+ else:
332
+ elt = unicode(elt)
333
+ elt = epytext.ParsedEpytextDocstring(
334
+ epytext.parse_as_para(elt), inline=True)
335
+
336
+ # Add in the metadata and remove from the variables
337
+ api_doc.metadata.append( (field, varname, elt) )
338
+
339
+ # Remove the variable itself (unless it's documented)
340
+ if var_doc.docstring in (None, UNKNOWN):
341
+ del api_doc.variables[varname]
342
+ if api_doc.sort_spec is not UNKNOWN:
343
+ try: api_doc.sort_spec.remove(varname)
344
+ except ValueError: pass
345
+
346
+ def initialize_api_doc(api_doc):
347
+ """A helper function for L{parse_docstring()} that initializes
348
+ the attributes that C{parse_docstring()} will write to."""
349
+ if api_doc.descr is UNKNOWN:
350
+ api_doc.descr = None
351
+ if api_doc.summary is UNKNOWN:
352
+ api_doc.summary = None
353
+ if api_doc.metadata is UNKNOWN:
354
+ api_doc.metadata = []
355
+ if isinstance(api_doc, RoutineDoc):
356
+ if api_doc.arg_descrs is UNKNOWN:
357
+ api_doc.arg_descrs = []
358
+ if api_doc.arg_types is UNKNOWN:
359
+ api_doc.arg_types = {}
360
+ if api_doc.return_descr is UNKNOWN:
361
+ api_doc.return_descr = None
362
+ if api_doc.return_type is UNKNOWN:
363
+ api_doc.return_type = None
364
+ if api_doc.exception_descrs is UNKNOWN:
365
+ api_doc.exception_descrs = []
366
+ if isinstance(api_doc, (VariableDoc, PropertyDoc)):
367
+ if api_doc.type_descr is UNKNOWN:
368
+ api_doc.type_descr = None
369
+ if isinstance(api_doc, NamespaceDoc):
370
+ if api_doc.group_specs is UNKNOWN:
371
+ api_doc.group_specs = []
372
+ if api_doc.sort_spec is UNKNOWN:
373
+ api_doc.sort_spec = []
374
+
375
+ def split_init_fields(fields, warnings):
376
+ """
377
+ Remove the fields related to the constructor from a class docstring
378
+ fields list.
379
+
380
+ @param fields: The fields to process. The list will be modified in place
381
+ @type fields: C{list} of L{markup.Field}
382
+ @param warnings: A list to emit processing warnings
383
+ @type warnings: C{list}
384
+ @return: The C{fields} items to be applied to the C{__init__} method
385
+ @rtype: C{list} of L{markup.Field}
386
+ """
387
+ init_fields = []
388
+
389
+ # Split fields in lists according to their argument, keeping order.
390
+ arg_fields = {}
391
+ args_order = []
392
+ i = 0
393
+ while i < len(fields):
394
+ field = fields[i]
395
+
396
+ # gather together all the fields with the same arg
397
+ if field.arg() is not None:
398
+ arg_fields.setdefault(field.arg(), []).append(fields.pop(i))
399
+ args_order.append(field.arg())
400
+ else:
401
+ i += 1
402
+
403
+ # Now check that for each argument there is at most a single variable
404
+ # and a single parameter, and at most a single type for each of them.
405
+ for arg in args_order:
406
+ ff = arg_fields.pop(arg, None)
407
+ if ff is None:
408
+ continue
409
+
410
+ var = tvar = par = tpar = None
411
+ for field in ff:
412
+ if field.tag() in VARIABLE_TAGS:
413
+ if var is None:
414
+ var = field
415
+ fields.append(field)
416
+ else:
417
+ warnings.append(
418
+ "There is more than one variable named '%s'"
419
+ % arg)
420
+ elif field.tag() in PARAMETER_TAGS:
421
+ if par is None:
422
+ par = field
423
+ init_fields.append(field)
424
+ else:
425
+ warnings.append(
426
+ "There is more than one parameter named '%s'"
427
+ % arg)
428
+
429
+ elif field.tag() == 'type':
430
+ if var is None and par is None:
431
+ # type before obj
432
+ tvar = tpar = field
433
+ else:
434
+ if var is not None and tvar is None:
435
+ tvar = field
436
+ if par is not None and tpar is None:
437
+ tpar = field
438
+
439
+ elif field.tag() in EXCEPTION_TAGS:
440
+ init_fields.append(field)
441
+
442
+ else: # Unespected field
443
+ fields.append(field)
444
+
445
+ # Put selected types into the proper output lists
446
+ if tvar is not None:
447
+ if var is not None:
448
+ fields.append(tvar)
449
+ else:
450
+ pass # [xx] warn about type w/o object?
451
+
452
+ if tpar is not None:
453
+ if par is not None:
454
+ init_fields.append(tpar)
455
+ else:
456
+ pass # [xx] warn about type w/o object?
457
+
458
+ return init_fields
459
+
460
+ def report_errors(api_doc, docindex, parse_errors, field_warnings):
461
+ """A helper function for L{parse_docstring()} that reports any
462
+ markup warnings and field warnings that we encountered while
463
+ processing C{api_doc}'s docstring."""
464
+ if not parse_errors and not field_warnings: return
465
+
466
+ # Get the name of the item containing the error, and the
467
+ # filename of its containing module.
468
+ name = api_doc.canonical_name
469
+ module = api_doc.defining_module
470
+ if module is not UNKNOWN and module.filename not in (None, UNKNOWN):
471
+ try: filename = py_src_filename(module.filename)
472
+ except: filename = module.filename
473
+ else:
474
+ filename = '??'
475
+
476
+ # [xx] Don't report markup errors for standard builtins.
477
+ # n.b. that we must use 'is' to compare pyvals here -- if we use
478
+ # 'in' or '==', then a user __cmp__ method might raise an
479
+ # exception, or lie.
480
+ if isinstance(api_doc, ValueDoc) and api_doc != module:
481
+ if module not in (None, UNKNOWN) and module.pyval is exceptions:
482
+ return
483
+ for builtin_val in __builtin__.__dict__.values():
484
+ if builtin_val is api_doc.pyval:
485
+ return
486
+
487
+ # Get the start line of the docstring containing the error.
488
+ startline = api_doc.docstring_lineno
489
+ if startline in (None, UNKNOWN):
490
+ startline = introspect_docstring_lineno(api_doc)
491
+ if startline in (None, UNKNOWN):
492
+ startline = None
493
+
494
+ # Display a block header.
495
+ header = 'File %s, ' % filename
496
+ if startline is not None:
497
+ header += 'line %d, ' % startline
498
+ header += 'in %s' % name
499
+ log.start_block(header)
500
+
501
+
502
+ # Display all parse errors. But first, combine any errors
503
+ # with duplicate description messages.
504
+ if startline is None:
505
+ # remove dups, but keep original order:
506
+ dups = {}
507
+ for error in parse_errors:
508
+ message = error.descr()
509
+ if message not in dups:
510
+ log.docstring_warning(message)
511
+ dups[message] = 1
512
+ else:
513
+ # Combine line number fields for dup messages:
514
+ messages = {} # maps message -> list of linenum
515
+ for error in parse_errors:
516
+ error.set_linenum_offset(startline)
517
+ message = error.descr()
518
+ messages.setdefault(message, []).append(error.linenum())
519
+ message_items = messages.items()
520
+ message_items.sort(lambda a,b:cmp(min(a[1]), min(b[1])))
521
+ for message, linenums in message_items:
522
+ linenums = [n for n in linenums if n is not None]
523
+ if len(linenums) == 0:
524
+ log.docstring_warning(message)
525
+ elif len(linenums) == 1:
526
+ log.docstring_warning("Line %s: %s" % (linenums[0], message))
527
+ else:
528
+ linenums = ', '.join(['%s' % l for l in linenums])
529
+ log.docstring_warning("Lines %s: %s" % (linenums, message))
530
+
531
+ # Display all field warnings.
532
+ for warning in field_warnings:
533
+ log.docstring_warning(warning)
534
+
535
+ # End the message block.
536
+ log.end_block()
537
+
538
+ RETURN_PDS = markup.parse('Returns:', markup='epytext')
539
+ """A ParsedDocstring containing the text 'Returns'. This is used to
540
+ construct summary descriptions for routines that have empty C{descr},
541
+ but non-empty C{return_descr}."""
542
+ RETURN_PDS._tree.children[0].attribs['inline'] = True
543
+
544
+ ######################################################################
545
+ #{ Field Processing Error Messages
546
+ ######################################################################
547
+
548
+ UNEXPECTED_ARG = '%r did not expect an argument'
549
+ EXPECTED_ARG = '%r expected an argument'
550
+ EXPECTED_SINGLE_ARG = '%r expected a single argument'
551
+ BAD_CONTEXT = 'Invalid context for %r'
552
+ REDEFINED = 'Redefinition of %s'
553
+ UNKNOWN_TAG = 'Unknown field tag %r'
554
+ BAD_PARAM = '@%s for unknown parameter %s'
555
+
556
+ ######################################################################
557
+ #{ Field Processing
558
+ ######################################################################
559
+
560
+ def process_field(api_doc, docindex, tag, arg, descr):
561
+ """
562
+ Process a single field, and use it to update C{api_doc}. If
563
+ C{tag} is the name of a special field, then call its handler
564
+ function. If C{tag} is the name of a simple field, then use
565
+ C{process_simple_field} to process it. Otherwise, check if it's a
566
+ user-defined field, defined in this docstring or the docstring of
567
+ a containing object; and if so, process it with
568
+ C{process_simple_field}.
569
+
570
+ @param tag: The field's tag, such as C{'author'}
571
+ @param arg: The field's optional argument
572
+ @param descr: The description following the field tag and
573
+ argument.
574
+ @raise ValueError: If a problem was encountered while processing
575
+ the field. The C{ValueError}'s string argument is an
576
+ explanation of the problem, which should be displayed as a
577
+ warning message.
578
+ """
579
+ # standard special fields
580
+ if tag in _field_dispatch_table:
581
+ handler = _field_dispatch_table[tag]
582
+ handler(api_doc, docindex, tag, arg, descr)
583
+ return
584
+
585
+ # standard simple fields & user-defined fields
586
+ for field in STANDARD_FIELDS + user_docfields(api_doc, docindex):
587
+ if tag in field.tags:
588
+ # [xx] check if it's redefined if it's not multivalue??
589
+ if not field.takes_arg:
590
+ _check(api_doc, tag, arg, expect_arg=False)
591
+ api_doc.metadata.append((field, arg, descr))
592
+ return
593
+
594
+ # If we didn't handle the field, then report a warning.
595
+ raise ValueError(UNKNOWN_TAG % tag)
596
+
597
+ def user_docfields(api_doc, docindex):
598
+ """
599
+ Return a list of user defined fields that can be used for the
600
+ given object. This list is taken from the given C{api_doc}, and
601
+ any of its containing C{NamepaceDoc}s.
602
+
603
+ @note: We assume here that a parent's docstring will always be
604
+ parsed before its childrens'. This is indeed the case when we
605
+ are called via L{docbuilder.build_doc_index()}. If a child's
606
+ docstring is parsed before its parents, then its parent won't
607
+ yet have had its C{extra_docstring_fields} attribute
608
+ initialized.
609
+ """
610
+ docfields = []
611
+ # Get any docfields from `api_doc` itself
612
+ if api_doc.extra_docstring_fields not in (None, UNKNOWN):
613
+ docfields += api_doc.extra_docstring_fields
614
+ # Get any docfields from `api_doc`'s ancestors
615
+ for i in range(len(api_doc.canonical_name)-1, 0, -1):
616
+ ancestor = docindex.get_valdoc(api_doc.canonical_name[:i])
617
+ if ancestor is not None \
618
+ and ancestor.extra_docstring_fields not in (None, UNKNOWN):
619
+ docfields += ancestor.extra_docstring_fields
620
+ return docfields
621
+
622
+ _field_dispatch_table = {}
623
+ def register_field_handler(handler, *field_tags):
624
+ """
625
+ Register the given field handler function for processing any
626
+ of the given field tags. Field handler functions should
627
+ have the following signature:
628
+
629
+ >>> def field_handler(api_doc, docindex, tag, arg, descr):
630
+ ... '''update api_doc in response to the field.'''
631
+
632
+ Where C{api_doc} is the documentation object to update;
633
+ C{docindex} is a L{DocIndex} that can be used to look up the
634
+ documentation for related objects; C{tag} is the field tag that
635
+ was used; C{arg} is the optional argument; and C{descr} is the
636
+ description following the field tag and argument.
637
+ """
638
+ for field_tag in field_tags:
639
+ _field_dispatch_table[field_tag] = handler
640
+
641
+ ######################################################################
642
+ #{ Field Handler Functions
643
+ ######################################################################
644
+
645
+ def process_summary_field(api_doc, docindex, tag, arg, descr):
646
+ """Store C{descr} in C{api_doc.summary}"""
647
+ _check(api_doc, tag, arg, expect_arg=False)
648
+ if api_doc.summary is not None:
649
+ raise ValueError(REDEFINED % tag)
650
+ api_doc.summary = descr
651
+
652
+ def process_include_field(api_doc, docindex, tag, arg, descr):
653
+ """Copy the docstring contents from the object named in C{descr}"""
654
+ _check(api_doc, tag, arg, expect_arg=False)
655
+ # options:
656
+ # a. just append the descr to our own
657
+ # b. append descr and update metadata
658
+ # c. append descr and process all fields.
659
+ # in any case, mark any errors we may find as coming from an
660
+ # imported docstring.
661
+
662
+ # how does this interact with documentation inheritance??
663
+ raise ValueError('%s not implemented yet' % tag)
664
+
665
+ def process_undocumented_field(api_doc, docindex, tag, arg, descr):
666
+ """Remove any documentation for the variables named in C{descr}"""
667
+ _check(api_doc, tag, arg, context=NamespaceDoc, expect_arg=False)
668
+ for ident in _descr_to_identifiers(descr):
669
+ var_name_re = re.compile('^%s$' % ident.replace('*', '(.*)'))
670
+ for var_name, var_doc in api_doc.variables.items():
671
+ if var_name_re.match(var_name):
672
+ # Remove the variable from `variables`.
673
+ api_doc.variables.pop(var_name, None)
674
+ if api_doc.sort_spec is not UNKNOWN:
675
+ try: api_doc.sort_spec.remove(var_name)
676
+ except ValueError: pass
677
+ # For modules, remove any submodules that match var_name_re.
678
+ if isinstance(api_doc, ModuleDoc):
679
+ removed = set([m for m in api_doc.submodules
680
+ if var_name_re.match(m.canonical_name[-1])])
681
+ if removed:
682
+ # Remove the indicated submodules from this module.
683
+ api_doc.submodules = [m for m in api_doc.submodules
684
+ if m not in removed]
685
+ # Remove all ancestors of the indicated submodules
686
+ # from the docindex root. E.g., if module x
687
+ # declares y to be undocumented, then x.y.z should
688
+ # also be undocumented.
689
+ for elt in docindex.root[:]:
690
+ for m in removed:
691
+ if m.canonical_name.dominates(elt.canonical_name):
692
+ docindex.root.remove(elt)
693
+
694
+ def process_group_field(api_doc, docindex, tag, arg, descr):
695
+ """Define a group named C{arg} containing the variables whose
696
+ names are listed in C{descr}."""
697
+ _check(api_doc, tag, arg, context=NamespaceDoc, expect_arg=True)
698
+ api_doc.group_specs.append( (arg, _descr_to_identifiers(descr)) )
699
+ # [xx] should this also set sort order?
700
+
701
+ def process_deffield_field(api_doc, docindex, tag, arg, descr):
702
+ """Define a new custom field."""
703
+ _check(api_doc, tag, arg, expect_arg=True)
704
+ if api_doc.extra_docstring_fields is UNKNOWN:
705
+ api_doc.extra_docstring_fields = []
706
+ try:
707
+ docstring_field = _descr_to_docstring_field(arg, descr)
708
+ docstring_field.varnames.append("__%s__" % arg)
709
+ api_doc.extra_docstring_fields.append(docstring_field)
710
+ except ValueError, e:
711
+ raise ValueError('Bad %s: %s' % (tag, e))
712
+
713
+ def process_raise_field(api_doc, docindex, tag, arg, descr):
714
+ """Record the fact that C{api_doc} can raise the exception named
715
+ C{tag} in C{api_doc.exception_descrs}."""
716
+ _check(api_doc, tag, arg, context=RoutineDoc, expect_arg='single')
717
+ try: name = DottedName(arg, strict=True)
718
+ except DottedName.InvalidDottedName: name = arg
719
+ api_doc.exception_descrs.append( (name, descr) )
720
+
721
+ def process_sort_field(api_doc, docindex, tag, arg, descr):
722
+ _check(api_doc, tag, arg, context=NamespaceDoc, expect_arg=False)
723
+ api_doc.sort_spec = _descr_to_identifiers(descr) + api_doc.sort_spec
724
+
725
+ # [xx] should I notice when they give a type for an unknown var?
726
+ def process_type_field(api_doc, docindex, tag, arg, descr):
727
+ # In namespace, "@type var: ..." describes the type of a var.
728
+ if isinstance(api_doc, NamespaceDoc):
729
+ _check(api_doc, tag, arg, expect_arg='single')
730
+ set_var_type(api_doc, arg, descr)
731
+
732
+ # For variables & properties, "@type: ..." describes the variable.
733
+ elif isinstance(api_doc, (VariableDoc, PropertyDoc)):
734
+ _check(api_doc, tag, arg, expect_arg=False)
735
+ if api_doc.type_descr is not None:
736
+ raise ValueError(REDEFINED % tag)
737
+ api_doc.type_descr = descr
738
+
739
+ # For routines, "@type param: ..." describes a parameter.
740
+ elif isinstance(api_doc, RoutineDoc):
741
+ _check(api_doc, tag, arg, expect_arg='single')
742
+ if arg in api_doc.arg_types:
743
+ raise ValueError(REDEFINED % ('type for '+arg))
744
+ api_doc.arg_types[arg] = descr
745
+
746
+ else:
747
+ raise ValueError(BAD_CONTEXT % tag)
748
+
749
+ def process_var_field(api_doc, docindex, tag, arg, descr):
750
+ _check(api_doc, tag, arg, context=ModuleDoc, expect_arg=True)
751
+ for ident in re.split('[:;, ] *', arg):
752
+ set_var_descr(api_doc, ident, descr)
753
+
754
+ def process_cvar_field(api_doc, docindex, tag, arg, descr):
755
+ # If @cvar is used *within* a variable, then use it as the
756
+ # variable's description, and treat the variable as a class var.
757
+ if (isinstance(api_doc, VariableDoc) and
758
+ isinstance(api_doc.container, ClassDoc)):
759
+ _check(api_doc, tag, arg, expect_arg=False)
760
+ api_doc.is_instvar = False
761
+ api_doc.descr = markup.ConcatenatedDocstring(api_doc.descr, descr)
762
+ api_doc.summary, api_doc.other_docs = descr.summary()
763
+
764
+ # Otherwise, @cvar should be used in a class.
765
+ else:
766
+ _check(api_doc, tag, arg, context=ClassDoc, expect_arg=True)
767
+ for ident in re.split('[:;, ] *', arg):
768
+ set_var_descr(api_doc, ident, descr)
769
+ api_doc.variables[ident].is_instvar = False
770
+
771
+ def process_ivar_field(api_doc, docindex, tag, arg, descr):
772
+ # If @ivar is used *within* a variable, then use it as the
773
+ # variable's description, and treat the variable as an instvar.
774
+ if (isinstance(api_doc, VariableDoc) and
775
+ isinstance(api_doc.container, ClassDoc)):
776
+ _check(api_doc, tag, arg, expect_arg=False)
777
+ # require that there be no other descr?
778
+ api_doc.is_instvar = True
779
+ api_doc.descr = markup.ConcatenatedDocstring(api_doc.descr, descr)
780
+ api_doc.summary, api_doc.other_docs = descr.summary()
781
+
782
+ # Otherwise, @ivar should be used in a class.
783
+ else:
784
+ _check(api_doc, tag, arg, context=ClassDoc, expect_arg=True)
785
+ for ident in re.split('[:;, ] *', arg):
786
+ set_var_descr(api_doc, ident, descr)
787
+ api_doc.variables[ident].is_instvar = True
788
+
789
+ # [xx] '@return: foo' used to get used as a descr if no other
790
+ # descr was present. is that still true?
791
+ def process_return_field(api_doc, docindex, tag, arg, descr):
792
+ _check(api_doc, tag, arg, context=RoutineDoc, expect_arg=False)
793
+ if api_doc.return_descr is not None:
794
+ raise ValueError(REDEFINED % 'return value description')
795
+ api_doc.return_descr = descr
796
+
797
+ def process_rtype_field(api_doc, docindex, tag, arg, descr):
798
+ _check(api_doc, tag, arg,
799
+ context=(RoutineDoc, PropertyDoc), expect_arg=False)
800
+ if isinstance(api_doc, RoutineDoc):
801
+ if api_doc.return_type is not None:
802
+ raise ValueError(REDEFINED % 'return value type')
803
+ api_doc.return_type = descr
804
+
805
+ elif isinstance(api_doc, PropertyDoc):
806
+ _check(api_doc, tag, arg, expect_arg=False)
807
+ if api_doc.type_descr is not None:
808
+ raise ValueError(REDEFINED % tag)
809
+ api_doc.type_descr = descr
810
+
811
+ def process_arg_field(api_doc, docindex, tag, arg, descr):
812
+ _check(api_doc, tag, arg, context=RoutineDoc, expect_arg=True)
813
+ idents = re.split('[:;, ] *', arg)
814
+ api_doc.arg_descrs.append( (idents, descr) )
815
+ # Check to make sure that the documented parameter(s) are
816
+ # actually part of the function signature.
817
+ all_args = api_doc.all_args()
818
+ if all_args not in (['...'], UNKNOWN):
819
+ bad_params = ['"%s"' % i for i in idents if i not in all_args]
820
+ if bad_params:
821
+ raise ValueError(BAD_PARAM % (tag, ', '.join(bad_params)))
822
+
823
+ def process_kwarg_field(api_doc, docindex, tag, arg, descr):
824
+ # [xx] these should -not- be checked if they exist..
825
+ # and listed separately or not??
826
+ _check(api_doc, tag, arg, context=RoutineDoc, expect_arg=True)
827
+ idents = re.split('[:;, ] *', arg)
828
+ api_doc.arg_descrs.append( (idents, descr) )
829
+
830
+ register_field_handler(process_group_field, 'group')
831
+ register_field_handler(process_deffield_field, 'deffield', 'newfield')
832
+ register_field_handler(process_sort_field, 'sort')
833
+ register_field_handler(process_summary_field, 'summary')
834
+ register_field_handler(process_undocumented_field, 'undocumented')
835
+ register_field_handler(process_include_field, 'include')
836
+ register_field_handler(process_var_field, 'var', 'variable')
837
+ register_field_handler(process_type_field, 'type')
838
+ register_field_handler(process_cvar_field, 'cvar', 'cvariable')
839
+ register_field_handler(process_ivar_field, 'ivar', 'ivariable')
840
+ register_field_handler(process_return_field, 'return', 'returns')
841
+ register_field_handler(process_rtype_field, 'rtype', 'returntype')
842
+ register_field_handler(process_arg_field, 'arg', 'argument',
843
+ 'parameter', 'param')
844
+ register_field_handler(process_kwarg_field, 'kwarg', 'keyword', 'kwparam')
845
+ register_field_handler(process_raise_field, 'raise', 'raises',
846
+ 'except', 'exception')
847
+
848
+ # Tags related to function parameters
849
+ PARAMETER_TAGS = ('arg', 'argument', 'parameter', 'param',
850
+ 'kwarg', 'keyword', 'kwparam')
851
+
852
+ # Tags related to variables in a class
853
+ VARIABLE_TAGS = ('cvar', 'cvariable', 'ivar', 'ivariable')
854
+
855
+ # Tags related to exceptions
856
+ EXCEPTION_TAGS = ('raise', 'raises', 'except', 'exception')
857
+
858
+ ######################################################################
859
+ #{ Helper Functions
860
+ ######################################################################
861
+
862
+ def check_type_fields(api_doc, field_warnings):
863
+ """Check to make sure that all type fields correspond to some
864
+ documented parameter; if not, append a warning to field_warnings."""
865
+ if isinstance(api_doc, RoutineDoc):
866
+ for arg in api_doc.arg_types:
867
+ if arg not in api_doc.all_args():
868
+ for args, descr in api_doc.arg_descrs:
869
+ if arg in args:
870
+ break
871
+ else:
872
+ field_warnings.append(BAD_PARAM % ('type', '"%s"' % arg))
873
+
874
+ def set_var_descr(api_doc, ident, descr):
875
+ if ident not in api_doc.variables:
876
+ api_doc.variables[ident] = VariableDoc(
877
+ container=api_doc, name=ident,
878
+ canonical_name=api_doc.canonical_name+ident)
879
+
880
+ var_doc = api_doc.variables[ident]
881
+ if var_doc.descr not in (None, UNKNOWN):
882
+ raise ValueError(REDEFINED % ('description for '+ident))
883
+ var_doc.descr = descr
884
+ if var_doc.summary in (None, UNKNOWN):
885
+ var_doc.summary, var_doc.other_docs = var_doc.descr.summary()
886
+
887
+ def set_var_type(api_doc, ident, descr):
888
+ if ident not in api_doc.variables:
889
+ api_doc.variables[ident] = VariableDoc(
890
+ container=api_doc, name=ident,
891
+ canonical_name=api_doc.canonical_name+ident)
892
+
893
+ var_doc = api_doc.variables[ident]
894
+ if var_doc.type_descr not in (None, UNKNOWN):
895
+ raise ValueError(REDEFINED % ('type for '+ident))
896
+ var_doc.type_descr = descr
897
+
898
+ def _check(api_doc, tag, arg, context=None, expect_arg=None):
899
+ if context is not None:
900
+ if not isinstance(api_doc, context):
901
+ raise ValueError(BAD_CONTEXT % tag)
902
+ if expect_arg is not None:
903
+ if expect_arg == True:
904
+ if arg is None:
905
+ raise ValueError(EXPECTED_ARG % tag)
906
+ elif expect_arg == False:
907
+ if arg is not None:
908
+ raise ValueError(UNEXPECTED_ARG % tag)
909
+ elif expect_arg == 'single':
910
+ if (arg is None or ' ' in arg):
911
+ raise ValueError(EXPECTED_SINGLE_ARG % tag)
912
+ else:
913
+ assert 0, 'bad value for expect_arg'
914
+
915
+ def get_docformat(api_doc, docindex):
916
+ """
917
+ Return the name of the markup language that should be used to
918
+ parse the API documentation for the given object.
919
+ """
920
+ # Find the module that defines api_doc.
921
+ module = api_doc.defining_module
922
+ # Look up its docformat.
923
+ if module is not UNKNOWN and module.docformat not in (None, UNKNOWN):
924
+ docformat = module.docformat
925
+ else:
926
+ docformat = DEFAULT_DOCFORMAT
927
+ # Convert to lower case & strip region codes.
928
+ try: return docformat.lower().split()[0]
929
+ except: return DEFAULT_DOCFORMAT
930
+
931
+ def unindent_docstring(docstring):
932
+ # [xx] copied from inspect.getdoc(); we can't use inspect.getdoc()
933
+ # itself, since it expects an object, not a string.
934
+
935
+ if not docstring: return ''
936
+ lines = docstring.expandtabs().split('\n')
937
+
938
+ # Find minimum indentation of any non-blank lines after first line.
939
+ margin = sys.maxint
940
+ for line in lines[1:]:
941
+ content = len(line.lstrip())
942
+ if content:
943
+ indent = len(line) - content
944
+ margin = min(margin, indent)
945
+ # Remove indentation.
946
+ if lines:
947
+ lines[0] = lines[0].lstrip()
948
+ if margin < sys.maxint:
949
+ for i in range(1, len(lines)): lines[i] = lines[i][margin:]
950
+ # Remove any trailing (but not leading!) blank lines.
951
+ while lines and not lines[-1]:
952
+ lines.pop()
953
+ #while lines and not lines[0]:
954
+ # lines.pop(0)
955
+ return '\n'.join(lines)
956
+
957
+ _IDENTIFIER_LIST_REGEXP = re.compile(r'^[\w.\*]+([\s,:;]\s*[\w.\*]+)*$')
958
+ def _descr_to_identifiers(descr):
959
+ """
960
+ Given a C{ParsedDocstring} that contains a list of identifiers,
961
+ return a list of those identifiers. This is used by fields such
962
+ as C{@group} and C{@sort}, which expect lists of identifiers as
963
+ their values. To extract the identifiers, the docstring is first
964
+ converted to plaintext, and then split. The plaintext content of
965
+ the docstring must be a a list of identifiers, separated by
966
+ spaces, commas, colons, or semicolons.
967
+
968
+ @rtype: C{list} of C{string}
969
+ @return: A list of the identifier names contained in C{descr}.
970
+ @type descr: L{markup.ParsedDocstring}
971
+ @param descr: A C{ParsedDocstring} containing a list of
972
+ identifiers.
973
+ @raise ValueError: If C{descr} does not contain a valid list of
974
+ identifiers.
975
+ """
976
+ idents = descr.to_plaintext(None).strip()
977
+ idents = re.sub(r'\s+', ' ', idents)
978
+ if not _IDENTIFIER_LIST_REGEXP.match(idents):
979
+ raise ValueError, 'Bad Identifier list: %r' % idents
980
+ rval = re.split('[:;, ] *', idents)
981
+ return rval
982
+
983
+ def _descr_to_docstring_field(arg, descr):
984
+ tags = [s.lower() for s in re.split('[:;, ] *', arg)]
985
+ descr = descr.to_plaintext(None).strip()
986
+ args = re.split('[:;,] *', descr)
987
+ if len(args) == 0 or len(args) > 3:
988
+ raise ValueError, 'Wrong number of arguments'
989
+ singular = args[0]
990
+ if len(args) >= 2: plural = args[1]
991
+ else: plural = None
992
+ short = 0
993
+ if len(args) >= 3:
994
+ if args[2] == 'short': short = 1
995
+ else: raise ValueError('Bad arg 2 (expected "short")')
996
+ return DocstringField(tags, singular, plural, short)
997
+
998
+ ######################################################################
999
+ #{ Function Signature Extraction
1000
+ ######################################################################
1001
+
1002
+ # [XX] todo: add optional type modifiers?
1003
+ _SIGNATURE_RE = re.compile(
1004
+ # Class name (for builtin methods)
1005
+ r'^\s*((?P<self>\w+)\.)?' +
1006
+ # The function name (must match exactly) [XX] not anymore!
1007
+ r'(?P<func>\w+)' +
1008
+ # The parameters
1009
+ r'\((?P<params>(\s*\[?\s*\*{0,2}[\w\-\.]+(\s*=.+?)?'+
1010
+ r'(\s*\[?\s*,\s*\]?\s*\*{0,2}[\w\-\.]+(\s*=.+?)?)*\]*)?)\s*\)' +
1011
+ # The return value (optional)
1012
+ r'(\s*(->)\s*(?P<return>\S.*?))?'+
1013
+ # The end marker
1014
+ r'\s*(\n|\s+(--|<=+>)\s+|$|\.\s+|\.\n)')
1015
+ """A regular expression that is used to extract signatures from
1016
+ docstrings."""
1017
+
1018
+ def parse_function_signature(func_doc, doc_source, docformat, parse_errors):
1019
+ """
1020
+ Construct the signature for a builtin function or method from
1021
+ its docstring. If the docstring uses the standard convention
1022
+ of including a signature in the first line of the docstring
1023
+ (and formats that signature according to standard
1024
+ conventions), then it will be used to extract a signature.
1025
+ Otherwise, the signature will be set to a single varargs
1026
+ variable named C{"..."}.
1027
+
1028
+ @param func_doc: The target object where to store parsed signature. Also
1029
+ container of the docstring to parse if doc_source is C{None}
1030
+ @type func_doc: L{RoutineDoc}
1031
+ @param doc_source: Contains the docstring to parse. If C{None}, parse
1032
+ L{func_doc} docstring instead
1033
+ @type doc_source: L{APIDoc}
1034
+ @rtype: C{None}
1035
+ """
1036
+ if doc_source is None:
1037
+ doc_source = func_doc
1038
+
1039
+ # If there's no docstring, then don't do anything.
1040
+ if not doc_source.docstring: return False
1041
+
1042
+ m = _SIGNATURE_RE.match(doc_source.docstring)
1043
+ if m is None: return False
1044
+
1045
+ # Do I want to be this strict?
1046
+ # Notice that __init__ must match the class name instead, if the signature
1047
+ # comes from the class docstring
1048
+ # if not (m.group('func') == func_doc.canonical_name[-1] or
1049
+ # '_'+m.group('func') == func_doc.canonical_name[-1]):
1050
+ # log.warning("Not extracting function signature from %s's "
1051
+ # "docstring, since the name doesn't match." %
1052
+ # func_doc.canonical_name)
1053
+ # return False
1054
+
1055
+ params = m.group('params')
1056
+ rtype = m.group('return')
1057
+ selfparam = m.group('self')
1058
+
1059
+ # Extract the parameters from the signature.
1060
+ func_doc.posargs = []
1061
+ func_doc.vararg = None
1062
+ func_doc.kwarg = None
1063
+ if func_doc.posarg_defaults is UNKNOWN:
1064
+ func_doc.posarg_defaults = []
1065
+ if params:
1066
+ # Figure out which parameters are optional.
1067
+ while '[' in params or ']' in params:
1068
+ m2 = re.match(r'(.*)\[([^\[\]]+)\](.*)', params)
1069
+ if not m2: return False
1070
+ (start, mid, end) = m2.groups()
1071
+ mid = re.sub(r'((,|^)\s*[\w\-\.]+)', r'\1=...', mid)
1072
+ params = start+mid+end
1073
+
1074
+ params = re.sub(r'=...=' , r'=', params)
1075
+ for name in params.split(','):
1076
+ if '=' in name:
1077
+ (name, default_repr) = name.split('=',1)
1078
+ default = GenericValueDoc(parse_repr=default_repr)
1079
+ else:
1080
+ default = None
1081
+ name = name.strip()
1082
+ if name == '...':
1083
+ func_doc.vararg = '...'
1084
+ elif name.startswith('**'):
1085
+ func_doc.kwarg = name[2:]
1086
+ elif name.startswith('*'):
1087
+ func_doc.vararg = name[1:]
1088
+ else:
1089
+ func_doc.posargs.append(name)
1090
+ if len(func_doc.posarg_defaults) < len(func_doc.posargs):
1091
+ func_doc.posarg_defaults.append(default)
1092
+ elif default is not None:
1093
+ argnum = len(func_doc.posargs)-1
1094
+ func_doc.posarg_defaults[argnum] = default
1095
+
1096
+ # Extract the return type/value from the signature
1097
+ if rtype:
1098
+ func_doc.return_type = markup.parse(rtype, docformat, parse_errors,
1099
+ inline=True)
1100
+
1101
+ # Add the self parameter, if it was specified.
1102
+ if selfparam:
1103
+ func_doc.posargs.insert(0, selfparam)
1104
+ func_doc.posarg_defaults.insert(0, None)
1105
+
1106
+ # Remove the signature from the docstring.
1107
+ doc_source.docstring = doc_source.docstring[m.end():]
1108
+
1109
+ # We found a signature.
1110
+ return True
1111
+