bee_python 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/{build/README → README} +1 -1
- data/egg/egg/build.yml +11 -49
- data/egg/egg.yml +19 -27
- data/egg/http/build.erb +32 -36
- data/egg/http/libhttp.py +102 -0
- data/egg/http/pylint.cfg +236 -0
- data/egg/http/server.py +7 -0
- data/egg/http/test.erb +32 -0
- data/egg/http.yml +33 -29
- data/egg/mysql/mysql.py +8 -9
- data/egg/project/build.erb +21 -53
- data/egg/project/pylint.cfg +236 -0
- data/egg/project/test.py +2 -2
- data/egg/project.yml +23 -31
- data/egg/script/build.erb +18 -23
- data/egg/script/pylint.cfg +236 -0
- data/egg/script.yml +22 -18
- data/egg/source/source.py +6 -6
- data/egg/test/test.py +1 -1
- data/lib/bee_task_python.rb +3 -34
- data/python.yml +123 -0
- metadata +61 -503
- data/test/build.yml +0 -16
- data/test/tc_bee_task_python.rb +0 -27
- data/test/test_build.rb +0 -26
- data/test/test_build_listener.rb +0 -110
- data/test/ts_bee_python.rb +0 -26
- data/tools/common/__init__.py +0 -5
- data/tools/common/common/__init__.py +0 -140
- data/tools/common/common/__pkginfo__.py +0 -43
- data/tools/common/common/adbh.py +0 -35
- data/tools/common/common/cache.py +0 -114
- data/tools/common/common/changelog.py +0 -234
- data/tools/common/common/clcommands.py +0 -181
- data/tools/common/common/cli.py +0 -212
- data/tools/common/common/compat.py +0 -328
- data/tools/common/common/configuration.py +0 -1087
- data/tools/common/common/contexts.py +0 -58
- data/tools/common/common/corbautils.py +0 -117
- data/tools/common/common/daemon.py +0 -171
- data/tools/common/common/date.py +0 -279
- data/tools/common/common/db.py +0 -49
- data/tools/common/common/dbf.py +0 -229
- data/tools/common/common/debugger.py +0 -208
- data/tools/common/common/decorators.py +0 -190
- data/tools/common/common/deprecation.py +0 -118
- data/tools/common/common/fileutils.py +0 -409
- data/tools/common/common/graph.py +0 -259
- data/tools/common/common/html.py +0 -142
- data/tools/common/common/interface.py +0 -76
- data/tools/common/common/logging_ext.py +0 -166
- data/tools/common/common/modutils.py +0 -670
- data/tools/common/common/optik_ext.py +0 -383
- data/tools/common/common/optparser.py +0 -92
- data/tools/common/common/pdf_ext.py +0 -111
- data/tools/common/common/proc.py +0 -276
- data/tools/common/common/pyro_ext.py +0 -146
- data/tools/common/common/pytest.py +0 -754
- data/tools/common/common/shellutils.py +0 -383
- data/tools/common/common/sphinx_ext.py +0 -87
- data/tools/common/common/sphinxutils.py +0 -122
- data/tools/common/common/sqlgen.py +0 -31
- data/tools/common/common/table.py +0 -930
- data/tools/common/common/tasksqueue.py +0 -97
- data/tools/common/common/test/__init__.py +0 -1
- data/tools/common/common/test/data/ChangeLog +0 -184
- data/tools/common/common/test/data/MyPyPa-0.1.0-py2.5.egg +0 -0
- data/tools/common/common/test/data/__init__.py +0 -1
- data/tools/common/common/test/data/content_differ_dir/NOTHING +0 -0
- data/tools/common/common/test/data/content_differ_dir/README +0 -1
- data/tools/common/common/test/data/content_differ_dir/subdir/coin +0 -1
- data/tools/common/common/test/data/content_differ_dir/subdir/toto.txt +0 -53
- data/tools/common/common/test/data/file_differ_dir/NOTHING +0 -0
- data/tools/common/common/test/data/file_differ_dir/README +0 -1
- data/tools/common/common/test/data/file_differ_dir/subdir/toto.txt +0 -53
- data/tools/common/common/test/data/file_differ_dir/subdirtwo/Hello +0 -0
- data/tools/common/common/test/data/find_test/__init__.py +0 -0
- data/tools/common/common/test/data/find_test/foo.txt +0 -0
- data/tools/common/common/test/data/find_test/module.py +0 -0
- data/tools/common/common/test/data/find_test/module2.py +0 -0
- data/tools/common/common/test/data/find_test/newlines.txt +0 -0
- data/tools/common/common/test/data/find_test/noendingnewline.py +0 -0
- data/tools/common/common/test/data/find_test/nonregr.py +0 -0
- data/tools/common/common/test/data/find_test/normal_file.txt +0 -0
- data/tools/common/common/test/data/find_test/spam.txt +0 -0
- data/tools/common/common/test/data/find_test/sub/doc.txt +0 -0
- data/tools/common/common/test/data/find_test/sub/momo.py +0 -0
- data/tools/common/common/test/data/find_test/test.ini +0 -0
- data/tools/common/common/test/data/find_test/test1.msg +0 -0
- data/tools/common/common/test/data/find_test/test2.msg +0 -0
- data/tools/common/common/test/data/find_test/write_protected_file.txt +0 -0
- data/tools/common/common/test/data/foo.txt +0 -9
- data/tools/common/common/test/data/module.py +0 -88
- data/tools/common/common/test/data/module2.py +0 -77
- data/tools/common/common/test/data/newlines.txt +0 -3
- data/tools/common/common/test/data/noendingnewline.py +0 -36
- data/tools/common/common/test/data/nonregr.py +0 -14
- data/tools/common/common/test/data/normal_file.txt +0 -0
- data/tools/common/common/test/data/reference_dir/NOTHING +0 -0
- data/tools/common/common/test/data/reference_dir/README +0 -1
- data/tools/common/common/test/data/reference_dir/subdir/coin +0 -1
- data/tools/common/common/test/data/reference_dir/subdir/toto.txt +0 -53
- data/tools/common/common/test/data/same_dir/NOTHING +0 -0
- data/tools/common/common/test/data/same_dir/README +0 -1
- data/tools/common/common/test/data/same_dir/subdir/coin +0 -1
- data/tools/common/common/test/data/same_dir/subdir/toto.txt +0 -53
- data/tools/common/common/test/data/spam.txt +0 -9
- data/tools/common/common/test/data/sub/doc.txt +0 -1
- data/tools/common/common/test/data/sub/momo.py +0 -1
- data/tools/common/common/test/data/subdir_differ_dir/NOTHING +0 -0
- data/tools/common/common/test/data/subdir_differ_dir/README +0 -1
- data/tools/common/common/test/data/subdir_differ_dir/subdir/coin +0 -1
- data/tools/common/common/test/data/subdir_differ_dir/subdir/toto.txt +0 -53
- data/tools/common/common/test/data/test.ini +0 -20
- data/tools/common/common/test/data/test1.msg +0 -30
- data/tools/common/common/test/data/test2.msg +0 -42
- data/tools/common/common/test/data/write_protected_file.txt +0 -0
- data/tools/common/common/test/foomod.py +0 -17
- data/tools/common/common/test/unittest_cache.py +0 -129
- data/tools/common/common/test/unittest_changelog.py +0 -37
- data/tools/common/common/test/unittest_compat.py +0 -239
- data/tools/common/common/test/unittest_configuration.py +0 -348
- data/tools/common/common/test/unittest_date.py +0 -154
- data/tools/common/common/test/unittest_decorators.py +0 -62
- data/tools/common/common/test/unittest_deprecation.py +0 -76
- data/tools/common/common/test/unittest_fileutils.py +0 -133
- data/tools/common/common/test/unittest_graph.py +0 -50
- data/tools/common/common/test/unittest_html.py +0 -76
- data/tools/common/common/test/unittest_interface.py +0 -87
- data/tools/common/common/test/unittest_modutils.py +0 -244
- data/tools/common/common/test/unittest_pytest.py +0 -50
- data/tools/common/common/test/unittest_shellutils.py +0 -248
- data/tools/common/common/test/unittest_table.py +0 -448
- data/tools/common/common/test/unittest_taskqueue.py +0 -71
- data/tools/common/common/test/unittest_testlib.py +0 -956
- data/tools/common/common/test/unittest_textutils.py +0 -247
- data/tools/common/common/test/unittest_tree.py +0 -248
- data/tools/common/common/test/unittest_umessage.py +0 -55
- data/tools/common/common/test/unittest_ureports_html.py +0 -64
- data/tools/common/common/test/unittest_ureports_text.py +0 -105
- data/tools/common/common/test/unittest_xmlutils.py +0 -75
- data/tools/common/common/test/utils.py +0 -87
- data/tools/common/common/testlib.py +0 -1927
- data/tools/common/common/textutils.py +0 -476
- data/tools/common/common/tree.py +0 -372
- data/tools/common/common/umessage.py +0 -161
- data/tools/common/common/ureports/__init__.py +0 -174
- data/tools/common/common/ureports/docbook_writer.py +0 -139
- data/tools/common/common/ureports/html_writer.py +0 -131
- data/tools/common/common/ureports/nodes.py +0 -201
- data/tools/common/common/ureports/text_writer.py +0 -140
- data/tools/common/common/vcgutils.py +0 -216
- data/tools/common/common/visitor.py +0 -107
- data/tools/common/common/xmlrpcutils.py +0 -136
- data/tools/common/common/xmlutils.py +0 -61
- data/tools/coverage/coverage.py +0 -602
- data/tools/epydoc/__init__.py +0 -227
- data/tools/epydoc/__init__.pyc +0 -0
- data/tools/epydoc/apidoc.py +0 -2203
- data/tools/epydoc/apidoc.pyc +0 -0
- data/tools/epydoc/checker.py +0 -349
- data/tools/epydoc/checker.pyc +0 -0
- data/tools/epydoc/cli.py +0 -1470
- data/tools/epydoc/cli.pyc +0 -0
- data/tools/epydoc/compat.py +0 -250
- data/tools/epydoc/compat.pyc +0 -0
- data/tools/epydoc/docbuilder.py +0 -1358
- data/tools/epydoc/docbuilder.pyc +0 -0
- data/tools/epydoc/docintrospecter.py +0 -1056
- data/tools/epydoc/docintrospecter.pyc +0 -0
- data/tools/epydoc/docparser.py +0 -2113
- data/tools/epydoc/docparser.pyc +0 -0
- data/tools/epydoc/docstringparser.py +0 -1111
- data/tools/epydoc/docstringparser.pyc +0 -0
- data/tools/epydoc/docwriter/__init__.py +0 -12
- data/tools/epydoc/docwriter/__init__.pyc +0 -0
- data/tools/epydoc/docwriter/dotgraph.py +0 -1351
- data/tools/epydoc/docwriter/dotgraph.pyc +0 -0
- data/tools/epydoc/docwriter/html.py +0 -3491
- data/tools/epydoc/docwriter/html.pyc +0 -0
- data/tools/epydoc/docwriter/html_colorize.py +0 -909
- data/tools/epydoc/docwriter/html_colorize.pyc +0 -0
- data/tools/epydoc/docwriter/html_css.py +0 -550
- data/tools/epydoc/docwriter/html_css.pyc +0 -0
- data/tools/epydoc/docwriter/html_help.py +0 -190
- data/tools/epydoc/docwriter/html_help.pyc +0 -0
- data/tools/epydoc/docwriter/latex.py +0 -1187
- data/tools/epydoc/docwriter/latex.pyc +0 -0
- data/tools/epydoc/docwriter/plaintext.py +0 -276
- data/tools/epydoc/docwriter/plaintext.pyc +0 -0
- data/tools/epydoc/docwriter/xlink.py +0 -505
- data/tools/epydoc/docwriter/xlink.pyc +0 -0
- data/tools/epydoc/gui.py +0 -1148
- data/tools/epydoc/gui.pyc +0 -0
- data/tools/epydoc/log.py +0 -204
- data/tools/epydoc/log.pyc +0 -0
- data/tools/epydoc/markup/__init__.py +0 -623
- data/tools/epydoc/markup/__init__.pyc +0 -0
- data/tools/epydoc/markup/doctest.py +0 -311
- data/tools/epydoc/markup/doctest.pyc +0 -0
- data/tools/epydoc/markup/epytext.py +0 -2116
- data/tools/epydoc/markup/epytext.pyc +0 -0
- data/tools/epydoc/markup/javadoc.py +0 -250
- data/tools/epydoc/markup/javadoc.pyc +0 -0
- data/tools/epydoc/markup/plaintext.py +0 -78
- data/tools/epydoc/markup/plaintext.pyc +0 -0
- data/tools/epydoc/markup/pyval_repr.py +0 -532
- data/tools/epydoc/markup/pyval_repr.pyc +0 -0
- data/tools/epydoc/markup/restructuredtext.py +0 -906
- data/tools/epydoc/markup/restructuredtext.pyc +0 -0
- data/tools/epydoc/test/__init__.py +0 -97
- data/tools/epydoc/test/__init__.pyc +0 -0
- data/tools/epydoc/test/util.py +0 -226
- data/tools/epydoc/test/util.pyc +0 -0
- data/tools/epydoc/util.py +0 -289
- data/tools/epydoc/util.pyc +0 -0
- data/tools/logilab/logilab/__init__.py +0 -5
- data/tools/logilab/logilab/astng/__init__.py +0 -82
- data/tools/logilab/logilab/astng/__pkginfo__.py +0 -76
- data/tools/logilab/logilab/astng/_exceptions.py +0 -64
- data/tools/logilab/logilab/astng/_nodes_ast.py +0 -667
- data/tools/logilab/logilab/astng/_nodes_compiler.py +0 -758
- data/tools/logilab/logilab/astng/bases.py +0 -608
- data/tools/logilab/logilab/astng/builder.py +0 -239
- data/tools/logilab/logilab/astng/inference.py +0 -426
- data/tools/logilab/logilab/astng/inspector.py +0 -289
- data/tools/logilab/logilab/astng/manager.py +0 -421
- data/tools/logilab/logilab/astng/mixins.py +0 -165
- data/tools/logilab/logilab/astng/node_classes.py +0 -848
- data/tools/logilab/logilab/astng/nodes.py +0 -85
- data/tools/logilab/logilab/astng/nodes_as_string.py +0 -389
- data/tools/logilab/logilab/astng/patchcomptransformer.py +0 -159
- data/tools/logilab/logilab/astng/protocols.py +0 -333
- data/tools/logilab/logilab/astng/raw_building.py +0 -212
- data/tools/logilab/logilab/astng/rebuilder.py +0 -307
- data/tools/logilab/logilab/astng/scoped_nodes.py +0 -951
- data/tools/logilab/logilab/astng/test/__init__.py +0 -19
- data/tools/logilab/logilab/astng/test/data/MyPyPa-0.1.0-py2.5.egg +0 -0
- data/tools/logilab/logilab/astng/test/data/MyPyPa-0.1.0-py2.5.zip +0 -0
- data/tools/logilab/logilab/astng/test/data/SSL1/Connection1.py +0 -33
- data/tools/logilab/logilab/astng/test/data/SSL1/__init__.py +0 -20
- data/tools/logilab/logilab/astng/test/data/__init__.py +0 -20
- data/tools/logilab/logilab/astng/test/data/all.py +0 -29
- data/tools/logilab/logilab/astng/test/data/appl/__init__.py +0 -23
- data/tools/logilab/logilab/astng/test/data/appl/myConnection.py +0 -30
- data/tools/logilab/logilab/astng/test/data/format.py +0 -34
- data/tools/logilab/logilab/astng/test/data/module.py +0 -90
- data/tools/logilab/logilab/astng/test/data/module2.py +0 -112
- data/tools/logilab/logilab/astng/test/data/noendingnewline.py +0 -57
- data/tools/logilab/logilab/astng/test/data/nonregr.py +0 -76
- data/tools/logilab/logilab/astng/test/data/notall.py +0 -28
- data/tools/logilab/logilab/astng/test/data2/__init__.py +0 -20
- data/tools/logilab/logilab/astng/test/data2/clientmodule_test.py +0 -51
- data/tools/logilab/logilab/astng/test/data2/suppliermodule_test.py +0 -32
- data/tools/logilab/logilab/astng/test/regrtest.py +0 -135
- data/tools/logilab/logilab/astng/test/regrtest_data/absimport.py +0 -22
- data/tools/logilab/logilab/astng/test/regrtest_data/descriptor_crash.py +0 -31
- data/tools/logilab/logilab/astng/test/regrtest_data/import_package_subpackage_module.py +0 -68
- data/tools/logilab/logilab/astng/test/regrtest_data/package/__init__.py +0 -24
- data/tools/logilab/logilab/astng/test/regrtest_data/package/subpackage/__init__.py +0 -20
- data/tools/logilab/logilab/astng/test/regrtest_data/package/subpackage/module.py +0 -20
- data/tools/logilab/logilab/astng/test/unittest_builder.py +0 -684
- data/tools/logilab/logilab/astng/test/unittest_inference.py +0 -1112
- data/tools/logilab/logilab/astng/test/unittest_inspector.py +0 -105
- data/tools/logilab/logilab/astng/test/unittest_lookup.py +0 -302
- data/tools/logilab/logilab/astng/test/unittest_manager.py +0 -98
- data/tools/logilab/logilab/astng/test/unittest_nodes.py +0 -302
- data/tools/logilab/logilab/astng/test/unittest_scoped_nodes.py +0 -501
- data/tools/logilab/logilab/astng/test/unittest_utils.py +0 -104
- data/tools/logilab/logilab/astng/utils.py +0 -342
- data/tools/logilab/logilab/common/__init__.py +0 -140
- data/tools/logilab/logilab/common/__pkginfo__.py +0 -43
- data/tools/logilab/logilab/common/adbh.py +0 -35
- data/tools/logilab/logilab/common/cache.py +0 -114
- data/tools/logilab/logilab/common/changelog.py +0 -234
- data/tools/logilab/logilab/common/clcommands.py +0 -181
- data/tools/logilab/logilab/common/cli.py +0 -212
- data/tools/logilab/logilab/common/compat.py +0 -328
- data/tools/logilab/logilab/common/configuration.py +0 -1087
- data/tools/logilab/logilab/common/contexts.py +0 -58
- data/tools/logilab/logilab/common/corbautils.py +0 -117
- data/tools/logilab/logilab/common/daemon.py +0 -171
- data/tools/logilab/logilab/common/date.py +0 -279
- data/tools/logilab/logilab/common/db.py +0 -49
- data/tools/logilab/logilab/common/dbf.py +0 -229
- data/tools/logilab/logilab/common/debugger.py +0 -208
- data/tools/logilab/logilab/common/decorators.py +0 -190
- data/tools/logilab/logilab/common/deprecation.py +0 -118
- data/tools/logilab/logilab/common/fileutils.py +0 -409
- data/tools/logilab/logilab/common/graph.py +0 -259
- data/tools/logilab/logilab/common/html.py +0 -142
- data/tools/logilab/logilab/common/interface.py +0 -76
- data/tools/logilab/logilab/common/logging_ext.py +0 -166
- data/tools/logilab/logilab/common/modutils.py +0 -670
- data/tools/logilab/logilab/common/optik_ext.py +0 -383
- data/tools/logilab/logilab/common/optparser.py +0 -92
- data/tools/logilab/logilab/common/pdf_ext.py +0 -111
- data/tools/logilab/logilab/common/proc.py +0 -276
- data/tools/logilab/logilab/common/pyro_ext.py +0 -146
- data/tools/logilab/logilab/common/pytest.py +0 -754
- data/tools/logilab/logilab/common/shellutils.py +0 -383
- data/tools/logilab/logilab/common/sphinx_ext.py +0 -87
- data/tools/logilab/logilab/common/sphinxutils.py +0 -122
- data/tools/logilab/logilab/common/sqlgen.py +0 -31
- data/tools/logilab/logilab/common/table.py +0 -930
- data/tools/logilab/logilab/common/tasksqueue.py +0 -97
- data/tools/logilab/logilab/common/test/__init__.py +0 -1
- data/tools/logilab/logilab/common/test/data/ChangeLog +0 -184
- data/tools/logilab/logilab/common/test/data/MyPyPa-0.1.0-py2.5.egg +0 -0
- data/tools/logilab/logilab/common/test/data/__init__.py +0 -1
- data/tools/logilab/logilab/common/test/data/content_differ_dir/NOTHING +0 -0
- data/tools/logilab/logilab/common/test/data/content_differ_dir/README +0 -1
- data/tools/logilab/logilab/common/test/data/content_differ_dir/subdir/coin +0 -1
- data/tools/logilab/logilab/common/test/data/content_differ_dir/subdir/toto.txt +0 -53
- data/tools/logilab/logilab/common/test/data/file_differ_dir/NOTHING +0 -0
- data/tools/logilab/logilab/common/test/data/file_differ_dir/README +0 -1
- data/tools/logilab/logilab/common/test/data/file_differ_dir/subdir/toto.txt +0 -53
- data/tools/logilab/logilab/common/test/data/file_differ_dir/subdirtwo/Hello +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/__init__.py +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/foo.txt +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/module.py +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/module2.py +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/newlines.txt +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/noendingnewline.py +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/nonregr.py +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/normal_file.txt +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/spam.txt +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/sub/doc.txt +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/sub/momo.py +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/test.ini +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/test1.msg +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/test2.msg +0 -0
- data/tools/logilab/logilab/common/test/data/find_test/write_protected_file.txt +0 -0
- data/tools/logilab/logilab/common/test/data/foo.txt +0 -9
- data/tools/logilab/logilab/common/test/data/module.py +0 -88
- data/tools/logilab/logilab/common/test/data/module2.py +0 -77
- data/tools/logilab/logilab/common/test/data/newlines.txt +0 -3
- data/tools/logilab/logilab/common/test/data/noendingnewline.py +0 -36
- data/tools/logilab/logilab/common/test/data/nonregr.py +0 -14
- data/tools/logilab/logilab/common/test/data/normal_file.txt +0 -0
- data/tools/logilab/logilab/common/test/data/reference_dir/NOTHING +0 -0
- data/tools/logilab/logilab/common/test/data/reference_dir/README +0 -1
- data/tools/logilab/logilab/common/test/data/reference_dir/subdir/coin +0 -1
- data/tools/logilab/logilab/common/test/data/reference_dir/subdir/toto.txt +0 -53
- data/tools/logilab/logilab/common/test/data/same_dir/NOTHING +0 -0
- data/tools/logilab/logilab/common/test/data/same_dir/README +0 -1
- data/tools/logilab/logilab/common/test/data/same_dir/subdir/coin +0 -1
- data/tools/logilab/logilab/common/test/data/same_dir/subdir/toto.txt +0 -53
- data/tools/logilab/logilab/common/test/data/spam.txt +0 -9
- data/tools/logilab/logilab/common/test/data/sub/doc.txt +0 -1
- data/tools/logilab/logilab/common/test/data/sub/momo.py +0 -1
- data/tools/logilab/logilab/common/test/data/subdir_differ_dir/NOTHING +0 -0
- data/tools/logilab/logilab/common/test/data/subdir_differ_dir/README +0 -1
- data/tools/logilab/logilab/common/test/data/subdir_differ_dir/subdir/coin +0 -1
- data/tools/logilab/logilab/common/test/data/subdir_differ_dir/subdir/toto.txt +0 -53
- data/tools/logilab/logilab/common/test/data/test.ini +0 -20
- data/tools/logilab/logilab/common/test/data/test1.msg +0 -30
- data/tools/logilab/logilab/common/test/data/test2.msg +0 -42
- data/tools/logilab/logilab/common/test/data/write_protected_file.txt +0 -0
- data/tools/logilab/logilab/common/test/foomod.py +0 -17
- data/tools/logilab/logilab/common/test/unittest_cache.py +0 -129
- data/tools/logilab/logilab/common/test/unittest_changelog.py +0 -37
- data/tools/logilab/logilab/common/test/unittest_compat.py +0 -239
- data/tools/logilab/logilab/common/test/unittest_configuration.py +0 -348
- data/tools/logilab/logilab/common/test/unittest_date.py +0 -154
- data/tools/logilab/logilab/common/test/unittest_decorators.py +0 -62
- data/tools/logilab/logilab/common/test/unittest_deprecation.py +0 -76
- data/tools/logilab/logilab/common/test/unittest_fileutils.py +0 -133
- data/tools/logilab/logilab/common/test/unittest_graph.py +0 -50
- data/tools/logilab/logilab/common/test/unittest_html.py +0 -76
- data/tools/logilab/logilab/common/test/unittest_interface.py +0 -87
- data/tools/logilab/logilab/common/test/unittest_modutils.py +0 -244
- data/tools/logilab/logilab/common/test/unittest_pytest.py +0 -50
- data/tools/logilab/logilab/common/test/unittest_shellutils.py +0 -248
- data/tools/logilab/logilab/common/test/unittest_table.py +0 -448
- data/tools/logilab/logilab/common/test/unittest_taskqueue.py +0 -71
- data/tools/logilab/logilab/common/test/unittest_testlib.py +0 -956
- data/tools/logilab/logilab/common/test/unittest_textutils.py +0 -247
- data/tools/logilab/logilab/common/test/unittest_tree.py +0 -248
- data/tools/logilab/logilab/common/test/unittest_umessage.py +0 -55
- data/tools/logilab/logilab/common/test/unittest_ureports_html.py +0 -64
- data/tools/logilab/logilab/common/test/unittest_ureports_text.py +0 -105
- data/tools/logilab/logilab/common/test/unittest_xmlutils.py +0 -75
- data/tools/logilab/logilab/common/test/utils.py +0 -87
- data/tools/logilab/logilab/common/testlib.py +0 -1927
- data/tools/logilab/logilab/common/textutils.py +0 -476
- data/tools/logilab/logilab/common/tree.py +0 -372
- data/tools/logilab/logilab/common/umessage.py +0 -161
- data/tools/logilab/logilab/common/ureports/__init__.py +0 -174
- data/tools/logilab/logilab/common/ureports/docbook_writer.py +0 -139
- data/tools/logilab/logilab/common/ureports/html_writer.py +0 -131
- data/tools/logilab/logilab/common/ureports/nodes.py +0 -201
- data/tools/logilab/logilab/common/ureports/text_writer.py +0 -140
- data/tools/logilab/logilab/common/vcgutils.py +0 -216
- data/tools/logilab/logilab/common/visitor.py +0 -107
- data/tools/logilab/logilab/common/xmlrpcutils.py +0 -136
- data/tools/logilab/logilab/common/xmlutils.py +0 -61
- data/tools/pychecker/COPYRIGHT +0 -31
- data/tools/pychecker/ChangeLog +0 -349
- data/tools/pychecker/CodeChecks.py +0 -1969
- data/tools/pychecker/CodeChecks.pyc +0 -0
- data/tools/pychecker/CodeChecks.pyo +0 -0
- data/tools/pychecker/Config.py +0 -475
- data/tools/pychecker/Config.pyc +0 -0
- data/tools/pychecker/Config.pyo +0 -0
- data/tools/pychecker/KNOWN_BUGS +0 -100
- data/tools/pychecker/MAINTAINERS +0 -81
- data/tools/pychecker/NEWS +0 -406
- data/tools/pychecker/OP.py +0 -131
- data/tools/pychecker/OP.pyc +0 -0
- data/tools/pychecker/OP.pyo +0 -0
- data/tools/pychecker/OptionTypes.py +0 -117
- data/tools/pychecker/OptionTypes.pyc +0 -0
- data/tools/pychecker/OptionTypes.pyo +0 -0
- data/tools/pychecker/README +0 -152
- data/tools/pychecker/Stack.py +0 -115
- data/tools/pychecker/Stack.pyc +0 -0
- data/tools/pychecker/Stack.pyo +0 -0
- data/tools/pychecker/TODO +0 -101
- data/tools/pychecker/VERSION +0 -1
- data/tools/pychecker/Warning.py +0 -50
- data/tools/pychecker/Warning.pyc +0 -0
- data/tools/pychecker/Warning.pyo +0 -0
- data/tools/pychecker/__init__.py +0 -17
- data/tools/pychecker/__init__.pyc +0 -0
- data/tools/pychecker/__init__.pyo +0 -0
- data/tools/pychecker/checker.py +0 -961
- data/tools/pychecker/checker.pyc +0 -0
- data/tools/pychecker/checker.pyo +0 -0
- data/tools/pychecker/function.py +0 -159
- data/tools/pychecker/function.pyc +0 -0
- data/tools/pychecker/function.pyo +0 -0
- data/tools/pychecker/msgs.py +0 -175
- data/tools/pychecker/msgs.pyc +0 -0
- data/tools/pychecker/msgs.pyo +0 -0
- data/tools/pychecker/options.py +0 -275
- data/tools/pychecker/options.pyc +0 -0
- data/tools/pychecker/options.pyo +0 -0
- data/tools/pychecker/pcmodules.py +0 -19
- data/tools/pychecker/pcmodules.pyc +0 -0
- data/tools/pychecker/pcmodules.pyo +0 -0
- data/tools/pychecker/printer.py +0 -47
- data/tools/pychecker/printer.pyc +0 -0
- data/tools/pychecker/printer.pyo +0 -0
- data/tools/pychecker/python.py +0 -427
- data/tools/pychecker/python.pyc +0 -0
- data/tools/pychecker/python.pyo +0 -0
- data/tools/pychecker/utils.py +0 -102
- data/tools/pychecker/utils.pyc +0 -0
- data/tools/pychecker/utils.pyo +0 -0
- data/tools/pychecker/warn.py +0 -778
- data/tools/pychecker/warn.pyc +0 -0
- data/tools/pychecker/warn.pyo +0 -0
- data/tools/pylint2/pylint/__init__.py +0 -16
- data/tools/pylint2/pylint/__pkginfo__.py +0 -67
- data/tools/pylint2/pylint/checkers/__init__.py +0 -155
- data/tools/pylint2/pylint/checkers/base.py +0 -749
- data/tools/pylint2/pylint/checkers/classes.py +0 -527
- data/tools/pylint2/pylint/checkers/design_analysis.py +0 -344
- data/tools/pylint2/pylint/checkers/exceptions.py +0 -183
- data/tools/pylint2/pylint/checkers/format.py +0 -367
- data/tools/pylint2/pylint/checkers/imports.py +0 -379
- data/tools/pylint2/pylint/checkers/logging.py +0 -98
- data/tools/pylint2/pylint/checkers/misc.py +0 -128
- data/tools/pylint2/pylint/checkers/newstyle.py +0 -107
- data/tools/pylint2/pylint/checkers/raw_metrics.py +0 -125
- data/tools/pylint2/pylint/checkers/similar.py +0 -333
- data/tools/pylint2/pylint/checkers/string_format.py +0 -239
- data/tools/pylint2/pylint/checkers/typecheck.py +0 -364
- data/tools/pylint2/pylint/checkers/utils.py +0 -208
- data/tools/pylint2/pylint/checkers/variables.py +0 -498
- data/tools/pylint2/pylint/config.py +0 -149
- data/tools/pylint2/pylint/epylint.py +0 -149
- data/tools/pylint2/pylint/gui.py +0 -433
- data/tools/pylint2/pylint/interfaces.py +0 -98
- data/tools/pylint2/pylint/lint.py +0 -914
- data/tools/pylint2/pylint/pyreverse/__init__.py +0 -5
- data/tools/pylint2/pylint/pyreverse/diadefslib.py +0 -229
- data/tools/pylint2/pylint/pyreverse/diagrams.py +0 -247
- data/tools/pylint2/pylint/pyreverse/main.py +0 -123
- data/tools/pylint2/pylint/pyreverse/utils.py +0 -131
- data/tools/pylint2/pylint/pyreverse/writer.py +0 -196
- data/tools/pylint2/pylint/reporters/__init__.py +0 -67
- data/tools/pylint2/pylint/reporters/guireporter.py +0 -36
- data/tools/pylint2/pylint/reporters/html.py +0 -69
- data/tools/pylint2/pylint/reporters/text.py +0 -156
- data/tools/pylint2/pylint/utils.py +0 -518
- data/tools/pylint2/pylint.py +0 -16
data/tools/epydoc/apidoc.py
DELETED
@@ -1,2203 +0,0 @@
|
|
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
|
-
|