bee_python 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
@@ -0,0 +1,778 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
|
3
|
+
# Copyright (c) 2001-2002, MetaSlash Inc. All rights reserved.
|
4
|
+
# Portions Copyright (c) 2005, Google, Inc. All rights reserved.
|
5
|
+
|
6
|
+
"""
|
7
|
+
Print out warnings from Python source files.
|
8
|
+
"""
|
9
|
+
|
10
|
+
import os.path
|
11
|
+
import sys
|
12
|
+
import string
|
13
|
+
import types
|
14
|
+
import traceback
|
15
|
+
import imp
|
16
|
+
import re
|
17
|
+
|
18
|
+
from pychecker import OP
|
19
|
+
from pychecker import Stack
|
20
|
+
from pychecker import function
|
21
|
+
from pychecker import python
|
22
|
+
from pychecker import pcmodules
|
23
|
+
|
24
|
+
from pychecker import msgs
|
25
|
+
from pychecker import utils
|
26
|
+
from pychecker import CodeChecks
|
27
|
+
from pychecker.Warning import Warning
|
28
|
+
|
29
|
+
|
30
|
+
def cfg() :
|
31
|
+
return utils.cfg()
|
32
|
+
|
33
|
+
def _checkSelfArg(method, warnings) :
|
34
|
+
"""Return a Warning if there is no self parameter or
|
35
|
+
the first parameter to a method is not self."""
|
36
|
+
|
37
|
+
if not cfg().methodArgName:
|
38
|
+
return
|
39
|
+
|
40
|
+
code = method.function.func_code
|
41
|
+
err = None
|
42
|
+
if method.isStaticMethod():
|
43
|
+
if code.co_argcount > 0 and cfg().methodArgName == code.co_varnames[0]:
|
44
|
+
err = msgs.SELF_IS_ARG % 'staticmethod'
|
45
|
+
elif code.co_argcount < 1:
|
46
|
+
err = msgs.NO_METHOD_ARGS % cfg().methodArgName
|
47
|
+
else:
|
48
|
+
if method.isClassMethod():
|
49
|
+
if code.co_varnames[0] not in cfg().classmethodArgNames:
|
50
|
+
err = msgs.SELF_NOT_FIRST_ARG % \
|
51
|
+
(cfg().classmethodArgNames, 'class')
|
52
|
+
elif code.co_varnames[0] != cfg().methodArgName:
|
53
|
+
err = msgs.SELF_NOT_FIRST_ARG % (cfg().methodArgName, '')
|
54
|
+
|
55
|
+
if err is not None :
|
56
|
+
warnings.append(Warning(code, code, err))
|
57
|
+
|
58
|
+
|
59
|
+
def _checkNoSelfArg(func, warnings) :
|
60
|
+
"Return a Warning if there is a self parameter to a function."
|
61
|
+
|
62
|
+
code = func.function.func_code
|
63
|
+
if code.co_argcount > 0 and cfg().methodArgName in code.co_varnames:
|
64
|
+
warnings.append(Warning(code, code, msgs.SELF_IS_ARG % 'function'))
|
65
|
+
|
66
|
+
|
67
|
+
def _checkSubclass(c1, c2):
|
68
|
+
try:
|
69
|
+
return issubclass(c1.classObject, c2.classObject)
|
70
|
+
except (TypeError, AttributeError):
|
71
|
+
return 0
|
72
|
+
|
73
|
+
|
74
|
+
_IGNORE_RETURN_TYPES = ( Stack.TYPE_FUNC_RETURN, Stack.TYPE_ATTRIBUTE,
|
75
|
+
Stack.TYPE_GLOBAL, Stack.TYPE_COMPARISON,
|
76
|
+
Stack.TYPE_UNKNOWN)
|
77
|
+
|
78
|
+
def _checkReturnWarnings(code) :
|
79
|
+
is_getattr = code.func_code.co_name in ('__getattr__', '__getattribute__')
|
80
|
+
if is_getattr :
|
81
|
+
for line, retval, dummy in code.returnValues :
|
82
|
+
if retval.isNone() :
|
83
|
+
err = msgs.DONT_RETURN_NONE % code.func_code.co_name
|
84
|
+
code.addWarning(err, line+1)
|
85
|
+
|
86
|
+
# there must be at least 2 real return values to check for consistency
|
87
|
+
returnValuesLen = len(code.returnValues)
|
88
|
+
if returnValuesLen < 2 :
|
89
|
+
return
|
90
|
+
|
91
|
+
# if the last return is implicit, check if there are non None returns
|
92
|
+
lastReturn = code.returnValues[-1]
|
93
|
+
|
94
|
+
# Python 2.4 optimizes the dead implicit return out, so we can't
|
95
|
+
# distinguish implicit and explicit "return None"
|
96
|
+
if utils.pythonVersion() < utils.PYTHON_2_4 and \
|
97
|
+
not code.starts_and_ends_with_finally and \
|
98
|
+
cfg().checkImplicitReturns and lastReturn[1].isImplicitNone():
|
99
|
+
for line, retval, dummy in code.returnValues[:-1] :
|
100
|
+
if not retval.isNone() :
|
101
|
+
code.addWarning(msgs.IMPLICIT_AND_EXPLICIT_RETURNS,
|
102
|
+
lastReturn[0]+1)
|
103
|
+
break
|
104
|
+
|
105
|
+
# __get*__ funcs can return different types, don't warn about inconsistency
|
106
|
+
if utils.startswith(code.func_code.co_name, '__get') and \
|
107
|
+
utils.endswith(code.func_code.co_name, '__') :
|
108
|
+
return
|
109
|
+
|
110
|
+
returnType, returnData = None, None
|
111
|
+
for line, value, dummy in code.returnValues :
|
112
|
+
if not value.isNone() :
|
113
|
+
valueType = value.getType(code.typeMap)
|
114
|
+
if returnType is None and valueType not in _IGNORE_RETURN_TYPES :
|
115
|
+
returnData = value
|
116
|
+
returnType = valueType
|
117
|
+
continue
|
118
|
+
|
119
|
+
# always ignore None, None can be returned w/any other type
|
120
|
+
# FIXME: if we stored func return values, we could do better
|
121
|
+
if returnType is not None and not value.isNone() and \
|
122
|
+
valueType not in _IGNORE_RETURN_TYPES and \
|
123
|
+
returnData.type not in _IGNORE_RETURN_TYPES :
|
124
|
+
ok = returnType in (type(value.data), valueType)
|
125
|
+
if ok :
|
126
|
+
if returnType == types.TupleType :
|
127
|
+
# FIXME: this isn't perfect, if len == 0
|
128
|
+
# the length can really be 0 OR unknown
|
129
|
+
# we shouldn't check the lengths for equality
|
130
|
+
# ONLY IF one of the lengths is truly unknown
|
131
|
+
if returnData.length > 0 and value.length > 0:
|
132
|
+
ok = returnData.length == value.length
|
133
|
+
else :
|
134
|
+
ok = _checkSubclass(returnType, valueType) or \
|
135
|
+
_checkSubclass(valueType, returnType)
|
136
|
+
if not ok :
|
137
|
+
code.addWarning(msgs.INCONSISTENT_RETURN_TYPE, line)
|
138
|
+
|
139
|
+
|
140
|
+
def _checkComplex(code, maxValue, value, func, err) :
|
141
|
+
if maxValue and value > maxValue :
|
142
|
+
line = func.function.func_code.co_firstlineno
|
143
|
+
code.addWarning(err % (func.function.__name__, value), line)
|
144
|
+
|
145
|
+
|
146
|
+
def _checkCode(code, codeSource) :
|
147
|
+
while code.index < code.maxCode :
|
148
|
+
op, oparg, operand = code.popNextOp()
|
149
|
+
dispatch_func = CodeChecks.DISPATCH[op]
|
150
|
+
if dispatch_func is not None :
|
151
|
+
dispatch_func(oparg, operand, codeSource, code)
|
152
|
+
|
153
|
+
def _name_unused(var) :
|
154
|
+
if var in cfg().unusedNames :
|
155
|
+
return 0
|
156
|
+
for name in cfg().unusedNames :
|
157
|
+
if name != '_' and utils.startswith(var, name) :
|
158
|
+
return 0
|
159
|
+
return 1
|
160
|
+
|
161
|
+
def _checkUnusedParam(var, line, func, code) :
|
162
|
+
if line is not None and line == 0 and _name_unused(var) :
|
163
|
+
if ((cfg().ignoreSelfUnused or var != cfg().methodArgName) and
|
164
|
+
(cfg().varArgumentsUsed or func.varArgName() != var)) :
|
165
|
+
code.addWarning(msgs.UNUSED_PARAMETER % var, code.func_code)
|
166
|
+
|
167
|
+
def _handleNestedCode(func_code, code, codeSource):
|
168
|
+
nested = not (codeSource.main or codeSource.in_class)
|
169
|
+
if func_code.co_name == utils.LAMBDA or nested:
|
170
|
+
utils.debug(' handling nested code')
|
171
|
+
varnames = None
|
172
|
+
if nested and func_code.co_name != utils.LAMBDA:
|
173
|
+
varnames = func_code.co_varnames + \
|
174
|
+
codeSource.calling_code[-1].function.func_code.co_varnames
|
175
|
+
# save the original return value and restore after checking
|
176
|
+
returnValues = code.returnValues
|
177
|
+
code.init(function.create_fake(func_code.co_name, func_code, {},
|
178
|
+
varnames))
|
179
|
+
_checkCode(code, codeSource)
|
180
|
+
code.returnValues = returnValues
|
181
|
+
|
182
|
+
def _findUnreachableCode(code) :
|
183
|
+
# code after RETURN or RAISE is unreachable unless there's a branch to it
|
184
|
+
unreachable = {}
|
185
|
+
terminals = code.returnValues[:-1] + code.raiseValues
|
186
|
+
terminals.sort(lambda a, b: cmp(a[2], b[2]))
|
187
|
+
for line, dummy, i in terminals :
|
188
|
+
if not code.branches.has_key(i) :
|
189
|
+
unreachable[i] = line
|
190
|
+
|
191
|
+
# find the index of the last return
|
192
|
+
lastLine = lastItem = lastIndex = None
|
193
|
+
if code.returnValues:
|
194
|
+
lastLine, lastItem, lastIndex = code.returnValues[-1]
|
195
|
+
if len(code.returnValues) >= 2 :
|
196
|
+
lastIndex = code.returnValues[-2][2]
|
197
|
+
if code.raiseValues :
|
198
|
+
lastIndex = max(lastIndex, code.raiseValues[-1][2])
|
199
|
+
|
200
|
+
# remove last return if it's unreachable AND implicit
|
201
|
+
if unreachable.get(lastIndex) == lastLine and lastItem and \
|
202
|
+
lastItem.isImplicitNone():
|
203
|
+
del code.returnValues[-1]
|
204
|
+
del unreachable[lastIndex]
|
205
|
+
|
206
|
+
if cfg().unreachableCode :
|
207
|
+
for index in unreachable.keys() :
|
208
|
+
try :
|
209
|
+
if not OP.JUMP_FORWARD(ord(code.bytes[index])) :
|
210
|
+
code.addWarning(msgs.CODE_UNREACHABLE, unreachable[index])
|
211
|
+
except IndexError :
|
212
|
+
pass
|
213
|
+
|
214
|
+
|
215
|
+
def _checkFunction(module, func, c = None, main = 0, in_class = 0) :
|
216
|
+
"Return a list of Warnings found in a function/method."
|
217
|
+
|
218
|
+
# always push a new config object, so we can pop at end of function
|
219
|
+
utils.pushConfig()
|
220
|
+
|
221
|
+
code = CodeChecks.Code()
|
222
|
+
code.init(func)
|
223
|
+
if main:
|
224
|
+
for key in func.function.func_globals.keys():
|
225
|
+
code.unusedLocals[key] = -1
|
226
|
+
codeSource = CodeChecks.CodeSource(module, func, c, main, in_class, code)
|
227
|
+
try :
|
228
|
+
_checkCode(code, codeSource)
|
229
|
+
if not in_class :
|
230
|
+
_findUnreachableCode(code)
|
231
|
+
|
232
|
+
# handle lambdas and nested functions
|
233
|
+
codeSource.calling_code.append(func)
|
234
|
+
for func_code in code.codeObjects.values() :
|
235
|
+
_handleNestedCode(func_code, code, codeSource)
|
236
|
+
del codeSource.calling_code[-1]
|
237
|
+
|
238
|
+
except (SystemExit, KeyboardInterrupt) :
|
239
|
+
exc_type, exc_value, exc_tb = sys.exc_info()
|
240
|
+
raise exc_type, exc_value
|
241
|
+
except :
|
242
|
+
exc_type, exc_value, exc_tb = sys.exc_info()
|
243
|
+
exc_list = traceback.format_exception(exc_type, exc_value, exc_tb)
|
244
|
+
for index in range(0, len(exc_list)) :
|
245
|
+
exc_list[index] = string.replace(exc_list[index], "\n", "\n\t")
|
246
|
+
code.addWarning(msgs.CHECKER_BROKEN % string.join(exc_list, ""))
|
247
|
+
|
248
|
+
if cfg().checkReturnValues :
|
249
|
+
_checkReturnWarnings(code)
|
250
|
+
|
251
|
+
if cfg().localVariablesUsed :
|
252
|
+
for var, line in code.unusedLocals.items() :
|
253
|
+
if line is not None and line > 0 and _name_unused(var) :
|
254
|
+
code.addWarning(msgs.UNUSED_LOCAL % var, line)
|
255
|
+
|
256
|
+
if cfg().argumentsUsed :
|
257
|
+
op = code.getFirstOp()
|
258
|
+
if not (OP.RAISE_VARARGS(op) or OP.RETURN_VALUE(op)) :
|
259
|
+
for var, line in code.unusedLocals.items() :
|
260
|
+
_checkUnusedParam(var, line, func, code)
|
261
|
+
|
262
|
+
# Check code complexity:
|
263
|
+
# loops should be counted as one branch, but there are typically 3
|
264
|
+
# branches in byte code to setup a loop, so subtract off 2/3's of them
|
265
|
+
# / 2 to approximate real branches
|
266
|
+
branches = (len(code.branches.keys()) - (2 * code.loops)) / 2
|
267
|
+
lines = (code.getLineNum() - code.func_code.co_firstlineno)
|
268
|
+
returns = len(code.returnValues)
|
269
|
+
if not main and not in_class :
|
270
|
+
args = code.func_code.co_argcount
|
271
|
+
locals = len(code.func_code.co_varnames) - args
|
272
|
+
_checkComplex(code, cfg().maxArgs, args, func, msgs.TOO_MANY_ARGS)
|
273
|
+
_checkComplex(code, cfg().maxLocals, locals, func, msgs.TOO_MANY_LOCALS)
|
274
|
+
_checkComplex(code, cfg().maxLines, lines, func, msgs.FUNC_TOO_LONG)
|
275
|
+
_checkComplex(code, cfg().maxReturns, returns, func, msgs.TOO_MANY_RETURNS)
|
276
|
+
_checkComplex(code, cfg().maxBranches, branches, func, msgs.TOO_MANY_BRANCHES)
|
277
|
+
|
278
|
+
if not (main or in_class) :
|
279
|
+
utils.popConfig()
|
280
|
+
func.returnValues = code.returnValues
|
281
|
+
return (code.warnings, code.globalRefs, code.functionsCalled,
|
282
|
+
code.codeObjects.values(), code.returnValues)
|
283
|
+
|
284
|
+
|
285
|
+
def _getUnused(module, globalRefs, dict, msg, filterPrefix = None) :
|
286
|
+
"Return a list of warnings for unused globals"
|
287
|
+
|
288
|
+
warnings = []
|
289
|
+
for ref in dict.keys() :
|
290
|
+
check = not filterPrefix or utils.startswith(ref, filterPrefix)
|
291
|
+
if check and globalRefs.get(ref) == None :
|
292
|
+
lineInfo = module.moduleLineNums.get(ref)
|
293
|
+
if lineInfo:
|
294
|
+
warnings.append(Warning(lineInfo[0], lineInfo[1], msg % ref))
|
295
|
+
return warnings
|
296
|
+
|
297
|
+
|
298
|
+
def _get_func_info(method) :
|
299
|
+
try:
|
300
|
+
fc = getattr(method.im_func, 'func_code', None)
|
301
|
+
if fc is not None :
|
302
|
+
return fc.co_filename, fc.co_firstlineno
|
303
|
+
except AttributeError:
|
304
|
+
# if the object derives from any object in 2.2,
|
305
|
+
# the builtin methods are wrapper_descriptors and
|
306
|
+
# have no im_func attr
|
307
|
+
pass
|
308
|
+
return None, None
|
309
|
+
|
310
|
+
_DOT_INIT = '.' + utils.INIT
|
311
|
+
|
312
|
+
def _baseInitCalled(classInitInfo, base, functionsCalled) :
|
313
|
+
baseInit = getattr(base, utils.INIT, None)
|
314
|
+
if baseInit is None or _get_func_info(baseInit) == classInitInfo :
|
315
|
+
return 1
|
316
|
+
|
317
|
+
initName = utils.safestr(base) + _DOT_INIT
|
318
|
+
if functionsCalled.has_key(initName) :
|
319
|
+
return 1
|
320
|
+
|
321
|
+
# ok, do this the hard way, there may be aliases, so check here
|
322
|
+
names = string.split(initName, '.')
|
323
|
+
|
324
|
+
# first look in our list of PyCheckerModules
|
325
|
+
moduleName = names[0]
|
326
|
+
moduleDir = os.path.dirname(classInitInfo[0])
|
327
|
+
pcmodule = pcmodules.getPCModule(moduleName, moduleDir)
|
328
|
+
if pcmodule:
|
329
|
+
obj = pcmodule.module
|
330
|
+
else:
|
331
|
+
# fall back to looking in sys.modules
|
332
|
+
try:
|
333
|
+
# i think this can raise an exception if the module is a library
|
334
|
+
# (.so)
|
335
|
+
obj = sys.modules[names[0]]
|
336
|
+
except KeyError:
|
337
|
+
return 1
|
338
|
+
for i in range(1, len(names)) :
|
339
|
+
obj = getattr(obj, names[i], None)
|
340
|
+
if obj is None:
|
341
|
+
return 0
|
342
|
+
if functionsCalled.has_key(string.join(names[i:], '.')) :
|
343
|
+
return 1
|
344
|
+
|
345
|
+
return 0
|
346
|
+
|
347
|
+
def _checkBaseClassInit(moduleFilename, c, func_code, funcInfo) :
|
348
|
+
"""Return a list of warnings that occur
|
349
|
+
for each base class whose __init__() is not called"""
|
350
|
+
|
351
|
+
warnings = []
|
352
|
+
functionsCalled, _, returnValues = funcInfo
|
353
|
+
for line, stackItem, dummy in returnValues :
|
354
|
+
if stackItem.data != None :
|
355
|
+
if not stackItem.isNone() or cfg().returnNoneFromInit :
|
356
|
+
warn = Warning(func_code, line, msgs.RETURN_FROM_INIT)
|
357
|
+
warnings.append(warn)
|
358
|
+
|
359
|
+
classInit = getattr(c.classObject, utils.INIT, None)
|
360
|
+
if cfg().baseClassInitted and classInit is not None :
|
361
|
+
classInitInfo = _get_func_info(classInit)
|
362
|
+
for base in getattr(c.classObject, '__bases__', None) or ():
|
363
|
+
if not _baseInitCalled(classInitInfo, base, functionsCalled):
|
364
|
+
warn = Warning(moduleFilename, func_code,
|
365
|
+
msgs.BASE_CLASS_NOT_INIT % utils.safestr(base))
|
366
|
+
warnings.append(warn)
|
367
|
+
return warnings
|
368
|
+
|
369
|
+
|
370
|
+
def _checkOverridenMethods(func, baseClasses, warnings) :
|
371
|
+
for baseClass in baseClasses :
|
372
|
+
if func.func_name != utils.INIT and \
|
373
|
+
not function.same_signature(func, baseClass) :
|
374
|
+
err = msgs.METHOD_SIGNATURE_MISMATCH % (func.func_name, utils.safestr(baseClass))
|
375
|
+
warnings.append(Warning(func.func_code, func.func_code, err))
|
376
|
+
break
|
377
|
+
|
378
|
+
|
379
|
+
def _updateFunctionWarnings(module, func, c, warnings, globalRefs,
|
380
|
+
main = 0, in_class = 0) :
|
381
|
+
"Update function warnings and global references"
|
382
|
+
|
383
|
+
newWarnings, newGlobalRefs, funcs, codeObjects, returnValues = \
|
384
|
+
_checkFunction(module, func, c, main, in_class)
|
385
|
+
warnings.extend(newWarnings)
|
386
|
+
globalRefs.update(newGlobalRefs)
|
387
|
+
|
388
|
+
return funcs, codeObjects, returnValues
|
389
|
+
|
390
|
+
|
391
|
+
def getBlackList(moduleList) :
|
392
|
+
blacklist = []
|
393
|
+
for badBoy in moduleList :
|
394
|
+
if badBoy[-3:] == ".py":
|
395
|
+
badBoy = badBoy[0:-3]
|
396
|
+
try :
|
397
|
+
file, path, flags = imp.find_module(badBoy)
|
398
|
+
if file :
|
399
|
+
file.close()
|
400
|
+
# apparently, imp.find_module can return None, path, (triple)
|
401
|
+
# This happened to me with twisted 2.2.0 in a separate path
|
402
|
+
if path:
|
403
|
+
blacklist.append(normalize_path(path))
|
404
|
+
except ImportError :
|
405
|
+
pass
|
406
|
+
return blacklist
|
407
|
+
|
408
|
+
def getStandardLibraries() :
|
409
|
+
"""
|
410
|
+
Return a list of standard libraries.
|
411
|
+
|
412
|
+
@rtype: list of str or None
|
413
|
+
"""
|
414
|
+
if cfg().ignoreStandardLibrary :
|
415
|
+
try :
|
416
|
+
from distutils import sysconfig
|
417
|
+
|
418
|
+
std_libs = [
|
419
|
+
sysconfig.get_python_lib(plat_specific=0),
|
420
|
+
sysconfig.get_python_lib(plat_specific=1)
|
421
|
+
]
|
422
|
+
ret = []
|
423
|
+
for std_lib in std_libs:
|
424
|
+
path = os.path.split(std_lib)
|
425
|
+
if path[1] == 'site-packages' :
|
426
|
+
ret.append(path[0])
|
427
|
+
return ret
|
428
|
+
except ImportError :
|
429
|
+
return None
|
430
|
+
|
431
|
+
def normalize_path(path):
|
432
|
+
return os.path.normpath(os.path.normcase(path))
|
433
|
+
|
434
|
+
def removeWarnings(warnings, blacklist, std_lib, cfg):
|
435
|
+
"""
|
436
|
+
@param blacklist: list of absolute paths not to warn for
|
437
|
+
@type blacklist: str
|
438
|
+
@param std_lib: list of standard library directories
|
439
|
+
@type std_lib: list of str or None
|
440
|
+
"""
|
441
|
+
if std_lib is not None:
|
442
|
+
std_lib = [normalize_path(p) for p in std_lib]
|
443
|
+
for index in range(len(warnings)-1, -1, -1) :
|
444
|
+
filename = normalize_path(warnings[index].file)
|
445
|
+
# the blacklist contains paths to packages and modules we do not
|
446
|
+
# want warnings for
|
447
|
+
# when we find a match, make sure we continue the warnings for loop
|
448
|
+
found = False
|
449
|
+
for path in blacklist:
|
450
|
+
if not found and filename.startswith(path):
|
451
|
+
found = True
|
452
|
+
del warnings[index]
|
453
|
+
if found:
|
454
|
+
continue
|
455
|
+
if std_lib:
|
456
|
+
found = False
|
457
|
+
for path in std_lib:
|
458
|
+
if not found and utils.startswith(filename, path) :
|
459
|
+
found = True
|
460
|
+
del warnings[index]
|
461
|
+
if found:
|
462
|
+
continue
|
463
|
+
elif cfg.only:
|
464
|
+
# ignore files not specified on the cmd line if requested
|
465
|
+
if os.path.abspath(filename) not in cfg.files:
|
466
|
+
del warnings[index]
|
467
|
+
continue
|
468
|
+
|
469
|
+
# filter by warning/error level if requested
|
470
|
+
if cfg.level and warnings[index].level < cfg.level:
|
471
|
+
del warnings[index]
|
472
|
+
|
473
|
+
if cfg.limit:
|
474
|
+
# sort by severity first, then normal sort (by file/line)
|
475
|
+
warnings.sort(lambda a, b: cmp(a.level, b.level) or cmp(a, b))
|
476
|
+
|
477
|
+
# strip duplicates
|
478
|
+
lastWarning = None
|
479
|
+
for index in range(len(warnings)-1, -1, -1):
|
480
|
+
warning = warnings[index]
|
481
|
+
|
482
|
+
# remove duplicate warnings
|
483
|
+
if lastWarning is not None and cmp(lastWarning, warning) == 0:
|
484
|
+
del warnings[index]
|
485
|
+
else:
|
486
|
+
lastWarning = warning
|
487
|
+
|
488
|
+
num_ignored = len(warnings) - cfg.limit
|
489
|
+
if num_ignored > 0:
|
490
|
+
del warnings[:-cfg.limit]
|
491
|
+
msg = msgs.TOO_MANY_WARNINGS % num_ignored
|
492
|
+
warnings.append(Warning('', 0, msg))
|
493
|
+
|
494
|
+
return warnings
|
495
|
+
|
496
|
+
|
497
|
+
class _SuppressionError(Exception) :
|
498
|
+
pass
|
499
|
+
|
500
|
+
def _updateSuppressions(suppress, warnings) :
|
501
|
+
if not utils.updateCheckerArgs(suppress, 'suppressions', 0, warnings) :
|
502
|
+
utils.popConfig()
|
503
|
+
raise _SuppressionError
|
504
|
+
|
505
|
+
_CLASS_NAME_RE = re.compile("<class '([A-Za-z0-9.]+)'>(\\..+)?")
|
506
|
+
|
507
|
+
def getSuppression(name, suppressions, warnings) :
|
508
|
+
try :
|
509
|
+
utils.pushConfig()
|
510
|
+
|
511
|
+
# cheesy hack to deal with new-style classes. i don't see a
|
512
|
+
# better way to get the name, '<' is an invalid identifier, so
|
513
|
+
# we can reliably check it and extract name from:
|
514
|
+
# <class 'class-name'>[.identifier[.identifier]...]
|
515
|
+
matches = _CLASS_NAME_RE.match(name)
|
516
|
+
if matches:
|
517
|
+
# pull out the names and make a complete identifier (ignore None)
|
518
|
+
name = string.join(filter(None, matches.groups()), '')
|
519
|
+
|
520
|
+
suppress = suppressions[0].get(name, None)
|
521
|
+
if suppress is not None :
|
522
|
+
_updateSuppressions(suppress, warnings)
|
523
|
+
|
524
|
+
regexList = suppressions[1].keys()
|
525
|
+
regexList.sort()
|
526
|
+
for regex in regexList :
|
527
|
+
match = regex.match(name)
|
528
|
+
if match and match.group() == name :
|
529
|
+
suppress = 1
|
530
|
+
_updateSuppressions(suppressions[1][regex], warnings)
|
531
|
+
|
532
|
+
if not suppress :
|
533
|
+
utils.popConfig()
|
534
|
+
|
535
|
+
return suppress
|
536
|
+
except _SuppressionError :
|
537
|
+
return None
|
538
|
+
|
539
|
+
def _findFunctionWarnings(module, globalRefs, warnings, suppressions) :
|
540
|
+
for func in module.functions.values() :
|
541
|
+
func_code = func.function.func_code
|
542
|
+
utils.debug("function:", func_code)
|
543
|
+
|
544
|
+
name = '%s.%s' % (module.moduleName, func.function.__name__)
|
545
|
+
suppress = getSuppression(name, suppressions, warnings)
|
546
|
+
if cfg().noDocFunc and func.function.__doc__ == None :
|
547
|
+
err = msgs.NO_FUNC_DOC % func.function.__name__
|
548
|
+
warnings.append(Warning(module.filename(), func_code, err))
|
549
|
+
|
550
|
+
_checkNoSelfArg(func, warnings)
|
551
|
+
_updateFunctionWarnings(module, func, None, warnings, globalRefs)
|
552
|
+
if suppress is not None :
|
553
|
+
utils.popConfig()
|
554
|
+
|
555
|
+
def _getModuleFromFilename(module, filename):
|
556
|
+
if module.filename() != filename:
|
557
|
+
for m in module.modules.values():
|
558
|
+
if m.filename() == filename:
|
559
|
+
return m
|
560
|
+
return module
|
561
|
+
|
562
|
+
# Create object for non-2.2 interpreters, any class object will do
|
563
|
+
try:
|
564
|
+
if object: pass
|
565
|
+
except NameError:
|
566
|
+
object = _SuppressionError
|
567
|
+
|
568
|
+
# Create property for pre-2.2 interpreters
|
569
|
+
try :
|
570
|
+
if property: pass
|
571
|
+
except NameError:
|
572
|
+
property = None
|
573
|
+
|
574
|
+
def _findClassWarnings(module, c, class_code,
|
575
|
+
globalRefs, warnings, suppressions) :
|
576
|
+
try:
|
577
|
+
className = utils.safestr(c.classObject)
|
578
|
+
except TypeError:
|
579
|
+
# goofy __getattr__
|
580
|
+
return
|
581
|
+
classSuppress = getSuppression(className, suppressions, warnings)
|
582
|
+
baseClasses = c.allBaseClasses()
|
583
|
+
for base in baseClasses :
|
584
|
+
baseModule = utils.safestr(base)
|
585
|
+
if '.' in baseModule :
|
586
|
+
# make sure we handle import x.y.z
|
587
|
+
packages = string.split(baseModule, '.')
|
588
|
+
baseModuleDir = string.join(packages[:-1], '.')
|
589
|
+
globalRefs[baseModuleDir] = baseModule
|
590
|
+
|
591
|
+
# handle class variables
|
592
|
+
if class_code is not None :
|
593
|
+
func = function.create_fake(c.name, class_code)
|
594
|
+
_updateFunctionWarnings(module, func, c, warnings, globalRefs, 0, 1)
|
595
|
+
|
596
|
+
filename = module.filename()
|
597
|
+
func_code = None
|
598
|
+
for method in c.methods.values() :
|
599
|
+
if method == None :
|
600
|
+
continue
|
601
|
+
func_code = method.function.func_code
|
602
|
+
utils.debug("method:", func_code)
|
603
|
+
|
604
|
+
try:
|
605
|
+
name = utils.safestr(c.classObject) + '.' + method.function.func_name
|
606
|
+
except AttributeError:
|
607
|
+
# func_name may not exist
|
608
|
+
continue
|
609
|
+
methodSuppress = getSuppression(name, suppressions, warnings)
|
610
|
+
|
611
|
+
if cfg().checkSpecialMethods:
|
612
|
+
funcname = method.function.func_name
|
613
|
+
if funcname[:2] == '__' == funcname[-2:] and \
|
614
|
+
funcname != '__init__':
|
615
|
+
err = None
|
616
|
+
argCount = python.SPECIAL_METHODS.get(funcname, -1)
|
617
|
+
if argCount != -1:
|
618
|
+
# if the args are None, it can be any # of args
|
619
|
+
if argCount is not None:
|
620
|
+
minArgs = maxArgs = argCount
|
621
|
+
err = CodeChecks.getFunctionArgErr(funcname,
|
622
|
+
func_code.co_argcount, minArgs, maxArgs)
|
623
|
+
else:
|
624
|
+
err = msgs.NOT_SPECIAL_METHOD % funcname
|
625
|
+
|
626
|
+
if err is not None:
|
627
|
+
warnings.append(Warning(filename, func_code, err))
|
628
|
+
|
629
|
+
if cfg().checkOverridenMethods :
|
630
|
+
_checkOverridenMethods(method.function, baseClasses, warnings)
|
631
|
+
|
632
|
+
if cfg().noDocFunc and method.function.__doc__ == None :
|
633
|
+
err = msgs.NO_FUNC_DOC % method.function.__name__
|
634
|
+
warnings.append(Warning(filename, func_code, err))
|
635
|
+
|
636
|
+
_checkSelfArg(method, warnings)
|
637
|
+
tmpModule = _getModuleFromFilename(module, func_code.co_filename)
|
638
|
+
funcInfo = _updateFunctionWarnings(tmpModule, method, c, warnings, globalRefs)
|
639
|
+
if func_code.co_name == utils.INIT :
|
640
|
+
if utils.INIT in dir(c.classObject) :
|
641
|
+
warns = _checkBaseClassInit(filename, c, func_code, funcInfo)
|
642
|
+
warnings.extend(warns)
|
643
|
+
elif cfg().initDefinedInSubclass :
|
644
|
+
err = msgs.NO_INIT_IN_SUBCLASS % c.name
|
645
|
+
warnings.append(Warning(filename, c.getFirstLine(), err))
|
646
|
+
if methodSuppress is not None :
|
647
|
+
utils.popConfig()
|
648
|
+
|
649
|
+
if c.memberRefs and cfg().membersUsed :
|
650
|
+
memberList = c.memberRefs.keys()
|
651
|
+
memberList.sort()
|
652
|
+
err = msgs.UNUSED_MEMBERS % (string.join(memberList, ', '), c.name)
|
653
|
+
warnings.append(Warning(filename, c.getFirstLine(), err))
|
654
|
+
|
655
|
+
try:
|
656
|
+
newStyleClass = issubclass(c.classObject, object)
|
657
|
+
except TypeError:
|
658
|
+
# FIXME: perhaps this should warn b/c it may be a class???
|
659
|
+
newStyleClass = 0
|
660
|
+
|
661
|
+
slots = c.statics.get('__slots__')
|
662
|
+
if slots is not None and cfg().slots:
|
663
|
+
lineNum = c.lineNums['__slots__']
|
664
|
+
if not newStyleClass:
|
665
|
+
err = msgs.USING_SLOTS_IN_CLASSIC_CLASS % c.name
|
666
|
+
warnings.append(Warning(filename, lineNum, err))
|
667
|
+
elif cfg().emptySlots:
|
668
|
+
try:
|
669
|
+
if len(slots.data) == 0:
|
670
|
+
err = msgs.EMPTY_SLOTS % c.name
|
671
|
+
warnings.append(Warning(filename, lineNum, err))
|
672
|
+
except AttributeError:
|
673
|
+
# happens when slots is an instance of a class w/o __len__
|
674
|
+
pass
|
675
|
+
|
676
|
+
if not newStyleClass and property is not None and cfg().classicProperties:
|
677
|
+
for static in c.statics.keys():
|
678
|
+
if type(getattr(c.classObject, static, None)) == property:
|
679
|
+
err = msgs.USING_PROPERTIES_IN_CLASSIC_CLASS % (static, c.name)
|
680
|
+
warnings.append(Warning(filename, c.lineNums[static], err))
|
681
|
+
|
682
|
+
coerceMethod = c.methods.get('__coerce__')
|
683
|
+
if newStyleClass and coerceMethod:
|
684
|
+
lineNum = coerceMethod.function.func_code.co_firstlineno
|
685
|
+
err = msgs.USING_COERCE_IN_NEW_CLASS % c.name
|
686
|
+
warnings.append(Warning(filename, lineNum, err))
|
687
|
+
|
688
|
+
for newClassMethodName in python.NEW_STYLE_CLASS_METHODS:
|
689
|
+
newClassMethod = c.methods.get(newClassMethodName)
|
690
|
+
if not newStyleClass and newClassMethod:
|
691
|
+
lineNum = newClassMethod.function.func_code.co_firstlineno
|
692
|
+
err = msgs.USING_NEW_STYLE_METHOD_IN_OLD_CLASS % (newClassMethodName, c.name)
|
693
|
+
warnings.append(Warning(filename, lineNum, err))
|
694
|
+
|
695
|
+
if cfg().noDocClass and c.classObject.__doc__ == None :
|
696
|
+
method = c.methods.get(utils.INIT, None)
|
697
|
+
if method != None :
|
698
|
+
func_code = method.function.func_code
|
699
|
+
# FIXME: check to make sure this is in our file,
|
700
|
+
# not a base class file???
|
701
|
+
err = msgs.NO_CLASS_DOC % c.classObject.__name__
|
702
|
+
warnings.append(Warning(filename, func_code, err))
|
703
|
+
|
704
|
+
# we have to do this here, b/c checkFunction doesn't popConfig for classes
|
705
|
+
# this allows us to have __pychecker__ apply to all methods
|
706
|
+
# when defined at class scope
|
707
|
+
if class_code is not None :
|
708
|
+
utils.popConfig()
|
709
|
+
|
710
|
+
if classSuppress is not None :
|
711
|
+
utils.popConfig()
|
712
|
+
|
713
|
+
|
714
|
+
def find(moduleList, initialCfg, suppressions = None) :
|
715
|
+
"Return a list of warnings found in the module list"
|
716
|
+
|
717
|
+
if suppressions is None :
|
718
|
+
suppressions = {}, {}
|
719
|
+
|
720
|
+
utils.initConfig(initialCfg)
|
721
|
+
|
722
|
+
warnings = []
|
723
|
+
for module in moduleList :
|
724
|
+
if module.moduleName in cfg().blacklist :
|
725
|
+
continue
|
726
|
+
|
727
|
+
modSuppress = getSuppression(module.moduleName, suppressions, warnings)
|
728
|
+
globalRefs, classCodes = {}, {}
|
729
|
+
|
730
|
+
# main_code can be null if there was a syntax error
|
731
|
+
if module.main_code != None :
|
732
|
+
funcInfo = _updateFunctionWarnings(module, module.main_code,
|
733
|
+
None, warnings, globalRefs, 1)
|
734
|
+
for code in funcInfo[1] :
|
735
|
+
classCodes[code.co_name] = code
|
736
|
+
|
737
|
+
_findFunctionWarnings(module, globalRefs, warnings, suppressions)
|
738
|
+
|
739
|
+
for c in module.classes.values() :
|
740
|
+
_findClassWarnings(module, c, classCodes.get(c.name),
|
741
|
+
globalRefs, warnings, suppressions)
|
742
|
+
|
743
|
+
if cfg().noDocModule and \
|
744
|
+
module.module != None and module.module.__doc__ == None :
|
745
|
+
warnings.append(Warning(module.filename(), 1, msgs.NO_MODULE_DOC))
|
746
|
+
|
747
|
+
if cfg().allVariablesUsed or cfg().privateVariableUsed :
|
748
|
+
prefix = None
|
749
|
+
if not cfg().allVariablesUsed :
|
750
|
+
prefix = "_"
|
751
|
+
for ignoreVar in cfg().variablesToIgnore + cfg().unusedNames :
|
752
|
+
globalRefs[ignoreVar] = ignoreVar
|
753
|
+
warnings.extend(_getUnused(module, globalRefs, module.variables,
|
754
|
+
msgs.VAR_NOT_USED, prefix))
|
755
|
+
if cfg().importUsed :
|
756
|
+
if module.moduleName != utils.INIT or cfg().packageImportUsed :
|
757
|
+
# always ignore readline module, if [raw_]input() is used
|
758
|
+
if globalRefs.has_key('input') or \
|
759
|
+
globalRefs.has_key('raw_input'):
|
760
|
+
globalRefs['readline'] = 0
|
761
|
+
warnings.extend(_getUnused(module, globalRefs, module.modules,
|
762
|
+
msgs.IMPORT_NOT_USED))
|
763
|
+
|
764
|
+
if module.main_code != None :
|
765
|
+
utils.popConfig()
|
766
|
+
if modSuppress is not None :
|
767
|
+
utils.popConfig()
|
768
|
+
|
769
|
+
std_lib = None
|
770
|
+
if cfg().ignoreStandardLibrary :
|
771
|
+
std_lib = getStandardLibraries()
|
772
|
+
return removeWarnings(warnings, getBlackList(cfg().blacklist), std_lib,
|
773
|
+
cfg())
|
774
|
+
|
775
|
+
if 0:
|
776
|
+
# if you want to test w/psyco, include this
|
777
|
+
import psyco
|
778
|
+
psyco.bind(_checkCode)
|