From 56168748234bf4b50b25b8b2d1153fff5683b105 Mon Sep 17 00:00:00 2001 From: holger krekel Date: Sun, 31 Oct 2010 23:28:31 +0100 Subject: [PATCH] streamline some hook docs and option handling, remove cruft bits, fix doc links --- doc/customize.txt | 2 +- doc/example/conftest.py | 1 + doc/faq.txt | 10 ++-------- pytest/hookspec.py | 33 +++++++++++++++++---------------- pytest/plugin/mark.py | 2 +- pytest/plugin/python.py | 4 +--- pytest/plugin/session.py | 8 ++++---- pytest/plugin/skipping.py | 2 +- pytest/plugin/terminal.py | 14 +++++++------- testing/plugin/test_session.py | 4 ++-- testing/plugin/test_terminal.py | 21 ++++++++++----------- 11 files changed, 47 insertions(+), 54 deletions(-) create mode 100644 doc/example/conftest.py diff --git a/doc/customize.txt b/doc/customize.txt index 65e810bde..0064517cf 100644 --- a/doc/customize.txt +++ b/doc/customize.txt @@ -261,7 +261,7 @@ reporting hooks Collection related reporting hooks: .. autofunction: pytest_collectstart -.. autofunction: pytest_log_itemcollect +.. autofunction: pytest_itemcollected .. autofunction: pytest_collectreport .. autofunction: pytest_deselected diff --git a/doc/example/conftest.py b/doc/example/conftest.py new file mode 100644 index 000000000..f905738c4 --- /dev/null +++ b/doc/example/conftest.py @@ -0,0 +1 @@ +collect_ignore = ["nonpython"] diff --git a/doc/faq.txt b/doc/faq.txt index e7b69e42f..c77f19754 100644 --- a/doc/faq.txt +++ b/doc/faq.txt @@ -16,9 +16,7 @@ more bug fixes and also works for Python3. For Python2 you can also consult pip_ for the popular ``pip`` tool. -for the according ``pip`` installation tool. installation instructions. -You can also `setuptools`_ and -If you want to install on Python3 you need to use Distribute_ which +However, If you want to install on Python3 you need to use Distribute_ which provides the ``easy_install`` utility. @@ -68,7 +66,6 @@ as a clone of ``py.test`` when py.test was in the ``0.8`` release cycle so some of the newer features_ introduced with py.test-1.0 and py.test-1.1 have no counterpart in nose_. -.. _nose: http://somethingaboutorange.com/mrl/projects/nose/0.11.1/ .. _features: test/features.html .. _apipkg: http://pypi.python.org/pypi/apipkg @@ -111,8 +108,6 @@ in a managed class/module/function scope. .. _monkeypatch: test/plugin/monkeypatch.html .. _tmpdir: test/plugin/tmpdir.html .. _capture: test/plugin/capture.html -.. _`xUnit style setup`: test/xunit_setup.html -.. _`pytest_nose`: test/plugin/nose.html .. _`why pytest_pyfuncarg__ methods?`: @@ -152,7 +147,6 @@ and implement the `parametrization scheme of your choice`_. .. _`pytest_generate_tests`: test/funcargs.html#parametrizing-tests .. _`parametrization scheme of your choice`: http://tetamap.wordpress.com/2009/05/13/parametrizing-python-tests-generalized/ - py.test interaction with other packages --------------------------------------------------- @@ -185,4 +179,4 @@ script with this content and invoke that with the python version:: .. _`install distribute`: http://pypi.python.org/pypi/distribute#installation-instructions - +.. include:: links.inc diff --git a/pytest/hookspec.py b/pytest/hookspec.py index d8016e371..4ef5bcb96 100644 --- a/pytest/hookspec.py +++ b/pytest/hookspec.py @@ -4,12 +4,15 @@ # Initialization # ------------------------------------------------------------------------- +def pytest_addhooks(pluginmanager): + """called at plugin load time to allow adding new hooks via a call to + pluginmanager.registerhooks(module).""" + + def pytest_namespace(): """return dict of name->object to be made globally available in the py.test/pytest namespace. This hook is called before command - line options are fully parsed. If you want to provide helper functions - that can interact with a test function invocation, please refer to - :ref:`funcarg mechanism`. + line options are parsed. """ def pytest_cmdline_parse(pluginmanager, args): @@ -17,12 +20,9 @@ def pytest_cmdline_parse(pluginmanager, args): pytest_cmdline_parse.firstresult = True def pytest_addoption(parser): - """allows to add optparse-style command line options via a call to - ``parser.addoption(...)``.""" - -def pytest_addhooks(pluginmanager): - """called at plugin load time to allow adding new hooks via a call to - pluginmanager.registerhooks(module).""" + """add optparse-style options and ini-style config values via calls + to ``parser.addoption`` and ``parser.addini(...)``. + """ def pytest_cmdline_main(config): """ called for performing the main command line action. The default @@ -45,15 +45,16 @@ pytest_runtest_mainloop.firstresult = True # collection hooks # ------------------------------------------------------------------------- -def pytest_perform_collection(session): +def pytest_collection_perform(session): """ perform the collection protocol for the given session. """ -pytest_perform_collection.firstresult = True +pytest_collection_perform.firstresult = True def pytest_collection_modifyitems(config, items): - """ called to allow filtering and selecting of test items (inplace). """ + """ called after collection has been performed, may filter or re-order + the items in-place.""" -def pytest_log_finishcollection(collection): - """ called after collection has finished. """ +def pytest_collection_finish(collection): + """ called after collection has been performed and modified. """ def pytest_ignore_collect(path, config): """ return True to prevent considering this path for collection. @@ -75,7 +76,7 @@ def pytest_collect_file(path, parent): def pytest_collectstart(collector): """ collector starts collecting. """ -def pytest_log_itemcollect(item): +def pytest_itemcollected(item): """ we just collected a test item. """ def pytest_collectreport(report): @@ -85,7 +86,7 @@ def pytest_deselected(items): """ called for test items deselected by keyword. """ def pytest_make_collect_report(collector): - """ perform a collection and return a collection. """ + """ perform ``collector.collect()`` and return a CollectReport. """ pytest_make_collect_report.firstresult = True # ------------------------------------------------------------------------- diff --git a/pytest/plugin/mark.py b/pytest/plugin/mark.py index 17317671e..5267cab72 100644 --- a/pytest/plugin/mark.py +++ b/pytest/plugin/mark.py @@ -155,7 +155,7 @@ class MarkInfo: return "" % ( self._name, self.args, self.kwargs) -def pytest_log_itemcollect(item): +def pytest_itemcollected(item): if not isinstance(item, py.test.collect.Function): return try: diff --git a/pytest/plugin/python.py b/pytest/plugin/python.py index d2ff143de..f2be50710 100644 --- a/pytest/plugin/python.py +++ b/pytest/plugin/python.py @@ -315,9 +315,7 @@ class FunctionMixin(PyobjMixin): def repr_failure(self, excinfo, outerr=None): assert outerr is None, "XXX outerr usage is deprecated" return self._repr_failure_py(excinfo, - style=self.config.getvalue("tbstyle")) - - shortfailurerepr = "F" + style=self.config.option.tbstyle) class FuncargLookupErrorRepr(TerminalRepr): def __init__(self, filename, firstlineno, deflines, errorstring): diff --git a/pytest/plugin/session.py b/pytest/plugin/session.py index 422a389f2..cbab454ec 100644 --- a/pytest/plugin/session.py +++ b/pytest/plugin/session.py @@ -46,13 +46,13 @@ def pytest_configure(config): def pytest_cmdline_main(config): return Session(config).main() -def pytest_perform_collection(session): +def pytest_collection_perform(session): collection = session.collection assert not hasattr(collection, 'items') hook = session.config.hook collection.items = items = collection.perform_collect() hook.pytest_collection_modifyitems(config=session.config, items=items) - hook.pytest_log_finishcollection(collection=collection) + hook.pytest_collection_finish(collection=collection) return True def pytest_runtest_mainloop(session): @@ -128,7 +128,7 @@ class Session(object): try: config.pluginmanager.do_configure(config) config.hook.pytest_sessionstart(session=self) - config.hook.pytest_perform_collection(session=self) + config.hook.pytest_collection_perform(session=self) config.hook.pytest_runtest_mainloop(session=self) except pytest.UsageError: raise @@ -261,7 +261,7 @@ class Collection: def genitems(self, node): if isinstance(node, pytest.collect.Item): - node.ihook.pytest_log_itemcollect(item=node) + node.ihook.pytest_itemcollected(item=node) yield node else: assert isinstance(node, pytest.collect.Collector) diff --git a/pytest/plugin/skipping.py b/pytest/plugin/skipping.py index 6c01a4c9c..7185c59c4 100644 --- a/pytest/plugin/skipping.py +++ b/pytest/plugin/skipping.py @@ -213,7 +213,7 @@ def pytest_pyfunc_call(pyfuncitem): check_xfail_no_run(pyfuncitem) def check_xfail_no_run(item): - if not item.config.getvalue("runxfail"): + if not item.config.option.runxfail: evalxfail = item._evalxfail if evalxfail.istrue(): if not evalxfail.get('run', True): diff --git a/pytest/plugin/terminal.py b/pytest/plugin/terminal.py index 42a07591f..b256f6153 100644 --- a/pytest/plugin/terminal.py +++ b/pytest/plugin/terminal.py @@ -58,7 +58,7 @@ def pytest_unconfigure(config): def getreportopt(config): reportopts = "" - optvalue = config.getvalue("report") + optvalue = config.option.report if optvalue: py.builtin.print_("DEPRECATED: use -r instead of --report option.", file=py.std.sys.stderr) @@ -69,7 +69,7 @@ def getreportopt(config): reportopts += "s" elif setting == "xfailed": reportopts += "x" - reportchars = config.getvalue("reportchars") + reportchars = config.option.reportchars if reportchars: for char in reportchars: if char not in reportopts: @@ -233,7 +233,7 @@ class TerminalReporter: for line in flatten(lines): self.write_line(line) - def pytest_log_finishcollection(self): + def pytest_collection_finish(self): if not self.showheader: return for i, testarg in enumerate(self.config.args): @@ -259,7 +259,7 @@ class TerminalReporter: msg = excrepr.reprcrash.message self.write_sep("!", msg) if "KeyboardInterrupt" in msg: - if self.config.getvalue("fulltrace"): + if self.config.option.fulltrace: excrepr.toterminal(self._tw) else: excrepr.reprcrash.toterminal(self._tw) @@ -304,7 +304,7 @@ class TerminalReporter: # def summary_failures(self): - tbstyle = self.config.getvalue("tbstyle") + tbstyle = self.config.option.tbstyle if 'failed' in self.stats and tbstyle != "no": self.write_sep("=", "FAILURES") for rep in self.stats['failed']: @@ -379,7 +379,7 @@ class CollectonlyReporter: self.outindent(collector) self.indent += self.INDENT - def pytest_log_itemcollect(self, item): + def pytest_itemcollected(self, item): self.outindent(item) def pytest_collectreport(self, report): @@ -394,7 +394,7 @@ class CollectonlyReporter: self._failed.append(report) self.indent = self.indent[:-len(self.INDENT)] - def pytest_log_finishcollection(self): + def pytest_collection_finish(self): if self._failed: self._tw.sep("!", "collection failures") for rep in self._failed: diff --git a/testing/plugin/test_session.py b/testing/plugin/test_session.py index 8684be9aa..60be53f4b 100644 --- a/testing/plugin/test_session.py +++ b/testing/plugin/test_session.py @@ -21,7 +21,7 @@ class SessionTests: assert failed[0].nodenames[-1] == "test_one_one" assert failed[1].nodenames[-1] == "test_other" assert failed[2].nodenames[-1] == "test_two" - itemstarted = reprec.getcalls("pytest_log_itemcollect") + itemstarted = reprec.getcalls("pytest_itemcollected") assert len(itemstarted) == 4 colstarted = reprec.getcalls("pytest_collectstart") assert len(colstarted) == 1 + 1 # XXX ExtraTopCollector @@ -181,7 +181,7 @@ class TestNewSession(SessionTests): ) reprec = testdir.inline_run('--collectonly', p.dirpath()) - itemstarted = reprec.getcalls("pytest_log_itemcollect") + itemstarted = reprec.getcalls("pytest_itemcollected") assert len(itemstarted) == 3 assert not reprec.getreports("pytest_runtest_logreport") started = reprec.getcalls("pytest_collectstart") diff --git a/testing/plugin/test_terminal.py b/testing/plugin/test_terminal.py index 5dc740f92..00e27222e 100644 --- a/testing/plugin/test_terminal.py +++ b/testing/plugin/test_terminal.py @@ -176,7 +176,7 @@ class TestCollectonly: "" ]) item = modcol.collect()[0] - rep.config.hook.pytest_log_itemcollect(item=item) + rep.config.hook.pytest_itemcollected(item=item) linecomp.assert_contains_lines([ " ", ]) @@ -456,24 +456,23 @@ def test_fail_reporting_on_pass(testdir): assert 'short test summary' not in result.stdout.str() def test_getreportopt(): - testdict = {} - class Config: - def getvalue(self, name): - return testdict.get(name, None) - config = Config() - testdict.update(dict(report="xfailed")) + class config: + class option: + reportchars = "" + config.option.report = "xfailed" assert getreportopt(config) == "x" - testdict.update(dict(report="xfailed,skipped")) + config.option.report = "xfailed,skipped" assert getreportopt(config) == "xs" - testdict.update(dict(report="skipped,xfailed")) + config.option.report = "skipped,xfailed" assert getreportopt(config) == "sx" - testdict.update(dict(report="skipped", reportchars="sf")) + config.option.report = "skipped" + config.option.reportchars = "sf" assert getreportopt(config) == "sf" - testdict.update(dict(reportchars="sfx")) + config.option.reportchars = "sfx" assert getreportopt(config) == "sfx" def test_terminalreporter_reportopt_addargs(testdir):