From e348a64fd79bdecdf7a1c8d482a4c404dde08b43 Mon Sep 17 00:00:00 2001 From: helionyeah Date: Tue, 8 Dec 2015 13:24:16 -0800 Subject: [PATCH 1/9] Create lastupdated.txt --- lastupdated.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 lastupdated.txt diff --git a/lastupdated.txt b/lastupdated.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/lastupdated.txt @@ -0,0 +1 @@ + From 2d84a038b814bce5b4104d006b7ae241515eca83 Mon Sep 17 00:00:00 2001 From: Gregory Arcara Date: Fri, 11 Dec 2015 10:54:57 -0800 Subject: [PATCH 2/9] Adding Tests --- .eggs/README.txt | 6 + .eggs/nose-1.3.7-py2.7.egg/EGG-INFO/PKG-INFO | 38 + .../nose-1.3.7-py2.7.egg/EGG-INFO/SOURCES.txt | 432 ++++ .../EGG-INFO/dependency_links.txt | 1 + .../EGG-INFO/entry_points.txt | 7 + .../EGG-INFO/not-zip-safe | 1 + .../EGG-INFO/top_level.txt | 1 + .../nose-1.3.7-py2.7.egg/man/man1/nosetests.1 | 581 +++++ .eggs/nose-1.3.7-py2.7.egg/nose/__init__.py | 15 + .eggs/nose-1.3.7-py2.7.egg/nose/__init__.pyc | Bin 0 -> 721 bytes .eggs/nose-1.3.7-py2.7.egg/nose/__main__.py | 8 + .eggs/nose-1.3.7-py2.7.egg/nose/__main__.pyc | Bin 0 -> 379 bytes .eggs/nose-1.3.7-py2.7.egg/nose/case.py | 397 +++ .eggs/nose-1.3.7-py2.7.egg/nose/case.pyc | Bin 0 -> 15701 bytes .eggs/nose-1.3.7-py2.7.egg/nose/commands.py | 172 ++ .eggs/nose-1.3.7-py2.7.egg/nose/commands.pyc | Bin 0 -> 6262 bytes .eggs/nose-1.3.7-py2.7.egg/nose/config.py | 661 +++++ .eggs/nose-1.3.7-py2.7.egg/nose/config.pyc | Bin 0 -> 24852 bytes .eggs/nose-1.3.7-py2.7.egg/nose/core.py | 341 +++ .eggs/nose-1.3.7-py2.7.egg/nose/core.pyc | Bin 0 -> 13791 bytes .eggs/nose-1.3.7-py2.7.egg/nose/exc.py | 9 + .eggs/nose-1.3.7-py2.7.egg/nose/exc.pyc | Bin 0 -> 608 bytes .../nose-1.3.7-py2.7.egg/nose/ext/__init__.py | 3 + .../nose/ext/__init__.pyc | Bin 0 -> 221 bytes .../nose-1.3.7-py2.7.egg/nose/ext/dtcompat.py | 2272 +++++++++++++++++ .../nose/ext/dtcompat.pyc | Bin 0 -> 72902 bytes .eggs/nose-1.3.7-py2.7.egg/nose/failure.py | 42 + .eggs/nose-1.3.7-py2.7.egg/nose/failure.pyc | Bin 0 -> 2110 bytes .eggs/nose-1.3.7-py2.7.egg/nose/importer.py | 167 ++ .eggs/nose-1.3.7-py2.7.egg/nose/importer.pyc | Bin 0 -> 5898 bytes .eggs/nose-1.3.7-py2.7.egg/nose/inspector.py | 207 ++ .eggs/nose-1.3.7-py2.7.egg/nose/inspector.pyc | Bin 0 -> 6164 bytes .eggs/nose-1.3.7-py2.7.egg/nose/loader.py | 623 +++++ .eggs/nose-1.3.7-py2.7.egg/nose/loader.pyc | Bin 0 -> 19273 bytes .../nose/plugins/__init__.py | 190 ++ .../nose/plugins/__init__.pyc | Bin 0 -> 6573 bytes .../nose/plugins/allmodules.py | 45 + .../nose/plugins/allmodules.pyc | Bin 0 -> 2535 bytes .../nose/plugins/attrib.py | 286 +++ .../nose/plugins/attrib.pyc | Bin 0 -> 9631 bytes .../nose-1.3.7-py2.7.egg/nose/plugins/base.py | 725 ++++++ .../nose/plugins/base.pyc | Bin 0 -> 33513 bytes .../nose/plugins/builtin.py | 34 + .../nose/plugins/builtin.pyc | Bin 0 -> 1813 bytes .../nose/plugins/capture.py | 115 + .../nose/plugins/capture.pyc | Bin 0 -> 5532 bytes .../nose/plugins/collect.py | 94 + .../nose/plugins/collect.pyc | Bin 0 -> 4806 bytes .../nose/plugins/cover.py | 271 ++ .../nose/plugins/cover.pyc | Bin 0 -> 9900 bytes .../nose/plugins/debug.py | 67 + .../nose/plugins/debug.pyc | Bin 0 -> 3103 bytes .../nose/plugins/deprecated.py | 45 + .../nose/plugins/deprecated.pyc | Bin 0 -> 2410 bytes .../nose/plugins/doctests.py | 455 ++++ .../nose/plugins/doctests.pyc | Bin 0 -> 18296 bytes .../nose/plugins/errorclass.py | 210 ++ .../nose/plugins/errorclass.pyc | Bin 0 -> 9483 bytes .../nose/plugins/failuredetail.py | 49 + .../nose/plugins/failuredetail.pyc | Bin 0 -> 2507 bytes .../nose/plugins/isolate.py | 103 + .../nose/plugins/isolate.pyc | Bin 0 -> 5012 bytes .../nose/plugins/logcapture.py | 245 ++ .../nose/plugins/logcapture.pyc | Bin 0 -> 12255 bytes .../nose/plugins/manager.py | 460 ++++ .../nose/plugins/manager.pyc | Bin 0 -> 21527 bytes .../nose/plugins/multiprocess.py | 835 ++++++ .../nose/plugins/multiprocess.pyc | Bin 0 -> 28589 bytes .../nose/plugins/plugintest.py | 416 +++ .../nose/plugins/plugintest.pyc | Bin 0 -> 16682 bytes .../nose-1.3.7-py2.7.egg/nose/plugins/prof.py | 154 ++ .../nose/plugins/prof.pyc | Bin 0 -> 5760 bytes .../nose-1.3.7-py2.7.egg/nose/plugins/skip.py | 63 + .../nose/plugins/skip.pyc | Bin 0 -> 2697 bytes .../nose/plugins/testid.py | 311 +++ .../nose/plugins/testid.pyc | Bin 0 -> 9602 bytes .../nose/plugins/xunit.py | 341 +++ .../nose/plugins/xunit.pyc | Bin 0 -> 14566 bytes .eggs/nose-1.3.7-py2.7.egg/nose/proxy.py | 188 ++ .eggs/nose-1.3.7-py2.7.egg/nose/proxy.pyc | Bin 0 -> 8780 bytes .eggs/nose-1.3.7-py2.7.egg/nose/pyversion.py | 215 ++ .eggs/nose-1.3.7-py2.7.egg/nose/pyversion.pyc | Bin 0 -> 10195 bytes .eggs/nose-1.3.7-py2.7.egg/nose/result.py | 200 ++ .eggs/nose-1.3.7-py2.7.egg/nose/result.pyc | Bin 0 -> 7254 bytes .eggs/nose-1.3.7-py2.7.egg/nose/selector.py | 251 ++ .eggs/nose-1.3.7-py2.7.egg/nose/selector.pyc | Bin 0 -> 9445 bytes .../nose/sphinx/__init__.py | 1 + .../nose/sphinx/__init__.pyc | Bin 0 -> 175 bytes .../nose/sphinx/pluginopts.py | 189 ++ .../nose/sphinx/pluginopts.pyc | Bin 0 -> 7073 bytes .eggs/nose-1.3.7-py2.7.egg/nose/suite.py | 609 +++++ .eggs/nose-1.3.7-py2.7.egg/nose/suite.pyc | Bin 0 -> 23272 bytes .../nose/tools/__init__.py | 15 + .../nose/tools/__init__.pyc | Bin 0 -> 597 bytes .../nose/tools/nontrivial.py | 151 ++ .../nose/tools/nontrivial.pyc | Bin 0 -> 6212 bytes .../nose/tools/trivial.py | 54 + .../nose/tools/trivial.pyc | Bin 0 -> 2354 bytes .../nose-1.3.7-py2.7.egg/nose/twistedtools.py | 173 ++ .../nose/twistedtools.pyc | Bin 0 -> 6510 bytes .eggs/nose-1.3.7-py2.7.egg/nose/usage.txt | 115 + .eggs/nose-1.3.7-py2.7.egg/nose/util.py | 668 +++++ .eggs/nose-1.3.7-py2.7.egg/nose/util.pyc | Bin 0 -> 22456 bytes python_env.egg-info/PKG-INFO | 18 + python_env.egg-info/SOURCES.txt | 6 + python_env.egg-info/dependency_links.txt | 1 + python_env.egg-info/requires.txt | 2 + python_env.egg-info/top_level.txt | 1 + tests/tests.py | 20 + tests/tests.pyc | Bin 0 -> 1248 bytes 110 files changed, 14375 insertions(+) create mode 100644 .eggs/README.txt create mode 100644 .eggs/nose-1.3.7-py2.7.egg/EGG-INFO/PKG-INFO create mode 100644 .eggs/nose-1.3.7-py2.7.egg/EGG-INFO/SOURCES.txt create mode 100644 .eggs/nose-1.3.7-py2.7.egg/EGG-INFO/dependency_links.txt create mode 100644 .eggs/nose-1.3.7-py2.7.egg/EGG-INFO/entry_points.txt create mode 100644 .eggs/nose-1.3.7-py2.7.egg/EGG-INFO/not-zip-safe create mode 100644 .eggs/nose-1.3.7-py2.7.egg/EGG-INFO/top_level.txt create mode 100644 .eggs/nose-1.3.7-py2.7.egg/man/man1/nosetests.1 create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/__init__.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/__init__.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/__main__.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/__main__.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/case.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/case.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/commands.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/commands.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/config.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/config.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/core.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/core.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/exc.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/exc.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/ext/__init__.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/ext/__init__.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/ext/dtcompat.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/ext/dtcompat.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/failure.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/failure.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/importer.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/importer.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/inspector.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/inspector.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/loader.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/loader.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/__init__.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/__init__.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/allmodules.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/allmodules.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/attrib.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/attrib.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/base.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/base.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/builtin.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/builtin.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/capture.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/capture.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/collect.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/collect.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/cover.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/cover.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/debug.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/debug.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/deprecated.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/deprecated.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/doctests.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/doctests.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/errorclass.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/errorclass.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/failuredetail.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/failuredetail.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/isolate.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/isolate.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/logcapture.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/logcapture.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/manager.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/manager.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/multiprocess.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/multiprocess.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/plugintest.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/plugintest.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/prof.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/prof.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/skip.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/skip.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/testid.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/testid.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/xunit.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/plugins/xunit.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/proxy.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/proxy.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/pyversion.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/pyversion.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/result.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/result.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/selector.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/selector.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/sphinx/__init__.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/sphinx/__init__.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/sphinx/pluginopts.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/sphinx/pluginopts.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/suite.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/suite.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/tools/__init__.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/tools/__init__.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/tools/nontrivial.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/tools/nontrivial.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/tools/trivial.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/tools/trivial.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/twistedtools.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/twistedtools.pyc create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/usage.txt create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/util.py create mode 100644 .eggs/nose-1.3.7-py2.7.egg/nose/util.pyc create mode 100644 python_env.egg-info/PKG-INFO create mode 100644 python_env.egg-info/SOURCES.txt create mode 100644 python_env.egg-info/dependency_links.txt create mode 100644 python_env.egg-info/requires.txt create mode 100644 python_env.egg-info/top_level.txt create mode 100644 tests/tests.py create mode 100644 tests/tests.pyc diff --git a/.eggs/README.txt b/.eggs/README.txt new file mode 100644 index 0000000..5d01668 --- /dev/null +++ b/.eggs/README.txt @@ -0,0 +1,6 @@ +This directory contains eggs that were downloaded by setuptools to build, test, and run plug-ins. + +This directory caches those eggs to prevent repeated downloads. + +However, it is safe to delete this directory. + diff --git a/.eggs/nose-1.3.7-py2.7.egg/EGG-INFO/PKG-INFO b/.eggs/nose-1.3.7-py2.7.egg/EGG-INFO/PKG-INFO new file mode 100644 index 0000000..112ec15 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/EGG-INFO/PKG-INFO @@ -0,0 +1,38 @@ +Metadata-Version: 1.1 +Name: nose +Version: 1.3.7 +Summary: nose extends unittest to make testing easier +Home-page: http://readthedocs.org/docs/nose/ +Author: Jason Pellerin +Author-email: jpellerin+nose@gmail.com +License: GNU LGPL +Description: nose extends the test loading and running features of unittest, making + it easier to write, find and run tests. + + By default, nose will run tests in files or directories under the current + working directory whose names include "test" or "Test" at a word boundary + (like "test_this" or "functional_test" or "TestClass" but not + "libtest"). Test output is similar to that of unittest, but also includes + captured stdout output from failing tests, for easy print-style debugging. + + These features, and many more, are customizable through the use of + plugins. Plugins included with nose provide support for doctest, code + coverage and profiling, flexible attribute-based test selection, + output capture and more. More information about writing plugins may be + found on in the nose API documentation, here: + http://readthedocs.org/docs/nose/ + + If you have recently reported a bug marked as fixed, or have a craving for + the very latest, you may want the development version instead: + https://github.com/nose-devs/nose/tarball/master#egg=nose-dev + +Keywords: test unittest doctest automatic discovery +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL) +Classifier: Natural Language :: English +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Topic :: Software Development :: Testing diff --git a/.eggs/nose-1.3.7-py2.7.egg/EGG-INFO/SOURCES.txt b/.eggs/nose-1.3.7-py2.7.egg/EGG-INFO/SOURCES.txt new file mode 100644 index 0000000..df3120f --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/EGG-INFO/SOURCES.txt @@ -0,0 +1,432 @@ +AUTHORS +CHANGELOG +MANIFEST.in +NEWS +README.txt +distribute_setup.py +install-rpm.sh +lgpl.txt +nosetests.1 +patch.py +selftest.py +setup.cfg +setup.py +setup3lib.py +bin/nosetests +doc/Makefile +doc/api.rst +doc/conf.py +doc/contributing.rst +doc/developing.rst +doc/docstring.py +doc/finding_tests.rst +doc/further_reading.rst +doc/index.html +doc/index.rst +doc/man.rst +doc/more_info.rst +doc/news.rst +doc/plugins.rst +doc/rtd-requirements.txt +doc/setuptools_integration.rst +doc/testing.rst +doc/testing_tools.rst +doc/usage.rst +doc/writing_tests.rst +doc/.static/nose.css +doc/.templates/index.html +doc/.templates/indexsidebar.html +doc/.templates/layout.html +doc/.templates/page.html +doc/api/commands.rst +doc/api/config.rst +doc/api/core.rst +doc/api/importer.rst +doc/api/inspector.rst +doc/api/loader.rst +doc/api/plugin_manager.rst +doc/api/proxy.rst +doc/api/result.rst +doc/api/selector.rst +doc/api/suite.rst +doc/api/test_cases.rst +doc/api/twistedtools.rst +doc/api/util.rst +doc/plugins/allmodules.rst +doc/plugins/attrib.rst +doc/plugins/builtin.rst +doc/plugins/capture.rst +doc/plugins/collect.rst +doc/plugins/cover.rst +doc/plugins/debug.rst +doc/plugins/deprecated.rst +doc/plugins/doctests.rst +doc/plugins/documenting.rst +doc/plugins/errorclasses.rst +doc/plugins/failuredetail.rst +doc/plugins/interface.rst +doc/plugins/isolate.rst +doc/plugins/logcapture.rst +doc/plugins/multiprocess.rst +doc/plugins/other.rst +doc/plugins/prof.rst +doc/plugins/skip.rst +doc/plugins/testid.rst +doc/plugins/testing.rst +doc/plugins/writing.rst +doc/plugins/xunit.rst +examples/attrib_plugin.py +examples/html_plugin/htmlplug.py +examples/html_plugin/setup.py +examples/plugin/plug.py +examples/plugin/setup.py +functional_tests/nosetests.xml +functional_tests/test_attribute_plugin.py +functional_tests/test_buggy_generators.py +functional_tests/test_cases.py +functional_tests/test_collector.py +functional_tests/test_commands.py +functional_tests/test_config_files.py +functional_tests/test_coverage_plugin.py +functional_tests/test_defaultpluginmanager.py +functional_tests/test_doctest_plugin.py +functional_tests/test_entrypoints.py +functional_tests/test_failure.py +functional_tests/test_failuredetail_plugin.py +functional_tests/test_generator_fixtures.py +functional_tests/test_id_plugin.py +functional_tests/test_importer.py +functional_tests/test_isolate_plugin.py +functional_tests/test_issue_072.py +functional_tests/test_issue_082.py +functional_tests/test_issue_408.py +functional_tests/test_issue_649.py +functional_tests/test_load_tests_from_test_case.py +functional_tests/test_loader.py +functional_tests/test_namespace_pkg.py +functional_tests/test_plugin_api.py +functional_tests/test_plugins.py +functional_tests/test_plugintest.py +functional_tests/test_program.py +functional_tests/test_result.py +functional_tests/test_selector.py +functional_tests/test_skip_pdb_interaction.py +functional_tests/test_string_exception.py +functional_tests/test_success.py +functional_tests/test_suite.py +functional_tests/test_withid_failures.rst +functional_tests/test_xunit.py +functional_tests/doc_tests/test_addplugins/test_addplugins.rst +functional_tests/doc_tests/test_addplugins/support/test.py +functional_tests/doc_tests/test_allmodules/test_allmodules.rst +functional_tests/doc_tests/test_allmodules/support/mod.py +functional_tests/doc_tests/test_allmodules/support/test.py +functional_tests/doc_tests/test_doctest_fixtures/doctest_fixtures.rst +functional_tests/doc_tests/test_doctest_fixtures/doctest_fixtures_fixtures.py +functional_tests/doc_tests/test_init_plugin/example.cfg +functional_tests/doc_tests/test_init_plugin/init_plugin.rst +functional_tests/doc_tests/test_init_plugin/init_plugin.rst.py3.patch +functional_tests/doc_tests/test_issue089/unwanted_package.rst +functional_tests/doc_tests/test_issue089/support/unwanted_package/__init__.py +functional_tests/doc_tests/test_issue089/support/unwanted_package/test_spam.py +functional_tests/doc_tests/test_issue089/support/wanted_package/__init__.py +functional_tests/doc_tests/test_issue089/support/wanted_package/test_eggs.py +functional_tests/doc_tests/test_issue097/plugintest_environment.rst +functional_tests/doc_tests/test_issue107/plugin_exceptions.rst +functional_tests/doc_tests/test_issue107/support/test_spam.py +functional_tests/doc_tests/test_issue119/empty_plugin.rst +functional_tests/doc_tests/test_issue119/test_zeronine.py +functional_tests/doc_tests/test_issue142/errorclass_failure.rst +functional_tests/doc_tests/test_issue142/support/errorclass_failing_test.py +functional_tests/doc_tests/test_issue142/support/errorclass_failure_plugin.py +functional_tests/doc_tests/test_issue142/support/errorclass_tests.py +functional_tests/doc_tests/test_issue145/imported_tests.rst +functional_tests/doc_tests/test_issue145/support/package1/__init__.py +functional_tests/doc_tests/test_issue145/support/package1/test_module.py +functional_tests/doc_tests/test_issue145/support/package2c/__init__.py +functional_tests/doc_tests/test_issue145/support/package2c/test_module.py +functional_tests/doc_tests/test_issue145/support/package2f/__init__.py +functional_tests/doc_tests/test_issue145/support/package2f/test_module.py +functional_tests/doc_tests/test_multiprocess/multiprocess.rst +functional_tests/doc_tests/test_multiprocess/multiprocess_fixtures.py +functional_tests/doc_tests/test_multiprocess/support/test_can_split.py +functional_tests/doc_tests/test_multiprocess/support/test_not_shared.py +functional_tests/doc_tests/test_multiprocess/support/test_shared.py +functional_tests/doc_tests/test_restricted_plugin_options/restricted_plugin_options.rst +functional_tests/doc_tests/test_restricted_plugin_options/restricted_plugin_options.rst.py3.patch +functional_tests/doc_tests/test_restricted_plugin_options/support/bad.cfg +functional_tests/doc_tests/test_restricted_plugin_options/support/start.cfg +functional_tests/doc_tests/test_restricted_plugin_options/support/test.py +functional_tests/doc_tests/test_selector_plugin/selector_plugin.rst +functional_tests/doc_tests/test_selector_plugin/support/mymodule.py +functional_tests/doc_tests/test_selector_plugin/support/mypackage/__init__.py +functional_tests/doc_tests/test_selector_plugin/support/mypackage/strings.py +functional_tests/doc_tests/test_selector_plugin/support/mypackage/math/__init__.py +functional_tests/doc_tests/test_selector_plugin/support/mypackage/math/basic.py +functional_tests/doc_tests/test_selector_plugin/support/tests/testlib.py +functional_tests/doc_tests/test_selector_plugin/support/tests/math/basic.py +functional_tests/doc_tests/test_selector_plugin/support/tests/mymodule/my_function.py +functional_tests/doc_tests/test_selector_plugin/support/tests/strings/cat.py +functional_tests/doc_tests/test_xunit_plugin/test_skips.rst +functional_tests/doc_tests/test_xunit_plugin/support/nosetests.xml +functional_tests/doc_tests/test_xunit_plugin/support/test_skip.py +functional_tests/support/test.cfg +functional_tests/support/test_buggy_generators.py +functional_tests/support/xunit.xml +functional_tests/support/att/test_attr.py +functional_tests/support/attrib-static/test.py +functional_tests/support/coverage/blah.py +functional_tests/support/coverage/tests/test_covered.py +functional_tests/support/coverage2/.coverage +functional_tests/support/coverage2/blah.py +functional_tests/support/coverage2/moo.py +functional_tests/support/coverage2/tests/test_covered.py +functional_tests/support/ctx/mod_import_skip.py +functional_tests/support/ctx/mod_setup_fails.py +functional_tests/support/ctx/mod_setup_skip.py +functional_tests/support/dir1/mod.py +functional_tests/support/dir1/pak/__init__.py +functional_tests/support/dir1/pak/mod.py +functional_tests/support/dir1/pak/sub/__init__.py +functional_tests/support/dir2/mod.py +functional_tests/support/dir2/pak/__init__.py +functional_tests/support/dir2/pak/mod.py +functional_tests/support/dir2/pak/sub/__init__.py +functional_tests/support/dir3/.hidden +functional_tests/support/dtt/some_mod.py +functional_tests/support/dtt/docs/doc.txt +functional_tests/support/dtt/docs/errdoc.txt +functional_tests/support/dtt/docs/nodoc.txt +functional_tests/support/empty/.hidden +functional_tests/support/ep/setup.py +functional_tests/support/ep/someplugin.py +functional_tests/support/ep/Some_plugin.egg-info/PKG-INFO +functional_tests/support/ep/Some_plugin.egg-info/SOURCES.txt +functional_tests/support/ep/Some_plugin.egg-info/dependency_links.txt +functional_tests/support/ep/Some_plugin.egg-info/entry_points.txt +functional_tests/support/ep/Some_plugin.egg-info/top_level.txt +functional_tests/support/fdp/test_fdp.py +functional_tests/support/fdp/test_fdp_no_capt.py +functional_tests/support/gen/test.py +functional_tests/support/id_fails/test_a.py +functional_tests/support/id_fails/test_b.py +functional_tests/support/idp/exm.py +functional_tests/support/idp/tests.py +functional_tests/support/ipt/test1/ipthelp.py +functional_tests/support/ipt/test1/tests.py +functional_tests/support/ipt/test2/ipthelp.py +functional_tests/support/ipt/test2/tests.py +functional_tests/support/issue038/test.py +functional_tests/support/issue072/test.py +functional_tests/support/issue082/_mypackage/__init__.py +functional_tests/support/issue082/_mypackage/_eggs.py +functional_tests/support/issue082/_mypackage/bacon.py +functional_tests/support/issue082/mypublicpackage/__init__.py +functional_tests/support/issue082/mypublicpackage/_foo.py +functional_tests/support/issue082/mypublicpackage/bar.py +functional_tests/support/issue130/test.py +functional_tests/support/issue134/test.py +functional_tests/support/issue143/not-a-package/__init__.py +functional_tests/support/issue143/not-a-package/test.py +functional_tests/support/issue191/setup.cfg +functional_tests/support/issue191/setup.py +functional_tests/support/issue191/test.py +functional_tests/support/issue191/UNKNOWN.egg-info/PKG-INFO +functional_tests/support/issue191/UNKNOWN.egg-info/SOURCES.txt +functional_tests/support/issue191/UNKNOWN.egg-info/dependency_links.txt +functional_tests/support/issue191/UNKNOWN.egg-info/top_level.txt +functional_tests/support/issue269/test_bad_class.py +functional_tests/support/issue279/test_mod_setup_fails.py +functional_tests/support/issue408/nosetests.xml +functional_tests/support/issue408/test.py +functional_tests/support/issue513/test.py +functional_tests/support/issue649/test.py +functional_tests/support/issue680/test.py +functional_tests/support/issue700/test.py +functional_tests/support/issue720/test.py +functional_tests/support/issue771/test.py +functional_tests/support/issue859/test.py +functional_tests/support/ltfn/state.py +functional_tests/support/ltfn/test_mod.py +functional_tests/support/ltfn/test_pak1/__init__.py +functional_tests/support/ltfn/test_pak1/test_mod.py +functional_tests/support/ltfn/test_pak2/__init__.py +functional_tests/support/ltftc/tests.py +functional_tests/support/namespace_pkg/namespace_pkg/__init__.py +functional_tests/support/namespace_pkg/namespace_pkg/example.py +functional_tests/support/namespace_pkg/namespace_pkg/test_pkg.py +functional_tests/support/namespace_pkg/site-packages/namespace_pkg/__init__.py +functional_tests/support/namespace_pkg/site-packages/namespace_pkg/example2.py +functional_tests/support/namespace_pkg/site-packages/namespace_pkg/test_pkg2.py +functional_tests/support/package1/example.py +functional_tests/support/package1/tests/test_example_function.py +functional_tests/support/package2/maths.py +functional_tests/support/package2/test_pak/__init__.py +functional_tests/support/package2/test_pak/test_mod.py +functional_tests/support/package2/test_pak/test_sub/__init__.py +functional_tests/support/package2/test_pak/test_sub/test_mod.py +functional_tests/support/package3/lib/a.py +functional_tests/support/package3/src/b.py +functional_tests/support/package3/tests/test_a.py +functional_tests/support/package3/tests/test_b.py +functional_tests/support/pass/test.py +functional_tests/support/string-exception/test.py +functional_tests/support/todo/test_with_todo.py +functional_tests/support/todo/todoplug.py +functional_tests/support/twist/test_twisted.py +functional_tests/support/xunit/test_xunit_as_suite.py +functional_tests/test_issue120/test_named_test_with_doctest.rst +functional_tests/test_issue120/support/some_test.py +functional_tests/test_multiprocessing/__init__.py +functional_tests/test_multiprocessing/test_class.py +functional_tests/test_multiprocessing/test_concurrent_shared.py +functional_tests/test_multiprocessing/test_keyboardinterrupt.py +functional_tests/test_multiprocessing/test_nameerror.py +functional_tests/test_multiprocessing/test_process_timeout.py +functional_tests/test_multiprocessing/support/class.py +functional_tests/test_multiprocessing/support/fake_nosetest.py +functional_tests/test_multiprocessing/support/keyboardinterrupt.py +functional_tests/test_multiprocessing/support/keyboardinterrupt_twice.py +functional_tests/test_multiprocessing/support/nameerror.py +functional_tests/test_multiprocessing/support/timeout.py +functional_tests/test_multiprocessing/support/concurrent_shared/__init__.py +functional_tests/test_multiprocessing/support/concurrent_shared/test.py +nose/__init__.py +nose/__main__.py +nose/case.py +nose/commands.py +nose/config.py +nose/core.py +nose/exc.py +nose/failure.py +nose/importer.py +nose/inspector.py +nose/loader.py +nose/proxy.py +nose/pyversion.py +nose/result.py +nose/selector.py +nose/suite.py +nose/twistedtools.py +nose/usage.txt +nose/util.py +nose.egg-info/PKG-INFO +nose.egg-info/SOURCES.txt +nose.egg-info/dependency_links.txt +nose.egg-info/entry_points.txt +nose.egg-info/not-zip-safe +nose.egg-info/top_level.txt +nose/ext/__init__.py +nose/ext/dtcompat.py +nose/plugins/__init__.py +nose/plugins/allmodules.py +nose/plugins/attrib.py +nose/plugins/base.py +nose/plugins/builtin.py +nose/plugins/capture.py +nose/plugins/collect.py +nose/plugins/cover.py +nose/plugins/debug.py +nose/plugins/deprecated.py +nose/plugins/doctests.py +nose/plugins/errorclass.py +nose/plugins/failuredetail.py +nose/plugins/isolate.py +nose/plugins/logcapture.py +nose/plugins/manager.py +nose/plugins/multiprocess.py +nose/plugins/plugintest.py +nose/plugins/prof.py +nose/plugins/skip.py +nose/plugins/testid.py +nose/plugins/xunit.py +nose/sphinx/__init__.py +nose/sphinx/pluginopts.py +nose/tools/__init__.py +nose/tools/nontrivial.py +nose/tools/trivial.py +unit_tests/helpers.py +unit_tests/mock.py +unit_tests/test_attribute_plugin.py +unit_tests/test_bug105.py +unit_tests/test_capture_plugin.py +unit_tests/test_cases.py +unit_tests/test_config.py +unit_tests/test_config_defaults.rst +unit_tests/test_core.py +unit_tests/test_cover_plugin.py +unit_tests/test_deprecated_plugin.py +unit_tests/test_doctest_error_handling.py +unit_tests/test_doctest_munging.rst +unit_tests/test_doctest_no_name.py +unit_tests/test_id_plugin.py +unit_tests/test_importer.py +unit_tests/test_inspector.py +unit_tests/test_isolation_plugin.py +unit_tests/test_issue135.py +unit_tests/test_issue155.rst +unit_tests/test_issue270.rst +unit_tests/test_issue270_fixtures.py +unit_tests/test_issue_006.py +unit_tests/test_issue_064.py +unit_tests/test_issue_065.py +unit_tests/test_issue_100.rst +unit_tests/test_issue_100.rst.py3.patch +unit_tests/test_issue_101.py +unit_tests/test_issue_159.rst +unit_tests/test_issue_227.py +unit_tests/test_issue_230.py +unit_tests/test_issue_786.py +unit_tests/test_lazy_suite.py +unit_tests/test_loader.py +unit_tests/test_logcapture_plugin.py +unit_tests/test_logging.py +unit_tests/test_ls_tree.rst +unit_tests/test_multiprocess.py +unit_tests/test_multiprocess_runner.py +unit_tests/test_pdb_plugin.py +unit_tests/test_plugin.py +unit_tests/test_plugin_interfaces.py +unit_tests/test_plugin_manager.py +unit_tests/test_plugins.py +unit_tests/test_result_proxy.py +unit_tests/test_selector.py +unit_tests/test_selector_plugins.py +unit_tests/test_skip_plugin.py +unit_tests/test_suite.py +unit_tests/test_tools.py +unit_tests/test_twisted.py +unit_tests/test_twisted_testcase.py +unit_tests/test_utils.py +unit_tests/test_xunit.py +unit_tests/support/script.py +unit_tests/support/test.py +unit_tests/support/bug101/tests.py +unit_tests/support/bug105/tests.py +unit_tests/support/config_defaults/a.cfg +unit_tests/support/config_defaults/b.cfg +unit_tests/support/config_defaults/invalid.cfg +unit_tests/support/config_defaults/invalid_value.cfg +unit_tests/support/doctest/.gitignore +unit_tests/support/doctest/err_doctests.py +unit_tests/support/doctest/no_doctests.py +unit_tests/support/doctest/noname_wrapped.not_py +unit_tests/support/doctest/noname_wrapped.not_pyc +unit_tests/support/doctest/noname_wrapper.py +unit_tests/support/foo/__init__.py +unit_tests/support/foo/doctests.txt +unit_tests/support/foo/test_foo.py +unit_tests/support/foo/bar/__init__.py +unit_tests/support/foo/bar/buz.py +unit_tests/support/foo/tests/dir_test_file.py +unit_tests/support/init_prefix_bug/__init__.py +unit_tests/support/init_prefix_bug/__init__not.py +unit_tests/support/issue006/tests.py +unit_tests/support/issue065/tests.py +unit_tests/support/issue135/tests.py +unit_tests/support/issue270/__init__.py +unit_tests/support/issue270/foo_test.py +unit_tests/support/other/file.txt +unit_tests/support/pkgorg/lib/modernity.py +unit_tests/support/pkgorg/tests/test_mod.py +unit_tests/support/test-dir/test.py \ No newline at end of file diff --git a/.eggs/nose-1.3.7-py2.7.egg/EGG-INFO/dependency_links.txt b/.eggs/nose-1.3.7-py2.7.egg/EGG-INFO/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/EGG-INFO/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/.eggs/nose-1.3.7-py2.7.egg/EGG-INFO/entry_points.txt b/.eggs/nose-1.3.7-py2.7.egg/EGG-INFO/entry_points.txt new file mode 100644 index 0000000..07c6548 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/EGG-INFO/entry_points.txt @@ -0,0 +1,7 @@ +[console_scripts] +nosetests = nose:run_exit +nosetests-2.7 = nose:run_exit + +[distutils.commands] +nosetests = nose.commands:nosetests + diff --git a/.eggs/nose-1.3.7-py2.7.egg/EGG-INFO/not-zip-safe b/.eggs/nose-1.3.7-py2.7.egg/EGG-INFO/not-zip-safe new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/EGG-INFO/not-zip-safe @@ -0,0 +1 @@ + diff --git a/.eggs/nose-1.3.7-py2.7.egg/EGG-INFO/top_level.txt b/.eggs/nose-1.3.7-py2.7.egg/EGG-INFO/top_level.txt new file mode 100644 index 0000000..f3c7e8e --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/EGG-INFO/top_level.txt @@ -0,0 +1 @@ +nose diff --git a/.eggs/nose-1.3.7-py2.7.egg/man/man1/nosetests.1 b/.eggs/nose-1.3.7-py2.7.egg/man/man1/nosetests.1 new file mode 100644 index 0000000..5772845 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/man/man1/nosetests.1 @@ -0,0 +1,581 @@ +.\" Man page generated from reStructuredText. +. +.TH "NOSETESTS" "1" "April 04, 2015" "1.3" "nose" +.SH NAME +nosetests \- Nicer testing for Python +. +.nr rst2man-indent-level 0 +. +.de1 rstReportMargin +\\$1 \\n[an-margin] +level \\n[rst2man-indent-level] +level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] +- +\\n[rst2man-indent0] +\\n[rst2man-indent1] +\\n[rst2man-indent2] +.. +.de1 INDENT +.\" .rstReportMargin pre: +. RS \\$1 +. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] +. nr rst2man-indent-level +1 +.\" .rstReportMargin post: +.. +.de UNINDENT +. RE +.\" indent \\n[an-margin] +.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] +.nr rst2man-indent-level -1 +.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] +.in \\n[rst2man-indent\\n[rst2man-indent-level]]u +.. +.SH NICER TESTING FOR PYTHON +.SS SYNOPSIS +.INDENT 0.0 +.INDENT 3.5 +nosetests [options] [names] +.UNINDENT +.UNINDENT +.SS DESCRIPTION +.sp +nose collects tests automatically from python source files, +directories and packages found in its working directory (which +defaults to the current working directory). Any python source file, +directory or package that matches the testMatch regular expression +(by default: \fI(?:^|[b_.\-])[Tt]est)\fP will be collected as a test (or +source for collection of tests). In addition, all other packages +found in the working directory will be examined for python source files +or directories that match testMatch. Package discovery descends all +the way down the tree, so package.tests and package.sub.tests and +package.sub.sub2.tests will all be collected. +.sp +Within a test directory or package, any python source file matching +testMatch will be examined for test cases. Within a test module, +functions and classes whose names match testMatch and TestCase +subclasses with any name will be loaded and executed as tests. Tests +may use the assert keyword or raise AssertionErrors to indicate test +failure. TestCase subclasses may do the same or use the various +TestCase methods available. +.sp +\fBIt is important to note that the default behavior of nose is to +not include tests from files which are executable.\fP To include +tests from such files, remove their executable bit or use +the \-\-exe flag (see \(aqOptions\(aq section below). +.SS Selecting Tests +.sp +To specify which tests to run, pass test names on the command line: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +nosetests only_test_this.py +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Test names specified may be file or module names, and may optionally +indicate the test case to run by separating the module or file name +from the test case name with a colon. Filenames may be relative or +absolute. Examples: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +nosetests test.module +nosetests another.test:TestCase.test_method +nosetests a.test:TestCase +nosetests /path/to/test/file.py:test_function +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +You may also change the working directory where nose looks for tests +by using the \-w switch: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +nosetests \-w /path/to/tests +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Note, however, that support for multiple \-w arguments is now deprecated +and will be removed in a future release. As of nose 0.10, you can get +the same behavior by specifying the target directories \fIwithout\fP +the \-w switch: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +nosetests /path/to/tests /another/path/to/tests +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +Further customization of test selection and loading is possible +through the use of plugins. +.sp +Test result output is identical to that of unittest, except for +the additional features (error classes, and plugin\-supplied +features such as output capture and assert introspection) detailed +in the options below. +.SS Configuration +.sp +In addition to passing command\-line options, you may also put +configuration options in your project\(aqs \fIsetup.cfg\fP file, or a .noserc +or nose.cfg file in your home directory. In any of these standard +ini\-style config files, you put your nosetests configuration in a +\fB[nosetests]\fP section. Options are the same as on the command line, +with the \-\- prefix removed. For options that are simple switches, you +must supply a value: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +[nosetests] +verbosity=3 +with\-doctest=1 +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +All configuration files that are found will be loaded and their +options combined. You can override the standard config file loading +with the \fB\-c\fP option. +.SS Using Plugins +.sp +There are numerous nose plugins available via easy_install and +elsewhere. To use a plugin, just install it. The plugin will add +command line options to nosetests. To verify that the plugin is installed, +run: +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +nosetests \-\-plugins +.ft P +.fi +.UNINDENT +.UNINDENT +.sp +You can add \-v or \-vv to that command to show more information +about each plugin. +.sp +If you are running nose.main() or nose.run() from a script, you +can specify a list of plugins to use by passing a list of plugins +with the plugins keyword argument. +.SS 0.9 plugins +.sp +nose 1.0 can use SOME plugins that were written for nose 0.9. The +default plugin manager inserts a compatibility wrapper around 0.9 +plugins that adapts the changed plugin api calls. However, plugins +that access nose internals are likely to fail, especially if they +attempt to access test case or test suite classes. For example, +plugins that try to determine if a test passed to startTest is an +individual test or a suite will fail, partly because suites are no +longer passed to startTest and partly because it\(aqs likely that the +plugin is trying to find out if the test is an instance of a class +that no longer exists. +.SS 0.10 and 0.11 plugins +.sp +All plugins written for nose 0.10 and 0.11 should work with nose 1.0. +.SS Options +.INDENT 0.0 +.TP +.B \-V, \-\-version +Output nose version and exit +.UNINDENT +.INDENT 0.0 +.TP +.B \-p, \-\-plugins +Output list of available plugins and exit. Combine with higher verbosity for greater detail +.UNINDENT +.INDENT 0.0 +.TP +.B \-v=DEFAULT, \-\-verbose=DEFAULT +Be more verbose. [NOSE_VERBOSE] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-verbosity=VERBOSITY +Set verbosity; \-\-verbosity=2 is the same as \-v +.UNINDENT +.INDENT 0.0 +.TP +.B \-q=DEFAULT, \-\-quiet=DEFAULT +Be less verbose +.UNINDENT +.INDENT 0.0 +.TP +.B \-c=FILES, \-\-config=FILES +Load configuration from config file(s). May be specified multiple times; in that case, all config files will be loaded and combined +.UNINDENT +.INDENT 0.0 +.TP +.B \-w=WHERE, \-\-where=WHERE +Look for tests in this directory. May be specified multiple times. The first directory passed will be used as the working directory, in place of the current working directory, which is the default. Others will be added to the list of tests to execute. [NOSE_WHERE] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-py3where=PY3WHERE +Look for tests in this directory under Python 3.x. Functions the same as \(aqwhere\(aq, but only applies if running under Python 3.x or above. Note that, if present under 3.x, this option completely replaces any directories specified with \(aqwhere\(aq, so the \(aqwhere\(aq option becomes ineffective. [NOSE_PY3WHERE] +.UNINDENT +.INDENT 0.0 +.TP +.B \-m=REGEX, \-\-match=REGEX, \-\-testmatch=REGEX +Files, directories, function names, and class names that match this regular expression are considered tests. Default: (?:^|[b_./\-])[Tt]est [NOSE_TESTMATCH] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-tests=NAMES +Run these tests (comma\-separated list). This argument is useful mainly from configuration files; on the command line, just pass the tests to run as additional arguments with no switch. +.UNINDENT +.INDENT 0.0 +.TP +.B \-l=DEFAULT, \-\-debug=DEFAULT +Activate debug logging for one or more systems. Available debug loggers: nose, nose.importer, nose.inspector, nose.plugins, nose.result and nose.selector. Separate multiple names with a comma. +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-debug\-log=FILE +Log debug messages to this file (default: sys.stderr) +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-logging\-config=FILE, \-\-log\-config=FILE +Load logging config from this file \-\- bypasses all other logging config settings. +.UNINDENT +.INDENT 0.0 +.TP +.B \-I=REGEX, \-\-ignore\-files=REGEX +Completely ignore any file that matches this regular expression. Takes precedence over any other settings or plugins. Specifying this option will replace the default setting. Specify this option multiple times to add more regular expressions [NOSE_IGNORE_FILES] +.UNINDENT +.INDENT 0.0 +.TP +.B \-e=REGEX, \-\-exclude=REGEX +Don\(aqt run tests that match regular expression [NOSE_EXCLUDE] +.UNINDENT +.INDENT 0.0 +.TP +.B \-i=REGEX, \-\-include=REGEX +This regular expression will be applied to files, directories, function names, and class names for a chance to include additional tests that do not match TESTMATCH. Specify this option multiple times to add more regular expressions [NOSE_INCLUDE] +.UNINDENT +.INDENT 0.0 +.TP +.B \-x, \-\-stop +Stop running tests after the first error or failure +.UNINDENT +.INDENT 0.0 +.TP +.B \-P, \-\-no\-path\-adjustment +Don\(aqt make any changes to sys.path when loading tests [NOSE_NOPATH] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-exe +Look for tests in python modules that are executable. Normal behavior is to exclude executable modules, since they may not be import\-safe [NOSE_INCLUDE_EXE] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-noexe +DO NOT look for tests in python modules that are executable. (The default on the windows platform is to do so.) +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-traverse\-namespace +Traverse through all path entries of a namespace package +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-first\-package\-wins, \-\-first\-pkg\-wins, \-\-1st\-pkg\-wins +nose\(aqs importer will normally evict a package from sys.modules if it sees a package with the same name in a different location. Set this option to disable that behavior. +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-no\-byte\-compile +Prevent nose from byte\-compiling the source into .pyc files while nose is scanning for and running tests. +.UNINDENT +.INDENT 0.0 +.TP +.B \-a=ATTR, \-\-attr=ATTR +Run only tests that have attributes specified by ATTR [NOSE_ATTR] +.UNINDENT +.INDENT 0.0 +.TP +.B \-A=EXPR, \-\-eval\-attr=EXPR +Run only tests for whose attributes the Python expression EXPR evaluates to True [NOSE_EVAL_ATTR] +.UNINDENT +.INDENT 0.0 +.TP +.B \-s, \-\-nocapture +Don\(aqt capture stdout (any stdout output will be printed immediately) [NOSE_NOCAPTURE] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-nologcapture +Disable logging capture plugin. Logging configuration will be left intact. [NOSE_NOLOGCAPTURE] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-logging\-format=FORMAT +Specify custom format to print statements. Uses the same format as used by standard logging handlers. [NOSE_LOGFORMAT] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-logging\-datefmt=FORMAT +Specify custom date/time format to print statements. Uses the same format as used by standard logging handlers. [NOSE_LOGDATEFMT] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-logging\-filter=FILTER +Specify which statements to filter in/out. By default, everything is captured. If the output is too verbose, +use this option to filter out needless output. +Example: filter=foo will capture statements issued ONLY to + foo or foo.what.ever.sub but not foobar or other logger. +Specify multiple loggers with comma: filter=foo,bar,baz. +If any logger name is prefixed with a minus, eg filter=\-foo, +it will be excluded rather than included. Default: exclude logging messages from nose itself (\-nose). [NOSE_LOGFILTER] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-logging\-clear\-handlers +Clear all other logging handlers +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-logging\-level=DEFAULT +Set the log level to capture +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-with\-coverage +Enable plugin Coverage: +Activate a coverage report using Ned Batchelder\(aqs coverage module. + [NOSE_WITH_COVERAGE] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-cover\-package=PACKAGE +Restrict coverage output to selected packages [NOSE_COVER_PACKAGE] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-cover\-erase +Erase previously collected coverage statistics before run +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-cover\-tests +Include test modules in coverage report [NOSE_COVER_TESTS] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-cover\-min\-percentage=DEFAULT +Minimum percentage of coverage for tests to pass [NOSE_COVER_MIN_PERCENTAGE] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-cover\-inclusive +Include all python files under working directory in coverage report. Useful for discovering holes in test coverage if not all files are imported by the test suite. [NOSE_COVER_INCLUSIVE] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-cover\-html +Produce HTML coverage information +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-cover\-html\-dir=DIR +Produce HTML coverage information in dir +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-cover\-branches +Include branch coverage in coverage report [NOSE_COVER_BRANCHES] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-cover\-xml +Produce XML coverage information +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-cover\-xml\-file=FILE +Produce XML coverage information in file +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-pdb +Drop into debugger on failures or errors +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-pdb\-failures +Drop into debugger on failures +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-pdb\-errors +Drop into debugger on errors +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-no\-deprecated +Disable special handling of DeprecatedTest exceptions. +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-with\-doctest +Enable plugin Doctest: +Activate doctest plugin to find and run doctests in non\-test modules. + [NOSE_WITH_DOCTEST] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-doctest\-tests +Also look for doctests in test modules. Note that classes, methods and functions should have either doctests or non\-doctest tests, not both. [NOSE_DOCTEST_TESTS] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-doctest\-extension=EXT +Also look for doctests in files with this extension [NOSE_DOCTEST_EXTENSION] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-doctest\-result\-variable=VAR +Change the variable name set to the result of the last interpreter command from the default \(aq_\(aq. Can be used to avoid conflicts with the _() function used for text translation. [NOSE_DOCTEST_RESULT_VAR] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-doctest\-fixtures=SUFFIX +Find fixtures for a doctest file in module with this name appended to the base name of the doctest file +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-doctest\-options=OPTIONS +Specify options to pass to doctest. Eg. \(aq+ELLIPSIS,+NORMALIZE_WHITESPACE\(aq +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-with\-isolation +Enable plugin IsolationPlugin: +Activate the isolation plugin to isolate changes to external +modules to a single test module or package. The isolation plugin +resets the contents of sys.modules after each test module or +package runs to its state before the test. PLEASE NOTE that this +plugin should not be used with the coverage plugin, or in any other case +where module reloading may produce undesirable side\-effects. + [NOSE_WITH_ISOLATION] +.UNINDENT +.INDENT 0.0 +.TP +.B \-d, \-\-detailed\-errors, \-\-failure\-detail +Add detail to error output by attempting to evaluate failed asserts [NOSE_DETAILED_ERRORS] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-with\-profile +Enable plugin Profile: +Use this plugin to run tests using the hotshot profiler. + [NOSE_WITH_PROFILE] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-profile\-sort=SORT +Set sort order for profiler output +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-profile\-stats\-file=FILE +Profiler stats file; default is a new temp file on each run +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-profile\-restrict=RESTRICT +Restrict profiler output. See help for pstats.Stats for details +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-no\-skip +Disable special handling of SkipTest exceptions. +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-with\-id +Enable plugin TestId: +Activate to add a test id (like #1) to each test name output. Activate +with \-\-failed to rerun failing tests only. + [NOSE_WITH_ID] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-id\-file=FILE +Store test ids found in test runs in this file. Default is the file .noseids in the working directory. +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-failed +Run the tests that failed in the last test run. +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-processes=NUM +Spread test run among this many processes. Set a number equal to the number of processors or cores in your machine for best results. Pass a negative number to have the number of processes automatically set to the number of cores. Passing 0 means to disable parallel testing. Default is 0 unless NOSE_PROCESSES is set. [NOSE_PROCESSES] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-process\-timeout=SECONDS +Set timeout for return of results from each test runner process. Default is 10. [NOSE_PROCESS_TIMEOUT] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-process\-restartworker +If set, will restart each worker process once their tests are done, this helps control memory leaks from killing the system. [NOSE_PROCESS_RESTARTWORKER] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-with\-xunit +Enable plugin Xunit: This plugin provides test results in the standard XUnit XML format. [NOSE_WITH_XUNIT] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-xunit\-file=FILE +Path to xml file to store the xunit report in. Default is nosetests.xml in the working directory [NOSE_XUNIT_FILE] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-xunit\-testsuite\-name=PACKAGE +Name of the testsuite in the xunit xml, generated by plugin. Default test suite name is nosetests. +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-all\-modules +Enable plugin AllModules: Collect tests from all python modules. + [NOSE_ALL_MODULES] +.UNINDENT +.INDENT 0.0 +.TP +.B \-\-collect\-only +Enable collect\-only: +Collect and output test names only, don\(aqt run any tests. + [COLLECT_ONLY] +.UNINDENT +.SH AUTHOR +Nose developers +.SH COPYRIGHT +2009, Jason Pellerin +.\" Generated by docutils manpage writer. +. diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/__init__.py b/.eggs/nose-1.3.7-py2.7.egg/nose/__init__.py new file mode 100644 index 0000000..1ae1362 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/__init__.py @@ -0,0 +1,15 @@ +from nose.core import collector, main, run, run_exit, runmodule +# backwards compatibility +from nose.exc import SkipTest, DeprecatedTest +from nose.tools import with_setup + +__author__ = 'Jason Pellerin' +__versioninfo__ = (1, 3, 7) +__version__ = '.'.join(map(str, __versioninfo__)) + +__all__ = [ + 'main', 'run', 'run_exit', 'runmodule', 'with_setup', + 'SkipTest', 'DeprecatedTest', 'collector' + ] + + diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/__init__.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ddcef280418515e3db8ca85d7920fd1bc8313c44 GIT binary patch literal 721 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.0'] + ) + +This will direct setuptools to download and activate nose during the setup +process, making the ``nosetests`` command available. + +""" +try: + from setuptools import Command +except ImportError: + Command = nosetests = None +else: + from nose.config import Config, option_blacklist, user_config_files, \ + flag, _bool + from nose.core import TestProgram + from nose.plugins import DefaultPluginManager + + + def get_user_options(parser): + """convert a optparse option list into a distutils option tuple list""" + opt_list = [] + for opt in parser.option_list: + if opt._long_opts[0][2:] in option_blacklist: + continue + long_name = opt._long_opts[0][2:] + if opt.action not in ('store_true', 'store_false'): + long_name = long_name + "=" + short_name = None + if opt._short_opts: + short_name = opt._short_opts[0][1:] + opt_list.append((long_name, short_name, opt.help or "")) + return opt_list + + + class nosetests(Command): + description = "Run unit tests using nosetests" + __config = Config(files=user_config_files(), + plugins=DefaultPluginManager()) + __parser = __config.getParser() + user_options = get_user_options(__parser) + + def initialize_options(self): + """create the member variables, but change hyphens to + underscores + """ + + self.option_to_cmds = {} + for opt in self.__parser.option_list: + cmd_name = opt._long_opts[0][2:] + option_name = cmd_name.replace('-', '_') + self.option_to_cmds[option_name] = cmd_name + setattr(self, option_name, None) + self.attr = None + + def finalize_options(self): + """nothing to do here""" + pass + + def run(self): + """ensure tests are capable of being run, then + run nose.main with a reconstructed argument list""" + if getattr(self.distribution, 'use_2to3', False): + # If we run 2to3 we can not do this inplace: + + # Ensure metadata is up-to-date + build_py = self.get_finalized_command('build_py') + build_py.inplace = 0 + build_py.run() + bpy_cmd = self.get_finalized_command("build_py") + build_path = bpy_cmd.build_lib + + # Build extensions + egg_info = self.get_finalized_command('egg_info') + egg_info.egg_base = build_path + egg_info.run() + + build_ext = self.get_finalized_command('build_ext') + build_ext.inplace = 0 + build_ext.run() + else: + self.run_command('egg_info') + + # Build extensions in-place + build_ext = self.get_finalized_command('build_ext') + build_ext.inplace = 1 + build_ext.run() + + if self.distribution.install_requires: + self.distribution.fetch_build_eggs( + self.distribution.install_requires) + if self.distribution.tests_require: + self.distribution.fetch_build_eggs( + self.distribution.tests_require) + + ei_cmd = self.get_finalized_command("egg_info") + argv = ['nosetests', '--where', ei_cmd.egg_base] + for (option_name, cmd_name) in self.option_to_cmds.items(): + if option_name in option_blacklist: + continue + value = getattr(self, option_name) + if value is not None: + argv.extend( + self.cfgToArg(option_name.replace('_', '-'), value)) + TestProgram(argv=argv, config=self.__config) + + def cfgToArg(self, optname, value): + argv = [] + long_optname = '--' + optname + opt = self.__parser.get_option(long_optname) + if opt.action in ('store_true', 'store_false'): + if not flag(value): + raise ValueError("Invalid value '%s' for '%s'" % ( + value, optname)) + if _bool(value): + argv.append(long_optname) + else: + argv.extend([long_optname, value]) + return argv diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/commands.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/commands.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3e7479e14e565b3e3257be043b3658fe0ea3d4a7 GIT binary patch literal 6262 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 VYa2CDt8IDb8lA?rx7}=S{}0}IZ!iD= literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/config.py b/.eggs/nose-1.3.7-py2.7.egg/nose/config.py new file mode 100644 index 0000000..125eb55 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/config.py @@ -0,0 +1,661 @@ +import logging +import optparse +import os +import re +import sys +import ConfigParser +from optparse import OptionParser +from nose.util import absdir, tolist +from nose.plugins.manager import NoPlugins +from warnings import warn, filterwarnings + +log = logging.getLogger(__name__) + +# not allowed in config files +option_blacklist = ['help', 'verbose'] + +config_files = [ + # Linux users will prefer this + "~/.noserc", + # Windows users will prefer this + "~/nose.cfg" + ] + +# plaforms on which the exe check defaults to off +# Windows and IronPython +exe_allowed_platforms = ('win32', 'cli') + +filterwarnings("always", category=DeprecationWarning, + module=r'(.*\.)?nose\.config') + +class NoSuchOptionError(Exception): + def __init__(self, name): + Exception.__init__(self, name) + self.name = name + + +class ConfigError(Exception): + pass + + +class ConfiguredDefaultsOptionParser(object): + """ + Handler for options from commandline and config files. + """ + def __init__(self, parser, config_section, error=None, file_error=None): + self._parser = parser + self._config_section = config_section + if error is None: + error = self._parser.error + self._error = error + if file_error is None: + file_error = lambda msg, **kw: error(msg) + self._file_error = file_error + + def _configTuples(self, cfg, filename): + config = [] + if self._config_section in cfg.sections(): + for name, value in cfg.items(self._config_section): + config.append((name, value, filename)) + return config + + def _readFromFilenames(self, filenames): + config = [] + for filename in filenames: + cfg = ConfigParser.RawConfigParser() + try: + cfg.read(filename) + except ConfigParser.Error, exc: + raise ConfigError("Error reading config file %r: %s" % + (filename, str(exc))) + config.extend(self._configTuples(cfg, filename)) + return config + + def _readFromFileObject(self, fh): + cfg = ConfigParser.RawConfigParser() + try: + filename = fh.name + except AttributeError: + filename = '' + try: + cfg.readfp(fh) + except ConfigParser.Error, exc: + raise ConfigError("Error reading config file %r: %s" % + (filename, str(exc))) + return self._configTuples(cfg, filename) + + def _readConfiguration(self, config_files): + try: + config_files.readline + except AttributeError: + filename_or_filenames = config_files + if isinstance(filename_or_filenames, basestring): + filenames = [filename_or_filenames] + else: + filenames = filename_or_filenames + config = self._readFromFilenames(filenames) + else: + fh = config_files + config = self._readFromFileObject(fh) + return config + + def _processConfigValue(self, name, value, values, parser): + opt_str = '--' + name + option = parser.get_option(opt_str) + if option is None: + raise NoSuchOptionError(name) + else: + option.process(opt_str, value, values, parser) + + def _applyConfigurationToValues(self, parser, config, values): + for name, value, filename in config: + if name in option_blacklist: + continue + try: + self._processConfigValue(name, value, values, parser) + except NoSuchOptionError, exc: + self._file_error( + "Error reading config file %r: " + "no such option %r" % (filename, exc.name), + name=name, filename=filename) + except optparse.OptionValueError, exc: + msg = str(exc).replace('--' + name, repr(name), 1) + self._file_error("Error reading config file %r: " + "%s" % (filename, msg), + name=name, filename=filename) + + def parseArgsAndConfigFiles(self, args, config_files): + values = self._parser.get_default_values() + try: + config = self._readConfiguration(config_files) + except ConfigError, exc: + self._error(str(exc)) + else: + try: + self._applyConfigurationToValues(self._parser, config, values) + except ConfigError, exc: + self._error(str(exc)) + return self._parser.parse_args(args, values) + + +class Config(object): + """nose configuration. + + Instances of Config are used throughout nose to configure + behavior, including plugin lists. Here are the default values for + all config keys:: + + self.env = env = kw.pop('env', {}) + self.args = () + self.testMatch = re.compile(r'(?:^|[\\b_\\.%s-])[Tt]est' % os.sep) + self.addPaths = not env.get('NOSE_NOPATH', False) + self.configSection = 'nosetests' + self.debug = env.get('NOSE_DEBUG') + self.debugLog = env.get('NOSE_DEBUG_LOG') + self.exclude = None + self.getTestCaseNamesCompat = False + self.includeExe = env.get('NOSE_INCLUDE_EXE', + sys.platform in exe_allowed_platforms) + self.ignoreFiles = (re.compile(r'^\.'), + re.compile(r'^_'), + re.compile(r'^setup\.py$') + ) + self.include = None + self.loggingConfig = None + self.logStream = sys.stderr + self.options = NoOptions() + self.parser = None + self.plugins = NoPlugins() + self.srcDirs = ('lib', 'src') + self.runOnInit = True + self.stopOnError = env.get('NOSE_STOP', False) + self.stream = sys.stderr + self.testNames = () + self.verbosity = int(env.get('NOSE_VERBOSE', 1)) + self.where = () + self.py3where = () + self.workingDir = None + """ + + def __init__(self, **kw): + self.env = env = kw.pop('env', {}) + self.args = () + self.testMatchPat = env.get('NOSE_TESTMATCH', + r'(?:^|[\b_\.%s-])[Tt]est' % os.sep) + self.testMatch = re.compile(self.testMatchPat) + self.addPaths = not env.get('NOSE_NOPATH', False) + self.configSection = 'nosetests' + self.debug = env.get('NOSE_DEBUG') + self.debugLog = env.get('NOSE_DEBUG_LOG') + self.exclude = None + self.getTestCaseNamesCompat = False + self.includeExe = env.get('NOSE_INCLUDE_EXE', + sys.platform in exe_allowed_platforms) + self.ignoreFilesDefaultStrings = [r'^\.', + r'^_', + r'^setup\.py$', + ] + self.ignoreFiles = map(re.compile, self.ignoreFilesDefaultStrings) + self.include = None + self.loggingConfig = None + self.logStream = sys.stderr + self.options = NoOptions() + self.parser = None + self.plugins = NoPlugins() + self.srcDirs = ('lib', 'src') + self.runOnInit = True + self.stopOnError = env.get('NOSE_STOP', False) + self.stream = sys.stderr + self.testNames = [] + self.verbosity = int(env.get('NOSE_VERBOSE', 1)) + self.where = () + self.py3where = () + self.workingDir = os.getcwd() + self.traverseNamespace = False + self.firstPackageWins = False + self.parserClass = OptionParser + self.worker = False + + self._default = self.__dict__.copy() + self.update(kw) + self._orig = self.__dict__.copy() + + def __getstate__(self): + state = self.__dict__.copy() + del state['stream'] + del state['_orig'] + del state['_default'] + del state['env'] + del state['logStream'] + # FIXME remove plugins, have only plugin manager class + state['plugins'] = self.plugins.__class__ + return state + + def __setstate__(self, state): + plugincls = state.pop('plugins') + self.update(state) + self.worker = True + # FIXME won't work for static plugin lists + self.plugins = plugincls() + self.plugins.loadPlugins() + # needed so .can_configure gets set appropriately + dummy_parser = self.parserClass() + self.plugins.addOptions(dummy_parser, {}) + self.plugins.configure(self.options, self) + + def __repr__(self): + d = self.__dict__.copy() + # don't expose env, could include sensitive info + d['env'] = {} + keys = [ k for k in d.keys() + if not k.startswith('_') ] + keys.sort() + return "Config(%s)" % ', '.join([ '%s=%r' % (k, d[k]) + for k in keys ]) + __str__ = __repr__ + + def _parseArgs(self, argv, cfg_files): + def warn_sometimes(msg, name=None, filename=None): + if (hasattr(self.plugins, 'excludedOption') and + self.plugins.excludedOption(name)): + msg = ("Option %r in config file %r ignored: " + "excluded by runtime environment" % + (name, filename)) + warn(msg, RuntimeWarning) + else: + raise ConfigError(msg) + parser = ConfiguredDefaultsOptionParser( + self.getParser(), self.configSection, file_error=warn_sometimes) + return parser.parseArgsAndConfigFiles(argv[1:], cfg_files) + + def configure(self, argv=None, doc=None): + """Configure the nose running environment. Execute configure before + collecting tests with nose.TestCollector to enable output capture and + other features. + """ + env = self.env + if argv is None: + argv = sys.argv + + cfg_files = getattr(self, 'files', []) + options, args = self._parseArgs(argv, cfg_files) + # If -c --config has been specified on command line, + # load those config files and reparse + if getattr(options, 'files', []): + options, args = self._parseArgs(argv, options.files) + + self.options = options + if args: + self.testNames = args + if options.testNames is not None: + self.testNames.extend(tolist(options.testNames)) + + if options.py3where is not None: + if sys.version_info >= (3,): + options.where = options.py3where + + # `where` is an append action, so it can't have a default value + # in the parser, or that default will always be in the list + if not options.where: + options.where = env.get('NOSE_WHERE', None) + + # include and exclude also + if not options.ignoreFiles: + options.ignoreFiles = env.get('NOSE_IGNORE_FILES', []) + if not options.include: + options.include = env.get('NOSE_INCLUDE', []) + if not options.exclude: + options.exclude = env.get('NOSE_EXCLUDE', []) + + self.addPaths = options.addPaths + self.stopOnError = options.stopOnError + self.verbosity = options.verbosity + self.includeExe = options.includeExe + self.traverseNamespace = options.traverseNamespace + self.debug = options.debug + self.debugLog = options.debugLog + self.loggingConfig = options.loggingConfig + self.firstPackageWins = options.firstPackageWins + self.configureLogging() + + if not options.byteCompile: + sys.dont_write_bytecode = True + + if options.where is not None: + self.configureWhere(options.where) + + if options.testMatch: + self.testMatch = re.compile(options.testMatch) + + if options.ignoreFiles: + self.ignoreFiles = map(re.compile, tolist(options.ignoreFiles)) + log.info("Ignoring files matching %s", options.ignoreFiles) + else: + log.info("Ignoring files matching %s", self.ignoreFilesDefaultStrings) + + if options.include: + self.include = map(re.compile, tolist(options.include)) + log.info("Including tests matching %s", options.include) + + if options.exclude: + self.exclude = map(re.compile, tolist(options.exclude)) + log.info("Excluding tests matching %s", options.exclude) + + # When listing plugins we don't want to run them + if not options.showPlugins: + self.plugins.configure(options, self) + self.plugins.begin() + + def configureLogging(self): + """Configure logging for nose, or optionally other packages. Any logger + name may be set with the debug option, and that logger will be set to + debug level and be assigned the same handler as the nose loggers, unless + it already has a handler. + """ + if self.loggingConfig: + from logging.config import fileConfig + fileConfig(self.loggingConfig) + return + + format = logging.Formatter('%(name)s: %(levelname)s: %(message)s') + if self.debugLog: + handler = logging.FileHandler(self.debugLog) + else: + handler = logging.StreamHandler(self.logStream) + handler.setFormatter(format) + + logger = logging.getLogger('nose') + logger.propagate = 0 + + # only add our default handler if there isn't already one there + # this avoids annoying duplicate log messages. + found = False + if self.debugLog: + debugLogAbsPath = os.path.abspath(self.debugLog) + for h in logger.handlers: + if type(h) == logging.FileHandler and \ + h.baseFilename == debugLogAbsPath: + found = True + else: + for h in logger.handlers: + if type(h) == logging.StreamHandler and \ + h.stream == self.logStream: + found = True + if not found: + logger.addHandler(handler) + + # default level + lvl = logging.WARNING + if self.verbosity >= 5: + lvl = 0 + elif self.verbosity >= 4: + lvl = logging.DEBUG + elif self.verbosity >= 3: + lvl = logging.INFO + logger.setLevel(lvl) + + # individual overrides + if self.debug: + # no blanks + debug_loggers = [ name for name in self.debug.split(',') + if name ] + for logger_name in debug_loggers: + l = logging.getLogger(logger_name) + l.setLevel(logging.DEBUG) + if not l.handlers and not logger_name.startswith('nose'): + l.addHandler(handler) + + def configureWhere(self, where): + """Configure the working directory or directories for the test run. + """ + from nose.importer import add_path + self.workingDir = None + where = tolist(where) + warned = False + for path in where: + if not self.workingDir: + abs_path = absdir(path) + if abs_path is None: + raise ValueError("Working directory '%s' not found, or " + "not a directory" % path) + log.info("Set working dir to %s", abs_path) + self.workingDir = abs_path + if self.addPaths and \ + os.path.exists(os.path.join(abs_path, '__init__.py')): + log.info("Working directory %s is a package; " + "adding to sys.path" % abs_path) + add_path(abs_path) + continue + if not warned: + warn("Use of multiple -w arguments is deprecated and " + "support may be removed in a future release. You can " + "get the same behavior by passing directories without " + "the -w argument on the command line, or by using the " + "--tests argument in a configuration file.", + DeprecationWarning) + warned = True + self.testNames.append(path) + + def default(self): + """Reset all config values to defaults. + """ + self.__dict__.update(self._default) + + def getParser(self, doc=None): + """Get the command line option parser. + """ + if self.parser: + return self.parser + env = self.env + parser = self.parserClass(doc) + parser.add_option( + "-V","--version", action="store_true", + dest="version", default=False, + help="Output nose version and exit") + parser.add_option( + "-p", "--plugins", action="store_true", + dest="showPlugins", default=False, + help="Output list of available plugins and exit. Combine with " + "higher verbosity for greater detail") + parser.add_option( + "-v", "--verbose", + action="count", dest="verbosity", + default=self.verbosity, + help="Be more verbose. [NOSE_VERBOSE]") + parser.add_option( + "--verbosity", action="store", dest="verbosity", + metavar='VERBOSITY', + type="int", help="Set verbosity; --verbosity=2 is " + "the same as -v") + parser.add_option( + "-q", "--quiet", action="store_const", const=0, dest="verbosity", + help="Be less verbose") + parser.add_option( + "-c", "--config", action="append", dest="files", + metavar="FILES", + help="Load configuration from config file(s). May be specified " + "multiple times; in that case, all config files will be " + "loaded and combined") + parser.add_option( + "-w", "--where", action="append", dest="where", + metavar="WHERE", + help="Look for tests in this directory. " + "May be specified multiple times. The first directory passed " + "will be used as the working directory, in place of the current " + "working directory, which is the default. Others will be added " + "to the list of tests to execute. [NOSE_WHERE]" + ) + parser.add_option( + "--py3where", action="append", dest="py3where", + metavar="PY3WHERE", + help="Look for tests in this directory under Python 3.x. " + "Functions the same as 'where', but only applies if running under " + "Python 3.x or above. Note that, if present under 3.x, this " + "option completely replaces any directories specified with " + "'where', so the 'where' option becomes ineffective. " + "[NOSE_PY3WHERE]" + ) + parser.add_option( + "-m", "--match", "--testmatch", action="store", + dest="testMatch", metavar="REGEX", + help="Files, directories, function names, and class names " + "that match this regular expression are considered tests. " + "Default: %s [NOSE_TESTMATCH]" % self.testMatchPat, + default=self.testMatchPat) + parser.add_option( + "--tests", action="store", dest="testNames", default=None, + metavar='NAMES', + help="Run these tests (comma-separated list). This argument is " + "useful mainly from configuration files; on the command line, " + "just pass the tests to run as additional arguments with no " + "switch.") + parser.add_option( + "-l", "--debug", action="store", + dest="debug", default=self.debug, + help="Activate debug logging for one or more systems. " + "Available debug loggers: nose, nose.importer, " + "nose.inspector, nose.plugins, nose.result and " + "nose.selector. Separate multiple names with a comma.") + parser.add_option( + "--debug-log", dest="debugLog", action="store", + default=self.debugLog, metavar="FILE", + help="Log debug messages to this file " + "(default: sys.stderr)") + parser.add_option( + "--logging-config", "--log-config", + dest="loggingConfig", action="store", + default=self.loggingConfig, metavar="FILE", + help="Load logging config from this file -- bypasses all other" + " logging config settings.") + parser.add_option( + "-I", "--ignore-files", action="append", dest="ignoreFiles", + metavar="REGEX", + help="Completely ignore any file that matches this regular " + "expression. Takes precedence over any other settings or " + "plugins. " + "Specifying this option will replace the default setting. " + "Specify this option multiple times " + "to add more regular expressions [NOSE_IGNORE_FILES]") + parser.add_option( + "-e", "--exclude", action="append", dest="exclude", + metavar="REGEX", + help="Don't run tests that match regular " + "expression [NOSE_EXCLUDE]") + parser.add_option( + "-i", "--include", action="append", dest="include", + metavar="REGEX", + help="This regular expression will be applied to files, " + "directories, function names, and class names for a chance " + "to include additional tests that do not match TESTMATCH. " + "Specify this option multiple times " + "to add more regular expressions [NOSE_INCLUDE]") + parser.add_option( + "-x", "--stop", action="store_true", dest="stopOnError", + default=self.stopOnError, + help="Stop running tests after the first error or failure") + parser.add_option( + "-P", "--no-path-adjustment", action="store_false", + dest="addPaths", + default=self.addPaths, + help="Don't make any changes to sys.path when " + "loading tests [NOSE_NOPATH]") + parser.add_option( + "--exe", action="store_true", dest="includeExe", + default=self.includeExe, + help="Look for tests in python modules that are " + "executable. Normal behavior is to exclude executable " + "modules, since they may not be import-safe " + "[NOSE_INCLUDE_EXE]") + parser.add_option( + "--noexe", action="store_false", dest="includeExe", + help="DO NOT look for tests in python modules that are " + "executable. (The default on the windows platform is to " + "do so.)") + parser.add_option( + "--traverse-namespace", action="store_true", + default=self.traverseNamespace, dest="traverseNamespace", + help="Traverse through all path entries of a namespace package") + parser.add_option( + "--first-package-wins", "--first-pkg-wins", "--1st-pkg-wins", + action="store_true", default=False, dest="firstPackageWins", + help="nose's importer will normally evict a package from sys." + "modules if it sees a package with the same name in a different " + "location. Set this option to disable that behavior.") + parser.add_option( + "--no-byte-compile", + action="store_false", default=True, dest="byteCompile", + help="Prevent nose from byte-compiling the source into .pyc files " + "while nose is scanning for and running tests.") + + self.plugins.loadPlugins() + self.pluginOpts(parser) + + self.parser = parser + return parser + + def help(self, doc=None): + """Return the generated help message + """ + return self.getParser(doc).format_help() + + def pluginOpts(self, parser): + self.plugins.addOptions(parser, self.env) + + def reset(self): + self.__dict__.update(self._orig) + + def todict(self): + return self.__dict__.copy() + + def update(self, d): + self.__dict__.update(d) + + +class NoOptions(object): + """Options container that returns None for all options. + """ + def __getstate__(self): + return {} + + def __setstate__(self, state): + pass + + def __getnewargs__(self): + return () + + def __nonzero__(self): + return False + + +def user_config_files(): + """Return path to any existing user config files + """ + return filter(os.path.exists, + map(os.path.expanduser, config_files)) + + +def all_config_files(): + """Return path to any existing user config files, plus any setup.cfg + in the current working directory. + """ + user = user_config_files() + if os.path.exists('setup.cfg'): + return user + ['setup.cfg'] + return user + + +# used when parsing config files +def flag(val): + """Does the value look like an on/off flag?""" + if val == 1: + return True + elif val == 0: + return False + val = str(val) + if len(val) > 5: + return False + return val.upper() in ('1', '0', 'F', 'T', 'TRUE', 'FALSE', 'ON', 'OFF') + + +def _bool(val): + return str(val).upper() in ('1', 'T', 'TRUE', 'ON') diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/config.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/config.pyc new file mode 100644 index 0000000000000000000000000000000000000000..02a16f52aab37dc0fe2898b8da69bedb57df5abd GIT binary patch literal 24852 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 literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/core.py b/.eggs/nose-1.3.7-py2.7.egg/nose/core.py new file mode 100644 index 0000000..49e7939 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/core.py @@ -0,0 +1,341 @@ +"""Implements nose test program and collector. +""" +from __future__ import generators + +import logging +import os +import sys +import time +import unittest + +from nose.config import Config, all_config_files +from nose.loader import defaultTestLoader +from nose.plugins.manager import PluginManager, DefaultPluginManager, \ + RestrictedPluginManager +from nose.result import TextTestResult +from nose.suite import FinalizingSuiteWrapper +from nose.util import isclass, tolist + + +log = logging.getLogger('nose.core') +compat_24 = sys.version_info >= (2, 4) + +__all__ = ['TestProgram', 'main', 'run', 'run_exit', 'runmodule', 'collector', + 'TextTestRunner'] + + +class TextTestRunner(unittest.TextTestRunner): + """Test runner that uses nose's TextTestResult to enable errorClasses, + as well as providing hooks for plugins to override or replace the test + output stream, results, and the test case itself. + """ + def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1, + config=None): + if config is None: + config = Config() + self.config = config + unittest.TextTestRunner.__init__(self, stream, descriptions, verbosity) + + + def _makeResult(self): + return TextTestResult(self.stream, + self.descriptions, + self.verbosity, + self.config) + + def run(self, test): + """Overrides to provide plugin hooks and defer all output to + the test result class. + """ + wrapper = self.config.plugins.prepareTest(test) + if wrapper is not None: + test = wrapper + + # plugins can decorate or capture the output stream + wrapped = self.config.plugins.setOutputStream(self.stream) + if wrapped is not None: + self.stream = wrapped + + result = self._makeResult() + start = time.time() + try: + test(result) + except KeyboardInterrupt: + pass + stop = time.time() + result.printErrors() + result.printSummary(start, stop) + self.config.plugins.finalize(result) + return result + + +class TestProgram(unittest.TestProgram): + """Collect and run tests, returning success or failure. + + The arguments to TestProgram() are the same as to + :func:`main()` and :func:`run()`: + + * module: All tests are in this module (default: None) + * defaultTest: Tests to load (default: '.') + * argv: Command line arguments (default: None; sys.argv is read) + * testRunner: Test runner instance (default: None) + * testLoader: Test loader instance (default: None) + * env: Environment; ignored if config is provided (default: None; + os.environ is read) + * config: :class:`nose.config.Config` instance (default: None) + * suite: Suite or list of tests to run (default: None). Passing a + suite or lists of tests will bypass all test discovery and + loading. *ALSO NOTE* that if you pass a unittest.TestSuite + instance as the suite, context fixtures at the class, module and + package level will not be used, and many plugin hooks will not + be called. If you want normal nose behavior, either pass a list + of tests, or a fully-configured :class:`nose.suite.ContextSuite`. + * exit: Exit after running tests and printing report (default: True) + * plugins: List of plugins to use; ignored if config is provided + (default: load plugins with DefaultPluginManager) + * addplugins: List of **extra** plugins to use. Pass a list of plugin + instances in this argument to make custom plugins available while + still using the DefaultPluginManager. + """ + verbosity = 1 + + def __init__(self, module=None, defaultTest='.', argv=None, + testRunner=None, testLoader=None, env=None, config=None, + suite=None, exit=True, plugins=None, addplugins=None): + if env is None: + env = os.environ + if config is None: + config = self.makeConfig(env, plugins) + if addplugins: + config.plugins.addPlugins(extraplugins=addplugins) + self.config = config + self.suite = suite + self.exit = exit + extra_args = {} + version = sys.version_info[0:2] + if version >= (2,7) and version != (3,0): + extra_args['exit'] = exit + unittest.TestProgram.__init__( + self, module=module, defaultTest=defaultTest, + argv=argv, testRunner=testRunner, testLoader=testLoader, + **extra_args) + + def getAllConfigFiles(self, env=None): + env = env or {} + if env.get('NOSE_IGNORE_CONFIG_FILES', False): + return [] + else: + return all_config_files() + + def makeConfig(self, env, plugins=None): + """Load a Config, pre-filled with user config files if any are + found. + """ + cfg_files = self.getAllConfigFiles(env) + if plugins: + manager = PluginManager(plugins=plugins) + else: + manager = DefaultPluginManager() + return Config( + env=env, files=cfg_files, plugins=manager) + + def parseArgs(self, argv): + """Parse argv and env and configure running environment. + """ + self.config.configure(argv, doc=self.usage()) + log.debug("configured %s", self.config) + + # quick outs: version, plugins (optparse would have already + # caught and exited on help) + if self.config.options.version: + from nose import __version__ + sys.stdout = sys.__stdout__ + print "%s version %s" % (os.path.basename(sys.argv[0]), __version__) + sys.exit(0) + + if self.config.options.showPlugins: + self.showPlugins() + sys.exit(0) + + if self.testLoader is None: + self.testLoader = defaultTestLoader(config=self.config) + elif isclass(self.testLoader): + self.testLoader = self.testLoader(config=self.config) + plug_loader = self.config.plugins.prepareTestLoader(self.testLoader) + if plug_loader is not None: + self.testLoader = plug_loader + log.debug("test loader is %s", self.testLoader) + + # FIXME if self.module is a string, add it to self.testNames? not sure + + if self.config.testNames: + self.testNames = self.config.testNames + else: + self.testNames = tolist(self.defaultTest) + log.debug('defaultTest %s', self.defaultTest) + log.debug('Test names are %s', self.testNames) + if self.config.workingDir is not None: + os.chdir(self.config.workingDir) + self.createTests() + + def createTests(self): + """Create the tests to run. If a self.suite + is set, then that suite will be used. Otherwise, tests will be + loaded from the given test names (self.testNames) using the + test loader. + """ + log.debug("createTests called with %s", self.suite) + if self.suite is not None: + # We were given an explicit suite to run. Make sure it's + # loaded and wrapped correctly. + self.test = self.testLoader.suiteClass(self.suite) + else: + self.test = self.testLoader.loadTestsFromNames(self.testNames) + + def runTests(self): + """Run Tests. Returns true on success, false on failure, and sets + self.success to the same value. + """ + log.debug("runTests called") + if self.testRunner is None: + self.testRunner = TextTestRunner(stream=self.config.stream, + verbosity=self.config.verbosity, + config=self.config) + plug_runner = self.config.plugins.prepareTestRunner(self.testRunner) + if plug_runner is not None: + self.testRunner = plug_runner + result = self.testRunner.run(self.test) + self.success = result.wasSuccessful() + if self.exit: + sys.exit(not self.success) + return self.success + + def showPlugins(self): + """Print list of available plugins. + """ + import textwrap + + class DummyParser: + def __init__(self): + self.options = [] + def add_option(self, *arg, **kw): + self.options.append((arg, kw.pop('help', ''))) + + v = self.config.verbosity + self.config.plugins.sort() + for p in self.config.plugins: + print "Plugin %s" % p.name + if v >= 2: + print " score: %s" % p.score + print '\n'.join(textwrap.wrap(p.help().strip(), + initial_indent=' ', + subsequent_indent=' ')) + if v >= 3: + parser = DummyParser() + p.addOptions(parser) + if len(parser.options): + print + print " Options:" + for opts, help in parser.options: + print ' %s' % (', '.join(opts)) + if help: + print '\n'.join( + textwrap.wrap(help.strip(), + initial_indent=' ', + subsequent_indent=' ')) + print + + def usage(cls): + import nose + try: + ld = nose.__loader__ + text = ld.get_data(os.path.join( + os.path.dirname(__file__), 'usage.txt')) + except AttributeError: + f = open(os.path.join( + os.path.dirname(__file__), 'usage.txt'), 'r') + try: + text = f.read() + finally: + f.close() + # Ensure that we return str, not bytes. + if not isinstance(text, str): + text = text.decode('utf-8') + return text + usage = classmethod(usage) + +# backwards compatibility +run_exit = main = TestProgram + + +def run(*arg, **kw): + """Collect and run tests, returning success or failure. + + The arguments to `run()` are the same as to `main()`: + + * module: All tests are in this module (default: None) + * defaultTest: Tests to load (default: '.') + * argv: Command line arguments (default: None; sys.argv is read) + * testRunner: Test runner instance (default: None) + * testLoader: Test loader instance (default: None) + * env: Environment; ignored if config is provided (default: None; + os.environ is read) + * config: :class:`nose.config.Config` instance (default: None) + * suite: Suite or list of tests to run (default: None). Passing a + suite or lists of tests will bypass all test discovery and + loading. *ALSO NOTE* that if you pass a unittest.TestSuite + instance as the suite, context fixtures at the class, module and + package level will not be used, and many plugin hooks will not + be called. If you want normal nose behavior, either pass a list + of tests, or a fully-configured :class:`nose.suite.ContextSuite`. + * plugins: List of plugins to use; ignored if config is provided + (default: load plugins with DefaultPluginManager) + * addplugins: List of **extra** plugins to use. Pass a list of plugin + instances in this argument to make custom plugins available while + still using the DefaultPluginManager. + + With the exception that the ``exit`` argument is always set + to False. + """ + kw['exit'] = False + return TestProgram(*arg, **kw).success + + +def runmodule(name='__main__', **kw): + """Collect and run tests in a single module only. Defaults to running + tests in __main__. Additional arguments to TestProgram may be passed + as keyword arguments. + """ + main(defaultTest=name, **kw) + + +def collector(): + """TestSuite replacement entry point. Use anywhere you might use a + unittest.TestSuite. The collector will, by default, load options from + all config files and execute loader.loadTestsFromNames() on the + configured testNames, or '.' if no testNames are configured. + """ + # plugins that implement any of these methods are disabled, since + # we don't control the test runner and won't be able to run them + # finalize() is also not called, but plugins that use it aren't disabled, + # because capture needs it. + setuptools_incompat = ('report', 'prepareTest', + 'prepareTestLoader', 'prepareTestRunner', + 'setOutputStream') + + plugins = RestrictedPluginManager(exclude=setuptools_incompat) + conf = Config(files=all_config_files(), + plugins=plugins) + conf.configure(argv=['collector']) + loader = defaultTestLoader(conf) + + if conf.testNames: + suite = loader.loadTestsFromNames(conf.testNames) + else: + suite = loader.loadTestsFromNames(('.',)) + return FinalizingSuiteWrapper(suite, plugins.finalize) + + + +if __name__ == '__main__': + main() diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/core.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/core.pyc new file mode 100644 index 0000000000000000000000000000000000000000..af00ee7f36ac4cbe742b06897529c6dd4a94c6c7 GIT binary patch literal 13791 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 E0Q0;FxBvhE literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/exc.py b/.eggs/nose-1.3.7-py2.7.egg/nose/exc.py new file mode 100644 index 0000000..8b780db --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/exc.py @@ -0,0 +1,9 @@ +"""Exceptions for marking tests as skipped or deprecated. + +This module exists to provide backwards compatibility with previous +versions of nose where skipped and deprecated tests were core +functionality, rather than being provided by plugins. It may be +removed in a future release. +""" +from nose.plugins.skip import SkipTest +from nose.plugins.deprecated import DeprecatedTest diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/exc.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/exc.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d2a0c535d29a6ababb4f72ba377d6e5de0733db3 GIT binary patch literal 608 zcmZ8ev2NQi5T$H4Ed;bkrVL$fG>V!+n;}aPWJrbrMTaEq;KiWHvqV@T2_7X|W52l{ z&>kH(2}*z`-n&P>yQk^zx8<+*+n-t-*Mz^Kum)kR^meDBA<(`HD%rJdZ5m-`Q^O=2tnaBDFw#NUZ@_s%*fkjO zNm4oULi5c}u9IP?VaBRlFdW6vSwRI%nYvLJ4W|R>- zKk#JMfr3q+dVV-!i;7T|_7AT)`yng=l_?UoxRJF^UQh<^o`T%2eDgK9kKRtR8gy_s))f;6~@$fw?H>k r66>0(EW7w5FXZJSjGyIYMh{?xdo7usNBZ*k^R9BwG~;kmoECopSaP)x literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/ext/__init__.py b/.eggs/nose-1.3.7-py2.7.egg/nose/ext/__init__.py new file mode 100644 index 0000000..5fd1516 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/ext/__init__.py @@ -0,0 +1,3 @@ +""" +External or vendor files +""" diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/ext/__init__.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/ext/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e41ff3d49dd7d034bd66bacee28bff121456e05d GIT binary patch literal 221 zcmYL>F$=;l5QS4aC;|U~E*-lxK^?k?xVXAV9b7_b&RDET$;Hx+{$~GxR}nmT-+TAq zE`HDXYk5Cc>^Bklo`jsB8M_c8c1kB>w;=FCAHdtPNt{nQu$t^zH-P+@j>ln2P)fT> zsgxr70}EPZf#6XZ561bS^i}Cg>7jKf+acVX&A@h2fH5eoL&#QQBl4^r)*>I), and the final +line of output is "Test failed.". + +Run it with the -v switch instead: + +python M.py -v + +and a detailed report of all examples tried is printed to stdout, along +with assorted summaries at the end. + +You can force verbose mode by passing "verbose=True" to testmod, or prohibit +it by passing "verbose=False". In either of those cases, sys.argv is not +examined by testmod. + +There are a variety of other ways to run doctests, including integration +with the unittest framework, and support for running non-Python text +files containing doctests. There are also many ways to override parts +of doctest's default behaviors. See the Library Reference Manual for +details. +""" + +__docformat__ = 'reStructuredText en' + +__all__ = [ + # 0, Option Flags + 'register_optionflag', + 'DONT_ACCEPT_TRUE_FOR_1', + 'DONT_ACCEPT_BLANKLINE', + 'NORMALIZE_WHITESPACE', + 'ELLIPSIS', + 'IGNORE_EXCEPTION_DETAIL', + 'COMPARISON_FLAGS', + 'REPORT_UDIFF', + 'REPORT_CDIFF', + 'REPORT_NDIFF', + 'REPORT_ONLY_FIRST_FAILURE', + 'REPORTING_FLAGS', + # 1. Utility Functions + 'is_private', + # 2. Example & DocTest + 'Example', + 'DocTest', + # 3. Doctest Parser + 'DocTestParser', + # 4. Doctest Finder + 'DocTestFinder', + # 5. Doctest Runner + 'DocTestRunner', + 'OutputChecker', + 'DocTestFailure', + 'UnexpectedException', + 'DebugRunner', + # 6. Test Functions + 'testmod', + 'testfile', + 'run_docstring_examples', + # 7. Tester + 'Tester', + # 8. Unittest Support + 'DocTestSuite', + 'DocFileSuite', + 'set_unittest_reportflags', + # 9. Debugging Support + 'script_from_examples', + 'testsource', + 'debug_src', + 'debug', +] + +import __future__ + +import sys, traceback, inspect, linecache, os, re +import unittest, difflib, pdb, tempfile +import warnings +from StringIO import StringIO + +# Don't whine about the deprecated is_private function in this +# module's tests. +warnings.filterwarnings("ignore", "is_private", DeprecationWarning, + __name__, 0) + +# There are 4 basic classes: +# - Example: a pair, plus an intra-docstring line number. +# - DocTest: a collection of examples, parsed from a docstring, plus +# info about where the docstring came from (name, filename, lineno). +# - DocTestFinder: extracts DocTests from a given object's docstring and +# its contained objects' docstrings. +# - DocTestRunner: runs DocTest cases, and accumulates statistics. +# +# So the basic picture is: +# +# list of: +# +------+ +---------+ +-------+ +# |object| --DocTestFinder-> | DocTest | --DocTestRunner-> |results| +# +------+ +---------+ +-------+ +# | Example | +# | ... | +# | Example | +# +---------+ + +# Option constants. + +OPTIONFLAGS_BY_NAME = {} +def register_optionflag(name): + # Create a new flag unless `name` is already known. + return OPTIONFLAGS_BY_NAME.setdefault(name, 1 << len(OPTIONFLAGS_BY_NAME)) + +DONT_ACCEPT_TRUE_FOR_1 = register_optionflag('DONT_ACCEPT_TRUE_FOR_1') +DONT_ACCEPT_BLANKLINE = register_optionflag('DONT_ACCEPT_BLANKLINE') +NORMALIZE_WHITESPACE = register_optionflag('NORMALIZE_WHITESPACE') +ELLIPSIS = register_optionflag('ELLIPSIS') +IGNORE_EXCEPTION_DETAIL = register_optionflag('IGNORE_EXCEPTION_DETAIL') + +COMPARISON_FLAGS = (DONT_ACCEPT_TRUE_FOR_1 | + DONT_ACCEPT_BLANKLINE | + NORMALIZE_WHITESPACE | + ELLIPSIS | + IGNORE_EXCEPTION_DETAIL) + +REPORT_UDIFF = register_optionflag('REPORT_UDIFF') +REPORT_CDIFF = register_optionflag('REPORT_CDIFF') +REPORT_NDIFF = register_optionflag('REPORT_NDIFF') +REPORT_ONLY_FIRST_FAILURE = register_optionflag('REPORT_ONLY_FIRST_FAILURE') + +REPORTING_FLAGS = (REPORT_UDIFF | + REPORT_CDIFF | + REPORT_NDIFF | + REPORT_ONLY_FIRST_FAILURE) + +# Special string markers for use in `want` strings: +BLANKLINE_MARKER = '' +ELLIPSIS_MARKER = '...' + +###################################################################### +## Table of Contents +###################################################################### +# 1. Utility Functions +# 2. Example & DocTest -- store test cases +# 3. DocTest Parser -- extracts examples from strings +# 4. DocTest Finder -- extracts test cases from objects +# 5. DocTest Runner -- runs test cases +# 6. Test Functions -- convenient wrappers for testing +# 7. Tester Class -- for backwards compatibility +# 8. Unittest Support +# 9. Debugging Support +# 10. Example Usage + +###################################################################### +## 1. Utility Functions +###################################################################### + +def is_private(prefix, base): + """prefix, base -> true iff name prefix + "." + base is "private". + + Prefix may be an empty string, and base does not contain a period. + Prefix is ignored (although functions you write conforming to this + protocol may make use of it). + Return true iff base begins with an (at least one) underscore, but + does not both begin and end with (at least) two underscores. + """ + warnings.warn("is_private is deprecated; it wasn't useful; " + "examine DocTestFinder.find() lists instead", + DeprecationWarning, stacklevel=2) + return base[:1] == "_" and not base[:2] == "__" == base[-2:] + +def _extract_future_flags(globs): + """ + Return the compiler-flags associated with the future features that + have been imported into the given namespace (globs). + """ + flags = 0 + for fname in __future__.all_feature_names: + feature = globs.get(fname, None) + if feature is getattr(__future__, fname): + flags |= feature.compiler_flag + return flags + +def _normalize_module(module, depth=2): + """ + Return the module specified by `module`. In particular: + - If `module` is a module, then return module. + - If `module` is a string, then import and return the + module with that name. + - If `module` is None, then return the calling module. + The calling module is assumed to be the module of + the stack frame at the given depth in the call stack. + """ + if inspect.ismodule(module): + return module + elif isinstance(module, (str, unicode)): + return __import__(module, globals(), locals(), ["*"]) + elif module is None: + return sys.modules[sys._getframe(depth).f_globals['__name__']] + else: + raise TypeError("Expected a module, string, or None") + +def _indent(s, indent=4): + """ + Add the given number of space characters to the beginning every + non-blank line in `s`, and return the result. + """ + # This regexp matches the start of non-blank lines: + return re.sub('(?m)^(?!$)', indent*' ', s) + +def _exception_traceback(exc_info): + """ + Return a string containing a traceback message for the given + exc_info tuple (as returned by sys.exc_info()). + """ + # Get a traceback message. + excout = StringIO() + exc_type, exc_val, exc_tb = exc_info + traceback.print_exception(exc_type, exc_val, exc_tb, file=excout) + return excout.getvalue() + +# Override some StringIO methods. +class _SpoofOut(StringIO): + def getvalue(self): + result = StringIO.getvalue(self) + # If anything at all was written, make sure there's a trailing + # newline. There's no way for the expected output to indicate + # that a trailing newline is missing. + if result and not result.endswith("\n"): + result += "\n" + # Prevent softspace from screwing up the next test case, in + # case they used print with a trailing comma in an example. + if hasattr(self, "softspace"): + del self.softspace + return result + + def truncate(self, size=None): + StringIO.truncate(self, size) + if hasattr(self, "softspace"): + del self.softspace + +# Worst-case linear-time ellipsis matching. +def _ellipsis_match(want, got): + if ELLIPSIS_MARKER not in want: + return want == got + + # Find "the real" strings. + ws = want.split(ELLIPSIS_MARKER) + assert len(ws) >= 2 + + # Deal with exact matches possibly needed at one or both ends. + startpos, endpos = 0, len(got) + w = ws[0] + if w: # starts with exact match + if got.startswith(w): + startpos = len(w) + del ws[0] + else: + return False + w = ws[-1] + if w: # ends with exact match + if got.endswith(w): + endpos -= len(w) + del ws[-1] + else: + return False + + if startpos > endpos: + # Exact end matches required more characters than we have, as in + # _ellipsis_match('aa...aa', 'aaa') + return False + + # For the rest, we only need to find the leftmost non-overlapping + # match for each piece. If there's no overall match that way alone, + # there's no overall match period. + for w in ws: + # w may be '' at times, if there are consecutive ellipses, or + # due to an ellipsis at the start or end of `want`. That's OK. + # Search for an empty string succeeds, and doesn't change startpos. + startpos = got.find(w, startpos, endpos) + if startpos < 0: + return False + startpos += len(w) + + return True + +def _comment_line(line): + "Return a commented form of the given line" + line = line.rstrip() + if line: + return '# '+line + else: + return '#' + +class _OutputRedirectingPdb(pdb.Pdb): + """ + A specialized version of the python debugger that redirects stdout + to a given stream when interacting with the user. Stdout is *not* + redirected when traced code is executed. + """ + def __init__(self, out): + self.__out = out + pdb.Pdb.__init__(self) + + def trace_dispatch(self, *args): + # Redirect stdout to the given stream. + save_stdout = sys.stdout + sys.stdout = self.__out + # Call Pdb's trace dispatch method. + try: + return pdb.Pdb.trace_dispatch(self, *args) + finally: + sys.stdout = save_stdout + +# [XX] Normalize with respect to os.path.pardir? +def _module_relative_path(module, path): + if not inspect.ismodule(module): + raise TypeError, 'Expected a module: %r' % module + if path.startswith('/'): + raise ValueError, 'Module-relative files may not have absolute paths' + + # Find the base directory for the path. + if hasattr(module, '__file__'): + # A normal module/package + basedir = os.path.split(module.__file__)[0] + elif module.__name__ == '__main__': + # An interactive session. + if len(sys.argv)>0 and sys.argv[0] != '': + basedir = os.path.split(sys.argv[0])[0] + else: + basedir = os.curdir + else: + # A module w/o __file__ (this includes builtins) + raise ValueError("Can't resolve paths relative to the module " + + module + " (it has no __file__)") + + # Combine the base directory and the path. + return os.path.join(basedir, *(path.split('/'))) + +###################################################################### +## 2. Example & DocTest +###################################################################### +## - An "example" is a pair, where "source" is a +## fragment of source code, and "want" is the expected output for +## "source." The Example class also includes information about +## where the example was extracted from. +## +## - A "doctest" is a collection of examples, typically extracted from +## a string (such as an object's docstring). The DocTest class also +## includes information about where the string was extracted from. + +class Example: + """ + A single doctest example, consisting of source code and expected + output. `Example` defines the following attributes: + + - source: A single Python statement, always ending with a newline. + The constructor adds a newline if needed. + + - want: The expected output from running the source code (either + from stdout, or a traceback in case of exception). `want` ends + with a newline unless it's empty, in which case it's an empty + string. The constructor adds a newline if needed. + + - exc_msg: The exception message generated by the example, if + the example is expected to generate an exception; or `None` if + it is not expected to generate an exception. This exception + message is compared against the return value of + `traceback.format_exception_only()`. `exc_msg` ends with a + newline unless it's `None`. The constructor adds a newline + if needed. + + - lineno: The line number within the DocTest string containing + this Example where the Example begins. This line number is + zero-based, with respect to the beginning of the DocTest. + + - indent: The example's indentation in the DocTest string. + I.e., the number of space characters that preceed the + example's first prompt. + + - options: A dictionary mapping from option flags to True or + False, which is used to override default options for this + example. Any option flags not contained in this dictionary + are left at their default value (as specified by the + DocTestRunner's optionflags). By default, no options are set. + """ + def __init__(self, source, want, exc_msg=None, lineno=0, indent=0, + options=None): + # Normalize inputs. + if not source.endswith('\n'): + source += '\n' + if want and not want.endswith('\n'): + want += '\n' + if exc_msg is not None and not exc_msg.endswith('\n'): + exc_msg += '\n' + # Store properties. + self.source = source + self.want = want + self.lineno = lineno + self.indent = indent + if options is None: options = {} + self.options = options + self.exc_msg = exc_msg + +class DocTest: + """ + A collection of doctest examples that should be run in a single + namespace. Each `DocTest` defines the following attributes: + + - examples: the list of examples. + + - globs: The namespace (aka globals) that the examples should + be run in. + + - name: A name identifying the DocTest (typically, the name of + the object whose docstring this DocTest was extracted from). + + - filename: The name of the file that this DocTest was extracted + from, or `None` if the filename is unknown. + + - lineno: The line number within filename where this DocTest + begins, or `None` if the line number is unavailable. This + line number is zero-based, with respect to the beginning of + the file. + + - docstring: The string that the examples were extracted from, + or `None` if the string is unavailable. + """ + def __init__(self, examples, globs, name, filename, lineno, docstring): + """ + Create a new DocTest containing the given examples. The + DocTest's globals are initialized with a copy of `globs`. + """ + assert not isinstance(examples, basestring), \ + "DocTest no longer accepts str; use DocTestParser instead" + self.examples = examples + self.docstring = docstring + self.globs = globs.copy() + self.name = name + self.filename = filename + self.lineno = lineno + + def __repr__(self): + if len(self.examples) == 0: + examples = 'no examples' + elif len(self.examples) == 1: + examples = '1 example' + else: + examples = '%d examples' % len(self.examples) + return ('' % + (self.name, self.filename, self.lineno, examples)) + + + # This lets us sort tests by name: + def __cmp__(self, other): + if not isinstance(other, DocTest): + return -1 + return cmp((self.name, self.filename, self.lineno, id(self)), + (other.name, other.filename, other.lineno, id(other))) + +###################################################################### +## 3. DocTestParser +###################################################################### + +class DocTestParser: + """ + A class used to parse strings containing doctest examples. + """ + # This regular expression is used to find doctest examples in a + # string. It defines three groups: `source` is the source code + # (including leading indentation and prompts); `indent` is the + # indentation of the first (PS1) line of the source code; and + # `want` is the expected output (including leading indentation). + _EXAMPLE_RE = re.compile(r''' + # Source consists of a PS1 line followed by zero or more PS2 lines. + (?P + (?:^(?P [ ]*) >>> .*) # PS1 line + (?:\n [ ]* \.\.\. .*)*) # PS2 lines + \n? + # Want consists of any non-blank lines that do not start with PS1. + (?P (?:(?![ ]*$) # Not a blank line + (?![ ]*>>>) # Not a line starting with PS1 + .*$\n? # But any other line + )*) + ''', re.MULTILINE | re.VERBOSE) + + # A regular expression for handling `want` strings that contain + # expected exceptions. It divides `want` into three pieces: + # - the traceback header line (`hdr`) + # - the traceback stack (`stack`) + # - the exception message (`msg`), as generated by + # traceback.format_exception_only() + # `msg` may have multiple lines. We assume/require that the + # exception message is the first non-indented line starting with a word + # character following the traceback header line. + _EXCEPTION_RE = re.compile(r""" + # Grab the traceback header. Different versions of Python have + # said different things on the first traceback line. + ^(?P Traceback\ \( + (?: most\ recent\ call\ last + | innermost\ last + ) \) : + ) + \s* $ # toss trailing whitespace on the header. + (?P .*?) # don't blink: absorb stuff until... + ^ (?P \w+ .*) # a line *starts* with alphanum. + """, re.VERBOSE | re.MULTILINE | re.DOTALL) + + # A callable returning a true value iff its argument is a blank line + # or contains a single comment. + _IS_BLANK_OR_COMMENT = re.compile(r'^[ ]*(#.*)?$').match + + def parse(self, string, name=''): + """ + Divide the given string into examples and intervening text, + and return them as a list of alternating Examples and strings. + Line numbers for the Examples are 0-based. The optional + argument `name` is a name identifying this string, and is only + used for error messages. + """ + string = string.expandtabs() + # If all lines begin with the same indentation, then strip it. + min_indent = self._min_indent(string) + if min_indent > 0: + string = '\n'.join([l[min_indent:] for l in string.split('\n')]) + + output = [] + charno, lineno = 0, 0 + # Find all doctest examples in the string: + for m in self._EXAMPLE_RE.finditer(string): + # Add the pre-example text to `output`. + output.append(string[charno:m.start()]) + # Update lineno (lines before this example) + lineno += string.count('\n', charno, m.start()) + # Extract info from the regexp match. + (source, options, want, exc_msg) = \ + self._parse_example(m, name, lineno) + # Create an Example, and add it to the list. + if not self._IS_BLANK_OR_COMMENT(source): + output.append( Example(source, want, exc_msg, + lineno=lineno, + indent=min_indent+len(m.group('indent')), + options=options) ) + # Update lineno (lines inside this example) + lineno += string.count('\n', m.start(), m.end()) + # Update charno. + charno = m.end() + # Add any remaining post-example text to `output`. + output.append(string[charno:]) + return output + + def get_doctest(self, string, globs, name, filename, lineno): + """ + Extract all doctest examples from the given string, and + collect them into a `DocTest` object. + + `globs`, `name`, `filename`, and `lineno` are attributes for + the new `DocTest` object. See the documentation for `DocTest` + for more information. + """ + return DocTest(self.get_examples(string, name), globs, + name, filename, lineno, string) + + def get_examples(self, string, name=''): + """ + Extract all doctest examples from the given string, and return + them as a list of `Example` objects. Line numbers are + 0-based, because it's most common in doctests that nothing + interesting appears on the same line as opening triple-quote, + and so the first interesting line is called \"line 1\" then. + + The optional argument `name` is a name identifying this + string, and is only used for error messages. + """ + return [x for x in self.parse(string, name) + if isinstance(x, Example)] + + def _parse_example(self, m, name, lineno): + """ + Given a regular expression match from `_EXAMPLE_RE` (`m`), + return a pair `(source, want)`, where `source` is the matched + example's source code (with prompts and indentation stripped); + and `want` is the example's expected output (with indentation + stripped). + + `name` is the string's name, and `lineno` is the line number + where the example starts; both are used for error messages. + """ + # Get the example's indentation level. + indent = len(m.group('indent')) + + # Divide source into lines; check that they're properly + # indented; and then strip their indentation & prompts. + source_lines = m.group('source').split('\n') + self._check_prompt_blank(source_lines, indent, name, lineno) + self._check_prefix(source_lines[1:], ' '*indent + '.', name, lineno) + source = '\n'.join([sl[indent+4:] for sl in source_lines]) + + # Divide want into lines; check that it's properly indented; and + # then strip the indentation. Spaces before the last newline should + # be preserved, so plain rstrip() isn't good enough. + want = m.group('want') + want_lines = want.split('\n') + if len(want_lines) > 1 and re.match(r' *$', want_lines[-1]): + del want_lines[-1] # forget final newline & spaces after it + self._check_prefix(want_lines, ' '*indent, name, + lineno + len(source_lines)) + want = '\n'.join([wl[indent:] for wl in want_lines]) + + # If `want` contains a traceback message, then extract it. + m = self._EXCEPTION_RE.match(want) + if m: + exc_msg = m.group('msg') + else: + exc_msg = None + + # Extract options from the source. + options = self._find_options(source, name, lineno) + + return source, options, want, exc_msg + + # This regular expression looks for option directives in the + # source code of an example. Option directives are comments + # starting with "doctest:". Warning: this may give false + # positives for string-literals that contain the string + # "#doctest:". Eliminating these false positives would require + # actually parsing the string; but we limit them by ignoring any + # line containing "#doctest:" that is *followed* by a quote mark. + _OPTION_DIRECTIVE_RE = re.compile(r'#\s*doctest:\s*([^\n\'"]*)$', + re.MULTILINE) + + def _find_options(self, source, name, lineno): + """ + Return a dictionary containing option overrides extracted from + option directives in the given source string. + + `name` is the string's name, and `lineno` is the line number + where the example starts; both are used for error messages. + """ + options = {} + # (note: with the current regexp, this will match at most once:) + for m in self._OPTION_DIRECTIVE_RE.finditer(source): + option_strings = m.group(1).replace(',', ' ').split() + for option in option_strings: + if (option[0] not in '+-' or + option[1:] not in OPTIONFLAGS_BY_NAME): + raise ValueError('line %r of the doctest for %s ' + 'has an invalid option: %r' % + (lineno+1, name, option)) + flag = OPTIONFLAGS_BY_NAME[option[1:]] + options[flag] = (option[0] == '+') + if options and self._IS_BLANK_OR_COMMENT(source): + raise ValueError('line %r of the doctest for %s has an option ' + 'directive on a line with no example: %r' % + (lineno, name, source)) + return options + + # This regular expression finds the indentation of every non-blank + # line in a string. + _INDENT_RE = re.compile('^([ ]*)(?=\S)', re.MULTILINE) + + def _min_indent(self, s): + "Return the minimum indentation of any non-blank line in `s`" + indents = [len(indent) for indent in self._INDENT_RE.findall(s)] + if len(indents) > 0: + return min(indents) + else: + return 0 + + def _check_prompt_blank(self, lines, indent, name, lineno): + """ + Given the lines of a source string (including prompts and + leading indentation), check to make sure that every prompt is + followed by a space character. If any line is not followed by + a space character, then raise ValueError. + """ + for i, line in enumerate(lines): + if len(line) >= indent+4 and line[indent+3] != ' ': + raise ValueError('line %r of the docstring for %s ' + 'lacks blank after %s: %r' % + (lineno+i+1, name, + line[indent:indent+3], line)) + + def _check_prefix(self, lines, prefix, name, lineno): + """ + Check that every line in the given list starts with the given + prefix; if any line does not, then raise a ValueError. + """ + for i, line in enumerate(lines): + if line and not line.startswith(prefix): + raise ValueError('line %r of the docstring for %s has ' + 'inconsistent leading whitespace: %r' % + (lineno+i+1, name, line)) + + +###################################################################### +## 4. DocTest Finder +###################################################################### + +class DocTestFinder: + """ + A class used to extract the DocTests that are relevant to a given + object, from its docstring and the docstrings of its contained + objects. Doctests can currently be extracted from the following + object types: modules, functions, classes, methods, staticmethods, + classmethods, and properties. + """ + + def __init__(self, verbose=False, parser=DocTestParser(), + recurse=True, _namefilter=None, exclude_empty=True): + """ + Create a new doctest finder. + + The optional argument `parser` specifies a class or + function that should be used to create new DocTest objects (or + objects that implement the same interface as DocTest). The + signature for this factory function should match the signature + of the DocTest constructor. + + If the optional argument `recurse` is false, then `find` will + only examine the given object, and not any contained objects. + + If the optional argument `exclude_empty` is false, then `find` + will include tests for objects with empty docstrings. + """ + self._parser = parser + self._verbose = verbose + self._recurse = recurse + self._exclude_empty = exclude_empty + # _namefilter is undocumented, and exists only for temporary backward- + # compatibility support of testmod's deprecated isprivate mess. + self._namefilter = _namefilter + + def find(self, obj, name=None, module=None, globs=None, + extraglobs=None): + """ + Return a list of the DocTests that are defined by the given + object's docstring, or by any of its contained objects' + docstrings. + + The optional parameter `module` is the module that contains + the given object. If the module is not specified or is None, then + the test finder will attempt to automatically determine the + correct module. The object's module is used: + + - As a default namespace, if `globs` is not specified. + - To prevent the DocTestFinder from extracting DocTests + from objects that are imported from other modules. + - To find the name of the file containing the object. + - To help find the line number of the object within its + file. + + Contained objects whose module does not match `module` are ignored. + + If `module` is False, no attempt to find the module will be made. + This is obscure, of use mostly in tests: if `module` is False, or + is None but cannot be found automatically, then all objects are + considered to belong to the (non-existent) module, so all contained + objects will (recursively) be searched for doctests. + + The globals for each DocTest is formed by combining `globs` + and `extraglobs` (bindings in `extraglobs` override bindings + in `globs`). A new copy of the globals dictionary is created + for each DocTest. If `globs` is not specified, then it + defaults to the module's `__dict__`, if specified, or {} + otherwise. If `extraglobs` is not specified, then it defaults + to {}. + + """ + # If name was not specified, then extract it from the object. + if name is None: + name = getattr(obj, '__name__', None) + if name is None: + raise ValueError("DocTestFinder.find: name must be given " + "when obj.__name__ doesn't exist: %r" % + (type(obj),)) + + # Find the module that contains the given object (if obj is + # a module, then module=obj.). Note: this may fail, in which + # case module will be None. + if module is False: + module = None + elif module is None: + module = inspect.getmodule(obj) + + # Read the module's source code. This is used by + # DocTestFinder._find_lineno to find the line number for a + # given object's docstring. + try: + file = inspect.getsourcefile(obj) or inspect.getfile(obj) + source_lines = linecache.getlines(file) + if not source_lines: + source_lines = None + except TypeError: + source_lines = None + + # Initialize globals, and merge in extraglobs. + if globs is None: + if module is None: + globs = {} + else: + globs = module.__dict__.copy() + else: + globs = globs.copy() + if extraglobs is not None: + globs.update(extraglobs) + + # Recursively expore `obj`, extracting DocTests. + tests = [] + self._find(tests, obj, name, module, source_lines, globs, {}) + # Sort the tests by alpha order of names, for consistency in + # verbose-mode output. This was a feature of doctest in Pythons + # <= 2.3 that got lost by accident in 2.4. It was repaired in + # 2.4.4 and 2.5. + tests.sort() + return tests + + def _filter(self, obj, prefix, base): + """ + Return true if the given object should not be examined. + """ + return (self._namefilter is not None and + self._namefilter(prefix, base)) + + def _from_module(self, module, object): + """ + Return true if the given object is defined in the given + module. + """ + if module is None: + return True + elif inspect.isfunction(object): + return module.__dict__ is object.func_globals + elif inspect.isclass(object): + # Some jython classes don't set __module__ + return module.__name__ == getattr(object, '__module__', None) + elif inspect.getmodule(object) is not None: + return module is inspect.getmodule(object) + elif hasattr(object, '__module__'): + return module.__name__ == object.__module__ + elif isinstance(object, property): + return True # [XX] no way not be sure. + else: + raise ValueError("object must be a class or function") + + def _find(self, tests, obj, name, module, source_lines, globs, seen): + """ + Find tests for the given object and any contained objects, and + add them to `tests`. + """ + if self._verbose: + print 'Finding tests in %s' % name + + # If we've already processed this object, then ignore it. + if id(obj) in seen: + return + seen[id(obj)] = 1 + + # Find a test for this object, and add it to the list of tests. + test = self._get_test(obj, name, module, globs, source_lines) + if test is not None: + tests.append(test) + + # Look for tests in a module's contained objects. + if inspect.ismodule(obj) and self._recurse: + for valname, val in obj.__dict__.items(): + # Check if this contained object should be ignored. + if self._filter(val, name, valname): + continue + valname = '%s.%s' % (name, valname) + # Recurse to functions & classes. + if ((inspect.isfunction(val) or inspect.isclass(val)) and + self._from_module(module, val)): + self._find(tests, val, valname, module, source_lines, + globs, seen) + + # Look for tests in a module's __test__ dictionary. + if inspect.ismodule(obj) and self._recurse: + for valname, val in getattr(obj, '__test__', {}).items(): + if not isinstance(valname, basestring): + raise ValueError("DocTestFinder.find: __test__ keys " + "must be strings: %r" % + (type(valname),)) + if not (inspect.isfunction(val) or inspect.isclass(val) or + inspect.ismethod(val) or inspect.ismodule(val) or + isinstance(val, basestring)): + raise ValueError("DocTestFinder.find: __test__ values " + "must be strings, functions, methods, " + "classes, or modules: %r" % + (type(val),)) + valname = '%s.__test__.%s' % (name, valname) + self._find(tests, val, valname, module, source_lines, + globs, seen) + + # Look for tests in a class's contained objects. + if inspect.isclass(obj) and self._recurse: + for valname, val in obj.__dict__.items(): + # Check if this contained object should be ignored. + if self._filter(val, name, valname): + continue + # Special handling for staticmethod/classmethod. + if isinstance(val, staticmethod): + val = getattr(obj, valname) + if isinstance(val, classmethod): + val = getattr(obj, valname).im_func + + # Recurse to methods, properties, and nested classes. + if ((inspect.isfunction(val) or inspect.isclass(val) or + isinstance(val, property)) and + self._from_module(module, val)): + valname = '%s.%s' % (name, valname) + self._find(tests, val, valname, module, source_lines, + globs, seen) + + def _get_test(self, obj, name, module, globs, source_lines): + """ + Return a DocTest for the given object, if it defines a docstring; + otherwise, return None. + """ + # Extract the object's docstring. If it doesn't have one, + # then return None (no test for this object). + if isinstance(obj, basestring): + docstring = obj + else: + try: + if obj.__doc__ is None: + docstring = '' + else: + docstring = obj.__doc__ + if not isinstance(docstring, basestring): + docstring = str(docstring) + except (TypeError, AttributeError): + docstring = '' + + # Find the docstring's location in the file. + lineno = self._find_lineno(obj, source_lines) + + # Don't bother if the docstring is empty. + if self._exclude_empty and not docstring: + return None + + # Return a DocTest for this object. + if module is None: + filename = None + else: + filename = getattr(module, '__file__', module.__name__) + if filename[-4:] in (".pyc", ".pyo"): + filename = filename[:-1] + elif sys.platform.startswith('java') and \ + filename.endswith('$py.class'): + filename = '%s.py' % filename[:-9] + return self._parser.get_doctest(docstring, globs, name, + filename, lineno) + + def _find_lineno(self, obj, source_lines): + """ + Return a line number of the given object's docstring. Note: + this method assumes that the object has a docstring. + """ + lineno = None + + # Find the line number for modules. + if inspect.ismodule(obj): + lineno = 0 + + # Find the line number for classes. + # Note: this could be fooled if a class is defined multiple + # times in a single file. + if inspect.isclass(obj): + if source_lines is None: + return None + pat = re.compile(r'^\s*class\s*%s\b' % + getattr(obj, '__name__', '-')) + for i, line in enumerate(source_lines): + if pat.match(line): + lineno = i + break + + # Find the line number for functions & methods. + if inspect.ismethod(obj): obj = obj.im_func + if inspect.isfunction(obj): obj = obj.func_code + if inspect.istraceback(obj): obj = obj.tb_frame + if inspect.isframe(obj): obj = obj.f_code + if inspect.iscode(obj): + lineno = getattr(obj, 'co_firstlineno', None)-1 + + # Find the line number where the docstring starts. Assume + # that it's the first line that begins with a quote mark. + # Note: this could be fooled by a multiline function + # signature, where a continuation line begins with a quote + # mark. + if lineno is not None: + if source_lines is None: + return lineno+1 + pat = re.compile('(^|.*:)\s*\w*("|\')') + for lineno in range(lineno, len(source_lines)): + if pat.match(source_lines[lineno]): + return lineno + + # We couldn't find the line number. + return None + +###################################################################### +## 5. DocTest Runner +###################################################################### + +class DocTestRunner: + # This divider string is used to separate failure messages, and to + # separate sections of the summary. + DIVIDER = "*" * 70 + + def __init__(self, checker=None, verbose=None, optionflags=0): + """ + Create a new test runner. + + Optional keyword arg `checker` is the `OutputChecker` that + should be used to compare the expected outputs and actual + outputs of doctest examples. + + Optional keyword arg 'verbose' prints lots of stuff if true, + only failures if false; by default, it's true iff '-v' is in + sys.argv. + + Optional argument `optionflags` can be used to control how the + test runner compares expected output to actual output, and how + it displays failures. See the documentation for `testmod` for + more information. + """ + self._checker = checker or OutputChecker() + if verbose is None: + verbose = '-v' in sys.argv + self._verbose = verbose + self.optionflags = optionflags + self.original_optionflags = optionflags + + # Keep track of the examples we've run. + self.tries = 0 + self.failures = 0 + self._name2ft = {} + + # Create a fake output target for capturing doctest output. + self._fakeout = _SpoofOut() + + #///////////////////////////////////////////////////////////////// + # Reporting methods + #///////////////////////////////////////////////////////////////// + + def report_start(self, out, test, example): + """ + Report that the test runner is about to process the given + example. (Only displays a message if verbose=True) + """ + if self._verbose: + if example.want: + out('Trying:\n' + _indent(example.source) + + 'Expecting:\n' + _indent(example.want)) + else: + out('Trying:\n' + _indent(example.source) + + 'Expecting nothing\n') + + def report_success(self, out, test, example, got): + """ + Report that the given example ran successfully. (Only + displays a message if verbose=True) + """ + if self._verbose: + out("ok\n") + + def report_failure(self, out, test, example, got): + """ + Report that the given example failed. + """ + out(self._failure_header(test, example) + + self._checker.output_difference(example, got, self.optionflags)) + + def report_unexpected_exception(self, out, test, example, exc_info): + """ + Report that the given example raised an unexpected exception. + """ + out(self._failure_header(test, example) + + 'Exception raised:\n' + _indent(_exception_traceback(exc_info))) + + def _failure_header(self, test, example): + out = [self.DIVIDER] + if test.filename: + if test.lineno is not None and example.lineno is not None: + lineno = test.lineno + example.lineno + 1 + else: + lineno = '?' + out.append('File "%s", line %s, in %s' % + (test.filename, lineno, test.name)) + else: + out.append('Line %s, in %s' % (example.lineno+1, test.name)) + out.append('Failed example:') + source = example.source + out.append(_indent(source)) + return '\n'.join(out) + + #///////////////////////////////////////////////////////////////// + # DocTest Running + #///////////////////////////////////////////////////////////////// + + def __run(self, test, compileflags, out): + """ + Run the examples in `test`. Write the outcome of each example + with one of the `DocTestRunner.report_*` methods, using the + writer function `out`. `compileflags` is the set of compiler + flags that should be used to execute examples. Return a tuple + `(f, t)`, where `t` is the number of examples tried, and `f` + is the number of examples that failed. The examples are run + in the namespace `test.globs`. + """ + # Keep track of the number of failures and tries. + failures = tries = 0 + + # Save the option flags (since option directives can be used + # to modify them). + original_optionflags = self.optionflags + + SUCCESS, FAILURE, BOOM = range(3) # `outcome` state + + check = self._checker.check_output + + # Process each example. + for examplenum, example in enumerate(test.examples): + + # If REPORT_ONLY_FIRST_FAILURE is set, then supress + # reporting after the first failure. + quiet = (self.optionflags & REPORT_ONLY_FIRST_FAILURE and + failures > 0) + + # Merge in the example's options. + self.optionflags = original_optionflags + if example.options: + for (optionflag, val) in example.options.items(): + if val: + self.optionflags |= optionflag + else: + self.optionflags &= ~optionflag + + # Record that we started this example. + tries += 1 + if not quiet: + self.report_start(out, test, example) + + # Use a special filename for compile(), so we can retrieve + # the source code during interactive debugging (see + # __patched_linecache_getlines). + filename = '' % (test.name, examplenum) + + # Run the example in the given context (globs), and record + # any exception that gets raised. (But don't intercept + # keyboard interrupts.) + try: + # Don't blink! This is where the user's code gets run. + exec compile(example.source, filename, "single", + compileflags, 1) in test.globs + self.debugger.set_continue() # ==== Example Finished ==== + exception = None + except KeyboardInterrupt: + raise + except: + exception = sys.exc_info() + self.debugger.set_continue() # ==== Example Finished ==== + + got = self._fakeout.getvalue() # the actual output + self._fakeout.truncate(0) + outcome = FAILURE # guilty until proved innocent or insane + + # If the example executed without raising any exceptions, + # verify its output. + if exception is None: + if check(example.want, got, self.optionflags): + outcome = SUCCESS + + # The example raised an exception: check if it was expected. + else: + exc_info = sys.exc_info() + exc_msg = traceback.format_exception_only(*exc_info[:2])[-1] + if not quiet: + got += _exception_traceback(exc_info) + + # If `example.exc_msg` is None, then we weren't expecting + # an exception. + if example.exc_msg is None: + outcome = BOOM + + # We expected an exception: see whether it matches. + elif check(example.exc_msg, exc_msg, self.optionflags): + outcome = SUCCESS + + # Another chance if they didn't care about the detail. + elif self.optionflags & IGNORE_EXCEPTION_DETAIL: + m1 = re.match(r'[^:]*:', example.exc_msg) + m2 = re.match(r'[^:]*:', exc_msg) + if m1 and m2 and check(m1.group(0), m2.group(0), + self.optionflags): + outcome = SUCCESS + + # Report the outcome. + if outcome is SUCCESS: + if not quiet: + self.report_success(out, test, example, got) + elif outcome is FAILURE: + if not quiet: + self.report_failure(out, test, example, got) + failures += 1 + elif outcome is BOOM: + if not quiet: + self.report_unexpected_exception(out, test, example, + exc_info) + failures += 1 + else: + assert False, ("unknown outcome", outcome) + + # Restore the option flags (in case they were modified) + self.optionflags = original_optionflags + + # Record and return the number of failures and tries. + self.__record_outcome(test, failures, tries) + return failures, tries + + def __record_outcome(self, test, f, t): + """ + Record the fact that the given DocTest (`test`) generated `f` + failures out of `t` tried examples. + """ + f2, t2 = self._name2ft.get(test.name, (0,0)) + self._name2ft[test.name] = (f+f2, t+t2) + self.failures += f + self.tries += t + + __LINECACHE_FILENAME_RE = re.compile(r'[\w\.]+)' + r'\[(?P\d+)\]>$') + def __patched_linecache_getlines(self, filename): + m = self.__LINECACHE_FILENAME_RE.match(filename) + if m and m.group('name') == self.test.name: + example = self.test.examples[int(m.group('examplenum'))] + return example.source.splitlines(True) + else: + return self.save_linecache_getlines(filename) + + def run(self, test, compileflags=None, out=None, clear_globs=True): + """ + Run the examples in `test`, and display the results using the + writer function `out`. + + The examples are run in the namespace `test.globs`. If + `clear_globs` is true (the default), then this namespace will + be cleared after the test runs, to help with garbage + collection. If you would like to examine the namespace after + the test completes, then use `clear_globs=False`. + + `compileflags` gives the set of flags that should be used by + the Python compiler when running the examples. If not + specified, then it will default to the set of future-import + flags that apply to `globs`. + + The output of each example is checked using + `DocTestRunner.check_output`, and the results are formatted by + the `DocTestRunner.report_*` methods. + """ + self.test = test + + if compileflags is None: + compileflags = _extract_future_flags(test.globs) + + save_stdout = sys.stdout + if out is None: + out = save_stdout.write + sys.stdout = self._fakeout + + # Patch pdb.set_trace to restore sys.stdout during interactive + # debugging (so it's not still redirected to self._fakeout). + # Note that the interactive output will go to *our* + # save_stdout, even if that's not the real sys.stdout; this + # allows us to write test cases for the set_trace behavior. + save_set_trace = pdb.set_trace + self.debugger = _OutputRedirectingPdb(save_stdout) + self.debugger.reset() + pdb.set_trace = self.debugger.set_trace + + # Patch linecache.getlines, so we can see the example's source + # when we're inside the debugger. + self.save_linecache_getlines = linecache.getlines + linecache.getlines = self.__patched_linecache_getlines + + try: + return self.__run(test, compileflags, out) + finally: + sys.stdout = save_stdout + pdb.set_trace = save_set_trace + linecache.getlines = self.save_linecache_getlines + if clear_globs: + test.globs.clear() + + #///////////////////////////////////////////////////////////////// + # Summarization + #///////////////////////////////////////////////////////////////// + def summarize(self, verbose=None): + """ + Print a summary of all the test cases that have been run by + this DocTestRunner, and return a tuple `(f, t)`, where `f` is + the total number of failed examples, and `t` is the total + number of tried examples. + + The optional `verbose` argument controls how detailed the + summary is. If the verbosity is not specified, then the + DocTestRunner's verbosity is used. + """ + if verbose is None: + verbose = self._verbose + notests = [] + passed = [] + failed = [] + totalt = totalf = 0 + for x in self._name2ft.items(): + name, (f, t) = x + assert f <= t + totalt += t + totalf += f + if t == 0: + notests.append(name) + elif f == 0: + passed.append( (name, t) ) + else: + failed.append(x) + if verbose: + if notests: + print len(notests), "items had no tests:" + notests.sort() + for thing in notests: + print " ", thing + if passed: + print len(passed), "items passed all tests:" + passed.sort() + for thing, count in passed: + print " %3d tests in %s" % (count, thing) + if failed: + print self.DIVIDER + print len(failed), "items had failures:" + failed.sort() + for thing, (f, t) in failed: + print " %3d of %3d in %s" % (f, t, thing) + if verbose: + print totalt, "tests in", len(self._name2ft), "items." + print totalt - totalf, "passed and", totalf, "failed." + if totalf: + print "***Test Failed***", totalf, "failures." + elif verbose: + print "Test passed." + return totalf, totalt + + #///////////////////////////////////////////////////////////////// + # Backward compatibility cruft to maintain doctest.master. + #///////////////////////////////////////////////////////////////// + def merge(self, other): + d = self._name2ft + for name, (f, t) in other._name2ft.items(): + if name in d: + print "*** DocTestRunner.merge: '" + name + "' in both" \ + " testers; summing outcomes." + f2, t2 = d[name] + f = f + f2 + t = t + t2 + d[name] = f, t + +class OutputChecker: + """ + A class used to check the whether the actual output from a doctest + example matches the expected output. `OutputChecker` defines two + methods: `check_output`, which compares a given pair of outputs, + and returns true if they match; and `output_difference`, which + returns a string describing the differences between two outputs. + """ + def check_output(self, want, got, optionflags): + """ + Return True iff the actual output from an example (`got`) + matches the expected output (`want`). These strings are + always considered to match if they are identical; but + depending on what option flags the test runner is using, + several non-exact match types are also possible. See the + documentation for `TestRunner` for more information about + option flags. + """ + # Handle the common case first, for efficiency: + # if they're string-identical, always return true. + if got == want: + return True + + # The values True and False replaced 1 and 0 as the return + # value for boolean comparisons in Python 2.3. + if not (optionflags & DONT_ACCEPT_TRUE_FOR_1): + if (got,want) == ("True\n", "1\n"): + return True + if (got,want) == ("False\n", "0\n"): + return True + + # can be used as a special sequence to signify a + # blank line, unless the DONT_ACCEPT_BLANKLINE flag is used. + if not (optionflags & DONT_ACCEPT_BLANKLINE): + # Replace in want with a blank line. + want = re.sub('(?m)^%s\s*?$' % re.escape(BLANKLINE_MARKER), + '', want) + # If a line in got contains only spaces, then remove the + # spaces. + got = re.sub('(?m)^\s*?$', '', got) + if got == want: + return True + + # This flag causes doctest to ignore any differences in the + # contents of whitespace strings. Note that this can be used + # in conjunction with the ELLIPSIS flag. + if optionflags & NORMALIZE_WHITESPACE: + got = ' '.join(got.split()) + want = ' '.join(want.split()) + if got == want: + return True + + # The ELLIPSIS flag says to let the sequence "..." in `want` + # match any substring in `got`. + if optionflags & ELLIPSIS: + if _ellipsis_match(want, got): + return True + + # We didn't find any match; return false. + return False + + # Should we do a fancy diff? + def _do_a_fancy_diff(self, want, got, optionflags): + # Not unless they asked for a fancy diff. + if not optionflags & (REPORT_UDIFF | + REPORT_CDIFF | + REPORT_NDIFF): + return False + + # If expected output uses ellipsis, a meaningful fancy diff is + # too hard ... or maybe not. In two real-life failures Tim saw, + # a diff was a major help anyway, so this is commented out. + # [todo] _ellipsis_match() knows which pieces do and don't match, + # and could be the basis for a kick-ass diff in this case. + ##if optionflags & ELLIPSIS and ELLIPSIS_MARKER in want: + ## return False + + # ndiff does intraline difference marking, so can be useful even + # for 1-line differences. + if optionflags & REPORT_NDIFF: + return True + + # The other diff types need at least a few lines to be helpful. + return want.count('\n') > 2 and got.count('\n') > 2 + + def output_difference(self, example, got, optionflags): + """ + Return a string describing the differences between the + expected output for a given example (`example`) and the actual + output (`got`). `optionflags` is the set of option flags used + to compare `want` and `got`. + """ + want = example.want + # If s are being used, then replace blank lines + # with in the actual output string. + if not (optionflags & DONT_ACCEPT_BLANKLINE): + got = re.sub('(?m)^[ ]*(?=\n)', BLANKLINE_MARKER, got) + + # Check if we should use diff. + if self._do_a_fancy_diff(want, got, optionflags): + # Split want & got into lines. + want_lines = want.splitlines(True) # True == keep line ends + got_lines = got.splitlines(True) + # Use difflib to find their differences. + if optionflags & REPORT_UDIFF: + diff = difflib.unified_diff(want_lines, got_lines, n=2) + diff = list(diff)[2:] # strip the diff header + kind = 'unified diff with -expected +actual' + elif optionflags & REPORT_CDIFF: + diff = difflib.context_diff(want_lines, got_lines, n=2) + diff = list(diff)[2:] # strip the diff header + kind = 'context diff with expected followed by actual' + elif optionflags & REPORT_NDIFF: + engine = difflib.Differ(charjunk=difflib.IS_CHARACTER_JUNK) + diff = list(engine.compare(want_lines, got_lines)) + kind = 'ndiff with -expected +actual' + else: + assert 0, 'Bad diff option' + # Remove trailing whitespace on diff output. + diff = [line.rstrip() + '\n' for line in diff] + return 'Differences (%s):\n' % kind + _indent(''.join(diff)) + + # If we're not using diff, then simply list the expected + # output followed by the actual output. + if want and got: + return 'Expected:\n%sGot:\n%s' % (_indent(want), _indent(got)) + elif want: + return 'Expected:\n%sGot nothing\n' % _indent(want) + elif got: + return 'Expected nothing\nGot:\n%s' % _indent(got) + else: + return 'Expected nothing\nGot nothing\n' + +class DocTestFailure(Exception): + """A DocTest example has failed in debugging mode. + + The exception instance has variables: + + - test: the DocTest object being run + + - excample: the Example object that failed + + - got: the actual output + """ + def __init__(self, test, example, got): + self.test = test + self.example = example + self.got = got + + def __str__(self): + return str(self.test) + +class UnexpectedException(Exception): + """A DocTest example has encountered an unexpected exception + + The exception instance has variables: + + - test: the DocTest object being run + + - excample: the Example object that failed + + - exc_info: the exception info + """ + def __init__(self, test, example, exc_info): + self.test = test + self.example = example + self.exc_info = exc_info + + def __str__(self): + return str(self.test) + +class DebugRunner(DocTestRunner): + + def run(self, test, compileflags=None, out=None, clear_globs=True): + r = DocTestRunner.run(self, test, compileflags, out, False) + if clear_globs: + test.globs.clear() + return r + + def report_unexpected_exception(self, out, test, example, exc_info): + raise UnexpectedException(test, example, exc_info) + + def report_failure(self, out, test, example, got): + raise DocTestFailure(test, example, got) + +###################################################################### +## 6. Test Functions +###################################################################### +# These should be backwards compatible. + +# For backward compatibility, a global instance of a DocTestRunner +# class, updated by testmod. +master = None + +def testmod(m=None, name=None, globs=None, verbose=None, isprivate=None, + report=True, optionflags=0, extraglobs=None, + raise_on_error=False, exclude_empty=False): + """m=None, name=None, globs=None, verbose=None, isprivate=None, + report=True, optionflags=0, extraglobs=None, raise_on_error=False, + exclude_empty=False + + Test examples in docstrings in functions and classes reachable + from module m (or the current module if m is not supplied), starting + with m.__doc__. Unless isprivate is specified, private names + are not skipped. + + Also test examples reachable from dict m.__test__ if it exists and is + not None. m.__test__ maps names to functions, classes and strings; + function and class docstrings are tested even if the name is private; + strings are tested directly, as if they were docstrings. + + Return (#failures, #tests). + + See doctest.__doc__ for an overview. + + Optional keyword arg "name" gives the name of the module; by default + use m.__name__. + + Optional keyword arg "globs" gives a dict to be used as the globals + when executing examples; by default, use m.__dict__. A copy of this + dict is actually used for each docstring, so that each docstring's + examples start with a clean slate. + + Optional keyword arg "extraglobs" gives a dictionary that should be + merged into the globals that are used to execute examples. By + default, no extra globals are used. This is new in 2.4. + + Optional keyword arg "verbose" prints lots of stuff if true, prints + only failures if false; by default, it's true iff "-v" is in sys.argv. + + Optional keyword arg "report" prints a summary at the end when true, + else prints nothing at the end. In verbose mode, the summary is + detailed, else very brief (in fact, empty if all tests passed). + + Optional keyword arg "optionflags" or's together module constants, + and defaults to 0. This is new in 2.3. Possible values (see the + docs for details): + + DONT_ACCEPT_TRUE_FOR_1 + DONT_ACCEPT_BLANKLINE + NORMALIZE_WHITESPACE + ELLIPSIS + IGNORE_EXCEPTION_DETAIL + REPORT_UDIFF + REPORT_CDIFF + REPORT_NDIFF + REPORT_ONLY_FIRST_FAILURE + + Optional keyword arg "raise_on_error" raises an exception on the + first unexpected exception or failure. This allows failures to be + post-mortem debugged. + + Deprecated in Python 2.4: + Optional keyword arg "isprivate" specifies a function used to + determine whether a name is private. The default function is + treat all functions as public. Optionally, "isprivate" can be + set to doctest.is_private to skip over functions marked as private + using the underscore naming convention; see its docs for details. + + Advanced tomfoolery: testmod runs methods of a local instance of + class doctest.Tester, then merges the results into (or creates) + global Tester instance doctest.master. Methods of doctest.master + can be called directly too, if you want to do something unusual. + Passing report=0 to testmod is especially useful then, to delay + displaying a summary. Invoke doctest.master.summarize(verbose) + when you're done fiddling. + """ + global master + + if isprivate is not None: + warnings.warn("the isprivate argument is deprecated; " + "examine DocTestFinder.find() lists instead", + DeprecationWarning) + + # If no module was given, then use __main__. + if m is None: + # DWA - m will still be None if this wasn't invoked from the command + # line, in which case the following TypeError is about as good an error + # as we should expect + m = sys.modules.get('__main__') + + # Check that we were actually given a module. + if not inspect.ismodule(m): + raise TypeError("testmod: module required; %r" % (m,)) + + # If no name was given, then use the module's name. + if name is None: + name = m.__name__ + + # Find, parse, and run all tests in the given module. + finder = DocTestFinder(_namefilter=isprivate, exclude_empty=exclude_empty) + + if raise_on_error: + runner = DebugRunner(verbose=verbose, optionflags=optionflags) + else: + runner = DocTestRunner(verbose=verbose, optionflags=optionflags) + + for test in finder.find(m, name, globs=globs, extraglobs=extraglobs): + runner.run(test) + + if report: + runner.summarize() + + if master is None: + master = runner + else: + master.merge(runner) + + return runner.failures, runner.tries + +def testfile(filename, module_relative=True, name=None, package=None, + globs=None, verbose=None, report=True, optionflags=0, + extraglobs=None, raise_on_error=False, parser=DocTestParser()): + """ + Test examples in the given file. Return (#failures, #tests). + + Optional keyword arg "module_relative" specifies how filenames + should be interpreted: + + - If "module_relative" is True (the default), then "filename" + specifies a module-relative path. By default, this path is + relative to the calling module's directory; but if the + "package" argument is specified, then it is relative to that + package. To ensure os-independence, "filename" should use + "/" characters to separate path segments, and should not + be an absolute path (i.e., it may not begin with "/"). + + - If "module_relative" is False, then "filename" specifies an + os-specific path. The path may be absolute or relative (to + the current working directory). + + Optional keyword arg "name" gives the name of the test; by default + use the file's basename. + + Optional keyword argument "package" is a Python package or the + name of a Python package whose directory should be used as the + base directory for a module relative filename. If no package is + specified, then the calling module's directory is used as the base + directory for module relative filenames. It is an error to + specify "package" if "module_relative" is False. + + Optional keyword arg "globs" gives a dict to be used as the globals + when executing examples; by default, use {}. A copy of this dict + is actually used for each docstring, so that each docstring's + examples start with a clean slate. + + Optional keyword arg "extraglobs" gives a dictionary that should be + merged into the globals that are used to execute examples. By + default, no extra globals are used. + + Optional keyword arg "verbose" prints lots of stuff if true, prints + only failures if false; by default, it's true iff "-v" is in sys.argv. + + Optional keyword arg "report" prints a summary at the end when true, + else prints nothing at the end. In verbose mode, the summary is + detailed, else very brief (in fact, empty if all tests passed). + + Optional keyword arg "optionflags" or's together module constants, + and defaults to 0. Possible values (see the docs for details): + + DONT_ACCEPT_TRUE_FOR_1 + DONT_ACCEPT_BLANKLINE + NORMALIZE_WHITESPACE + ELLIPSIS + IGNORE_EXCEPTION_DETAIL + REPORT_UDIFF + REPORT_CDIFF + REPORT_NDIFF + REPORT_ONLY_FIRST_FAILURE + + Optional keyword arg "raise_on_error" raises an exception on the + first unexpected exception or failure. This allows failures to be + post-mortem debugged. + + Optional keyword arg "parser" specifies a DocTestParser (or + subclass) that should be used to extract tests from the files. + + Advanced tomfoolery: testmod runs methods of a local instance of + class doctest.Tester, then merges the results into (or creates) + global Tester instance doctest.master. Methods of doctest.master + can be called directly too, if you want to do something unusual. + Passing report=0 to testmod is especially useful then, to delay + displaying a summary. Invoke doctest.master.summarize(verbose) + when you're done fiddling. + """ + global master + + if package and not module_relative: + raise ValueError("Package may only be specified for module-" + "relative paths.") + + # Relativize the path + if module_relative: + package = _normalize_module(package) + filename = _module_relative_path(package, filename) + + # If no name was given, then use the file's name. + if name is None: + name = os.path.basename(filename) + + # Assemble the globals. + if globs is None: + globs = {} + else: + globs = globs.copy() + if extraglobs is not None: + globs.update(extraglobs) + + if raise_on_error: + runner = DebugRunner(verbose=verbose, optionflags=optionflags) + else: + runner = DocTestRunner(verbose=verbose, optionflags=optionflags) + + # Read the file, convert it to a test, and run it. + s = open(filename).read() + test = parser.get_doctest(s, globs, name, filename, 0) + runner.run(test) + + if report: + runner.summarize() + + if master is None: + master = runner + else: + master.merge(runner) + + return runner.failures, runner.tries + +def run_docstring_examples(f, globs, verbose=False, name="NoName", + compileflags=None, optionflags=0): + """ + Test examples in the given object's docstring (`f`), using `globs` + as globals. Optional argument `name` is used in failure messages. + If the optional argument `verbose` is true, then generate output + even if there are no failures. + + `compileflags` gives the set of flags that should be used by the + Python compiler when running the examples. If not specified, then + it will default to the set of future-import flags that apply to + `globs`. + + Optional keyword arg `optionflags` specifies options for the + testing and output. See the documentation for `testmod` for more + information. + """ + # Find, parse, and run all tests in the given module. + finder = DocTestFinder(verbose=verbose, recurse=False) + runner = DocTestRunner(verbose=verbose, optionflags=optionflags) + for test in finder.find(f, name, globs=globs): + runner.run(test, compileflags=compileflags) + +###################################################################### +## 7. Tester +###################################################################### +# This is provided only for backwards compatibility. It's not +# actually used in any way. + +class Tester: + def __init__(self, mod=None, globs=None, verbose=None, + isprivate=None, optionflags=0): + + warnings.warn("class Tester is deprecated; " + "use class doctest.DocTestRunner instead", + DeprecationWarning, stacklevel=2) + if mod is None and globs is None: + raise TypeError("Tester.__init__: must specify mod or globs") + if mod is not None and not inspect.ismodule(mod): + raise TypeError("Tester.__init__: mod must be a module; %r" % + (mod,)) + if globs is None: + globs = mod.__dict__ + self.globs = globs + + self.verbose = verbose + self.isprivate = isprivate + self.optionflags = optionflags + self.testfinder = DocTestFinder(_namefilter=isprivate) + self.testrunner = DocTestRunner(verbose=verbose, + optionflags=optionflags) + + def runstring(self, s, name): + test = DocTestParser().get_doctest(s, self.globs, name, None, None) + if self.verbose: + print "Running string", name + (f,t) = self.testrunner.run(test) + if self.verbose: + print f, "of", t, "examples failed in string", name + return (f,t) + + def rundoc(self, object, name=None, module=None): + f = t = 0 + tests = self.testfinder.find(object, name, module=module, + globs=self.globs) + for test in tests: + (f2, t2) = self.testrunner.run(test) + (f,t) = (f+f2, t+t2) + return (f,t) + + def rundict(self, d, name, module=None): + import new + m = new.module(name) + m.__dict__.update(d) + if module is None: + module = False + return self.rundoc(m, name, module) + + def run__test__(self, d, name): + import new + m = new.module(name) + m.__test__ = d + return self.rundoc(m, name) + + def summarize(self, verbose=None): + return self.testrunner.summarize(verbose) + + def merge(self, other): + self.testrunner.merge(other.testrunner) + +###################################################################### +## 8. Unittest Support +###################################################################### + +_unittest_reportflags = 0 + +def set_unittest_reportflags(flags): + global _unittest_reportflags + + if (flags & REPORTING_FLAGS) != flags: + raise ValueError("Only reporting flags allowed", flags) + old = _unittest_reportflags + _unittest_reportflags = flags + return old + + +class DocTestCase(unittest.TestCase): + + def __init__(self, test, optionflags=0, setUp=None, tearDown=None, + checker=None): + + unittest.TestCase.__init__(self) + self._dt_optionflags = optionflags + self._dt_checker = checker + self._dt_test = test + self._dt_setUp = setUp + self._dt_tearDown = tearDown + + def setUp(self): + test = self._dt_test + + if self._dt_setUp is not None: + self._dt_setUp(test) + + def tearDown(self): + test = self._dt_test + + if self._dt_tearDown is not None: + self._dt_tearDown(test) + + test.globs.clear() + + def runTest(self): + test = self._dt_test + old = sys.stdout + new = StringIO() + optionflags = self._dt_optionflags + + if not (optionflags & REPORTING_FLAGS): + # The option flags don't include any reporting flags, + # so add the default reporting flags + optionflags |= _unittest_reportflags + + runner = DocTestRunner(optionflags=optionflags, + checker=self._dt_checker, verbose=False) + + try: + runner.DIVIDER = "-"*70 + failures, tries = runner.run( + test, out=new.write, clear_globs=False) + finally: + sys.stdout = old + + if failures: + raise self.failureException(self.format_failure(new.getvalue())) + + def format_failure(self, err): + test = self._dt_test + if test.lineno is None: + lineno = 'unknown line number' + else: + lineno = '%s' % test.lineno + lname = '.'.join(test.name.split('.')[-1:]) + return ('Failed doctest test for %s\n' + ' File "%s", line %s, in %s\n\n%s' + % (test.name, test.filename, lineno, lname, err) + ) + + def debug(self): + self.setUp() + runner = DebugRunner(optionflags=self._dt_optionflags, + checker=self._dt_checker, verbose=False) + runner.run(self._dt_test) + self.tearDown() + + def id(self): + return self._dt_test.name + + def __repr__(self): + name = self._dt_test.name.split('.') + return "%s (%s)" % (name[-1], '.'.join(name[:-1])) + + __str__ = __repr__ + + def shortDescription(self): + return "Doctest: " + self._dt_test.name + +def DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None, + **options): + """ + Convert doctest tests for a module to a unittest test suite. + + This converts each documentation string in a module that + contains doctest tests to a unittest test case. If any of the + tests in a doc string fail, then the test case fails. An exception + is raised showing the name of the file containing the test and a + (sometimes approximate) line number. + + The `module` argument provides the module to be tested. The argument + can be either a module or a module name. + + If no argument is given, the calling module is used. + + A number of options may be provided as keyword arguments: + + setUp + A set-up function. This is called before running the + tests in each file. The setUp function will be passed a DocTest + object. The setUp function can access the test globals as the + globs attribute of the test passed. + + tearDown + A tear-down function. This is called after running the + tests in each file. The tearDown function will be passed a DocTest + object. The tearDown function can access the test globals as the + globs attribute of the test passed. + + globs + A dictionary containing initial global variables for the tests. + + optionflags + A set of doctest option flags expressed as an integer. + """ + + if test_finder is None: + test_finder = DocTestFinder() + + module = _normalize_module(module) + tests = test_finder.find(module, globs=globs, extraglobs=extraglobs) + if globs is None: + globs = module.__dict__ + if not tests: + # Why do we want to do this? Because it reveals a bug that might + # otherwise be hidden. + raise ValueError(module, "has no tests") + + tests.sort() + suite = unittest.TestSuite() + for test in tests: + if len(test.examples) == 0: + continue + if not test.filename: + filename = module.__file__ + if filename[-4:] in (".pyc", ".pyo"): + filename = filename[:-1] + elif sys.platform.startswith('java') and \ + filename.endswith('$py.class'): + filename = '%s.py' % filename[:-9] + test.filename = filename + suite.addTest(DocTestCase(test, **options)) + + return suite + +class DocFileCase(DocTestCase): + + def id(self): + return '_'.join(self._dt_test.name.split('.')) + + def __repr__(self): + return self._dt_test.filename + __str__ = __repr__ + + def format_failure(self, err): + return ('Failed doctest test for %s\n File "%s", line 0\n\n%s' + % (self._dt_test.name, self._dt_test.filename, err) + ) + +def DocFileTest(path, module_relative=True, package=None, + globs=None, parser=DocTestParser(), **options): + if globs is None: + globs = {} + + if package and not module_relative: + raise ValueError("Package may only be specified for module-" + "relative paths.") + + # Relativize the path. + if module_relative: + package = _normalize_module(package) + path = _module_relative_path(package, path) + + # Find the file and read it. + name = os.path.basename(path) + doc = open(path).read() + + # Convert it to a test, and wrap it in a DocFileCase. + test = parser.get_doctest(doc, globs, name, path, 0) + return DocFileCase(test, **options) + +def DocFileSuite(*paths, **kw): + """A unittest suite for one or more doctest files. + + The path to each doctest file is given as a string; the + interpretation of that string depends on the keyword argument + "module_relative". + + A number of options may be provided as keyword arguments: + + module_relative + If "module_relative" is True, then the given file paths are + interpreted as os-independent module-relative paths. By + default, these paths are relative to the calling module's + directory; but if the "package" argument is specified, then + they are relative to that package. To ensure os-independence, + "filename" should use "/" characters to separate path + segments, and may not be an absolute path (i.e., it may not + begin with "/"). + + If "module_relative" is False, then the given file paths are + interpreted as os-specific paths. These paths may be absolute + or relative (to the current working directory). + + package + A Python package or the name of a Python package whose directory + should be used as the base directory for module relative paths. + If "package" is not specified, then the calling module's + directory is used as the base directory for module relative + filenames. It is an error to specify "package" if + "module_relative" is False. + + setUp + A set-up function. This is called before running the + tests in each file. The setUp function will be passed a DocTest + object. The setUp function can access the test globals as the + globs attribute of the test passed. + + tearDown + A tear-down function. This is called after running the + tests in each file. The tearDown function will be passed a DocTest + object. The tearDown function can access the test globals as the + globs attribute of the test passed. + + globs + A dictionary containing initial global variables for the tests. + + optionflags + A set of doctest option flags expressed as an integer. + + parser + A DocTestParser (or subclass) that should be used to extract + tests from the files. + """ + suite = unittest.TestSuite() + + # We do this here so that _normalize_module is called at the right + # level. If it were called in DocFileTest, then this function + # would be the caller and we might guess the package incorrectly. + if kw.get('module_relative', True): + kw['package'] = _normalize_module(kw.get('package')) + + for path in paths: + suite.addTest(DocFileTest(path, **kw)) + + return suite + +###################################################################### +## 9. Debugging Support +###################################################################### + +def script_from_examples(s): + output = [] + for piece in DocTestParser().parse(s): + if isinstance(piece, Example): + # Add the example's source code (strip trailing NL) + output.append(piece.source[:-1]) + # Add the expected output: + want = piece.want + if want: + output.append('# Expected:') + output += ['## '+l for l in want.split('\n')[:-1]] + else: + # Add non-example text. + output += [_comment_line(l) + for l in piece.split('\n')[:-1]] + + # Trim junk on both ends. + while output and output[-1] == '#': + output.pop() + while output and output[0] == '#': + output.pop(0) + # Combine the output, and return it. + # Add a courtesy newline to prevent exec from choking (see bug #1172785) + return '\n'.join(output) + '\n' + +def testsource(module, name): + """Extract the test sources from a doctest docstring as a script. + + Provide the module (or dotted name of the module) containing the + test to be debugged and the name (within the module) of the object + with the doc string with tests to be debugged. + """ + module = _normalize_module(module) + tests = DocTestFinder().find(module) + test = [t for t in tests if t.name == name] + if not test: + raise ValueError(name, "not found in tests") + test = test[0] + testsrc = script_from_examples(test.docstring) + return testsrc + +def debug_src(src, pm=False, globs=None): + """Debug a single doctest docstring, in argument `src`'""" + testsrc = script_from_examples(src) + debug_script(testsrc, pm, globs) + +def debug_script(src, pm=False, globs=None): + "Debug a test script. `src` is the script, as a string." + import pdb + + # Note that tempfile.NameTemporaryFile() cannot be used. As the + # docs say, a file so created cannot be opened by name a second time + # on modern Windows boxes, and execfile() needs to open it. + srcfilename = tempfile.mktemp(".py", "doctestdebug") + f = open(srcfilename, 'w') + f.write(src) + f.close() + + try: + if globs: + globs = globs.copy() + else: + globs = {} + + if pm: + try: + execfile(srcfilename, globs, globs) + except: + print sys.exc_info()[1] + pdb.post_mortem(sys.exc_info()[2]) + else: + # Note that %r is vital here. '%s' instead can, e.g., cause + # backslashes to get treated as metacharacters on Windows. + pdb.run("execfile(%r)" % srcfilename, globs, globs) + + finally: + os.remove(srcfilename) + +def debug(module, name, pm=False): + """Debug a single doctest docstring. + + Provide the module (or dotted name of the module) containing the + test to be debugged and the name (within the module) of the object + with the docstring with tests to be debugged. + """ + module = _normalize_module(module) + testsrc = testsource(module, name) + debug_script(testsrc, pm, module.__dict__) + + +__test__ = {} diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/ext/dtcompat.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/ext/dtcompat.pyc new file mode 100644 index 0000000000000000000000000000000000000000..da31a9ff4f50afb4a722460e7ae25d03fd2485e8 GIT binary patch literal 72902 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 Q3Hm@Cs3Ub09meDMKSG|*82|tP literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/importer.py b/.eggs/nose-1.3.7-py2.7.egg/nose/importer.py new file mode 100644 index 0000000..e677658 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/importer.py @@ -0,0 +1,167 @@ +"""Implements an importer that looks only in specific path (ignoring +sys.path), and uses a per-path cache in addition to sys.modules. This is +necessary because test modules in different directories frequently have the +same names, which means that the first loaded would mask the rest when using +the builtin importer. +""" +import logging +import os +import sys +from nose.config import Config + +from imp import find_module, load_module, acquire_lock, release_lock + +log = logging.getLogger(__name__) + +try: + _samefile = os.path.samefile +except AttributeError: + def _samefile(src, dst): + return (os.path.normcase(os.path.realpath(src)) == + os.path.normcase(os.path.realpath(dst))) + + +class Importer(object): + """An importer class that does only path-specific imports. That + is, the given module is not searched for on sys.path, but only at + the path or in the directory specified. + """ + def __init__(self, config=None): + if config is None: + config = Config() + self.config = config + + def importFromPath(self, path, fqname): + """Import a dotted-name package whose tail is at path. In other words, + given foo.bar and path/to/foo/bar.py, import foo from path/to/foo then + bar from path/to/foo/bar, returning bar. + """ + # find the base dir of the package + path_parts = os.path.normpath(os.path.abspath(path)).split(os.sep) + name_parts = fqname.split('.') + if path_parts[-1] == '__init__.py': + path_parts.pop() + path_parts = path_parts[:-(len(name_parts))] + dir_path = os.sep.join(path_parts) + # then import fqname starting from that dir + return self.importFromDir(dir_path, fqname) + + def importFromDir(self, dir, fqname): + """Import a module *only* from path, ignoring sys.path and + reloading if the version in sys.modules is not the one we want. + """ + dir = os.path.normpath(os.path.abspath(dir)) + log.debug("Import %s from %s", fqname, dir) + + # FIXME reimplement local per-dir cache? + + # special case for __main__ + if fqname == '__main__': + return sys.modules[fqname] + + if self.config.addPaths: + add_path(dir, self.config) + + path = [dir] + parts = fqname.split('.') + part_fqname = '' + mod = parent = fh = None + + for part in parts: + if part_fqname == '': + part_fqname = part + else: + part_fqname = "%s.%s" % (part_fqname, part) + try: + acquire_lock() + log.debug("find module part %s (%s) in %s", + part, part_fqname, path) + fh, filename, desc = find_module(part, path) + old = sys.modules.get(part_fqname) + if old is not None: + # test modules frequently have name overlap; make sure + # we get a fresh copy of anything we are trying to load + # from a new path + log.debug("sys.modules has %s as %s", part_fqname, old) + if (self.sameModule(old, filename) + or (self.config.firstPackageWins and + getattr(old, '__path__', None))): + mod = old + else: + del sys.modules[part_fqname] + mod = load_module(part_fqname, fh, filename, desc) + else: + mod = load_module(part_fqname, fh, filename, desc) + finally: + if fh: + fh.close() + release_lock() + if parent: + setattr(parent, part, mod) + if hasattr(mod, '__path__'): + path = mod.__path__ + parent = mod + return mod + + def _dirname_if_file(self, filename): + # We only take the dirname if we have a path to a non-dir, + # because taking the dirname of a symlink to a directory does not + # give the actual directory parent. + if os.path.isdir(filename): + return filename + else: + return os.path.dirname(filename) + + def sameModule(self, mod, filename): + mod_paths = [] + if hasattr(mod, '__path__'): + for path in mod.__path__: + mod_paths.append(self._dirname_if_file(path)) + elif hasattr(mod, '__file__'): + mod_paths.append(self._dirname_if_file(mod.__file__)) + else: + # builtin or other module-like object that + # doesn't have __file__; must be new + return False + new_path = self._dirname_if_file(filename) + for mod_path in mod_paths: + log.debug( + "module already loaded? mod: %s new: %s", + mod_path, new_path) + if _samefile(mod_path, new_path): + return True + return False + + +def add_path(path, config=None): + """Ensure that the path, or the root of the current package (if + path is in a package), is in sys.path. + """ + + # FIXME add any src-looking dirs seen too... need to get config for that + + log.debug('Add path %s' % path) + if not path: + return [] + added = [] + parent = os.path.dirname(path) + if (parent + and os.path.exists(os.path.join(path, '__init__.py'))): + added.extend(add_path(parent, config)) + elif not path in sys.path: + log.debug("insert %s into sys.path", path) + sys.path.insert(0, path) + added.append(path) + if config and config.srcDirs: + for dirname in config.srcDirs: + dirpath = os.path.join(path, dirname) + if os.path.isdir(dirpath): + sys.path.insert(0, dirpath) + added.append(dirpath) + return added + + +def remove_path(path): + log.debug('Remove path %s' % path) + if path in sys.path: + sys.path.remove(path) diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/importer.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/importer.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b00c5b3c3bddd3e5cc90e15f1747385c5f04a921 GIT binary patch literal 5898 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 JzdUU}^M4!2GWY-h literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/inspector.py b/.eggs/nose-1.3.7-py2.7.egg/nose/inspector.py new file mode 100644 index 0000000..a6c4a3e --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/inspector.py @@ -0,0 +1,207 @@ +"""Simple traceback introspection. Used to add additional information to +AssertionErrors in tests, so that failure messages may be more informative. +""" +import inspect +import logging +import re +import sys +import textwrap +import tokenize + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + +log = logging.getLogger(__name__) + +def inspect_traceback(tb): + """Inspect a traceback and its frame, returning source for the expression + where the exception was raised, with simple variable replacement performed + and the line on which the exception was raised marked with '>>' + """ + log.debug('inspect traceback %s', tb) + + # we only want the innermost frame, where the exception was raised + while tb.tb_next: + tb = tb.tb_next + + frame = tb.tb_frame + lines, exc_line = tbsource(tb) + + # figure out the set of lines to grab. + inspect_lines, mark_line = find_inspectable_lines(lines, exc_line) + src = StringIO(textwrap.dedent(''.join(inspect_lines))) + exp = Expander(frame.f_locals, frame.f_globals) + + while inspect_lines: + try: + for tok in tokenize.generate_tokens(src.readline): + exp(*tok) + except tokenize.TokenError, e: + # this can happen if our inspectable region happens to butt up + # against the end of a construct like a docstring with the closing + # """ on separate line + log.debug("Tokenizer error: %s", e) + inspect_lines.pop(0) + mark_line -= 1 + src = StringIO(textwrap.dedent(''.join(inspect_lines))) + exp = Expander(frame.f_locals, frame.f_globals) + continue + break + padded = [] + if exp.expanded_source: + exp_lines = exp.expanded_source.split('\n') + ep = 0 + for line in exp_lines: + if ep == mark_line: + padded.append('>> ' + line) + else: + padded.append(' ' + line) + ep += 1 + return '\n'.join(padded) + + +def tbsource(tb, context=6): + """Get source from a traceback object. + + A tuple of two things is returned: a list of lines of context from + the source code, and the index of the current line within that list. + The optional second argument specifies the number of lines of context + to return, which are centered around the current line. + + .. Note :: + This is adapted from inspect.py in the python 2.4 standard library, + since a bug in the 2.3 version of inspect prevents it from correctly + locating source lines in a traceback frame. + """ + + lineno = tb.tb_lineno + frame = tb.tb_frame + + if context > 0: + start = lineno - 1 - context//2 + log.debug("lineno: %s start: %s", lineno, start) + + try: + lines, dummy = inspect.findsource(frame) + except IOError: + lines, index = [''], 0 + else: + all_lines = lines + start = max(start, 1) + start = max(0, min(start, len(lines) - context)) + lines = lines[start:start+context] + index = lineno - 1 - start + + # python 2.5 compat: if previous line ends in a continuation, + # decrement start by 1 to match 2.4 behavior + if sys.version_info >= (2, 5) and index > 0: + while lines[index-1].strip().endswith('\\'): + start -= 1 + lines = all_lines[start:start+context] + else: + lines, index = [''], 0 + log.debug("tbsource lines '''%s''' around index %s", lines, index) + return (lines, index) + + +def find_inspectable_lines(lines, pos): + """Find lines in home that are inspectable. + + Walk back from the err line up to 3 lines, but don't walk back over + changes in indent level. + + Walk forward up to 3 lines, counting \ separated lines as 1. Don't walk + over changes in indent level (unless part of an extended line) + """ + cnt = re.compile(r'\\[\s\n]*$') + df = re.compile(r':[\s\n]*$') + ind = re.compile(r'^(\s*)') + toinspect = [] + home = lines[pos] + home_indent = ind.match(home).groups()[0] + + before = lines[max(pos-3, 0):pos] + before.reverse() + after = lines[pos+1:min(pos+4, len(lines))] + + for line in before: + if ind.match(line).groups()[0] == home_indent: + toinspect.append(line) + else: + break + toinspect.reverse() + toinspect.append(home) + home_pos = len(toinspect)-1 + continued = cnt.search(home) + for line in after: + if ((continued or ind.match(line).groups()[0] == home_indent) + and not df.search(line)): + toinspect.append(line) + continued = cnt.search(line) + else: + break + log.debug("Inspecting lines '''%s''' around %s", toinspect, home_pos) + return toinspect, home_pos + + +class Expander: + """Simple expression expander. Uses tokenize to find the names and + expands any that can be looked up in the frame. + """ + def __init__(self, locals, globals): + self.locals = locals + self.globals = globals + self.lpos = None + self.expanded_source = '' + + def __call__(self, ttype, tok, start, end, line): + # TODO + # deal with unicode properly + + # TODO + # Dealing with instance members + # always keep the last thing seen + # if the current token is a dot, + # get ready to getattr(lastthing, this thing) on the + # next call. + + if self.lpos is not None: + if start[1] >= self.lpos: + self.expanded_source += ' ' * (start[1]-self.lpos) + elif start[1] < self.lpos: + # newline, indent correctly + self.expanded_source += ' ' * start[1] + self.lpos = end[1] + + if ttype == tokenize.INDENT: + pass + elif ttype == tokenize.NAME: + # Clean this junk up + try: + val = self.locals[tok] + if callable(val): + val = tok + else: + val = repr(val) + except KeyError: + try: + val = self.globals[tok] + if callable(val): + val = tok + else: + val = repr(val) + + except KeyError: + val = tok + # FIXME... not sure how to handle things like funcs, classes + # FIXME this is broken for some unicode strings + self.expanded_source += val + else: + self.expanded_source += tok + # if this is the end of the line and the line ends with + # \, then tack a \ and newline onto the output + # print line[end[1]:] + if re.match(r'\s+\\\n', line[end[1]:]): + self.expanded_source += ' \\\n' diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/inspector.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/inspector.pyc new file mode 100644 index 0000000000000000000000000000000000000000..590e892e31e0df7824abda648fca895072125216 GIT binary patch literal 6164 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 literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/loader.py b/.eggs/nose-1.3.7-py2.7.egg/nose/loader.py new file mode 100644 index 0000000..3744e54 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/loader.py @@ -0,0 +1,623 @@ +""" +Test Loader +----------- + +nose's test loader implements the same basic functionality as its +superclass, unittest.TestLoader, but extends it by more liberal +interpretations of what may be a test and how a test may be named. +""" +from __future__ import generators + +import logging +import os +import sys +import unittest +import types +from inspect import isfunction +from nose.pyversion import unbound_method, ismethod +from nose.case import FunctionTestCase, MethodTestCase +from nose.failure import Failure +from nose.config import Config +from nose.importer import Importer, add_path, remove_path +from nose.selector import defaultSelector, TestAddress +from nose.util import func_lineno, getpackage, isclass, isgenerator, \ + ispackage, regex_last_key, resolve_name, transplant_func, \ + transplant_class, test_address +from nose.suite import ContextSuiteFactory, ContextList, LazySuite +from nose.pyversion import sort_list, cmp_to_key + + +log = logging.getLogger(__name__) +#log.setLevel(logging.DEBUG) + +# for efficiency and easier mocking +op_normpath = os.path.normpath +op_abspath = os.path.abspath +op_join = os.path.join +op_isdir = os.path.isdir +op_isfile = os.path.isfile + + +__all__ = ['TestLoader', 'defaultTestLoader'] + + +class TestLoader(unittest.TestLoader): + """Test loader that extends unittest.TestLoader to: + + * Load tests from test-like functions and classes that are not + unittest.TestCase subclasses + * Find and load test modules in a directory + * Support tests that are generators + * Support easy extensions of or changes to that behavior through plugins + """ + config = None + importer = None + workingDir = None + selector = None + suiteClass = None + + def __init__(self, config=None, importer=None, workingDir=None, + selector=None): + """Initialize a test loader. + + Parameters (all optional): + + * config: provide a `nose.config.Config`_ or other config class + instance; if not provided a `nose.config.Config`_ with + default values is used. + * importer: provide an importer instance that implements + `importFromPath`. If not provided, a + `nose.importer.Importer`_ is used. + * workingDir: the directory to which file and module names are + relative. If not provided, assumed to be the current working + directory. + * selector: a selector class or instance. If a class is + provided, it will be instantiated with one argument, the + current config. If not provided, a `nose.selector.Selector`_ + is used. + """ + if config is None: + config = Config() + if importer is None: + importer = Importer(config=config) + if workingDir is None: + workingDir = config.workingDir + if selector is None: + selector = defaultSelector(config) + elif isclass(selector): + selector = selector(config) + self.config = config + self.importer = importer + self.workingDir = op_normpath(op_abspath(workingDir)) + self.selector = selector + if config.addPaths: + add_path(workingDir, config) + self.suiteClass = ContextSuiteFactory(config=config) + + self._visitedPaths = set([]) + + unittest.TestLoader.__init__(self) + + def getTestCaseNames(self, testCaseClass): + """Override to select with selector, unless + config.getTestCaseNamesCompat is True + """ + if self.config.getTestCaseNamesCompat: + return unittest.TestLoader.getTestCaseNames(self, testCaseClass) + + def wanted(attr, cls=testCaseClass, sel=self.selector): + item = getattr(cls, attr, None) + if isfunction(item): + item = unbound_method(cls, item) + elif not ismethod(item): + return False + return sel.wantMethod(item) + + cases = filter(wanted, dir(testCaseClass)) + + # add runTest if nothing else picked + if not cases and hasattr(testCaseClass, 'runTest'): + cases = ['runTest'] + if self.sortTestMethodsUsing: + sort_list(cases, cmp_to_key(self.sortTestMethodsUsing)) + return cases + + def _haveVisited(self, path): + # For cases where path is None, we always pretend we haven't visited + # them. + if path is None: + return False + + return path in self._visitedPaths + + def _addVisitedPath(self, path): + if path is not None: + self._visitedPaths.add(path) + + def loadTestsFromDir(self, path): + """Load tests from the directory at path. This is a generator + -- each suite of tests from a module or other file is yielded + and is expected to be executed before the next file is + examined. + """ + log.debug("load from dir %s", path) + plugins = self.config.plugins + plugins.beforeDirectory(path) + if self.config.addPaths: + paths_added = add_path(path, self.config) + + entries = os.listdir(path) + sort_list(entries, regex_last_key(self.config.testMatch)) + for entry in entries: + # this hard-coded initial-dot test will be removed: + # http://code.google.com/p/python-nose/issues/detail?id=82 + if entry.startswith('.'): + continue + entry_path = op_abspath(op_join(path, entry)) + is_file = op_isfile(entry_path) + wanted = False + if is_file: + is_dir = False + wanted = self.selector.wantFile(entry_path) + else: + is_dir = op_isdir(entry_path) + if is_dir: + # this hard-coded initial-underscore test will be removed: + # http://code.google.com/p/python-nose/issues/detail?id=82 + if entry.startswith('_'): + continue + wanted = self.selector.wantDirectory(entry_path) + is_package = ispackage(entry_path) + + # Python 3.3 now implements PEP 420: Implicit Namespace Packages. + # As a result, it's now possible that parent paths that have a + # segment with the same basename as our package ends up + # in module.__path__. So we have to keep track of what we've + # visited, and not-revisit them again. + if wanted and not self._haveVisited(entry_path): + self._addVisitedPath(entry_path) + if is_file: + plugins.beforeContext() + if entry.endswith('.py'): + yield self.loadTestsFromName( + entry_path, discovered=True) + else: + yield self.loadTestsFromFile(entry_path) + plugins.afterContext() + elif is_package: + # Load the entry as a package: given the full path, + # loadTestsFromName() will figure it out + yield self.loadTestsFromName( + entry_path, discovered=True) + else: + # Another test dir in this one: recurse lazily + yield self.suiteClass( + lambda: self.loadTestsFromDir(entry_path)) + tests = [] + for test in plugins.loadTestsFromDir(path): + tests.append(test) + # TODO: is this try/except needed? + try: + if tests: + yield self.suiteClass(tests) + except (KeyboardInterrupt, SystemExit): + raise + except: + yield self.suiteClass([Failure(*sys.exc_info())]) + + # pop paths + if self.config.addPaths: + for p in paths_added: + remove_path(p) + plugins.afterDirectory(path) + + def loadTestsFromFile(self, filename): + """Load tests from a non-module file. Default is to raise a + ValueError; plugins may implement `loadTestsFromFile` to + provide a list of tests loaded from the file. + """ + log.debug("Load from non-module file %s", filename) + try: + tests = [test for test in + self.config.plugins.loadTestsFromFile(filename)] + if tests: + # Plugins can yield False to indicate that they were + # unable to load tests from a file, but it was not an + # error -- the file just had no tests to load. + tests = filter(None, tests) + return self.suiteClass(tests) + else: + # Nothing was able to even try to load from this file + open(filename, 'r').close() # trigger os error + raise ValueError("Unable to load tests from file %s" + % filename) + except (KeyboardInterrupt, SystemExit): + raise + except: + exc = sys.exc_info() + return self.suiteClass( + [Failure(exc[0], exc[1], exc[2], + address=(filename, None, None))]) + + def loadTestsFromGenerator(self, generator, module): + """Lazy-load tests from a generator function. The generator function + may yield either: + + * a callable, or + * a function name resolvable within the same module + """ + def generate(g=generator, m=module): + try: + for test in g(): + test_func, arg = self.parseGeneratedTest(test) + if not callable(test_func): + test_func = getattr(m, test_func) + yield FunctionTestCase(test_func, arg=arg, descriptor=g) + except KeyboardInterrupt: + raise + except: + exc = sys.exc_info() + yield Failure(exc[0], exc[1], exc[2], + address=test_address(generator)) + return self.suiteClass(generate, context=generator, can_split=False) + + def loadTestsFromGeneratorMethod(self, generator, cls): + """Lazy-load tests from a generator method. + + This is more complicated than loading from a generator function, + since a generator method may yield: + + * a function + * a bound or unbound method, or + * a method name + """ + # convert the unbound generator method + # into a bound method so it can be called below + if hasattr(generator, 'im_class'): + cls = generator.im_class + inst = cls() + method = generator.__name__ + generator = getattr(inst, method) + + def generate(g=generator, c=cls): + try: + for test in g(): + test_func, arg = self.parseGeneratedTest(test) + if not callable(test_func): + test_func = unbound_method(c, getattr(c, test_func)) + if ismethod(test_func): + yield MethodTestCase(test_func, arg=arg, descriptor=g) + elif callable(test_func): + # In this case we're forcing the 'MethodTestCase' + # to run the inline function as its test call, + # but using the generator method as the 'method of + # record' (so no need to pass it as the descriptor) + yield MethodTestCase(g, test=test_func, arg=arg) + else: + yield Failure( + TypeError, + "%s is not a callable or method" % test_func) + except KeyboardInterrupt: + raise + except: + exc = sys.exc_info() + yield Failure(exc[0], exc[1], exc[2], + address=test_address(generator)) + return self.suiteClass(generate, context=generator, can_split=False) + + def loadTestsFromModule(self, module, path=None, discovered=False): + """Load all tests from module and return a suite containing + them. If the module has been discovered and is not test-like, + the suite will be empty by default, though plugins may add + their own tests. + """ + log.debug("Load from module %s", module) + tests = [] + test_classes = [] + test_funcs = [] + # For *discovered* modules, we only load tests when the module looks + # testlike. For modules we've been directed to load, we always + # look for tests. (discovered is set to True by loadTestsFromDir) + if not discovered or self.selector.wantModule(module): + for item in dir(module): + test = getattr(module, item, None) + # print "Check %s (%s) in %s" % (item, test, module.__name__) + if isclass(test): + if self.selector.wantClass(test): + test_classes.append(test) + elif isfunction(test) and self.selector.wantFunction(test): + test_funcs.append(test) + sort_list(test_classes, lambda x: x.__name__) + sort_list(test_funcs, func_lineno) + tests = map(lambda t: self.makeTest(t, parent=module), + test_classes + test_funcs) + + # Now, descend into packages + # FIXME can or should this be lazy? + # is this syntax 2.2 compatible? + module_paths = getattr(module, '__path__', []) + + if path: + path = os.path.normcase(os.path.realpath(path)) + + for module_path in module_paths: + log.debug("Load tests from module path %s?", module_path) + log.debug("path: %s os.path.realpath(%s): %s", + path, os.path.normcase(module_path), + os.path.realpath(os.path.normcase(module_path))) + if (self.config.traverseNamespace or not path) or \ + os.path.realpath( + os.path.normcase(module_path)).startswith(path): + # Egg files can be on sys.path, so make sure the path is a + # directory before trying to load from it. + if os.path.isdir(module_path): + tests.extend(self.loadTestsFromDir(module_path)) + + for test in self.config.plugins.loadTestsFromModule(module, path): + tests.append(test) + + return self.suiteClass(ContextList(tests, context=module)) + + def loadTestsFromName(self, name, module=None, discovered=False): + """Load tests from the entity with the given name. + + The name may indicate a file, directory, module, or any object + within a module. See `nose.util.split_test_name` for details on + test name parsing. + """ + # FIXME refactor this method into little bites? + log.debug("load from %s (%s)", name, module) + + suite = self.suiteClass + + # give plugins first crack + plug_tests = self.config.plugins.loadTestsFromName(name, module) + if plug_tests: + return suite(plug_tests) + + addr = TestAddress(name, workingDir=self.workingDir) + if module: + # Two cases: + # name is class.foo + # The addr will be incorrect, since it thinks class.foo is + # a dotted module name. It's actually a dotted attribute + # name. In this case we want to use the full submitted + # name as the name to load from the module. + # name is module:class.foo + # The addr will be correct. The part we want is the part after + # the :, which is in addr.call. + if addr.call: + name = addr.call + parent, obj = self.resolve(name, module) + if (isclass(parent) + and getattr(parent, '__module__', None) != module.__name__ + and not isinstance(obj, Failure)): + parent = transplant_class(parent, module.__name__) + obj = getattr(parent, obj.__name__) + log.debug("parent %s obj %s module %s", parent, obj, module) + if isinstance(obj, Failure): + return suite([obj]) + else: + return suite(ContextList([self.makeTest(obj, parent)], + context=parent)) + else: + if addr.module: + try: + if addr.filename is None: + module = resolve_name(addr.module) + else: + self.config.plugins.beforeImport( + addr.filename, addr.module) + # FIXME: to support module.name names, + # do what resolve-name does and keep trying to + # import, popping tail of module into addr.call, + # until we either get an import or run out of + # module parts + try: + module = self.importer.importFromPath( + addr.filename, addr.module) + finally: + self.config.plugins.afterImport( + addr.filename, addr.module) + except (KeyboardInterrupt, SystemExit): + raise + except: + exc = sys.exc_info() + return suite([Failure(exc[0], exc[1], exc[2], + address=addr.totuple())]) + if addr.call: + return self.loadTestsFromName(addr.call, module) + else: + return self.loadTestsFromModule( + module, addr.filename, + discovered=discovered) + elif addr.filename: + path = addr.filename + if addr.call: + package = getpackage(path) + if package is None: + return suite([ + Failure(ValueError, + "Can't find callable %s in file %s: " + "file is not a python module" % + (addr.call, path), + address=addr.totuple())]) + return self.loadTestsFromName(addr.call, module=package) + else: + if op_isdir(path): + # In this case we *can* be lazy since we know + # that each module in the dir will be fully + # loaded before its tests are executed; we + # also know that we're not going to be asked + # to load from . and ./some_module.py *as part + # of this named test load* + return LazySuite( + lambda: self.loadTestsFromDir(path)) + elif op_isfile(path): + return self.loadTestsFromFile(path) + else: + return suite([ + Failure(OSError, "No such file %s" % path, + address=addr.totuple())]) + else: + # just a function? what to do? I think it can only be + # handled when module is not None + return suite([ + Failure(ValueError, "Unresolvable test name %s" % name, + address=addr.totuple())]) + + def loadTestsFromNames(self, names, module=None): + """Load tests from all names, returning a suite containing all + tests. + """ + plug_res = self.config.plugins.loadTestsFromNames(names, module) + if plug_res: + suite, names = plug_res + if suite: + return self.suiteClass([ + self.suiteClass(suite), + unittest.TestLoader.loadTestsFromNames(self, names, module) + ]) + return unittest.TestLoader.loadTestsFromNames(self, names, module) + + def loadTestsFromTestCase(self, testCaseClass): + """Load tests from a unittest.TestCase subclass. + """ + cases = [] + plugins = self.config.plugins + for case in plugins.loadTestsFromTestCase(testCaseClass): + cases.append(case) + # For efficiency in the most common case, just call and return from + # super. This avoids having to extract cases and rebuild a context + # suite when there are no plugin-contributed cases. + if not cases: + return super(TestLoader, self).loadTestsFromTestCase(testCaseClass) + cases.extend( + [case for case in + super(TestLoader, self).loadTestsFromTestCase(testCaseClass)]) + return self.suiteClass(cases) + + def loadTestsFromTestClass(self, cls): + """Load tests from a test class that is *not* a unittest.TestCase + subclass. + + In this case, we can't depend on the class's `__init__` taking method + name arguments, so we have to compose a MethodTestCase for each + method in the class that looks testlike. + """ + def wanted(attr, cls=cls, sel=self.selector): + item = getattr(cls, attr, None) + if isfunction(item): + item = unbound_method(cls, item) + elif not ismethod(item): + return False + return sel.wantMethod(item) + cases = [self.makeTest(getattr(cls, case), cls) + for case in filter(wanted, dir(cls))] + for test in self.config.plugins.loadTestsFromTestClass(cls): + cases.append(test) + return self.suiteClass(ContextList(cases, context=cls)) + + def makeTest(self, obj, parent=None): + try: + return self._makeTest(obj, parent) + except (KeyboardInterrupt, SystemExit): + raise + except: + exc = sys.exc_info() + try: + addr = test_address(obj) + except KeyboardInterrupt: + raise + except: + addr = None + return Failure(exc[0], exc[1], exc[2], address=addr) + + def _makeTest(self, obj, parent=None): + """Given a test object and its parent, return a test case + or test suite. + """ + plug_tests = [] + try: + addr = test_address(obj) + except KeyboardInterrupt: + raise + except: + addr = None + for test in self.config.plugins.makeTest(obj, parent): + plug_tests.append(test) + # TODO: is this try/except needed? + try: + if plug_tests: + return self.suiteClass(plug_tests) + except (KeyboardInterrupt, SystemExit): + raise + except: + exc = sys.exc_info() + return Failure(exc[0], exc[1], exc[2], address=addr) + + if isfunction(obj) and parent and not isinstance(parent, types.ModuleType): + # This is a Python 3.x 'unbound method'. Wrap it with its + # associated class.. + obj = unbound_method(parent, obj) + + if isinstance(obj, unittest.TestCase): + return obj + elif isclass(obj): + if parent and obj.__module__ != parent.__name__: + obj = transplant_class(obj, parent.__name__) + if issubclass(obj, unittest.TestCase): + return self.loadTestsFromTestCase(obj) + else: + return self.loadTestsFromTestClass(obj) + elif ismethod(obj): + if parent is None: + parent = obj.__class__ + if issubclass(parent, unittest.TestCase): + return parent(obj.__name__) + else: + if isgenerator(obj): + return self.loadTestsFromGeneratorMethod(obj, parent) + else: + return MethodTestCase(obj) + elif isfunction(obj): + if parent and obj.__module__ != parent.__name__: + obj = transplant_func(obj, parent.__name__) + if isgenerator(obj): + return self.loadTestsFromGenerator(obj, parent) + else: + return FunctionTestCase(obj) + else: + return Failure(TypeError, + "Can't make a test from %s" % obj, + address=addr) + + def resolve(self, name, module): + """Resolve name within module + """ + obj = module + parts = name.split('.') + for part in parts: + parent, obj = obj, getattr(obj, part, None) + if obj is None: + # no such test + obj = Failure(ValueError, "No such test %s" % name) + return parent, obj + + def parseGeneratedTest(self, test): + """Given the yield value of a test generator, return a func and args. + + This is used in the two loadTestsFromGenerator* methods. + + """ + if not isinstance(test, tuple): # yield test + test_func, arg = (test, tuple()) + elif len(test) == 1: # yield (test,) + test_func, arg = (test[0], tuple()) + else: # yield test, foo, bar, ... + assert len(test) > 1 # sanity check + test_func, arg = (test[0], test[1:]) + return test_func, arg + +defaultTestLoader = TestLoader + diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/loader.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/loader.pyc new file mode 100644 index 0000000000000000000000000000000000000000..97ebf4d208ba3363bcf9b8b76e6e781254e67a53 GIT binary patch literal 19273 zcmcg!Ym8jiT|akbU$dU|uGil6WBs^J{1`j-I*&GK?KC9y)`^>B6YeD5bP{)bcjoTy ztmn1&+_iT@Ttb{z5vnLEg7T0GMMbE<2PCAzmm-0H5AdZDe5jC+s6c>_kbo~#MdkPV z|IfWMYi|l)wzlWYx#ynu`Tu|a*BR&kb8PfyW^P`q8TTiT@2Byx-|>v88&g5*nR?DN zJ=4mWO3rwE&YNc5RPyo;`2kZINb`fHGMMIvOl2s|51Y!cgQqaBzO>@+= zcA3g9(<+)uQA>wRbIi1Mo62s}8aI`3Egd$^3DeqRDtq*K#55;OYp<#7)#rj~?lY|^ zQ<*ZYX;Yatt^KC5U*CXetLy>yW7&($Za~Ib&LfP35p@9Wj+7rghX*j+)jn zQ#oc@zNz@8b=*{ro7MxS@_=bQXetky)(KNNVOl3m<)rpfG|f|{b=p);n^wtGN~U$j zRL$o4cN=%$jJxtX?py51Yy(Y5q}Dc`VI;%v3&} z<{vkeC(`^UOy!fNzT4Et%`#5rBJulgJZu+fG z9Qn=0VibqX(MCIo;%*!zA-lGIXUV_45+;5t-1HYCKh(K}?Yh6xxt%_`mu<|gK0Dg@ zA^wy=!zLL;vK+P1bJB_Je6O%!)7h7DthgJ=dV8_6-mX_$QL@shCnG3oSbfk+6DYaj z7R@DH4s9eYUz8SUk&ZIV%3-6q9!FX*go4YR_EKZHL{5|bueQ3K7z>t%uwJir!(=7d zh1YS^>fDOtSqC3SVLe(3*PBT>YDP6INGfvFXX^DhvbMzKN+B0lZ8q9byW{pC>4vqN z;c}F4UJWZJBvl(W+n}T%@6wvwlQ>$AHmW$zqi1gF=*ndJ20r$W{NOPt>DcFV- zsD>1Hh7?GKbcAW|pJ(0$5Eh7*;JwNyIgXiKramBM z9Y%XhyP8Hj51iTKDks* zKO%OZ?+}bmiewl5R(K#U`F4HL)pw&@X`l;sLoia-Z*}VHO?233gZt}^SU6$R)i1Ai z$xv=$*_auH+k5Ioq21IK+Z1g&v0qyW+smADN2k3Qt%SE4c#*8co%Q7vzuR12ZnU+t z8p($r67*$mYYyA`mI%(9BPKpz5|3bf$1`n|gQ{|d<&T>Ld5<;k8t+a{-a@MC+j*9+ z=FOeFltaR5dBY?F(!?`&226X#B!lLy0Sc4&U1r#uzLGh-WlVL5gEBKr%mFLCm1iCN zV_{xeAu}o??lSRT8?ZU*uq%jsOgaJ0rW0kG-3ENW3=yMUOc*fO>ZDoS%N|kaVX|cb zIXjMBxe77RfRK1I@+YJh=SuLLhU;tciRDGOO2eJwWDJ4pSj_BAEjxGt?wdj)HSRy^99fH(8qQ~2f zWTmeIhb8{4u(?iBwEnuKf$b=iS z{?)B>J?Dr0)ny~nQD?8Z;jtOpOzw6kzS(Fm&o$zUm_gLzB2xVAl}2sFUurb5zhFFN zH=ke+hK{4YG2^HSA$=>_Zfe%9Ll(0?2yKp0TaRNX5xyI{ubYgA`}fZ}5qA+slIHas zdAjKV%E+NBZzw`_X0cCSQy+h<#@0bE=1Oa7jaFlOF zHAz(mzUy?W?M~bh?SZln&*7q#N7hYen5r41C>v0M2K$l7XqNK#G8MNZFHI7#J(&Gg z!{S9pYE=Jt0Q_9W$9@S3aBLO-fU3s` z(*WXCV5>kXFtH41WDT)(-pv_+Hx3mj3*|}y7?ptB0MTN+!aYJMFcGDAL}nQft-y|6 z3MT$p9sz1Y?_s|MLwr{3MX7_*D(3alttgHOePAp-RHftefT?psIQBTf5ij&U3VI6J zd2;gQ4rzth@JhViBl;RoKHZEmH{(SlNh(U}Kz9*I*b>YOlZ+oWpcZZi9%apKNCRw@ zytPkLJe9FAtJoeXDvK^WUm~T8DvFtfNfHOgP!LdO4|pH}CxW(Ap_@>$Nz=EXV5*{B z;uM9>*i^{1)=bH^DK9{>FvjpllARznVPnoIsy8u?rGjgO*hp{#o~$ljZ*$*Ee5tHE zjokL95u9PA!$=Zp(Dzmn{*gg}%`_RfMZiuOXC<_<6@(Ki#T-=k%D!p=^}!*$2xgGT z-USaKC+wX#su0Ex9%C_gy#_+DJG+0u;}|Ex$4(+K14VCdZgONQKaJfhcn7^2=^*_G zV;(^P8OezL1UmCFPK0ta1U@1C%!}fo^mHE20hb{rgRYviLtxz5)rqB4h1wWhQ~bPx zVJ(s0xfmQ$!lwoSNNJm|@)mX)34HCxi>We5GHy?^RduNCoc?Z}&Wa7V*{D=%9TCb}!Y}!wnWN+F8^P=wWx#1Kn z^PUdJb)fCOv@+UaxT*9J>lilirVKId3XAS}zkBvLmtXd{VFzek$Urdh)D*ZQn|FwH zVRa@mSdn+lYwwmW54$d|N$VrhdhI*jTcEl>+_oKFa>hr^2gZEhnI)JlL*{+inrmDU z{w=^7xHD=tPRJ30c!g%?uJ1K>Aks$7s&C$s^YGUG&0E-#tPUI5Y30V4GfdV zx#R4LCOKu^DsmieZ7sKep}2LYQ|5vtUM`K0M8AuKUIS-Bs%^VPM~2)ae$4u>tU!L^ zU+8D{Wv2I?Kkr8&^k~tl=)@w>I#W4JmFmn+5p5eiZ8oB2J*sEDPyt7Aw9$o?o2k>$ zMpRqp<6^W#*BRC8Hq3Ta+WXYtXd`UF2h?YnSV|VLrDb6dAO1-T95rTE(yGlf59Nyz zw+=rMoKSI8ui;7l5VFK~K)&W?BNa+Wfr)*I{NgASLzX5COpOxTtLuh+L*b4$#l0o4 zEN^#2O!HKqY=*7Hdid0zB5(15kl=sz z_o6*R4}z|3MFi6gh5b}XOOYl{D<1ocVNzR>4TaemCzh5+@E~h&AgJoA9e6#djUx}o zBuuYBB-aVn;ryv)TtTrsNF|IU@|$mZ6QiFic#6r>NThaoPv18www}G zL(!h76yE<@WbFdufi=wI4CA8jsn!nl5w9^H7ot4_M|riE(u znTtI_-+KU#{Ss4ja-;%Z>$ zsmchUNom7YWp72x;ovCXK5{fdiI!d}yBlIn^L?C|`84`|~-ocE%Y#@pWpF zb;!ZgGGI%{P&ET^-c)wPCZfFq35Ij1i!Ct?lzzv9EVuz#u#4U(CkuX^B7m~sS!O`q ztGn3}vS0fKvqI2A1|HkChT`%wcaKLud~4$Os+He zJQFgeI1*G{CoXVibU+25KNBn=5!e7+C{Lom>nfc5$E32cVC@ z4MIOcK$IYG!Bh8;kf3r&)>d?XZo@D>1YBXT%|)~EI++z*J9qtM!iL)gQM%udeW5C^ z4h7HHD|Ek5F$deKe?bnPyM{t>i?cf~2TgR$EG)EN0%i<|=D3lf#gl>-(EEo3Euats z4}eX100h1W7x)5PK&=HX;Vb|^014G70m5Z*SIn!G6)y`F*CSht8(l=J?qQe!Dv=RP zNvH*M!`Md8Y6vnCg-AqQy5Ye&)CmTd2s3QugMi+G61P!A(6Xd0VS`M&keFN0We*+J z7N#YnWlHIfLBVokMgNU)?ExePj4~l&YSKF z+4yD#Ltp!Uz|cz$hImFP81?W7#{qbPKVh9`@e$aRVOspFQcDm&tD7Pi=p5*TL&ckE zjL;8jBLZuGxfRw5W)e} z5xT6(t%+(?VZR48(nKeN=gxe3Q959dRprjHYDB4ScZ(?95!Nxgn<2`PMKF(dg zO-~%y49{?rfwmcv0EI)QBM&D0a@vLX;8^l)@&&96t>CSF+pIk&5f^RnT-pGxsw&r2Q}Ob2kD)GJ?E;hH1=o@U$NvJy&+lTN|+LL1cr2Q*;0*mRP_SQ7v2>RTU}+7 zGu7xe!ws_am{&y914or3M3l0<+!GWlQA+~I)L~sq#8Kc?i`oc@r>-xFg2UV+7;-4N z77>C_-GgYgW z7Oqg={glTVu%UlKOl>|~#FO8#v&_%NQP^arbkd&T3y~G`r6XL;vrL|2LP;Ygh6Ft2 zwo~v4z7T0D<~1WPqCK;UhVCk?AxBL?EDl3=Q&ByVbe)L-(+a!6^Q`7)slPn76SxSlCu=Jl%c#DC#Mr!X0n7t;%D4n)#H$%mre?(G1}l!)&!DjO=S&nCtL9d_7#*+$@%Rvy4ewL z!7pH(kC9}a=7{jyiHC0BAbbRq@X}4<`zUmU31|zG-o)T!Zpb^H8^dz}&&Tk#;2q6R zdVcO0{B)TVC2NZmT|t^jQEH(;(0m#{gNPw-iCYfQ5BD0P2YCcT<_M(75JIUYitCLH zhEe1pz=h7@IR=#wQHv7_E@bq|8mj@Eb-tTnA$LW3qYX<&L|Up`!>r{M>QiPhN|$yPAEwyB zqjTor0e)xB77`RP1#^>|7O?D@_e6fQ{T$b}*Tjpt&9`NpxJx-C5#==xF*tpTRnbg) zy>C+??a**vS^=W>&13RAShaSInjw0u96M+Mnfga){dDPO4V^5I(z{ zncgzBTL#k+eJP>as2mJa zbpW^PVo>|=sKJ?eu6O0`oKrn$+d|dY^gD~I2s35Mf%CJaF~eEE97XQl*?Q7w&Wi7( zD!|CmZukfZLi2#K(}dt@XZ^5-&W9c;=s|sI22q|^tx6OG76nw`qf}70T6JhzwTDoq zQd;EN;wr!NZ6?pQvknE=?NexdIc%S1q!KDx%{d*}2V9BH|9nw1PU8xFy$I$835eh| zeB=+^KcZStxRE5pYeI}GQ4;EPf00Qg)>jXc$eD-u$g&*~1Xs}UU!=N&rLdmIb*=UE zTIES=52EbVcAq=7cRVL;=``N1hhGScwFP zB)`mx;`O2eE(>JXR=B}RT?Q_K_gF2D1gs@KQt8}<`?jNu9U%%H8^bF0ZDh>I-drJn z02;z*Zps@PEx>+0AP!R8N`%{V8WFs)+zdVi_!q`Sf0!7`LqnK`CXvSPilR>xaB*q~ zZAbBze|hJTQNDa`0y+ii59jfXNFRI^6W;Uy(;ByfJ2!+6x6#tcsul!XlzQt(rG?&O zj6=$ZHz1t{s1^WnSppdiVXvv&Ji(>|+u0nwsm74!FO8u=}H$Mg~zC&-VS;#ZJahEGKf0B}fmb6&3H zKr@s;3Qj_dZfH*8Wx+|J$Xk2BETF)?$}<8_;ryT}WKG;1PISHP>$&R)0i(wO!w_&H zJ(4U$&&%-GK91Slcf>#9XCOThC3kar;YR3b_gELNK)hXs4HM7~a+rW0qRD9nUq+dn zaPM4$ODubm$yK(Xl}a0EhmZ4jFwFOOocoY52+J24lpkPdo&otY8j2@VW{mlZcpxib zJ0+CxE_e`nE#@rzrQtE`F^+5Q`f-WA3qxW_Y(~Y78KgX$63=PltaK+4F`kk5nuIEF z@L*9W&tfWgYZ0gdy%oe;rqMQ5R#yx$#2&|L?mtrzXX1f}^FuEhpM?X3zWwz2xcn%P zN0xDJ`s<%QCF&|8j8Fx5H0S)=5i(RC>Je|5K)sRpql|Of`Zv;h=m@EY{DFgWS7!r| zkF)Fkz!ZyLJ48M&X)+$pum@t)n4-EjQ<4&mikG>veq7kWg+Ke2+3a*~;$i@3k-voM zk*~llNsJ!?-HzU??sF92aQZG(>#d?$lxcMB0^ict96ZA0QNF-u2Q{O|(EATa|I}al zZ%d0SLFp36N*@&e7GJ!_q{HOve2dQxk|AlT z0P8{Q8Af&XK|>+{Q*)w!hWSxFqG8nKgfHV`n`i{0aXT%*4CuXQr_ZIwqdPss_uOeX z!Fjg#`Djw)#S1uM9P$QcVRJuECjMz@C8tDDy3l@J$pLqn^os1SrQ?p?XPNh`=z z{K*{N$E6%Q>0eVRm&lE0yk+Ovnz9k*a$JDlKf>{Bg#A1vct7Z-qEABE4$c_yLy-C` zO^0X2#}JBeaXtc#OyE|rTI8vY?7K>onVHCfQ$S?0L_>OlX*+%v<5bOb@^jjqgdk4h zH}nr;HgYjVxm+C588oXMDbDCqtoH_!%m`GYQ-sp5;DzXE31Y$O-F;C!#EcDV^!N;` zj37xRv6{8N#4g`vLM_mlwW;n9P{Rrcy808M0&-RLAtUNaB|5mvguok62@7yE?gGvi zkdvD}DlmGm^qZ{mbtV)Tf>JvSP``(94iKPd3mfQ%{jfy$Fb%vt8E8G2JDH!%P2yKa zG$W^ALXN@sOMm`029t3Dj%Ix)c^Hh_!P`v?1}dh>2O8I#D*|sDrzs5Pt{)SJvfNYy zGy$uCCU^5D2M;nDtsREC2qBUecWOwZ8(JuEhlEYO(BHfPwh*!)_s|7H?QhYAsW8Xmn$3Hd^S^%~Yw-H?)Kahegz-_(eE~o(7 zAj)q7r=DjeVm=%7DxTk3alqIb&k6T!U3GqW=9udk)Q}z)=VQNwM4^a|PrXqnzk=pn z)le}eyZh6JNDSHtUg6iau+FnnO)nnt_tSI&ve)FcUQQ+3%dZErD_3WoM&I9qURA}k zoKo8Z7P^|m?}OW;;~;z@6R zj(j^`n!!s2H^Q7as;bp`rv~uq0qt>C@|m1qB0zhVxyPA2#pG!wb4-XJ3UZ(Vy<4aL zw`+X-29q9UzRyR3Pe2L{IMv>6NNz`bV}~&gReVb&eP~2)wo3~CSMf~YKw+dXPj(I+3FPO_T;Vgx1nYwS_vdKJ=N_3F>RIYe)KI{yQ9rG8X8nN_^enIB9t z*~>&^oVa|@pl4$599kv9%+6Yzf*O8^TqtZADSPUx&H;M;)(?T literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/__init__.py b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/__init__.py new file mode 100644 index 0000000..08ee8f3 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/__init__.py @@ -0,0 +1,190 @@ +""" +Writing Plugins +--------------- + +nose supports plugins for test collection, selection, observation and +reporting. There are two basic rules for plugins: + +* Plugin classes should subclass :class:`nose.plugins.Plugin`. + +* Plugins may implement any of the methods described in the class + :doc:`IPluginInterface ` in nose.plugins.base. Please note that + this class is for documentary purposes only; plugins may not subclass + IPluginInterface. + +Hello World +=========== + +Here's a basic plugin. It doesn't do much so read on for more ideas or dive +into the :doc:`IPluginInterface ` to see all available hooks. + +.. code-block:: python + + import logging + import os + + from nose.plugins import Plugin + + log = logging.getLogger('nose.plugins.helloworld') + + class HelloWorld(Plugin): + name = 'helloworld' + + def options(self, parser, env=os.environ): + super(HelloWorld, self).options(parser, env=env) + + def configure(self, options, conf): + super(HelloWorld, self).configure(options, conf) + if not self.enabled: + return + + def finalize(self, result): + log.info('Hello pluginized world!') + +Registering +=========== + +.. Note:: + Important note: the following applies only to the default + plugin manager. Other plugin managers may use different means to + locate and load plugins. + +For nose to find a plugin, it must be part of a package that uses +setuptools_, and the plugin must be included in the entry points defined +in the setup.py for the package: + +.. code-block:: python + + setup(name='Some plugin', + # ... + entry_points = { + 'nose.plugins.0.10': [ + 'someplugin = someplugin:SomePlugin' + ] + }, + # ... + ) + +Once the package is installed with install or develop, nose will be able +to load the plugin. + +.. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools + +Registering a plugin without setuptools +======================================= + +It is currently possible to register a plugin programmatically by +creating a custom nose runner like this : + +.. code-block:: python + + import nose + from yourplugin import YourPlugin + + if __name__ == '__main__': + nose.main(addplugins=[YourPlugin()]) + +Defining options +================ + +All plugins must implement the methods ``options(self, parser, env)`` +and ``configure(self, options, conf)``. Subclasses of nose.plugins.Plugin +that want the standard options should call the superclass methods. + +nose uses optparse.OptionParser from the standard library to parse +arguments. A plugin's ``options()`` method receives a parser +instance. It's good form for a plugin to use that instance only to add +additional arguments that take only long arguments (--like-this). Most +of nose's built-in arguments get their default value from an environment +variable. + +A plugin's ``configure()`` method receives the parsed ``OptionParser`` options +object, as well as the current config object. Plugins should configure their +behavior based on the user-selected settings, and may raise exceptions +if the configured behavior is nonsensical. + +Logging +======= + +nose uses the logging classes from the standard library. To enable users +to view debug messages easily, plugins should use ``logging.getLogger()`` to +acquire a logger in the ``nose.plugins`` namespace. + +Recipes +======= + +* Writing a plugin that monitors or controls test result output + + Implement any or all of ``addError``, ``addFailure``, etc., to monitor test + results. If you also want to monitor output, implement + ``setOutputStream`` and keep a reference to the output stream. If you + want to prevent the builtin ``TextTestResult`` output, implement + ``setOutputSteam`` and *return a dummy stream*. The default output will go + to the dummy stream, while you send your desired output to the real stream. + + Example: `examples/html_plugin/htmlplug.py`_ + +* Writing a plugin that handles exceptions + + Subclass :doc:`ErrorClassPlugin `. + + Examples: :doc:`nose.plugins.deprecated `, + :doc:`nose.plugins.skip ` + +* Writing a plugin that adds detail to error reports + + Implement ``formatError`` and/or ``formatFailure``. The error tuple + you return (error class, error message, traceback) will replace the + original error tuple. + + Examples: :doc:`nose.plugins.capture `, + :doc:`nose.plugins.failuredetail ` + +* Writing a plugin that loads tests from files other than python modules + + Implement ``wantFile`` and ``loadTestsFromFile``. In ``wantFile``, + return True for files that you want to examine for tests. In + ``loadTestsFromFile``, for those files, return an iterable + containing TestCases (or yield them as you find them; + ``loadTestsFromFile`` may also be a generator). + + Example: :doc:`nose.plugins.doctests ` + +* Writing a plugin that prints a report + + Implement ``begin`` if you need to perform setup before testing + begins. Implement ``report`` and output your report to the provided stream. + + Examples: :doc:`nose.plugins.cover `, :doc:`nose.plugins.prof ` + +* Writing a plugin that selects or rejects tests + + Implement any or all ``want*`` methods. Return False to reject the test + candidate, True to accept it -- which means that the test candidate + will pass through the rest of the system, so you must be prepared to + load tests from it if tests can't be loaded by the core loader or + another plugin -- and None if you don't care. + + Examples: :doc:`nose.plugins.attrib `, + :doc:`nose.plugins.doctests `, :doc:`nose.plugins.testid ` + + +More Examples +============= + +See any builtin plugin or example plugin in the examples_ directory in +the nose source distribution. There is a list of third-party plugins +`on jottit`_. + +.. _examples/html_plugin/htmlplug.py: http://python-nose.googlecode.com/svn/trunk/examples/html_plugin/htmlplug.py +.. _examples: http://python-nose.googlecode.com/svn/trunk/examples +.. _on jottit: http://nose-plugins.jottit.com/ + +""" +from nose.plugins.base import Plugin +from nose.plugins.manager import * +from nose.plugins.plugintest import PluginTester + +if __name__ == '__main__': + import doctest + doctest.testmod() diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/__init__.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..07f7d418a84e917eb988631347a01ab35d9f5155 GIT binary patch literal 6573 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 literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/allmodules.py b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/allmodules.py new file mode 100644 index 0000000..1ccd777 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/allmodules.py @@ -0,0 +1,45 @@ +"""Use the AllModules plugin by passing ``--all-modules`` or setting the +NOSE_ALL_MODULES environment variable to enable collection and execution of +tests in all python modules. Normal nose behavior is to look for tests only in +modules that match testMatch. + +More information: :doc:`../doc_tests/test_allmodules/test_allmodules` + +.. warning :: + + This plugin can have surprising interactions with plugins that load tests + from what nose normally considers non-test modules, such as + the :doc:`doctest plugin `. This is because any given + object in a module can't be loaded both by a plugin and the normal nose + :class:`test loader `. Also, if you have functions + or classes in non-test modules that look like tests but aren't, you will + likely see errors as nose attempts to run them as tests. + +""" + +import os +from nose.plugins.base import Plugin + +class AllModules(Plugin): + """Collect tests from all python modules. + """ + def options(self, parser, env): + """Register commandline options. + """ + env_opt = 'NOSE_ALL_MODULES' + parser.add_option('--all-modules', + action="store_true", + dest=self.enableOpt, + default=env.get(env_opt), + help="Enable plugin %s: %s [%s]" % + (self.__class__.__name__, self.help(), env_opt)) + + def wantFile(self, file): + """Override to return True for all files ending with .py""" + # always want .py files + if file.endswith('.py'): + return True + + def wantModule(self, module): + """Override return True for all modules""" + return True diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/allmodules.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/allmodules.pyc new file mode 100644 index 0000000000000000000000000000000000000000..af89aeef922ac6b4cb77ec17c11335117c2a4762 GIT binary patch literal 2535 zcmcgt-)|!|5cX!<+%@#LgA*X&#SavUXf^_bPKv4%1qv_yfzlolJ)w=W>m=Jcc4T{7 zB9#YJ{$u_C_-1xXp}JQt%6i9Rd*++ZGqdTRk9xm>ll1mjrWoL3c?)Q~3{YA55JeJPOpkt&(obDYRpX}#*2M77#@pmr{_D`g? zmz8&Rp>33x%2#S);KxDFQsIozMXa2a%9c|9s*9RuZrY1F#2^6x9_4Zs=h)Ob&g7Bv z3uUBrfIZQ3by)#P709%4?m|v6Z45YTRHOa-m`|=M9G>Wxd{^^BUW54r{#mwofo`soH@rgsK7^ zrweYvLQK4?1-9GH!}D?0AO`4(E>sPEm0ihMb*U|xaFcUf7+*{4LL#b9B6c%YUCN0= z5Xc&J8#Y}nxo+SxbTTz84DxC?W*`)&_Hviv%9=@biZ~8fPq6k(a67V^%9X1d7N@ms zcw=B*vOOd&a^^k_w`3wUOm%@23=#K&v8ViHjKZ zVu`#&qWRiVSPNQYdq|_|FZ_h?+WL`eDE1)URaSu+|7hDcc*3U`H0l^7im^i# zj6y~2qDV{Kq?>FckCQYhI?&ucoEz^!(Pl+LSMQ&Sn1~bpWDp(UD-6e%C=PTTt_2-y zZ{;bjgL^Nf;k2T!h_)qlL+)&V6X-bJN899(S;US&%gh~F;H42|0ISH(YvhYA_Db3K zJ=|_V4wPOZeSAj~l`YdmD^VcjNfSQ8@DC^c6@;{(4cF|IX_XaZY{%U0An+ zWPW3#yS1=JU4!BGAQmJDbUq&fmns BztaE! literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/attrib.py b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/attrib.py new file mode 100644 index 0000000..3d4422a --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/attrib.py @@ -0,0 +1,286 @@ +"""Attribute selector plugin. + +Oftentimes when testing you will want to select tests based on +criteria rather then simply by filename. For example, you might want +to run all tests except for the slow ones. You can do this with the +Attribute selector plugin by setting attributes on your test methods. +Here is an example: + +.. code-block:: python + + def test_big_download(): + import urllib + # commence slowness... + + test_big_download.slow = 1 + +Once you've assigned an attribute ``slow = 1`` you can exclude that +test and all other tests having the slow attribute by running :: + + $ nosetests -a '!slow' + +There is also a decorator available for you that will set attributes. +Here's how to set ``slow=1`` like above with the decorator: + +.. code-block:: python + + from nose.plugins.attrib import attr + @attr('slow') + def test_big_download(): + import urllib + # commence slowness... + +And here's how to set an attribute with a specific value: + +.. code-block:: python + + from nose.plugins.attrib import attr + @attr(speed='slow') + def test_big_download(): + import urllib + # commence slowness... + +This test could be run with :: + + $ nosetests -a speed=slow + +In Python 2.6 and higher, ``@attr`` can be used on a class to set attributes +on all its test methods at once. For example: + +.. code-block:: python + + from nose.plugins.attrib import attr + @attr(speed='slow') + class MyTestCase: + def test_long_integration(self): + pass + def test_end_to_end_something(self): + pass + +Below is a reference to the different syntaxes available. + +Simple syntax +------------- + +Examples of using the ``-a`` and ``--attr`` options: + +* ``nosetests -a status=stable`` + Only runs tests with attribute "status" having value "stable" + +* ``nosetests -a priority=2,status=stable`` + Runs tests having both attributes and values + +* ``nosetests -a priority=2 -a slow`` + Runs tests that match either attribute + +* ``nosetests -a tags=http`` + If a test's ``tags`` attribute was a list and it contained the value + ``http`` then it would be run + +* ``nosetests -a slow`` + Runs tests with the attribute ``slow`` if its value does not equal False + (False, [], "", etc...) + +* ``nosetests -a '!slow'`` + Runs tests that do NOT have the attribute ``slow`` or have a ``slow`` + attribute that is equal to False + **NOTE**: + if your shell (like bash) interprets '!' as a special character make sure to + put single quotes around it. + +Expression Evaluation +--------------------- + +Examples using the ``-A`` and ``--eval-attr`` options: + +* ``nosetests -A "not slow"`` + Evaluates the Python expression "not slow" and runs the test if True + +* ``nosetests -A "(priority > 5) and not slow"`` + Evaluates a complex Python expression and runs the test if True + +""" +import inspect +import logging +import os +import sys +from inspect import isfunction +from nose.plugins.base import Plugin +from nose.util import tolist + +log = logging.getLogger('nose.plugins.attrib') +compat_24 = sys.version_info >= (2, 4) + +def attr(*args, **kwargs): + """Decorator that adds attributes to classes or functions + for use with the Attribute (-a) plugin. + """ + def wrap_ob(ob): + for name in args: + setattr(ob, name, True) + for name, value in kwargs.iteritems(): + setattr(ob, name, value) + return ob + return wrap_ob + +def get_method_attr(method, cls, attr_name, default = False): + """Look up an attribute on a method/ function. + If the attribute isn't found there, looking it up in the + method's class, if any. + """ + Missing = object() + value = getattr(method, attr_name, Missing) + if value is Missing and cls is not None: + value = getattr(cls, attr_name, Missing) + if value is Missing: + return default + return value + + +class ContextHelper: + """Object that can act as context dictionary for eval and looks up + names as attributes on a method/ function and its class. + """ + def __init__(self, method, cls): + self.method = method + self.cls = cls + + def __getitem__(self, name): + return get_method_attr(self.method, self.cls, name) + + +class AttributeSelector(Plugin): + """Selects test cases to be run based on their attributes. + """ + + def __init__(self): + Plugin.__init__(self) + self.attribs = [] + + def options(self, parser, env): + """Register command line options""" + parser.add_option("-a", "--attr", + dest="attr", action="append", + default=env.get('NOSE_ATTR'), + metavar="ATTR", + help="Run only tests that have attributes " + "specified by ATTR [NOSE_ATTR]") + # disable in < 2.4: eval can't take needed args + if compat_24: + parser.add_option("-A", "--eval-attr", + dest="eval_attr", metavar="EXPR", action="append", + default=env.get('NOSE_EVAL_ATTR'), + help="Run only tests for whose attributes " + "the Python expression EXPR evaluates " + "to True [NOSE_EVAL_ATTR]") + + def configure(self, options, config): + """Configure the plugin and system, based on selected options. + + attr and eval_attr may each be lists. + + self.attribs will be a list of lists of tuples. In that list, each + list is a group of attributes, all of which must match for the rule to + match. + """ + self.attribs = [] + + # handle python eval-expression parameter + if compat_24 and options.eval_attr: + eval_attr = tolist(options.eval_attr) + for attr in eval_attr: + # "" + # -> eval(expr) in attribute context must be True + def eval_in_context(expr, obj, cls): + return eval(expr, None, ContextHelper(obj, cls)) + self.attribs.append([(attr, eval_in_context)]) + + # attribute requirements are a comma separated list of + # 'key=value' pairs + if options.attr: + std_attr = tolist(options.attr) + for attr in std_attr: + # all attributes within an attribute group must match + attr_group = [] + for attrib in attr.strip().split(","): + # don't die on trailing comma + if not attrib: + continue + items = attrib.split("=", 1) + if len(items) > 1: + # "name=value" + # -> 'str(obj.name) == value' must be True + key, value = items + else: + key = items[0] + if key[0] == "!": + # "!name" + # 'bool(obj.name)' must be False + key = key[1:] + value = False + else: + # "name" + # -> 'bool(obj.name)' must be True + value = True + attr_group.append((key, value)) + self.attribs.append(attr_group) + if self.attribs: + self.enabled = True + + def validateAttrib(self, method, cls = None): + """Verify whether a method has the required attributes + The method is considered a match if it matches all attributes + for any attribute group. + .""" + # TODO: is there a need for case-sensitive value comparison? + any = False + for group in self.attribs: + match = True + for key, value in group: + attr = get_method_attr(method, cls, key) + if callable(value): + if not value(key, method, cls): + match = False + break + elif value is True: + # value must exist and be True + if not bool(attr): + match = False + break + elif value is False: + # value must not exist or be False + if bool(attr): + match = False + break + elif type(attr) in (list, tuple): + # value must be found in the list attribute + if not str(value).lower() in [str(x).lower() + for x in attr]: + match = False + break + else: + # value must match, convert to string and compare + if (value != attr + and str(value).lower() != str(attr).lower()): + match = False + break + any = any or match + if any: + # not True because we don't want to FORCE the selection of the + # item, only say that it is acceptable + return None + return False + + def wantFunction(self, function): + """Accept the function if its attributes match. + """ + return self.validateAttrib(function) + + def wantMethod(self, method): + """Accept the method if its attributes match. + """ + try: + cls = method.im_class + except AttributeError: + return False + return self.validateAttrib(method, cls) diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/attrib.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/attrib.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cb8ee94a64f5faf298b7aec2ce81d5fdf027e792 GIT binary patch literal 9631 zcmcgyTW=g^8UAKZ_HOLhb$Uo?3ty6gH^E*jDWxK6s=A3wE9IoMX&Sd?J)W6ePdq!b zo^Lj`g@XjCpaL#H;(`lQA;b@W8}8wPEB*zDKfn)w=Xt-`T|0H!o7#?NJcsY_9-sFx zDgJk|_LG;kKJZljQ^eo5ahQMLm5V`_EG-j`K0uDVsVT2)R^P!DR#uc*h^;*<(X>cNEar_>gvPb$Bv zJ^>l0RWPOen)(D|rj>t6`8ZGT)nldZuRf#vNfnH#HugF_d^$tIm+Q}vpHrulTFkOE z+~{Y4HbE44S(55r)bE6GqgK1q&Vo1#yMfU=n?bCzz+_?E(R)c>?}SmLcicGBS&~nc z_eO8HCh&C<*Ss{$f;4n>>Smiks&R_73A?>$PjBq$b{GY*+YK7}U2Gccx_A-H$>QCx zvzf{2HLRZYW9?!$Zf`Kq3woJuV-6P7CQ5d&SzsFaKFIRiSo;aygrGUhHaVvDR31r& z2{K{I9SFi;IZ}c3v7zn;*=FLKM(w>I4K$X;4mq(`Yqds0dx;;+Z$yc=b@i(5?O}9W zt7-iBL0gt+ZG@ecpX|g@;`;TASLG!KKom)u>3$kT;l}Xk1+3WZ2C-+E18b(yfHpXT z6dhWwA^cy{m!U1r0Nt|>1MM0Uc4DXj#10wL>+6Hj>+2$CN(=Ig`hEaGxmis(c4N$g zyc4T6k@}|lkeVM#e6%P;2nEG_dldp9m9OeJfmmhYysKx=aogEiZ3R|fMHrbxyAY6< zz&4;s_n{j`?nV@dUTI$>#~K+{8u5_pVbYh_wU%+A*@ZLN67Q^OAn#>y1EsU08dHEm@i<`C9G$Sl<OfC zgF%RjU=Or#EZet`1e^0B_{P9+hE{B9@Oj#N2!s)ea<_-&0S-KX)IpRwZaG^bZ|$wX zg{}imN02czv?z%?tuW4l4m>DK;yU2FeE?hNhdr<==EPklaNig?o(&i z-U$e>ggu=GZP+AH27X5*@WZw|$+X#vGj|tpV(7>KtYtzyKuq4%<`4eVYD*UH0k&;u zXMip1>+>$OMqT1^p8COU(j$ikQon@9hp@$DZq_%~@CV?rzD{oM#E36|B&*0g3=B1` z&)X^Ibq;CbIPw%LoIhfVUK%EdWP8`H%pI{?bF@*u;0AE>0AL9-vWfY^#Wj$Uc5RtB zu&f|q*Uh|59U!71kPewSV!_Pqm}{F^*0bxp--hC7(14Qlb-tu{2cZrjmWqu+#5u}5 z%n*B^$&jIg8Wy@K)b(|{CZEO}w{yT_k09enPKJm)BEW_u&=j`C_pCPj1f~=xnGUx5 zZlvFJBNLE{x?IiakJje&`SWu+$UKC`i%0CA$DE^ui3H*HofR4Y!ye+rP#!~a5R>G! z3(iNpj0TEQ;1!lY_`{IKOP8?r(xpq{v*1cH39}ghTkf9 z*wBN3Ir#N9-PHB)UUyxDGt)=Z%n}Nq*N3mcS>RUN{RDc|ZkqH(b8xt&T`Y*m4=h`v zAO#o>JKn$v4>;fl=)6cf-x;J)v^hWrBg#g@#pJA`Vx*uh z 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 R#!RC=nkrN$CQhH3_&*e^#3TR! literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/base.py b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/base.py new file mode 100644 index 0000000..f09beb6 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/base.py @@ -0,0 +1,725 @@ +import os +import textwrap +from optparse import OptionConflictError +from warnings import warn +from nose.util import tolist + +class Plugin(object): + """Base class for nose plugins. It's recommended but not *necessary* to + subclass this class to create a plugin, but all plugins *must* implement + `options(self, parser, env)` and `configure(self, options, conf)`, and + must have the attributes `enabled`, `name` and `score`. The `name` + attribute may contain hyphens ('-'). + + Plugins should not be enabled by default. + + Subclassing Plugin (and calling the superclass methods in + __init__, configure, and options, if you override them) will give + your plugin some friendly default behavior: + + * A --with-$name option will be added to the command line interface + to enable the plugin, and a corresponding environment variable + will be used as the default value. The plugin class's docstring + will be used as the help for this option. + * The plugin will not be enabled unless this option is selected by + the user. + """ + can_configure = False + enabled = False + enableOpt = None + name = None + score = 100 + + def __init__(self): + if self.name is None: + self.name = self.__class__.__name__.lower() + if self.enableOpt is None: + self.enableOpt = "enable_plugin_%s" % self.name.replace('-', '_') + + def addOptions(self, parser, env=None): + """Add command-line options for this plugin. + + The base plugin class adds --with-$name by default, used to enable the + plugin. + + .. warning :: Don't implement addOptions unless you want to override + all default option handling behavior, including + warnings for conflicting options. Implement + :meth:`options + ` + instead. + """ + self.add_options(parser, env) + + def add_options(self, parser, env=None): + """Non-camel-case version of func name for backwards compatibility. + + .. warning :: + + DEPRECATED: Do not use this method, + use :meth:`options ` + instead. + + """ + # FIXME raise deprecation warning if wasn't called by wrapper + if env is None: + env = os.environ + try: + self.options(parser, env) + self.can_configure = True + except OptionConflictError, e: + warn("Plugin %s has conflicting option string: %s and will " + "be disabled" % (self, e), RuntimeWarning) + self.enabled = False + self.can_configure = False + + def options(self, parser, env): + """Register commandline options. + + Implement this method for normal options behavior with protection from + OptionConflictErrors. If you override this method and want the default + --with-$name option to be registered, be sure to call super(). + """ + env_opt = 'NOSE_WITH_%s' % self.name.upper() + env_opt = env_opt.replace('-', '_') + parser.add_option("--with-%s" % self.name, + action="store_true", + dest=self.enableOpt, + default=env.get(env_opt), + help="Enable plugin %s: %s [%s]" % + (self.__class__.__name__, self.help(), env_opt)) + + def configure(self, options, conf): + """Configure the plugin and system, based on selected options. + + The base plugin class sets the plugin to enabled if the enable option + for the plugin (self.enableOpt) is true. + """ + if not self.can_configure: + return + self.conf = conf + if hasattr(options, self.enableOpt): + self.enabled = getattr(options, self.enableOpt) + + def help(self): + """Return help for this plugin. This will be output as the help + section of the --with-$name option that enables the plugin. + """ + if self.__class__.__doc__: + # doc sections are often indented; compress the spaces + return textwrap.dedent(self.__class__.__doc__) + return "(no help available)" + + # Compatiblity shim + def tolist(self, val): + warn("Plugin.tolist is deprecated. Use nose.util.tolist instead", + DeprecationWarning) + return tolist(val) + + +class IPluginInterface(object): + """ + IPluginInterface describes the plugin API. Do not subclass or use this + class directly. + """ + def __new__(cls, *arg, **kw): + raise TypeError("IPluginInterface class is for documentation only") + + def addOptions(self, parser, env): + """Called to allow plugin to register command-line options with the + parser. DO NOT return a value from this method unless you want to stop + all other plugins from setting their options. + + .. warning :: + + DEPRECATED -- implement + :meth:`options ` instead. + """ + pass + add_options = addOptions + add_options.deprecated = True + + def addDeprecated(self, test): + """Called when a deprecated test is seen. DO NOT return a value + unless you want to stop other plugins from seeing the deprecated + test. + + .. warning :: DEPRECATED -- check error class in addError instead + """ + pass + addDeprecated.deprecated = True + + def addError(self, test, err): + """Called when a test raises an uncaught exception. DO NOT return a + value unless you want to stop other plugins from seeing that the + test has raised an error. + + :param test: the test case + :type test: :class:`nose.case.Test` + :param err: sys.exc_info() tuple + :type err: 3-tuple + """ + pass + addError.changed = True + + def addFailure(self, test, err): + """Called when a test fails. DO NOT return a value unless you + want to stop other plugins from seeing that the test has failed. + + :param test: the test case + :type test: :class:`nose.case.Test` + :param err: 3-tuple + :type err: sys.exc_info() tuple + """ + pass + addFailure.changed = True + + def addSkip(self, test): + """Called when a test is skipped. DO NOT return a value unless + you want to stop other plugins from seeing the skipped test. + + .. warning:: DEPRECATED -- check error class in addError instead + """ + pass + addSkip.deprecated = True + + def addSuccess(self, test): + """Called when a test passes. DO NOT return a value unless you + want to stop other plugins from seeing the passing test. + + :param test: the test case + :type test: :class:`nose.case.Test` + """ + pass + addSuccess.changed = True + + def afterContext(self): + """Called after a context (generally a module) has been + lazy-loaded, imported, setup, had its tests loaded and + executed, and torn down. + """ + pass + afterContext._new = True + + def afterDirectory(self, path): + """Called after all tests have been loaded from directory at path + and run. + + :param path: the directory that has finished processing + :type path: string + """ + pass + afterDirectory._new = True + + def afterImport(self, filename, module): + """Called after module is imported from filename. afterImport + is called even if the import failed. + + :param filename: The file that was loaded + :type filename: string + :param module: The name of the module + :type module: string + """ + pass + afterImport._new = True + + def afterTest(self, test): + """Called after the test has been run and the result recorded + (after stopTest). + + :param test: the test case + :type test: :class:`nose.case.Test` + """ + pass + afterTest._new = True + + def beforeContext(self): + """Called before a context (generally a module) is + examined. Because the context is not yet loaded, plugins don't + get to know what the context is; so any context operations + should use a stack that is pushed in `beforeContext` and popped + in `afterContext` to ensure they operate symmetrically. + + `beforeContext` and `afterContext` are mainly useful for tracking + and restoring global state around possible changes from within a + context, whatever the context may be. If you need to operate on + contexts themselves, see `startContext` and `stopContext`, which + are passed the context in question, but are called after + it has been loaded (imported in the module case). + """ + pass + beforeContext._new = True + + def beforeDirectory(self, path): + """Called before tests are loaded from directory at path. + + :param path: the directory that is about to be processed + """ + pass + beforeDirectory._new = True + + def beforeImport(self, filename, module): + """Called before module is imported from filename. + + :param filename: The file that will be loaded + :param module: The name of the module found in file + :type module: string + """ + beforeImport._new = True + + def beforeTest(self, test): + """Called before the test is run (before startTest). + + :param test: the test case + :type test: :class:`nose.case.Test` + """ + pass + beforeTest._new = True + + def begin(self): + """Called before any tests are collected or run. Use this to + perform any setup needed before testing begins. + """ + pass + + def configure(self, options, conf): + """Called after the command line has been parsed, with the + parsed options and the config container. Here, implement any + config storage or changes to state or operation that are set + by command line options. + + DO NOT return a value from this method unless you want to + stop all other plugins from being configured. + """ + pass + + def finalize(self, result): + """Called after all report output, including output from all + plugins, has been sent to the stream. Use this to print final + test results or perform final cleanup. Return None to allow + other plugins to continue printing, or any other value to stop + them. + + :param result: test result object + + .. Note:: When tests are run under a test runner other than + :class:`nose.core.TextTestRunner`, such as + via ``python setup.py test``, this method may be called + **before** the default report output is sent. + """ + pass + + def describeTest(self, test): + """Return a test description. + + Called by :meth:`nose.case.Test.shortDescription`. + + :param test: the test case + :type test: :class:`nose.case.Test` + """ + pass + describeTest._new = True + + def formatError(self, test, err): + """Called in result.addError, before plugin.addError. If you + want to replace or modify the error tuple, return a new error + tuple, otherwise return err, the original error tuple. + + :param test: the test case + :type test: :class:`nose.case.Test` + :param err: sys.exc_info() tuple + :type err: 3-tuple + """ + pass + formatError._new = True + formatError.chainable = True + # test arg is not chainable + formatError.static_args = (True, False) + + def formatFailure(self, test, err): + """Called in result.addFailure, before plugin.addFailure. If you + want to replace or modify the error tuple, return a new error + tuple, otherwise return err, the original error tuple. + + :param test: the test case + :type test: :class:`nose.case.Test` + :param err: sys.exc_info() tuple + :type err: 3-tuple + """ + pass + formatFailure._new = True + formatFailure.chainable = True + # test arg is not chainable + formatFailure.static_args = (True, False) + + def handleError(self, test, err): + """Called on addError. To handle the error yourself and prevent normal + error processing, return a true value. + + :param test: the test case + :type test: :class:`nose.case.Test` + :param err: sys.exc_info() tuple + :type err: 3-tuple + """ + pass + handleError._new = True + + def handleFailure(self, test, err): + """Called on addFailure. To handle the failure yourself and + prevent normal failure processing, return a true value. + + :param test: the test case + :type test: :class:`nose.case.Test` + :param err: sys.exc_info() tuple + :type err: 3-tuple + """ + pass + handleFailure._new = True + + def loadTestsFromDir(self, path): + """Return iterable of tests from a directory. May be a + generator. Each item returned must be a runnable + unittest.TestCase (or subclass) instance or suite instance. + Return None if your plugin cannot collect any tests from + directory. + + :param path: The path to the directory. + """ + pass + loadTestsFromDir.generative = True + loadTestsFromDir._new = True + + def loadTestsFromModule(self, module, path=None): + """Return iterable of tests in a module. May be a + generator. Each item returned must be a runnable + unittest.TestCase (or subclass) instance. + Return None if your plugin cannot + collect any tests from module. + + :param module: The module object + :type module: python module + :param path: the path of the module to search, to distinguish from + namespace package modules + + .. note:: + + NEW. The ``path`` parameter will only be passed by nose 0.11 + or above. + """ + pass + loadTestsFromModule.generative = True + + def loadTestsFromName(self, name, module=None, importPath=None): + """Return tests in this file or module. Return None if you are not able + to load any tests, or an iterable if you are. May be a + generator. + + :param name: The test name. May be a file or module name plus a test + callable. Use split_test_name to split into parts. Or it might + be some crazy name of your own devising, in which case, do + whatever you want. + :param module: Module from which the name is to be loaded + :param importPath: Path from which file (must be a python module) was + found + + .. warning:: DEPRECATED: this argument will NOT be passed. + """ + pass + loadTestsFromName.generative = True + + def loadTestsFromNames(self, names, module=None): + """Return a tuple of (tests loaded, remaining names). Return + None if you are not able to load any tests. Multiple plugins + may implement loadTestsFromNames; the remaining name list from + each will be passed to the next as input. + + :param names: List of test names. + :type names: iterable + :param module: Module from which the names are to be loaded + """ + pass + loadTestsFromNames._new = True + loadTestsFromNames.chainable = True + + def loadTestsFromFile(self, filename): + """Return tests in this file. Return None if you are not + interested in loading any tests, or an iterable if you are and + can load some. May be a generator. *If you are interested in + loading tests from the file and encounter no errors, but find + no tests, yield False or return [False].* + + .. Note:: This method replaces loadTestsFromPath from the 0.9 + API. + + :param filename: The full path to the file or directory. + """ + pass + loadTestsFromFile.generative = True + loadTestsFromFile._new = True + + def loadTestsFromPath(self, path): + """ + .. warning:: DEPRECATED -- use loadTestsFromFile instead + """ + pass + loadTestsFromPath.deprecated = True + + def loadTestsFromTestCase(self, cls): + """Return tests in this test case class. Return None if you are + not able to load any tests, or an iterable if you are. May be a + generator. + + :param cls: The test case class. Must be subclass of + :class:`unittest.TestCase`. + """ + pass + loadTestsFromTestCase.generative = True + + def loadTestsFromTestClass(self, cls): + """Return tests in this test class. Class will *not* be a + unittest.TestCase subclass. Return None if you are not able to + load any tests, an iterable if you are. May be a generator. + + :param cls: The test case class. Must be **not** be subclass of + :class:`unittest.TestCase`. + """ + pass + loadTestsFromTestClass._new = True + loadTestsFromTestClass.generative = True + + def makeTest(self, obj, parent): + """Given an object and its parent, return or yield one or more + test cases. Each test must be a unittest.TestCase (or subclass) + instance. This is called before default test loading to allow + plugins to load an alternate test case or cases for an + object. May be a generator. + + :param obj: The object to be made into a test + :param parent: The parent of obj (eg, for a method, the class) + """ + pass + makeTest._new = True + makeTest.generative = True + + def options(self, parser, env): + """Called to allow plugin to register command line + options with the parser. + + DO NOT return a value from this method unless you want to stop + all other plugins from setting their options. + + :param parser: options parser instance + :type parser: :class:`ConfigParser.ConfigParser` + :param env: environment, default is os.environ + """ + pass + options._new = True + + def prepareTest(self, test): + """Called before the test is run by the test runner. Please + note the article *the* in the previous sentence: prepareTest + is called *only once*, and is passed the test case or test + suite that the test runner will execute. It is *not* called + for each individual test case. If you return a non-None value, + that return value will be run as the test. Use this hook to + wrap or decorate the test with another function. If you need + to modify or wrap individual test cases, use `prepareTestCase` + instead. + + :param test: the test case + :type test: :class:`nose.case.Test` + """ + pass + + def prepareTestCase(self, test): + """Prepare or wrap an individual test case. Called before + execution of the test. The test passed here is a + nose.case.Test instance; the case to be executed is in the + test attribute of the passed case. To modify the test to be + run, you should return a callable that takes one argument (the + test result object) -- it is recommended that you *do not* + side-effect the nose.case.Test instance you have been passed. + + Keep in mind that when you replace the test callable you are + replacing the run() method of the test case -- including the + exception handling and result calls, etc. + + :param test: the test case + :type test: :class:`nose.case.Test` + """ + pass + prepareTestCase._new = True + + def prepareTestLoader(self, loader): + """Called before tests are loaded. To replace the test loader, + return a test loader. To allow other plugins to process the + test loader, return None. Only one plugin may replace the test + loader. Only valid when using nose.TestProgram. + + :param loader: :class:`nose.loader.TestLoader` + (or other loader) instance + """ + pass + prepareTestLoader._new = True + + def prepareTestResult(self, result): + """Called before the first test is run. To use a different + test result handler for all tests than the given result, + return a test result handler. NOTE however that this handler + will only be seen by tests, that is, inside of the result + proxy system. The TestRunner and TestProgram -- whether nose's + or other -- will continue to see the original result + handler. For this reason, it is usually better to monkeypatch + the result (for instance, if you want to handle some + exceptions in a unique way). Only one plugin may replace the + result, but many may monkeypatch it. If you want to + monkeypatch and stop other plugins from doing so, monkeypatch + and return the patched result. + + :param result: :class:`nose.result.TextTestResult` + (or other result) instance + """ + pass + prepareTestResult._new = True + + def prepareTestRunner(self, runner): + """Called before tests are run. To replace the test runner, + return a test runner. To allow other plugins to process the + test runner, return None. Only valid when using nose.TestProgram. + + :param runner: :class:`nose.core.TextTestRunner` + (or other runner) instance + """ + pass + prepareTestRunner._new = True + + def report(self, stream): + """Called after all error output has been printed. Print your + plugin's report to the provided stream. Return None to allow + other plugins to print reports, any other value to stop them. + + :param stream: stream object; send your output here + :type stream: file-like object + """ + pass + + def setOutputStream(self, stream): + """Called before test output begins. To direct test output to a + new stream, return a stream object, which must implement a + `write(msg)` method. If you only want to note the stream, not + capture or redirect it, then return None. + + :param stream: stream object; send your output here + :type stream: file-like object + """ + + def startContext(self, context): + """Called before context setup and the running of tests in the + context. Note that tests have already been *loaded* from the + context before this call. + + :param context: the context about to be setup. May be a module or + class, or any other object that contains tests. + """ + pass + startContext._new = True + + def startTest(self, test): + """Called before each test is run. DO NOT return a value unless + you want to stop other plugins from seeing the test start. + + :param test: the test case + :type test: :class:`nose.case.Test` + """ + pass + + def stopContext(self, context): + """Called after the tests in a context have run and the + context has been torn down. + + :param context: the context that has been torn down. May be a module or + class, or any other object that contains tests. + """ + pass + stopContext._new = True + + def stopTest(self, test): + """Called after each test is run. DO NOT return a value unless + you want to stop other plugins from seeing that the test has stopped. + + :param test: the test case + :type test: :class:`nose.case.Test` + """ + pass + + def testName(self, test): + """Return a short test name. Called by `nose.case.Test.__str__`. + + :param test: the test case + :type test: :class:`nose.case.Test` + """ + pass + testName._new = True + + def wantClass(self, cls): + """Return true if you want the main test selector to collect + tests from this class, false if you don't, and None if you don't + care. + + :param cls: The class being examined by the selector + """ + pass + + def wantDirectory(self, dirname): + """Return true if you want test collection to descend into this + directory, false if you do not, and None if you don't care. + + :param dirname: Full path to directory being examined by the selector + """ + pass + + def wantFile(self, file): + """Return true if you want to collect tests from this file, + false if you do not and None if you don't care. + + Change from 0.9: The optional package parameter is no longer passed. + + :param file: Full path to file being examined by the selector + """ + pass + + def wantFunction(self, function): + """Return true to collect this function as a test, false to + prevent it from being collected, and None if you don't care. + + :param function: The function object being examined by the selector + """ + pass + + def wantMethod(self, method): + """Return true to collect this method as a test, false to + prevent it from being collected, and None if you don't care. + + :param method: The method object being examined by the selector + :type method: unbound method + """ + pass + + def wantModule(self, module): + """Return true if you want to collection to descend into this + module, false to prevent the collector from descending into the + module, and None if you don't care. + + :param module: The module object being examined by the selector + :type module: python module + """ + pass + + def wantModuleTests(self, module): + """ + .. warning:: DEPRECATED -- this method will not be called, it has + been folded into wantModule. + """ + pass + wantModuleTests.deprecated = True + diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/base.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/base.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5059097981ee9e55062a4eea52297521276bdc30 GIT binary patch literal 33513 zcmeHQOKcqHeIJSxCF)^GmMuGW9FLPIA{lb!M;ynrlgQR1QDal;ijEVd$#S?mBv;x8 zJu@qcZUQv5Q=|pjqL(6vwm=U(^w1VXdTM*jA%~!sppQe*LoNk^0&UStQJ`plzu*6x zZ)SH%t^8WUMr7}B_M30M*Z=+azMcH9qldox@XfE*1NUzdf6w8Q-o~YY|0jZ05M1~7 z6T$TfmG28$`-1jlaD6hEV7o1i9MXc z!|f>P*tcoc@3xw0mhtv#tGChY`04FK(Tn(`ui+A7Vw%kLeL;+wOzFBmXv}cbydLCm zIMjU{;dP7-_mjb!C_JqDDcv6lFhf>2>SlQT9?p&>$AX4tcl~%!y*7J@UH=}|_{AuV z!+I-9({R0;gq<$FZfU4#CA^%SNy8+rciZi_(})}4S}#MDES&Ge^*BwVWM@9ix`#si zOM7e9Ot#rfU5i;atS51l#bM+cT~HHItCe>W&bNDMHXkqT1GVGd4BOETd�^C*0iG+KfACID2OC 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 aO|Mz2d#8QJ>oa7Z^`^WgJx9H1lKukl7394D literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/capture.py b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/capture.py new file mode 100644 index 0000000..fa4e5dc --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/capture.py @@ -0,0 +1,115 @@ +""" +This plugin captures stdout during test execution. If the test fails +or raises an error, the captured output will be appended to the error +or failure output. It is enabled by default but can be disabled with +the options ``-s`` or ``--nocapture``. + +:Options: + ``--nocapture`` + Don't capture stdout (any stdout output will be printed immediately) + +""" +import logging +import os +import sys +from nose.plugins.base import Plugin +from nose.pyversion import exc_to_unicode, force_unicode +from nose.util import ln +from StringIO import StringIO + + +log = logging.getLogger(__name__) + +class Capture(Plugin): + """ + Output capture plugin. Enabled by default. Disable with ``-s`` or + ``--nocapture``. This plugin captures stdout during test execution, + appending any output captured to the error or failure output, + should the test fail or raise an error. + """ + enabled = True + env_opt = 'NOSE_NOCAPTURE' + name = 'capture' + score = 1600 + + def __init__(self): + self.stdout = [] + self._buf = None + + def options(self, parser, env): + """Register commandline options + """ + parser.add_option( + "-s", "--nocapture", action="store_false", + default=not env.get(self.env_opt), dest="capture", + help="Don't capture stdout (any stdout output " + "will be printed immediately) [NOSE_NOCAPTURE]") + + def configure(self, options, conf): + """Configure plugin. Plugin is enabled by default. + """ + self.conf = conf + if not options.capture: + self.enabled = False + + def afterTest(self, test): + """Clear capture buffer. + """ + self.end() + self._buf = None + + def begin(self): + """Replace sys.stdout with capture buffer. + """ + self.start() # get an early handle on sys.stdout + + def beforeTest(self, test): + """Flush capture buffer. + """ + self.start() + + def formatError(self, test, err): + """Add captured output to error report. + """ + test.capturedOutput = output = self.buffer + self._buf = None + if not output: + # Don't return None as that will prevent other + # formatters from formatting and remove earlier formatters + # formats, instead return the err we got + return err + ec, ev, tb = err + return (ec, self.addCaptureToErr(ev, output), tb) + + def formatFailure(self, test, err): + """Add captured output to failure report. + """ + return self.formatError(test, err) + + def addCaptureToErr(self, ev, output): + ev = exc_to_unicode(ev) + output = force_unicode(output) + return u'\n'.join([ev, ln(u'>> begin captured stdout <<'), + output, ln(u'>> end captured stdout <<')]) + + def start(self): + self.stdout.append(sys.stdout) + self._buf = StringIO() + sys.stdout = self._buf + + def end(self): + if self.stdout: + sys.stdout = self.stdout.pop() + + def finalize(self, result): + """Restore stdout. + """ + while self.stdout: + self.end() + + def _get_buffer(self): + if self._buf is not None: + return self._buf.getvalue() + + buffer = property(_get_buffer, None, None, + """Captured stdout output.""") diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/capture.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/capture.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dabfd255b22894fd2508a9653302222fa7974691 GIT binary patch literal 5532 zcmcgwdvD{$5g&?@Y{~Z7_eieSqzRixqc*XWN6~8o_mIT73xX7OK>ON6X+cxuO5%kg zRqpC?D(pWB_e=C!^t<%~w7;1pCD}<@6li35N5kFa?(EEO9xL~sJMF)|@b&K_D*s%3 ze}Ja{4iXdfK^=-~lseQ0WBD5OYZdQO-xc1av`&)-^&8~yygH>#nru*igC?8Q-?Y6A zN?SB(Q@?GWo0M+RWQ+P+qa^d9aB60S(w;VPJ~LiCE0S#F8KsSCaG@c zg;#`$#+za0siMe>w`5AWVC-SFDHi-DNmFm2yl^^IS*&8up&P zDhmfGW)J3GtcKw%HQoTLMc53B#fi4V-y~+-X36p?3#z@dvweMb=3!lM`&nL!b9UBk zx8FauliqK8*GJLgc^~K58@z>Rq*6#H%;pt;?MPFo%0R|sGEs378kNp}-fk!V!rxH` ziYC(p`CJs;sqym-5cMnyOdia#B+6rDcF;Aze$&M>fa^* zq;s1kcNmy#gkuYv$_f^yUGL$y@X+->wkQC^%y?;dS>?L%z5f~WZ^=3qwd@fLgVO$` zY*(Sokh=2Q6TY$8H5^OM&NVQ;Q%F2v_5X?cs|NAB}_1w4K2*LTdQ=~!8Zxf zUx4d9)~e9GQK3e8F%OF#EU6_p)58{dc>-+-JW(p8ZaD2{>a2A$XF ziNi;KQsW4?4HyH!2z~(VWv%W2vL_v0M!yc?t5KqjD!eG4Ou{TqlWY+=!~hIH&5GUE zn%`Q9Afmu9;wWQeL6a9M7>21c@Ecf5aE>tE>3p&3L7@~es@B#KF20M>M-=gSP_=6 zrsJUcXkp$mA1#&W-^IB9Ban6JjuSYGCntOx51P{pxh-}X)>+lWWmr7+3n>D)xG2Md z1Bc*=P$U$Vsu12#W;{fKp(<9@!Z0c!68pTr&p4C!Es{iUK>Ip%5DwwOr`Ys9WU)cR zZ99v&$gxp0z{&QC2Fio8>U=d#!$^60uDfOBBU$A8Rl&;|#)LLuVI*RT3f6UU-gW7>TB>s}+STX^Ra6JCt;h{dy{2X0R@caI%0sCZU0>dGQGz^)?8(dx$yBdL40l zk*wKBVw^oN);O>YOaMLGN<{ZC@;w@^N~h~OwvP4-ytop28I}I)+=sRfXqH7f6!FO3 zR!*_+DmwY_9F0W*?4braaJVG7aL8CSfR`H}N)-&j)~Lua0UBZ+cywq~XL=&(=xD|c z*`B=s`rrX>JuBC>xVn)X9L(<7aa^vJ$Sp(K!GWygi)S;CB*i_+lgwvE zXlu}@{~EUW63tcs&Ne=`mNA@V6;(1~ES8Y_fqqVB4mnWRr3?g>OJmGdzg5x8uIX=r z*uqV2pW6`Eg`>OfGz` zmiP9gY}9E!^}G09dxr8~#I6u)rH<$GaO1OyIXMkIyIURYo-ptd%=oiQe?XB^rf4p! zd?W$nf)eSgQJ0sL1Iw1nY$cY)ZyETpU`^JPJIpZ2!Zi7d8bhqI9QiJrdKk7gg_6E* zQSoABS%d*t^SVVj9ZL3)O;F4~4bz!gyIJM36JUG3D55+B_9_eSI-0A@GNCPEl1*IQ zqYhiKyya!#L?IFG>B!Jig0<^LFre+NXm_(fZGMF4}(*~eDi z92R}XlkYM4DHBc;{+mo*W5TW`5b@t(?mZ9@XIkV_Tz%#?H?yxT;Ue4*dhhi)GO^w? z@6~KJo$^y_)myFBMyuIs;Io6qTphH&?Q}S+`o97Zt)=-0>0l)FK(58%%}osQ1-x6{ zwY!5*D<7TqcPBeEe~QaI?yxI4f$Mr1#BY76BnF9(hWlan-(f3N_`l?JIKW_QIl?-1 dCT2UZxOu?QTHgX`O4`_V_MGR@_T1gtzX76m7d!v} literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/collect.py b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/collect.py new file mode 100644 index 0000000..6f9f0fa --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/collect.py @@ -0,0 +1,94 @@ +""" +This plugin bypasses the actual execution of tests, and instead just collects +test names. Fixtures are also bypassed, so running nosetests with the +collection plugin enabled should be very quick. + +This plugin is useful in combination with the testid plugin (``--with-id``). +Run both together to get an indexed list of all tests, which will enable you to +run individual tests by index number. + +This plugin is also useful for counting tests in a test suite, and making +people watching your demo think all of your tests pass. +""" +from nose.plugins.base import Plugin +from nose.case import Test +import logging +import unittest + +log = logging.getLogger(__name__) + + +class CollectOnly(Plugin): + """ + Collect and output test names only, don't run any tests. + """ + name = "collect-only" + enableOpt = 'collect_only' + + def options(self, parser, env): + """Register commandline options. + """ + parser.add_option('--collect-only', + action='store_true', + dest=self.enableOpt, + default=env.get('NOSE_COLLECT_ONLY'), + help="Enable collect-only: %s [COLLECT_ONLY]" % + (self.help())) + + def prepareTestLoader(self, loader): + """Install collect-only suite class in TestLoader. + """ + # Disable context awareness + log.debug("Preparing test loader") + loader.suiteClass = TestSuiteFactory(self.conf) + + def prepareTestCase(self, test): + """Replace actual test with dummy that always passes. + """ + # Return something that always passes + log.debug("Preparing test case %s", test) + if not isinstance(test, Test): + return + def run(result): + # We need to make these plugin calls because there won't be + # a result proxy, due to using a stripped-down test suite + self.conf.plugins.startTest(test) + result.startTest(test) + self.conf.plugins.addSuccess(test) + result.addSuccess(test) + self.conf.plugins.stopTest(test) + result.stopTest(test) + return run + + +class TestSuiteFactory: + """ + Factory for producing configured test suites. + """ + def __init__(self, conf): + self.conf = conf + + def __call__(self, tests=(), **kw): + return TestSuite(tests, conf=self.conf) + + +class TestSuite(unittest.TestSuite): + """ + Basic test suite that bypasses most proxy and plugin calls, but does + wrap tests in a nose.case.Test so prepareTestCase will be called. + """ + def __init__(self, tests=(), conf=None): + self.conf = conf + # Exec lazy suites: makes discovery depth-first + if callable(tests): + tests = tests() + log.debug("TestSuite(%r)", tests) + unittest.TestSuite.__init__(self, tests) + + def addTest(self, test): + log.debug("Add test %s", test) + if isinstance(test, unittest.TestSuite): + self._tests.append(test) + else: + self._tests.append(Test(test, config=self.conf)) + diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/collect.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/collect.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2fb64755d283bd246857feb4ee412fd186f7040a GIT binary patch literal 4806 zcmcgwTW=f38J#65N}{FOv0L|{mrNSCp%IfpFM)eQn_6|+q5@^CoT5=tte3kZa;4?& zc4yWy0r#Ph(d51Tr~Lu#Ip6SR=UF1Kqq)y~=R4nJ)c)^&@1Nhf_;aEbzc&7UiqHNV zMXJ;(%0Q(pl?Q6pQl~8yu-#U9Tg^J^wBy?ym2aujEt!jYSDkj1*;41*%Iv7CK%MTY zbW53*I>X|wdZW~pQeT|*RJyIwTPodIb)m7VOjn)n$=u#*U{9qTb<*GC<@Q@j^`1{N ztE;@3WQ88jtJqp&wVN6pC$5QeZC;tAaamdD@=QBpoqeR^BGp-8orzO@-dLxTGS5xo zY>yLk5zmYr>d&%QuBowGTw}M~mdpLqM;eW~DT=I^=%Tbn_SKh}o66C>#eO_>aWzxK zV+N8{a(6gW@A%-T?RpHA;?)-Lz1R&1kA68Y_U|eZ8B%PQfBc5X7nmk zR=Lrau}h|0fqT?CHM0`vX2peE8h4j&zZ>;F>}CJMuOEOLu8ZQCu)?=HXg>#RBX4~&t*^W*-uaya2^~**&>@y+ay0|4$6bIqqXFl-jgE*N35}GW2!y}(Hz-~Q z>U?RexGb*uTB&o0vZY?P)H$T-(h_NKJ2KR!4c@;BIsq*1q~GI4KSU9l2`B>YfPpg@ zOr8}+mlcT!q$wYN_8XWw7`$~+q5$K=L?^qsvNn;c8{?>i6iRU0QaOv8+`0EqA03}O zjSi2Gj-DPqkB&!2U&z#{$t$_bQ!yUgM66Wc_=SF8^6 zmG+>TyJ=Yru;yTBCKG!=r!e@@@F&B^gKGZc;bZnn=YjVJ_Fy5*5KD>10@?4PDymoQ zy`UTH2DgKDkigHW<#)&#AEIzxuL0E=xYkmc0VxoHsV!)e655}k_#?a>O??wWZ+JS% zVLNm+G>@Y)PHD_uyU_2qu=p8-jO(T8>RjfG`dhpNPsq!OV^lWEG|vD9hw&q<_wd;i#aAGTa0S-SD}yfd39H6>yuCTT zYOKdQo8zkn&NvY#>nRa_6K4vi7gQG$1pR79n3wi>(j_B+V_I}z<;8`kjx41q7Y#+%UmKZ5)%@8F*@ON_&v`1 zKKt;gwKOtty+Yi^fg9vL1VaYsvh>KRa|eE<6WrbH6Ma!Z6frDCkw_FpvodXRHtCz9 zC@mAzsRPam8F50|dH8J>8ikh-l^bxFA?Z!WB|+f@LC!paZO8OWuwbFu6&-#lp&Va&yewF zNbU1o^p4l@4+^|@xSL6RAY0|Gl;-q$DIwJ?05U^`p)%E9;{!k?Gdb@Noca^7V2_wj z1d8|9UGViZbDv4_y&f=C5J0J>k)_-JZMyJ#53B@g?+*LSr`I@!@3Z+a3o=$FM#R*w ziL1&KsRYZl2U$nV8-i9s8y*Uz2*I;dz5=#)gL^Hx!$=-<@AwFbf}^r9-dP-A&HBPp zyIw*NQ1Q%NRJxsRaC^s}Pr8d2lNS{qAj3rhHXOq~Lkuf%(=tSp6%7as$l&q+lZmKI z=HQKVgg#Sy=_TQzRf(?>rQW2_lA-*{=On+DfBi7|=t5U_U=4e%+wJ=w-@EmHCk=sf literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/cover.py b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/cover.py new file mode 100644 index 0000000..fbe2e30 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/cover.py @@ -0,0 +1,271 @@ +"""If you have Ned Batchelder's coverage_ module installed, you may activate a +coverage report with the ``--with-coverage`` switch or NOSE_WITH_COVERAGE +environment variable. The coverage report will cover any python source module +imported after the start of the test run, excluding modules that match +testMatch. If you want to include those modules too, use the ``--cover-tests`` +switch, or set the NOSE_COVER_TESTS environment variable to a true value. To +restrict the coverage report to modules from a particular package or packages, +use the ``--cover-package`` switch or the NOSE_COVER_PACKAGE environment +variable. + +.. _coverage: http://www.nedbatchelder.com/code/modules/coverage.html +""" +import logging +import re +import sys +import StringIO +from nose.plugins.base import Plugin +from nose.util import src, tolist + +log = logging.getLogger(__name__) + + +class Coverage(Plugin): + """ + Activate a coverage report using Ned Batchelder's coverage module. + """ + coverTests = False + coverPackages = None + coverInstance = None + coverErase = False + coverMinPercentage = None + score = 200 + status = {} + + def options(self, parser, env): + """ + Add options to command line. + """ + super(Coverage, self).options(parser, env) + parser.add_option("--cover-package", action="append", + default=env.get('NOSE_COVER_PACKAGE'), + metavar="PACKAGE", + dest="cover_packages", + help="Restrict coverage output to selected packages " + "[NOSE_COVER_PACKAGE]") + parser.add_option("--cover-erase", action="store_true", + default=env.get('NOSE_COVER_ERASE'), + dest="cover_erase", + help="Erase previously collected coverage " + "statistics before run") + parser.add_option("--cover-tests", action="store_true", + dest="cover_tests", + default=env.get('NOSE_COVER_TESTS'), + help="Include test modules in coverage report " + "[NOSE_COVER_TESTS]") + parser.add_option("--cover-min-percentage", action="store", + dest="cover_min_percentage", + default=env.get('NOSE_COVER_MIN_PERCENTAGE'), + help="Minimum percentage of coverage for tests " + "to pass [NOSE_COVER_MIN_PERCENTAGE]") + parser.add_option("--cover-inclusive", action="store_true", + dest="cover_inclusive", + default=env.get('NOSE_COVER_INCLUSIVE'), + help="Include all python files under working " + "directory in coverage report. Useful for " + "discovering holes in test coverage if not all " + "files are imported by the test suite. " + "[NOSE_COVER_INCLUSIVE]") + parser.add_option("--cover-html", action="store_true", + default=env.get('NOSE_COVER_HTML'), + dest='cover_html', + help="Produce HTML coverage information") + parser.add_option('--cover-html-dir', action='store', + default=env.get('NOSE_COVER_HTML_DIR', 'cover'), + dest='cover_html_dir', + metavar='DIR', + help='Produce HTML coverage information in dir') + parser.add_option("--cover-branches", action="store_true", + default=env.get('NOSE_COVER_BRANCHES'), + dest="cover_branches", + help="Include branch coverage in coverage report " + "[NOSE_COVER_BRANCHES]") + parser.add_option("--cover-xml", action="store_true", + default=env.get('NOSE_COVER_XML'), + dest="cover_xml", + help="Produce XML coverage information") + parser.add_option("--cover-xml-file", action="store", + default=env.get('NOSE_COVER_XML_FILE', 'coverage.xml'), + dest="cover_xml_file", + metavar="FILE", + help="Produce XML coverage information in file") + + def configure(self, options, conf): + """ + Configure plugin. + """ + try: + self.status.pop('active') + except KeyError: + pass + super(Coverage, self).configure(options, conf) + if self.enabled: + try: + import coverage + if not hasattr(coverage, 'coverage'): + raise ImportError("Unable to import coverage module") + except ImportError: + log.error("Coverage not available: " + "unable to import coverage module") + self.enabled = False + return + self.conf = conf + self.coverErase = options.cover_erase + self.coverTests = options.cover_tests + self.coverPackages = [] + if options.cover_packages: + if isinstance(options.cover_packages, (list, tuple)): + cover_packages = options.cover_packages + else: + cover_packages = [options.cover_packages] + for pkgs in [tolist(x) for x in cover_packages]: + self.coverPackages.extend(pkgs) + self.coverInclusive = options.cover_inclusive + if self.coverPackages: + log.info("Coverage report will include only packages: %s", + self.coverPackages) + self.coverHtmlDir = None + if options.cover_html: + self.coverHtmlDir = options.cover_html_dir + log.debug('Will put HTML coverage report in %s', self.coverHtmlDir) + self.coverBranches = options.cover_branches + self.coverXmlFile = None + if options.cover_min_percentage: + self.coverMinPercentage = int(options.cover_min_percentage.rstrip('%')) + if options.cover_xml: + self.coverXmlFile = options.cover_xml_file + log.debug('Will put XML coverage report in %s', self.coverXmlFile) + if self.enabled: + self.status['active'] = True + self.coverInstance = coverage.coverage(auto_data=False, + branch=self.coverBranches, data_suffix=conf.worker, + source=self.coverPackages) + self.coverInstance._warn_no_data = False + self.coverInstance.is_worker = conf.worker + self.coverInstance.exclude('#pragma[: ]+[nN][oO] [cC][oO][vV][eE][rR]') + + log.debug("Coverage begin") + self.skipModules = sys.modules.keys()[:] + if self.coverErase: + log.debug("Clearing previously collected coverage statistics") + self.coverInstance.combine() + self.coverInstance.erase() + + if not self.coverInstance.is_worker: + self.coverInstance.load() + self.coverInstance.start() + + + def beforeTest(self, *args, **kwargs): + """ + Begin recording coverage information. + """ + + if self.coverInstance.is_worker: + self.coverInstance.load() + self.coverInstance.start() + + def afterTest(self, *args, **kwargs): + """ + Stop recording coverage information. + """ + + if self.coverInstance.is_worker: + self.coverInstance.stop() + self.coverInstance.save() + + + def report(self, stream): + """ + Output code coverage report. + """ + log.debug("Coverage report") + self.coverInstance.stop() + self.coverInstance.combine() + self.coverInstance.save() + modules = [module + for name, module in sys.modules.items() + if self.wantModuleCoverage(name, module)] + log.debug("Coverage report will cover modules: %s", modules) + self.coverInstance.report(modules, file=stream) + + import coverage + if self.coverHtmlDir: + log.debug("Generating HTML coverage report") + try: + self.coverInstance.html_report(modules, self.coverHtmlDir) + except coverage.misc.CoverageException, e: + log.warning("Failed to generate HTML report: %s" % str(e)) + + if self.coverXmlFile: + log.debug("Generating XML coverage report") + try: + self.coverInstance.xml_report(modules, self.coverXmlFile) + except coverage.misc.CoverageException, e: + log.warning("Failed to generate XML report: %s" % str(e)) + + # make sure we have minimum required coverage + if self.coverMinPercentage: + f = StringIO.StringIO() + self.coverInstance.report(modules, file=f) + + multiPackageRe = (r'-------\s\w+\s+\d+\s+\d+(?:\s+\d+\s+\d+)?' + r'\s+(\d+)%\s+\d*\s{0,1}$') + singlePackageRe = (r'-------\s[\w./]+\s+\d+\s+\d+(?:\s+\d+\s+\d+)?' + r'\s+(\d+)%(?:\s+[-\d, ]+)\s{0,1}$') + + m = re.search(multiPackageRe, f.getvalue()) + if m is None: + m = re.search(singlePackageRe, f.getvalue()) + + if m: + percentage = int(m.groups()[0]) + if percentage < self.coverMinPercentage: + log.error('TOTAL Coverage did not reach minimum ' + 'required: %d%%' % self.coverMinPercentage) + sys.exit(1) + else: + log.error("No total percentage was found in coverage output, " + "something went wrong.") + + + def wantModuleCoverage(self, name, module): + if not hasattr(module, '__file__'): + log.debug("no coverage of %s: no __file__", name) + return False + module_file = src(module.__file__) + if not module_file or not module_file.endswith('.py'): + log.debug("no coverage of %s: not a python file", name) + return False + if self.coverPackages: + for package in self.coverPackages: + if (re.findall(r'^%s\b' % re.escape(package), name) + and (self.coverTests + or not self.conf.testMatch.search(name))): + log.debug("coverage for %s", name) + return True + if name in self.skipModules: + log.debug("no coverage for %s: loaded before coverage start", + name) + return False + if self.conf.testMatch.search(name) and not self.coverTests: + log.debug("no coverage for %s: is a test", name) + return False + # accept any package that passed the previous tests, unless + # coverPackages is on -- in that case, if we wanted this + # module, we would have already returned True + return not self.coverPackages + + def wantFile(self, file, package=None): + """If inclusive coverage enabled, return true for all source files + in wanted packages. + """ + if self.coverInclusive: + if file.endswith(".py"): + if package and self.coverPackages: + for want in self.coverPackages: + if package.startswith(want): + return True + else: + return True + return None diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/cover.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/cover.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0d5ef920cd641cd79a59783edd2220508045ad5e GIT binary patch literal 9900 zcmcgyU2_}9a-9YE1&|c=Nn6&nw7wE;$Ra_@_O%nnxwb@67GsH07PO?0qM;>r0WJva zf;$U-Bx0%(-z1e^k*ZYXRvuHSyyXw%E%^({Q=XGor;>Aec7dg2Ra~iDk;GtTwtKp# zXQum1FN^;@jIR$f1vF~wC~4m%dgwr$m@4} zI|y~+b~?T{FI-*s$aWh^u2uy^f)>5r#549n)#M z;gQ`tN_L{q)=@uh_^H>zp8cm?8L&or1GO%%imz}@=BKni&rjJt9CupY{}k9lHStd;=#c| zHT1ph!LF+|qV8fN^8CeAWi-qttnMV;PC58*{H#?h?B8Sz#iLHY6@(S+WR>uo>9`^N zNz@5+l1!j$IUS&Zy8Mv%Ha_|fQTRBII3Xwt%E!6GS;Ju(lX6^oCZt~C8QdtV0F;wF zL^x4AV@0XpSdB>K6i*!=&7`MpXq__$Lh5pegv7!e<#DZDG<0{w(zZo}i%G1@!{;0_zrP?abd`LYN93 zv|))+dJ=dK%m9j0{j&1tUPdz>SO8v2rl0bh5*|>)0-!#P=14{j6BuedKAV$sPIy3l zK2Lo?sAom=TRG~tGwO?Z>UVNuU&>McETeumPklL~9?bQM&_OX<^nNc-{qszd0rgeo zU8C)2mN_xe`@;4C*apU_ydva!Cgek*zL6I){|fa&MqL%^#XR*#uc&lWc^_vgeIhD- zDr~<1+o>isqj;og zg5*4EW}+ae=SVK%LC!1>R@dr}R-EOPwRL!Y@nsK!FzEKX_K=BTcAyw$Z_DJk+j_3n zC)VfWcw72RPFV@EI@tFU?na~Cu#Xz&6kAP1?Z9?gl5q3wcQT^ zbnJsD-lc=}f*1=I#YYI}LyZlXsoM6p+HdwdHfP`kS`;AHPQ;PG!D$WIf~FltiA|A4 zmWyQ{Ad&4O3HZXI`$2*zo?okh`dgYFJXee|KuDxUmCrBXVsCtArf+@ld|e$Vx$3)uKX0aG!>Xmh~JLg z5U^9fEdI80Yi;@7N-ZZeBh_C)ShldHGe6B?Jq4qA^Jc?tX`blJ28S>%T~BWMPhr~< zx{Pf>pl!4=)8gq+Oz;}Zf@y&p;N_`-xqf%`{)#NHjE^H&&2$(DtP3yQpAhFQ{5tV8 zFuB$$JkaJ;_i-E@E|YlN)ZxpvaXqhY+Omvr0~Mj8NI27`ICtPh?VEK5B&8Bc3jG+h zMI4M+FScU8g|p+v4L5cdX?4A5;P?V~7OQ@%r58g0V3hQ5lAeu_ekT(r(wGu9Y>#|x&$?=kef@;#b92L~y@k@5~W2TuejF=la< zm+{erO-JX6lG^wK`mq>#HOuhkJE zH$VceZsY10)D!B3;42^peW0+n48;0VONB~3+50tQltji~QwA2O4XimP8YEMcR0kL< zs@hYK18=consVExq&_3{(^5a9TA%^JS?N5d;=2|cJBiP!rO8`S@l=78>(YN!rDDn==ITIUqvy%iOW&g3|f7}Fmq6c;BWv0_kD9YlS^0T(ZpeX8}b6rh;IVm&}*ib zyx-#K%dm@t&3!lMkZB1q`hQ`r=9ven2gF@L2e_6;Az)dC2bb(QEmM0EfP|>=WQ0ry zfDfJ1xGgC)r+HZN|=)J_YK5nYMjgeDzIsb$sMV07ZT( z3a!xIMh$4%*W&qmhyoMn|HeOBiQ_1CuAyOKh6#b`29OBi%c6MBJO`rx+;O#=B(cnO zRq`z|h>YBcS`vkP4lA|0ZU>N?A*O+SYt{5Vb>eGVEIiHqZ%CyKJmSCTXD^ z#&4kta76~p4jX1zx%^A`>-RdogUhd(uYZ`}mf~Dso7R-k1Vsq4q(%(nqS{&%`Z%{K z(LI2jJ3;KcjSlA$3Ym!KZ}(fyWi|)O-Oj+wfcI&)a~A>GA-EEY1YsiPkD0aU$wf&t z0eF5iz~hb$a)+Bw)LG}Xgu9Ax6~TBQZ#A1Zd+G;n9M;2h6LR4KT~9fbB7+W^NmSrY4y!&3pU672oE;#|^I$#geL&ox>Df4uTHd^IC=L92JTD}UXo%;#bZ{=YT)FNfsfD#_)6e5h&bSry)kP9 zcog8bJtL^OU|GPU!Y*moRz9BQ%6cV6Ct-|1ZGLQJsWZ;;&AEG-0kA}WT@`%eB&NEN-``n=? z`|#!n*i8Idmfa$3lQYMgt-+c43OK*^L*(KTqMskbaf03M0!tzz2>97D)M-}4C?J54 z5j;24kAOT$s{F`EB+U)<6$V-`KhN~DgB#EEjb~n3R=!-yH?Mz*Rs~P5&q?=(&-5RC zG=KB>ntqTUWb@fUb#dz_4rD}ZEJebCtn+q7d^w%iXA{Y@b0Q1Sc0~c?VA|%ofeugV=60-An5r<6g z4p--Z@A3}tQm<95(Ao}@r_MbV5}RDsc-42dS*)}87KNY-B*?m2U=m-s8Ca6dL1LC! z0fRNDsX!RXPnjpOb-Kvf;j9j~+sa|Xm)y6&AR;GdYM@aPJHN+qh)R)^siy+CGJ=w8 z0B&Jx^&wIMI86qaX~6Ktjyy&hMPAN1ck$TyhFpwmtvKrUw8IpxXyhLTNri6Ogkh2Z z5&CXdo`x=r$36ql#2f~3b47f)oiqi;c9CumQc&!e1Sww`b^Ku;S-LWvVP^J?#3=_6 zMEyNJng&%Pgh%`>0)$<*PFu5pN(4mBQYbs11>P%jda%@)QAV?{tR>r!D15Nrn2 zlh(O{q;44A1|e<%bA-FX9h^xUWLR*g$Ne5ndD%s0j>WCPw!EfG9)m%wsHXHPzmT#) zT!QPHinlUO(8^fCN%uLf;(u0$O>w2;2!~H4)J-S^LbygOzVYrDW!7-UJ)xac`XAB& zhd9Q3jie-|@HkZxiIh~-jH>PRRGLGf(9>!c>7@V2C=p0bDmBH}I2bdYlUO^6dCXbq z;0P!uS;o~=t-|}knrzs*BpT~=&9fQuMNs-C0m=J0y#yy=4@in2L55CWdmSm#-Y4?x zT%qsg^s{XV0E3~KNylaUqnCy;-Agv_7I53?89!Jp(LJzrnIexxwxIN$bB?-PD0nJ7k^4|bXkNs;b zo}iGVtGNU9*|(2EypcJ?CZ9_QX+q-7oWUjp{yRRJw=u=b3NAr2xZv=+gz^f?S$t2* z`5H&>6+Ro0Q^p$v7kwEYO@PZi3AeY&O*KH2Yyt%SzC4x6;f=I@XX~QiMI1Xha5x?D zO}fC^-c6)EpPK3>Q*$`0HNn){gP_$W!V3Pmg17VGo=me3^9a02KgOFE{xbx(4d1q; z|NB9lpa-BIv5Ao*_g*lEN;oy_=d}ubt#gOPAG6?&5RYlLoa_===eu}du2oz;hl)Di zlbD90oHw$lvVAFyxrHKjwY*YMBPA>$7kI{+ER?Oaiew!opjo}nh*Gc1oa*&-L)K-# z*Xv%?sMj4iA+pmsNpmP9KL0M868?Ca@%k(FosZc!$AZ^v=Q)c83%Y!Vd(QcD6hmuB z?Kk<-fJ^xnKH|p4icJ3Jeha0g((O{IR4#p1x>Pwu{r(b#7ywBsT&r8+0Sx-UW+b$y zJJfzPeLqp%M(Tt2XyXOsQ9lVf#;Xtvh<8BzzmEa&(&aDEWjqjddvm6c-SLH4<6jbD Q$nF?J7&X5PyfelB0f-A)F8}}l literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/debug.py b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/debug.py new file mode 100644 index 0000000..78243e6 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/debug.py @@ -0,0 +1,67 @@ +""" +This plugin provides ``--pdb`` and ``--pdb-failures`` options. The ``--pdb`` +option will drop the test runner into pdb when it encounters an error. To +drop into pdb on failure, use ``--pdb-failures``. +""" + +import pdb +from nose.plugins.base import Plugin + +class Pdb(Plugin): + """ + Provides --pdb and --pdb-failures options that cause the test runner to + drop into pdb if it encounters an error or failure, respectively. + """ + enabled_for_errors = False + enabled_for_failures = False + score = 5 # run last, among builtins + + def options(self, parser, env): + """Register commandline options. + """ + parser.add_option( + "--pdb", action="store_true", dest="debugBoth", + default=env.get('NOSE_PDB', False), + help="Drop into debugger on failures or errors") + parser.add_option( + "--pdb-failures", action="store_true", + dest="debugFailures", + default=env.get('NOSE_PDB_FAILURES', False), + help="Drop into debugger on failures") + parser.add_option( + "--pdb-errors", action="store_true", + dest="debugErrors", + default=env.get('NOSE_PDB_ERRORS', False), + help="Drop into debugger on errors") + + def configure(self, options, conf): + """Configure which kinds of exceptions trigger plugin. + """ + self.conf = conf + self.enabled_for_errors = options.debugErrors or options.debugBoth + self.enabled_for_failures = options.debugFailures or options.debugBoth + self.enabled = self.enabled_for_failures or self.enabled_for_errors + + def addError(self, test, err): + """Enter pdb if configured to debug errors. + """ + if not self.enabled_for_errors: + return + self.debug(err) + + def addFailure(self, test, err): + """Enter pdb if configured to debug failures. + """ + if not self.enabled_for_failures: + return + self.debug(err) + + def debug(self, err): + import sys # FIXME why is this import here? + ec, ev, tb = err + stdout = sys.stdout + sys.stdout = sys.__stdout__ + try: + pdb.post_mortem(tb) + finally: + sys.stdout = stdout diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/debug.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/debug.pyc new file mode 100644 index 0000000000000000000000000000000000000000..32af184066570967dff3204eb387322e63b492e4 GIT binary patch literal 3103 zcmcguZEqVz5Z?1^>?F+#6ct)v`2g|*jOt?f(Cx2N58 zN>K6vh5x{R;_vVS;F&qwxwfkM0X4R7JiE8Ed-KdQGgtj*v;D`-=g%Us_*C)#9WHwh zA{Jr*>4~@^Qcnz^;8zuCMa-&VP!(QW6RIl4n5~OHg}4ynmqCq|A9WhE%ij>~C)32r zJe^OHOy)+PB(bt`IP7-wcr+Z!FpHO??l?@+xltC=I(LcAY)?L!s^$IRuw6{c7fG7R z*yvn3+;+-3Y35m`j7&18C3coCrYe((lPZh!Jafue93_=8+F(=NX6w~zoyo=FU&^^% zomhIJUOV|0pM#DEryRL=$UZs3>@Xg!Fr@o?xa^M*3K#+&$O=IPbV$|-$w7mV0&IgO zp-Re{0HUO{7KjeoB5v@^y6}%WP1^P^h_=M%a0wE^1A>;g@M_+|003aNFjy}cY?KT(%Ldm<23sYA?UKO`8^pWd>3j5mUqJY3 zl3370MtU{_DbplVO8^V+2y;swGRjPW5bo>Dk*C&aqXK8<%GEFg$(?JlGMZ2Jw3|AL zUaZF9Jaujj`oZI){owGy9zFJlGE37+VZoR$K>9Jclv7QY;Cx5+2K z>fs`h+)nA7;NkZ_JbLQyAK6dddXC*#?Oq(`)|Y$lQwmwPRo;2u_aFO5_SPHsEjBsm z5HA?6Fph&FnK^+b$~l7eVVGJ~tRfVxO2-Uz9vZ6*FICwI;UrktXVCgjanJTAMoqLi z4NVl9uy0hZZ9hMCQ=N5T)9yPUq z-(v-9V2)bhfvvPN*XH{=8z&RgO4PX|n#$)%7K0pPseX%8Q97kF3Dc)=?2^L=Tt}F7 z5w`IuvOa)^YlFpef`mwgI7b$H;@7G;$FC;N zk-6N>&WpB&yA=_5;`beaNFUe4S)JMS6Rgj832y$3L6O%7{C?5lM5HolPc4@|>ta23 zTr`8A7z6=R2d_C?mQmGH#m(u zmO$Cu@>-BpZ>Q3sHp9&@2(oad;1~rYfH(0xr6Hjo1hI~Sz^9hOS>+RPIJInqu3HqF z8+7*;iH}Jzt)N_yll0cduK`p;8?^>{1HP5kZfmX8Y&AKoKH=?u2El!qT2XJ&b$X-F iDk7KgX{XD;u=Xyy+!~I%SHS%(agXWWsBC!KmHz+8`>S?#j)wB0M+~d*XQ4u`SPd zp;CE3<$?dp4}f#WX}m=s@j@-lWWMK~bI-jK?~jAv*LRQdp*#-+JS8;|B5IjKi#Kr74*=r^J(q95jal>FTn5}ay z>Y~l^QskvJvM98W;$-?bnjU{Oo1O^OG*u&#LTW8mXqmMVN49&kI8k+@5@}RAQ`#&7 z^>di$W}wD5@+|X#k`6x^#Dqkj6CmvNcLn zD?8UH-4^D7SS(H!3jzDk*cp$J(F@fqE3G~XuFtMoQ@7Y5%k-aaFDt_qBvo4imyn>N z+>(IPS28c!MuowtVHB#A%L1#G7cg=qttGHdB-n#POxu*0tyU{u(dxX+VBdILR^uMi zVi5-UpZG>D++qS$Q|A1bDK~H2=svcdGOuCqCigqhz^U{#ism&6qJb(qE{xVvxX(khAL z5t`Ij`bTspPqb?EBx_VwH5al;WFseysw+LIFU-0s$EtiW300QqNeQQoKMp?)56AVz zC*dKF+QCUDS3P;jy!s+y@?J&J16022JJzdoT7>75XYX{RWAUazW-f3t_13b|B8 zhi#{GGsHx$x8h9LP0RvI=@>bb>C!WYEwmio8T5+K|_sjjR*%HkO_}I-kZ*PiNmgdNPaq zkkqeZ?r#xbm`0g!;;_K9sTviVrd5Vvq@c*KYs;$V%}Q+>b9U8Q6}A2ht4?ywK`C^t zl3W&I-PxIO#_0Fo49yxdSK;W5-UL;urSWye)MC9-4BUCAHZ|v zS;ctN9C4Qy45+k9I=5`;clf}nT;&;Z;`SNoWpEa84jQp&%>gPT#W=ZMZ8_wgH60vt zW{=+FwVXt@iPh2_y@i43K39C9oliR_-y*{tVms?UKu5DA$r~a_hTz$EY?wqWnTVN= zEO2hkpyY_%5}}aIR2@=QTe^GPI*9LMtcPV=|9kG__`8c@9}R!t1I&<%I~<;k*c}}f z4r@-!;Wh(@_P>GsFVG?52gc^2>GiA9f#vgW8IygczUUsNhYUfp5x#rRyXXG}`44O} literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/doctests.py b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/doctests.py new file mode 100644 index 0000000..5ef6579 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/doctests.py @@ -0,0 +1,455 @@ +"""Use the Doctest plugin with ``--with-doctest`` or the NOSE_WITH_DOCTEST +environment variable to enable collection and execution of :mod:`doctests +`. Because doctests are usually included in the tested package +(instead of being grouped into packages or modules of their own), nose only +looks for them in the non-test packages it discovers in the working directory. + +Doctests may also be placed into files other than python modules, in which +case they can be collected and executed by using the ``--doctest-extension`` +switch or NOSE_DOCTEST_EXTENSION environment variable to indicate which file +extension(s) to load. + +When loading doctests from non-module files, use the ``--doctest-fixtures`` +switch to specify how to find modules containing fixtures for the tests. A +module name will be produced by appending the value of that switch to the base +name of each doctest file loaded. For example, a doctest file "widgets.rst" +with the switch ``--doctest_fixtures=_fixt`` will load fixtures from the module +``widgets_fixt.py``. + +A fixtures module may define any or all of the following functions: + +* setup([module]) or setup_module([module]) + + Called before the test runs. You may raise SkipTest to skip all tests. + +* teardown([module]) or teardown_module([module]) + + Called after the test runs, if setup/setup_module did not raise an + unhandled exception. + +* setup_test(test) + + Called before the test. NOTE: the argument passed is a + doctest.DocTest instance, *not* a unittest.TestCase. + +* teardown_test(test) + + Called after the test, if setup_test did not raise an exception. NOTE: the + argument passed is a doctest.DocTest instance, *not* a unittest.TestCase. + +Doctests are run like any other test, with the exception that output +capture does not work; doctest does its own output capture while running a +test. + +.. note :: + + See :doc:`../doc_tests/test_doctest_fixtures/doctest_fixtures` for + additional documentation and examples. + +""" +from __future__ import generators + +import logging +import os +import sys +import unittest +from inspect import getmodule +from nose.plugins.base import Plugin +from nose.suite import ContextList +from nose.util import anyp, getpackage, test_address, resolve_name, \ + src, tolist, isproperty +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO +import sys +import __builtin__ as builtin_mod + +log = logging.getLogger(__name__) + +try: + import doctest + doctest.DocTestCase + # system version of doctest is acceptable, but needs a monkeypatch +except (ImportError, AttributeError): + # system version is too old + import nose.ext.dtcompat as doctest + + +# +# Doctest and coverage don't get along, so we need to create +# a monkeypatch that will replace the part of doctest that +# interferes with coverage reports. +# +# The monkeypatch is based on this zope patch: +# http://svn.zope.org/Zope3/trunk/src/zope/testing/doctest.py?rev=28679&r1=28703&r2=28705 +# +_orp = doctest._OutputRedirectingPdb + +class NoseOutputRedirectingPdb(_orp): + def __init__(self, out): + self.__debugger_used = False + _orp.__init__(self, out) + + def set_trace(self): + self.__debugger_used = True + _orp.set_trace(self, sys._getframe().f_back) + + def set_continue(self): + # Calling set_continue unconditionally would break unit test + # coverage reporting, as Bdb.set_continue calls sys.settrace(None). + if self.__debugger_used: + _orp.set_continue(self) +doctest._OutputRedirectingPdb = NoseOutputRedirectingPdb + + +class DoctestSuite(unittest.TestSuite): + """ + Doctest suites are parallelizable at the module or file level only, + since they may be attached to objects that are not individually + addressable (like properties). This suite subclass is used when + loading doctests from a module to ensure that behavior. + + This class is used only if the plugin is not fully prepared; + in normal use, the loader's suiteClass is used. + + """ + can_split = False + + def __init__(self, tests=(), context=None, can_split=False): + self.context = context + self.can_split = can_split + unittest.TestSuite.__init__(self, tests=tests) + + def address(self): + return test_address(self.context) + + def __iter__(self): + # 2.3 compat + return iter(self._tests) + + def __str__(self): + return str(self._tests) + + +class Doctest(Plugin): + """ + Activate doctest plugin to find and run doctests in non-test modules. + """ + extension = None + suiteClass = DoctestSuite + + def options(self, parser, env): + """Register commmandline options. + """ + Plugin.options(self, parser, env) + parser.add_option('--doctest-tests', action='store_true', + dest='doctest_tests', + default=env.get('NOSE_DOCTEST_TESTS'), + help="Also look for doctests in test modules. " + "Note that classes, methods and functions should " + "have either doctests or non-doctest tests, " + "not both. [NOSE_DOCTEST_TESTS]") + parser.add_option('--doctest-extension', action="append", + dest="doctestExtension", + metavar="EXT", + help="Also look for doctests in files with " + "this extension [NOSE_DOCTEST_EXTENSION]") + parser.add_option('--doctest-result-variable', + dest='doctest_result_var', + default=env.get('NOSE_DOCTEST_RESULT_VAR'), + metavar="VAR", + help="Change the variable name set to the result of " + "the last interpreter command from the default '_'. " + "Can be used to avoid conflicts with the _() " + "function used for text translation. " + "[NOSE_DOCTEST_RESULT_VAR]") + parser.add_option('--doctest-fixtures', action="store", + dest="doctestFixtures", + metavar="SUFFIX", + help="Find fixtures for a doctest file in module " + "with this name appended to the base name " + "of the doctest file") + parser.add_option('--doctest-options', action="append", + dest="doctestOptions", + metavar="OPTIONS", + help="Specify options to pass to doctest. " + + "Eg. '+ELLIPSIS,+NORMALIZE_WHITESPACE'") + # Set the default as a list, if given in env; otherwise + # an additional value set on the command line will cause + # an error. + env_setting = env.get('NOSE_DOCTEST_EXTENSION') + if env_setting is not None: + parser.set_defaults(doctestExtension=tolist(env_setting)) + + def configure(self, options, config): + """Configure plugin. + """ + Plugin.configure(self, options, config) + self.doctest_result_var = options.doctest_result_var + self.doctest_tests = options.doctest_tests + self.extension = tolist(options.doctestExtension) + self.fixtures = options.doctestFixtures + self.finder = doctest.DocTestFinder() + self.optionflags = 0 + if options.doctestOptions: + flags = ",".join(options.doctestOptions).split(',') + for flag in flags: + if not flag or flag[0] not in '+-': + raise ValueError( + "Must specify doctest options with starting " + + "'+' or '-'. Got %s" % (flag,)) + mode, option_name = flag[0], flag[1:] + option_flag = doctest.OPTIONFLAGS_BY_NAME.get(option_name) + if not option_flag: + raise ValueError("Unknown doctest option %s" % + (option_name,)) + if mode == '+': + self.optionflags |= option_flag + elif mode == '-': + self.optionflags &= ~option_flag + + def prepareTestLoader(self, loader): + """Capture loader's suiteClass. + + This is used to create test suites from doctest files. + + """ + self.suiteClass = loader.suiteClass + + def loadTestsFromModule(self, module): + """Load doctests from the module. + """ + log.debug("loading from %s", module) + if not self.matches(module.__name__): + log.debug("Doctest doesn't want module %s", module) + return + try: + tests = self.finder.find(module) + except AttributeError: + log.exception("Attribute error loading from %s", module) + # nose allows module.__test__ = False; doctest does not and throws + # AttributeError + return + if not tests: + log.debug("No tests found in %s", module) + return + tests.sort() + module_file = src(module.__file__) + # FIXME this breaks the id plugin somehow (tests probably don't + # get wrapped in result proxy or something) + cases = [] + for test in tests: + if not test.examples: + continue + if not test.filename: + test.filename = module_file + cases.append(DocTestCase(test, + optionflags=self.optionflags, + result_var=self.doctest_result_var)) + if cases: + yield self.suiteClass(cases, context=module, can_split=False) + + def loadTestsFromFile(self, filename): + """Load doctests from the file. + + Tests are loaded only if filename's extension matches + configured doctest extension. + + """ + if self.extension and anyp(filename.endswith, self.extension): + name = os.path.basename(filename) + dh = open(filename) + try: + doc = dh.read() + finally: + dh.close() + + fixture_context = None + globs = {'__file__': filename} + if self.fixtures: + base, ext = os.path.splitext(name) + dirname = os.path.dirname(filename) + sys.path.append(dirname) + fixt_mod = base + self.fixtures + try: + fixture_context = __import__( + fixt_mod, globals(), locals(), ["nop"]) + except ImportError, e: + log.debug( + "Could not import %s: %s (%s)", fixt_mod, e, sys.path) + log.debug("Fixture module %s resolved to %s", + fixt_mod, fixture_context) + if hasattr(fixture_context, 'globs'): + globs = fixture_context.globs(globs) + parser = doctest.DocTestParser() + test = parser.get_doctest( + doc, globs=globs, name=name, + filename=filename, lineno=0) + if test.examples: + case = DocFileCase( + test, + optionflags=self.optionflags, + setUp=getattr(fixture_context, 'setup_test', None), + tearDown=getattr(fixture_context, 'teardown_test', None), + result_var=self.doctest_result_var) + if fixture_context: + yield ContextList((case,), context=fixture_context) + else: + yield case + else: + yield False # no tests to load + + def makeTest(self, obj, parent): + """Look for doctests in the given object, which will be a + function, method or class. + """ + name = getattr(obj, '__name__', 'Unnammed %s' % type(obj)) + doctests = self.finder.find(obj, module=getmodule(parent), name=name) + if doctests: + for test in doctests: + if len(test.examples) == 0: + continue + yield DocTestCase(test, obj=obj, optionflags=self.optionflags, + result_var=self.doctest_result_var) + + def matches(self, name): + # FIXME this seems wrong -- nothing is ever going to + # fail this test, since we're given a module NAME not FILE + if name == '__init__.py': + return False + # FIXME don't think we need include/exclude checks here? + return ((self.doctest_tests or not self.conf.testMatch.search(name) + or (self.conf.include + and filter(None, + [inc.search(name) + for inc in self.conf.include]))) + and (not self.conf.exclude + or not filter(None, + [exc.search(name) + for exc in self.conf.exclude]))) + + def wantFile(self, file): + """Override to select all modules and any file ending with + configured doctest extension. + """ + # always want .py files + if file.endswith('.py'): + return True + # also want files that match my extension + if (self.extension + and anyp(file.endswith, self.extension) + and (not self.conf.exclude + or not filter(None, + [exc.search(file) + for exc in self.conf.exclude]))): + return True + return None + + +class DocTestCase(doctest.DocTestCase): + """Overrides DocTestCase to + provide an address() method that returns the correct address for + the doctest case. To provide hints for address(), an obj may also + be passed -- this will be used as the test object for purposes of + determining the test address, if it is provided. + """ + def __init__(self, test, optionflags=0, setUp=None, tearDown=None, + checker=None, obj=None, result_var='_'): + self._result_var = result_var + self._nose_obj = obj + super(DocTestCase, self).__init__( + test, optionflags=optionflags, setUp=setUp, tearDown=tearDown, + checker=checker) + + def address(self): + if self._nose_obj is not None: + return test_address(self._nose_obj) + obj = resolve_name(self._dt_test.name) + + if isproperty(obj): + # properties have no connection to the class they are in + # so we can't just look 'em up, we have to first look up + # the class, then stick the prop on the end + parts = self._dt_test.name.split('.') + class_name = '.'.join(parts[:-1]) + cls = resolve_name(class_name) + base_addr = test_address(cls) + return (base_addr[0], base_addr[1], + '.'.join([base_addr[2], parts[-1]])) + else: + return test_address(obj) + + # doctests loaded via find(obj) omit the module name + # so we need to override id, __repr__ and shortDescription + # bonus: this will squash a 2.3 vs 2.4 incompatiblity + def id(self): + name = self._dt_test.name + filename = self._dt_test.filename + if filename is not None: + pk = getpackage(filename) + if pk is None: + return name + if not name.startswith(pk): + name = "%s.%s" % (pk, name) + return name + + def __repr__(self): + name = self.id() + name = name.split('.') + return "%s (%s)" % (name[-1], '.'.join(name[:-1])) + __str__ = __repr__ + + def shortDescription(self): + return 'Doctest: %s' % self.id() + + def setUp(self): + if self._result_var is not None: + self._old_displayhook = sys.displayhook + sys.displayhook = self._displayhook + super(DocTestCase, self).setUp() + + def _displayhook(self, value): + if value is None: + return + setattr(builtin_mod, self._result_var, value) + print repr(value) + + def tearDown(self): + super(DocTestCase, self).tearDown() + if self._result_var is not None: + sys.displayhook = self._old_displayhook + delattr(builtin_mod, self._result_var) + + +class DocFileCase(doctest.DocFileCase): + """Overrides to provide address() method that returns the correct + address for the doc file case. + """ + def __init__(self, test, optionflags=0, setUp=None, tearDown=None, + checker=None, result_var='_'): + self._result_var = result_var + super(DocFileCase, self).__init__( + test, optionflags=optionflags, setUp=setUp, tearDown=tearDown, + checker=None) + + def address(self): + return (self._dt_test.filename, None, None) + + def setUp(self): + if self._result_var is not None: + self._old_displayhook = sys.displayhook + sys.displayhook = self._displayhook + super(DocFileCase, self).setUp() + + def _displayhook(self, value): + if value is None: + return + setattr(builtin_mod, self._result_var, value) + print repr(value) + + def tearDown(self): + super(DocFileCase, self).tearDown() + if self._result_var is not None: + sys.displayhook = self._old_displayhook + delattr(builtin_mod, self._result_var) diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/doctests.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/doctests.pyc new file mode 100644 index 0000000000000000000000000000000000000000..83a11a70df1445fbd042498becaf5f6f21624dd3 GIT binary patch literal 18296 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 literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/errorclass.py b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/errorclass.py new file mode 100644 index 0000000..d1540e0 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/errorclass.py @@ -0,0 +1,210 @@ +""" +ErrorClass Plugins +------------------ + +ErrorClass plugins provide an easy way to add support for custom +handling of particular classes of exceptions. + +An ErrorClass plugin defines one or more ErrorClasses and how each is +handled and reported on. Each error class is stored in a different +attribute on the result, and reported separately. Each error class must +indicate the exceptions that fall under that class, the label to use +for reporting, and whether exceptions of the class should be +considered as failures for the whole test run. + +ErrorClasses use a declarative syntax. Assign an ErrorClass to the +attribute you wish to add to the result object, defining the +exceptions, label and isfailure attributes. For example, to declare an +ErrorClassPlugin that defines TodoErrors (and subclasses of TodoError) +as an error class with the label 'TODO' that is considered a failure, +do this: + + >>> class Todo(Exception): + ... pass + >>> class TodoError(ErrorClassPlugin): + ... todo = ErrorClass(Todo, label='TODO', isfailure=True) + +The MetaErrorClass metaclass translates the ErrorClass declarations +into the tuples used by the error handling and reporting functions in +the result. This is an internal format and subject to change; you +should always use the declarative syntax for attaching ErrorClasses to +an ErrorClass plugin. + + >>> TodoError.errorClasses # doctest: +ELLIPSIS + ((, ('todo', 'TODO', True)),) + +Let's see the plugin in action. First some boilerplate. + + >>> import sys + >>> import unittest + >>> try: + ... # 2.7+ + ... from unittest.runner import _WritelnDecorator + ... except ImportError: + ... from unittest import _WritelnDecorator + ... + >>> buf = _WritelnDecorator(sys.stdout) + +Now define a test case that raises a Todo. + + >>> class TestTodo(unittest.TestCase): + ... def runTest(self): + ... raise Todo("I need to test something") + >>> case = TestTodo() + +Prepare the result using our plugin. Normally this happens during the +course of test execution within nose -- you won't be doing this +yourself. For the purposes of this testing document, I'm stepping +through the internal process of nose so you can see what happens at +each step. + + >>> plugin = TodoError() + >>> from nose.result import _TextTestResult + >>> result = _TextTestResult(stream=buf, descriptions=0, verbosity=2) + >>> plugin.prepareTestResult(result) + +Now run the test. TODO is printed. + + >>> _ = case(result) # doctest: +ELLIPSIS + runTest (....TestTodo) ... TODO: I need to test something + +Errors and failures are empty, but todo has our test: + + >>> result.errors + [] + >>> result.failures + [] + >>> result.todo # doctest: +ELLIPSIS + [(<....TestTodo testMethod=runTest>, '...Todo: I need to test something\\n')] + >>> result.printErrors() # doctest: +ELLIPSIS + + ====================================================================== + TODO: runTest (....TestTodo) + ---------------------------------------------------------------------- + Traceback (most recent call last): + ... + ...Todo: I need to test something + + +Since we defined a Todo as a failure, the run was not successful. + + >>> result.wasSuccessful() + False +""" + +from nose.pyversion import make_instancemethod +from nose.plugins.base import Plugin +from nose.result import TextTestResult +from nose.util import isclass + +class MetaErrorClass(type): + """Metaclass for ErrorClassPlugins that allows error classes to be + set up in a declarative manner. + """ + def __init__(self, name, bases, attr): + errorClasses = [] + for name, detail in attr.items(): + if isinstance(detail, ErrorClass): + attr.pop(name) + for cls in detail: + errorClasses.append( + (cls, (name, detail.label, detail.isfailure))) + super(MetaErrorClass, self).__init__(name, bases, attr) + self.errorClasses = tuple(errorClasses) + + +class ErrorClass(object): + def __init__(self, *errorClasses, **kw): + self.errorClasses = errorClasses + try: + for key in ('label', 'isfailure'): + setattr(self, key, kw.pop(key)) + except KeyError: + raise TypeError("%r is a required named argument for ErrorClass" + % key) + + def __iter__(self): + return iter(self.errorClasses) + + +class ErrorClassPlugin(Plugin): + """ + Base class for ErrorClass plugins. Subclass this class and declare the + exceptions that you wish to handle as attributes of the subclass. + """ + __metaclass__ = MetaErrorClass + score = 1000 + errorClasses = () + + def addError(self, test, err): + err_cls, a, b = err + if not isclass(err_cls): + return + classes = [e[0] for e in self.errorClasses] + if filter(lambda c: issubclass(err_cls, c), classes): + return True + + def prepareTestResult(self, result): + if not hasattr(result, 'errorClasses'): + self.patchResult(result) + for cls, (storage_attr, label, isfail) in self.errorClasses: + if cls not in result.errorClasses: + storage = getattr(result, storage_attr, []) + setattr(result, storage_attr, storage) + result.errorClasses[cls] = (storage, label, isfail) + + def patchResult(self, result): + result.printLabel = print_label_patch(result) + result._orig_addError, result.addError = \ + result.addError, add_error_patch(result) + result._orig_wasSuccessful, result.wasSuccessful = \ + result.wasSuccessful, wassuccessful_patch(result) + if hasattr(result, 'printErrors'): + result._orig_printErrors, result.printErrors = \ + result.printErrors, print_errors_patch(result) + if hasattr(result, 'addSkip'): + result._orig_addSkip, result.addSkip = \ + result.addSkip, add_skip_patch(result) + result.errorClasses = {} + + +def add_error_patch(result): + """Create a new addError method to patch into a result instance + that recognizes the errorClasses attribute and deals with + errorclasses correctly. + """ + return make_instancemethod(TextTestResult.addError, result) + + +def print_errors_patch(result): + """Create a new printErrors method that prints errorClasses items + as well. + """ + return make_instancemethod(TextTestResult.printErrors, result) + + +def print_label_patch(result): + """Create a new printLabel method that prints errorClasses items + as well. + """ + return make_instancemethod(TextTestResult.printLabel, result) + + +def wassuccessful_patch(result): + """Create a new wasSuccessful method that checks errorClasses for + exceptions that were put into other slots than error or failure + but that still count as not success. + """ + return make_instancemethod(TextTestResult.wasSuccessful, result) + + +def add_skip_patch(result): + """Create a new addSkip method to patch into a result instance + that delegates to addError. + """ + return make_instancemethod(TextTestResult.addSkip, result) + + +if __name__ == '__main__': + import doctest + doctest.testmod() diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/errorclass.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/errorclass.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d149ca17e85ff2cba86779fbff7c0782bc7a123a GIT binary patch literal 9483 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 begin captured logging <<')] + \ + records + \ + [ln('>> end captured logging <<')]) diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/logcapture.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/logcapture.pyc new file mode 100644 index 0000000000000000000000000000000000000000..07d854bdd95f5a9bffe88492f8871fd4e8b43fca GIT binary patch literal 12255 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 self.config.multiprocess_timeout-0.1): + log.debug('worker %d has finished its work item, ' + 'but is not exiting? do we wait for it?', + iworker) + else: + any_alive = True + if (len(worker_addr) > 0 + and timeprocessing > self.config.multiprocess_timeout-0.1): + log.debug('timed out worker %s: %s', + iworker,worker_addr) + w.currentaddr.value = bytes_('') + # If the process is in C++ code, sending a SIGILL + # might not send a python KeybordInterrupt exception + # therefore, send multiple signals until an + # exception is caught. If this takes too long, then + # terminate the process + w.keyboardCaught.clear() + startkilltime = time.time() + while not w.keyboardCaught.is_set() and w.is_alive(): + if time.time()-startkilltime > self.waitkilltime: + # have to terminate... + log.error("terminating worker %s",iworker) + w.terminate() + # there is a small probability that the + # terminated process might send a result, + # which has to be specially handled or + # else processes might get orphaned. + workers[iworker] = w = self.startProcess(iworker, testQueue, resultQueue, shouldStop, result) + break + os.kill(w.pid, signal.SIGILL) + time.sleep(0.1) + if not any_alive and testQueue.empty(): + log.debug("All workers dead") + break + nexttimeout=self.config.multiprocess_timeout + for w in workers: + if w.is_alive() and len(w.currentaddr.value) > 0: + timeprocessing = time.time()-w.currentstart.value + if timeprocessing <= self.config.multiprocess_timeout: + nexttimeout = min(nexttimeout, + self.config.multiprocess_timeout-timeprocessing) + log.debug("Completed %s tasks (%s remain)", len(completed), len(tasks)) + + except (KeyboardInterrupt, SystemExit), e: + log.info('parent received ctrl-c when waiting for test results') + thrownError = e + #resultQueue.get(False) + + result.addError(test, sys.exc_info()) + + try: + for case in to_teardown: + log.debug("Tearing down shared fixtures for %s", case) + try: + case.tearDown() + except (KeyboardInterrupt, SystemExit): + raise + except: + result.addError(case, sys.exc_info()) + + stop = time.time() + + # first write since can freeze on shutting down processes + result.printErrors() + result.printSummary(start, stop) + self.config.plugins.finalize(result) + + if thrownError is None: + log.debug("Tell all workers to stop") + for w in workers: + if w.is_alive(): + testQueue.put('STOP', block=False) + + # wait for the workers to end + for iworker,worker in enumerate(workers): + if worker.is_alive(): + log.debug('joining worker %s',iworker) + worker.join() + if worker.is_alive(): + log.debug('failed to join worker %s',iworker) + except (KeyboardInterrupt, SystemExit): + log.info('parent received ctrl-c when shutting down: stop all processes') + for worker in workers: + if worker.is_alive(): + worker.terminate() + + if thrownError: raise thrownError + else: raise + + return result + + def addtask(testQueue,tasks,case): + arg = None + if isinstance(case,nose.case.Test) and hasattr(case.test,'arg'): + # this removes the top level descriptor and allows real function + # name to be returned + case.test.descriptor = None + arg = case.test.arg + test_addr = MultiProcessTestRunner.address(case) + testQueue.put((test_addr,arg), block=False) + if arg is not None: + test_addr += str(arg) + if tasks is not None: + tasks.append(test_addr) + return test_addr + addtask = staticmethod(addtask) + + def address(case): + if hasattr(case, 'address'): + file, mod, call = case.address() + elif hasattr(case, 'context'): + file, mod, call = test_address(case.context) + else: + raise Exception("Unable to convert %s to address" % case) + parts = [] + if file is None: + if mod is None: + raise Exception("Unaddressable case %s" % case) + else: + parts.append(mod) + else: + # strip __init__.py(c) from end of file part + # if present, having it there confuses loader + dirname, basename = os.path.split(file) + if basename.startswith('__init__'): + file = dirname + parts.append(file) + if call is not None: + parts.append(call) + return ':'.join(map(str, parts)) + address = staticmethod(address) + + def nextBatch(self, test): + # allows tests or suites to mark themselves as not safe + # for multiprocess execution + if hasattr(test, 'context'): + if not getattr(test.context, '_multiprocess_', True): + return + + if ((isinstance(test, ContextSuite) + and test.hasFixtures(self.checkCanSplit)) + or not getattr(test, 'can_split', True) + or not isinstance(test, unittest.TestSuite)): + # regular test case, or a suite with context fixtures + + # special case: when run like nosetests path/to/module.py + # the top-level suite has only one item, and it shares + # the same context as that item. In that case, we want the + # item, not the top-level suite + if isinstance(test, ContextSuite): + contained = list(test) + if (len(contained) == 1 + and getattr(contained[0], + 'context', None) == test.context): + test = contained[0] + yield test + else: + # Suite is without fixtures at this level; but it may have + # fixtures at any deeper level, so we need to examine it all + # the way down to the case level + for case in test: + for batch in self.nextBatch(case): + yield batch + + def checkCanSplit(context, fixt): + """ + Callback that we use to check whether the fixtures found in a + context or ancestor are ones we care about. + + Contexts can tell us that their fixtures are reentrant by setting + _multiprocess_can_split_. So if we see that, we return False to + disregard those fixtures. + """ + if not fixt: + return False + if getattr(context, '_multiprocess_can_split_', False): + return False + return True + checkCanSplit = staticmethod(checkCanSplit) + + def sharedFixtures(self, case): + context = getattr(case, 'context', None) + if not context: + return False + return getattr(context, '_multiprocess_shared_', False) + + def consolidate(self, result, batch_result): + log.debug("batch result is %s" , batch_result) + try: + output, testsRun, failures, errors, errorClasses = batch_result + except ValueError: + log.debug("result in unexpected format %s", batch_result) + failure.Failure(*sys.exc_info())(result) + return + self.stream.write(output) + result.testsRun += testsRun + result.failures.extend(failures) + result.errors.extend(errors) + for key, (storage, label, isfail) in errorClasses.items(): + if key not in result.errorClasses: + # Ordinarily storage is result attribute + # but it's only processed through the errorClasses + # dict, so it's ok to fake it here + result.errorClasses[key] = ([], label, isfail) + mystorage, _junk, _junk = result.errorClasses[key] + mystorage.extend(storage) + log.debug("Ran %s tests (total: %s)", testsRun, result.testsRun) + + +def runner(ix, testQueue, resultQueue, currentaddr, currentstart, + keyboardCaught, shouldStop, loaderClass, resultClass, config): + try: + try: + return __runner(ix, testQueue, resultQueue, currentaddr, currentstart, + keyboardCaught, shouldStop, loaderClass, resultClass, config) + except KeyboardInterrupt: + log.debug('Worker %s keyboard interrupt, stopping',ix) + except Empty: + log.debug("Worker %s timed out waiting for tasks", ix) + +def __runner(ix, testQueue, resultQueue, currentaddr, currentstart, + keyboardCaught, shouldStop, loaderClass, resultClass, config): + + config = pickle.loads(config) + dummy_parser = config.parserClass() + if _instantiate_plugins is not None: + for pluginclass in _instantiate_plugins: + plugin = pluginclass() + plugin.addOptions(dummy_parser,{}) + config.plugins.addPlugin(plugin) + config.plugins.configure(config.options,config) + config.plugins.begin() + log.debug("Worker %s executing, pid=%d", ix,os.getpid()) + loader = loaderClass(config=config) + loader.suiteClass.suiteClass = NoSharedFixtureContextSuite + + def get(): + return testQueue.get(timeout=config.multiprocess_timeout) + + def makeResult(): + stream = _WritelnDecorator(StringIO()) + result = resultClass(stream, descriptions=1, + verbosity=config.verbosity, + config=config) + plug_result = config.plugins.prepareTestResult(result) + if plug_result: + return plug_result + return result + + def batch(result): + failures = [(TestLet(c), err) for c, err in result.failures] + errors = [(TestLet(c), err) for c, err in result.errors] + errorClasses = {} + for key, (storage, label, isfail) in result.errorClasses.items(): + errorClasses[key] = ([(TestLet(c), err) for c, err in storage], + label, isfail) + return ( + result.stream.getvalue(), + result.testsRun, + failures, + errors, + errorClasses) + for test_addr, arg in iter(get, 'STOP'): + if shouldStop.is_set(): + log.exception('Worker %d STOPPED',ix) + break + result = makeResult() + test = loader.loadTestsFromNames([test_addr]) + test.testQueue = testQueue + test.tasks = [] + test.arg = arg + log.debug("Worker %s Test is %s (%s)", ix, test_addr, test) + try: + if arg is not None: + test_addr = test_addr + str(arg) + currentaddr.value = bytes_(test_addr) + currentstart.value = time.time() + test(result) + currentaddr.value = bytes_('') + resultQueue.put((ix, test_addr, test.tasks, batch(result))) + except KeyboardInterrupt, e: #TimedOutException: + timeout = isinstance(e, TimedOutException) + if timeout: + keyboardCaught.set() + if len(currentaddr.value): + if timeout: + msg = 'Worker %s timed out, failing current test %s' + else: + msg = 'Worker %s keyboard interrupt, failing current test %s' + log.exception(msg,ix,test_addr) + currentaddr.value = bytes_('') + failure.Failure(*sys.exc_info())(result) + resultQueue.put((ix, test_addr, test.tasks, batch(result))) + else: + if timeout: + msg = 'Worker %s test %s timed out' + else: + msg = 'Worker %s test %s keyboard interrupt' + log.debug(msg,ix,test_addr) + resultQueue.put((ix, test_addr, test.tasks, batch(result))) + if not timeout: + raise + except SystemExit: + currentaddr.value = bytes_('') + log.exception('Worker %s system exit',ix) + raise + except: + currentaddr.value = bytes_('') + log.exception("Worker %s error running test or returning " + "results",ix) + failure.Failure(*sys.exc_info())(result) + resultQueue.put((ix, test_addr, test.tasks, batch(result))) + if config.multiprocess_restartworker: + break + log.debug("Worker %s ending", ix) + + +class NoSharedFixtureContextSuite(ContextSuite): + """ + Context suite that never fires shared fixtures. + + When a context sets _multiprocess_shared_, fixtures in that context + are executed by the main process. Using this suite class prevents them + from executing in the runner process as well. + + """ + testQueue = None + tasks = None + arg = None + def setupContext(self, context): + if getattr(context, '_multiprocess_shared_', False): + return + super(NoSharedFixtureContextSuite, self).setupContext(context) + + def teardownContext(self, context): + if getattr(context, '_multiprocess_shared_', False): + return + super(NoSharedFixtureContextSuite, self).teardownContext(context) + def run(self, result): + """Run tests in suite inside of suite fixtures. + """ + # proxy the result for myself + log.debug("suite %s (%s) run called, tests: %s", + id(self), self, self._tests) + if self.resultProxy: + result, orig = self.resultProxy(result, self), result + else: + result, orig = result, result + try: + #log.debug('setUp for %s', id(self)); + self.setUp() + except KeyboardInterrupt: + raise + except: + self.error_context = 'setup' + result.addError(self, self._exc_info()) + return + try: + for test in self._tests: + if (isinstance(test,nose.case.Test) + and self.arg is not None): + test.test.arg = self.arg + else: + test.arg = self.arg + test.testQueue = self.testQueue + test.tasks = self.tasks + if result.shouldStop: + log.debug("stopping") + break + # each nose.case.Test will create its own result proxy + # so the cases need the original result, to avoid proxy + # chains + #log.debug('running test %s in suite %s', test, self); + try: + test(orig) + except KeyboardInterrupt, e: + timeout = isinstance(e, TimedOutException) + if timeout: + msg = 'Timeout when running test %s in suite %s' + else: + msg = 'KeyboardInterrupt when running test %s in suite %s' + log.debug(msg, test, self) + err = (TimedOutException,TimedOutException(str(test)), + sys.exc_info()[2]) + test.config.plugins.addError(test,err) + orig.addError(test,err) + if not timeout: + raise + finally: + self.has_run = True + try: + #log.debug('tearDown for %s', id(self)); + self.tearDown() + except KeyboardInterrupt: + raise + except: + self.error_context = 'teardown' + result.addError(self, self._exc_info()) diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/multiprocess.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/multiprocess.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5dca8a4699bbb6ccc615efb78351ea812869d8aa GIT binary patch literal 28589 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 TM~_U^tL3S`a7p!nYU6(cP{kHv literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/plugintest.py b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/plugintest.py new file mode 100644 index 0000000..76d0d2c --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/plugintest.py @@ -0,0 +1,416 @@ +""" +Testing Plugins +=============== + +The plugin interface is well-tested enough to safely unit test your +use of its hooks with some level of confidence. However, there is also +a mixin for unittest.TestCase called PluginTester that's designed to +test plugins in their native runtime environment. + +Here's a simple example with a do-nothing plugin and a composed suite. + + >>> import unittest + >>> from nose.plugins import Plugin, PluginTester + >>> class FooPlugin(Plugin): + ... pass + >>> class TestPluginFoo(PluginTester, unittest.TestCase): + ... activate = '--with-foo' + ... plugins = [FooPlugin()] + ... def test_foo(self): + ... for line in self.output: + ... # i.e. check for patterns + ... pass + ... + ... # or check for a line containing ... + ... assert "ValueError" in self.output + ... def makeSuite(self): + ... class TC(unittest.TestCase): + ... def runTest(self): + ... raise ValueError("I hate foo") + ... return [TC('runTest')] + ... + >>> res = unittest.TestResult() + >>> case = TestPluginFoo('test_foo') + >>> _ = case(res) + >>> res.errors + [] + >>> res.failures + [] + >>> res.wasSuccessful() + True + >>> res.testsRun + 1 + +And here is a more complex example of testing a plugin that has extra +arguments and reads environment variables. + + >>> import unittest, os + >>> from nose.plugins import Plugin, PluginTester + >>> class FancyOutputter(Plugin): + ... name = "fancy" + ... def configure(self, options, conf): + ... Plugin.configure(self, options, conf) + ... if not self.enabled: + ... return + ... self.fanciness = 1 + ... if options.more_fancy: + ... self.fanciness = 2 + ... if 'EVEN_FANCIER' in self.env: + ... self.fanciness = 3 + ... + ... def options(self, parser, env=os.environ): + ... self.env = env + ... parser.add_option('--more-fancy', action='store_true') + ... Plugin.options(self, parser, env=env) + ... + ... def report(self, stream): + ... stream.write("FANCY " * self.fanciness) + ... + >>> class TestFancyOutputter(PluginTester, unittest.TestCase): + ... activate = '--with-fancy' # enables the plugin + ... plugins = [FancyOutputter()] + ... args = ['--more-fancy'] + ... env = {'EVEN_FANCIER': '1'} + ... + ... def test_fancy_output(self): + ... assert "FANCY FANCY FANCY" in self.output, ( + ... "got: %s" % self.output) + ... def makeSuite(self): + ... class TC(unittest.TestCase): + ... def runTest(self): + ... raise ValueError("I hate fancy stuff") + ... return [TC('runTest')] + ... + >>> res = unittest.TestResult() + >>> case = TestFancyOutputter('test_fancy_output') + >>> _ = case(res) + >>> res.errors + [] + >>> res.failures + [] + >>> res.wasSuccessful() + True + >>> res.testsRun + 1 + +""" + +import re +import sys +from warnings import warn + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + +__all__ = ['PluginTester', 'run'] + +from os import getpid +class MultiProcessFile(object): + """ + helper for testing multiprocessing + + multiprocessing poses a problem for doctests, since the strategy + of replacing sys.stdout/stderr with file-like objects then + inspecting the results won't work: the child processes will + write to the objects, but the data will not be reflected + in the parent doctest-ing process. + + The solution is to create file-like objects which will interact with + multiprocessing in a more desirable way. + + All processes can write to this object, but only the creator can read. + This allows the testing system to see a unified picture of I/O. + """ + def __init__(self): + # per advice at: + # http://docs.python.org/library/multiprocessing.html#all-platforms + self.__master = getpid() + self.__queue = Manager().Queue() + self.__buffer = StringIO() + self.softspace = 0 + + def buffer(self): + if getpid() != self.__master: + return + + from Queue import Empty + from collections import defaultdict + cache = defaultdict(str) + while True: + try: + pid, data = self.__queue.get_nowait() + except Empty: + break + if pid == (): + #show parent output after children + #this is what users see, usually + pid = ( 1e100, ) # googol! + cache[pid] += data + for pid in sorted(cache): + #self.__buffer.write( '%s wrote: %r\n' % (pid, cache[pid]) ) #DEBUG + self.__buffer.write( cache[pid] ) + def write(self, data): + # note that these pids are in the form of current_process()._identity + # rather than OS pids + from multiprocessing import current_process + pid = current_process()._identity + self.__queue.put((pid, data)) + def __iter__(self): + "getattr doesn't work for iter()" + self.buffer() + return self.__buffer + def seek(self, offset, whence=0): + self.buffer() + return self.__buffer.seek(offset, whence) + def getvalue(self): + self.buffer() + return self.__buffer.getvalue() + def __getattr__(self, attr): + return getattr(self.__buffer, attr) + +try: + from multiprocessing import Manager + Buffer = MultiProcessFile +except ImportError: + Buffer = StringIO + +class PluginTester(object): + """A mixin for testing nose plugins in their runtime environment. + + Subclass this and mix in unittest.TestCase to run integration/functional + tests on your plugin. When setUp() is called, the stub test suite is + executed with your plugin so that during an actual test you can inspect the + artifacts of how your plugin interacted with the stub test suite. + + - activate + + - the argument to send nosetests to activate the plugin + + - suitepath + + - if set, this is the path of the suite to test. Otherwise, you + will need to use the hook, makeSuite() + + - plugins + + - the list of plugins to make available during the run. Note + that this does not mean these plugins will be *enabled* during + the run -- only the plugins enabled by the activate argument + or other settings in argv or env will be enabled. + + - args + + - a list of arguments to add to the nosetests command, in addition to + the activate argument + + - env + + - optional dict of environment variables to send nosetests + + """ + activate = None + suitepath = None + args = None + env = {} + argv = None + plugins = [] + ignoreFiles = None + + def makeSuite(self): + """returns a suite object of tests to run (unittest.TestSuite()) + + If self.suitepath is None, this must be implemented. The returned suite + object will be executed with all plugins activated. It may return + None. + + Here is an example of a basic suite object you can return :: + + >>> import unittest + >>> class SomeTest(unittest.TestCase): + ... def runTest(self): + ... raise ValueError("Now do something, plugin!") + ... + >>> unittest.TestSuite([SomeTest()]) # doctest: +ELLIPSIS + ]> + + """ + raise NotImplementedError + + def _execPlugin(self): + """execute the plugin on the internal test suite. + """ + from nose.config import Config + from nose.core import TestProgram + from nose.plugins.manager import PluginManager + + suite = None + stream = Buffer() + conf = Config(env=self.env, + stream=stream, + plugins=PluginManager(plugins=self.plugins)) + if self.ignoreFiles is not None: + conf.ignoreFiles = self.ignoreFiles + if not self.suitepath: + suite = self.makeSuite() + + self.nose = TestProgram(argv=self.argv, config=conf, suite=suite, + exit=False) + self.output = AccessDecorator(stream) + + def setUp(self): + """runs nosetests with the specified test suite, all plugins + activated. + """ + self.argv = ['nosetests', self.activate] + if self.args: + self.argv.extend(self.args) + if self.suitepath: + self.argv.append(self.suitepath) + + self._execPlugin() + + +class AccessDecorator(object): + stream = None + _buf = None + def __init__(self, stream): + self.stream = stream + stream.seek(0) + self._buf = stream.read() + stream.seek(0) + def __contains__(self, val): + return val in self._buf + def __iter__(self): + return iter(self.stream) + def __str__(self): + return self._buf + + +def blankline_separated_blocks(text): + "a bunch of === characters is also considered a blank line" + block = [] + for line in text.splitlines(True): + block.append(line) + line = line.strip() + if not line or line.startswith('===') and not line.strip('='): + yield "".join(block) + block = [] + if block: + yield "".join(block) + + +def remove_stack_traces(out): + # this regexp taken from Python 2.5's doctest + traceback_re = re.compile(r""" + # Grab the traceback header. Different versions of Python have + # said different things on the first traceback line. + ^(?P Traceback\ \( + (?: most\ recent\ call\ last + | innermost\ last + ) \) : + ) + \s* $ # toss trailing whitespace on the header. + (?P .*?) # don't blink: absorb stuff until... + ^(?=\w) # a line *starts* with alphanum. + .*?(?P \w+ ) # exception name + (?P [:\n] .*) # the rest + """, re.VERBOSE | re.MULTILINE | re.DOTALL) + blocks = [] + for block in blankline_separated_blocks(out): + blocks.append(traceback_re.sub(r"\g\n...\n\g\g", block)) + return "".join(blocks) + + +def simplify_warnings(out): + warn_re = re.compile(r""" + # Cut the file and line no, up to the warning name + ^.*:\d+:\s + (?P\w+): \s+ # warning category + (?P.+) $ \n? # warning message + ^ .* $ # stack frame + """, re.VERBOSE | re.MULTILINE) + return warn_re.sub(r"\g: \g", out) + + +def remove_timings(out): + return re.sub( + r"Ran (\d+ tests?) in [0-9.]+s", r"Ran \1 in ...s", out) + + +def munge_nose_output_for_doctest(out): + """Modify nose output to make it easy to use in doctests.""" + out = remove_stack_traces(out) + out = simplify_warnings(out) + out = remove_timings(out) + return out.strip() + + +def run(*arg, **kw): + """ + Specialized version of nose.run for use inside of doctests that + test test runs. + + This version of run() prints the result output to stdout. Before + printing, the output is processed by replacing the timing + information with an ellipsis (...), removing traceback stacks, and + removing trailing whitespace. + + Use this version of run wherever you are writing a doctest that + tests nose (or unittest) test result output. + + Note: do not use doctest: +ELLIPSIS when testing nose output, + since ellipses ("test_foo ... ok") in your expected test runner + output may match multiple lines of output, causing spurious test + passes! + """ + from nose import run + from nose.config import Config + from nose.plugins.manager import PluginManager + + buffer = Buffer() + if 'config' not in kw: + plugins = kw.pop('plugins', []) + if isinstance(plugins, list): + plugins = PluginManager(plugins=plugins) + env = kw.pop('env', {}) + kw['config'] = Config(env=env, plugins=plugins) + if 'argv' not in kw: + kw['argv'] = ['nosetests', '-v'] + kw['config'].stream = buffer + + # Set up buffering so that all output goes to our buffer, + # or warn user if deprecated behavior is active. If this is not + # done, prints and warnings will either be out of place or + # disappear. + stderr = sys.stderr + stdout = sys.stdout + if kw.pop('buffer_all', False): + sys.stdout = sys.stderr = buffer + restore = True + else: + restore = False + warn("The behavior of nose.plugins.plugintest.run() will change in " + "the next release of nose. The current behavior does not " + "correctly account for output to stdout and stderr. To enable " + "correct behavior, use run_buffered() instead, or pass " + "the keyword argument buffer_all=True to run().", + DeprecationWarning, stacklevel=2) + try: + run(*arg, **kw) + finally: + if restore: + sys.stderr = stderr + sys.stdout = stdout + out = buffer.getvalue() + print munge_nose_output_for_doctest(out) + + +def run_buffered(*arg, **kw): + kw['buffer_all'] = True + run(*arg, **kw) + +if __name__ == '__main__': + import doctest + doctest.testmod() diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/plugintest.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/plugintest.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f3713275fba58d9d73de1dd461ca7a3b55b4500e GIT binary patch literal 16682 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 2.7 +# - unittest2 SkipTest is second preference for older pythons. This +# mirrors logic for choosing SkipTest exception in testtools +# - if none of the above, provide custom class +try: + from unittest.case import SkipTest +except ImportError: + try: + from unittest2.case import SkipTest + except ImportError: + class SkipTest(Exception): + """Raise this exception to mark a test as skipped. + """ + pass + + +class Skip(ErrorClassPlugin): + """ + Plugin that installs a SKIP error class for the SkipTest + exception. When SkipTest is raised, the exception will be logged + in the skipped attribute of the result, 'S' or 'SKIP' (verbose) + will be output, and the exception will not be counted as an error + or failure. + """ + enabled = True + skipped = ErrorClass(SkipTest, + label='SKIP', + isfailure=False) + + def options(self, parser, env): + """ + Add my options to command line. + """ + env_opt = 'NOSE_WITHOUT_SKIP' + parser.add_option('--no-skip', action='store_true', + dest='noSkip', default=env.get(env_opt, False), + help="Disable special handling of SkipTest " + "exceptions.") + + def configure(self, options, conf): + """ + Configure plugin. Skip plugin is enabled by default. + """ + if not self.can_configure: + return + self.conf = conf + disable = getattr(options, 'noSkip', False) + if disable: + self.enabled = False + diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/skip.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/skip.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1b91695a419163e96829425fe77af1e76f01b5c7 GIT binary patch literal 2697 zcmcguQEwYX5T3IgJ2nJCiJ$^ht$2wM^_do-N>EimNJWH{ROh5Ae&BMxTie&1?~dDb zi>36TgrC8`>nQ-ytHR zA*4f5jS`1uH5%4vR;OW|oW-sj)G2AuY>S3lSZt;S1Q>!OTLfyAT#V|ZTXf~rhT8=GfHp&r zLijW6a4OlB`Ix!EsVSjBLIe9s{E&|;1YD*56G_C%b)u+OC5qTsac_exQn!_dC7u4A zEMjGYFtWGY@sePqlM)gz)N*Ty&5~CkR}`bg<-d=|d<6j@UexK*p{H2a2#5d(K!Ao7 zwdk@&PaV3fldaJeP61OJcr~1;gUtQyVp&O_qPW8IN z?K}AD=y-78pB1f;kMNf*ybf;4eWkbNQ}|}Mdr_n5+;DC>75MD6fY0o_B!=DW za1{)IHTJ&4Sfd_L42a~aF6B|D;!EDLLW5E%n}OuXJcOMJ|NSf-#}hR1W3?Xl4;&am_UN5=e^6i+z6L5LO}6$@xtRS<$bU^UrveF zf&*7^<@XoZm^UG)(FSkYK%?mhb3867kMZy%WL}-1y1kG16&{jqyN;22Fs5@E*)5!} zqmkAB*!G!= 2 + + def finalize(self, result): + """Save new ids file, if needed. + """ + if result.wasSuccessful(): + self.failed = [] + if self.collecting: + ids = dict(list(zip(list(self.tests.values()), list(self.tests.keys())))) + else: + ids = self.ids + fh = open(self.idfile, 'wb') + dump({'ids': ids, + 'failed': self.failed, + 'source_names': self.source_names}, fh) + fh.close() + log.debug('Saved test ids: %s, failed %s to %s', + ids, self.failed, self.idfile) + + def loadTestsFromNames(self, names, module=None): + """Translate ids in the list of requested names into their + test addresses, if they are found in my dict of tests. + """ + log.debug('ltfn %s %s', names, module) + try: + fh = open(self.idfile, 'rb') + data = load(fh) + if 'ids' in data: + self.ids = data['ids'] + self.failed = data['failed'] + self.source_names = data['source_names'] + else: + # old ids field + self.ids = data + self.failed = [] + self.source_names = names + if self.ids: + self.id = max(self.ids) + 1 + self.tests = dict(list(zip(list(self.ids.values()), list(self.ids.keys())))) + else: + self.id = 1 + log.debug( + 'Loaded test ids %s tests %s failed %s sources %s from %s', + self.ids, self.tests, self.failed, self.source_names, + self.idfile) + fh.close() + except ValueError, e: + # load() may throw a ValueError when reading the ids file, if it + # was generated with a newer version of Python than we are currently + # running. + log.debug('Error loading %s : %s', self.idfile, str(e)) + except IOError: + log.debug('IO error reading %s', self.idfile) + + if self.loopOnFailed and self.failed: + self.collecting = False + names = self.failed + self.failed = [] + # I don't load any tests myself, only translate names like '#2' + # into the associated test addresses + translated = [] + new_source = [] + really_new = [] + for name in names: + trans = self.tr(name) + if trans != name: + translated.append(trans) + else: + new_source.append(name) + # names that are not ids and that are not in the current + # list of source names go into the list for next time + if new_source: + new_set = set(new_source) + old_set = set(self.source_names) + log.debug("old: %s new: %s", old_set, new_set) + really_new = [s for s in new_source + if not s in old_set] + if really_new: + # remember new sources + self.source_names.extend(really_new) + if not translated: + # new set of source names, no translations + # means "run the requested tests" + names = new_source + else: + # no new names to translate and add to id set + self.collecting = False + log.debug("translated: %s new sources %s names %s", + translated, really_new, names) + return (None, translated + really_new or names) + + def makeName(self, addr): + log.debug("Make name %s", addr) + filename, module, call = addr + if filename is not None: + head = src(filename) + else: + head = module + if call is not None: + return "%s:%s" % (head, call) + return head + + def setOutputStream(self, stream): + """Get handle on output stream so the plugin can print id #s + """ + self.stream = stream + + def startTest(self, test): + """Maybe output an id # before the test name. + + Example output:: + + #1 test.test ... ok + #2 test.test_two ... ok + + """ + adr = test.address() + log.debug('start test %s (%s)', adr, adr in self.tests) + if adr in self.tests: + if adr in self._seen: + self.write(' ') + else: + self.write('#%s ' % self.tests[adr]) + self._seen[adr] = 1 + return + self.tests[adr] = self.id + self.write('#%s ' % self.id) + self.id += 1 + + def afterTest(self, test): + # None means test never ran, False means failed/err + if test.passed is False: + try: + key = str(self.tests[test.address()]) + except KeyError: + # never saw this test -- startTest didn't run + pass + else: + if key not in self.failed: + self.failed.append(key) + + def tr(self, name): + log.debug("tr '%s'", name) + try: + key = int(name.replace('#', '')) + except ValueError: + return name + log.debug("Got key %s", key) + # I'm running tests mapped from the ids file, + # not collecting new ones + if key in self.ids: + return self.makeName(self.ids[key]) + return name + + def write(self, output): + if self._write_hashes: + self.stream.write(output) diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/testid.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/testid.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ee921a6a654259c270cd7f07c3ee9aa222e77b1a GIT binary patch literal 9602 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 bc$+*|+ymuDioN7rt<}97P@NmK#rppPYzGJg literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/xunit.py b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/xunit.py new file mode 100644 index 0000000..90b52f5 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/xunit.py @@ -0,0 +1,341 @@ +"""This plugin provides test results in the standard XUnit XML format. + +It's designed for the `Jenkins`_ (previously Hudson) continuous build +system, but will probably work for anything else that understands an +XUnit-formatted XML representation of test results. + +Add this shell command to your builder :: + + nosetests --with-xunit + +And by default a file named nosetests.xml will be written to the +working directory. + +In a Jenkins builder, tick the box named "Publish JUnit test result report" +under the Post-build Actions and enter this value for Test report XMLs:: + + **/nosetests.xml + +If you need to change the name or location of the file, you can set the +``--xunit-file`` option. + +If you need to change the name of the test suite, you can set the +``--xunit-testsuite-name`` option. + +Here is an abbreviated version of what an XML test report might look like:: + + + + + + Traceback (most recent call last): + ... + TypeError: oops, wrong type + + + + +.. _Jenkins: http://jenkins-ci.org/ + +""" +import codecs +import doctest +import os +import sys +import traceback +import re +import inspect +from StringIO import StringIO +from time import time +from xml.sax import saxutils + +from nose.plugins.base import Plugin +from nose.exc import SkipTest +from nose.pyversion import force_unicode, format_exception + +# Invalid XML characters, control characters 0-31 sans \t, \n and \r +CONTROL_CHARACTERS = re.compile(r"[\000-\010\013\014\016-\037]") + +TEST_ID = re.compile(r'^(.*?)(\(.*\))$') + +def xml_safe(value): + """Replaces invalid XML characters with '?'.""" + return CONTROL_CHARACTERS.sub('?', value) + +def escape_cdata(cdata): + """Escape a string for an XML CDATA section.""" + return xml_safe(cdata).replace(']]>', ']]>]]>>> nice_classname(Exception()) # doctest: +ELLIPSIS + '...Exception' + >>> nice_classname(Exception) # doctest: +ELLIPSIS + '...Exception' + + """ + if inspect.isclass(obj): + cls_name = obj.__name__ + else: + cls_name = obj.__class__.__name__ + mod = inspect.getmodule(obj) + if mod: + name = mod.__name__ + # jython + if name.startswith('org.python.core.'): + name = name[len('org.python.core.'):] + return "%s.%s" % (name, cls_name) + else: + return cls_name + +def exc_message(exc_info): + """Return the exception's message.""" + exc = exc_info[1] + if exc is None: + # str exception + result = exc_info[0] + else: + try: + result = str(exc) + except UnicodeEncodeError: + try: + result = unicode(exc) + except UnicodeError: + # Fallback to args as neither str nor + # unicode(Exception(u'\xe6')) work in Python < 2.6 + result = exc.args[0] + result = force_unicode(result, 'UTF-8') + return xml_safe(result) + +class Tee(object): + def __init__(self, encoding, *args): + self._encoding = encoding + self._streams = args + + def write(self, data): + data = force_unicode(data, self._encoding) + for s in self._streams: + s.write(data) + + def writelines(self, lines): + for line in lines: + self.write(line) + + def flush(self): + for s in self._streams: + s.flush() + + def isatty(self): + return False + + +class Xunit(Plugin): + """This plugin provides test results in the standard XUnit XML format.""" + name = 'xunit' + score = 1500 + encoding = 'UTF-8' + error_report_file = None + + def __init__(self): + super(Xunit, self).__init__() + self._capture_stack = [] + self._currentStdout = None + self._currentStderr = None + + def _timeTaken(self): + if hasattr(self, '_timer'): + taken = time() - self._timer + else: + # test died before it ran (probably error in setup()) + # or success/failure added before test started probably + # due to custom TestResult munging + taken = 0.0 + return taken + + def _quoteattr(self, attr): + """Escape an XML attribute. Value can be unicode.""" + attr = xml_safe(attr) + return saxutils.quoteattr(attr) + + def options(self, parser, env): + """Sets additional command line options.""" + Plugin.options(self, parser, env) + parser.add_option( + '--xunit-file', action='store', + dest='xunit_file', metavar="FILE", + default=env.get('NOSE_XUNIT_FILE', 'nosetests.xml'), + help=("Path to xml file to store the xunit report in. " + "Default is nosetests.xml in the working directory " + "[NOSE_XUNIT_FILE]")) + + parser.add_option( + '--xunit-testsuite-name', action='store', + dest='xunit_testsuite_name', metavar="PACKAGE", + default=env.get('NOSE_XUNIT_TESTSUITE_NAME', 'nosetests'), + help=("Name of the testsuite in the xunit xml, generated by plugin. " + "Default test suite name is nosetests.")) + + def configure(self, options, config): + """Configures the xunit plugin.""" + Plugin.configure(self, options, config) + self.config = config + if self.enabled: + self.stats = {'errors': 0, + 'failures': 0, + 'passes': 0, + 'skipped': 0 + } + self.errorlist = [] + self.error_report_file_name = os.path.realpath(options.xunit_file) + self.xunit_testsuite_name = options.xunit_testsuite_name + + def report(self, stream): + """Writes an Xunit-formatted XML file + + The file includes a report of test errors and failures. + + """ + self.error_report_file = codecs.open(self.error_report_file_name, 'w', + self.encoding, 'replace') + self.stats['encoding'] = self.encoding + self.stats['testsuite_name'] = self.xunit_testsuite_name + self.stats['total'] = (self.stats['errors'] + self.stats['failures'] + + self.stats['passes'] + self.stats['skipped']) + self.error_report_file.write( + u'' + u'' % self.stats) + self.error_report_file.write(u''.join([force_unicode(e, self.encoding) + for e in self.errorlist])) + self.error_report_file.write(u'') + self.error_report_file.close() + if self.config.verbosity > 1: + stream.writeln("-" * 70) + stream.writeln("XML: %s" % self.error_report_file.name) + + def _startCapture(self): + self._capture_stack.append((sys.stdout, sys.stderr)) + self._currentStdout = StringIO() + self._currentStderr = StringIO() + sys.stdout = Tee(self.encoding, self._currentStdout, sys.stdout) + sys.stderr = Tee(self.encoding, self._currentStderr, sys.stderr) + + def startContext(self, context): + self._startCapture() + + def stopContext(self, context): + self._endCapture() + + def beforeTest(self, test): + """Initializes a timer before starting a test.""" + self._timer = time() + self._startCapture() + + def _endCapture(self): + if self._capture_stack: + sys.stdout, sys.stderr = self._capture_stack.pop() + + def afterTest(self, test): + self._endCapture() + self._currentStdout = None + self._currentStderr = None + + def finalize(self, test): + while self._capture_stack: + self._endCapture() + + def _getCapturedStdout(self): + if self._currentStdout: + value = self._currentStdout.getvalue() + if value: + return '' % escape_cdata( + value) + return '' + + def _getCapturedStderr(self): + if self._currentStderr: + value = self._currentStderr.getvalue() + if value: + return '' % escape_cdata( + value) + return '' + + def addError(self, test, err, capt=None): + """Add error output to Xunit report. + """ + taken = self._timeTaken() + + if issubclass(err[0], SkipTest): + type = 'skipped' + self.stats['skipped'] += 1 + else: + type = 'error' + self.stats['errors'] += 1 + + tb = format_exception(err, self.encoding) + id = test.id() + + self.errorlist.append( + u'' + u'<%(type)s type=%(errtype)s message=%(message)s>' + u'%(systemout)s%(systemerr)s' % + {'cls': self._quoteattr(id_split(id)[0]), + 'name': self._quoteattr(id_split(id)[-1]), + 'taken': taken, + 'type': type, + 'errtype': self._quoteattr(nice_classname(err[0])), + 'message': self._quoteattr(exc_message(err)), + 'tb': escape_cdata(tb), + 'systemout': self._getCapturedStdout(), + 'systemerr': self._getCapturedStderr(), + }) + + def addFailure(self, test, err, capt=None, tb_info=None): + """Add failure output to Xunit report. + """ + taken = self._timeTaken() + tb = format_exception(err, self.encoding) + self.stats['failures'] += 1 + id = test.id() + + self.errorlist.append( + u'' + u'' + u'%(systemout)s%(systemerr)s' % + {'cls': self._quoteattr(id_split(id)[0]), + 'name': self._quoteattr(id_split(id)[-1]), + 'taken': taken, + 'errtype': self._quoteattr(nice_classname(err[0])), + 'message': self._quoteattr(exc_message(err)), + 'tb': escape_cdata(tb), + 'systemout': self._getCapturedStdout(), + 'systemerr': self._getCapturedStderr(), + }) + + def addSuccess(self, test, capt=None): + """Add success output to Xunit report. + """ + taken = self._timeTaken() + self.stats['passes'] += 1 + id = test.id() + self.errorlist.append( + '%(systemout)s%(systemerr)s' % + {'cls': self._quoteattr(id_split(id)[0]), + 'name': self._quoteattr(id_split(id)[-1]), + 'taken': taken, + 'systemout': self._getCapturedStdout(), + 'systemerr': self._getCapturedStderr(), + }) diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/xunit.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/plugins/xunit.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b91bb183f4f7a07ceb19c5216913ea062b2b59e7 GIT binary patch literal 14566 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 literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/proxy.py b/.eggs/nose-1.3.7-py2.7.egg/nose/proxy.py new file mode 100644 index 0000000..c2676cb --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/proxy.py @@ -0,0 +1,188 @@ +""" +Result Proxy +------------ + +The result proxy wraps the result instance given to each test. It +performs two functions: enabling extended error/failure reporting +and calling plugins. + +As each result event is fired, plugins are called with the same event; +however, plugins are called with the nose.case.Test instance that +wraps the actual test. So when a test fails and calls +result.addFailure(self, err), the result proxy calls +addFailure(self.test, err) for each plugin. This allows plugins to +have a single stable interface for all test types, and also to +manipulate the test object itself by setting the `test` attribute of +the nose.case.Test that they receive. +""" +import logging +from nose.config import Config + + +log = logging.getLogger(__name__) + + +def proxied_attribute(local_attr, proxied_attr, doc): + """Create a property that proxies attribute ``proxied_attr`` through + the local attribute ``local_attr``. + """ + def fget(self): + return getattr(getattr(self, local_attr), proxied_attr) + def fset(self, value): + setattr(getattr(self, local_attr), proxied_attr, value) + def fdel(self): + delattr(getattr(self, local_attr), proxied_attr) + return property(fget, fset, fdel, doc) + + +class ResultProxyFactory(object): + """Factory for result proxies. Generates a ResultProxy bound to each test + and the result passed to the test. + """ + def __init__(self, config=None): + if config is None: + config = Config() + self.config = config + self.__prepared = False + self.__result = None + + def __call__(self, result, test): + """Return a ResultProxy for the current test. + + On first call, plugins are given a chance to replace the + result used for the remaining tests. If a plugin returns a + value from prepareTestResult, that object will be used as the + result for all tests. + """ + if not self.__prepared: + self.__prepared = True + plug_result = self.config.plugins.prepareTestResult(result) + if plug_result is not None: + self.__result = result = plug_result + if self.__result is not None: + result = self.__result + return ResultProxy(result, test, config=self.config) + + +class ResultProxy(object): + """Proxy to TestResults (or other results handler). + + One ResultProxy is created for each nose.case.Test. The result + proxy calls plugins with the nose.case.Test instance (instead of + the wrapped test case) as each result call is made. Finally, the + real result method is called, also with the nose.case.Test + instance as the test parameter. + + """ + def __init__(self, result, test, config=None): + if config is None: + config = Config() + self.config = config + self.plugins = config.plugins + self.result = result + self.test = test + + def __repr__(self): + return repr(self.result) + + def _prepareErr(self, err): + if not isinstance(err[1], Exception) and isinstance(err[0], type): + # Turn value back into an Exception (required in Python 3.x). + # Plugins do all sorts of crazy things with exception values. + # Convert it to a custom subclass of Exception with the same + # name as the actual exception to make it print correctly. + value = type(err[0].__name__, (Exception,), {})(err[1]) + err = (err[0], value, err[2]) + return err + + def assertMyTest(self, test): + # The test I was called with must be my .test or my + # .test's .test. or my .test.test's .case + + case = getattr(self.test, 'test', None) + assert (test is self.test + or test is case + or test is getattr(case, '_nose_case', None)), ( + "ResultProxy for %r (%s) was called with test %r (%s)" + % (self.test, id(self.test), test, id(test))) + + def afterTest(self, test): + self.assertMyTest(test) + self.plugins.afterTest(self.test) + if hasattr(self.result, "afterTest"): + self.result.afterTest(self.test) + + def beforeTest(self, test): + self.assertMyTest(test) + self.plugins.beforeTest(self.test) + if hasattr(self.result, "beforeTest"): + self.result.beforeTest(self.test) + + def addError(self, test, err): + self.assertMyTest(test) + plugins = self.plugins + plugin_handled = plugins.handleError(self.test, err) + if plugin_handled: + return + # test.passed is set in result, to account for error classes + formatted = plugins.formatError(self.test, err) + if formatted is not None: + err = formatted + plugins.addError(self.test, err) + self.result.addError(self.test, self._prepareErr(err)) + if not self.result.wasSuccessful() and self.config.stopOnError: + self.shouldStop = True + + def addFailure(self, test, err): + self.assertMyTest(test) + plugins = self.plugins + plugin_handled = plugins.handleFailure(self.test, err) + if plugin_handled: + return + self.test.passed = False + formatted = plugins.formatFailure(self.test, err) + if formatted is not None: + err = formatted + plugins.addFailure(self.test, err) + self.result.addFailure(self.test, self._prepareErr(err)) + if self.config.stopOnError: + self.shouldStop = True + + def addSkip(self, test, reason): + # 2.7 compat shim + from nose.plugins.skip import SkipTest + self.assertMyTest(test) + plugins = self.plugins + if not isinstance(reason, Exception): + # for Python 3.2+ + reason = Exception(reason) + plugins.addError(self.test, (SkipTest, reason, None)) + self.result.addSkip(self.test, reason) + + def addSuccess(self, test): + self.assertMyTest(test) + self.plugins.addSuccess(self.test) + self.result.addSuccess(self.test) + + def startTest(self, test): + self.assertMyTest(test) + self.plugins.startTest(self.test) + self.result.startTest(self.test) + + def stop(self): + self.result.stop() + + def stopTest(self, test): + self.assertMyTest(test) + self.plugins.stopTest(self.test) + self.result.stopTest(self.test) + + # proxied attributes + shouldStop = proxied_attribute('result', 'shouldStop', + """Should the test run stop?""") + errors = proxied_attribute('result', 'errors', + """Tests that raised an exception""") + failures = proxied_attribute('result', 'failures', + """Tests that failed""") + testsRun = proxied_attribute('result', 'testsRun', + """Number of tests run""") diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/proxy.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/proxy.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5a8b1c0a5dc53d94c13b84cf1db6b4706d648866 GIT binary patch literal 8780 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 p?+ELnPuz>oj{ literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/pyversion.py b/.eggs/nose-1.3.7-py2.7.egg/nose/pyversion.py new file mode 100644 index 0000000..091238d --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/pyversion.py @@ -0,0 +1,215 @@ +""" +This module contains fixups for using nose under different versions of Python. +""" +import sys +import os +import traceback +import types +import inspect +import nose.util + +__all__ = ['make_instancemethod', 'cmp_to_key', 'sort_list', 'ClassType', + 'TypeType', 'UNICODE_STRINGS', 'unbound_method', 'ismethod', + 'bytes_', 'is_base_exception', 'force_unicode', 'exc_to_unicode', + 'format_exception'] + +# In Python 3.x, all strings are unicode (the call to 'unicode()' in the 2.x +# source will be replaced with 'str()' when running 2to3, so this test will +# then become true) +UNICODE_STRINGS = (type(unicode()) == type(str())) + +if sys.version_info[:2] < (3, 0): + def force_unicode(s, encoding='UTF-8'): + try: + s = unicode(s) + except UnicodeDecodeError: + s = str(s).decode(encoding, 'replace') + + return s +else: + def force_unicode(s, encoding='UTF-8'): + return str(s) + +# new.instancemethod() is obsolete for new-style classes (Python 3.x) +# We need to use descriptor methods instead. +try: + import new + def make_instancemethod(function, instance): + return new.instancemethod(function.im_func, instance, + instance.__class__) +except ImportError: + def make_instancemethod(function, instance): + return function.__get__(instance, instance.__class__) + +# To be forward-compatible, we do all list sorts using keys instead of cmp +# functions. However, part of the unittest.TestLoader API involves a +# user-provideable cmp function, so we need some way to convert that. +def cmp_to_key(mycmp): + 'Convert a cmp= function into a key= function' + class Key(object): + def __init__(self, obj): + self.obj = obj + def __lt__(self, other): + return mycmp(self.obj, other.obj) < 0 + def __gt__(self, other): + return mycmp(self.obj, other.obj) > 0 + def __eq__(self, other): + return mycmp(self.obj, other.obj) == 0 + return Key + +# Python 2.3 also does not support list-sorting by key, so we need to convert +# keys to cmp functions if we're running on old Python.. +if sys.version_info < (2, 4): + def sort_list(l, key, reverse=False): + if reverse: + return l.sort(lambda a, b: cmp(key(b), key(a))) + else: + return l.sort(lambda a, b: cmp(key(a), key(b))) +else: + def sort_list(l, key, reverse=False): + return l.sort(key=key, reverse=reverse) + +# In Python 3.x, all objects are "new style" objects descended from 'type', and +# thus types.ClassType and types.TypeType don't exist anymore. For +# compatibility, we make sure they still work. +if hasattr(types, 'ClassType'): + ClassType = types.ClassType + TypeType = types.TypeType +else: + ClassType = type + TypeType = type + +# The following emulates the behavior (we need) of an 'unbound method' under +# Python 3.x (namely, the ability to have a class associated with a function +# definition so that things can do stuff based on its associated class) +class UnboundMethod: + def __init__(self, cls, func): + # Make sure we have all the same attributes as the original function, + # so that the AttributeSelector plugin will work correctly... + self.__dict__ = func.__dict__.copy() + self._func = func + self.__self__ = UnboundSelf(cls) + if sys.version_info < (3, 0): + self.im_class = cls + self.__doc__ = getattr(func, '__doc__', None) + + def address(self): + cls = self.__self__.cls + modname = cls.__module__ + module = sys.modules[modname] + filename = getattr(module, '__file__', None) + if filename is not None: + filename = os.path.abspath(filename) + return (nose.util.src(filename), modname, "%s.%s" % (cls.__name__, + self._func.__name__)) + + def __call__(self, *args, **kwargs): + return self._func(*args, **kwargs) + + def __getattr__(self, attr): + return getattr(self._func, attr) + + def __repr__(self): + return '' % (self.__self__.cls.__name__, + self._func.__name__) + +class UnboundSelf: + def __init__(self, cls): + self.cls = cls + + # We have to do this hackery because Python won't let us override the + # __class__ attribute... + def __getattribute__(self, attr): + if attr == '__class__': + return self.cls + else: + return object.__getattribute__(self, attr) + +def unbound_method(cls, func): + if inspect.ismethod(func): + return func + if not inspect.isfunction(func): + raise TypeError('%s is not a function' % (repr(func),)) + return UnboundMethod(cls, func) + +def ismethod(obj): + return inspect.ismethod(obj) or isinstance(obj, UnboundMethod) + + +# Make a pseudo-bytes function that can be called without the encoding arg: +if sys.version_info >= (3, 0): + def bytes_(s, encoding='utf8'): + if isinstance(s, bytes): + return s + return bytes(s, encoding) +else: + def bytes_(s, encoding=None): + return str(s) + + +if sys.version_info[:2] >= (2, 6): + def isgenerator(o): + if isinstance(o, UnboundMethod): + o = o._func + return inspect.isgeneratorfunction(o) or inspect.isgenerator(o) +else: + try: + from compiler.consts import CO_GENERATOR + except ImportError: + # IronPython doesn't have a complier module + CO_GENERATOR=0x20 + + def isgenerator(func): + try: + return func.func_code.co_flags & CO_GENERATOR != 0 + except AttributeError: + return False + +# Make a function to help check if an exception is derived from BaseException. +# In Python 2.4, we just use Exception instead. +if sys.version_info[:2] < (2, 5): + def is_base_exception(exc): + return isinstance(exc, Exception) +else: + def is_base_exception(exc): + return isinstance(exc, BaseException) + +if sys.version_info[:2] < (3, 0): + def exc_to_unicode(ev, encoding='utf-8'): + if is_base_exception(ev): + if not hasattr(ev, '__unicode__'): + # 2.5- + if not hasattr(ev, 'message'): + # 2.4 + msg = len(ev.args) and ev.args[0] or '' + else: + msg = ev.message + msg = force_unicode(msg, encoding=encoding) + clsname = force_unicode(ev.__class__.__name__, + encoding=encoding) + ev = u'%s: %s' % (clsname, msg) + elif not isinstance(ev, unicode): + ev = repr(ev) + + return force_unicode(ev, encoding=encoding) +else: + def exc_to_unicode(ev, encoding='utf-8'): + return str(ev) + +def format_exception(exc_info, encoding='UTF-8'): + ec, ev, tb = exc_info + + # Our exception object may have been turned into a string, and Python 3's + # traceback.format_exception() doesn't take kindly to that (it expects an + # actual exception object). So we work around it, by doing the work + # ourselves if ev is not an exception object. + if not is_base_exception(ev): + tb_data = force_unicode( + ''.join(traceback.format_tb(tb)), + encoding) + ev = exc_to_unicode(ev) + return tb_data + ev + else: + return force_unicode( + ''.join(traceback.format_exception(*exc_info)), + encoding) diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/pyversion.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/pyversion.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f9edbf7bd85068dddd4a56ad659f40db99f2ac55 GIT binary patch literal 10195 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 h*Qg(>Phx$tF)`' % type(exc).__name__ + + +class TextTestResult(_TextTestResult): + """Text test result that extends unittest's default test result + support for a configurable set of errorClasses (eg, Skip, + Deprecated, TODO) that extend the errors/failures/success triad. + """ + def __init__(self, stream, descriptions, verbosity, config=None, + errorClasses=None): + if errorClasses is None: + errorClasses = {} + self.errorClasses = errorClasses + if config is None: + config = Config() + self.config = config + _TextTestResult.__init__(self, stream, descriptions, verbosity) + + def addSkip(self, test, reason): + # 2.7 skip compat + from nose.plugins.skip import SkipTest + if SkipTest in self.errorClasses: + storage, label, isfail = self.errorClasses[SkipTest] + storage.append((test, reason)) + self.printLabel(label, (SkipTest, reason, None)) + + def addError(self, test, err): + """Overrides normal addError to add support for + errorClasses. If the exception is a registered class, the + error will be added to the list for that class, not errors. + """ + ec, ev, tb = err + try: + exc_info = self._exc_info_to_string(err, test) + except TypeError: + # 2.3 compat + exc_info = self._exc_info_to_string(err) + for cls, (storage, label, isfail) in self.errorClasses.items(): + #if 'Skip' in cls.__name__ or 'Skip' in ec.__name__: + # from nose.tools import set_trace + # set_trace() + if isclass(ec) and issubclass(ec, cls): + if isfail: + test.passed = False + storage.append((test, exc_info)) + self.printLabel(label, err) + return + self.errors.append((test, exc_info)) + test.passed = False + self.printLabel('ERROR') + + # override to bypass changes in 2.7 + def getDescription(self, test): + if self.descriptions: + return test.shortDescription() or str(test) + else: + return str(test) + + def printLabel(self, label, err=None): + # Might get patched into a streamless result + stream = getattr(self, 'stream', None) + if stream is not None: + if self.showAll: + message = [label] + if err: + detail = _exception_detail(err[1]) + if detail: + message.append(detail) + stream.writeln(": ".join(message)) + elif self.dots: + stream.write(label[:1]) + + def printErrors(self): + """Overrides to print all errorClasses errors as well. + """ + _TextTestResult.printErrors(self) + for cls in self.errorClasses.keys(): + storage, label, isfail = self.errorClasses[cls] + if isfail: + self.printErrorList(label, storage) + # Might get patched into a result with no config + if hasattr(self, 'config'): + self.config.plugins.report(self.stream) + + def printSummary(self, start, stop): + """Called by the test runner to print the final summary of test + run results. + """ + write = self.stream.write + writeln = self.stream.writeln + taken = float(stop - start) + run = self.testsRun + plural = run != 1 and "s" or "" + + writeln(self.separator2) + writeln("Ran %s test%s in %.3fs" % (run, plural, taken)) + writeln() + + summary = {} + eckeys = self.errorClasses.keys() + for cls in eckeys: + storage, label, isfail = self.errorClasses[cls] + count = len(storage) + if not count: + continue + summary[label] = count + if len(self.failures): + summary['failures'] = len(self.failures) + if len(self.errors): + summary['errors'] = len(self.errors) + + if not self.wasSuccessful(): + write("FAILED") + else: + write("OK") + items = summary.items() + if items: + items.sort() + write(" (") + write(", ".join(["%s=%s" % (label, count) for + label, count in items])) + writeln(")") + else: + writeln() + + def wasSuccessful(self): + """Overrides to check that there are no errors in errorClasses + lists that are marked as errors and should cause a run to + fail. + """ + if self.errors or self.failures: + return False + for cls in self.errorClasses.keys(): + storage, label, isfail = self.errorClasses[cls] + if not isfail: + continue + if storage: + return False + return True + + def _addError(self, test, err): + try: + exc_info = self._exc_info_to_string(err, test) + except TypeError: + # 2.3: does not take test arg + exc_info = self._exc_info_to_string(err) + self.errors.append((test, exc_info)) + if self.showAll: + self.stream.write('ERROR') + elif self.dots: + self.stream.write('E') + + def _exc_info_to_string(self, err, test=None): + # 2.7 skip compat + from nose.plugins.skip import SkipTest + if isclass(err[0]) and issubclass(err[0], SkipTest): + return str(err[1]) + # 2.3/2.4 -- 2.4 passes test, 2.3 does not + try: + return _TextTestResult._exc_info_to_string(self, err, test) + except TypeError: + # 2.3: does not take test arg + return _TextTestResult._exc_info_to_string(self, err) + + +def ln(*arg, **kw): + from warnings import warn + warn("ln() has moved to nose.util from nose.result and will be removed " + "from nose.result in a future release. Please update your imports ", + DeprecationWarning) + return _ln(*arg, **kw) + + diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/result.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/result.pyc new file mode 100644 index 0000000000000000000000000000000000000000..16f4d5819a4e5bed7ae4a9899d7239a5ba96ba36 GIT binary patch literal 7254 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 G{_r0ivoLx9 literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/selector.py b/.eggs/nose-1.3.7-py2.7.egg/nose/selector.py new file mode 100644 index 0000000..b63f7af --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/selector.py @@ -0,0 +1,251 @@ +""" +Test Selection +-------------- + +Test selection is handled by a Selector. The test loader calls the +appropriate selector method for each object it encounters that it +thinks may be a test. +""" +import logging +import os +import unittest +from nose.config import Config +from nose.util import split_test_name, src, getfilename, getpackage, ispackage, is_executable + +log = logging.getLogger(__name__) + +__all__ = ['Selector', 'defaultSelector', 'TestAddress'] + + +# for efficiency and easier mocking +op_join = os.path.join +op_basename = os.path.basename +op_exists = os.path.exists +op_splitext = os.path.splitext +op_isabs = os.path.isabs +op_abspath = os.path.abspath + + +class Selector(object): + """Core test selector. Examines test candidates and determines whether, + given the specified configuration, the test candidate should be selected + as a test. + """ + def __init__(self, config): + if config is None: + config = Config() + self.configure(config) + + def configure(self, config): + self.config = config + self.exclude = config.exclude + self.ignoreFiles = config.ignoreFiles + self.include = config.include + self.plugins = config.plugins + self.match = config.testMatch + + def matches(self, name): + """Does the name match my requirements? + + To match, a name must match config.testMatch OR config.include + and it must not match config.exclude + """ + return ((self.match.search(name) + or (self.include and + filter(None, + [inc.search(name) for inc in self.include]))) + and ((not self.exclude) + or not filter(None, + [exc.search(name) for exc in self.exclude]) + )) + + def wantClass(self, cls): + """Is the class a wanted test class? + + A class must be a unittest.TestCase subclass, or match test name + requirements. Classes that start with _ are always excluded. + """ + declared = getattr(cls, '__test__', None) + if declared is not None: + wanted = declared + else: + wanted = (not cls.__name__.startswith('_') + and (issubclass(cls, unittest.TestCase) + or self.matches(cls.__name__))) + + plug_wants = self.plugins.wantClass(cls) + if plug_wants is not None: + log.debug("Plugin setting selection of %s to %s", cls, plug_wants) + wanted = plug_wants + log.debug("wantClass %s? %s", cls, wanted) + return wanted + + def wantDirectory(self, dirname): + """Is the directory a wanted test directory? + + All package directories match, so long as they do not match exclude. + All other directories must match test requirements. + """ + tail = op_basename(dirname) + if ispackage(dirname): + wanted = (not self.exclude + or not filter(None, + [exc.search(tail) for exc in self.exclude] + )) + else: + wanted = (self.matches(tail) + or (self.config.srcDirs + and tail in self.config.srcDirs)) + plug_wants = self.plugins.wantDirectory(dirname) + if plug_wants is not None: + log.debug("Plugin setting selection of %s to %s", + dirname, plug_wants) + wanted = plug_wants + log.debug("wantDirectory %s? %s", dirname, wanted) + return wanted + + def wantFile(self, file): + """Is the file a wanted test file? + + The file must be a python source file and match testMatch or + include, and not match exclude. Files that match ignore are *never* + wanted, regardless of plugin, testMatch, include or exclude settings. + """ + # never, ever load files that match anything in ignore + # (.* _* and *setup*.py by default) + base = op_basename(file) + ignore_matches = [ ignore_this for ignore_this in self.ignoreFiles + if ignore_this.search(base) ] + if ignore_matches: + log.debug('%s matches ignoreFiles pattern; skipped', + base) + return False + if not self.config.includeExe and is_executable(file): + log.info('%s is executable; skipped', file) + return False + dummy, ext = op_splitext(base) + pysrc = ext == '.py' + + wanted = pysrc and self.matches(base) + plug_wants = self.plugins.wantFile(file) + if plug_wants is not None: + log.debug("plugin setting want %s to %s", file, plug_wants) + wanted = plug_wants + log.debug("wantFile %s? %s", file, wanted) + return wanted + + def wantFunction(self, function): + """Is the function a test function? + """ + try: + if hasattr(function, 'compat_func_name'): + funcname = function.compat_func_name + else: + funcname = function.__name__ + except AttributeError: + # not a function + return False + declared = getattr(function, '__test__', None) + if declared is not None: + wanted = declared + else: + wanted = not funcname.startswith('_') and self.matches(funcname) + plug_wants = self.plugins.wantFunction(function) + if plug_wants is not None: + wanted = plug_wants + log.debug("wantFunction %s? %s", function, wanted) + return wanted + + def wantMethod(self, method): + """Is the method a test method? + """ + try: + method_name = method.__name__ + except AttributeError: + # not a method + return False + if method_name.startswith('_'): + # never collect 'private' methods + return False + declared = getattr(method, '__test__', None) + if declared is not None: + wanted = declared + else: + wanted = self.matches(method_name) + plug_wants = self.plugins.wantMethod(method) + if plug_wants is not None: + wanted = plug_wants + log.debug("wantMethod %s? %s", method, wanted) + return wanted + + def wantModule(self, module): + """Is the module a test module? + + The tail of the module name must match test requirements. One exception: + we always want __main__. + """ + declared = getattr(module, '__test__', None) + if declared is not None: + wanted = declared + else: + wanted = self.matches(module.__name__.split('.')[-1]) \ + or module.__name__ == '__main__' + plug_wants = self.plugins.wantModule(module) + if plug_wants is not None: + wanted = plug_wants + log.debug("wantModule %s? %s", module, wanted) + return wanted + +defaultSelector = Selector + + +class TestAddress(object): + """A test address represents a user's request to run a particular + test. The user may specify a filename or module (or neither), + and/or a callable (a class, function, or method). The naming + format for test addresses is: + + filename_or_module:callable + + Filenames that are not absolute will be made absolute relative to + the working dir. + + The filename or module part will be considered a module name if it + doesn't look like a file, that is, if it doesn't exist on the file + system and it doesn't contain any directory separators and it + doesn't end in .py. + + Callables may be a class name, function name, method name, or + class.method specification. + """ + def __init__(self, name, workingDir=None): + if workingDir is None: + workingDir = os.getcwd() + self.name = name + self.workingDir = workingDir + self.filename, self.module, self.call = split_test_name(name) + log.debug('Test name %s resolved to file %s, module %s, call %s', + name, self.filename, self.module, self.call) + if self.filename is None: + if self.module is not None: + self.filename = getfilename(self.module, self.workingDir) + if self.filename: + self.filename = src(self.filename) + if not op_isabs(self.filename): + self.filename = op_abspath(op_join(workingDir, + self.filename)) + if self.module is None: + self.module = getpackage(self.filename) + log.debug( + 'Final resolution of test name %s: file %s module %s call %s', + name, self.filename, self.module, self.call) + + def totuple(self): + return (self.filename, self.module, self.call) + + def __str__(self): + return self.name + + def __repr__(self): + return "%s: (%s, %s, %s)" % (self.name, self.filename, + self.module, self.call) diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/selector.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/selector.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d463c93fb09bd62a9c9e003a65951f3f11e4cdf9 GIT binary patch literal 9445 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 Xry~DOc%8~(WwB;c5>}T#t5^RED=mjn literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/sphinx/__init__.py b/.eggs/nose-1.3.7-py2.7.egg/nose/sphinx/__init__.py new file mode 100644 index 0000000..2ae2839 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/sphinx/__init__.py @@ -0,0 +1 @@ +pass diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/sphinx/__init__.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/sphinx/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..201d23406ab1ad06fdfd55542f016b92fda3ad90 GIT binary patch literal 175 zcmZSn%*)j%ogJ3U00oRd+5w1*S%5?e14FO|NW@PANHCxg#SuU;{m|mnqGJ8@qSW;K zqRPagr=y!_%+T|+%%J#*cHN+UgUkSJJC ozqlYHGp|BFK0Y%qvm`!V52%#`Xt+&oeoARhsvXD)#X!se03=K)!vFvP literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/sphinx/pluginopts.py b/.eggs/nose-1.3.7-py2.7.egg/nose/sphinx/pluginopts.py new file mode 100644 index 0000000..d2b284a --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/sphinx/pluginopts.py @@ -0,0 +1,189 @@ +""" +Adds a sphinx directive that can be used to automatically document a plugin. + +this:: + + .. autoplugin :: nose.plugins.foo + :plugin: Pluggy + +produces:: + + .. automodule :: nose.plugins.foo + + Options + ------- + + .. cmdoption :: --foo=BAR, --fooble=BAR + + Do the foo thing to the new thing. + + Plugin + ------ + + .. autoclass :: nose.plugins.foo.Pluggy + :members: + + Source + ------ + + .. include :: path/to/nose/plugins/foo.py + :literal: + +""" +import os +try: + from docutils import nodes, utils + from docutils.statemachine import ViewList + from docutils.parsers.rst import directives +except ImportError: + pass # won't run anyway + +from nose.util import resolve_name +from nose.plugins.base import Plugin +from nose.plugins.manager import BuiltinPluginManager +from nose.config import Config +from nose.core import TestProgram +from inspect import isclass + + +def autoplugin_directive(dirname, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + mod_name = arguments[0] + mod = resolve_name(mod_name) + plug_name = options.get('plugin', None) + if plug_name: + obj = getattr(mod, plug_name) + else: + for entry in dir(mod): + obj = getattr(mod, entry) + if isclass(obj) and issubclass(obj, Plugin) and obj is not Plugin: + plug_name = '%s.%s' % (mod_name, entry) + break + + # mod docstring + rst = ViewList() + rst.append('.. automodule :: %s\n' % mod_name, '') + rst.append('', '') + + # options + rst.append('Options', '') + rst.append('-------', '') + rst.append('', '') + + plug = obj() + opts = OptBucket() + plug.options(opts, {}) + for opt in opts: + rst.append(opt.options(), '') + rst.append(' \n', '') + rst.append(' ' + opt.help + '\n', '') + rst.append('\n', '') + + # plugin class + rst.append('Plugin', '') + rst.append('------', '') + rst.append('', '') + + rst.append('.. autoclass :: %s\n' % plug_name, '') + rst.append(' :members:\n', '') + rst.append(' :show-inheritance:\n', '') + rst.append('', '') + + # source + rst.append('Source', '') + rst.append('------', '') + rst.append( + '.. include :: %s\n' % utils.relative_path( + state_machine.document['source'], + os.path.abspath(mod.__file__.replace('.pyc', '.py'))), + '') + rst.append(' :literal:\n', '') + rst.append('', '') + + node = nodes.section() + node.document = state.document + surrounding_title_styles = state.memo.title_styles + surrounding_section_level = state.memo.section_level + state.memo.title_styles = [] + state.memo.section_level = 0 + state.nested_parse(rst, 0, node, match_titles=1) + state.memo.title_styles = surrounding_title_styles + state.memo.section_level = surrounding_section_level + + return node.children + + +def autohelp_directive(dirname, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + """produces rst from nose help""" + config = Config(parserClass=OptBucket, + plugins=BuiltinPluginManager()) + parser = config.getParser(TestProgram.usage()) + rst = ViewList() + for line in parser.format_help().split('\n'): + rst.append(line, '') + + rst.append('Options', '') + rst.append('-------', '') + rst.append('', '') + for opt in parser: + rst.append(opt.options(), '') + rst.append(' \n', '') + rst.append(' ' + opt.help + '\n', '') + rst.append('\n', '') + node = nodes.section() + node.document = state.document + surrounding_title_styles = state.memo.title_styles + surrounding_section_level = state.memo.section_level + state.memo.title_styles = [] + state.memo.section_level = 0 + state.nested_parse(rst, 0, node, match_titles=1) + state.memo.title_styles = surrounding_title_styles + state.memo.section_level = surrounding_section_level + + return node.children + + +class OptBucket(object): + def __init__(self, doc=None, prog='nosetests'): + self.opts = [] + self.doc = doc + self.prog = prog + + def __iter__(self): + return iter(self.opts) + + def format_help(self): + return self.doc.replace('%prog', self.prog).replace(':\n', '::\n') + + def add_option(self, *arg, **kw): + self.opts.append(Opt(*arg, **kw)) + + +class Opt(object): + def __init__(self, *arg, **kw): + self.opts = arg + self.action = kw.pop('action', None) + self.default = kw.pop('default', None) + self.metavar = kw.pop('metavar', None) + self.help = kw.pop('help', None) + + def options(self): + buf = [] + for optstring in self.opts: + desc = optstring + if self.action not in ('store_true', 'store_false'): + desc += '=%s' % self.meta(optstring) + buf.append(desc) + return '.. cmdoption :: ' + ', '.join(buf) + + def meta(self, optstring): + # FIXME optparser default metavar? + return self.metavar or 'DEFAULT' + + +def setup(app): + app.add_directive('autoplugin', + autoplugin_directive, 1, (1, 0, 1), + plugin=directives.unchanged) + app.add_directive('autohelp', autohelp_directive, 0, (0, 0, 1)) diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/sphinx/pluginopts.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/sphinx/pluginopts.pyc new file mode 100644 index 0000000000000000000000000000000000000000..754196271c7aa57b5ff14f41317e08aaa813fcd7 GIT binary patch literal 7073 zcmcgxOLH7o6+S&9OPY~njoyBQN|VGyKr|vrfkBmo#Ige^Y{j&bD2NJOt?t&SM?Kx+ zzCE^7B`qjt%?379L9u`xTQ>X!{tg><@O|g@%t!*3mgK&^_uO+|=kc9$uj>DtYySH7 z(HEgqKiBa8hxp8lBNB=1p>!mwN$SX+BPUzhtV>#xUS0O;(wmUI3313YA?Y>gP0HS+ zZC{ggN_x|>H!aR?wjdL6LynqK_~JND=E#>EG%0CQdNZ;&V+T!1IxD?7*_*TNX-Th3 zZ(jE1ZMz|9OL_~kw_w{%Nf)KJBzsG?JtOI|^j2hV1?^e+8b?@_Xih6@5?z=0h8$qs zc~V}8{9^B>M6DrpVMM(p(V`Bz&C@?wU!qX{0iiTMiX!6%uIV2p*|8fXMI4sNv)C;U zgVGIy%-xUOfr%rx%-vv6=Dnay!XQmg+$awRy*Mi|x}Od@N!D&Q%frNMZ8e*2yRF=| z!`<3)v)sgO+cfQiJa4-A*|LN!_c12uoG7i?FY;&*#&(|JL_N^b`2S3Vai8|fB+m?L z8}GLkUHU~$ z&SvCvMv4!mtjj5SXOuWASs=&1l5&DX47~rz1}GR;*?kkIKYyNgFsPO@H3u?tOG zKWeZZVd{pQ&dEVdR+7$e@OUZ!fk-DV;rkF{p2aEy z5Q4HSv=fl$QB?3OLXa8k>)G`1o?<8^5cKvp7|j3_Wp#?Gz@~{e*`}8WnN2PPEmvAPmC1o--&q8r6-r zHtY_uD&oAVC{40B%ggKNtH^$SaDbUrko##K9{FW_Tx#Gkkauji#hTv>ur`!Ih=FzS^zFuxfTMLx(PL~?5*Ln+a- z&Uapr*g85z3xixyHa|Cr)tj9n?&QTuP=rAdY(g`++3cT`hk3RUXU{gx`#efF_6Ne)C z%GoSq0fHmqDdHmo^HK_Y2H2`#5jKo!afx)deJ9 zGfs8jDm+*KzZe2MLgjhb_c+0SVZVkNZysG1N@<=R0m>t&d$bSrP+;g|B1z%ViEVmm zko8&27O%5-gT);b>$FYpTP)sW zK}hoGp5C`ve22w%S-iz!1BHSVkO_IGR;{GGciF{YK>YH4K<>LNe#qiSD6Y=&7qJ>0 zp8^`YJtMXG9tx?`MOWasuQ*>(kKC6$)`e9+AqVoOj_)2m^A3s_w?#NHJWL(> z>l$yk$eOgq)Heqt`Y*^C}9OzKD+!c?~KkYg*Bq z{E24wJL??geIJDlxp}B6fN^)UOIs#R54?}b_!AUYrv{p@?=vRIeY{B<`kChF#CF5gI4XU}dPJ4p6DU2o-D6 z06)DZ!wP)d-$!;nBI34giCAGo#Djn(0wYI6q$RW%I>n9#mcVA?R74aX1cTIG43I?! z&w@guoN8%|fBn2~)xzlKJz?<~3kJlowRw+7+aV2~Enc>kXeWQcXJ|ykz!m*fAy0t9 zQ*YxlfPF&$nIp$|9#JH@|J6M?gLB~-1|qh|GATz>Qaq4Th}9C60l>L>7hIWY3aKRe zL35tAWH*AauSpjQQGi{0qQcuzvo>X3#C}-}VoiQ*^B_n~tT)8>aUE`9W0zn1)LGtg z^+iliHlD}Z1-~j&)#FhkisMwDg#n(so8zsE6@@m%f&IaO=0Qy3%L11R9fp^-@aojX zEa z>0!NJvWf3%EbvP#^f!DK;A&Pik3sN$&O(7qlRq+!x23h0?Hxp`KjYI30XM3tMngS= zBBuMRn3+RbF^{fJ_+tR98c_q5{$c{zzxoTT93}&|h;UQlpBe}&(->`SeS9Uh|59$?^s^L1%YT5*H?YkQG4}$yrm$x@rtDK;L{2px9PuP-(Yyr7?Rui z08za<*c;07`EGkTFm2qjtTcFk`J~s+i}C?p4+@oz{^5eF*q0>+)(d~j*bhvs&qjKs zztGjQ590Rr#JRQC-cIy#HC`YD#MvtqO)AMu9}hYDLS>aj&1l@gqX>KSRz}P8LKI^) sU4=)e=-;!c#s@BzH*cVrgtF@T7O{*A%S3f`v2PKL?Z&ICt<}~405QnocK`qY literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/suite.py b/.eggs/nose-1.3.7-py2.7.egg/nose/suite.py new file mode 100644 index 0000000..a831105 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/suite.py @@ -0,0 +1,609 @@ +""" +Test Suites +----------- + +Provides a LazySuite, which is a suite whose test list is a generator +function, and ContextSuite,which can run fixtures (setup/teardown +functions or methods) for the context that contains its tests. + +""" +from __future__ import generators + +import logging +import sys +import unittest +from nose.case import Test +from nose.config import Config +from nose.proxy import ResultProxyFactory +from nose.util import isclass, resolve_name, try_run + +if sys.platform == 'cli': + if sys.version_info[:2] < (2, 6): + import clr + clr.AddReference("IronPython") + from IronPython.Runtime.Exceptions import StringException + else: + class StringException(Exception): + pass + +log = logging.getLogger(__name__) +#log.setLevel(logging.DEBUG) + +# Singleton for default value -- see ContextSuite.__init__ below +_def = object() + + +def _strclass(cls): + return "%s.%s" % (cls.__module__, cls.__name__) + +class MixedContextError(Exception): + """Error raised when a context suite sees tests from more than + one context. + """ + pass + + +class LazySuite(unittest.TestSuite): + """A suite that may use a generator as its list of tests + """ + def __init__(self, tests=()): + """Initialize the suite. tests may be an iterable or a generator + """ + super(LazySuite, self).__init__() + self._set_tests(tests) + + def __iter__(self): + return iter(self._tests) + + def __repr__(self): + return "<%s tests=generator (%s)>" % ( + _strclass(self.__class__), id(self)) + + def __hash__(self): + return object.__hash__(self) + + __str__ = __repr__ + + def addTest(self, test): + self._precache.append(test) + + # added to bypass run changes in 2.7's unittest + def run(self, result): + for test in self._tests: + if result.shouldStop: + break + test(result) + return result + + def __nonzero__(self): + log.debug("tests in %s?", id(self)) + if self._precache: + return True + if self.test_generator is None: + return False + try: + test = self.test_generator.next() + if test is not None: + self._precache.append(test) + return True + except StopIteration: + pass + return False + + def _get_tests(self): + log.debug("precache is %s", self._precache) + for test in self._precache: + yield test + if self.test_generator is None: + return + for test in self.test_generator: + yield test + + def _set_tests(self, tests): + self._precache = [] + is_suite = isinstance(tests, unittest.TestSuite) + if callable(tests) and not is_suite: + self.test_generator = tests() + elif is_suite: + # Suites need special treatment: they must be called like + # tests for their setup/teardown to run (if any) + self.addTests([tests]) + self.test_generator = None + else: + self.addTests(tests) + self.test_generator = None + + _tests = property(_get_tests, _set_tests, None, + "Access the tests in this suite. Access is through a " + "generator, so iteration may not be repeatable.") + + +class ContextSuite(LazySuite): + """A suite with context. + + A ContextSuite executes fixtures (setup and teardown functions or + methods) for the context containing its tests. + + The context may be explicitly passed. If it is not, a context (or + nested set of contexts) will be constructed by examining the tests + in the suite. + """ + failureException = unittest.TestCase.failureException + was_setup = False + was_torndown = False + classSetup = ('setup_class', 'setup_all', 'setupClass', 'setupAll', + 'setUpClass', 'setUpAll') + classTeardown = ('teardown_class', 'teardown_all', 'teardownClass', + 'teardownAll', 'tearDownClass', 'tearDownAll') + moduleSetup = ('setup_module', 'setupModule', 'setUpModule', 'setup', + 'setUp') + moduleTeardown = ('teardown_module', 'teardownModule', 'tearDownModule', + 'teardown', 'tearDown') + packageSetup = ('setup_package', 'setupPackage', 'setUpPackage') + packageTeardown = ('teardown_package', 'teardownPackage', + 'tearDownPackage') + + def __init__(self, tests=(), context=None, factory=None, + config=None, resultProxy=None, can_split=True): + log.debug("Context suite for %s (%s) (%s)", tests, context, id(self)) + self.context = context + self.factory = factory + if config is None: + config = Config() + self.config = config + self.resultProxy = resultProxy + self.has_run = False + self.can_split = can_split + self.error_context = None + super(ContextSuite, self).__init__(tests) + + def __repr__(self): + return "<%s context=%s>" % ( + _strclass(self.__class__), + getattr(self.context, '__name__', self.context)) + __str__ = __repr__ + + def id(self): + if self.error_context: + return '%s:%s' % (repr(self), self.error_context) + else: + return repr(self) + + def __hash__(self): + return object.__hash__(self) + + # 2.3 compat -- force 2.4 call sequence + def __call__(self, *arg, **kw): + return self.run(*arg, **kw) + + def exc_info(self): + """Hook for replacing error tuple output + """ + return sys.exc_info() + + def _exc_info(self): + """Bottleneck to fix up IronPython string exceptions + """ + e = self.exc_info() + if sys.platform == 'cli': + if isinstance(e[0], StringException): + # IronPython throws these StringExceptions, but + # traceback checks type(etype) == str. Make a real + # string here. + e = (str(e[0]), e[1], e[2]) + + return e + + def run(self, result): + """Run tests in suite inside of suite fixtures. + """ + # proxy the result for myself + log.debug("suite %s (%s) run called, tests: %s", id(self), self, self._tests) + #import pdb + #pdb.set_trace() + if self.resultProxy: + result, orig = self.resultProxy(result, self), result + else: + result, orig = result, result + try: + self.setUp() + except KeyboardInterrupt: + raise + except: + self.error_context = 'setup' + result.addError(self, self._exc_info()) + return + try: + for test in self._tests: + if result.shouldStop: + log.debug("stopping") + break + # each nose.case.Test will create its own result proxy + # so the cases need the original result, to avoid proxy + # chains + test(orig) + finally: + self.has_run = True + try: + self.tearDown() + except KeyboardInterrupt: + raise + except: + self.error_context = 'teardown' + result.addError(self, self._exc_info()) + + def hasFixtures(self, ctx_callback=None): + context = self.context + if context is None: + return False + if self.implementsAnyFixture(context, ctx_callback=ctx_callback): + return True + # My context doesn't have any, but its ancestors might + factory = self.factory + if factory: + ancestors = factory.context.get(self, []) + for ancestor in ancestors: + if self.implementsAnyFixture( + ancestor, ctx_callback=ctx_callback): + return True + return False + + def implementsAnyFixture(self, context, ctx_callback): + if isclass(context): + names = self.classSetup + self.classTeardown + else: + names = self.moduleSetup + self.moduleTeardown + if hasattr(context, '__path__'): + names += self.packageSetup + self.packageTeardown + # If my context has any fixture attribute, I have fixtures + fixt = False + for m in names: + if hasattr(context, m): + fixt = True + break + if ctx_callback is None: + return fixt + return ctx_callback(context, fixt) + + def setUp(self): + log.debug("suite %s setUp called, tests: %s", id(self), self._tests) + if not self: + # I have no tests + log.debug("suite %s has no tests", id(self)) + return + if self.was_setup: + log.debug("suite %s already set up", id(self)) + return + context = self.context + if context is None: + return + # before running my own context's setup, I need to + # ask the factory if my context's contexts' setups have been run + factory = self.factory + if factory: + # get a copy, since we'll be destroying it as we go + ancestors = factory.context.get(self, [])[:] + while ancestors: + ancestor = ancestors.pop() + log.debug("ancestor %s may need setup", ancestor) + if ancestor in factory.was_setup: + continue + log.debug("ancestor %s does need setup", ancestor) + self.setupContext(ancestor) + if not context in factory.was_setup: + self.setupContext(context) + else: + self.setupContext(context) + self.was_setup = True + log.debug("completed suite setup") + + def setupContext(self, context): + self.config.plugins.startContext(context) + log.debug("%s setup context %s", self, context) + if self.factory: + if context in self.factory.was_setup: + return + # note that I ran the setup for this context, so that I'll run + # the teardown in my teardown + self.factory.was_setup[context] = self + if isclass(context): + names = self.classSetup + else: + names = self.moduleSetup + if hasattr(context, '__path__'): + names = self.packageSetup + names + try_run(context, names) + + def shortDescription(self): + if self.context is None: + return "test suite" + return "test suite for %s" % self.context + + def tearDown(self): + log.debug('context teardown') + if not self.was_setup or self.was_torndown: + log.debug( + "No reason to teardown (was_setup? %s was_torndown? %s)" + % (self.was_setup, self.was_torndown)) + return + self.was_torndown = True + context = self.context + if context is None: + log.debug("No context to tear down") + return + + # for each ancestor... if the ancestor was setup + # and I did the setup, I can do teardown + factory = self.factory + if factory: + ancestors = factory.context.get(self, []) + [context] + for ancestor in ancestors: + log.debug('ancestor %s may need teardown', ancestor) + if not ancestor in factory.was_setup: + log.debug('ancestor %s was not setup', ancestor) + continue + if ancestor in factory.was_torndown: + log.debug('ancestor %s already torn down', ancestor) + continue + setup = factory.was_setup[ancestor] + log.debug("%s setup ancestor %s", setup, ancestor) + if setup is self: + self.teardownContext(ancestor) + else: + self.teardownContext(context) + + def teardownContext(self, context): + log.debug("%s teardown context %s", self, context) + if self.factory: + if context in self.factory.was_torndown: + return + self.factory.was_torndown[context] = self + if isclass(context): + names = self.classTeardown + else: + names = self.moduleTeardown + if hasattr(context, '__path__'): + names = self.packageTeardown + names + try_run(context, names) + self.config.plugins.stopContext(context) + + # FIXME the wrapping has to move to the factory? + def _get_wrapped_tests(self): + for test in self._get_tests(): + if isinstance(test, Test) or isinstance(test, unittest.TestSuite): + yield test + else: + yield Test(test, + config=self.config, + resultProxy=self.resultProxy) + + _tests = property(_get_wrapped_tests, LazySuite._set_tests, None, + "Access the tests in this suite. Tests are returned " + "inside of a context wrapper.") + + +class ContextSuiteFactory(object): + """Factory for ContextSuites. Called with a collection of tests, + the factory decides on a hierarchy of contexts by introspecting + the collection or the tests themselves to find the objects + containing the test objects. It always returns one suite, but that + suite may consist of a hierarchy of nested suites. + """ + suiteClass = ContextSuite + def __init__(self, config=None, suiteClass=None, resultProxy=_def): + if config is None: + config = Config() + self.config = config + if suiteClass is not None: + self.suiteClass = suiteClass + # Using a singleton to represent default instead of None allows + # passing resultProxy=None to turn proxying off. + if resultProxy is _def: + resultProxy = ResultProxyFactory(config=config) + self.resultProxy = resultProxy + self.suites = {} + self.context = {} + self.was_setup = {} + self.was_torndown = {} + + def __call__(self, tests, **kw): + """Return ``ContextSuite`` for tests. ``tests`` may either + be a callable (in which case the resulting ContextSuite will + have no parent context and be evaluated lazily) or an + iterable. In that case the tests will wrapped in + nose.case.Test, be examined and the context of each found and a + suite of suites returned, organized into a stack with the + outermost suites belonging to the outermost contexts. + """ + log.debug("Create suite for %s", tests) + context = kw.pop('context', getattr(tests, 'context', None)) + log.debug("tests %s context %s", tests, context) + if context is None: + tests = self.wrapTests(tests) + try: + context = self.findContext(tests) + except MixedContextError: + return self.makeSuite(self.mixedSuites(tests), None, **kw) + return self.makeSuite(tests, context, **kw) + + def ancestry(self, context): + """Return the ancestry of the context (that is, all of the + packages and modules containing the context), in order of + descent with the outermost ancestor last. + This method is a generator. + """ + log.debug("get ancestry %s", context) + if context is None: + return + # Methods include reference to module they are defined in, we + # don't want that, instead want the module the class is in now + # (classes are re-ancestored elsewhere). + if hasattr(context, 'im_class'): + context = context.im_class + elif hasattr(context, '__self__'): + context = context.__self__.__class__ + if hasattr(context, '__module__'): + ancestors = context.__module__.split('.') + elif hasattr(context, '__name__'): + ancestors = context.__name__.split('.')[:-1] + else: + raise TypeError("%s has no ancestors?" % context) + while ancestors: + log.debug(" %s ancestors %s", context, ancestors) + yield resolve_name('.'.join(ancestors)) + ancestors.pop() + + def findContext(self, tests): + if callable(tests) or isinstance(tests, unittest.TestSuite): + return None + context = None + for test in tests: + # Don't look at suites for contexts, only tests + ctx = getattr(test, 'context', None) + if ctx is None: + continue + if context is None: + context = ctx + elif context != ctx: + raise MixedContextError( + "Tests with different contexts in same suite! %s != %s" + % (context, ctx)) + return context + + def makeSuite(self, tests, context, **kw): + suite = self.suiteClass( + tests, context=context, config=self.config, factory=self, + resultProxy=self.resultProxy, **kw) + if context is not None: + self.suites.setdefault(context, []).append(suite) + self.context.setdefault(suite, []).append(context) + log.debug("suite %s has context %s", suite, + getattr(context, '__name__', None)) + for ancestor in self.ancestry(context): + self.suites.setdefault(ancestor, []).append(suite) + self.context[suite].append(ancestor) + log.debug("suite %s has ancestor %s", suite, ancestor.__name__) + return suite + + def mixedSuites(self, tests): + """The complex case where there are tests that don't all share + the same context. Groups tests into suites with common ancestors, + according to the following (essentially tail-recursive) procedure: + + Starting with the context of the first test, if it is not + None, look for tests in the remaining tests that share that + ancestor. If any are found, group into a suite with that + ancestor as the context, and replace the current suite with + that suite. Continue this process for each ancestor of the + first test, until all ancestors have been processed. At this + point if any tests remain, recurse with those tests as the + input, returning a list of the common suite (which may be the + suite or test we started with, if no common tests were found) + plus the results of recursion. + """ + if not tests: + return [] + head = tests.pop(0) + if not tests: + return [head] # short circuit when none are left to combine + suite = head # the common ancestry suite, so far + tail = tests[:] + context = getattr(head, 'context', None) + if context is not None: + ancestors = [context] + [a for a in self.ancestry(context)] + for ancestor in ancestors: + common = [suite] # tests with ancestor in common, so far + remain = [] # tests that remain to be processed + for test in tail: + found_common = False + test_ctx = getattr(test, 'context', None) + if test_ctx is None: + remain.append(test) + continue + if test_ctx is ancestor: + common.append(test) + continue + for test_ancestor in self.ancestry(test_ctx): + if test_ancestor is ancestor: + common.append(test) + found_common = True + break + if not found_common: + remain.append(test) + if common: + suite = self.makeSuite(common, ancestor) + tail = self.mixedSuites(remain) + return [suite] + tail + + def wrapTests(self, tests): + log.debug("wrap %s", tests) + if callable(tests) or isinstance(tests, unittest.TestSuite): + log.debug("I won't wrap") + return tests + wrapped = [] + for test in tests: + log.debug("wrapping %s", test) + if isinstance(test, Test) or isinstance(test, unittest.TestSuite): + wrapped.append(test) + elif isinstance(test, ContextList): + wrapped.append(self.makeSuite(test, context=test.context)) + else: + wrapped.append( + Test(test, config=self.config, resultProxy=self.resultProxy) + ) + return wrapped + + +class ContextList(object): + """Not quite a suite -- a group of tests in a context. This is used + to hint the ContextSuiteFactory about what context the tests + belong to, in cases where it may be ambiguous or missing. + """ + def __init__(self, tests, context=None): + self.tests = tests + self.context = context + + def __iter__(self): + return iter(self.tests) + + +class FinalizingSuiteWrapper(unittest.TestSuite): + """Wraps suite and calls final function after suite has + executed. Used to call final functions in cases (like running in + the standard test runner) where test running is not under nose's + control. + """ + def __init__(self, suite, finalize): + super(FinalizingSuiteWrapper, self).__init__() + self.suite = suite + self.finalize = finalize + + def __call__(self, *arg, **kw): + return self.run(*arg, **kw) + + # 2.7 compat + def __iter__(self): + return iter(self.suite) + + def run(self, *arg, **kw): + try: + return self.suite(*arg, **kw) + finally: + self.finalize(*arg, **kw) + + +# backwards compat -- sort of +class TestDir: + def __init__(*arg, **kw): + raise NotImplementedError( + "TestDir is not usable with nose 0.10. The class is present " + "in nose.suite for backwards compatibility purposes but it " + "may not be used.") + + +class TestModule: + def __init__(*arg, **kw): + raise NotImplementedError( + "TestModule is not usable with nose 0.10. The class is present " + "in nose.suite for backwards compatibility purposes but it " + "may not be used.") diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/suite.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/suite.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2a2b95b6896beb0af576d6714ccc7fb53c2d7148 GIT binary patch literal 23272 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 YkJ$UVBe!Yc<`vgbG8`1Lc#}{08+JRR3IG5A literal 0 HcmV?d00001 diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/tools/nontrivial.py b/.eggs/nose-1.3.7-py2.7.egg/nose/tools/nontrivial.py new file mode 100644 index 0000000..2839732 --- /dev/null +++ b/.eggs/nose-1.3.7-py2.7.egg/nose/tools/nontrivial.py @@ -0,0 +1,151 @@ +"""Tools not exempt from being descended into in tracebacks""" + +import time + + +__all__ = ['make_decorator', 'raises', 'set_trace', 'timed', 'with_setup', + 'TimeExpired', 'istest', 'nottest'] + + +class TimeExpired(AssertionError): + pass + + +def make_decorator(func): + """ + Wraps a test decorator so as to properly replicate metadata + of the decorated function, including nose's additional stuff + (namely, setup and teardown). + """ + def decorate(newfunc): + if hasattr(func, 'compat_func_name'): + name = func.compat_func_name + else: + name = func.__name__ + newfunc.__dict__ = func.__dict__ + newfunc.__doc__ = func.__doc__ + newfunc.__module__ = func.__module__ + if not hasattr(newfunc, 'compat_co_firstlineno'): + newfunc.compat_co_firstlineno = func.func_code.co_firstlineno + try: + newfunc.__name__ = name + except TypeError: + # can't set func name in 2.3 + newfunc.compat_func_name = name + return newfunc + return decorate + + +def raises(*exceptions): + """Test must raise one of expected exceptions to pass. + + Example use:: + + @raises(TypeError, ValueError) + def test_raises_type_error(): + raise TypeError("This test passes") + + @raises(Exception) + def test_that_fails_by_passing(): + pass + + If you want to test many assertions about exceptions in a single test, + you may want to use `assert_raises` instead. + """ + valid = ' or '.join([e.__name__ for e in exceptions]) + def decorate(func): + name = func.__name__ + def newfunc(*arg, **kw): + try: + func(*arg, **kw) + except exceptions: + pass + except: + raise + else: + message = "%s() did not raise %s" % (name, valid) + raise AssertionError(message) + newfunc = make_decorator(func)(newfunc) + return newfunc + return decorate + + +def set_trace(): + """Call pdb.set_trace in the calling frame, first restoring + sys.stdout to the real output stream. Note that sys.stdout is NOT + reset to whatever it was before the call once pdb is done! + """ + import pdb + import sys + stdout = sys.stdout + sys.stdout = sys.__stdout__ + pdb.Pdb().set_trace(sys._getframe().f_back) + + +def timed(limit): + """Test must finish within specified time limit to pass. + + Example use:: + + @timed(.1) + def test_that_fails(): + time.sleep(.2) + """ + def decorate(func): + def newfunc(*arg, **kw): + start = time.time() + result = func(*arg, **kw) + end = time.time() + if end - start > limit: + raise TimeExpired("Time limit (%s) exceeded" % limit) + return result + newfunc = make_decorator(func)(newfunc) + return newfunc + return decorate + + +def with_setup(setup=None, teardown=None): + """Decorator to add setup and/or teardown methods to a test function:: + + @with_setup(setup, teardown) + def test_something(): + " ... " + + Note that `with_setup` is useful *only* for test functions, not for test + methods or inside of TestCase subclasses. + """ + def decorate(func, setup=setup, teardown=teardown): + if setup: + if hasattr(func, 'setup'): + _old_s = func.setup + def _s(): + setup() + _old_s() + func.setup = _s + else: + func.setup = setup + if teardown: + if hasattr(func, 'teardown'): + _old_t = func.teardown + def _t(): + _old_t() + teardown() + func.teardown = _t + else: + func.teardown = teardown + return func + return decorate + + +def istest(func): + """Decorator to mark a function or method as a test + """ + func.__test__ = True + return func + + +def nottest(func): + """Decorator to mark a function or method as *not* a test + """ + func.__test__ = False + return func diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/tools/nontrivial.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/tools/nontrivial.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c0fd571c97eb0eb5414e8053476ca470a8f68bd6 GIT binary patch literal 6212 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 ispackage('nose') + True + >>> ispackage('unit_tests') + False + >>> ispackage('nose/plugins') + True + >>> ispackage('nose/loader.py') + False + """ + if os.path.isdir(path): + # at least the end of the path must be a legal python identifier + # and __init__.py[co] must exist + end = os.path.basename(path) + if ident_re.match(end): + for init in ('__init__.py', '__init__.pyc', '__init__.pyo'): + if os.path.isfile(os.path.join(path, init)): + return True + if sys.platform.startswith('java') and \ + os.path.isfile(os.path.join(path, '__init__$py.class')): + return True + return False + + +def isproperty(obj): + """ + Is this a property? + + >>> class Foo: + ... def got(self): + ... return 2 + ... def get(self): + ... return 1 + ... get = property(get) + + >>> isproperty(Foo.got) + False + >>> isproperty(Foo.get) + True + """ + return type(obj) == property + + +def getfilename(package, relativeTo=None): + """Find the python source file for a package, relative to a + particular directory (defaults to current working directory if not + given). + """ + if relativeTo is None: + relativeTo = os.getcwd() + path = os.path.join(relativeTo, os.sep.join(package.split('.'))) + if os.path.exists(path + '/__init__.py'): + return path + filename = path + '.py' + if os.path.exists(filename): + return filename + return None + + +def getpackage(filename): + """ + Find the full dotted package name for a given python source file + name. Returns None if the file is not a python source file. + + >>> getpackage('foo.py') + 'foo' + >>> getpackage('biff/baf.py') + 'baf' + >>> getpackage('nose/util.py') + 'nose.util' + + Works for directories too. + + >>> getpackage('nose') + 'nose' + >>> getpackage('nose/plugins') + 'nose.plugins' + + And __init__ files stuck onto directories + + >>> getpackage('nose/plugins/__init__.py') + 'nose.plugins' + + Absolute paths also work. + + >>> path = os.path.abspath(os.path.join('nose', 'plugins')) + >>> getpackage(path) + 'nose.plugins' + """ + src_file = src(filename) + if (os.path.isdir(src_file) or not src_file.endswith('.py')) and not ispackage(src_file): + return None + base, ext = os.path.splitext(os.path.basename(src_file)) + if base == '__init__': + mod_parts = [] + else: + mod_parts = [base] + path, part = os.path.split(os.path.split(src_file)[0]) + while part: + if ispackage(os.path.join(path, part)): + mod_parts.append(part) + else: + break + path, part = os.path.split(path) + mod_parts.reverse() + return '.'.join(mod_parts) + + +def ln(label): + """Draw a 70-char-wide divider, with label in the middle. + + >>> ln('hello there') + '---------------------------- hello there -----------------------------' + """ + label_len = len(label) + 2 + chunk = (70 - label_len) // 2 + out = '%s %s %s' % ('-' * chunk, label, '-' * chunk) + pad = 70 - len(out) + if pad > 0: + out = out + ('-' * pad) + return out + + +def resolve_name(name, module=None): + """Resolve a dotted name to a module and its parts. This is stolen + wholesale from unittest.TestLoader.loadTestByName. + + >>> resolve_name('nose.util') #doctest: +ELLIPSIS + + >>> resolve_name('nose.util.resolve_name') #doctest: +ELLIPSIS + + """ + parts = name.split('.') + parts_copy = parts[:] + if module is None: + while parts_copy: + try: + log.debug("__import__ %s", name) + module = __import__('.'.join(parts_copy)) + break + except ImportError: + del parts_copy[-1] + if not parts_copy: + raise + parts = parts[1:] + obj = module + log.debug("resolve: %s, %s, %s, %s", parts, name, obj, module) + for part in parts: + obj = getattr(obj, part) + return obj + + +def split_test_name(test): + """Split a test name into a 3-tuple containing file, module, and callable + names, any of which (but not all) may be blank. + + Test names are in the form: + + file_or_module:callable + + Either side of the : may be dotted. To change the splitting behavior, you + can alter nose.util.split_test_re. + """ + norm = os.path.normpath + file_or_mod = test + fn = None + if not ':' in test: + # only a file or mod part + if file_like(test): + return (norm(test), None, None) + else: + return (None, test, None) + + # could be path|mod:callable, or a : in the file path someplace + head, tail = os.path.split(test) + if not head: + # this is a case like 'foo:bar' -- generally a module + # name followed by a callable, but also may be a windows + # drive letter followed by a path + try: + file_or_mod, fn = test.split(':') + if file_like(fn): + # must be a funny path + file_or_mod, fn = test, None + except ValueError: + # more than one : in the test + # this is a case like c:\some\path.py:a_test + parts = test.split(':') + if len(parts[0]) == 1: + file_or_mod, fn = ':'.join(parts[:-1]), parts[-1] + else: + # nonsense like foo:bar:baz + raise ValueError("Test name '%s' could not be parsed. Please " + "format test names as path:callable or " + "module:callable." % (test,)) + elif not tail: + # this is a case like 'foo:bar/' + # : must be part of the file path, so ignore it + file_or_mod = test + else: + if ':' in tail: + file_part, fn = tail.split(':') + else: + file_part = tail + file_or_mod = os.sep.join([head, file_part]) + if file_or_mod: + if file_like(file_or_mod): + return (norm(file_or_mod), None, fn) + else: + return (None, file_or_mod, fn) + else: + return (None, None, fn) +split_test_name.__test__ = False # do not collect + + +def test_address(test): + """Find the test address for a test, which may be a module, filename, + class, method or function. + """ + if hasattr(test, "address"): + return test.address() + # type-based polymorphism sucks in general, but I believe is + # appropriate here + t = type(test) + file = module = call = None + if t == types.ModuleType: + file = getattr(test, '__file__', None) + module = getattr(test, '__name__', None) + return (src(file), module, call) + if t == types.FunctionType or issubclass(t, type) or t == types.ClassType: + module = getattr(test, '__module__', None) + if module is not None: + m = sys.modules[module] + file = getattr(m, '__file__', None) + if file is not None: + file = os.path.abspath(file) + call = getattr(test, '__name__', None) + return (src(file), module, call) + if t == types.MethodType: + cls_adr = test_address(test.im_class) + return (src(cls_adr[0]), cls_adr[1], + "%s.%s" % (cls_adr[2], test.__name__)) + # handle unittest.TestCase instances + if isinstance(test, unittest.TestCase): + if (hasattr(test, '_FunctionTestCase__testFunc') # pre 2.7 + or hasattr(test, '_testFunc')): # 2.7 + # unittest FunctionTestCase + try: + return test_address(test._FunctionTestCase__testFunc) + except AttributeError: + return test_address(test._testFunc) + # regular unittest.TestCase + cls_adr = test_address(test.__class__) + # 2.5 compat: __testMethodName changed to _testMethodName + try: + method_name = test._TestCase__testMethodName + except AttributeError: + method_name = test._testMethodName + return (src(cls_adr[0]), cls_adr[1], + "%s.%s" % (cls_adr[2], method_name)) + if (hasattr(test, '__class__') and + test.__class__.__module__ not in ('__builtin__', 'builtins')): + return test_address(test.__class__) + raise TypeError("I don't know what %s is (%s)" % (test, t)) +test_address.__test__ = False # do not collect + + +def try_run(obj, names): + """Given a list of possible method names, try to run them with the + provided object. Keep going until something works. Used to run + setup/teardown methods for module, package, and function tests. + """ + for name in names: + func = getattr(obj, name, None) + if func is not None: + if type(obj) == types.ModuleType: + # py.test compatibility + if isinstance(func, types.FunctionType): + args, varargs, varkw, defaults = \ + inspect.getargspec(func) + else: + # Not a function. If it's callable, call it anyway + if hasattr(func, '__call__') and not inspect.ismethod(func): + func = func.__call__ + try: + args, varargs, varkw, defaults = \ + inspect.getargspec(func) + args.pop(0) # pop the self off + except TypeError: + raise TypeError("Attribute %s of %r is not a python " + "function. Only functions or callables" + " may be used as fixtures." % + (name, obj)) + if len(args): + log.debug("call fixture %s.%s(%s)", obj, name, obj) + return func(obj) + log.debug("call fixture %s.%s", obj, name) + return func() + + +def src(filename): + """Find the python source file for a .pyc, .pyo or $py.class file on + jython. Returns the filename provided if it is not a python source + file. + """ + if filename is None: + return filename + if sys.platform.startswith('java') and filename.endswith('$py.class'): + return '.'.join((filename[:-9], 'py')) + base, ext = os.path.splitext(filename) + if ext in ('.pyc', '.pyo', '.py'): + return '.'.join((base, 'py')) + return filename + + +def regex_last_key(regex): + """Sort key function factory that puts items that match a + regular expression last. + + >>> from nose.config import Config + >>> from nose.pyversion import sort_list + >>> c = Config() + >>> regex = c.testMatch + >>> entries = ['.', '..', 'a_test', 'src', 'lib', 'test', 'foo.py'] + >>> sort_list(entries, regex_last_key(regex)) + >>> entries + ['.', '..', 'foo.py', 'lib', 'src', 'a_test', 'test'] + """ + def k(obj): + if regex.search(obj): + return (1, obj) + return (0, obj) + return k + + +def tolist(val): + """Convert a value that may be a list or a (possibly comma-separated) + string into a list. The exception: None is returned as None, not [None]. + + >>> tolist(["one", "two"]) + ['one', 'two'] + >>> tolist("hello") + ['hello'] + >>> tolist("separate,values, with, commas, spaces , are ,ok") + ['separate', 'values', 'with', 'commas', 'spaces', 'are', 'ok'] + """ + if val is None: + return None + try: + # might already be a list + val.extend([]) + return val + except AttributeError: + pass + # might be a string + try: + return re.split(r'\s*,\s*', val) + except TypeError: + # who knows... + return list(val) + + +class odict(dict): + """Simple ordered dict implementation, based on: + + http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/107747 + """ + def __init__(self, *arg, **kw): + self._keys = [] + super(odict, self).__init__(*arg, **kw) + + def __delitem__(self, key): + super(odict, self).__delitem__(key) + self._keys.remove(key) + + def __setitem__(self, key, item): + super(odict, self).__setitem__(key, item) + if key not in self._keys: + self._keys.append(key) + + def __str__(self): + return "{%s}" % ', '.join(["%r: %r" % (k, v) for k, v in self.items()]) + + def clear(self): + super(odict, self).clear() + self._keys = [] + + def copy(self): + d = super(odict, self).copy() + d._keys = self._keys[:] + return d + + def items(self): + return zip(self._keys, self.values()) + + def keys(self): + return self._keys[:] + + def setdefault(self, key, failobj=None): + item = super(odict, self).setdefault(key, failobj) + if key not in self._keys: + self._keys.append(key) + return item + + def update(self, dict): + super(odict, self).update(dict) + for key in dict.keys(): + if key not in self._keys: + self._keys.append(key) + + def values(self): + return map(self.get, self._keys) + + +def transplant_func(func, module): + """ + Make a function imported from module A appear as if it is located + in module B. + + >>> from pprint import pprint + >>> pprint.__module__ + 'pprint' + >>> pp = transplant_func(pprint, __name__) + >>> pp.__module__ + 'nose.util' + + The original function is not modified. + + >>> pprint.__module__ + 'pprint' + + Calling the transplanted function calls the original. + + >>> pp([1, 2]) + [1, 2] + >>> pprint([1,2]) + [1, 2] + + """ + from nose.tools import make_decorator + if isgenerator(func): + def newfunc(*arg, **kw): + for v in func(*arg, **kw): + yield v + else: + def newfunc(*arg, **kw): + return func(*arg, **kw) + + newfunc = make_decorator(func)(newfunc) + newfunc.__module__ = module + return newfunc + + +def transplant_class(cls, module): + """ + Make a class appear to reside in `module`, rather than the module in which + it is actually defined. + + >>> from nose.failure import Failure + >>> Failure.__module__ + 'nose.failure' + >>> Nf = transplant_class(Failure, __name__) + >>> Nf.__module__ + 'nose.util' + >>> Nf.__name__ + 'Failure' + + """ + class C(cls): + pass + C.__module__ = module + C.__name__ = cls.__name__ + return C + + +def safe_str(val, encoding='utf-8'): + try: + return str(val) + except UnicodeEncodeError: + if isinstance(val, Exception): + return ' '.join([safe_str(arg, encoding) + for arg in val]) + return unicode(val).encode(encoding) + + +def is_executable(file): + if not os.path.exists(file): + return False + st = os.stat(file) + return bool(st.st_mode & (stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)) + + +if __name__ == '__main__': + import doctest + doctest.testmod() diff --git a/.eggs/nose-1.3.7-py2.7.egg/nose/util.pyc b/.eggs/nose-1.3.7-py2.7.egg/nose/util.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b87f196840a3a3382b304f104d6b6239ec88bdf5 GIT binary patch literal 22456 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 FDtD4U`3Z=gDm6*o=b?gR&cyNJZNcL2swa%0Hg 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 Ro_w)5Rh%3hDGsrpzXf~1{fz(s literal 0 HcmV?d00001 diff --git a/python_env.egg-info/PKG-INFO b/python_env.egg-info/PKG-INFO new file mode 100644 index 0000000..8b1aec0 --- /dev/null +++ b/python_env.egg-info/PKG-INFO @@ -0,0 +1,18 @@ +Metadata-Version: 1.1 +Name: python-env +Version: 0.0.1 +Summary: HP Helion Cloud Sample Python WSGI App +Home-page: https://github.com/hpcloud/python-env +Author: John Hopper +Author-email: john.hopper@hp.com +License: UNKNOWN +Description: UNKNOWN +Platform: UNKNOWN +Classifier: Development Status :: 4 - Beta +Classifier: Environment :: Other Environment +Classifier: Natural Language :: English +Classifier: Intended Audience :: Developers +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3.3 +Classifier: Topic :: Internet +Classifier: Topic :: Utilities diff --git a/python_env.egg-info/SOURCES.txt b/python_env.egg-info/SOURCES.txt new file mode 100644 index 0000000..d714ae6 --- /dev/null +++ b/python_env.egg-info/SOURCES.txt @@ -0,0 +1,6 @@ +setup.py +python_env.egg-info/PKG-INFO +python_env.egg-info/SOURCES.txt +python_env.egg-info/dependency_links.txt +python_env.egg-info/requires.txt +python_env.egg-info/top_level.txt \ No newline at end of file diff --git a/python_env.egg-info/dependency_links.txt b/python_env.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/python_env.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/python_env.egg-info/requires.txt b/python_env.egg-info/requires.txt new file mode 100644 index 0000000..36b0b24 --- /dev/null +++ b/python_env.egg-info/requires.txt @@ -0,0 +1,2 @@ +bottle +nose diff --git a/python_env.egg-info/top_level.txt b/python_env.egg-info/top_level.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/python_env.egg-info/top_level.txt @@ -0,0 +1 @@ + diff --git a/tests/tests.py b/tests/tests.py new file mode 100644 index 0000000..7523e7c --- /dev/null +++ b/tests/tests.py @@ -0,0 +1,20 @@ +import unittest + +class TestStringMethods(unittest.TestCase): + + def test_upper(self): + self.assertEqual('foo'.upper(), 'FOO') + + def test_isupper(self): + self.assertTrue('FOO'.isupper()) + self.assertFalse('Foo'.isupper()) + + def test_split(self): + s = 'hello world' + self.assertEqual(s.split(), ['hello', 'world']) + # check that s.split fails when the separator is not a string + with self.assertRaises(TypeError): + s.split(2) + +if __name__ == '__main__': + unittest.main() diff --git a/tests/tests.pyc b/tests/tests.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6bbbdf9d723b8cb88dbc36274882871b434ee780 GIT binary patch literal 1248 zcmb_bO>fgc5S_I{ASFnpJ@Iis;$k5|E*w#Xs9K2wsc^zqE|wKw0UBDUt;hpm;$e%if95SB1`ny(9BQ~ z(+{FG(WeQbF%=!UipZbnj*cvtT2n{K4IESc#xo3e;f^hbQSfCwe`CX?D|icRuqv4R z7zRiaz>vTI0wlx%P^3$mA4*@55Y!r^18nTA8mSGB~YG8V1=tb56hK z7Z*u{dAJReGg}|dzAW=92=isrSf2<$=)kb8W(mHehM&V5yh8>L=HAYoU*&$9`+VSS z<9N`lps;>w>#u_V+1%P^2p=F(LYbZ~Kr9rK{gm(H; z)gvO$ozprgVk>U!mp0tQTFHw3m+tetVykLX;j|B>eVn68H)yvoXDKC_<5sP3?P93f z*KpA6?`EU<+H3?uX%W*rBI#r+9^HfNpGTPME?hz>!w1yi?ME$!h#0c;_0m?Ad-Tou zs?fgbTs@7ILLw1bsZ>oDxT(qzgnwJNG%pz~>me{+HTKMV=k?-ft%BSU-bcl@cS8vX zK1ggrGFXA`Q4}& z_c|LIi@dC}Y)5Qaqi`sdE|1}y=4>@TJw~qnNs_ZKYKrrs)qkRW5Q_ci-eKST0Xnt` AWdHyG literal 0 HcmV?d00001 From 970bb5f5bd476af15451cf6ee90f5b19882521a8 Mon Sep 17 00:00:00 2001 From: helionyeah Date: Tue, 22 Dec 2015 11:03:51 -0800 Subject: [PATCH 3/9] Update app.py --- app.py | 1 + 1 file changed, 1 insertion(+) diff --git a/app.py b/app.py index c2852f6..198fa7e 100644 --- a/app.py +++ b/app.py @@ -13,6 +13,7 @@
  • {{name}}: {{value}}
  • % end +
    {{guid_token}}
    ''' From b3c726ca8e599b35ce739a45db9ad7d68aaaeca3 Mon Sep 17 00:00:00 2001 From: helionyeah Date: Tue, 26 Jan 2016 15:50:37 -0800 Subject: [PATCH 4/9] Update tests.py --- tests/tests.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/tests.py b/tests/tests.py index 7523e7c..03b1b14 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -18,3 +18,4 @@ def test_split(self): if __name__ == '__main__': unittest.main() +# comment From 9f91cc6195eb50b7c35d19e2bd701f9734ec5a91 Mon Sep 17 00:00:00 2001 From: helionyeah Date: Tue, 26 Jan 2016 15:59:37 -0800 Subject: [PATCH 5/9] Update tests.py --- tests/tests.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/tests.py b/tests/tests.py index 03b1b14..7523e7c 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -18,4 +18,3 @@ def test_split(self): if __name__ == '__main__': unittest.main() -# comment From dc896d50c792620a7eec7c28c76ee8a889dd0517 Mon Sep 17 00:00:00 2001 From: helionyeah Date: Tue, 26 Jan 2016 16:28:34 -0800 Subject: [PATCH 6/9] Update setup.py --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index afb789b..bba8862 100644 --- a/setup.py +++ b/setup.py @@ -29,3 +29,4 @@ def read(relative): test_suite='nose.collector', include_package_data=True, packages=find_packages(exclude=['*.tests'])) +# comment From 147ee6c3c1a17f7bd52c845555caa311560c4c35 Mon Sep 17 00:00:00 2001 From: helionyeah Date: Tue, 26 Jan 2016 16:45:12 -0800 Subject: [PATCH 7/9] Update setup.py --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index bba8862..afb789b 100644 --- a/setup.py +++ b/setup.py @@ -29,4 +29,3 @@ def read(relative): test_suite='nose.collector', include_package_data=True, packages=find_packages(exclude=['*.tests'])) -# comment From a06ef0dbd77a7e4c6d842105648008e084d85b67 Mon Sep 17 00:00:00 2001 From: helionyeah Date: Wed, 27 Jan 2016 14:26:34 -0800 Subject: [PATCH 8/9] Update setup.py --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index afb789b..bba8862 100644 --- a/setup.py +++ b/setup.py @@ -29,3 +29,4 @@ def read(relative): test_suite='nose.collector', include_package_data=True, packages=find_packages(exclude=['*.tests'])) +# comment From af02d28614ddba90f371aacc431f3774638e28e7 Mon Sep 17 00:00:00 2001 From: Jason Zhu Date: Fri, 12 Feb 2016 07:10:06 -0800 Subject: [PATCH 9/9] added Dockerfile and updated app.py --- Dockerfile | 10 ++++++++++ app.py | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b8c24cc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,10 @@ +FROM python:2.7.8-slim + +COPY ./ /src +WORKDIR /src + +RUN pip install -r requirements.pypm + +EXPOSE 8080 + +CMD ["python", "app.py"] diff --git a/app.py b/app.py index 198fa7e..ed3aef5 100644 --- a/app.py +++ b/app.py @@ -13,12 +13,12 @@
  • {{name}}: {{value}}
  • % end -
    {{guid_token}}
    +
    GUID: {{guid}}
    ''' @route('/') def index(): - return template(html_template, envlist=os.environ) + return template(html_template, envlist=os.environ, guid='{{guid_token}}') run(host='0.0.0.0', port=int(os.getenv("PORT", 8080)))