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
@@ -0,0 +1,961 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
|
3
|
+
# Copyright (c) 2001-2004, MetaSlash Inc. All rights reserved.
|
4
|
+
# Portions Copyright (c) 2005, Google, Inc. All rights reserved.
|
5
|
+
|
6
|
+
"""
|
7
|
+
Check python source code files for possible errors and print warnings
|
8
|
+
|
9
|
+
Contact Info:
|
10
|
+
http://pychecker.sourceforge.net/
|
11
|
+
pychecker-list@lists.sourceforge.net
|
12
|
+
"""
|
13
|
+
|
14
|
+
import string
|
15
|
+
import types
|
16
|
+
import sys
|
17
|
+
import imp
|
18
|
+
import os
|
19
|
+
import glob
|
20
|
+
import traceback
|
21
|
+
import re
|
22
|
+
|
23
|
+
# see __init__.py for meaning, this must match the version there
|
24
|
+
LOCAL_MAIN_VERSION = 3
|
25
|
+
|
26
|
+
|
27
|
+
def setupNamespace(path) :
|
28
|
+
# remove pychecker if it's the first component, it needs to be last
|
29
|
+
if sys.path[0][-9:] == 'pychecker' :
|
30
|
+
del sys.path[0]
|
31
|
+
|
32
|
+
# make sure pychecker is last in path, so we can import
|
33
|
+
checker_path = os.path.dirname(os.path.dirname(path))
|
34
|
+
if checker_path not in sys.path :
|
35
|
+
sys.path.append(checker_path)
|
36
|
+
|
37
|
+
|
38
|
+
def setupSysPathForDevelopment():
|
39
|
+
import pychecker
|
40
|
+
this_module = sys.modules[__name__]
|
41
|
+
this_path = os.path.normpath(os.path.dirname(this_module.__file__))
|
42
|
+
pkg_path = os.path.normpath(os.path.dirname(pychecker.__file__))
|
43
|
+
if pkg_path != this_path:
|
44
|
+
# pychecker was probably found in site-packages, insert this
|
45
|
+
# directory before the other one so we can do development and run
|
46
|
+
# our local version and not the version from site-packages.
|
47
|
+
pkg_dir = os.path.dirname(pkg_path)
|
48
|
+
i = 0
|
49
|
+
for p in sys.path:
|
50
|
+
if os.path.normpath(p) == pkg_dir:
|
51
|
+
sys.path.insert(i-1, os.path.dirname(this_path))
|
52
|
+
break
|
53
|
+
i = i + 1
|
54
|
+
del sys.modules['pychecker']
|
55
|
+
|
56
|
+
|
57
|
+
if __name__ == '__main__' :
|
58
|
+
setupNamespace(sys.argv[0])
|
59
|
+
setupSysPathForDevelopment()
|
60
|
+
|
61
|
+
from pychecker import utils
|
62
|
+
from pychecker import printer
|
63
|
+
from pychecker import warn
|
64
|
+
from pychecker import OP
|
65
|
+
from pychecker import Config
|
66
|
+
from pychecker import function
|
67
|
+
from pychecker import msgs
|
68
|
+
from pychecker import pcmodules
|
69
|
+
from pychecker.Warning import Warning
|
70
|
+
|
71
|
+
_cfg = None
|
72
|
+
|
73
|
+
# Constants
|
74
|
+
_DEFAULT_MODULE_TOKENS = ('__builtins__', '__doc__', '__file__', '__name__',
|
75
|
+
'__path__')
|
76
|
+
_DEFAULT_CLASS_TOKENS = ('__doc__', '__name__', '__module__')
|
77
|
+
|
78
|
+
# When using introspection on objects from some C extension modules,
|
79
|
+
# the interpreter will crash. Since pychecker exercises these bugs we
|
80
|
+
# need to blacklist the objects and ignore them. For more info on how
|
81
|
+
# to determine what object is causing the crash, search for this
|
82
|
+
# comment below (ie, it is also several hundred lines down):
|
83
|
+
#
|
84
|
+
# README if interpreter is crashing:
|
85
|
+
|
86
|
+
# FIXME: the values should indicate the versions of these modules
|
87
|
+
# that are broken. We shouldn't ignore good modules.
|
88
|
+
|
89
|
+
_EVIL_C_OBJECTS = {
|
90
|
+
'matplotlib.axes.BinOpType': None, # broken on versions <= 0.83.2
|
91
|
+
|
92
|
+
# broken on versions at least 2.5.5 up to 2.6
|
93
|
+
'wx.TheClipboard': None,
|
94
|
+
'wx._core.TheClipboard': None,
|
95
|
+
'wx._misc.TheClipboard': None,
|
96
|
+
}
|
97
|
+
|
98
|
+
_VERSION_MISMATCH_ERROR = '''
|
99
|
+
There seem to be two versions of PyChecker being used.
|
100
|
+
One is probably in python/site-packages, the other in a local directory.
|
101
|
+
If you want to run the local version, you must remove the version
|
102
|
+
from site-packages. Or you can install the current version
|
103
|
+
by doing python setup.py install.
|
104
|
+
'''
|
105
|
+
|
106
|
+
def cfg() :
|
107
|
+
return utils.cfg()
|
108
|
+
|
109
|
+
def _flattenList(list) :
|
110
|
+
"Returns a list which contains no lists"
|
111
|
+
|
112
|
+
new_list = []
|
113
|
+
for element in list :
|
114
|
+
if type(element) == types.ListType :
|
115
|
+
new_list.extend(_flattenList(element))
|
116
|
+
else :
|
117
|
+
new_list.append(element)
|
118
|
+
|
119
|
+
return new_list
|
120
|
+
|
121
|
+
def getModules(arg_list) :
|
122
|
+
"""
|
123
|
+
arg_list is a list of arguments to pychecker; arguments can represent
|
124
|
+
a module name, a filename, or a wildcard file specification.
|
125
|
+
|
126
|
+
Returns a list of (module name, dirPath) that can be imported, where
|
127
|
+
dirPath is the on-disk path to the module name for that argument.
|
128
|
+
|
129
|
+
dirPath can be None (in case the given argument is an actual module).
|
130
|
+
"""
|
131
|
+
|
132
|
+
new_arguments = []
|
133
|
+
for arg in arg_list :
|
134
|
+
# is this a wildcard filespec? (necessary for windows)
|
135
|
+
if '*' in arg or '?' in arg or '[' in arg :
|
136
|
+
arg = glob.glob(arg)
|
137
|
+
new_arguments.append(arg)
|
138
|
+
|
139
|
+
PY_SUFFIXES = ['.py']
|
140
|
+
PY_SUFFIX_LENS = [3]
|
141
|
+
if _cfg.quixote:
|
142
|
+
PY_SUFFIXES.append('.ptl')
|
143
|
+
PY_SUFFIX_LENS.append(4)
|
144
|
+
|
145
|
+
modules = []
|
146
|
+
for arg in _flattenList(new_arguments) :
|
147
|
+
# if arg is an actual module, return None for the directory
|
148
|
+
arg_dir = None
|
149
|
+
# is it a .py file?
|
150
|
+
for suf, suflen in zip(PY_SUFFIXES, PY_SUFFIX_LENS):
|
151
|
+
if len(arg) > suflen and arg[-suflen:] == suf:
|
152
|
+
arg_dir = os.path.dirname(arg)
|
153
|
+
if arg_dir and not os.path.exists(arg) :
|
154
|
+
print 'File or pathname element does not exist: "%s"' % arg
|
155
|
+
continue
|
156
|
+
|
157
|
+
module_name = os.path.basename(arg)[:-suflen]
|
158
|
+
|
159
|
+
arg = module_name
|
160
|
+
modules.append((arg, arg_dir))
|
161
|
+
|
162
|
+
return modules
|
163
|
+
|
164
|
+
def _q_file(f):
|
165
|
+
# crude hack!!!
|
166
|
+
# imp.load_module requires a real file object, so we can't just
|
167
|
+
# fiddle def lines and yield them
|
168
|
+
import tempfile
|
169
|
+
fd, newfname = tempfile.mkstemp(suffix=".py", text=True)
|
170
|
+
newf = os.fdopen(fd, 'r+')
|
171
|
+
os.unlink(newfname)
|
172
|
+
for line in f:
|
173
|
+
mat = re.match(r'(\s*def\s+\w+\s*)\[(html|plain)\](.*)', line)
|
174
|
+
if mat is None:
|
175
|
+
newf.write(line)
|
176
|
+
else:
|
177
|
+
newf.write(mat.group(1)+mat.group(3)+'\n')
|
178
|
+
newf.seek(0)
|
179
|
+
return newf
|
180
|
+
|
181
|
+
def _q_find_module(p, path):
|
182
|
+
if not _cfg.quixote:
|
183
|
+
return imp.find_module(p, path)
|
184
|
+
else:
|
185
|
+
for direc in path:
|
186
|
+
try:
|
187
|
+
return imp.find_module(p, [direc])
|
188
|
+
except ImportError:
|
189
|
+
f = os.path.join(direc, p+".ptl")
|
190
|
+
if os.path.exists(f):
|
191
|
+
return _q_file(file(f)), f, ('.ptl', 'U', 1)
|
192
|
+
|
193
|
+
def _findModule(name, moduleDir=None) :
|
194
|
+
"""Returns the result of an imp.find_module(), ie, (file, filename, smt)
|
195
|
+
name can be a module or a package name. It is *not* a filename."""
|
196
|
+
|
197
|
+
path = sys.path[:]
|
198
|
+
if moduleDir:
|
199
|
+
path.insert(0, moduleDir)
|
200
|
+
|
201
|
+
packages = string.split(name, '.')
|
202
|
+
for p in packages :
|
203
|
+
# smt = (suffix, mode, type)
|
204
|
+
file, filename, smt = _q_find_module(p, path)
|
205
|
+
if smt[-1] == imp.PKG_DIRECTORY :
|
206
|
+
try :
|
207
|
+
# package found - read path info from init file
|
208
|
+
m = imp.load_module(p, file, filename, smt)
|
209
|
+
finally :
|
210
|
+
if file is not None :
|
211
|
+
file.close()
|
212
|
+
|
213
|
+
# importing xml plays a trick, which replaces itself with _xmlplus
|
214
|
+
# both have subdirs w/same name, but different modules in them
|
215
|
+
# we need to choose the real (replaced) version
|
216
|
+
if m.__name__ != p :
|
217
|
+
try :
|
218
|
+
file, filename, smt = _q_find_module(m.__name__, path)
|
219
|
+
m = imp.load_module(p, file, filename, smt)
|
220
|
+
finally :
|
221
|
+
if file is not None :
|
222
|
+
file.close()
|
223
|
+
|
224
|
+
new_path = m.__path__
|
225
|
+
if type(new_path) == types.ListType :
|
226
|
+
new_path = filename
|
227
|
+
if new_path not in path :
|
228
|
+
path.insert(1, new_path)
|
229
|
+
elif smt[-1] != imp.PY_COMPILED:
|
230
|
+
if p is not packages[-1] :
|
231
|
+
if file is not None :
|
232
|
+
file.close()
|
233
|
+
raise ImportError, "No module named %s" % packages[-1]
|
234
|
+
return file, filename, smt
|
235
|
+
|
236
|
+
# in case we have been given a package to check
|
237
|
+
return file, filename, smt
|
238
|
+
|
239
|
+
|
240
|
+
class Variable :
|
241
|
+
"Class to hold all information about a variable"
|
242
|
+
|
243
|
+
def __init__(self, name, type):
|
244
|
+
self.name = name
|
245
|
+
self.type = type
|
246
|
+
self.value = None
|
247
|
+
|
248
|
+
def __str__(self) :
|
249
|
+
return self.name
|
250
|
+
|
251
|
+
__repr__ = utils.std_repr
|
252
|
+
|
253
|
+
|
254
|
+
def _filterDir(object, ignoreList) :
|
255
|
+
"Return a list of tokens (attributes) in a class, except for ignoreList"
|
256
|
+
|
257
|
+
tokens = dir(object)
|
258
|
+
for token in ignoreList :
|
259
|
+
if token in tokens :
|
260
|
+
tokens.remove(token)
|
261
|
+
return tokens
|
262
|
+
|
263
|
+
def _getClassTokens(c) :
|
264
|
+
return _filterDir(c, _DEFAULT_CLASS_TOKENS)
|
265
|
+
|
266
|
+
|
267
|
+
class Class :
|
268
|
+
"Class to hold all information about a class"
|
269
|
+
|
270
|
+
def __init__(self, name, pcmodule) :
|
271
|
+
"""
|
272
|
+
@type pcmodule: PyCheckerModule
|
273
|
+
"""
|
274
|
+
self.name = name
|
275
|
+
module = pcmodule.module
|
276
|
+
self.classObject = getattr(module, name)
|
277
|
+
|
278
|
+
modname = getattr(self.classObject, '__module__', None)
|
279
|
+
if modname is None:
|
280
|
+
# hm, some ExtensionClasses don't have a __module__ attribute
|
281
|
+
# so try parsing the type output
|
282
|
+
typerepr = repr(type(self.classObject))
|
283
|
+
mo = re.match("^<type ['\"](.+)['\"]>$", typerepr)
|
284
|
+
if mo:
|
285
|
+
modname = ".".join(mo.group(1).split(".")[:-1])
|
286
|
+
|
287
|
+
# TODO(nnorwitz): this check for __name__ might not be necessary
|
288
|
+
# any more. Previously we checked objects as if they were classes.
|
289
|
+
# This problem is fixed by not adding objects as if they are classes.
|
290
|
+
|
291
|
+
# zope.interface for example has Provides and Declaration that
|
292
|
+
# look a lot like class objects but do not have __name__
|
293
|
+
if not hasattr(self.classObject, '__name__'):
|
294
|
+
if modname not in cfg().blacklist:
|
295
|
+
sys.stderr.write("warning: no __name__ attribute "
|
296
|
+
"for class %s (module name: %s)\n"
|
297
|
+
% (self.classObject, modname))
|
298
|
+
self.classObject.__name__ = name
|
299
|
+
# later pychecker code uses this
|
300
|
+
self.classObject__name__ = self.classObject.__name__
|
301
|
+
|
302
|
+
self.module = sys.modules.get(modname)
|
303
|
+
# if the pcmodule has moduleDir, it means we processed it before,
|
304
|
+
# and deleted it from sys.modules
|
305
|
+
if not self.module and not pcmodule.moduleDir:
|
306
|
+
self.module = module
|
307
|
+
if modname not in cfg().blacklist:
|
308
|
+
sys.stderr.write("warning: couldn't find real module "
|
309
|
+
"for class %s (module name: %s)\n"
|
310
|
+
% (self.classObject, modname))
|
311
|
+
self.ignoreAttrs = 0
|
312
|
+
self.methods = {}
|
313
|
+
self.members = { '__class__': types.ClassType,
|
314
|
+
'__doc__': types.StringType,
|
315
|
+
'__dict__': types.DictType, }
|
316
|
+
self.memberRefs = {}
|
317
|
+
self.statics = {}
|
318
|
+
self.lineNums = {}
|
319
|
+
|
320
|
+
def __str__(self) :
|
321
|
+
return self.name
|
322
|
+
|
323
|
+
__repr__ = utils.std_repr
|
324
|
+
|
325
|
+
def getFirstLine(self) :
|
326
|
+
"Return first line we can find in THIS class, not any base classes"
|
327
|
+
|
328
|
+
lineNums = []
|
329
|
+
classDir = dir(self.classObject)
|
330
|
+
for m in self.methods.values() :
|
331
|
+
if m != None and m.function.func_code.co_name in classDir:
|
332
|
+
lineNums.append(m.function.func_code.co_firstlineno)
|
333
|
+
if lineNums :
|
334
|
+
return min(lineNums)
|
335
|
+
return 0
|
336
|
+
|
337
|
+
def allBaseClasses(self, c = None) :
|
338
|
+
"Return a list of all base classes for this class and it's subclasses"
|
339
|
+
|
340
|
+
baseClasses = []
|
341
|
+
if c == None :
|
342
|
+
c = self.classObject
|
343
|
+
for base in getattr(c, '__bases__', None) or ():
|
344
|
+
baseClasses = baseClasses + [ base ] + self.allBaseClasses(base)
|
345
|
+
return baseClasses
|
346
|
+
|
347
|
+
def __getMethodName(self, func_name, className = None) :
|
348
|
+
if func_name[0:2] == '__' and func_name[-2:] != '__' :
|
349
|
+
if className == None :
|
350
|
+
className = self.name
|
351
|
+
if className[0] != '_' :
|
352
|
+
className = '_' + className
|
353
|
+
func_name = className + func_name
|
354
|
+
return func_name
|
355
|
+
|
356
|
+
def addMethod(self, method, methodName = None) :
|
357
|
+
if type(method) == types.StringType :
|
358
|
+
self.methods[method] = None
|
359
|
+
else :
|
360
|
+
assert methodName is not None, "must supply methodName"
|
361
|
+
self.methods[methodName] = function.Function(method, 1)
|
362
|
+
|
363
|
+
def addMethods(self, classObject) :
|
364
|
+
for classToken in _getClassTokens(classObject) :
|
365
|
+
token = getattr(classObject, classToken, None)
|
366
|
+
if token is None:
|
367
|
+
continue
|
368
|
+
|
369
|
+
# Looks like a method. Need to code it this way to
|
370
|
+
# accommodate ExtensionClass and Python 2.2. Yecchh.
|
371
|
+
if (hasattr(token, "func_code") and
|
372
|
+
hasattr(token.func_code, "co_argcount")):
|
373
|
+
self.addMethod(token, token.__name__)
|
374
|
+
|
375
|
+
elif hasattr(token, '__get__') and \
|
376
|
+
not hasattr(token, '__set__') and \
|
377
|
+
type(token) is not types.ClassType :
|
378
|
+
self.addMethod(getattr(token, '__name__', classToken))
|
379
|
+
else :
|
380
|
+
self.members[classToken] = type(token)
|
381
|
+
self.memberRefs[classToken] = None
|
382
|
+
|
383
|
+
self.cleanupMemberRefs()
|
384
|
+
# add standard methods
|
385
|
+
for methodName in ('__class__',) :
|
386
|
+
self.addMethod(methodName, self.classObject__name__)
|
387
|
+
|
388
|
+
def addMembers(self, classObject) :
|
389
|
+
if not cfg().onlyCheckInitForMembers :
|
390
|
+
for classToken in _getClassTokens(classObject) :
|
391
|
+
method = getattr(classObject, classToken, None)
|
392
|
+
if type(method) == types.MethodType :
|
393
|
+
self.addMembersFromMethod(method.im_func)
|
394
|
+
else:
|
395
|
+
try:
|
396
|
+
self.addMembersFromMethod(classObject.__init__.im_func)
|
397
|
+
except AttributeError:
|
398
|
+
pass
|
399
|
+
|
400
|
+
def addMembersFromMethod(self, method) :
|
401
|
+
if not hasattr(method, 'func_code') :
|
402
|
+
return
|
403
|
+
|
404
|
+
func_code, code, i, maxCode, extended_arg = OP.initFuncCode(method)
|
405
|
+
stack = []
|
406
|
+
while i < maxCode :
|
407
|
+
op, oparg, i, extended_arg = OP.getInfo(code, i, extended_arg)
|
408
|
+
if op >= OP.HAVE_ARGUMENT :
|
409
|
+
operand = OP.getOperand(op, func_code, oparg)
|
410
|
+
if OP.LOAD_CONST(op) or OP.LOAD_FAST(op) or OP.LOAD_GLOBAL(op):
|
411
|
+
stack.append(operand)
|
412
|
+
elif OP.LOAD_DEREF(op):
|
413
|
+
try:
|
414
|
+
operand = func_code.co_cellvars[oparg]
|
415
|
+
except IndexError:
|
416
|
+
index = oparg - len(func_code.co_cellvars)
|
417
|
+
operand = func_code.co_freevars[index]
|
418
|
+
stack.append(operand)
|
419
|
+
elif OP.STORE_ATTR(op) :
|
420
|
+
if len(stack) > 0 :
|
421
|
+
if stack[-1] == cfg().methodArgName:
|
422
|
+
value = None
|
423
|
+
if len(stack) > 1 :
|
424
|
+
value = type(stack[-2])
|
425
|
+
self.members[operand] = value
|
426
|
+
self.memberRefs[operand] = None
|
427
|
+
stack = []
|
428
|
+
|
429
|
+
self.cleanupMemberRefs()
|
430
|
+
|
431
|
+
def cleanupMemberRefs(self) :
|
432
|
+
try :
|
433
|
+
del self.memberRefs[Config.CHECKER_VAR]
|
434
|
+
except KeyError :
|
435
|
+
pass
|
436
|
+
|
437
|
+
def abstractMethod(self, m):
|
438
|
+
"""Return 1 if method is abstract, None if not
|
439
|
+
An abstract method always raises an exception.
|
440
|
+
"""
|
441
|
+
if not self.methods.get(m, None):
|
442
|
+
return None
|
443
|
+
func_code, bytes, i, maxCode, extended_arg = \
|
444
|
+
OP.initFuncCode(self.methods[m].function)
|
445
|
+
# abstract if the first opcode is RAISE_VARARGS and it raises
|
446
|
+
# NotImplementedError
|
447
|
+
arg = ""
|
448
|
+
while i < maxCode:
|
449
|
+
op, oparg, i, extended_arg = OP.getInfo(bytes, i, extended_arg)
|
450
|
+
if OP.LOAD_GLOBAL(op):
|
451
|
+
arg = func_code.co_names[oparg]
|
452
|
+
elif OP.RAISE_VARARGS(op):
|
453
|
+
# if we saw NotImplementedError sometime before the raise
|
454
|
+
# assume it's related to this raise stmt
|
455
|
+
return arg == "NotImplementedError"
|
456
|
+
if OP.conditional(op):
|
457
|
+
break
|
458
|
+
return None
|
459
|
+
|
460
|
+
def isAbstract(self):
|
461
|
+
"""Return the method names that make a class abstract.
|
462
|
+
An abstract class has at least one abstract method."""
|
463
|
+
result = []
|
464
|
+
for m in self.methods.keys():
|
465
|
+
if self.abstractMethod(m):
|
466
|
+
result.append(m)
|
467
|
+
return result
|
468
|
+
|
469
|
+
def _getLineInFile(moduleName, moduleDir, linenum):
|
470
|
+
line = ''
|
471
|
+
file, filename, smt = _findModule(moduleName, moduleDir)
|
472
|
+
if file is None:
|
473
|
+
return ''
|
474
|
+
try:
|
475
|
+
lines = file.readlines()
|
476
|
+
line = string.rstrip(lines[linenum - 1])
|
477
|
+
except (IOError, IndexError):
|
478
|
+
pass
|
479
|
+
file.close()
|
480
|
+
return line
|
481
|
+
|
482
|
+
def importError(moduleName, moduleDir=None):
|
483
|
+
exc_type, exc_value, tb = sys.exc_info()
|
484
|
+
|
485
|
+
# First, try to get a nice-looking name for this exception type.
|
486
|
+
exc_name = getattr(exc_type, '__name__', None)
|
487
|
+
if not exc_name:
|
488
|
+
# either it's a string exception or a user-defined exception class
|
489
|
+
# show string or fully-qualified class name
|
490
|
+
exc_name = utils.safestr(exc_type)
|
491
|
+
|
492
|
+
# Print a traceback, unless this is an ImportError. ImportError is
|
493
|
+
# presumably the most common import-time exception, so this saves
|
494
|
+
# the clutter of a traceback most of the time. Also, the locus of
|
495
|
+
# the error is usually irrelevant for ImportError, so the lack of
|
496
|
+
# traceback shouldn't be a problem.
|
497
|
+
if exc_type is SyntaxError:
|
498
|
+
# SyntaxErrors are special, we want to control how we format
|
499
|
+
# the output and make it consistent for all versions of Python
|
500
|
+
e = exc_value
|
501
|
+
msg = '%s (%s, line %d)' % (e.msg, e.filename, e.lineno)
|
502
|
+
line = _getLineInFile(moduleName, moduleDir, e.lineno)
|
503
|
+
offset = e.offset
|
504
|
+
if type(offset) is not types.IntType:
|
505
|
+
offset = 0
|
506
|
+
exc_value = '%s\n %s\n %s^' % (msg, line, ' ' * offset)
|
507
|
+
elif exc_type is not ImportError:
|
508
|
+
sys.stderr.write(" Caught exception importing module %s:\n" %
|
509
|
+
moduleName)
|
510
|
+
|
511
|
+
try:
|
512
|
+
tbinfo = traceback.extract_tb(tb)
|
513
|
+
except:
|
514
|
+
tbinfo = []
|
515
|
+
sys.stderr.write(" Unable to format traceback\n")
|
516
|
+
for filename, line, func, text in tbinfo[1:]:
|
517
|
+
sys.stderr.write(" File \"%s\", line %d" % (filename, line))
|
518
|
+
if func != "?":
|
519
|
+
sys.stderr.write(", in %s()" % func)
|
520
|
+
sys.stderr.write("\n")
|
521
|
+
if text:
|
522
|
+
sys.stderr.write(" %s\n" % text)
|
523
|
+
|
524
|
+
# And finally print the exception type and value.
|
525
|
+
# Careful formatting exc_value -- can fail for some user exceptions
|
526
|
+
sys.stderr.write(" %s: " % exc_name)
|
527
|
+
try:
|
528
|
+
sys.stderr.write(utils.safestr(exc_value) + '\n')
|
529
|
+
except:
|
530
|
+
sys.stderr.write('**error formatting exception value**\n')
|
531
|
+
|
532
|
+
|
533
|
+
def _getPyFile(filename):
|
534
|
+
"""Return the file and '.py' filename from a filename which could
|
535
|
+
end with .py, .pyc, or .pyo"""
|
536
|
+
|
537
|
+
if filename[-1] in 'oc' and filename[-4:-1] == '.py':
|
538
|
+
return filename[:-1]
|
539
|
+
return filename
|
540
|
+
|
541
|
+
class PyCheckerModule :
|
542
|
+
"Class to hold all information for a module"
|
543
|
+
|
544
|
+
def __init__(self, moduleName, check = 1, moduleDir=None) :
|
545
|
+
"""
|
546
|
+
@param moduleDir: if specified, the directory where the module can
|
547
|
+
be loaded from; allows discerning between modules
|
548
|
+
with the same name in a different directory
|
549
|
+
|
550
|
+
"""
|
551
|
+
self.moduleName = moduleName
|
552
|
+
self.moduleDir = moduleDir
|
553
|
+
self.variables = {}
|
554
|
+
self.functions = {}
|
555
|
+
self.classes = {}
|
556
|
+
self.modules = {}
|
557
|
+
self.moduleLineNums = {}
|
558
|
+
self.attributes = [ '__dict__' ]
|
559
|
+
self.main_code = None
|
560
|
+
self.module = None
|
561
|
+
self.check = check
|
562
|
+
# key on a combination of moduleName and moduleDir so we have separate
|
563
|
+
# entries for modules with the same name but in different directories
|
564
|
+
pcmodules.addPCModule(self)
|
565
|
+
|
566
|
+
def __str__(self) :
|
567
|
+
return self.moduleName
|
568
|
+
|
569
|
+
__repr__ = utils.std_repr
|
570
|
+
|
571
|
+
def addVariable(self, var, varType) :
|
572
|
+
self.variables[var] = Variable(var, varType)
|
573
|
+
|
574
|
+
def addFunction(self, func) :
|
575
|
+
self.functions[func.__name__] = function.Function(func)
|
576
|
+
|
577
|
+
def __addAttributes(self, c, classObject) :
|
578
|
+
for base in getattr(classObject, '__bases__', None) or ():
|
579
|
+
self.__addAttributes(c, base)
|
580
|
+
c.addMethods(classObject)
|
581
|
+
c.addMembers(classObject)
|
582
|
+
|
583
|
+
def addClass(self, name) :
|
584
|
+
self.classes[name] = c = Class(name, self)
|
585
|
+
try:
|
586
|
+
objName = utils.safestr(c.classObject)
|
587
|
+
except TypeError:
|
588
|
+
# this can happen if there is a goofy __getattr__
|
589
|
+
c.ignoreAttrs = 1
|
590
|
+
else:
|
591
|
+
packages = string.split(objName, '.')
|
592
|
+
c.ignoreAttrs = packages[0] in cfg().blacklist
|
593
|
+
if not c.ignoreAttrs :
|
594
|
+
self.__addAttributes(c, c.classObject)
|
595
|
+
|
596
|
+
def addModule(self, name, moduleDir=None) :
|
597
|
+
module = pcmodules.getPCModule(name, moduleDir)
|
598
|
+
if module is None :
|
599
|
+
self.modules[name] = module = PyCheckerModule(name, 0)
|
600
|
+
if imp.is_builtin(name) == 0:
|
601
|
+
module.load()
|
602
|
+
else :
|
603
|
+
globalModule = globals().get(name)
|
604
|
+
if globalModule :
|
605
|
+
module.attributes.extend(dir(globalModule))
|
606
|
+
else :
|
607
|
+
self.modules[name] = module
|
608
|
+
|
609
|
+
def filename(self) :
|
610
|
+
try :
|
611
|
+
filename = self.module.__file__
|
612
|
+
except AttributeError :
|
613
|
+
filename = self.moduleName
|
614
|
+
# FIXME: this would be nice to have, but changes output of
|
615
|
+
# NOT PROCESSED UNABLE TO IMPORT like in test8
|
616
|
+
#if self.moduleDir:
|
617
|
+
# filename = self.moduleDir + ': ' + filename
|
618
|
+
|
619
|
+
return _getPyFile(filename)
|
620
|
+
|
621
|
+
def load(self):
|
622
|
+
try :
|
623
|
+
# there's no need to reload modules we already have if no moduleDir
|
624
|
+
# is specified for this module
|
625
|
+
if not self.moduleDir:
|
626
|
+
module = sys.modules.get(self.moduleName)
|
627
|
+
if module :
|
628
|
+
if not pcmodules.getPCModule(self.moduleName).module :
|
629
|
+
return self._initModule(module)
|
630
|
+
return 1
|
631
|
+
|
632
|
+
return self._initModule(self.setupMainCode())
|
633
|
+
except (SystemExit, KeyboardInterrupt) :
|
634
|
+
exc_type, exc_value, exc_tb = sys.exc_info()
|
635
|
+
raise exc_type, exc_value
|
636
|
+
except :
|
637
|
+
importError(self.moduleName, self.moduleDir)
|
638
|
+
return cfg().ignoreImportErrors
|
639
|
+
|
640
|
+
def initModule(self, module) :
|
641
|
+
if not self.module:
|
642
|
+
filename = _getPyFile(module.__file__)
|
643
|
+
if string.lower(filename[-3:]) == '.py':
|
644
|
+
try:
|
645
|
+
file = open(filename)
|
646
|
+
except IOError:
|
647
|
+
pass
|
648
|
+
else:
|
649
|
+
self._setupMainCode(file, filename, module)
|
650
|
+
return self._initModule(module)
|
651
|
+
return 1
|
652
|
+
|
653
|
+
def _initModule(self, module):
|
654
|
+
self.module = module
|
655
|
+
self.attributes = dir(self.module)
|
656
|
+
|
657
|
+
pychecker_attr = getattr(module, Config.CHECKER_VAR, None)
|
658
|
+
if pychecker_attr is not None :
|
659
|
+
utils.pushConfig()
|
660
|
+
utils.updateCheckerArgs(pychecker_attr, 'suppressions', 0, [])
|
661
|
+
|
662
|
+
for tokenName in _filterDir(self.module, _DEFAULT_MODULE_TOKENS) :
|
663
|
+
if _EVIL_C_OBJECTS.has_key('%s.%s' % (self.moduleName, tokenName)):
|
664
|
+
continue
|
665
|
+
|
666
|
+
# README if interpreter is crashing:
|
667
|
+
# Change 0 to 1 if the interpretter is crashing and re-run.
|
668
|
+
# Follow the instructions from the last line printed.
|
669
|
+
if _cfg.findEvil:
|
670
|
+
print "Add the following line to _EVIL_C_OBJECTS or the string to evil in a config file:\n" \
|
671
|
+
" '%s.%s': None, " % (self.moduleName, tokenName)
|
672
|
+
|
673
|
+
token = getattr(self.module, tokenName)
|
674
|
+
if isinstance(token, types.ModuleType) :
|
675
|
+
# get the real module name, tokenName could be an alias
|
676
|
+
self.addModule(token.__name__)
|
677
|
+
elif isinstance(token, types.FunctionType) :
|
678
|
+
self.addFunction(token)
|
679
|
+
elif isinstance(token, types.ClassType) or \
|
680
|
+
hasattr(token, '__bases__') and \
|
681
|
+
issubclass(type(token), type):
|
682
|
+
self.addClass(tokenName)
|
683
|
+
else :
|
684
|
+
self.addVariable(tokenName, type(token))
|
685
|
+
|
686
|
+
if pychecker_attr is not None :
|
687
|
+
utils.popConfig()
|
688
|
+
return 1
|
689
|
+
|
690
|
+
def setupMainCode(self) :
|
691
|
+
file, filename, smt = _findModule(self.moduleName, self.moduleDir)
|
692
|
+
# FIXME: if the smt[-1] == imp.PKG_DIRECTORY : load __all__
|
693
|
+
# HACK: to make sibling imports work, we add self.moduleDir to sys.path
|
694
|
+
# temporarily, and remove it later
|
695
|
+
if self.moduleDir:
|
696
|
+
oldsyspath = sys.path[:]
|
697
|
+
sys.path.insert(0, self.moduleDir)
|
698
|
+
module = imp.load_module(self.moduleName, file, filename, smt)
|
699
|
+
if self.moduleDir:
|
700
|
+
sys.path = oldsyspath
|
701
|
+
# to make sure that subsequent modules with the same moduleName
|
702
|
+
# do not persist, and get their namespace clobbered, delete it
|
703
|
+
del sys.modules[self.moduleName]
|
704
|
+
|
705
|
+
self._setupMainCode(file, filename, module)
|
706
|
+
return module
|
707
|
+
|
708
|
+
def _setupMainCode(self, file, filename, module):
|
709
|
+
try :
|
710
|
+
self.main_code = function.create_from_file(file, filename, module)
|
711
|
+
finally :
|
712
|
+
if file != None :
|
713
|
+
file.close()
|
714
|
+
|
715
|
+
|
716
|
+
def getAllModules() :
|
717
|
+
"Returns a list of all modules that should be checked."
|
718
|
+
modules = []
|
719
|
+
for module in pcmodules.getPCModules():
|
720
|
+
if module.check :
|
721
|
+
modules.append(module)
|
722
|
+
return modules
|
723
|
+
|
724
|
+
_BUILTIN_MODULE_ATTRS = { 'sys': [ 'ps1', 'ps2', 'tracebacklimit',
|
725
|
+
'exc_type', 'exc_value', 'exc_traceback',
|
726
|
+
'last_type', 'last_value', 'last_traceback',
|
727
|
+
],
|
728
|
+
}
|
729
|
+
|
730
|
+
def fixupBuiltinModules(needs_init=0):
|
731
|
+
for moduleName in sys.builtin_module_names :
|
732
|
+
# Skip sys since it will reset sys.stdout in IDLE and cause
|
733
|
+
# stdout to go to the real console rather than the IDLE console.
|
734
|
+
# FIXME: this breaks test42
|
735
|
+
# if moduleName == 'sys':
|
736
|
+
# continue
|
737
|
+
|
738
|
+
if needs_init:
|
739
|
+
_ = PyCheckerModule(moduleName, 0)
|
740
|
+
# builtin modules don't have a moduleDir
|
741
|
+
module = pcmodules.getPCModule(moduleName)
|
742
|
+
if module is not None :
|
743
|
+
try :
|
744
|
+
m = imp.init_builtin(moduleName)
|
745
|
+
except ImportError :
|
746
|
+
pass
|
747
|
+
else :
|
748
|
+
extra_attrs = _BUILTIN_MODULE_ATTRS.get(moduleName, [])
|
749
|
+
module.attributes = [ '__dict__' ] + dir(m) + extra_attrs
|
750
|
+
|
751
|
+
|
752
|
+
def _printWarnings(warnings, stream=None):
|
753
|
+
if stream is None:
|
754
|
+
stream = sys.stdout
|
755
|
+
|
756
|
+
warnings.sort()
|
757
|
+
lastWarning = None
|
758
|
+
for warning in warnings :
|
759
|
+
if lastWarning is not None:
|
760
|
+
# ignore duplicate warnings
|
761
|
+
if cmp(lastWarning, warning) == 0:
|
762
|
+
continue
|
763
|
+
# print blank line between files
|
764
|
+
if lastWarning.file != warning.file:
|
765
|
+
stream.write("\n")
|
766
|
+
|
767
|
+
lastWarning = warning
|
768
|
+
warning.output(stream)
|
769
|
+
|
770
|
+
|
771
|
+
class NullModule:
|
772
|
+
def __getattr__(self, unused_attr):
|
773
|
+
return None
|
774
|
+
|
775
|
+
def install_ignore__import__():
|
776
|
+
|
777
|
+
_orig__import__ = None
|
778
|
+
|
779
|
+
def __import__(name, globals=None, locals=None, fromlist=None):
|
780
|
+
if globals is None:
|
781
|
+
globals = {}
|
782
|
+
if locals is None:
|
783
|
+
locals = {}
|
784
|
+
if fromlist is None:
|
785
|
+
fromlist = ()
|
786
|
+
|
787
|
+
try:
|
788
|
+
pymodule = _orig__import__(name, globals, locals, fromlist)
|
789
|
+
except ImportError:
|
790
|
+
pymodule = NullModule()
|
791
|
+
if not _cfg.quiet:
|
792
|
+
modname = '.'.join((name,) + fromlist)
|
793
|
+
sys.stderr.write("Can't import module: %s, ignoring.\n" % modname)
|
794
|
+
return pymodule
|
795
|
+
|
796
|
+
# keep the orig __import__ around so we can call it
|
797
|
+
import __builtin__
|
798
|
+
_orig__import__ = __builtin__.__import__
|
799
|
+
__builtin__.__import__ = __import__
|
800
|
+
|
801
|
+
def processFiles(files, cfg = None, pre_process_cb = None) :
|
802
|
+
# insert this here, so we find files in the local dir before std library
|
803
|
+
if sys.path[0] != '' :
|
804
|
+
sys.path.insert(0, '')
|
805
|
+
|
806
|
+
# ensure we have a config object, it's necessary
|
807
|
+
global _cfg
|
808
|
+
if cfg is not None :
|
809
|
+
_cfg = cfg
|
810
|
+
elif _cfg is None :
|
811
|
+
_cfg = Config.Config()
|
812
|
+
|
813
|
+
if _cfg.ignoreImportErrors:
|
814
|
+
install_ignore__import__()
|
815
|
+
|
816
|
+
warnings = []
|
817
|
+
utils.initConfig(_cfg)
|
818
|
+
for file, (moduleName, moduleDir) in zip(files, getModules(files)) :
|
819
|
+
if callable(pre_process_cb) :
|
820
|
+
pre_process_cb("module %s (%s)" % (moduleName, file))
|
821
|
+
oldsyspath = sys.path[:]
|
822
|
+
sys.path.insert(0, moduleDir)
|
823
|
+
module = PyCheckerModule(moduleName, moduleDir=moduleDir)
|
824
|
+
if not module.load() :
|
825
|
+
w = Warning(module.filename(), 1,
|
826
|
+
msgs.Internal("NOT PROCESSED UNABLE TO IMPORT"))
|
827
|
+
warnings.append(w)
|
828
|
+
sys.path = oldsyspath
|
829
|
+
utils.popConfig()
|
830
|
+
return warnings
|
831
|
+
|
832
|
+
|
833
|
+
def getWarnings(files, cfg = None, suppressions = None):
|
834
|
+
warnings = processFiles(files, cfg)
|
835
|
+
fixupBuiltinModules()
|
836
|
+
return warnings + warn.find(getAllModules(), _cfg, suppressions)
|
837
|
+
|
838
|
+
|
839
|
+
def _print_processing(name) :
|
840
|
+
if not _cfg.quiet :
|
841
|
+
sys.stderr.write("Processing %s...\n" % name)
|
842
|
+
|
843
|
+
|
844
|
+
def main(argv) :
|
845
|
+
__pychecker__ = 'no-miximport'
|
846
|
+
import pychecker
|
847
|
+
if LOCAL_MAIN_VERSION != pychecker.MAIN_MODULE_VERSION :
|
848
|
+
sys.stderr.write(_VERSION_MISMATCH_ERROR)
|
849
|
+
sys.exit(100)
|
850
|
+
|
851
|
+
# remove empty arguments
|
852
|
+
argv = filter(None, argv)
|
853
|
+
|
854
|
+
# if the first arg starts with an @, read options from the file
|
855
|
+
# after the @ (this is mostly for windows)
|
856
|
+
if len(argv) >= 2 and argv[1][0] == '@':
|
857
|
+
# read data from the file
|
858
|
+
command_file = argv[1][1:]
|
859
|
+
try:
|
860
|
+
f = open(command_file, 'r')
|
861
|
+
command_line = f.read()
|
862
|
+
f.close()
|
863
|
+
except IOError, err:
|
864
|
+
sys.stderr.write("Unable to read commands from file: %s\n %s\n" % \
|
865
|
+
(command_file, err))
|
866
|
+
sys.exit(101)
|
867
|
+
|
868
|
+
# convert to an argv list, keeping argv[0] and the files to process
|
869
|
+
argv = argv[:1] + string.split(command_line) + argv[2:]
|
870
|
+
|
871
|
+
global _cfg
|
872
|
+
_cfg, files, suppressions = Config.setupFromArgs(argv[1:])
|
873
|
+
if not files :
|
874
|
+
return 0
|
875
|
+
|
876
|
+
# Now that we've got the args, update the list of evil C objects
|
877
|
+
for evil_doer in _cfg.evil:
|
878
|
+
_EVIL_C_OBJECTS[evil_doer] = None
|
879
|
+
|
880
|
+
# insert this here, so we find files in the local dir before std library
|
881
|
+
sys.path.insert(0, '')
|
882
|
+
|
883
|
+
importWarnings = processFiles(files, _cfg, _print_processing)
|
884
|
+
fixupBuiltinModules()
|
885
|
+
if _cfg.printParse :
|
886
|
+
for module in getAllModules() :
|
887
|
+
printer.module(module)
|
888
|
+
|
889
|
+
warnings = warn.find(getAllModules(), _cfg, suppressions)
|
890
|
+
if not _cfg.quiet :
|
891
|
+
print "\nWarnings...\n"
|
892
|
+
if warnings or importWarnings :
|
893
|
+
_printWarnings(importWarnings + warnings)
|
894
|
+
return 1
|
895
|
+
|
896
|
+
if not _cfg.quiet :
|
897
|
+
print "None"
|
898
|
+
return 0
|
899
|
+
|
900
|
+
|
901
|
+
if __name__ == '__main__' :
|
902
|
+
try :
|
903
|
+
sys.exit(main(sys.argv))
|
904
|
+
except Config.UsageError :
|
905
|
+
sys.exit(127)
|
906
|
+
|
907
|
+
else :
|
908
|
+
_orig__import__ = None
|
909
|
+
_suppressions = None
|
910
|
+
_warnings_cache = {}
|
911
|
+
|
912
|
+
def _get_unique_warnings(warnings):
|
913
|
+
for i in range(len(warnings)-1, -1, -1):
|
914
|
+
w = warnings[i].format()
|
915
|
+
if _warnings_cache.has_key(w):
|
916
|
+
del warnings[i]
|
917
|
+
else:
|
918
|
+
_warnings_cache[w] = 1
|
919
|
+
return warnings
|
920
|
+
|
921
|
+
def __import__(name, globals=None, locals=None, fromlist=None):
|
922
|
+
if globals is None:
|
923
|
+
globals = {}
|
924
|
+
if locals is None:
|
925
|
+
locals = {}
|
926
|
+
if fromlist is None:
|
927
|
+
fromlist = []
|
928
|
+
|
929
|
+
check = not sys.modules.has_key(name) and name[:10] != 'pychecker.'
|
930
|
+
pymodule = _orig__import__(name, globals, locals, fromlist)
|
931
|
+
if check :
|
932
|
+
try :
|
933
|
+
# FIXME: can we find a good moduleDir ?
|
934
|
+
module = PyCheckerModule(pymodule.__name__)
|
935
|
+
if module.initModule(pymodule):
|
936
|
+
warnings = warn.find([module], _cfg, _suppressions)
|
937
|
+
_printWarnings(_get_unique_warnings(warnings))
|
938
|
+
else :
|
939
|
+
print 'Unable to load module', pymodule.__name__
|
940
|
+
except Exception:
|
941
|
+
name = getattr(pymodule, '__name__', utils.safestr(pymodule))
|
942
|
+
# FIXME: can we use it here ?
|
943
|
+
importError(name)
|
944
|
+
|
945
|
+
return pymodule
|
946
|
+
|
947
|
+
def _init() :
|
948
|
+
global _cfg, _suppressions, _orig__import__
|
949
|
+
|
950
|
+
args = string.split(os.environ.get('PYCHECKER', ''))
|
951
|
+
_cfg, files, _suppressions = Config.setupFromArgs(args)
|
952
|
+
utils.initConfig(_cfg)
|
953
|
+
fixupBuiltinModules(1)
|
954
|
+
|
955
|
+
# keep the orig __import__ around so we can call it
|
956
|
+
import __builtin__
|
957
|
+
_orig__import__ = __builtin__.__import__
|
958
|
+
__builtin__.__import__ = __import__
|
959
|
+
|
960
|
+
if not os.environ.get('PYCHECKER_DISABLED') :
|
961
|
+
_init()
|