bee_python 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +202 -0
- data/build/README +23 -0
- data/egg/egg/build.yml +70 -0
- data/egg/egg/ez_setup.py +280 -0
- data/egg/egg/script.py +12 -0
- data/egg/egg/setup.erb +11 -0
- data/egg/egg/suite.py +37 -0
- data/egg/egg/test.py +31 -0
- data/egg/egg.yml +69 -0
- data/egg/http/build.erb +53 -0
- data/egg/http/server.py +34 -0
- data/egg/http.yml +50 -0
- data/egg/mysql/mysql.py +43 -0
- data/egg/mysql.yml +44 -0
- data/egg/project/build.erb +77 -0
- data/egg/project/script.py +42 -0
- data/egg/project/test.py +31 -0
- data/egg/project.yml +59 -0
- data/egg/script/build.erb +35 -0
- data/egg/script/script.py +42 -0
- data/egg/script.yml +50 -0
- data/egg/soap/build.erb +52 -0
- data/egg/soap/client.py +18 -0
- data/egg/soap/server.py +30 -0
- data/egg/soap.yml +58 -0
- data/egg/source/source.py +42 -0
- data/egg/source.yml +47 -0
- data/egg/test/test.py +28 -0
- data/egg/test.yml +44 -0
- data/egg/xmlrpc/build.erb +52 -0
- data/egg/xmlrpc/client.py +22 -0
- data/egg/xmlrpc/server.py +24 -0
- data/egg/xmlrpc.yml +51 -0
- data/lib/bee_task_python.rb +390 -0
- data/test/build.yml +16 -0
- data/test/tc_bee_task_python.rb +27 -0
- data/test/test_build.rb +26 -0
- data/test/test_build_listener.rb +62 -0
- data/test/ts_bee_python.rb +26 -0
- data/tools/common/__init__.py +5 -0
- data/tools/common/common/__init__.py +140 -0
- data/tools/common/common/__pkginfo__.py +43 -0
- data/tools/common/common/adbh.py +35 -0
- data/tools/common/common/cache.py +114 -0
- data/tools/common/common/changelog.py +234 -0
- data/tools/common/common/clcommands.py +181 -0
- data/tools/common/common/cli.py +212 -0
- data/tools/common/common/compat.py +328 -0
- data/tools/common/common/configuration.py +1087 -0
- data/tools/common/common/contexts.py +58 -0
- data/tools/common/common/corbautils.py +117 -0
- data/tools/common/common/daemon.py +171 -0
- data/tools/common/common/date.py +279 -0
- data/tools/common/common/db.py +49 -0
- data/tools/common/common/dbf.py +229 -0
- data/tools/common/common/debugger.py +208 -0
- data/tools/common/common/decorators.py +190 -0
- data/tools/common/common/deprecation.py +118 -0
- data/tools/common/common/fileutils.py +409 -0
- data/tools/common/common/graph.py +259 -0
- data/tools/common/common/html.py +142 -0
- data/tools/common/common/interface.py +76 -0
- data/tools/common/common/logging_ext.py +166 -0
- data/tools/common/common/modutils.py +670 -0
- data/tools/common/common/optik_ext.py +383 -0
- data/tools/common/common/optparser.py +92 -0
- data/tools/common/common/pdf_ext.py +111 -0
- data/tools/common/common/proc.py +276 -0
- data/tools/common/common/pyro_ext.py +146 -0
- data/tools/common/common/pytest.py +754 -0
- data/tools/common/common/shellutils.py +383 -0
- data/tools/common/common/sphinx_ext.py +87 -0
- data/tools/common/common/sphinxutils.py +122 -0
- data/tools/common/common/sqlgen.py +31 -0
- data/tools/common/common/table.py +930 -0
- data/tools/common/common/tasksqueue.py +97 -0
- data/tools/common/common/test/__init__.py +1 -0
- data/tools/common/common/test/data/ChangeLog +184 -0
- data/tools/common/common/test/data/MyPyPa-0.1.0-py2.5.egg +0 -0
- data/tools/common/common/test/data/__init__.py +1 -0
- data/tools/common/common/test/data/content_differ_dir/NOTHING +0 -0
- data/tools/common/common/test/data/content_differ_dir/README +1 -0
- data/tools/common/common/test/data/content_differ_dir/subdir/coin +1 -0
- data/tools/common/common/test/data/content_differ_dir/subdir/toto.txt +53 -0
- data/tools/common/common/test/data/file_differ_dir/NOTHING +0 -0
- data/tools/common/common/test/data/file_differ_dir/README +1 -0
- data/tools/common/common/test/data/file_differ_dir/subdir/toto.txt +53 -0
- 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 +9 -0
- data/tools/common/common/test/data/module.py +88 -0
- data/tools/common/common/test/data/module2.py +77 -0
- data/tools/common/common/test/data/newlines.txt +3 -0
- data/tools/common/common/test/data/noendingnewline.py +36 -0
- data/tools/common/common/test/data/nonregr.py +14 -0
- 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 +1 -0
- data/tools/common/common/test/data/reference_dir/subdir/coin +1 -0
- data/tools/common/common/test/data/reference_dir/subdir/toto.txt +53 -0
- data/tools/common/common/test/data/same_dir/NOTHING +0 -0
- data/tools/common/common/test/data/same_dir/README +1 -0
- data/tools/common/common/test/data/same_dir/subdir/coin +1 -0
- data/tools/common/common/test/data/same_dir/subdir/toto.txt +53 -0
- data/tools/common/common/test/data/spam.txt +9 -0
- data/tools/common/common/test/data/sub/doc.txt +1 -0
- data/tools/common/common/test/data/sub/momo.py +1 -0
- data/tools/common/common/test/data/subdir_differ_dir/NOTHING +0 -0
- data/tools/common/common/test/data/subdir_differ_dir/README +1 -0
- data/tools/common/common/test/data/subdir_differ_dir/subdir/coin +1 -0
- data/tools/common/common/test/data/subdir_differ_dir/subdir/toto.txt +53 -0
- data/tools/common/common/test/data/test.ini +20 -0
- data/tools/common/common/test/data/test1.msg +30 -0
- data/tools/common/common/test/data/test2.msg +42 -0
- data/tools/common/common/test/data/write_protected_file.txt +0 -0
- data/tools/common/common/test/foomod.py +17 -0
- data/tools/common/common/test/unittest_cache.py +129 -0
- data/tools/common/common/test/unittest_changelog.py +37 -0
- data/tools/common/common/test/unittest_compat.py +239 -0
- data/tools/common/common/test/unittest_configuration.py +348 -0
- data/tools/common/common/test/unittest_date.py +154 -0
- data/tools/common/common/test/unittest_decorators.py +62 -0
- data/tools/common/common/test/unittest_deprecation.py +76 -0
- data/tools/common/common/test/unittest_fileutils.py +133 -0
- data/tools/common/common/test/unittest_graph.py +50 -0
- data/tools/common/common/test/unittest_html.py +76 -0
- data/tools/common/common/test/unittest_interface.py +87 -0
- data/tools/common/common/test/unittest_modutils.py +244 -0
- data/tools/common/common/test/unittest_pytest.py +50 -0
- data/tools/common/common/test/unittest_shellutils.py +248 -0
- data/tools/common/common/test/unittest_table.py +448 -0
- data/tools/common/common/test/unittest_taskqueue.py +71 -0
- data/tools/common/common/test/unittest_testlib.py +956 -0
- data/tools/common/common/test/unittest_textutils.py +247 -0
- data/tools/common/common/test/unittest_tree.py +248 -0
- data/tools/common/common/test/unittest_umessage.py +55 -0
- data/tools/common/common/test/unittest_ureports_html.py +64 -0
- data/tools/common/common/test/unittest_ureports_text.py +105 -0
- data/tools/common/common/test/unittest_xmlutils.py +75 -0
- data/tools/common/common/test/utils.py +87 -0
- data/tools/common/common/testlib.py +1927 -0
- data/tools/common/common/textutils.py +476 -0
- data/tools/common/common/tree.py +372 -0
- data/tools/common/common/umessage.py +161 -0
- data/tools/common/common/ureports/__init__.py +174 -0
- data/tools/common/common/ureports/docbook_writer.py +139 -0
- data/tools/common/common/ureports/html_writer.py +131 -0
- data/tools/common/common/ureports/nodes.py +201 -0
- data/tools/common/common/ureports/text_writer.py +140 -0
- data/tools/common/common/vcgutils.py +216 -0
- data/tools/common/common/visitor.py +107 -0
- data/tools/common/common/xmlrpcutils.py +136 -0
- data/tools/common/common/xmlutils.py +61 -0
- data/tools/compile/compile.py +16 -0
- data/tools/coverage/coverage.py +602 -0
- data/tools/epydoc/__init__.py +227 -0
- data/tools/epydoc/__init__.pyc +0 -0
- data/tools/epydoc/apidoc.py +2203 -0
- data/tools/epydoc/apidoc.pyc +0 -0
- data/tools/epydoc/checker.py +349 -0
- data/tools/epydoc/checker.pyc +0 -0
- data/tools/epydoc/cli.py +1470 -0
- data/tools/epydoc/cli.pyc +0 -0
- data/tools/epydoc/compat.py +250 -0
- data/tools/epydoc/compat.pyc +0 -0
- data/tools/epydoc/docbuilder.py +1358 -0
- data/tools/epydoc/docbuilder.pyc +0 -0
- data/tools/epydoc/docintrospecter.py +1056 -0
- data/tools/epydoc/docintrospecter.pyc +0 -0
- data/tools/epydoc/docparser.py +2113 -0
- data/tools/epydoc/docparser.pyc +0 -0
- data/tools/epydoc/docstringparser.py +1111 -0
- data/tools/epydoc/docstringparser.pyc +0 -0
- data/tools/epydoc/docwriter/__init__.py +12 -0
- data/tools/epydoc/docwriter/__init__.pyc +0 -0
- data/tools/epydoc/docwriter/dotgraph.py +1351 -0
- data/tools/epydoc/docwriter/dotgraph.pyc +0 -0
- data/tools/epydoc/docwriter/html.py +3491 -0
- data/tools/epydoc/docwriter/html.pyc +0 -0
- data/tools/epydoc/docwriter/html_colorize.py +909 -0
- data/tools/epydoc/docwriter/html_colorize.pyc +0 -0
- data/tools/epydoc/docwriter/html_css.py +550 -0
- data/tools/epydoc/docwriter/html_css.pyc +0 -0
- data/tools/epydoc/docwriter/html_help.py +190 -0
- data/tools/epydoc/docwriter/html_help.pyc +0 -0
- data/tools/epydoc/docwriter/latex.py +1187 -0
- data/tools/epydoc/docwriter/latex.pyc +0 -0
- data/tools/epydoc/docwriter/plaintext.py +276 -0
- data/tools/epydoc/docwriter/plaintext.pyc +0 -0
- data/tools/epydoc/docwriter/xlink.py +505 -0
- data/tools/epydoc/docwriter/xlink.pyc +0 -0
- data/tools/epydoc/gui.py +1148 -0
- data/tools/epydoc/gui.pyc +0 -0
- data/tools/epydoc/log.py +204 -0
- data/tools/epydoc/log.pyc +0 -0
- data/tools/epydoc/markup/__init__.py +623 -0
- data/tools/epydoc/markup/__init__.pyc +0 -0
- data/tools/epydoc/markup/doctest.py +311 -0
- data/tools/epydoc/markup/doctest.pyc +0 -0
- data/tools/epydoc/markup/epytext.py +2116 -0
- data/tools/epydoc/markup/epytext.pyc +0 -0
- data/tools/epydoc/markup/javadoc.py +250 -0
- data/tools/epydoc/markup/javadoc.pyc +0 -0
- data/tools/epydoc/markup/plaintext.py +78 -0
- data/tools/epydoc/markup/plaintext.pyc +0 -0
- data/tools/epydoc/markup/pyval_repr.py +532 -0
- data/tools/epydoc/markup/pyval_repr.pyc +0 -0
- data/tools/epydoc/markup/restructuredtext.py +906 -0
- data/tools/epydoc/markup/restructuredtext.pyc +0 -0
- data/tools/epydoc/test/__init__.py +97 -0
- data/tools/epydoc/test/__init__.pyc +0 -0
- data/tools/epydoc/test/util.py +226 -0
- data/tools/epydoc/test/util.pyc +0 -0
- data/tools/epydoc/util.py +289 -0
- data/tools/epydoc/util.pyc +0 -0
- data/tools/logilab/logilab/__init__.py +5 -0
- data/tools/logilab/logilab/astng/__init__.py +82 -0
- data/tools/logilab/logilab/astng/__pkginfo__.py +76 -0
- data/tools/logilab/logilab/astng/_exceptions.py +64 -0
- data/tools/logilab/logilab/astng/_nodes_ast.py +667 -0
- data/tools/logilab/logilab/astng/_nodes_compiler.py +758 -0
- data/tools/logilab/logilab/astng/bases.py +608 -0
- data/tools/logilab/logilab/astng/builder.py +239 -0
- data/tools/logilab/logilab/astng/inference.py +426 -0
- data/tools/logilab/logilab/astng/inspector.py +289 -0
- data/tools/logilab/logilab/astng/manager.py +421 -0
- data/tools/logilab/logilab/astng/mixins.py +165 -0
- data/tools/logilab/logilab/astng/node_classes.py +848 -0
- data/tools/logilab/logilab/astng/nodes.py +85 -0
- data/tools/logilab/logilab/astng/nodes_as_string.py +389 -0
- data/tools/logilab/logilab/astng/patchcomptransformer.py +159 -0
- data/tools/logilab/logilab/astng/protocols.py +333 -0
- data/tools/logilab/logilab/astng/raw_building.py +212 -0
- data/tools/logilab/logilab/astng/rebuilder.py +307 -0
- data/tools/logilab/logilab/astng/scoped_nodes.py +951 -0
- data/tools/logilab/logilab/astng/test/__init__.py +19 -0
- 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 +33 -0
- data/tools/logilab/logilab/astng/test/data/SSL1/__init__.py +20 -0
- data/tools/logilab/logilab/astng/test/data/__init__.py +20 -0
- data/tools/logilab/logilab/astng/test/data/all.py +29 -0
- data/tools/logilab/logilab/astng/test/data/appl/__init__.py +23 -0
- data/tools/logilab/logilab/astng/test/data/appl/myConnection.py +30 -0
- data/tools/logilab/logilab/astng/test/data/format.py +34 -0
- data/tools/logilab/logilab/astng/test/data/module.py +90 -0
- data/tools/logilab/logilab/astng/test/data/module2.py +112 -0
- data/tools/logilab/logilab/astng/test/data/noendingnewline.py +57 -0
- data/tools/logilab/logilab/astng/test/data/nonregr.py +76 -0
- data/tools/logilab/logilab/astng/test/data/notall.py +28 -0
- data/tools/logilab/logilab/astng/test/data2/__init__.py +20 -0
- data/tools/logilab/logilab/astng/test/data2/clientmodule_test.py +51 -0
- data/tools/logilab/logilab/astng/test/data2/suppliermodule_test.py +32 -0
- data/tools/logilab/logilab/astng/test/regrtest.py +135 -0
- data/tools/logilab/logilab/astng/test/regrtest_data/absimport.py +22 -0
- data/tools/logilab/logilab/astng/test/regrtest_data/descriptor_crash.py +31 -0
- data/tools/logilab/logilab/astng/test/regrtest_data/import_package_subpackage_module.py +68 -0
- data/tools/logilab/logilab/astng/test/regrtest_data/package/__init__.py +24 -0
- data/tools/logilab/logilab/astng/test/regrtest_data/package/subpackage/__init__.py +20 -0
- data/tools/logilab/logilab/astng/test/regrtest_data/package/subpackage/module.py +20 -0
- data/tools/logilab/logilab/astng/test/unittest_builder.py +684 -0
- data/tools/logilab/logilab/astng/test/unittest_inference.py +1112 -0
- data/tools/logilab/logilab/astng/test/unittest_inspector.py +105 -0
- data/tools/logilab/logilab/astng/test/unittest_lookup.py +302 -0
- data/tools/logilab/logilab/astng/test/unittest_manager.py +98 -0
- data/tools/logilab/logilab/astng/test/unittest_nodes.py +302 -0
- data/tools/logilab/logilab/astng/test/unittest_scoped_nodes.py +501 -0
- data/tools/logilab/logilab/astng/test/unittest_utils.py +104 -0
- data/tools/logilab/logilab/astng/utils.py +342 -0
- data/tools/logilab/logilab/common/__init__.py +140 -0
- data/tools/logilab/logilab/common/__pkginfo__.py +43 -0
- data/tools/logilab/logilab/common/adbh.py +35 -0
- data/tools/logilab/logilab/common/cache.py +114 -0
- data/tools/logilab/logilab/common/changelog.py +234 -0
- data/tools/logilab/logilab/common/clcommands.py +181 -0
- data/tools/logilab/logilab/common/cli.py +212 -0
- data/tools/logilab/logilab/common/compat.py +328 -0
- data/tools/logilab/logilab/common/configuration.py +1087 -0
- data/tools/logilab/logilab/common/contexts.py +58 -0
- data/tools/logilab/logilab/common/corbautils.py +117 -0
- data/tools/logilab/logilab/common/daemon.py +171 -0
- data/tools/logilab/logilab/common/date.py +279 -0
- data/tools/logilab/logilab/common/db.py +49 -0
- data/tools/logilab/logilab/common/dbf.py +229 -0
- data/tools/logilab/logilab/common/debugger.py +208 -0
- data/tools/logilab/logilab/common/decorators.py +190 -0
- data/tools/logilab/logilab/common/deprecation.py +118 -0
- data/tools/logilab/logilab/common/fileutils.py +409 -0
- data/tools/logilab/logilab/common/graph.py +259 -0
- data/tools/logilab/logilab/common/html.py +142 -0
- data/tools/logilab/logilab/common/interface.py +76 -0
- data/tools/logilab/logilab/common/logging_ext.py +166 -0
- data/tools/logilab/logilab/common/modutils.py +670 -0
- data/tools/logilab/logilab/common/optik_ext.py +383 -0
- data/tools/logilab/logilab/common/optparser.py +92 -0
- data/tools/logilab/logilab/common/pdf_ext.py +111 -0
- data/tools/logilab/logilab/common/proc.py +276 -0
- data/tools/logilab/logilab/common/pyro_ext.py +146 -0
- data/tools/logilab/logilab/common/pytest.py +754 -0
- data/tools/logilab/logilab/common/shellutils.py +383 -0
- data/tools/logilab/logilab/common/sphinx_ext.py +87 -0
- data/tools/logilab/logilab/common/sphinxutils.py +122 -0
- data/tools/logilab/logilab/common/sqlgen.py +31 -0
- data/tools/logilab/logilab/common/table.py +930 -0
- data/tools/logilab/logilab/common/tasksqueue.py +97 -0
- data/tools/logilab/logilab/common/test/__init__.py +1 -0
- data/tools/logilab/logilab/common/test/data/ChangeLog +184 -0
- 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 +1 -0
- data/tools/logilab/logilab/common/test/data/content_differ_dir/NOTHING +0 -0
- data/tools/logilab/logilab/common/test/data/content_differ_dir/README +1 -0
- data/tools/logilab/logilab/common/test/data/content_differ_dir/subdir/coin +1 -0
- data/tools/logilab/logilab/common/test/data/content_differ_dir/subdir/toto.txt +53 -0
- data/tools/logilab/logilab/common/test/data/file_differ_dir/NOTHING +0 -0
- data/tools/logilab/logilab/common/test/data/file_differ_dir/README +1 -0
- data/tools/logilab/logilab/common/test/data/file_differ_dir/subdir/toto.txt +53 -0
- 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 +9 -0
- data/tools/logilab/logilab/common/test/data/module.py +88 -0
- data/tools/logilab/logilab/common/test/data/module2.py +77 -0
- data/tools/logilab/logilab/common/test/data/newlines.txt +3 -0
- data/tools/logilab/logilab/common/test/data/noendingnewline.py +36 -0
- data/tools/logilab/logilab/common/test/data/nonregr.py +14 -0
- 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 +1 -0
- data/tools/logilab/logilab/common/test/data/reference_dir/subdir/coin +1 -0
- data/tools/logilab/logilab/common/test/data/reference_dir/subdir/toto.txt +53 -0
- data/tools/logilab/logilab/common/test/data/same_dir/NOTHING +0 -0
- data/tools/logilab/logilab/common/test/data/same_dir/README +1 -0
- data/tools/logilab/logilab/common/test/data/same_dir/subdir/coin +1 -0
- data/tools/logilab/logilab/common/test/data/same_dir/subdir/toto.txt +53 -0
- data/tools/logilab/logilab/common/test/data/spam.txt +9 -0
- data/tools/logilab/logilab/common/test/data/sub/doc.txt +1 -0
- data/tools/logilab/logilab/common/test/data/sub/momo.py +1 -0
- data/tools/logilab/logilab/common/test/data/subdir_differ_dir/NOTHING +0 -0
- data/tools/logilab/logilab/common/test/data/subdir_differ_dir/README +1 -0
- data/tools/logilab/logilab/common/test/data/subdir_differ_dir/subdir/coin +1 -0
- data/tools/logilab/logilab/common/test/data/subdir_differ_dir/subdir/toto.txt +53 -0
- data/tools/logilab/logilab/common/test/data/test.ini +20 -0
- data/tools/logilab/logilab/common/test/data/test1.msg +30 -0
- data/tools/logilab/logilab/common/test/data/test2.msg +42 -0
- data/tools/logilab/logilab/common/test/data/write_protected_file.txt +0 -0
- data/tools/logilab/logilab/common/test/foomod.py +17 -0
- data/tools/logilab/logilab/common/test/unittest_cache.py +129 -0
- data/tools/logilab/logilab/common/test/unittest_changelog.py +37 -0
- data/tools/logilab/logilab/common/test/unittest_compat.py +239 -0
- data/tools/logilab/logilab/common/test/unittest_configuration.py +348 -0
- data/tools/logilab/logilab/common/test/unittest_date.py +154 -0
- data/tools/logilab/logilab/common/test/unittest_decorators.py +62 -0
- data/tools/logilab/logilab/common/test/unittest_deprecation.py +76 -0
- data/tools/logilab/logilab/common/test/unittest_fileutils.py +133 -0
- data/tools/logilab/logilab/common/test/unittest_graph.py +50 -0
- data/tools/logilab/logilab/common/test/unittest_html.py +76 -0
- data/tools/logilab/logilab/common/test/unittest_interface.py +87 -0
- data/tools/logilab/logilab/common/test/unittest_modutils.py +244 -0
- data/tools/logilab/logilab/common/test/unittest_pytest.py +50 -0
- data/tools/logilab/logilab/common/test/unittest_shellutils.py +248 -0
- data/tools/logilab/logilab/common/test/unittest_table.py +448 -0
- data/tools/logilab/logilab/common/test/unittest_taskqueue.py +71 -0
- data/tools/logilab/logilab/common/test/unittest_testlib.py +956 -0
- data/tools/logilab/logilab/common/test/unittest_textutils.py +247 -0
- data/tools/logilab/logilab/common/test/unittest_tree.py +248 -0
- data/tools/logilab/logilab/common/test/unittest_umessage.py +55 -0
- data/tools/logilab/logilab/common/test/unittest_ureports_html.py +64 -0
- data/tools/logilab/logilab/common/test/unittest_ureports_text.py +105 -0
- data/tools/logilab/logilab/common/test/unittest_xmlutils.py +75 -0
- data/tools/logilab/logilab/common/test/utils.py +87 -0
- data/tools/logilab/logilab/common/testlib.py +1927 -0
- data/tools/logilab/logilab/common/textutils.py +476 -0
- data/tools/logilab/logilab/common/tree.py +372 -0
- data/tools/logilab/logilab/common/umessage.py +161 -0
- data/tools/logilab/logilab/common/ureports/__init__.py +174 -0
- data/tools/logilab/logilab/common/ureports/docbook_writer.py +139 -0
- data/tools/logilab/logilab/common/ureports/html_writer.py +131 -0
- data/tools/logilab/logilab/common/ureports/nodes.py +201 -0
- data/tools/logilab/logilab/common/ureports/text_writer.py +140 -0
- data/tools/logilab/logilab/common/vcgutils.py +216 -0
- data/tools/logilab/logilab/common/visitor.py +107 -0
- data/tools/logilab/logilab/common/xmlrpcutils.py +136 -0
- data/tools/logilab/logilab/common/xmlutils.py +61 -0
- data/tools/pychecker/COPYRIGHT +31 -0
- data/tools/pychecker/ChangeLog +349 -0
- data/tools/pychecker/CodeChecks.py +1969 -0
- data/tools/pychecker/CodeChecks.pyc +0 -0
- data/tools/pychecker/CodeChecks.pyo +0 -0
- data/tools/pychecker/Config.py +475 -0
- data/tools/pychecker/Config.pyc +0 -0
- data/tools/pychecker/Config.pyo +0 -0
- data/tools/pychecker/KNOWN_BUGS +100 -0
- data/tools/pychecker/MAINTAINERS +81 -0
- data/tools/pychecker/NEWS +406 -0
- data/tools/pychecker/OP.py +131 -0
- data/tools/pychecker/OP.pyc +0 -0
- data/tools/pychecker/OP.pyo +0 -0
- data/tools/pychecker/OptionTypes.py +117 -0
- data/tools/pychecker/OptionTypes.pyc +0 -0
- data/tools/pychecker/OptionTypes.pyo +0 -0
- data/tools/pychecker/README +152 -0
- data/tools/pychecker/Stack.py +115 -0
- data/tools/pychecker/Stack.pyc +0 -0
- data/tools/pychecker/Stack.pyo +0 -0
- data/tools/pychecker/TODO +101 -0
- data/tools/pychecker/VERSION +1 -0
- data/tools/pychecker/Warning.py +50 -0
- data/tools/pychecker/Warning.pyc +0 -0
- data/tools/pychecker/Warning.pyo +0 -0
- data/tools/pychecker/__init__.py +17 -0
- data/tools/pychecker/__init__.pyc +0 -0
- data/tools/pychecker/__init__.pyo +0 -0
- data/tools/pychecker/checker.py +961 -0
- data/tools/pychecker/checker.pyc +0 -0
- data/tools/pychecker/checker.pyo +0 -0
- data/tools/pychecker/function.py +159 -0
- data/tools/pychecker/function.pyc +0 -0
- data/tools/pychecker/function.pyo +0 -0
- data/tools/pychecker/msgs.py +175 -0
- data/tools/pychecker/msgs.pyc +0 -0
- data/tools/pychecker/msgs.pyo +0 -0
- data/tools/pychecker/options.py +275 -0
- data/tools/pychecker/options.pyc +0 -0
- data/tools/pychecker/options.pyo +0 -0
- data/tools/pychecker/pcmodules.py +19 -0
- data/tools/pychecker/pcmodules.pyc +0 -0
- data/tools/pychecker/pcmodules.pyo +0 -0
- data/tools/pychecker/printer.py +47 -0
- data/tools/pychecker/printer.pyc +0 -0
- data/tools/pychecker/printer.pyo +0 -0
- data/tools/pychecker/python.py +427 -0
- data/tools/pychecker/python.pyc +0 -0
- data/tools/pychecker/python.pyo +0 -0
- data/tools/pychecker/utils.py +102 -0
- data/tools/pychecker/utils.pyc +0 -0
- data/tools/pychecker/utils.pyo +0 -0
- data/tools/pychecker/warn.py +778 -0
- data/tools/pychecker/warn.pyc +0 -0
- data/tools/pychecker/warn.pyo +0 -0
- data/tools/pylint2/pylint/__init__.py +16 -0
- data/tools/pylint2/pylint/__pkginfo__.py +67 -0
- data/tools/pylint2/pylint/checkers/__init__.py +155 -0
- data/tools/pylint2/pylint/checkers/base.py +749 -0
- data/tools/pylint2/pylint/checkers/classes.py +527 -0
- data/tools/pylint2/pylint/checkers/design_analysis.py +344 -0
- data/tools/pylint2/pylint/checkers/exceptions.py +183 -0
- data/tools/pylint2/pylint/checkers/format.py +367 -0
- data/tools/pylint2/pylint/checkers/imports.py +379 -0
- data/tools/pylint2/pylint/checkers/logging.py +98 -0
- data/tools/pylint2/pylint/checkers/misc.py +128 -0
- data/tools/pylint2/pylint/checkers/newstyle.py +107 -0
- data/tools/pylint2/pylint/checkers/raw_metrics.py +125 -0
- data/tools/pylint2/pylint/checkers/similar.py +333 -0
- data/tools/pylint2/pylint/checkers/string_format.py +239 -0
- data/tools/pylint2/pylint/checkers/typecheck.py +364 -0
- data/tools/pylint2/pylint/checkers/utils.py +208 -0
- data/tools/pylint2/pylint/checkers/variables.py +498 -0
- data/tools/pylint2/pylint/config.py +149 -0
- data/tools/pylint2/pylint/epylint.py +149 -0
- data/tools/pylint2/pylint/gui.py +433 -0
- data/tools/pylint2/pylint/interfaces.py +98 -0
- data/tools/pylint2/pylint/lint.py +914 -0
- data/tools/pylint2/pylint/pyreverse/__init__.py +5 -0
- data/tools/pylint2/pylint/pyreverse/diadefslib.py +229 -0
- data/tools/pylint2/pylint/pyreverse/diagrams.py +247 -0
- data/tools/pylint2/pylint/pyreverse/main.py +123 -0
- data/tools/pylint2/pylint/pyreverse/utils.py +131 -0
- data/tools/pylint2/pylint/pyreverse/writer.py +196 -0
- data/tools/pylint2/pylint/reporters/__init__.py +67 -0
- data/tools/pylint2/pylint/reporters/guireporter.py +36 -0
- data/tools/pylint2/pylint/reporters/html.py +69 -0
- data/tools/pylint2/pylint/reporters/text.py +156 -0
- data/tools/pylint2/pylint/utils.py +518 -0
- data/tools/pylint2/pylint.py +16 -0
- data/tools/test/suite.py +35 -0
- metadata +566 -0
data/tools/epydoc/cli.py
ADDED
@@ -0,0 +1,1470 @@
|
|
1
|
+
# epydoc -- Command line interface
|
2
|
+
#
|
3
|
+
# Copyright (C) 2005 Edward Loper
|
4
|
+
# Author: Edward Loper <edloper@loper.org>
|
5
|
+
# URL: <http://epydoc.sf.net>
|
6
|
+
#
|
7
|
+
# $Id: cli.py,v 1.1 2009/11/26 13:20:36 casa Exp $
|
8
|
+
|
9
|
+
"""
|
10
|
+
Command-line interface for epydoc. Abbreviated Usage::
|
11
|
+
|
12
|
+
epydoc [options] NAMES...
|
13
|
+
|
14
|
+
NAMES... The Python modules to document.
|
15
|
+
--html Generate HTML output (default).
|
16
|
+
--latex Generate LaTeX output.
|
17
|
+
--pdf Generate pdf output, via LaTeX.
|
18
|
+
-o DIR, --output DIR The output directory.
|
19
|
+
--inheritance STYLE The format for showing inherited objects.
|
20
|
+
-V, --version Print the version of epydoc.
|
21
|
+
-h, --help Display a usage message.
|
22
|
+
|
23
|
+
Run \"epydoc --help\" for a complete option list. See the epydoc(1)
|
24
|
+
man page for more information.
|
25
|
+
|
26
|
+
Config Files
|
27
|
+
============
|
28
|
+
Configuration files can be specified with the C{--config} option.
|
29
|
+
These files are read using U{ConfigParser
|
30
|
+
<http://docs.python.org/lib/module-ConfigParser.html>}. Configuration
|
31
|
+
files may set options or add names of modules to document. Option
|
32
|
+
names are (usually) identical to the long names of command line
|
33
|
+
options. To specify names to document, use any of the following
|
34
|
+
option names::
|
35
|
+
|
36
|
+
module modules value values object objects
|
37
|
+
|
38
|
+
A simple example of a config file is::
|
39
|
+
|
40
|
+
[epydoc]
|
41
|
+
modules: sys, os, os.path, re, %(MYSANDBOXPATH)/utilities.py
|
42
|
+
name: Example
|
43
|
+
graph: classtree
|
44
|
+
introspect: no
|
45
|
+
|
46
|
+
All ConfigParser interpolations are done using local values and the
|
47
|
+
environment variables.
|
48
|
+
|
49
|
+
|
50
|
+
Verbosity Levels
|
51
|
+
================
|
52
|
+
The C{-v} and C{-q} options increase and decrease verbosity,
|
53
|
+
respectively. The default verbosity level is zero. The verbosity
|
54
|
+
levels are currently defined as follows::
|
55
|
+
|
56
|
+
Progress Markup warnings Warnings Errors
|
57
|
+
-3 none no no no
|
58
|
+
-2 none no no yes
|
59
|
+
-1 none no yes yes
|
60
|
+
0 (default) bar no yes yes
|
61
|
+
1 bar yes yes yes
|
62
|
+
2 list yes yes yes
|
63
|
+
"""
|
64
|
+
__docformat__ = 'epytext en'
|
65
|
+
|
66
|
+
import sys, os, time, re, pickle, textwrap
|
67
|
+
from glob import glob
|
68
|
+
from optparse import OptionParser, OptionGroup, SUPPRESS_HELP
|
69
|
+
import optparse
|
70
|
+
import epydoc
|
71
|
+
from epydoc import log
|
72
|
+
from epydoc.util import wordwrap, run_subprocess, RunSubprocessError
|
73
|
+
from epydoc.util import plaintext_to_html
|
74
|
+
from epydoc.apidoc import UNKNOWN
|
75
|
+
from epydoc.compat import *
|
76
|
+
import ConfigParser
|
77
|
+
from epydoc.docwriter.html_css import STYLESHEETS as CSS_STYLESHEETS
|
78
|
+
|
79
|
+
# This module is only available if Docutils are in the system
|
80
|
+
try:
|
81
|
+
from epydoc.docwriter import xlink
|
82
|
+
except:
|
83
|
+
xlink = None
|
84
|
+
|
85
|
+
INHERITANCE_STYLES = ('grouped', 'listed', 'included')
|
86
|
+
GRAPH_TYPES = ('classtree', 'callgraph', 'umlclasstree')
|
87
|
+
ACTIONS = ('html', 'text', 'latex', 'dvi', 'ps', 'pdf', 'check')
|
88
|
+
DEFAULT_DOCFORMAT = 'epytext'
|
89
|
+
PROFILER = 'profile' #: Which profiler to use: 'hotshot' or 'profile'
|
90
|
+
|
91
|
+
######################################################################
|
92
|
+
#{ Help Topics
|
93
|
+
######################################################################
|
94
|
+
|
95
|
+
DOCFORMATS = ('epytext', 'plaintext', 'restructuredtext', 'javadoc')
|
96
|
+
HELP_TOPICS = {
|
97
|
+
'docformat': textwrap.dedent('''\
|
98
|
+
__docformat__ is a module variable that specifies the markup
|
99
|
+
language for the docstrings in a module. Its value is a
|
100
|
+
string, consisting the name of a markup language, optionally
|
101
|
+
followed by a language code (such as "en" for English). Epydoc
|
102
|
+
currently recognizes the following markup language names:
|
103
|
+
''' + ', '.join(DOCFORMATS)),
|
104
|
+
'inheritance': textwrap.dedent('''\
|
105
|
+
The following inheritance formats are currently supported:
|
106
|
+
- grouped: inherited objects are gathered into groups,
|
107
|
+
based on what class they were inherited from.
|
108
|
+
- listed: inherited objects are listed in a short list
|
109
|
+
at the end of their section.
|
110
|
+
- included: inherited objects are mixed in with
|
111
|
+
non-inherited objects.'''),
|
112
|
+
'css': textwrap.dedent(
|
113
|
+
'The following built-in CSS stylesheets are available:\n' +
|
114
|
+
'\n'.join([' %10s: %s' % (key, descr)
|
115
|
+
for (key, (sheet, descr))
|
116
|
+
in CSS_STYLESHEETS.items()])),
|
117
|
+
#'checks': textwrap.dedent('''\
|
118
|
+
#
|
119
|
+
# '''),
|
120
|
+
}
|
121
|
+
|
122
|
+
|
123
|
+
HELP_TOPICS['topics'] = wordwrap(
|
124
|
+
'Epydoc can provide additional help for the following topics: ' +
|
125
|
+
', '.join(['%r' % topic for topic in HELP_TOPICS.keys()]))
|
126
|
+
|
127
|
+
######################################################################
|
128
|
+
#{ Argument & Config File Parsing
|
129
|
+
######################################################################
|
130
|
+
|
131
|
+
OPTION_DEFAULTS = dict(
|
132
|
+
action="html", show_frames=True, docformat=DEFAULT_DOCFORMAT,
|
133
|
+
show_private=True, show_imports=False, inheritance="listed",
|
134
|
+
verbose=0, quiet=0, load_pickle=False, parse=True, introspect=True,
|
135
|
+
debug=epydoc.DEBUG, profile=False, graphs=[],
|
136
|
+
list_classes_separately=False, graph_font=None, graph_font_size=None,
|
137
|
+
include_source_code=True, pstat_files=[], simple_term=False, fail_on=None,
|
138
|
+
exclude=[], exclude_parse=[], exclude_introspect=[],
|
139
|
+
external_api=[], external_api_file=[], external_api_root=[],
|
140
|
+
redundant_details=False, src_code_tab_width=8)
|
141
|
+
|
142
|
+
def parse_arguments():
|
143
|
+
# Construct the option parser.
|
144
|
+
usage = '%prog [ACTION] [options] NAMES...'
|
145
|
+
version = "Epydoc, version %s" % epydoc.__version__
|
146
|
+
optparser = OptionParser(usage=usage, add_help_option=False)
|
147
|
+
|
148
|
+
optparser.add_option('--config',
|
149
|
+
action='append', dest="configfiles", metavar='FILE',
|
150
|
+
help=("A configuration file, specifying additional OPTIONS "
|
151
|
+
"and/or NAMES. This option may be repeated."))
|
152
|
+
|
153
|
+
optparser.add_option("--output", "-o",
|
154
|
+
dest="target", metavar="PATH",
|
155
|
+
help="The output directory. If PATH does not exist, then "
|
156
|
+
"it will be created.")
|
157
|
+
|
158
|
+
optparser.add_option("--quiet", "-q",
|
159
|
+
action="count", dest="quiet",
|
160
|
+
help="Decrease the verbosity.")
|
161
|
+
|
162
|
+
optparser.add_option("--verbose", "-v",
|
163
|
+
action="count", dest="verbose",
|
164
|
+
help="Increase the verbosity.")
|
165
|
+
|
166
|
+
optparser.add_option("--debug",
|
167
|
+
action="store_true", dest="debug",
|
168
|
+
help="Show full tracebacks for internal errors.")
|
169
|
+
|
170
|
+
optparser.add_option("--simple-term",
|
171
|
+
action="store_true", dest="simple_term",
|
172
|
+
help="Do not try to use color or cursor control when displaying "
|
173
|
+
"the progress bar, warnings, or errors.")
|
174
|
+
|
175
|
+
|
176
|
+
action_group = OptionGroup(optparser, 'Actions')
|
177
|
+
optparser.add_option_group(action_group)
|
178
|
+
|
179
|
+
action_group.add_option("--html",
|
180
|
+
action="store_const", dest="action", const="html",
|
181
|
+
help="Write HTML output.")
|
182
|
+
|
183
|
+
action_group.add_option("--text",
|
184
|
+
action="store_const", dest="action", const="text",
|
185
|
+
help="Write plaintext output. (not implemented yet)")
|
186
|
+
|
187
|
+
action_group.add_option("--latex",
|
188
|
+
action="store_const", dest="action", const="latex",
|
189
|
+
help="Write LaTeX output.")
|
190
|
+
|
191
|
+
action_group.add_option("--dvi",
|
192
|
+
action="store_const", dest="action", const="dvi",
|
193
|
+
help="Write DVI output.")
|
194
|
+
|
195
|
+
action_group.add_option("--ps",
|
196
|
+
action="store_const", dest="action", const="ps",
|
197
|
+
help="Write Postscript output.")
|
198
|
+
|
199
|
+
action_group.add_option("--pdf",
|
200
|
+
action="store_const", dest="action", const="pdf",
|
201
|
+
help="Write PDF output.")
|
202
|
+
|
203
|
+
action_group.add_option("--check",
|
204
|
+
action="store_const", dest="action", const="check",
|
205
|
+
help="Check completeness of docs.")
|
206
|
+
|
207
|
+
action_group.add_option("--pickle",
|
208
|
+
action="store_const", dest="action", const="pickle",
|
209
|
+
help="Write the documentation to a pickle file.")
|
210
|
+
|
211
|
+
# Provide our own --help and --version options.
|
212
|
+
action_group.add_option("--version",
|
213
|
+
action="store_const", dest="action", const="version",
|
214
|
+
help="Show epydoc's version number and exit.")
|
215
|
+
|
216
|
+
action_group.add_option("-h", "--help",
|
217
|
+
action="store_const", dest="action", const="help",
|
218
|
+
help="Show this message and exit. For help on specific "
|
219
|
+
"topics, use \"--help TOPIC\". Use \"--help topics\" for a "
|
220
|
+
"list of available help topics")
|
221
|
+
|
222
|
+
|
223
|
+
generation_group = OptionGroup(optparser, 'Generation Options')
|
224
|
+
optparser.add_option_group(generation_group)
|
225
|
+
|
226
|
+
generation_group.add_option("--docformat",
|
227
|
+
dest="docformat", metavar="NAME",
|
228
|
+
help="The default markup language for docstrings. Defaults "
|
229
|
+
"to \"%s\"." % DEFAULT_DOCFORMAT)
|
230
|
+
|
231
|
+
generation_group.add_option("--parse-only",
|
232
|
+
action="store_false", dest="introspect",
|
233
|
+
help="Get all information from parsing (don't introspect)")
|
234
|
+
|
235
|
+
generation_group.add_option("--introspect-only",
|
236
|
+
action="store_false", dest="parse",
|
237
|
+
help="Get all information from introspecting (don't parse)")
|
238
|
+
|
239
|
+
generation_group.add_option("--exclude",
|
240
|
+
dest="exclude", metavar="PATTERN", action="append",
|
241
|
+
help="Exclude modules whose dotted name matches "
|
242
|
+
"the regular expression PATTERN")
|
243
|
+
|
244
|
+
generation_group.add_option("--exclude-introspect",
|
245
|
+
dest="exclude_introspect", metavar="PATTERN", action="append",
|
246
|
+
help="Exclude introspection of modules whose dotted name matches "
|
247
|
+
"the regular expression PATTERN")
|
248
|
+
|
249
|
+
generation_group.add_option("--exclude-parse",
|
250
|
+
dest="exclude_parse", metavar="PATTERN", action="append",
|
251
|
+
help="Exclude parsing of modules whose dotted name matches "
|
252
|
+
"the regular expression PATTERN")
|
253
|
+
|
254
|
+
generation_group.add_option("--inheritance",
|
255
|
+
dest="inheritance", metavar="STYLE",
|
256
|
+
help="The format for showing inheritance objects. STYLE "
|
257
|
+
"should be one of: %s." % ', '.join(INHERITANCE_STYLES))
|
258
|
+
|
259
|
+
generation_group.add_option("--show-private",
|
260
|
+
action="store_true", dest="show_private",
|
261
|
+
help="Include private variables in the output. (default)")
|
262
|
+
|
263
|
+
generation_group.add_option("--no-private",
|
264
|
+
action="store_false", dest="show_private",
|
265
|
+
help="Do not include private variables in the output.")
|
266
|
+
|
267
|
+
generation_group.add_option("--show-imports",
|
268
|
+
action="store_true", dest="show_imports",
|
269
|
+
help="List each module's imports.")
|
270
|
+
|
271
|
+
generation_group.add_option("--no-imports",
|
272
|
+
action="store_false", dest="show_imports",
|
273
|
+
help="Do not list each module's imports. (default)")
|
274
|
+
|
275
|
+
generation_group.add_option('--show-sourcecode',
|
276
|
+
action='store_true', dest='include_source_code',
|
277
|
+
help=("Include source code with syntax highlighting in the "
|
278
|
+
"HTML output. (default)"))
|
279
|
+
|
280
|
+
generation_group.add_option('--no-sourcecode',
|
281
|
+
action='store_false', dest='include_source_code',
|
282
|
+
help=("Do not include source code with syntax highlighting in the "
|
283
|
+
"HTML output."))
|
284
|
+
|
285
|
+
generation_group.add_option('--include-log',
|
286
|
+
action='store_true', dest='include_log',
|
287
|
+
help=("Include a page with the process log (epydoc-log.html)"))
|
288
|
+
|
289
|
+
generation_group.add_option(
|
290
|
+
'--redundant-details',
|
291
|
+
action='store_true', dest='redundant_details',
|
292
|
+
help=("Include values in the details lists even if all info "
|
293
|
+
"about them is already provided by the summary table."))
|
294
|
+
|
295
|
+
output_group = OptionGroup(optparser, 'Output Options')
|
296
|
+
optparser.add_option_group(output_group)
|
297
|
+
|
298
|
+
output_group.add_option("--name", "-n",
|
299
|
+
dest="prj_name", metavar="NAME",
|
300
|
+
help="The documented project's name (for the navigation bar).")
|
301
|
+
|
302
|
+
output_group.add_option("--css", "-c",
|
303
|
+
dest="css", metavar="STYLESHEET",
|
304
|
+
help="The CSS stylesheet. STYLESHEET can be either a "
|
305
|
+
"builtin stylesheet or the name of a CSS file.")
|
306
|
+
|
307
|
+
output_group.add_option("--url", "-u",
|
308
|
+
dest="prj_url", metavar="URL",
|
309
|
+
help="The documented project's URL (for the navigation bar).")
|
310
|
+
|
311
|
+
output_group.add_option("--navlink",
|
312
|
+
dest="prj_link", metavar="HTML",
|
313
|
+
help="HTML code for a navigation link to place in the "
|
314
|
+
"navigation bar.")
|
315
|
+
|
316
|
+
output_group.add_option("--top",
|
317
|
+
dest="top_page", metavar="PAGE",
|
318
|
+
help="The \"top\" page for the HTML documentation. PAGE can "
|
319
|
+
"be a URL, the name of a module or class, or one of the "
|
320
|
+
"special names \"trees.html\", \"indices.html\", or \"help.html\"")
|
321
|
+
|
322
|
+
output_group.add_option("--help-file",
|
323
|
+
dest="help_file", metavar="FILE",
|
324
|
+
help="An alternate help file. FILE should contain the body "
|
325
|
+
"of an HTML file -- navigation bars will be added to it.")
|
326
|
+
|
327
|
+
output_group.add_option("--show-frames",
|
328
|
+
action="store_true", dest="show_frames",
|
329
|
+
help="Include frames in the HTML output. (default)")
|
330
|
+
|
331
|
+
output_group.add_option("--no-frames",
|
332
|
+
action="store_false", dest="show_frames",
|
333
|
+
help="Do not include frames in the HTML output.")
|
334
|
+
|
335
|
+
output_group.add_option('--separate-classes',
|
336
|
+
action='store_true', dest='list_classes_separately',
|
337
|
+
help=("When generating LaTeX or PDF output, list each class in "
|
338
|
+
"its own section, instead of listing them under their "
|
339
|
+
"containing module."))
|
340
|
+
|
341
|
+
output_group.add_option('--src-code-tab-width',
|
342
|
+
action='store', type='int', dest='src_code_tab_width',
|
343
|
+
help=("When generating HTML output, sets the number of spaces "
|
344
|
+
"each tab in source code listings is replaced with."))
|
345
|
+
|
346
|
+
# The group of external API options.
|
347
|
+
# Skip if the module couldn't be imported (usually missing docutils)
|
348
|
+
if xlink is not None:
|
349
|
+
link_group = OptionGroup(optparser,
|
350
|
+
xlink.ApiLinkReader.settings_spec[0])
|
351
|
+
optparser.add_option_group(link_group)
|
352
|
+
|
353
|
+
for help, names, opts in xlink.ApiLinkReader.settings_spec[2]:
|
354
|
+
opts = opts.copy()
|
355
|
+
opts['help'] = help
|
356
|
+
link_group.add_option(*names, **opts)
|
357
|
+
|
358
|
+
graph_group = OptionGroup(optparser, 'Graph Options')
|
359
|
+
optparser.add_option_group(graph_group)
|
360
|
+
|
361
|
+
graph_group.add_option('--graph',
|
362
|
+
action='append', dest='graphs', metavar='GRAPHTYPE',
|
363
|
+
help=("Include graphs of type GRAPHTYPE in the generated output. "
|
364
|
+
"Graphs are generated using the Graphviz dot executable. "
|
365
|
+
"If this executable is not on the path, then use --dotpath "
|
366
|
+
"to specify its location. This option may be repeated to "
|
367
|
+
"include multiple graph types in the output. GRAPHTYPE "
|
368
|
+
"should be one of: all, %s." % ', '.join(GRAPH_TYPES)))
|
369
|
+
|
370
|
+
graph_group.add_option("--dotpath",
|
371
|
+
dest="dotpath", metavar='PATH',
|
372
|
+
help="The path to the Graphviz 'dot' executable.")
|
373
|
+
|
374
|
+
graph_group.add_option('--graph-font',
|
375
|
+
dest='graph_font', metavar='FONT',
|
376
|
+
help=("Specify the font used to generate Graphviz graphs. (e.g., "
|
377
|
+
"helvetica or times)."))
|
378
|
+
|
379
|
+
graph_group.add_option('--graph-font-size',
|
380
|
+
dest='graph_font_size', metavar='SIZE',
|
381
|
+
help=("Specify the font size used to generate Graphviz graphs, "
|
382
|
+
"in points."))
|
383
|
+
|
384
|
+
graph_group.add_option('--pstat',
|
385
|
+
action='append', dest='pstat_files', metavar='FILE',
|
386
|
+
help="A pstat output file, to be used in generating call graphs.")
|
387
|
+
|
388
|
+
# this option is for developers, not users.
|
389
|
+
graph_group.add_option("--profile-epydoc",
|
390
|
+
action="store_true", dest="profile",
|
391
|
+
help=SUPPRESS_HELP or
|
392
|
+
("Run the hotshot profiler on epydoc itself. Output "
|
393
|
+
"will be written to profile.out."))
|
394
|
+
|
395
|
+
|
396
|
+
return_group = OptionGroup(optparser, 'Return Value Options')
|
397
|
+
optparser.add_option_group(return_group)
|
398
|
+
|
399
|
+
return_group.add_option("--fail-on-error",
|
400
|
+
action="store_const", dest="fail_on", const=log.ERROR,
|
401
|
+
help="Return a non-zero exit status, indicating failure, if any "
|
402
|
+
"errors are encountered.")
|
403
|
+
|
404
|
+
return_group.add_option("--fail-on-warning",
|
405
|
+
action="store_const", dest="fail_on", const=log.WARNING,
|
406
|
+
help="Return a non-zero exit status, indicating failure, if any "
|
407
|
+
"errors or warnings are encountered (not including docstring "
|
408
|
+
"warnings).")
|
409
|
+
|
410
|
+
return_group.add_option("--fail-on-docstring-warning",
|
411
|
+
action="store_const", dest="fail_on", const=log.DOCSTRING_WARNING,
|
412
|
+
help="Return a non-zero exit status, indicating failure, if any "
|
413
|
+
"errors or warnings are encountered (including docstring "
|
414
|
+
"warnings).")
|
415
|
+
|
416
|
+
# Set the option parser's defaults.
|
417
|
+
optparser.set_defaults(**OPTION_DEFAULTS)
|
418
|
+
|
419
|
+
# Parse the arguments.
|
420
|
+
options, names = optparser.parse_args()
|
421
|
+
|
422
|
+
# Print help message, if requested. We also provide support for
|
423
|
+
# --help [topic]
|
424
|
+
if options.action == 'help':
|
425
|
+
names = set([n.lower() for n in names])
|
426
|
+
for (topic, msg) in HELP_TOPICS.items():
|
427
|
+
if topic.lower() in names:
|
428
|
+
print '\n' + msg.rstrip() + '\n'
|
429
|
+
sys.exit(0)
|
430
|
+
optparser.print_help()
|
431
|
+
sys.exit(0)
|
432
|
+
|
433
|
+
# Print version message, if requested.
|
434
|
+
if options.action == 'version':
|
435
|
+
print version
|
436
|
+
sys.exit(0)
|
437
|
+
|
438
|
+
# Process any config files.
|
439
|
+
if options.configfiles:
|
440
|
+
try:
|
441
|
+
parse_configfiles(options.configfiles, options, names)
|
442
|
+
except (KeyboardInterrupt,SystemExit): raise
|
443
|
+
except Exception, e:
|
444
|
+
if len(options.configfiles) == 1:
|
445
|
+
cf_name = 'config file %s' % options.configfiles[0]
|
446
|
+
else:
|
447
|
+
cf_name = 'config files %s' % ', '.join(options.configfiles)
|
448
|
+
optparser.error('Error reading %s:\n %s' % (cf_name, e))
|
449
|
+
|
450
|
+
# Check if the input file is a pickle file.
|
451
|
+
for name in names:
|
452
|
+
if name.endswith('.pickle'):
|
453
|
+
if len(names) != 1:
|
454
|
+
optparser.error("When a pickle file is specified, no other "
|
455
|
+
"input files may be specified.")
|
456
|
+
options.load_pickle = True
|
457
|
+
|
458
|
+
# Check to make sure all options are valid.
|
459
|
+
if len(names) == 0:
|
460
|
+
optparser.error("No names specified.")
|
461
|
+
|
462
|
+
# perform shell expansion.
|
463
|
+
for i, name in reversed(list(enumerate(names[:]))):
|
464
|
+
if '?' in name or '*' in name:
|
465
|
+
names[i:i+1] = glob(name)
|
466
|
+
|
467
|
+
if options.inheritance not in INHERITANCE_STYLES:
|
468
|
+
optparser.error("Bad inheritance style. Valid options are " +
|
469
|
+
",".join(INHERITANCE_STYLES))
|
470
|
+
if not options.parse and not options.introspect:
|
471
|
+
optparser.error("Invalid option combination: --parse-only "
|
472
|
+
"and --introspect-only.")
|
473
|
+
if options.action == 'text' and len(names) > 1:
|
474
|
+
optparser.error("--text option takes only one name.")
|
475
|
+
|
476
|
+
# Check the list of requested graph types to make sure they're
|
477
|
+
# acceptable.
|
478
|
+
options.graphs = [graph_type.lower() for graph_type in options.graphs]
|
479
|
+
for graph_type in options.graphs:
|
480
|
+
if graph_type == 'callgraph' and not options.pstat_files:
|
481
|
+
optparser.error('"callgraph" graph type may only be used if '
|
482
|
+
'one or more pstat files are specified.')
|
483
|
+
# If it's 'all', then add everything (but don't add callgraph if
|
484
|
+
# we don't have any profiling info to base them on).
|
485
|
+
if graph_type == 'all':
|
486
|
+
if options.pstat_files:
|
487
|
+
options.graphs = GRAPH_TYPES
|
488
|
+
else:
|
489
|
+
options.graphs = [g for g in GRAPH_TYPES if g != 'callgraph']
|
490
|
+
break
|
491
|
+
elif graph_type not in GRAPH_TYPES:
|
492
|
+
optparser.error("Invalid graph type %s." % graph_type)
|
493
|
+
|
494
|
+
# Calculate verbosity.
|
495
|
+
verbosity = getattr(options, 'verbosity', 0)
|
496
|
+
options.verbosity = verbosity + options.verbose - options.quiet
|
497
|
+
|
498
|
+
# The target default depends on the action.
|
499
|
+
if options.target is None:
|
500
|
+
options.target = options.action
|
501
|
+
|
502
|
+
# Return parsed args.
|
503
|
+
options.names = names
|
504
|
+
return options, names
|
505
|
+
|
506
|
+
def parse_configfiles(configfiles, options, names):
|
507
|
+
configparser = ConfigParser.ConfigParser()
|
508
|
+
# ConfigParser.read() silently ignores errors, so open the files
|
509
|
+
# manually (since we want to notify the user of any errors).
|
510
|
+
for configfile in configfiles:
|
511
|
+
fp = open(configfile, 'r') # may raise IOError.
|
512
|
+
configparser.readfp(fp, configfile)
|
513
|
+
fp.close()
|
514
|
+
for optname in configparser.options('epydoc'):
|
515
|
+
val = configparser.get('epydoc', optname, vars=os.environ).strip()
|
516
|
+
optname = optname.lower().strip()
|
517
|
+
|
518
|
+
if optname in ('modules', 'objects', 'values',
|
519
|
+
'module', 'object', 'value'):
|
520
|
+
names.extend(_str_to_list(val))
|
521
|
+
elif optname == 'target':
|
522
|
+
options.target = val
|
523
|
+
elif optname == 'output':
|
524
|
+
if val.lower() not in ACTIONS:
|
525
|
+
raise ValueError('"%s" expected one of: %s' %
|
526
|
+
(optname, ', '.join(ACTIONS)))
|
527
|
+
options.action = val.lower()
|
528
|
+
elif optname == 'verbosity':
|
529
|
+
options.verbosity = _str_to_int(val, optname)
|
530
|
+
elif optname == 'debug':
|
531
|
+
options.debug = _str_to_bool(val, optname)
|
532
|
+
elif optname in ('simple-term', 'simple_term'):
|
533
|
+
options.simple_term = _str_to_bool(val, optname)
|
534
|
+
|
535
|
+
# Generation options
|
536
|
+
elif optname == 'docformat':
|
537
|
+
options.docformat = val
|
538
|
+
elif optname == 'parse':
|
539
|
+
options.parse = _str_to_bool(val, optname)
|
540
|
+
elif optname == 'introspect':
|
541
|
+
options.introspect = _str_to_bool(val, optname)
|
542
|
+
elif optname == 'exclude':
|
543
|
+
options.exclude.extend(_str_to_list(val))
|
544
|
+
elif optname in ('exclude-parse', 'exclude_parse'):
|
545
|
+
options.exclude_parse.extend(_str_to_list(val))
|
546
|
+
elif optname in ('exclude-introspect', 'exclude_introspect'):
|
547
|
+
options.exclude_introspect.extend(_str_to_list(val))
|
548
|
+
elif optname == 'inheritance':
|
549
|
+
if val.lower() not in INHERITANCE_STYLES:
|
550
|
+
raise ValueError('"%s" expected one of: %s.' %
|
551
|
+
(optname, ', '.join(INHERITANCE_STYLES)))
|
552
|
+
options.inheritance = val.lower()
|
553
|
+
elif optname =='private':
|
554
|
+
options.show_private = _str_to_bool(val, optname)
|
555
|
+
elif optname =='imports':
|
556
|
+
options.show_imports = _str_to_bool(val, optname)
|
557
|
+
elif optname == 'sourcecode':
|
558
|
+
options.include_source_code = _str_to_bool(val, optname)
|
559
|
+
elif optname in ('include-log', 'include_log'):
|
560
|
+
options.include_log = _str_to_bool(val, optname)
|
561
|
+
elif optname in ('redundant-details', 'redundant_details'):
|
562
|
+
options.redundant_details = _str_to_bool(val, optname)
|
563
|
+
|
564
|
+
# Output options
|
565
|
+
elif optname == 'name':
|
566
|
+
options.prj_name = val
|
567
|
+
elif optname == 'css':
|
568
|
+
options.css = val
|
569
|
+
elif optname == 'url':
|
570
|
+
options.prj_url = val
|
571
|
+
elif optname == 'link':
|
572
|
+
options.prj_link = val
|
573
|
+
elif optname == 'top':
|
574
|
+
options.top_page = val
|
575
|
+
elif optname == 'help':
|
576
|
+
options.help_file = val
|
577
|
+
elif optname =='frames':
|
578
|
+
options.show_frames = _str_to_bool(val, optname)
|
579
|
+
elif optname in ('separate-classes', 'separate_classes'):
|
580
|
+
options.list_classes_separately = _str_to_bool(val, optname)
|
581
|
+
elif optname in ('src-code-tab-width', 'src_code_tab_width'):
|
582
|
+
options.src_code_tab_width = _str_to_int(val, optname)
|
583
|
+
|
584
|
+
# External API
|
585
|
+
elif optname in ('external-api', 'external_api'):
|
586
|
+
options.external_api.extend(_str_to_list(val))
|
587
|
+
elif optname in ('external-api-file', 'external_api_file'):
|
588
|
+
options.external_api_file.extend(_str_to_list(val))
|
589
|
+
elif optname in ('external-api-root', 'external_api_root'):
|
590
|
+
options.external_api_root.extend(_str_to_list(val))
|
591
|
+
|
592
|
+
# Graph options
|
593
|
+
elif optname == 'graph':
|
594
|
+
graphtypes = _str_to_list(val)
|
595
|
+
for graphtype in graphtypes:
|
596
|
+
if graphtype not in GRAPH_TYPES + ('all',):
|
597
|
+
raise ValueError('"%s" expected one of: all, %s.' %
|
598
|
+
(optname, ', '.join(GRAPH_TYPES)))
|
599
|
+
options.graphs.extend(graphtypes)
|
600
|
+
elif optname == 'dotpath':
|
601
|
+
options.dotpath = val
|
602
|
+
elif optname in ('graph-font', 'graph_font'):
|
603
|
+
options.graph_font = val
|
604
|
+
elif optname in ('graph-font-size', 'graph_font_size'):
|
605
|
+
options.graph_font_size = _str_to_int(val, optname)
|
606
|
+
elif optname == 'pstat':
|
607
|
+
options.pstat_files.extend(_str_to_list(val))
|
608
|
+
|
609
|
+
# Return value options
|
610
|
+
elif optname in ('failon', 'fail-on', 'fail_on'):
|
611
|
+
if val.lower().strip() in ('error', 'errors'):
|
612
|
+
options.fail_on = log.ERROR
|
613
|
+
elif val.lower().strip() in ('warning', 'warnings'):
|
614
|
+
options.fail_on = log.WARNING
|
615
|
+
elif val.lower().strip() in ('docstring_warning',
|
616
|
+
'docstring_warnings'):
|
617
|
+
options.fail_on = log.DOCSTRING_WARNING
|
618
|
+
else:
|
619
|
+
raise ValueError("%r expected one of: error, warning, "
|
620
|
+
"docstring_warning" % optname)
|
621
|
+
else:
|
622
|
+
raise ValueError('Unknown option %s' % optname)
|
623
|
+
|
624
|
+
def _str_to_bool(val, optname):
|
625
|
+
if val.lower() in ('0', 'no', 'false', 'n', 'f', 'hide'):
|
626
|
+
return False
|
627
|
+
elif val.lower() in ('1', 'yes', 'true', 'y', 't', 'show'):
|
628
|
+
return True
|
629
|
+
else:
|
630
|
+
raise ValueError('"%s" option expected a boolean' % optname)
|
631
|
+
|
632
|
+
def _str_to_int(val, optname):
|
633
|
+
try:
|
634
|
+
return int(val)
|
635
|
+
except ValueError:
|
636
|
+
raise ValueError('"%s" option expected an int' % optname)
|
637
|
+
|
638
|
+
def _str_to_list(val):
|
639
|
+
return val.replace(',', ' ').split()
|
640
|
+
|
641
|
+
######################################################################
|
642
|
+
#{ Interface
|
643
|
+
######################################################################
|
644
|
+
|
645
|
+
def main(options, names):
|
646
|
+
# Set the debug flag, if '--debug' was specified.
|
647
|
+
if options.debug:
|
648
|
+
epydoc.DEBUG = True
|
649
|
+
|
650
|
+
## [XX] Did this serve a purpose? Commenting out for now:
|
651
|
+
#if options.action == 'text':
|
652
|
+
# if options.parse and options.introspect:
|
653
|
+
# options.parse = False
|
654
|
+
|
655
|
+
# Set up the logger
|
656
|
+
if options.simple_term:
|
657
|
+
TerminalController.FORCE_SIMPLE_TERM = True
|
658
|
+
if options.action == 'text':
|
659
|
+
logger = None # no logger for text output.
|
660
|
+
elif options.verbosity > 1:
|
661
|
+
logger = ConsoleLogger(options.verbosity)
|
662
|
+
log.register_logger(logger)
|
663
|
+
else:
|
664
|
+
# Each number is a rough approximation of how long we spend on
|
665
|
+
# that task, used to divide up the unified progress bar.
|
666
|
+
stages = [40, # Building documentation
|
667
|
+
7, # Merging parsed & introspected information
|
668
|
+
1, # Linking imported variables
|
669
|
+
3, # Indexing documentation
|
670
|
+
1, # Checking for overridden methods
|
671
|
+
30, # Parsing Docstrings
|
672
|
+
1, # Inheriting documentation
|
673
|
+
2] # Sorting & Grouping
|
674
|
+
if options.load_pickle:
|
675
|
+
stages = [30] # Loading pickled documentation
|
676
|
+
if options.action == 'html': stages += [100]
|
677
|
+
elif options.action == 'text': stages += [30]
|
678
|
+
elif options.action == 'latex': stages += [60]
|
679
|
+
elif options.action == 'dvi': stages += [60,30]
|
680
|
+
elif options.action == 'ps': stages += [60,40]
|
681
|
+
elif options.action == 'pdf': stages += [60,50]
|
682
|
+
elif options.action == 'check': stages += [10]
|
683
|
+
elif options.action == 'pickle': stages += [10]
|
684
|
+
else: raise ValueError, '%r not supported' % options.action
|
685
|
+
if options.parse and not options.introspect:
|
686
|
+
del stages[1] # no merging
|
687
|
+
if options.introspect and not options.parse:
|
688
|
+
del stages[1:3] # no merging or linking
|
689
|
+
logger = UnifiedProgressConsoleLogger(options.verbosity, stages)
|
690
|
+
log.register_logger(logger)
|
691
|
+
|
692
|
+
# check the output directory.
|
693
|
+
if options.action not in ('text', 'check', 'pickle'):
|
694
|
+
if os.path.exists(options.target):
|
695
|
+
if not os.path.isdir(options.target):
|
696
|
+
log.error("%s is not a directory" % options.target)
|
697
|
+
sys.exit(1)
|
698
|
+
|
699
|
+
if options.include_log:
|
700
|
+
if options.action == 'html':
|
701
|
+
if not os.path.exists(options.target):
|
702
|
+
os.mkdir(options.target)
|
703
|
+
log.register_logger(HTMLLogger(options.target, options))
|
704
|
+
else:
|
705
|
+
log.warning("--include-log requires --html")
|
706
|
+
|
707
|
+
# Set the default docformat
|
708
|
+
from epydoc import docstringparser
|
709
|
+
docstringparser.DEFAULT_DOCFORMAT = options.docformat
|
710
|
+
|
711
|
+
# Configure the external API linking
|
712
|
+
if xlink is not None:
|
713
|
+
try:
|
714
|
+
xlink.ApiLinkReader.read_configuration(options, problematic=False)
|
715
|
+
except Exception, exc:
|
716
|
+
log.error("Error while configuring external API linking: %s: %s"
|
717
|
+
% (exc.__class__.__name__, exc))
|
718
|
+
|
719
|
+
# Set the dot path
|
720
|
+
if options.dotpath:
|
721
|
+
from epydoc.docwriter import dotgraph
|
722
|
+
dotgraph.DOT_COMMAND = options.dotpath
|
723
|
+
|
724
|
+
# Set the default graph font & size
|
725
|
+
if options.graph_font:
|
726
|
+
from epydoc.docwriter import dotgraph
|
727
|
+
fontname = options.graph_font
|
728
|
+
dotgraph.DotGraph.DEFAULT_NODE_DEFAULTS['fontname'] = fontname
|
729
|
+
dotgraph.DotGraph.DEFAULT_EDGE_DEFAULTS['fontname'] = fontname
|
730
|
+
if options.graph_font_size:
|
731
|
+
from epydoc.docwriter import dotgraph
|
732
|
+
fontsize = options.graph_font_size
|
733
|
+
dotgraph.DotGraph.DEFAULT_NODE_DEFAULTS['fontsize'] = fontsize
|
734
|
+
dotgraph.DotGraph.DEFAULT_EDGE_DEFAULTS['fontsize'] = fontsize
|
735
|
+
|
736
|
+
# If the input name is a pickle file, then read the docindex that
|
737
|
+
# it contains. Otherwise, build the docs for the input names.
|
738
|
+
if options.load_pickle:
|
739
|
+
assert len(names) == 1
|
740
|
+
log.start_progress('Deserializing')
|
741
|
+
log.progress(0.1, 'Loading %r' % names[0])
|
742
|
+
t0 = time.time()
|
743
|
+
unpickler = pickle.Unpickler(open(names[0], 'rb'))
|
744
|
+
unpickler.persistent_load = pickle_persistent_load
|
745
|
+
docindex = unpickler.load()
|
746
|
+
log.debug('deserialization time: %.1f sec' % (time.time()-t0))
|
747
|
+
log.end_progress()
|
748
|
+
else:
|
749
|
+
# Build docs for the named values.
|
750
|
+
from epydoc.docbuilder import build_doc_index
|
751
|
+
exclude_parse = '|'.join(options.exclude_parse+options.exclude)
|
752
|
+
exclude_introspect = '|'.join(options.exclude_introspect+
|
753
|
+
options.exclude)
|
754
|
+
docindex = build_doc_index(names, options.introspect, options.parse,
|
755
|
+
add_submodules=(options.action!='text'),
|
756
|
+
exclude_introspect=exclude_introspect,
|
757
|
+
exclude_parse=exclude_parse)
|
758
|
+
|
759
|
+
if docindex is None:
|
760
|
+
if log.ERROR in logger.reported_message_levels:
|
761
|
+
sys.exit(1)
|
762
|
+
else:
|
763
|
+
return # docbuilder already logged an error.
|
764
|
+
|
765
|
+
# Load profile information, if it was given.
|
766
|
+
if options.pstat_files:
|
767
|
+
try: import pstats
|
768
|
+
except ImportError:
|
769
|
+
log.error("Could not import pstats -- ignoring pstat files.")
|
770
|
+
try:
|
771
|
+
profile_stats = pstats.Stats(options.pstat_files[0])
|
772
|
+
for filename in options.pstat_files[1:]:
|
773
|
+
profile_stats.add(filename)
|
774
|
+
except KeyboardInterrupt: raise
|
775
|
+
except Exception, e:
|
776
|
+
log.error("Error reading pstat file: %s" % e)
|
777
|
+
profile_stats = None
|
778
|
+
if profile_stats is not None:
|
779
|
+
docindex.read_profiling_info(profile_stats)
|
780
|
+
|
781
|
+
# Perform the specified action.
|
782
|
+
if options.action == 'html':
|
783
|
+
write_html(docindex, options)
|
784
|
+
elif options.action in ('latex', 'dvi', 'ps', 'pdf'):
|
785
|
+
write_latex(docindex, options, options.action)
|
786
|
+
elif options.action == 'text':
|
787
|
+
write_text(docindex, options)
|
788
|
+
elif options.action == 'check':
|
789
|
+
check_docs(docindex, options)
|
790
|
+
elif options.action == 'pickle':
|
791
|
+
write_pickle(docindex, options)
|
792
|
+
else:
|
793
|
+
print >>sys.stderr, '\nUnsupported action %s!' % options.action
|
794
|
+
|
795
|
+
# If we suppressed docstring warnings, then let the user know.
|
796
|
+
if logger is not None and logger.suppressed_docstring_warning:
|
797
|
+
if logger.suppressed_docstring_warning == 1:
|
798
|
+
prefix = '1 markup error was found'
|
799
|
+
else:
|
800
|
+
prefix = ('%d markup errors were found' %
|
801
|
+
logger.suppressed_docstring_warning)
|
802
|
+
log.warning("%s while processing docstrings. Use the verbose "
|
803
|
+
"switch (-v) to display markup errors." % prefix)
|
804
|
+
|
805
|
+
# Basic timing breakdown:
|
806
|
+
if options.verbosity >= 2 and logger is not None:
|
807
|
+
logger.print_times()
|
808
|
+
|
809
|
+
# If we encountered any message types that we were requested to
|
810
|
+
# fail on, then exit with status 2.
|
811
|
+
if options.fail_on is not None:
|
812
|
+
max_reported_message_level = max(logger.reported_message_levels)
|
813
|
+
if max_reported_message_level >= options.fail_on:
|
814
|
+
sys.exit(2)
|
815
|
+
|
816
|
+
def write_html(docindex, options):
|
817
|
+
from epydoc.docwriter.html import HTMLWriter
|
818
|
+
html_writer = HTMLWriter(docindex, **options.__dict__)
|
819
|
+
if options.verbose > 0:
|
820
|
+
log.start_progress('Writing HTML docs to %r' % options.target)
|
821
|
+
else:
|
822
|
+
log.start_progress('Writing HTML docs')
|
823
|
+
html_writer.write(options.target)
|
824
|
+
log.end_progress()
|
825
|
+
|
826
|
+
def write_pickle(docindex, options):
|
827
|
+
"""Helper for writing output to a pickle file, which can then be
|
828
|
+
read in at a later time. But loading the pickle is only marginally
|
829
|
+
faster than building the docs from scratch, so this has pretty
|
830
|
+
limited application."""
|
831
|
+
if options.target == 'pickle':
|
832
|
+
options.target = 'api.pickle'
|
833
|
+
elif not options.target.endswith('.pickle'):
|
834
|
+
options.target += '.pickle'
|
835
|
+
|
836
|
+
log.start_progress('Serializing output')
|
837
|
+
log.progress(0.2, 'Writing %r' % options.target)
|
838
|
+
outfile = open(options.target, 'wb')
|
839
|
+
pickler = pickle.Pickler(outfile, protocol=0)
|
840
|
+
pickler.persistent_id = pickle_persistent_id
|
841
|
+
pickler.dump(docindex)
|
842
|
+
outfile.close()
|
843
|
+
log.end_progress()
|
844
|
+
|
845
|
+
def pickle_persistent_id(obj):
|
846
|
+
"""Helper for pickling, which allows us to save and restore UNKNOWN,
|
847
|
+
which is required to be identical to apidoc.UNKNOWN."""
|
848
|
+
if obj is UNKNOWN: return 'UNKNOWN'
|
849
|
+
else: return None
|
850
|
+
|
851
|
+
def pickle_persistent_load(identifier):
|
852
|
+
"""Helper for pickling, which allows us to save and restore UNKNOWN,
|
853
|
+
which is required to be identical to apidoc.UNKNOWN."""
|
854
|
+
if identifier == 'UNKNOWN': return UNKNOWN
|
855
|
+
else: raise pickle.UnpicklingError, 'Invalid persistent id'
|
856
|
+
|
857
|
+
_RERUN_LATEX_RE = re.compile(r'(?im)^LaTeX\s+Warning:\s+Label\(s\)\s+may'
|
858
|
+
r'\s+have\s+changed.\s+Rerun')
|
859
|
+
|
860
|
+
def write_latex(docindex, options, format):
|
861
|
+
from epydoc.docwriter.latex import LatexWriter
|
862
|
+
latex_writer = LatexWriter(docindex, **options.__dict__)
|
863
|
+
log.start_progress('Writing LaTeX docs')
|
864
|
+
latex_writer.write(options.target)
|
865
|
+
log.end_progress()
|
866
|
+
# If we're just generating the latex, and not any output format,
|
867
|
+
# then we're done.
|
868
|
+
if format == 'latex': return
|
869
|
+
|
870
|
+
if format == 'dvi': steps = 4
|
871
|
+
elif format == 'ps': steps = 5
|
872
|
+
elif format == 'pdf': steps = 6
|
873
|
+
|
874
|
+
log.start_progress('Processing LaTeX docs')
|
875
|
+
oldpath = os.path.abspath(os.curdir)
|
876
|
+
running = None # keep track of what we're doing.
|
877
|
+
try:
|
878
|
+
try:
|
879
|
+
os.chdir(options.target)
|
880
|
+
|
881
|
+
# Clear any old files out of the way.
|
882
|
+
for ext in 'tex aux log out idx ilg toc ind'.split():
|
883
|
+
if os.path.exists('apidoc.%s' % ext):
|
884
|
+
os.remove('apidoc.%s' % ext)
|
885
|
+
|
886
|
+
# The first pass generates index files.
|
887
|
+
running = 'latex'
|
888
|
+
log.progress(0./steps, 'LaTeX: First pass')
|
889
|
+
run_subprocess('latex api.tex')
|
890
|
+
|
891
|
+
# Build the index.
|
892
|
+
running = 'makeindex'
|
893
|
+
log.progress(1./steps, 'LaTeX: Build index')
|
894
|
+
run_subprocess('makeindex api.idx')
|
895
|
+
|
896
|
+
# The second pass generates our output.
|
897
|
+
running = 'latex'
|
898
|
+
log.progress(2./steps, 'LaTeX: Second pass')
|
899
|
+
out, err = run_subprocess('latex api.tex')
|
900
|
+
|
901
|
+
# The third pass is only necessary if the second pass
|
902
|
+
# changed what page some things are on.
|
903
|
+
running = 'latex'
|
904
|
+
if _RERUN_LATEX_RE.match(out):
|
905
|
+
log.progress(3./steps, 'LaTeX: Third pass')
|
906
|
+
out, err = run_subprocess('latex api.tex')
|
907
|
+
|
908
|
+
# A fourth path should (almost?) never be necessary.
|
909
|
+
running = 'latex'
|
910
|
+
if _RERUN_LATEX_RE.match(out):
|
911
|
+
log.progress(3./steps, 'LaTeX: Fourth pass')
|
912
|
+
run_subprocess('latex api.tex')
|
913
|
+
|
914
|
+
# If requested, convert to postscript.
|
915
|
+
if format in ('ps', 'pdf'):
|
916
|
+
running = 'dvips'
|
917
|
+
log.progress(4./steps, 'dvips')
|
918
|
+
run_subprocess('dvips api.dvi -o api.ps -G0 -Ppdf')
|
919
|
+
|
920
|
+
# If requested, convert to pdf.
|
921
|
+
if format in ('pdf'):
|
922
|
+
running = 'ps2pdf'
|
923
|
+
log.progress(5./steps, 'ps2pdf')
|
924
|
+
run_subprocess(
|
925
|
+
'ps2pdf -sPAPERSIZE#letter -dMaxSubsetPct#100 '
|
926
|
+
'-dSubsetFonts#true -dCompatibilityLevel#1.2 '
|
927
|
+
'-dEmbedAllFonts#true api.ps api.pdf')
|
928
|
+
except RunSubprocessError, e:
|
929
|
+
if running == 'latex':
|
930
|
+
e.out = re.sub(r'(?sm)\A.*?!( LaTeX Error:)?', r'', e.out)
|
931
|
+
e.out = re.sub(r'(?sm)\s*Type X to quit.*', '', e.out)
|
932
|
+
e.out = re.sub(r'(?sm)^! Emergency stop.*', '', e.out)
|
933
|
+
log.error("%s failed: %s" % (running, (e.out+e.err).lstrip()))
|
934
|
+
except OSError, e:
|
935
|
+
log.error("%s failed: %s" % (running, e))
|
936
|
+
finally:
|
937
|
+
os.chdir(oldpath)
|
938
|
+
log.end_progress()
|
939
|
+
|
940
|
+
def write_text(docindex, options):
|
941
|
+
log.start_progress('Writing output')
|
942
|
+
from epydoc.docwriter.plaintext import PlaintextWriter
|
943
|
+
plaintext_writer = PlaintextWriter()
|
944
|
+
s = ''
|
945
|
+
for apidoc in docindex.root:
|
946
|
+
s += plaintext_writer.write(apidoc)
|
947
|
+
log.end_progress()
|
948
|
+
if isinstance(s, unicode):
|
949
|
+
s = s.encode('ascii', 'backslashreplace')
|
950
|
+
print s
|
951
|
+
|
952
|
+
def check_docs(docindex, options):
|
953
|
+
from epydoc.checker import DocChecker
|
954
|
+
DocChecker(docindex).check()
|
955
|
+
|
956
|
+
def cli():
|
957
|
+
# Parse command-line arguments.
|
958
|
+
options, names = parse_arguments()
|
959
|
+
|
960
|
+
try:
|
961
|
+
try:
|
962
|
+
if options.profile:
|
963
|
+
_profile()
|
964
|
+
else:
|
965
|
+
main(options, names)
|
966
|
+
finally:
|
967
|
+
log.close()
|
968
|
+
except SystemExit:
|
969
|
+
raise
|
970
|
+
except KeyboardInterrupt:
|
971
|
+
print '\n\n'
|
972
|
+
print >>sys.stderr, 'Keyboard interrupt.'
|
973
|
+
except:
|
974
|
+
if options.debug: raise
|
975
|
+
print '\n\n'
|
976
|
+
exc_info = sys.exc_info()
|
977
|
+
if isinstance(exc_info[0], basestring): e = exc_info[0]
|
978
|
+
else: e = exc_info[1]
|
979
|
+
print >>sys.stderr, ('\nUNEXPECTED ERROR:\n'
|
980
|
+
'%s\n' % (str(e) or e.__class__.__name__))
|
981
|
+
print >>sys.stderr, 'Use --debug to see trace information.'
|
982
|
+
sys.exit(3)
|
983
|
+
|
984
|
+
def _profile():
|
985
|
+
# Hotshot profiler.
|
986
|
+
if PROFILER == 'hotshot':
|
987
|
+
try: import hotshot, hotshot.stats
|
988
|
+
except ImportError:
|
989
|
+
print >>sys.stderr, "Could not import profile module!"
|
990
|
+
return
|
991
|
+
try:
|
992
|
+
prof = hotshot.Profile('hotshot.out')
|
993
|
+
prof = prof.runctx('main(*parse_arguments())', globals(), {})
|
994
|
+
except SystemExit:
|
995
|
+
pass
|
996
|
+
prof.close()
|
997
|
+
# Convert profile.hotshot -> profile.out
|
998
|
+
print 'Consolidating hotshot profiling info...'
|
999
|
+
hotshot.stats.load('hotshot.out').dump_stats('profile.out')
|
1000
|
+
|
1001
|
+
# Standard 'profile' profiler.
|
1002
|
+
elif PROFILER == 'profile':
|
1003
|
+
# cProfile module was added in Python 2.5 -- use it if its'
|
1004
|
+
# available, since it's faster.
|
1005
|
+
try: from cProfile import Profile
|
1006
|
+
except ImportError:
|
1007
|
+
try: from profile import Profile
|
1008
|
+
except ImportError:
|
1009
|
+
print >>sys.stderr, "Could not import profile module!"
|
1010
|
+
return
|
1011
|
+
|
1012
|
+
# There was a bug in Python 2.4's profiler. Check if it's
|
1013
|
+
# present, and if so, fix it. (Bug was fixed in 2.4maint:
|
1014
|
+
# <http://mail.python.org/pipermail/python-checkins/
|
1015
|
+
# 2005-September/047099.html>)
|
1016
|
+
if (hasattr(Profile, 'dispatch') and
|
1017
|
+
Profile.dispatch['c_exception'] is
|
1018
|
+
Profile.trace_dispatch_exception.im_func):
|
1019
|
+
trace_dispatch_return = Profile.trace_dispatch_return.im_func
|
1020
|
+
Profile.dispatch['c_exception'] = trace_dispatch_return
|
1021
|
+
try:
|
1022
|
+
prof = Profile()
|
1023
|
+
prof = prof.runctx('main(*parse_arguments())', globals(), {})
|
1024
|
+
except SystemExit:
|
1025
|
+
pass
|
1026
|
+
prof.dump_stats('profile.out')
|
1027
|
+
|
1028
|
+
else:
|
1029
|
+
print >>sys.stderr, 'Unknown profiler %s' % PROFILER
|
1030
|
+
return
|
1031
|
+
|
1032
|
+
######################################################################
|
1033
|
+
#{ Logging
|
1034
|
+
######################################################################
|
1035
|
+
|
1036
|
+
class TerminalController:
|
1037
|
+
"""
|
1038
|
+
A class that can be used to portably generate formatted output to
|
1039
|
+
a terminal. See
|
1040
|
+
U{http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/475116}
|
1041
|
+
for documentation. (This is a somewhat stripped-down version.)
|
1042
|
+
"""
|
1043
|
+
BOL = '' #: Move the cursor to the beginning of the line
|
1044
|
+
UP = '' #: Move the cursor up one line
|
1045
|
+
DOWN = '' #: Move the cursor down one line
|
1046
|
+
LEFT = '' #: Move the cursor left one char
|
1047
|
+
RIGHT = '' #: Move the cursor right one char
|
1048
|
+
CLEAR_EOL = '' #: Clear to the end of the line.
|
1049
|
+
CLEAR_LINE = '' #: Clear the current line; cursor to BOL.
|
1050
|
+
BOLD = '' #: Turn on bold mode
|
1051
|
+
NORMAL = '' #: Turn off all modes
|
1052
|
+
COLS = 75 #: Width of the terminal (default to 75)
|
1053
|
+
BLACK = BLUE = GREEN = CYAN = RED = MAGENTA = YELLOW = WHITE = ''
|
1054
|
+
|
1055
|
+
_STRING_CAPABILITIES = """
|
1056
|
+
BOL=cr UP=cuu1 DOWN=cud1 LEFT=cub1 RIGHT=cuf1
|
1057
|
+
CLEAR_EOL=el BOLD=bold UNDERLINE=smul NORMAL=sgr0""".split()
|
1058
|
+
_COLORS = """BLACK BLUE GREEN CYAN RED MAGENTA YELLOW WHITE""".split()
|
1059
|
+
_ANSICOLORS = "BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE".split()
|
1060
|
+
|
1061
|
+
#: If this is set to true, then new TerminalControllers will
|
1062
|
+
#: assume that the terminal is not capable of doing manipulation
|
1063
|
+
#: of any kind.
|
1064
|
+
FORCE_SIMPLE_TERM = False
|
1065
|
+
|
1066
|
+
def __init__(self, term_stream=sys.stdout):
|
1067
|
+
# If the stream isn't a tty, then assume it has no capabilities.
|
1068
|
+
if not term_stream.isatty(): return
|
1069
|
+
if self.FORCE_SIMPLE_TERM: return
|
1070
|
+
|
1071
|
+
# Curses isn't available on all platforms
|
1072
|
+
try: import curses
|
1073
|
+
except:
|
1074
|
+
# If it's not available, then try faking enough to get a
|
1075
|
+
# simple progress bar.
|
1076
|
+
self.BOL = '\r'
|
1077
|
+
self.CLEAR_LINE = '\r' + ' '*self.COLS + '\r'
|
1078
|
+
|
1079
|
+
# Check the terminal type. If we fail, then assume that the
|
1080
|
+
# terminal has no capabilities.
|
1081
|
+
try: curses.setupterm()
|
1082
|
+
except: return
|
1083
|
+
|
1084
|
+
# Look up numeric capabilities.
|
1085
|
+
self.COLS = curses.tigetnum('cols')
|
1086
|
+
|
1087
|
+
# Look up string capabilities.
|
1088
|
+
for capability in self._STRING_CAPABILITIES:
|
1089
|
+
(attrib, cap_name) = capability.split('=')
|
1090
|
+
setattr(self, attrib, self._tigetstr(cap_name) or '')
|
1091
|
+
if self.BOL and self.CLEAR_EOL:
|
1092
|
+
self.CLEAR_LINE = self.BOL+self.CLEAR_EOL
|
1093
|
+
|
1094
|
+
# Colors
|
1095
|
+
set_fg = self._tigetstr('setf')
|
1096
|
+
if set_fg:
|
1097
|
+
for i,color in zip(range(len(self._COLORS)), self._COLORS):
|
1098
|
+
setattr(self, color, curses.tparm(set_fg, i) or '')
|
1099
|
+
set_fg_ansi = self._tigetstr('setaf')
|
1100
|
+
if set_fg_ansi:
|
1101
|
+
for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS):
|
1102
|
+
setattr(self, color, curses.tparm(set_fg_ansi, i) or '')
|
1103
|
+
|
1104
|
+
def _tigetstr(self, cap_name):
|
1105
|
+
# String capabilities can include "delays" of the form "$<2>".
|
1106
|
+
# For any modern terminal, we should be able to just ignore
|
1107
|
+
# these, so strip them out.
|
1108
|
+
import curses
|
1109
|
+
cap = curses.tigetstr(cap_name) or ''
|
1110
|
+
return re.sub(r'\$<\d+>[/*]?', '', cap)
|
1111
|
+
|
1112
|
+
class ConsoleLogger(log.Logger):
|
1113
|
+
def __init__(self, verbosity, progress_mode=None):
|
1114
|
+
self._verbosity = verbosity
|
1115
|
+
self._progress = None
|
1116
|
+
self._message_blocks = []
|
1117
|
+
# For ETA display:
|
1118
|
+
self._progress_start_time = None
|
1119
|
+
# For per-task times:
|
1120
|
+
self._task_times = []
|
1121
|
+
self._progress_header = None
|
1122
|
+
|
1123
|
+
self.reported_message_levels = set()
|
1124
|
+
"""This set contains all the message levels (WARNING, ERROR,
|
1125
|
+
etc) that have been reported. It is used by the options
|
1126
|
+
--fail-on-warning etc to determine the return value."""
|
1127
|
+
|
1128
|
+
self.suppressed_docstring_warning = 0
|
1129
|
+
"""This variable will be incremented once every time a
|
1130
|
+
docstring warning is reported tothe logger, but the verbosity
|
1131
|
+
level is too low for it to be displayed."""
|
1132
|
+
|
1133
|
+
self.term = TerminalController()
|
1134
|
+
|
1135
|
+
# Set the progress bar mode.
|
1136
|
+
if verbosity >= 2: self._progress_mode = 'list'
|
1137
|
+
elif verbosity >= 0:
|
1138
|
+
if progress_mode is not None:
|
1139
|
+
self._progress_mode = progress_mode
|
1140
|
+
elif self.term.COLS < 15:
|
1141
|
+
self._progress_mode = 'simple-bar'
|
1142
|
+
elif self.term.BOL and self.term.CLEAR_EOL and self.term.UP:
|
1143
|
+
self._progress_mode = 'multiline-bar'
|
1144
|
+
elif self.term.BOL and self.term.CLEAR_LINE:
|
1145
|
+
self._progress_mode = 'bar'
|
1146
|
+
else:
|
1147
|
+
self._progress_mode = 'simple-bar'
|
1148
|
+
else: self._progress_mode = 'hide'
|
1149
|
+
|
1150
|
+
def start_block(self, header):
|
1151
|
+
self._message_blocks.append( (header, []) )
|
1152
|
+
|
1153
|
+
def end_block(self):
|
1154
|
+
header, messages = self._message_blocks.pop()
|
1155
|
+
if messages:
|
1156
|
+
width = self.term.COLS - 5 - 2*len(self._message_blocks)
|
1157
|
+
prefix = self.term.CYAN+self.term.BOLD+'| '+self.term.NORMAL
|
1158
|
+
divider = (self.term.CYAN+self.term.BOLD+'+'+'-'*(width-1)+
|
1159
|
+
self.term.NORMAL)
|
1160
|
+
# Mark up the header:
|
1161
|
+
header = wordwrap(header, right=width-2, splitchars='\\/').rstrip()
|
1162
|
+
header = '\n'.join([prefix+self.term.CYAN+l+self.term.NORMAL
|
1163
|
+
for l in header.split('\n')])
|
1164
|
+
# Construct the body:
|
1165
|
+
body = ''
|
1166
|
+
for message in messages:
|
1167
|
+
if message.endswith('\n'): body += message
|
1168
|
+
else: body += message+'\n'
|
1169
|
+
# Indent the body:
|
1170
|
+
body = '\n'.join([prefix+' '+l for l in body.split('\n')])
|
1171
|
+
# Put it all together:
|
1172
|
+
message = divider + '\n' + header + '\n' + body + '\n'
|
1173
|
+
self._report(message)
|
1174
|
+
|
1175
|
+
def _format(self, prefix, message, color):
|
1176
|
+
"""
|
1177
|
+
Rewrap the message; but preserve newlines, and don't touch any
|
1178
|
+
lines that begin with spaces.
|
1179
|
+
"""
|
1180
|
+
lines = message.split('\n')
|
1181
|
+
startindex = indent = len(prefix)
|
1182
|
+
for i in range(len(lines)):
|
1183
|
+
if lines[i].startswith(' '):
|
1184
|
+
lines[i] = ' '*(indent-startindex) + lines[i] + '\n'
|
1185
|
+
else:
|
1186
|
+
width = self.term.COLS - 5 - 4*len(self._message_blocks)
|
1187
|
+
lines[i] = wordwrap(lines[i], indent, width, startindex, '\\/')
|
1188
|
+
startindex = 0
|
1189
|
+
return color+prefix+self.term.NORMAL+''.join(lines)
|
1190
|
+
|
1191
|
+
def log(self, level, message):
|
1192
|
+
self.reported_message_levels.add(level)
|
1193
|
+
if self._verbosity >= -2 and level >= log.ERROR:
|
1194
|
+
message = self._format(' Error: ', message, self.term.RED)
|
1195
|
+
elif self._verbosity >= -1 and level >= log.WARNING:
|
1196
|
+
message = self._format('Warning: ', message, self.term.YELLOW)
|
1197
|
+
elif self._verbosity >= 1 and level >= log.DOCSTRING_WARNING:
|
1198
|
+
message = self._format('Warning: ', message, self.term.YELLOW)
|
1199
|
+
elif self._verbosity >= 3 and level >= log.INFO:
|
1200
|
+
message = self._format(' Info: ', message, self.term.NORMAL)
|
1201
|
+
elif epydoc.DEBUG and level == log.DEBUG:
|
1202
|
+
message = self._format(' Debug: ', message, self.term.CYAN)
|
1203
|
+
else:
|
1204
|
+
if level >= log.DOCSTRING_WARNING:
|
1205
|
+
self.suppressed_docstring_warning += 1
|
1206
|
+
return
|
1207
|
+
|
1208
|
+
self._report(message)
|
1209
|
+
|
1210
|
+
def _report(self, message):
|
1211
|
+
if not message.endswith('\n'): message += '\n'
|
1212
|
+
|
1213
|
+
if self._message_blocks:
|
1214
|
+
self._message_blocks[-1][-1].append(message)
|
1215
|
+
else:
|
1216
|
+
# If we're in the middle of displaying a progress bar,
|
1217
|
+
# then make room for the message.
|
1218
|
+
if self._progress_mode == 'simple-bar':
|
1219
|
+
if self._progress is not None:
|
1220
|
+
print
|
1221
|
+
self._progress = None
|
1222
|
+
if self._progress_mode == 'bar':
|
1223
|
+
sys.stdout.write(self.term.CLEAR_LINE)
|
1224
|
+
if self._progress_mode == 'multiline-bar':
|
1225
|
+
sys.stdout.write((self.term.CLEAR_EOL + '\n')*2 +
|
1226
|
+
self.term.CLEAR_EOL + self.term.UP*2)
|
1227
|
+
|
1228
|
+
# Display the message message.
|
1229
|
+
sys.stdout.write(message)
|
1230
|
+
sys.stdout.flush()
|
1231
|
+
|
1232
|
+
def progress(self, percent, message=''):
|
1233
|
+
percent = min(1.0, percent)
|
1234
|
+
message = '%s' % message
|
1235
|
+
|
1236
|
+
if self._progress_mode == 'list':
|
1237
|
+
if message:
|
1238
|
+
print '[%3d%%] %s' % (100*percent, message)
|
1239
|
+
sys.stdout.flush()
|
1240
|
+
|
1241
|
+
elif self._progress_mode == 'bar':
|
1242
|
+
dots = int((self.term.COLS/2-8)*percent)
|
1243
|
+
background = '-'*(self.term.COLS/2-8)
|
1244
|
+
if len(message) > self.term.COLS/2:
|
1245
|
+
message = message[:self.term.COLS/2-3]+'...'
|
1246
|
+
sys.stdout.write(self.term.CLEAR_LINE + '%3d%% '%(100*percent) +
|
1247
|
+
self.term.GREEN + '[' + self.term.BOLD +
|
1248
|
+
'='*dots + background[dots:] + self.term.NORMAL +
|
1249
|
+
self.term.GREEN + '] ' + self.term.NORMAL +
|
1250
|
+
message + self.term.BOL)
|
1251
|
+
sys.stdout.flush()
|
1252
|
+
self._progress = percent
|
1253
|
+
elif self._progress_mode == 'multiline-bar':
|
1254
|
+
dots = int((self.term.COLS-10)*percent)
|
1255
|
+
background = '-'*(self.term.COLS-10)
|
1256
|
+
|
1257
|
+
if len(message) > self.term.COLS-10:
|
1258
|
+
message = message[:self.term.COLS-10-3]+'...'
|
1259
|
+
else:
|
1260
|
+
message = message.center(self.term.COLS-10)
|
1261
|
+
|
1262
|
+
time_elapsed = time.time()-self._progress_start_time
|
1263
|
+
if percent > 0:
|
1264
|
+
time_remain = (time_elapsed / percent) * (1-percent)
|
1265
|
+
else:
|
1266
|
+
time_remain = 0
|
1267
|
+
|
1268
|
+
sys.stdout.write(
|
1269
|
+
# Line 1:
|
1270
|
+
self.term.CLEAR_EOL + ' ' +
|
1271
|
+
'%-8s' % self._timestr(time_elapsed) +
|
1272
|
+
self.term.BOLD + 'Progress:'.center(self.term.COLS-26) +
|
1273
|
+
self.term.NORMAL + '%8s' % self._timestr(time_remain) + '\n' +
|
1274
|
+
# Line 2:
|
1275
|
+
self.term.CLEAR_EOL + ('%3d%% ' % (100*percent)) +
|
1276
|
+
self.term.GREEN + '[' + self.term.BOLD + '='*dots +
|
1277
|
+
background[dots:] + self.term.NORMAL + self.term.GREEN +
|
1278
|
+
']' + self.term.NORMAL + '\n' +
|
1279
|
+
# Line 3:
|
1280
|
+
self.term.CLEAR_EOL + ' ' + message + self.term.BOL +
|
1281
|
+
self.term.UP + self.term.UP)
|
1282
|
+
|
1283
|
+
sys.stdout.flush()
|
1284
|
+
self._progress = percent
|
1285
|
+
elif self._progress_mode == 'simple-bar':
|
1286
|
+
if self._progress is None:
|
1287
|
+
sys.stdout.write(' [')
|
1288
|
+
self._progress = 0.0
|
1289
|
+
dots = int((self.term.COLS-2)*percent)
|
1290
|
+
progress_dots = int((self.term.COLS-2)*self._progress)
|
1291
|
+
if dots > progress_dots:
|
1292
|
+
sys.stdout.write('.'*(dots-progress_dots))
|
1293
|
+
sys.stdout.flush()
|
1294
|
+
self._progress = percent
|
1295
|
+
|
1296
|
+
def _timestr(self, dt):
|
1297
|
+
dt = int(dt)
|
1298
|
+
if dt >= 3600:
|
1299
|
+
return '%d:%02d:%02d' % (dt/3600, dt%3600/60, dt%60)
|
1300
|
+
else:
|
1301
|
+
return '%02d:%02d' % (dt/60, dt%60)
|
1302
|
+
|
1303
|
+
def start_progress(self, header=None):
|
1304
|
+
if self._progress is not None:
|
1305
|
+
raise ValueError
|
1306
|
+
self._progress = None
|
1307
|
+
self._progress_start_time = time.time()
|
1308
|
+
self._progress_header = header
|
1309
|
+
if self._progress_mode != 'hide' and header:
|
1310
|
+
print self.term.BOLD + header + self.term.NORMAL
|
1311
|
+
|
1312
|
+
def end_progress(self):
|
1313
|
+
self.progress(1.)
|
1314
|
+
if self._progress_mode == 'bar':
|
1315
|
+
sys.stdout.write(self.term.CLEAR_LINE)
|
1316
|
+
if self._progress_mode == 'multiline-bar':
|
1317
|
+
sys.stdout.write((self.term.CLEAR_EOL + '\n')*2 +
|
1318
|
+
self.term.CLEAR_EOL + self.term.UP*2)
|
1319
|
+
if self._progress_mode == 'simple-bar':
|
1320
|
+
print ']'
|
1321
|
+
self._progress = None
|
1322
|
+
self._task_times.append( (time.time()-self._progress_start_time,
|
1323
|
+
self._progress_header) )
|
1324
|
+
|
1325
|
+
def print_times(self):
|
1326
|
+
print
|
1327
|
+
print 'Timing summary:'
|
1328
|
+
total = sum([time for (time, task) in self._task_times])
|
1329
|
+
max_t = max([time for (time, task) in self._task_times])
|
1330
|
+
for (time, task) in self._task_times:
|
1331
|
+
task = task[:31]
|
1332
|
+
print ' %s%s %7.1fs' % (task, '.'*(35-len(task)), time),
|
1333
|
+
if self.term.COLS > 55:
|
1334
|
+
print '|'+'=' * int((self.term.COLS-53) * time / max_t)
|
1335
|
+
else:
|
1336
|
+
print
|
1337
|
+
print
|
1338
|
+
|
1339
|
+
class UnifiedProgressConsoleLogger(ConsoleLogger):
|
1340
|
+
def __init__(self, verbosity, stages, progress_mode=None):
|
1341
|
+
self.stage = 0
|
1342
|
+
self.stages = stages
|
1343
|
+
self.task = None
|
1344
|
+
ConsoleLogger.__init__(self, verbosity, progress_mode)
|
1345
|
+
|
1346
|
+
def progress(self, percent, message=''):
|
1347
|
+
#p = float(self.stage-1+percent)/self.stages
|
1348
|
+
i = self.stage-1
|
1349
|
+
p = ((sum(self.stages[:i]) + percent*self.stages[i]) /
|
1350
|
+
float(sum(self.stages)))
|
1351
|
+
|
1352
|
+
if message is UNKNOWN: message = None
|
1353
|
+
if message: message = '%s: %s' % (self.task, message)
|
1354
|
+
ConsoleLogger.progress(self, p, message)
|
1355
|
+
|
1356
|
+
def start_progress(self, header=None):
|
1357
|
+
self.task = header
|
1358
|
+
if self.stage == 0:
|
1359
|
+
ConsoleLogger.start_progress(self)
|
1360
|
+
self.stage += 1
|
1361
|
+
|
1362
|
+
def end_progress(self):
|
1363
|
+
if self.stage == len(self.stages):
|
1364
|
+
ConsoleLogger.end_progress(self)
|
1365
|
+
|
1366
|
+
def print_times(self):
|
1367
|
+
pass
|
1368
|
+
|
1369
|
+
class HTMLLogger(log.Logger):
|
1370
|
+
"""
|
1371
|
+
A logger used to generate a log of all warnings and messages to an
|
1372
|
+
HTML file.
|
1373
|
+
"""
|
1374
|
+
|
1375
|
+
FILENAME = "epydoc-log.html"
|
1376
|
+
HEADER = textwrap.dedent('''\
|
1377
|
+
<?xml version="1.0" encoding="ascii"?>
|
1378
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
1379
|
+
"DTD/xhtml1-transitional.dtd">
|
1380
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
1381
|
+
<head>
|
1382
|
+
<title>Epydoc Log</title>
|
1383
|
+
<link rel="stylesheet" href="epydoc.css" type="text/css" />
|
1384
|
+
</head>
|
1385
|
+
|
1386
|
+
<body bgcolor="white" text="black" link="blue" vlink="#204080"
|
1387
|
+
alink="#204080">
|
1388
|
+
<h1 class="epydoc">Epydoc Log</h1>
|
1389
|
+
<p class="log">Epydoc started at %s</p>''')
|
1390
|
+
START_BLOCK = '<div class="log-block"><h2 class="log-hdr">%s</h2>'
|
1391
|
+
MESSAGE = ('<div class="log-%s"><b>%s</b>: \n'
|
1392
|
+
'%s</div>\n')
|
1393
|
+
END_BLOCK = '</div>'
|
1394
|
+
FOOTER = "</body>\n</html>\n"
|
1395
|
+
|
1396
|
+
def __init__(self, directory, options):
|
1397
|
+
self.start_time = time.time()
|
1398
|
+
self.out = open(os.path.join(directory, self.FILENAME), 'w')
|
1399
|
+
self.out.write(self.HEADER % time.ctime(self.start_time))
|
1400
|
+
self.is_empty = True
|
1401
|
+
self.options = options
|
1402
|
+
|
1403
|
+
def write_options(self, options):
|
1404
|
+
self.out.write(self.START_BLOCK % 'Epydoc Options')
|
1405
|
+
msg = '<table border="0" cellpadding="0" cellspacing="0">\n'
|
1406
|
+
opts = [(key, getattr(options, key)) for key in dir(options)
|
1407
|
+
if key not in dir(optparse.Values)]
|
1408
|
+
opts = [(val==OPTION_DEFAULTS.get(key), key, val)
|
1409
|
+
for (key, val) in opts]
|
1410
|
+
for is_default, key, val in sorted(opts):
|
1411
|
+
css = is_default and 'opt-default' or 'opt-changed'
|
1412
|
+
msg += ('<tr valign="top" class="%s"><td valign="top">%s</td>'
|
1413
|
+
'<td valign="top"><tt> = </tt></td>'
|
1414
|
+
'<td valign="top"><tt>%s</tt></td></tr>' %
|
1415
|
+
(css, key, plaintext_to_html(repr(val))))
|
1416
|
+
msg += '</table>\n'
|
1417
|
+
self.out.write('<div class="log-info">\n%s</div>\n' % msg)
|
1418
|
+
self.out.write(self.END_BLOCK)
|
1419
|
+
|
1420
|
+
def start_block(self, header):
|
1421
|
+
self.out.write(self.START_BLOCK % header)
|
1422
|
+
|
1423
|
+
def end_block(self):
|
1424
|
+
self.out.write(self.END_BLOCK)
|
1425
|
+
|
1426
|
+
def log(self, level, message):
|
1427
|
+
if message.endswith("(-v) to display markup errors."): return
|
1428
|
+
if level >= log.ERROR:
|
1429
|
+
self.out.write(self._message('error', message))
|
1430
|
+
elif level >= log.WARNING:
|
1431
|
+
self.out.write(self._message('warning', message))
|
1432
|
+
elif level >= log.DOCSTRING_WARNING:
|
1433
|
+
self.out.write(self._message('docstring warning', message))
|
1434
|
+
|
1435
|
+
def _message(self, level, message):
|
1436
|
+
self.is_empty = False
|
1437
|
+
message = plaintext_to_html(message)
|
1438
|
+
if '\n' in message:
|
1439
|
+
message = '<pre class="log">%s</pre>' % message
|
1440
|
+
hdr = ' '.join([w.capitalize() for w in level.split()])
|
1441
|
+
return self.MESSAGE % (level.split()[-1], hdr, message)
|
1442
|
+
|
1443
|
+
def close(self):
|
1444
|
+
if self.is_empty:
|
1445
|
+
self.out.write('<div class="log-info">'
|
1446
|
+
'No warnings or errors!</div>')
|
1447
|
+
self.write_options(self.options)
|
1448
|
+
self.out.write('<p class="log">Epydoc finished at %s</p>\n'
|
1449
|
+
'<p class="log">(Elapsed time: %s)</p>' %
|
1450
|
+
(time.ctime(), self._elapsed_time()))
|
1451
|
+
self.out.write(self.FOOTER)
|
1452
|
+
self.out.close()
|
1453
|
+
|
1454
|
+
def _elapsed_time(self):
|
1455
|
+
secs = int(time.time()-self.start_time)
|
1456
|
+
if secs < 60:
|
1457
|
+
return '%d seconds' % secs
|
1458
|
+
if secs < 3600:
|
1459
|
+
return '%d minutes, %d seconds' % (secs/60, secs%60)
|
1460
|
+
else:
|
1461
|
+
return '%d hours, %d minutes' % (secs/3600, secs%3600)
|
1462
|
+
|
1463
|
+
|
1464
|
+
######################################################################
|
1465
|
+
## main
|
1466
|
+
######################################################################
|
1467
|
+
|
1468
|
+
if __name__ == '__main__':
|
1469
|
+
cli()
|
1470
|
+
|