From commits-noreply at bitbucket.org Thu Dec 1 11:52:02 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Thu, 01 Dec 2011 10:52:02 -0000 Subject: [py-svn] commit/pytest: hpk42: some updates, add fslayout idea Message-ID: <20111201105202.10695.37949@bitbucket03.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/5ee61fe7cb9a/ changeset: 5ee61fe7cb9a user: hpk42 date: 2011-12-01 11:51:43 summary: some updates, add fslayout idea affected #: 1 file diff -r c350e81eba007b8037b0562b0a6f6fdd9fd9b05f -r 5ee61fe7cb9a00df76551153af37f3113d7daffa ISSUES.txt --- a/ISSUES.txt +++ b/ISSUES.txt @@ -105,7 +105,7 @@ to better implement the word meaning. It also signals better that we always have some kind of an implementation reason that can be formualated. -Compatibility? Maybe rename to "pytest.mark.xfail"? +Compatibility? how to introduce a new name/keep compat? introduce py.test.mark registration ----------------------------------------- @@ -250,3 +250,25 @@ in collect.py. Probably good: - inline consider_file/dir methods, no need to have them subclass-overridable because of hooks + +implement fslayout decorator +--------------------------------- +tags: feature + +Improve the way how tests can work with pre-made examples, +keeping the layout close to the test function: + + at pytest.mark.fslayout(""" + conftest.py: + # empty + tests/ + test_%(NAME)s: # becomes test_run1.py + def test_function(self): + pass +""") +def test_run(pytester, fslayout): + p = fslayout.find("test_*.py") + result = pytester.runpytest(p) + assert result.ret == 0 + assert result.passed == 1 + Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Thu Dec 1 13:23:39 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Thu, 01 Dec 2011 12:23:39 -0000 Subject: [py-svn] commit/pytest: hpk42: add new "parametrize refinement" issue critical for 2.2 series Message-ID: <20111201122339.29132.61002@bitbucket01.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/bfc767236dda/ changeset: bfc767236dda user: hpk42 date: 2011-12-01 13:23:28 summary: add new "parametrize refinement" issue critical for 2.2 series also cleanup issues a bit and make a note on xUnit/funcargs collaboration affected #: 1 file diff -r 5ee61fe7cb9a00df76551153af37f3113d7daffa -r bfc767236dda1c9c517f35d446f956f8384390e1 ISSUES.txt --- a/ISSUES.txt +++ b/ISSUES.txt @@ -1,3 +1,24 @@ +refine parametrize API in 2.2 series +------------------------------------------------------------- +tags: critical feature 2.2 + +extend metafunc.parametrize to better support indirection +by specifying a setupfunc(request, val) which will _substitute_ +the funcarg factory. Here is an example: + + def setupdb(request, val): + # setup "resource" based on test request and the values passed + # in to parametrize. setupfunc is called for each such value. + # you may use request.addfinalizer() or request.cached_setup ... + return db + + @pytest.mark.parametrize("db", ["pg", "mysql"], setupfunc=setupdb) + def test_heavy_functional_test(db): + ... + +There would be no need to write funcarg factories for this example, only +to explain the attributes and functionality of "request". + checks / deprecations for next release --------------------------------------------------------------- tags: bug 2.4 core xdist @@ -27,7 +48,7 @@ do early-teardown of test modules ----------------------------------------- -tags: feature 2.2 +tags: feature 2.3 currently teardowns are called when the next tests is setup except for the function/method level where interally @@ -39,7 +60,7 @@ consider and document __init__ file usage in test directories --------------------------------------------------------------- -tags: bug 2.2 core +tags: bug 2.3 core Currently, a test module is imported with its fully qualified package path, determined by checking __init__ files upwards. @@ -54,7 +75,7 @@ relax requirement to have tests/testing contain an __init__ ---------------------------------------------------------------- -tags: feature 2.2 +tags: feature 2.3 bb: http://bitbucket.org/hpk42/py-trunk/issue/64 A local test run of a "tests" directory may work @@ -65,7 +86,7 @@ customize test function collection ------------------------------------------------------- -tags: feature 2.2 +tags: feature 2.3 - introduce py.test.mark.nocollect for not considering a function for test collection at all. maybe also introduce a py.test.mark.test to @@ -74,7 +95,7 @@ introduce pytest.mark.importorskip ------------------------------------------------------- -tags: feature 2.2 +tags: feature 2.3 in addition to the imperative pytest.importorskip also introduce a pytest.mark.importorskip so that the test count is more correct. @@ -82,7 +103,7 @@ introduce py.test.mark.platform ------------------------------------------------------- -tags: feature 2.2 +tags: feature 2.3 Introduce nice-to-spell platform-skipping, examples: @@ -99,7 +120,7 @@ pytest.mark.xfail signature change ------------------------------------------------------- -tags: feature 2.2 +tags: feature 2.3 change to pytest.mark.xfail(reason, (optional)condition) to better implement the word meaning. It also signals @@ -109,7 +130,7 @@ introduce py.test.mark registration ----------------------------------------- -tags: feature 2.2 +tags: feature 2.3 introduce a hook that allows to register a named mark decorator with documentation and add "py.test --marks" to get @@ -118,7 +139,7 @@ allow to non-intrusively apply skipfs/xfail/marks --------------------------------------------------- -tags: feature 2.2 +tags: feature 2.3 use case: mark a module or directory structures to be skipped on certain platforms (i.e. no import @@ -129,14 +150,14 @@ explicit referencing of conftest.py files ----------------------------------------- -tags: feature 2.2 +tags: feature 2.3 allow to name conftest.py files (in sub directories) that should be imported early, as to include command line options. improve central py.test ini file ---------------------------------- -tags: feature 2.2 +tags: feature 2.3 introduce more declarative configuration options: - (to-be-collected test directories) @@ -147,33 +168,16 @@ new documentation ---------------------------------- -tags: feature 2.2 +tags: feature 2.3 - logo py.test - examples for unittest or functional testing - resource management for functional testing - patterns: page object -- parametrized testing -- better / more integrated plugin docs - -generalize parametrized testing to generate combinations -------------------------------------------------------------- -tags: feature 2.2 - -think about extending metafunc.addcall or add a new method to allow to -generate tests with combinations of all generated versions - what to do -about "id" and "param" in such combinations though? - -introduce py.test.mark.multi ------------------------------------------ -tags: feature 1.3 - -introduce py.test.mark.multi to specify a number -of values for a given function argument. have imported module mismatch honour relative paths -------------------------------------------------------- -tags: bug 2.2 +tags: bug 2.3 With 1.1.1 py.test fails at least on windows if an import is relative and compared against an absolute conftest.py @@ -181,7 +185,7 @@ call termination with small timeout ------------------------------------------------- -tags: feature 2.2 +tags: feature 2.3 test: testing/pytest/dist/test_dsession.py - test_terminate_on_hanging_node Call gateway group termination with a small timeout if available. @@ -189,7 +193,7 @@ consider globals: py.test.ensuretemp and config -------------------------------------------------------------- -tags: experimental-wish 2.2 +tags: experimental-wish 2.3 consider deprecating py.test.ensuretemp and py.test.config to further reduce py.test globality. Also consider @@ -198,7 +202,7 @@ consider allowing funcargs for setup methods -------------------------------------------------------------- -tags: experimental-wish 2.2 +tags: experimental-wish 2.3 Users have expressed the wish to have funcargs available to setup functions. Experiment with allowing funcargs there - it might @@ -208,13 +212,20 @@ attributes. However, how to handle parametrized test functions and funcargs? -setup_function -> request can be like it is now -setup_class -> request has no request.function -setup_module -> request has no request.cls +maybe introduce a setup method like: + + setup_invocation(self, request) + +which has full access to the test invocation through "request" +through which you can get funcargvalues, use cached_setup etc. +Therefore, the access to funcargs would be indirect but it +could be consistently implemented. setup_invocation() would +be a "glue" function for bringing together the xUnit and funcargs +world. consider pytest_addsyspath hook ----------------------------------------- -tags: 2.2 +tags: 2.3 py.test could call a new pytest_addsyspath() in order to systematically allow manipulation of sys.path and to inhibit it via --no-addsyspath @@ -226,7 +237,7 @@ show plugin information in test header ---------------------------------------------------------------- -tags: feature 2.2 +tags: feature 2.3 Now that external plugins are becoming more numerous it would be useful to have external plugins along with @@ -234,7 +245,7 @@ deprecate global py.test.config usage ---------------------------------------------------------------- -tags: feature 2.2 +tags: feature 2.3 py.test.ensuretemp and py.test.config are probably the last objects containing global state. Often using them is not @@ -244,7 +255,7 @@ remove deprecated bits in collect.py ------------------------------------------------------------------- -tags: feature 2.2 +tags: feature 2.3 In an effort to further simplify code, review and remove deprecated bits in collect.py. Probably good: @@ -253,7 +264,7 @@ implement fslayout decorator --------------------------------- -tags: feature +tags: feature 2.3 Improve the way how tests can work with pre-made examples, keeping the layout close to the test function: @@ -272,3 +283,4 @@ assert result.ret == 0 assert result.passed == 1 + Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Thu Dec 1 19:45:33 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Thu, 01 Dec 2011 18:45:33 -0000 Subject: [py-svn] commit/pytest: RonnyPfannschmidt: simplify the loop in Node.listchain Message-ID: <20111201184533.18183.70159@bitbucket01.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/58eee296ceda/ changeset: 58eee296ceda user: RonnyPfannschmidt date: 2011-12-01 19:36:44 summary: simplify the loop in Node.listchain affected #: 2 files diff -r bfc767236dda1c9c517f35d446f956f8384390e1 -r 58eee296cedaa9d329970074db0e4943c74a18c4 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -29,6 +29,7 @@ - fix issue83: link to generated funcarg list - fix issue74: pyarg module names are now checked against imp.find_module false positives - fix compatibility with twisted/trial-11.1.0 use cases +- simplify Node.listchain Changes between 2.1.2 and 2.1.3 ---------------------------------------- diff -r bfc767236dda1c9c517f35d446f956f8384390e1 -r 58eee296cedaa9d329970074db0e4943c74a18c4 _pytest/main.py --- a/_pytest/main.py +++ b/_pytest/main.py @@ -229,13 +229,13 @@ def listchain(self): """ return list of all parent collectors up to self, starting from root of collection tree. """ - l = [self] - while 1: - x = l[0] - if x.parent is not None: # and x.parent.parent is not None: - l.insert(0, x.parent) - else: - return l + chain = [] + item = self + while item is not None: + chain.append(item) + item = item.parent + chain.reverse() + return chain def listnames(self): return [x.name for x in self.listchain()] Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Thu Dec 1 20:11:16 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Thu, 01 Dec 2011 19:11:16 -0000 Subject: [py-svn] commit/pytest: RonnyPfannschmidt: use py.xml for generating the junitxml files Message-ID: <20111201191116.21784.26023@bitbucket03.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/03438e53b03b/ changeset: 03438e53b03b user: RonnyPfannschmidt date: 2011-12-01 20:08:51 summary: use py.xml for generating the junitxml files affected #: 2 files diff -r 58eee296cedaa9d329970074db0e4943c74a18c4 -r 03438e53b03b1b138dfc9756068aa7ae25097887 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -30,6 +30,7 @@ - fix issue74: pyarg module names are now checked against imp.find_module false positives - fix compatibility with twisted/trial-11.1.0 use cases - simplify Node.listchain +- simplify junitxml output code by relying on py.xml Changes between 2.1.2 and 2.1.3 ---------------------------------------- diff -r 58eee296cedaa9d329970074db0e4943c74a18c4 -r 03438e53b03b1b138dfc9756068aa7ae25097887 _pytest/junitxml.py --- a/_pytest/junitxml.py +++ b/_pytest/junitxml.py @@ -25,6 +25,10 @@ long = int +class Junit(py.xml.Namespace): + pass + + # We need to get the subset of the invalid unicode ranges according to # XML 1.0 which are valid in this python build. Hence we calculate # this dynamically instead of hardcoding it. The spec range of valid @@ -40,6 +44,14 @@ del _illegal_unichrs del _illegal_ranges +def bin_xml_escape(arg): + def repl(matchobj): + i = ord(matchobj.group()) + if i <= 0xFF: + return unicode('#x%02X') % i + else: + return unicode('#x%04X') % i + return illegal_xml_re.sub(repl, py.xml.escape(arg)) def pytest_addoption(parser): group = parser.getgroup("terminal reporting") @@ -68,116 +80,97 @@ logfile = os.path.expanduser(os.path.expandvars(logfile)) self.logfile = os.path.normpath(logfile) self.prefix = prefix - self.test_logs = [] + self.tests = [] self.passed = self.skipped = 0 self.failed = self.errors = 0 def _opentestcase(self, report): names = report.nodeid.split("::") names[0] = names[0].replace("/", '.') - names = tuple(names) - d = {'time': getattr(report, 'duration', 0)} names = [x.replace(".py", "") for x in names if x != "()"] classnames = names[:-1] if self.prefix: classnames.insert(0, self.prefix) - d['classname'] = ".".join(classnames) - d['name'] = py.xml.escape(names[-1]) - attrs = ['%s="%s"' % item for item in sorted(d.items())] - self.test_logs.append("\n" % " ".join(attrs)) + self.tests.append(Junit.testcase( + classname=".".join(classnames), + name=names[-1], + time=getattr(report, 'duration', 0) + )) - def _closetestcase(self): - self.test_logs.append("") - - def appendlog(self, fmt, *args): - def repl(matchobj): - i = ord(matchobj.group()) - if i <= 0xFF: - return unicode('#x%02X') % i - else: - return unicode('#x%04X') % i - args = tuple([illegal_xml_re.sub(repl, py.xml.escape(arg)) - for arg in args]) - self.test_logs.append(fmt % args) + def append(self, obj): + self.tests[-1].append(obj) def append_pass(self, report): self.passed += 1 - self._opentestcase(report) - self._closetestcase() def append_failure(self, report): - self._opentestcase(report) #msg = str(report.longrepr.reprtraceback.extraline) if "xfail" in report.keywords: - self.appendlog( - '') + self.append( + Junit.skipped(message="xfail-marked test passes unexpectedly")) self.skipped += 1 else: sec = dict(report.sections) - self.appendlog('%s', - report.longrepr) + fail = Junit.failure(message="test failure") + fail.append(str(report.longrepr)) + self.append(fail) for name in ('out', 'err'): content = sec.get("Captured std%s" % name) if content: - self.appendlog( - "%%s" % (name, name), content) + tag = getattr(Junit, 'system-'+name) + self.append(tag(bin_xml_escape(content))) self.failed += 1 - self._closetestcase() def append_collect_failure(self, report): - self._opentestcase(report) #msg = str(report.longrepr.reprtraceback.extraline) - self.appendlog('%s', - report.longrepr) - self._closetestcase() + self.append(Junit.failure(str(report.longrepr), + message="collection failure")) self.errors += 1 def append_collect_skipped(self, report): - self._opentestcase(report) #msg = str(report.longrepr.reprtraceback.extraline) - self.appendlog('%s', - report.longrepr) - self._closetestcase() + self.append(Junit.skipped(str(report.longrepr), + message="collection skipped")) self.skipped += 1 def append_error(self, report): - self._opentestcase(report) - self.appendlog('%s', - report.longrepr) - self._closetestcase() + self.append(Junit.error(str(report.longrepr), + message="test setup failure")) self.errors += 1 def append_skipped(self, report): - self._opentestcase(report) if "xfail" in report.keywords: - self.appendlog( - '%s', - report.keywords['xfail']) + self.append(Junit.skipped(str(report.keywords['xfail']), + message="expected test failure")) else: filename, lineno, skipreason = report.longrepr if skipreason.startswith("Skipped: "): skipreason = skipreason[9:] - self.appendlog('%s', - skipreason, "%s:%s: %s" % report.longrepr, - ) - self._closetestcase() + self.append( + Junit.skipped("%s:%s: %s" % report.longrepr, + type="pytest.skip", + message=skipreason + )) self.skipped += 1 def pytest_runtest_logreport(self, report): if report.passed: if report.when == "call": # ignore setup/teardown + self._opentestcase(report) self.append_pass(report) elif report.failed: + self._opentestcase(report) if report.when != "call": self.append_error(report) else: self.append_failure(report) elif report.skipped: + self._opentestcase(report) self.append_skipped(report) def pytest_collectreport(self, report): if not report.passed: + self._opentestcase(report) if report.failed: self.append_collect_failure(report) else: @@ -186,10 +179,11 @@ def pytest_internalerror(self, excrepr): self.errors += 1 data = py.xml.escape(excrepr) - self.test_logs.append( - '\n' - ' ' - '%s' % data) + self.tests.append( + Junit.testcase( + Junit.error(data, message="internal error"), + classname="pytest", + name="internal")) def pytest_sessionstart(self, session): self.suite_start_time = time.time() @@ -203,17 +197,17 @@ suite_stop_time = time.time() suite_time_delta = suite_stop_time - self.suite_start_time numtests = self.passed + self.failed + logfile.write('') - logfile.write('') - logfile.writelines(self.test_logs) - logfile.write('') + logfile.write(Junit.testsuite( + self.tests, + name="", + errors=self.errors, + failures=self.failed, + skips=self.skipped, + tests=numtests, + time="%.3f" % suite_time_delta, + ).unicode(indent=0)) logfile.close() def pytest_terminal_summary(self, terminalreporter): Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Thu Dec 1 20:18:14 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Thu, 01 Dec 2011 19:18:14 -0000 Subject: [py-svn] commit/pytest: RonnyPfannschmidt: take the skip property of unittest cases and functions into account Message-ID: <20111201191814.2755.58512@bitbucket03.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/4a015a903b16/ changeset: 4a015a903b16 user: RonnyPfannschmidt date: 2011-12-01 20:17:24 summary: take the skip property of unittest cases and functions into account affected #: 3 files diff -r 03438e53b03b1b138dfc9756068aa7ae25097887 -r 4a015a903b1650c15fed3c8283f67f8c46271127 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -31,6 +31,7 @@ - fix compatibility with twisted/trial-11.1.0 use cases - simplify Node.listchain - simplify junitxml output code by relying on py.xml +- add support for skip properties on unittest classes and functions Changes between 2.1.2 and 2.1.3 ---------------------------------------- diff -r 03438e53b03b1b138dfc9756068aa7ae25097887 -r 4a015a903b1650c15fed3c8283f67f8c46271127 _pytest/unittest.py --- a/_pytest/unittest.py +++ b/_pytest/unittest.py @@ -46,6 +46,10 @@ def setup(self): self._testcase = self.parent.obj(self.name) self._obj = getattr(self._testcase, self.name) + if hasattr(self._testcase, 'skip'): + pytest.skip(self._testcase.skip) + if hasattr(self._obj, 'skip'): + pytest.skip(self._obj.skip) if hasattr(self._testcase, 'setup_method'): self._testcase.setup_method(self._obj) diff -r 03438e53b03b1b138dfc9756068aa7ae25097887 -r 4a015a903b1650c15fed3c8283f67f8c46271127 testing/test_unittest.py --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -232,6 +232,29 @@ reprec.assertoutcome(skipped=1) +def test_testcase_skip_property(testdir): + testpath = testdir.makepyfile(""" + import unittest + class MyTestCase(unittest.TestCase): + skip = 'dont run' + def test_func(self): + pass + """) + reprec = testdir.inline_run(testpath, "-s") + reprec.assertoutcome(skipped=1) + +def test_testfunction_skip_property(testdir): + testpath = testdir.makepyfile(""" + import unittest + class MyTestCase(unittest.TestCase): + def test_func(self): + pass + test_func.skip = 'dont run' + """) + reprec = testdir.inline_run(testpath, "-s") + reprec.assertoutcome(skipped=1) + + class TestTrialUnittest: def setup_class(cls): pytest.importorskip("twisted.trial.unittest") Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Fri Dec 2 22:05:50 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Fri, 02 Dec 2011 21:05:50 -0000 Subject: [py-svn] commit/pytest-xdist: 2 new changesets Message-ID: <20111202210550.14943.72512@bitbucket13.managed.contegix.com> 2 new commits in pytest-xdist: https://bitbucket.org/hpk42/pytest-xdist/changeset/b92fb2f2a998/ changeset: b92fb2f2a998 user: hpk42 date: 2011-12-02 22:03:29 summary: fix issue 93 of pytest - avoid delayed teardowns affected #: 9 files diff -r 247b401a756ad6a0c5f73206b8bb5f0182057783 -r b92fb2f2a998db9de2a881dd7d6cd70e611b685a CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +1.8 +------------------------- + +- fix pytest-issue93 - use the refined pytest-2.2.1 runtestprotocol + interface to perform eager teardowns for test items. + 1.7 ------------------------- diff -r 247b401a756ad6a0c5f73206b8bb5f0182057783 -r b92fb2f2a998db9de2a881dd7d6cd70e611b685a setup.py --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name="pytest-xdist", - version='1.7', + version='1.8.dev1', description='py.test xdist plugin for distributed testing and loop-on-failing modes', long_description=open('README.txt').read(), license='GPLv2 or later', @@ -13,7 +13,7 @@ packages = ['xdist'], entry_points = {'pytest11': ['xdist = xdist.plugin'],}, zip_safe=False, - install_requires = ['execnet>=1.0.8', 'pytest>=2.2.0'], + install_requires = ['execnet>=1.0.8', 'pytest>=2.2.1.dev1'], classifiers=[ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', diff -r 247b401a756ad6a0c5f73206b8bb5f0182057783 -r b92fb2f2a998db9de2a881dd7d6cd70e611b685a testing/test_dsession.py --- a/testing/test_dsession.py +++ b/testing/test_dsession.py @@ -48,11 +48,11 @@ assert sched.node2collection[node1] == collection assert sched.node2collection[node2] == collection sched.init_distribute() - assert not sched.tests_finished() + assert sched.tests_finished() assert node1.sent == ['ALL'] assert node2.sent == ['ALL'] sched.remove_item(node1, collection[0]) - assert not sched.tests_finished() + assert sched.tests_finished() sched.remove_item(node2, collection[0]) assert sched.tests_finished() @@ -66,7 +66,7 @@ assert sched.collection_is_completed assert sched.node2collection[node1] == collection sched.init_distribute() - assert not sched.tests_finished() + assert sched.tests_finished() crashitem = sched.remove_node(node1) assert crashitem assert sched.tests_finished() @@ -88,7 +88,7 @@ assert sched.node2collection[node1] == collection assert sched.node2collection[node2] == collection sched.init_distribute() - assert not sched.tests_finished() + assert sched.tests_finished() assert len(node1.sent) == 1 assert len(node2.sent) == 1 x = sorted(node1.sent + node2.sent) @@ -109,6 +109,7 @@ sched.addnode_collection(node1, col) sched.addnode_collection(node2, col) sched.init_distribute() + #assert not sched.tests_finished() sent1 = node1.sent sent2 = node2.sent chunkitems = col[:sched.ITEM_CHUNKSIZE] diff -r 247b401a756ad6a0c5f73206b8bb5f0182057783 -r b92fb2f2a998db9de2a881dd7d6cd70e611b685a testing/test_remote.py --- a/testing/test_remote.py +++ b/testing/test_remote.py @@ -138,6 +138,7 @@ ids = ev.kwargs['ids'] assert len(ids) == 1 slave.sendcommand("runtests", ids=ids) + slave.sendcommand("shutdown") ev = slave.popevent("testreport") # setup ev = slave.popevent("testreport") assert ev.name == "testreport" @@ -145,7 +146,6 @@ assert rep.nodeid.endswith("::test_func") assert rep.passed assert rep.when == "call" - slave.sendcommand("shutdown") ev = slave.popevent("slavefinished") assert 'slaveoutput' in ev.kwargs diff -r 247b401a756ad6a0c5f73206b8bb5f0182057783 -r b92fb2f2a998db9de2a881dd7d6cd70e611b685a tox.ini --- a/tox.ini +++ b/tox.ini @@ -21,3 +21,4 @@ [pytest] addopts = -rsfxX +;; hello diff -r 247b401a756ad6a0c5f73206b8bb5f0182057783 -r b92fb2f2a998db9de2a881dd7d6cd70e611b685a xdist/__init__.py --- a/xdist/__init__.py +++ b/xdist/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '1.7' +__version__ = '1.8.dev1' diff -r 247b401a756ad6a0c5f73206b8bb5f0182057783 -r b92fb2f2a998db9de2a881dd7d6cd70e611b685a xdist/dsession.py --- a/xdist/dsession.py +++ b/xdist/dsession.py @@ -24,9 +24,6 @@ def tests_finished(self): if not self.collection_is_completed: return False - for items in self.node2pending.values(): - if items: - return False return True def addnode_collection(self, node, collection): @@ -79,9 +76,9 @@ def tests_finished(self): if not self.collection_is_completed or self.pending: return False - for items in self.node2pending.values(): - if items: - return False + #for items in self.node2pending.values(): + # if items: + # return False return True def addnode_collection(self, node, collection): @@ -107,7 +104,7 @@ pending.append(item) self.item2nodes.setdefault(item, []).append(node) node.send_runtest(item) - #self.log("items waiting for node: %d" %(len(self.pending))) + self.log("items waiting for node: %d" %(len(self.pending))) #self.log("item2pending still executing: %s" %(self.item2nodes,)) #self.log("node2pending: %s" %(self.node2pending,)) diff -r 247b401a756ad6a0c5f73206b8bb5f0182057783 -r b92fb2f2a998db9de2a881dd7d6cd70e611b685a xdist/remote.py --- a/xdist/remote.py +++ b/xdist/remote.py @@ -46,18 +46,26 @@ def pytest_runtestloop(self, session): self.log("entering main loop") + torun = [] while 1: name, kwargs = self.channel.receive() self.log("received command %s(**%s)" % (name, kwargs)) if name == "runtests": ids = kwargs['ids'] for nodeid in ids: - item = self._id2item[nodeid] - self.config.hook.pytest_runtest_protocol(item=item) + torun.append(self._id2item[nodeid]) elif name == "runtests_all": - for item in session.items: - self.config.hook.pytest_runtest_protocol(item=item) - elif name == "shutdown": + torun.extend(session.items) + self.log("items to run: %s" %(len(torun))) + while len(torun) >= 2: + item = torun.pop(0) + nextitem = torun[0] + self.config.hook.pytest_runtest_protocol(item=item, + nextitem=nextitem) + if name == "shutdown": + while torun: + self.config.hook.pytest_runtest_protocol( + item=torun.pop(0), nextitem=None) break return True @@ -118,7 +126,7 @@ config.option.numprocesses = None config.args = args return config - + if __name__ == '__channelexec__': slaveinput,args,option_dict = channel.receive() diff -r 247b401a756ad6a0c5f73206b8bb5f0182057783 -r b92fb2f2a998db9de2a881dd7d6cd70e611b685a xdist/slavemanage.py --- a/xdist/slavemanage.py +++ b/xdist/slavemanage.py @@ -183,7 +183,7 @@ raise ValueError("arg %s not relative to an rsync root" % (arg,)) l.append(splitcode.join(parts)) return l - + class SlaveController(object): ENDMARK = -1 @@ -237,8 +237,11 @@ self.sendcommand("runtests_all",) def shutdown(self): - if not self._down and not self.channel.isclosed(): - self.sendcommand("shutdown") + if not self._down: + try: + self.sendcommand("shutdown") + except IOError: + pass def sendcommand(self, name, **kwargs): """ send a named parametrized command to the other side. """ https://bitbucket.org/hpk42/pytest-xdist/changeset/6d23d5c1326f/ changeset: 6d23d5c1326f user: hpk42 date: 2011-12-02 22:03:58 summary: remove usage of final_logerrors now that we have better teardown information affected #: 6 files diff -r b92fb2f2a998db9de2a881dd7d6cd70e611b685a -r 6d23d5c1326f88b97066e5b1e950cc6950d9ee05 setup.py --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name="pytest-xdist", - version='1.8.dev1', + version='1.8.dev2', description='py.test xdist plugin for distributed testing and loop-on-failing modes', long_description=open('README.txt').read(), license='GPLv2 or later', @@ -13,7 +13,7 @@ packages = ['xdist'], entry_points = {'pytest11': ['xdist = xdist.plugin'],}, zip_safe=False, - install_requires = ['execnet>=1.0.8', 'pytest>=2.2.1.dev1'], + install_requires = ['execnet>=1.0.8', 'pytest>=2.2.1.dev2'], classifiers=[ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', @@ -27,4 +27,4 @@ 'Programming Language :: Python', 'Programming Language :: Python :: 3', ], -) \ No newline at end of file +) diff -r b92fb2f2a998db9de2a881dd7d6cd70e611b685a -r 6d23d5c1326f88b97066e5b1e950cc6950d9ee05 testing/acceptance_test.py --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -314,7 +314,7 @@ @py.test.mark.xfail def test_terminate_on_hangingnode(testdir): p = testdir.makeconftest(""" - def pytest__teardown_final(session): + def pytest_sessionfinishes(session): if session.nodeid == "my": # running on slave import time time.sleep(3) diff -r b92fb2f2a998db9de2a881dd7d6cd70e611b685a -r 6d23d5c1326f88b97066e5b1e950cc6950d9ee05 xdist/__init__.py --- a/xdist/__init__.py +++ b/xdist/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '1.8.dev1' +__version__ = '1.8.dev2' diff -r b92fb2f2a998db9de2a881dd7d6cd70e611b685a -r 6d23d5c1326f88b97066e5b1e950cc6950d9ee05 xdist/dsession.py --- a/xdist/dsession.py +++ b/xdist/dsession.py @@ -284,10 +284,6 @@ self.config.hook.pytest_runtest_logreport(report=rep) self._handlefailures(rep) - def slave_teardownreport(self, node, rep): - rep.node = node - self.config.hook.pytest__teardown_final_logerror(report=rep) - def slave_collectreport(self, node, rep): #self.report_line("collectreport %s: %s" %(rep.id, rep.status)) #rep.node = node diff -r b92fb2f2a998db9de2a881dd7d6cd70e611b685a -r 6d23d5c1326f88b97066e5b1e950cc6950d9ee05 xdist/remote.py --- a/xdist/remote.py +++ b/xdist/remote.py @@ -26,10 +26,6 @@ for line in str(excrepr).split("\n"): self.log("IERROR> " + line) - def pytest__teardown_final_logerror(self, report): - rep = serialize_report(report) - self.sendevent("teardownreport", data=rep) - def pytest_sessionstart(self, session): self.session = session slaveinfo = getinfodict() diff -r b92fb2f2a998db9de2a881dd7d6cd70e611b685a -r 6d23d5c1326f88b97066e5b1e950cc6950d9ee05 xdist/slavemanage.py --- a/xdist/slavemanage.py +++ b/xdist/slavemanage.py @@ -301,5 +301,3 @@ return runner.TestReport(**d) elif name == "collectreport": return runner.CollectReport(**d) - elif name == "teardownreport": - return runner.TeardownErrorReport(**d) Repository URL: https://bitbucket.org/hpk42/pytest-xdist/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Fri Dec 2 22:05:54 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Fri, 02 Dec 2011 21:05:54 -0000 Subject: [py-svn] commit/pytest: 2 new changesets Message-ID: <20111202210554.23596.98626@bitbucket03.managed.contegix.com> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/changeset/e4b9018a524e/ changeset: e4b9018a524e user: hpk42 date: 2011-12-02 22:00:19 summary: fix issue93 - avoid "delayed" teardowns for distributed testing by simplifying handling of teardowns. affected #: 8 files diff -r 4a015a903b1650c15fed3c8283f67f8c46271127 -r e4b9018a524e8176ae3a2970cb5cc84342b9188b CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,13 @@ +Changes between 2.2.0 and 2.2.1.dev +---------------------------------------- + +- fix issue93 (in pytest and pytest-xdist) avoid "delayed teardowns": + the final test in a test node will now run its teardown directly + instead of waiting for the end of the session. Thanks Dave Hunt for + the good reporting and feedback. The pytest_runtest_protocol as well + as the pytest_runtest_teardown hooks now have "nextitem" available + which will be None indicating the end of the test run. + Changes between 2.1.3 and 2.2.0 ---------------------------------------- diff -r 4a015a903b1650c15fed3c8283f67f8c46271127 -r e4b9018a524e8176ae3a2970cb5cc84342b9188b _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.2.0' +__version__ = '2.2.1.dev1' diff -r 4a015a903b1650c15fed3c8283f67f8c46271127 -r e4b9018a524e8176ae3a2970cb5cc84342b9188b _pytest/hookspec.py --- a/_pytest/hookspec.py +++ b/_pytest/hookspec.py @@ -121,16 +121,23 @@ def pytest_itemstart(item, node=None): """ (deprecated, use pytest_runtest_logstart). """ -def pytest_runtest_protocol(item): - """ implements the standard runtest_setup/call/teardown protocol including - capturing exceptions and calling reporting hooks on the results accordingly. +def pytest_runtest_protocol(item, nextitem): + """ implements the runtest_setup/call/teardown protocol for + the given test item, including capturing exceptions and calling + reporting hooks. + + :arg item: test item for which the runtest protocol is performed. + + :arg nexitem: the scheduled-to-be-next test item (or None if this + is the end my friend). This argument is passed on to + :py:func:`pytest_runtest_teardown`. :return boolean: True if no further hook implementations should be invoked. """ pytest_runtest_protocol.firstresult = True def pytest_runtest_logstart(nodeid, location): - """ signal the start of a test run. """ + """ signal the start of running a single test item. """ def pytest_runtest_setup(item): """ called before ``pytest_runtest_call(item)``. """ @@ -138,8 +145,14 @@ def pytest_runtest_call(item): """ called to execute the test ``item``. """ -def pytest_runtest_teardown(item): - """ called after ``pytest_runtest_call``. """ +def pytest_runtest_teardown(item, nextitem): + """ called after ``pytest_runtest_call``. + + :arg nexitem: the scheduled-to-be-next test item (None if no further + test item is scheduled). This argument can be used to + perform exact teardowns, i.e. calling just enough finalizers + so that nextitem only needs to call setup-functions. + """ def pytest_runtest_makereport(item, call): """ return a :py:class:`_pytest.runner.TestReport` object diff -r 4a015a903b1650c15fed3c8283f67f8c46271127 -r e4b9018a524e8176ae3a2970cb5cc84342b9188b _pytest/main.py --- a/_pytest/main.py +++ b/_pytest/main.py @@ -106,8 +106,12 @@ def pytest_runtestloop(session): if session.config.option.collectonly: return True - for item in session.items: - item.config.hook.pytest_runtest_protocol(item=item) + for i, item in enumerate(session.items): + try: + nextitem = session.items[i+1] + except IndexError: + nextitem = None + item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem) if session.shouldstop: raise session.Interrupted(session.shouldstop) return True diff -r 4a015a903b1650c15fed3c8283f67f8c46271127 -r e4b9018a524e8176ae3a2970cb5cc84342b9188b _pytest/runner.py --- a/_pytest/runner.py +++ b/_pytest/runner.py @@ -59,33 +59,20 @@ def __init__(self, location): self.location = location -def perform_pending_teardown(config, nextitem): - try: - olditem, log = config._pendingteardown - except AttributeError: - pass - else: - del config._pendingteardown - olditem.nextitem = nextitem - call_and_report(olditem, "teardown", log) - -def pytest_runtest_protocol(item): - perform_pending_teardown(item.config, item) +def pytest_runtest_protocol(item, nextitem): item.ihook.pytest_runtest_logstart( nodeid=item.nodeid, location=item.location, ) - runtestprotocol(item, teardowndelayed=True) + runtestprotocol(item, nextitem=nextitem) return True -def runtestprotocol(item, log=True, teardowndelayed=False): +def runtestprotocol(item, log=True, nextitem=None): rep = call_and_report(item, "setup", log) reports = [rep] if rep.passed: reports.append(call_and_report(item, "call", log)) - if teardowndelayed: - item.config._pendingteardown = item, log - else: - reports.append(call_and_report(item, "teardown", log)) + reports.append(call_and_report(item, "teardown", log, + nextitem=nextitem)) return reports def pytest_runtest_setup(item): @@ -94,17 +81,8 @@ def pytest_runtest_call(item): item.runtest() -def pytest_runtest_teardown(item): - item.session._setupstate.teardown_exact(item) - -def pytest__teardown_final(session): - perform_pending_teardown(session.config, None) - #call = CallInfo(session._setupstate.teardown_all, when="teardown") - #if call.excinfo: - # ntraceback = call.excinfo.traceback .cut(excludepath=py._pydir) - # call.excinfo.traceback = ntraceback.filter() - # longrepr = call.excinfo.getrepr(funcargs=True) - # return TeardownErrorReport(longrepr) +def pytest_runtest_teardown(item, nextitem): + item.session._setupstate.teardown_exact(item, nextitem) def pytest_report_teststatus(report): if report.when in ("setup", "teardown"): @@ -120,18 +98,18 @@ # # Implementation -def call_and_report(item, when, log=True): - call = call_runtest_hook(item, when) +def call_and_report(item, when, log=True, **kwds): + call = call_runtest_hook(item, when, **kwds) hook = item.ihook report = hook.pytest_runtest_makereport(item=item, call=call) if log: hook.pytest_runtest_logreport(report=report) return report -def call_runtest_hook(item, when): +def call_runtest_hook(item, when, **kwds): hookname = "pytest_runtest_" + when ihook = getattr(item.ihook, hookname) - return CallInfo(lambda: ihook(item=item), when=when) + return CallInfo(lambda: ihook(item=item, **kwds), when=when) class CallInfo: """ Result/Exception info a function invocation. """ @@ -338,9 +316,8 @@ self._teardown_with_finalization(None) assert not self._finalizers - def teardown_exact(self, item): - colitem = item.nextitem - needed_collectors = colitem and colitem.listchain() or [] + def teardown_exact(self, item, nextitem): + needed_collectors = nextitem and nextitem.listchain() or [] self._teardown_towards(needed_collectors) def _teardown_towards(self, needed_collectors): diff -r 4a015a903b1650c15fed3c8283f67f8c46271127 -r e4b9018a524e8176ae3a2970cb5cc84342b9188b setup.py --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.2.0', + version='2.2.1.dev1', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], @@ -70,4 +70,4 @@ return {'console_scripts': l} if __name__ == '__main__': - main() + main() \ No newline at end of file diff -r 4a015a903b1650c15fed3c8283f67f8c46271127 -r e4b9018a524e8176ae3a2970cb5cc84342b9188b testing/test_python.py --- a/testing/test_python.py +++ b/testing/test_python.py @@ -689,7 +689,7 @@ teardownlist = item.getparent(pytest.Module).obj.teardownlist ss = item.session._setupstate assert not teardownlist - ss.teardown_exact(item) + ss.teardown_exact(item, None) print(ss.stack) assert teardownlist == [1] diff -r 4a015a903b1650c15fed3c8283f67f8c46271127 -r e4b9018a524e8176ae3a2970cb5cc84342b9188b testing/test_runner.py --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -30,9 +30,9 @@ def test_teardown_exact_stack_empty(self, testdir): item = testdir.getitem("def test_func(): pass") ss = runner.SetupState() - ss.teardown_exact(item) - ss.teardown_exact(item) - ss.teardown_exact(item) + ss.teardown_exact(item, None) + ss.teardown_exact(item, None) + ss.teardown_exact(item, None) def test_setup_fails_and_failure_is_cached(self, testdir): item = testdir.getitem(""" https://bitbucket.org/hpk42/pytest/changeset/ff737e56f188/ changeset: ff737e56f188 user: hpk42 date: 2011-12-02 22:00:21 summary: yay! now that we have perfect teardowns we don't need some ugly internal hooks anymore. affected #: 6 files diff -r e4b9018a524e8176ae3a2970cb5cc84342b9188b -r ff737e56f1881a9bd7169b145b39fdb26052e421 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.2.1.dev1' +__version__ = '2.2.1.dev2' diff -r e4b9018a524e8176ae3a2970cb5cc84342b9188b -r ff737e56f1881a9bd7169b145b39fdb26052e421 _pytest/hookspec.py --- a/_pytest/hookspec.py +++ b/_pytest/hookspec.py @@ -165,14 +165,6 @@ """ process a test setup/call/teardown report relating to the respective phase of executing a test. """ -# special handling for final teardown - somewhat internal for now -def pytest__teardown_final(session): - """ called before test session finishes. """ -pytest__teardown_final.firstresult = True - -def pytest__teardown_final_logerror(report, session): - """ called if runtest_teardown_final failed. """ - # ------------------------------------------------------------------------- # test session related hooks # ------------------------------------------------------------------------- diff -r e4b9018a524e8176ae3a2970cb5cc84342b9188b -r ff737e56f1881a9bd7169b145b39fdb26052e421 _pytest/runner.py --- a/_pytest/runner.py +++ b/_pytest/runner.py @@ -48,13 +48,6 @@ def pytest_sessionstart(session): session._setupstate = SetupState() -def pytest_sessionfinish(session, exitstatus): - hook = session.config.hook - rep = hook.pytest__teardown_final(session=session) - if rep: - hook.pytest__teardown_final_logerror(session=session, report=rep) - session.exitstatus = 1 - class NodeInfo: def __init__(self, location): self.location = location diff -r e4b9018a524e8176ae3a2970cb5cc84342b9188b -r ff737e56f1881a9bd7169b145b39fdb26052e421 _pytest/terminal.py --- a/_pytest/terminal.py +++ b/_pytest/terminal.py @@ -161,9 +161,6 @@ def pytest_deselected(self, items): self.stats.setdefault('deselected', []).extend(items) - def pytest__teardown_final_logerror(self, report): - self.stats.setdefault("error", []).append(report) - def pytest_runtest_logstart(self, nodeid, location): # ensure that the path is printed before the # 1st test of a module starts running diff -r e4b9018a524e8176ae3a2970cb5cc84342b9188b -r ff737e56f1881a9bd7169b145b39fdb26052e421 setup.py --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.2.1.dev1', + version='2.2.1.dev2', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff -r e4b9018a524e8176ae3a2970cb5cc84342b9188b -r ff737e56f1881a9bd7169b145b39fdb26052e421 testing/test_capture.py --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -205,7 +205,7 @@ #"*1 fixture failure*" ]) - def test_teardown_final_capturing(self, testdir): + def test_teardown_capturing_final(self, testdir): p = testdir.makepyfile(""" def teardown_module(mod): print ("teardown module") Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Mon Dec 5 11:52:47 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Mon, 05 Dec 2011 10:52:47 -0000 Subject: [py-svn] commit/pytest: jurko: Documentation cleanup - corrected typos & minor stylistic changes. Message-ID: <20111205105247.337.59791@bitbucket12.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/896c7b1b455b/ changeset: 896c7b1b455b user: jurko date: 2011-12-05 11:10:48 summary: Documentation cleanup - corrected typos & minor stylistic changes. affected #: 20 files diff -r ff737e56f1881a9bd7169b145b39fdb26052e421 -r 896c7b1b455b435848d8957445edd18c0741c061 _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -588,8 +588,8 @@ self._ids = py.builtin.set() def parametrize(self, argnames, argvalues, indirect=False, ids=None): - """ add new invocations to the underlying test function using the - list of argvalues for the given argnames. Parametrization is performed + """ Add new invocations to the underlying test function using the list + of argvalues for the given argnames. Parametrization is performed during the collection phase. If you need to setup expensive resources you may pass indirect=True and implement a funcarg factory which can perform the expensive setup just before a test is actually run. @@ -599,14 +599,14 @@ :arg argvalues: a list of values for the argname or a list of tuples of values for the list of argument names. - :arg indirect: if True each argvalue corresponding to an argument will be - passed as request.param to its respective funcarg factory so that - it can perform more expensive setups during the setup phase of + :arg indirect: if True each argvalue corresponding to an argument will + be passed as request.param to its respective funcarg factory so + that it can perform more expensive setups during the setup phase of a test rather than at collection time. - :arg ids: list of string ids each corresponding to the argvalues - so that they are part of the test id. If no ids are provided - they will be generated automatically from the argvalues. + :arg ids: list of string ids each corresponding to the argvalues so + that they are part of the test id. If no ids are provided they will + be generated automatically from the argvalues. """ if not isinstance(argnames, (tuple, list)): argnames = (argnames,) @@ -628,12 +628,11 @@ self._calls = newcalls def addcall(self, funcargs=None, id=_notexists, param=_notexists): - """ (deprecated, use parametrize) add a new call to the underlying - test function during - the collection phase of a test run. Note that request.addcall() is - called during the test collection phase prior and independently - to actual test execution. You should only use addcall() - if you need to specify multiple arguments of a test function + """ (deprecated, use parametrize) Add a new call to the underlying + test function during the collection phase of a test run. Note that + request.addcall() is called during the test collection phase prior and + independently to actual test execution. You should only use addcall() + if you need to specify multiple arguments of a test function. :arg funcargs: argument keyword dictionary used when invoking the test function. @@ -750,7 +749,7 @@ def applymarker(self, marker): - """ apply a marker to a single test function invocation. + """ Apply a marker to a single test function invocation. This method is useful if you don't want to have a keyword/marker on all function invocations. @@ -762,7 +761,7 @@ self._pyfuncitem.keywords[marker.markname] = marker def cached_setup(self, setup, teardown=None, scope="module", extrakey=None): - """ return a testing resource managed by ``setup`` & + """ Return a testing resource managed by ``setup`` & ``teardown`` calls. ``scope`` and ``extrakey`` determine when the ``teardown`` function will be called so that subsequent calls to ``setup`` would recreate the resource. @@ -937,8 +936,7 @@ >>> raises(ZeroDivisionError, f, x=0) - A third possibility is to use a string which which will - be executed:: + A third possibility is to use a string to be executed:: >>> raises(ZeroDivisionError, "f(0)") diff -r ff737e56f1881a9bd7169b145b39fdb26052e421 -r 896c7b1b455b435848d8957445edd18c0741c061 doc/announce/release-2.0.2.txt --- a/doc/announce/release-2.0.2.txt +++ b/doc/announce/release-2.0.2.txt @@ -1,4 +1,4 @@ -py.test 2.0.2: bug fixes, improved xfail/skip expressions, speedups +py.test 2.0.2: bug fixes, improved xfail/skip expressions, speed ups =========================================================================== Welcome to pytest-2.0.2, a maintenance and bug fix release of pytest, @@ -32,17 +32,17 @@ Also you can now access module globals from xfail/skipif expressions so that this for example works now:: - + import pytest import mymodule @pytest.mark.skipif("mymodule.__version__[0] == "1") def test_function(): pass - This will not run the test function if the module's version string + This will not run the test function if the module's version string does not start with a "1". Note that specifying a string instead - of a boolean expressions allows py.test to report meaningful information - when summarizing a test run as to what conditions lead to skipping + of a boolean expressions allows py.test to report meaningful information + when summarizing a test run as to what conditions lead to skipping (or xfail-ing) tests. - fix issue28 - setup_method and pytest_generate_tests work together @@ -65,7 +65,7 @@ - fixed typos in the docs (thanks Victor Garcia, Brianna Laugher) and particular thanks to Laura Creighton who also revieved parts of the documentation. -- fix slighly wrong output of verbose progress reporting for classes +- fix slighly wrong output of verbose progress reporting for classes (thanks Amaury) - more precise (avoiding of) deprecation warnings for node.Class|Function accesses diff -r ff737e56f1881a9bd7169b145b39fdb26052e421 -r 896c7b1b455b435848d8957445edd18c0741c061 doc/announce/release-2.1.0.txt --- a/doc/announce/release-2.1.0.txt +++ b/doc/announce/release-2.1.0.txt @@ -1,7 +1,7 @@ py.test 2.1.0: perfected assertions and bug fixes =========================================================================== -Welcome to the relase of pytest-2.1, a mature testing tool for Python, +Welcome to the release of pytest-2.1, a mature testing tool for Python, supporting CPython 2.4-3.2, Jython and latest PyPy interpreters. See the improved extensive docs (now also as PDF!) with tested examples here: @@ -15,7 +15,7 @@ See http://pytest.org/assert.html#advanced-assertion-introspection for detailed information. The work has been partly sponsored by my company, merlinux GmbH. - + For further details on bug fixes and smaller enhancements see below. If you want to install or upgrade pytest, just type one of:: @@ -39,10 +39,9 @@ unexpected exceptions - fix issue47: timing output in junitxml for test cases is now correct - fix issue48: typo in MarkInfo repr leading to exception -- fix issue49: avoid confusing error when initizaliation partially fails +- fix issue49: avoid confusing error when initialization partially fails - fix issue44: env/username expansion for junitxml file path - show releaselevel information in test runs for pypy - reworked doc pages for better navigation and PDF generation - report KeyboardInterrupt even if interrupted during session startup - fix issue 35 - provide PDF doc version and download link from index page - diff -r ff737e56f1881a9bd7169b145b39fdb26052e421 -r 896c7b1b455b435848d8957445edd18c0741c061 doc/announce/release-2.2.0.txt --- a/doc/announce/release-2.2.0.txt +++ b/doc/announce/release-2.2.0.txt @@ -2,7 +2,7 @@ =========================================================================== pytest-2.2.0 is a test-suite compatible release of the popular -py.test testing tool. Plugins might need upgrades. It comes +py.test testing tool. Plugins might need upgrades. It comes with these improvements: * easier and more powerful parametrization of tests: @@ -20,11 +20,11 @@ - the new "--strict" bails out with an error if using unregistered markers. - see examples at http://pytest.org/latest/example/markers.html -* duration profiling: new "--duration=N" option showing the N slowest test +* duration profiling: new "--duration=N" option showing the N slowest test execution or setup/teardown calls. This is most useful if you want to find out where your slowest test code is. -* also 2.2.0 performs more eager calling of teardown/finalizers functions +* also 2.2.0 performs more eager calling of teardown/finalizers functions resulting in better and more accurate reporting when they fail Besides there is the usual set of bug fixes along with a cleanup of @@ -50,14 +50,14 @@ While test suites should work unchanged you might need to upgrade plugins: -* You need a new version of the pytest-xdist plugin (1.7) for distributing - test runs. +* You need a new version of the pytest-xdist plugin (1.7) for distributing + test runs. * Other plugins might need an upgrade if they implement the ``pytest_runtest_logreport`` hook which now is called unconditionally for the setup/teardown fixture phases of a test. You may choose to ignore setup/teardown failures by inserting "if rep.when != 'call': return" - or something similar. Note that most code probably "just" works because + or something similar. Note that most code probably "just" works because the hook was already called for failing setup/teardown phases of a test so a plugin should have been ready to grok such reports already. @@ -67,29 +67,29 @@ - fix issue90: introduce eager tearing down of test items so that teardown function are called earlier. -- add an all-powerful metafunc.parametrize function which allows to +- add an all-powerful metafunc.parametrize function which allows to parametrize test function arguments in multiple steps and therefore - from indepdenent plugins and palces. + from independent plugins and places. - add a @pytest.mark.parametrize helper which allows to easily - call a test function with different argument values -- Add examples to the "parametrize" example page, including a quick port + call a test function with different argument values. +- Add examples to the "parametrize" example page, including a quick port of Test scenarios and the new parametrize function and decorator. - introduce registration for "pytest.mark.*" helpers via ini-files - or through plugin hooks. Also introduce a "--strict" option which + or through plugin hooks. Also introduce a "--strict" option which will treat unregistered markers as errors allowing to avoid typos and maintain a well described set of markers - for your test suite. See exaples at http://pytest.org/latest/mark.html + for your test suite. See examples at http://pytest.org/latest/mark.html and its links. - issue50: introduce "-m marker" option to select tests based on markers - (this is a stricter and more predictable version of '-k' in that "-m" + (this is a stricter and more predictable version of "-k" in that "-m" only matches complete markers and has more obvious rules for and/or semantics. -- new feature to help optimizing the speed of your tests: - --durations=N option for displaying N slowest test calls +- new feature to help optimizing the speed of your tests: + --durations=N option for displaying N slowest test calls and setup/teardown methods. - fix issue87: --pastebin now works with python3 - fix issue89: --pdb with unexpected exceptions in doctest work more sensibly -- fix and cleanup pytest's own test suite to not leak FDs +- fix and cleanup pytest's own test suite to not leak FDs - fix issue83: link to generated funcarg list - fix issue74: pyarg module names are now checked against imp.find_module false positives - fix compatibility with twisted/trial-11.1.0 use cases diff -r ff737e56f1881a9bd7169b145b39fdb26052e421 -r 896c7b1b455b435848d8957445edd18c0741c061 doc/assert.txt --- a/doc/assert.txt +++ b/doc/assert.txt @@ -73,7 +73,7 @@ # do checks related to excinfo.type, excinfo.value, excinfo.traceback -If you want to write test code that works on Python2.4 as well, +If you want to write test code that works on Python 2.4 as well, you may also use two other ways to test for an expected exception:: pytest.raises(ExpectedException, func, *args, **kwargs) diff -r ff737e56f1881a9bd7169b145b39fdb26052e421 -r 896c7b1b455b435848d8957445edd18c0741c061 doc/customize.txt --- a/doc/customize.txt +++ b/doc/customize.txt @@ -64,13 +64,13 @@ .. confval:: minversion - specifies a minimal pytest version required for running tests. + Specifies a minimal pytest version required for running tests. minversion = 2.1 # will fail if we run with pytest-2.0 .. confval:: addopts - add the specified ``OPTS`` to the set of command line arguments as if they + Add the specified ``OPTS`` to the set of command line arguments as if they had been specified by the user. Example: if you have this ini file content:: [pytest] @@ -121,4 +121,3 @@ and methods are considered as test modules. See :ref:`change naming conventions` for examples. - diff -r ff737e56f1881a9bd7169b145b39fdb26052e421 -r 896c7b1b455b435848d8957445edd18c0741c061 doc/example/index.txt --- a/doc/example/index.txt +++ b/doc/example/index.txt @@ -9,7 +9,7 @@ .. note:: - see :doc:`../getting-started` for basic introductionary examples + see :doc:`../getting-started` for basic introductory examples .. toctree:: :maxdepth: 2 diff -r ff737e56f1881a9bd7169b145b39fdb26052e421 -r 896c7b1b455b435848d8957445edd18c0741c061 doc/example/markers.txt --- a/doc/example/markers.txt +++ b/doc/example/markers.txt @@ -6,7 +6,7 @@ Here are some example using the :ref:`mark` mechanism. -marking test functions and selecting them for a run +Marking test functions and selecting them for a run ---------------------------------------------------- You can "mark" a test function with custom metadata like this:: @@ -57,8 +57,8 @@ # content of pytest.ini [pytest] - markers = - webtest: mark a test as a webtest. + markers = + webtest: mark a test as a webtest. You can ask which markers exist for your test suite - the list includes our just defined ``webtest`` markers:: @@ -76,7 +76,7 @@ @pytest.mark.trylast: mark a hook implementation function such that the plugin machinery will try to call it last/as late as possible. -For an example on how to add and work with markers from a plugin, see +For an example on how to add and work with markers from a plugin, see :ref:`adding a custom marker from a plugin`. .. note:: @@ -96,8 +96,8 @@ Marking whole classes or modules ---------------------------------------------------- -If you are programming with Python2.6 you may use ``pytest.mark`` decorators -with classes to apply markers to all of its test methods:: +If you are programming with Python 2.6 or later you may use ``pytest.mark`` +decorators with classes to apply markers to all of its test methods:: # content of test_mark_classlevel.py import pytest @@ -111,7 +111,7 @@ This is equivalent to directly applying the decorator to the two test functions. -To remain backward-compatible with Python2.4 you can also set a +To remain backward-compatible with Python 2.4 you can also set a ``pytestmark`` attribute on a TestClass like this:: import pytest @@ -137,7 +137,8 @@ Using ``-k TEXT`` to select tests ---------------------------------------------------- -You can use the ``-k`` command line option to only run tests with names that match the given argument:: +You can use the ``-k`` command line option to only run tests with names matching +the given argument:: $ py.test -k send_http # running with the above defined examples ============================= test session starts ============================== @@ -176,7 +177,7 @@ .. _`adding a custom marker from a plugin`: -custom marker and command line option to control test runs +Custom marker and command line option to control test runs ---------------------------------------------------------- .. regendoc:wipe @@ -195,7 +196,7 @@ def pytest_configure(config): # register an additional marker - config.addinivalue_line("markers", + config.addinivalue_line("markers", "env(name): mark test to run only on named environment") def pytest_runtest_setup(item): diff -r ff737e56f1881a9bd7169b145b39fdb26052e421 -r 896c7b1b455b435848d8957445edd18c0741c061 doc/example/mysetup.txt --- a/doc/example/mysetup.txt +++ b/doc/example/mysetup.txt @@ -38,7 +38,7 @@ def myapp(self): return MyApp() -To run the example we stub out a a simple ``MyApp`` application object:: +To run the example we stub out a simple ``MyApp`` application object:: # content of myapp.py class MyApp: diff -r ff737e56f1881a9bd7169b145b39fdb26052e421 -r 896c7b1b455b435848d8957445edd18c0741c061 doc/example/nonpython.txt --- a/doc/example/nonpython.txt +++ b/doc/example/nonpython.txt @@ -51,8 +51,8 @@ representation string of your choice. It will be reported as a (red) string. -``reportinfo()`` is used for representing the test location and is also consulted for -reporting in ``verbose`` mode:: +``reportinfo()`` is used for representing the test location and is also +consulted when reporting in ``verbose`` mode:: nonpython $ py.test -v =========================== test session starts ============================ diff -r ff737e56f1881a9bd7169b145b39fdb26052e421 -r 896c7b1b455b435848d8957445edd18c0741c061 doc/example/parametrize.txt --- a/doc/example/parametrize.txt +++ b/doc/example/parametrize.txt @@ -12,12 +12,12 @@ .. _parametrizemark: -simple "decorator" parametrization of a test function +Simple "decorator" parametrization of a test function ---------------------------------------------------------------------------- .. versionadded:: 2.2 -The builtin ``pytest.mark.parametrize`` decorator directly enables +The builtin ``pytest.mark.parametrize`` decorator directly enables parametrization of arguments for a test function. Here is an example of a test function that wants to compare that processing some input results in expected output:: @@ -32,7 +32,7 @@ def test_eval(input, expected): assert eval(input) == expected -we parametrize two arguments of the test function so that the test +we parametrize two arguments of the test function so that the test function is called three times. Let's run it:: $ py.test -q @@ -119,12 +119,12 @@ As expected when running the full range of ``param1`` values we'll get an error on the last one. -a quick port of "testscenarios" +A quick port of "testscenarios" ------------------------------------ .. _`test scenarios`: http://bazaar.launchpad.net/~lifeless/testscenarios/trunk/annotate/head%3A/doc/example.py -Here is a quick port of to run tests configured with `test scenarios`_, +Here is a quick port to run tests configured with `test scenarios`_, an add-on from Robert Collins for the standard unittest framework. We only have to work a bit to construct the correct arguments for pytest's :py:func:`Metafunc.parametrize`:: @@ -183,12 +183,12 @@ The parametrization of test functions happens at collection time. It is a good idea to setup expensive resources like DB -connections or subprocess only when the actual test is run. -Here is a simple example how you can achieve that, first +connections or subprocess only when the actual test is run. +Here is a simple example how you can achieve that, first the actual test requiring a ``db`` object:: # content of test_backends.py - + import pytest def test_db_initialized(db): # a dummy test @@ -209,7 +209,7 @@ "one database object" class DB2: "alternative database object" - + def pytest_funcarg__db(request): if request.param == "d1": return DB1() @@ -260,7 +260,7 @@ Here is an example ``pytest_generate_function`` function implementing a -parametrization scheme similar to Michael Foords `unittest +parametrization scheme similar to Michael Foord's `unittest parameterizer`_ but in a lot less code:: # content of ./test_parametrize.py @@ -270,7 +270,7 @@ # called once per each test function funcarglist = metafunc.cls.params[metafunc.function.__name__] argnames = list(funcarglist[0]) - metafunc.parametrize(argnames, [[funcargs[name] for name in argnames] + metafunc.parametrize(argnames, [[funcargs[name] for name in argnames] for funcargs in funcarglist]) class TestClass: @@ -313,7 +313,7 @@ with different sets of arguments for its three arguments: * ``python1``: first python interpreter, run to pickle-dump an object to a file -* ``python2``: second interpreter, run to pickle-load an object from a file +* ``python2``: second interpreter, run to pickle-load an object from a file * ``obj``: object to be dumped/loaded .. literalinclude:: multipython.py diff -r ff737e56f1881a9bd7169b145b39fdb26052e421 -r 896c7b1b455b435848d8957445edd18c0741c061 doc/example/simple.txt --- a/doc/example/simple.txt +++ b/doc/example/simple.txt @@ -240,9 +240,9 @@ # called from within a test run else: # called "normally" - + accordingly in your application. It's also a good idea -to rather use your own application module rather than ``sys`` +to use your own application module rather than ``sys`` for handling flag. Adding info to test report header @@ -275,7 +275,7 @@ you present more information appropriately:: # content of conftest.py - + def pytest_report_header(config): if config.option.verbose > 0: return ["info1: did you know that ...", "did you?"] @@ -308,22 +308,22 @@ .. versionadded: 2.2 If you have a slow running large test suite you might want to find -out which tests are slowest. Let's make an artifical test suite:: +out which tests are the slowest. Let's make an artifical test suite:: # content of test_some_are_slow.py - - import time + + import time def test_funcfast(): pass - + def test_funcslow1(): time.sleep(0.1) - + def test_funcslow2(): time.sleep(0.2) - -Now we can profile which test functions execute slowest:: + +Now we can profile which test functions execute the slowest:: $ py.test --durations=3 =========================== test session starts ============================ diff -r ff737e56f1881a9bd7169b145b39fdb26052e421 -r 896c7b1b455b435848d8957445edd18c0741c061 doc/faq.txt --- a/doc/faq.txt +++ b/doc/faq.txt @@ -18,7 +18,7 @@ TAB-completion. If you install ``pip install pycmd`` you get these tools from a separate package. These days the command line tool could be called ``pytest`` -since many people have gotten used to the old name and there +but since many people have gotten used to the old name and there is another tool named "pytest" we just decided to stick with ``py.test``. @@ -47,14 +47,14 @@ ``py.test`` still uses many metaprogramming techniques and reading its source is thus likely not something for Python beginners. -A second "magic" issue arguably the assert statement debugging feature. When +A second "magic" issue is arguably the assert statement debugging feature. When loading test modules py.test rewrites the source code of assert statements. When a rewritten assert statement fails, its error message has more information than the original. py.test also has a second assert debugging technique. When an ``assert`` statement that was missed by the rewriter fails, py.test re-interprets the expression to show intermediate values if a test fails. This -second technique suffers from caveat that the rewriting does not: If your -expression has side effects (better to avoid them anyway!) the intermediate +second technique suffers from a caveat that the rewriting does not: If your +expression has side effects (better to avoid them anyway!) the intermediate values may not be the same, confusing the reinterpreter and obfuscating the initial error (this is also explained at the command line if it happens). You can turn off all assertion debugging with ``py.test --assertmode=off``. @@ -91,8 +91,8 @@ We like `Convention over Configuration`_ and didn't see much point in allowing a more flexible or abstract mechanism. Moreover, -is is nice to be able to search for ``pytest_funcarg__MYARG`` in -a source code and safely find all factory functions for +it is nice to be able to search for ``pytest_funcarg__MYARG`` in +source code and safely find all factory functions for the ``MYARG`` function argument. .. _`Convention over Configuration`: http://en.wikipedia.org/wiki/Convention_over_Configuration diff -r ff737e56f1881a9bd7169b145b39fdb26052e421 -r 896c7b1b455b435848d8957445edd18c0741c061 doc/funcargs.txt --- a/doc/funcargs.txt +++ b/doc/funcargs.txt @@ -16,7 +16,7 @@ also possible to run a test function multiple times with different objects. The basic mechanism for injecting objects is also called the -*funcarg mechanism* because objects are ultimatly injected +*funcarg mechanism* because objects are ultimately injected by calling a test function with it as an argument. Unlike the classical xUnit approach *funcargs* relate more to `Dependency Injection`_ because they help to de-couple test code from objects required for @@ -119,9 +119,9 @@ The funcarg **request** object ============================================= -Each funcarg factory receives a **request** object which is tied to a -specific test function call. A request object is passed to a funcarg -factory and provides access to test configuration and context: +Each funcarg factory receives a **request** object tied to a specific test +function call. A request object is passed to a funcarg factory and provides +access to test configuration and context: .. autoclass:: _pytest.python.FuncargRequest() :members: function,cls,module,keywords,config diff -r ff737e56f1881a9bd7169b145b39fdb26052e421 -r 896c7b1b455b435848d8957445edd18c0741c061 doc/goodpractises.txt --- a/doc/goodpractises.txt +++ b/doc/goodpractises.txt @@ -21,7 +21,7 @@ Use tox and Continuous Integration servers ------------------------------------------------- -If you frequently relase code to the public you +If you frequently release code to the public you may want to look into `tox`_, the virtualenv test automation tool and its `pytest support `_. The basic idea is to generate a JUnitXML file through the ``--junitxml=PATH`` option and have a continuous integration server like Jenkins_ pick it up @@ -30,7 +30,7 @@ .. _standalone: .. _`genscript method`: -Create a py.test standalone Script +Create a py.test standalone script ------------------------------------------- If you are a maintainer or application developer and want others @@ -159,7 +159,7 @@ * find ``basedir`` -- this is the first "upward" (towards the root) directory not containing an ``__init__.py``. If both the ``a`` - and ``b`` directories contain an ``__init__.py`` the basedir will + and ``b`` directories contain an ``__init__.py`` the basedir will be the parent dir of ``a``. * perform ``sys.path.insert(0, basedir)`` to make the test module diff -r ff737e56f1881a9bd7169b145b39fdb26052e421 -r 896c7b1b455b435848d8957445edd18c0741c061 doc/plugins.txt --- a/doc/plugins.txt +++ b/doc/plugins.txt @@ -264,7 +264,7 @@ by simply not specifying them. If you mistype argument names or the hook name itself you get an error showing the available arguments. -Initialisation, command line and configuration hooks +Initialization, command line and configuration hooks -------------------------------------------------------------------- .. currentmodule:: _pytest.hookspec diff -r ff737e56f1881a9bd7169b145b39fdb26052e421 -r 896c7b1b455b435848d8957445edd18c0741c061 doc/recwarn.txt --- a/doc/recwarn.txt +++ b/doc/recwarn.txt @@ -1,5 +1,5 @@ -Asserting deprecation and other warnings. +Asserting deprecation and other warnings ===================================================== The recwarn function argument @@ -35,4 +35,3 @@ def test_global(): pytest.deprecated_call(myfunction, 17) - diff -r ff737e56f1881a9bd7169b145b39fdb26052e421 -r 896c7b1b455b435848d8957445edd18c0741c061 doc/test/plugin/cov.txt --- a/doc/test/plugin/cov.txt +++ b/doc/test/plugin/cov.txt @@ -35,10 +35,11 @@ .. IMPORTANT:: - Ensure that you manually delete the init_covmain.pth file in your site-packages directory. + Ensure that you manually delete the init_covmain.pth file in your + site-packages directory. - This file starts coverage collection of subprocesses if appropriate during site initialisation - at python startup. + This file starts coverage collection of subprocesses if appropriate during + site initialization at python startup. Usage @@ -198,7 +199,7 @@ For subprocess measurement environment variables must make it from the main process to the subprocess. The python used by the subprocess must have pytest-cov installed. The subprocess must -do normal site initialisation so that the environment variables can be detected and coverage +do normal site initialization so that the environment variables can be detected and coverage started. diff -r ff737e56f1881a9bd7169b145b39fdb26052e421 -r 896c7b1b455b435848d8957445edd18c0741c061 doc/usage.txt --- a/doc/usage.txt +++ b/doc/usage.txt @@ -96,11 +96,11 @@ .. versionadded: 2.0.0 In previous versions you could only enter PDB tracing if -you disable capturing on the command line via ``py.test -s``. +you disabled capturing on the command line via ``py.test -s``. .. _durations: -Profiling test execution duration +Profiling test execution duration ------------------------------------- .. versionadded: 2.2 diff -r ff737e56f1881a9bd7169b145b39fdb26052e421 -r 896c7b1b455b435848d8957445edd18c0741c061 doc/xunit_setup.txt --- a/doc/xunit_setup.txt +++ b/doc/xunit_setup.txt @@ -24,13 +24,11 @@ which will usually be called once for all the functions:: def setup_module(module): - """ setup up any state specific to the execution - of the given module. - """ + """ setup any state specific to the execution of the given module.""" def teardown_module(module): - """ teardown any state that was previously setup - with a setup_module method. + """ teardown any state that was previously setup with a setup_module + method. """ Class level setup/teardown @@ -41,14 +39,14 @@ @classmethod def setup_class(cls): - """ setup up any state specific to the execution - of the given class (which usually contains tests). + """ setup any state specific to the execution of the given class (which + usually contains tests). """ @classmethod def teardown_class(cls): - """ teardown any state that was previously setup - with a call to setup_class. + """ teardown any state that was previously setup with a call to + setup_class. """ Method and function level setup/teardown @@ -57,31 +55,29 @@ Similarly, the following methods are called around each method invocation:: def setup_method(self, method): - """ setup up any state tied to the execution of the given - method in a class. setup_method is invoked for every - test method of a class. + """ setup any state tied to the execution of the given method in a + class. setup_method is invoked for every test method of a class. """ def teardown_method(self, method): - """ teardown any state that was previously setup - with a setup_method call. + """ teardown any state that was previously setup with a setup_method + call. """ If you would rather define test functions directly at module level you can also use the following functions to implement fixtures:: def setup_function(function): - """ setup up any state tied to the execution of the given - function. Invoked for every test function in the module. + """ setup any state tied to the execution of the given function. + Invoked for every test function in the module. """ def teardown_function(function): - """ teardown any state that was previously setup - with a setup_function call. + """ teardown any state that was previously setup with a setup_function + call. """ - -Note that it possible that setup/teardown pairs are invoked multiple -times per testing process. + +Note that it is possible for setup/teardown pairs to be invoked multiple times +per testing process. .. _`unittest.py module`: http://docs.python.org/library/unittest.html - Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Sat Dec 10 09:49:36 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Sat, 10 Dec 2011 08:49:36 -0000 Subject: [py-svn] commit/pytest: hpk42: fix issue99 - internalerror with --resultlog now produce better output. Message-ID: <20111210084936.8469.21503@bitbucket13.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/88a2c2a4cf70/ changeset: 88a2c2a4cf70 user: hpk42 date: 2011-12-10 09:49:21 summary: fix issue99 - internalerror with --resultlog now produce better output. the fix depends on another change in the py lib which unifies the output for native and non-native traceback formatting styles affected #: 5 files diff -r 896c7b1b455b435848d8957445edd18c0741c061 -r 88a2c2a4cf7097adb8579654bf7df8b6cc5c67cc CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,11 @@ Changes between 2.2.0 and 2.2.1.dev ---------------------------------------- +- fix issue99 (in pytest and py) internallerrors with resultlog now + produce better output - fixed by normalizing pytest_internalerror + input arguments. +- fix traceback issues (in pytest and py) improve traceback output + in conjunction with jinja2 and cython which hack tracebacks - fix issue93 (in pytest and pytest-xdist) avoid "delayed teardowns": the final test in a test node will now run its teardown directly instead of waiting for the end of the session. Thanks Dave Hunt for diff -r 896c7b1b455b435848d8957445edd18c0741c061 -r 88a2c2a4cf7097adb8579654bf7df8b6cc5c67cc _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.2.1.dev2' +__version__ = '2.2.1.dev3' diff -r 896c7b1b455b435848d8957445edd18c0741c061 -r 88a2c2a4cf7097adb8579654bf7df8b6cc5c67cc _pytest/resultlog.py --- a/_pytest/resultlog.py +++ b/_pytest/resultlog.py @@ -91,5 +91,8 @@ self.log_outcome(report, code, longrepr) def pytest_internalerror(self, excrepr): - path = excrepr.reprcrash.path + reprcrash = getattr(excrepr, 'reprcrash', None) + path = getattr(reprcrash, "path", None) + if path is None: + path = "cwd:%s" % py.path.local() self.write_log_entry(path, '!', str(excrepr)) diff -r 896c7b1b455b435848d8957445edd18c0741c061 -r 88a2c2a4cf7097adb8579654bf7df8b6cc5c67cc setup.py --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.2.1.dev2', + version='2.2.1.dev3', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], @@ -32,7 +32,7 @@ author_email='holger at merlinux.eu', entry_points= make_entry_points(), # the following should be enabled for release - install_requires=['py>=1.4.5'], + install_requires=['py>=1.4.6.dev4'], classifiers=['Development Status :: 6 - Mature', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', @@ -70,4 +70,4 @@ return {'console_scripts': l} if __name__ == '__main__': - main() \ No newline at end of file + main() diff -r 896c7b1b455b435848d8957445edd18c0741c061 -r 88a2c2a4cf7097adb8579654bf7df8b6cc5c67cc testing/test_resultlog.py --- a/testing/test_resultlog.py +++ b/testing/test_resultlog.py @@ -133,23 +133,26 @@ assert lines[14].startswith('X ') assert len(lines) == 15 - def test_internal_exception(self): + @pytest.mark.parametrize("style", ("native", "long", "short")) + def test_internal_exception(self, style): # they are produced for example by a teardown failing - # at the end of the run + # at the end of the run or a failing hook invocation try: raise ValueError except ValueError: excinfo = py.code.ExceptionInfo() reslog = ResultLog(None, py.io.TextIO()) - reslog.pytest_internalerror(excinfo.getrepr()) + reslog.pytest_internalerror(excinfo.getrepr(style=style)) entry = reslog.logfile.getvalue() entry_lines = entry.splitlines() assert entry_lines[0].startswith('! ') - assert os.path.basename(__file__)[:-9] in entry_lines[0] #.pyc/class + if style != "native": + assert os.path.basename(__file__)[:-9] in entry_lines[0] #.pyc/class assert entry_lines[-1][0] == ' ' assert 'ValueError' in entry + def test_generic(testdir, LineMatcher): testdir.plugins.append("resultlog") testdir.makepyfile(""" Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Sat Dec 10 09:50:23 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Sat, 10 Dec 2011 08:50:23 -0000 Subject: [py-svn] commit/py: hpk42: help to fix pytest issue99: unify output of Message-ID: <20111210085023.8469.59970@bitbucket13.managed.contegix.com> 1 new commit in py: https://bitbucket.org/hpk42/py/changeset/2366418b7ccc/ changeset: 2366418b7ccc user: hpk42 date: 2011-12-10 09:11:41 summary: help to fix pytest issue99: unify output of ExceptionInfo.getrepr(style="native") with ...(style="long") affected #: 5 files diff -r bb527bc1a4145d2531a0fb879aad610c04333605 -r 2366418b7ccc912749fc7ccb759cc057c55959ca CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,8 @@ Changes between 1.4.5 and 1.4.x ================================================== +- help to fix pytest issue99: unify output of + ExceptionInfo.getrepr(style="native") with ...(style="long") - fix issue7: source.getstatementrange() now raises proper error if no valid statement can be found - fix issue8: fix code and tests of svnurl/svnwc to work on subversion 1.7 - diff -r bb527bc1a4145d2531a0fb879aad610c04333605 -r 2366418b7ccc912749fc7ccb759cc057c55959ca py/__init__.py --- a/py/__init__.py +++ b/py/__init__.py @@ -8,7 +8,7 @@ (c) Holger Krekel and others, 2004-2010 """ -__version__ = '1.4.6.dev3' +__version__ = '1.4.6.dev4' from py import _apipkg diff -r bb527bc1a4145d2531a0fb879aad610c04333605 -r 2366418b7ccc912749fc7ccb759cc057c55959ca py/_code/code.py --- a/py/_code/code.py +++ b/py/_code/code.py @@ -283,7 +283,7 @@ """ cache = {} for i, entry in enumerate(self): - # id for the code.raw is needed to work around + # id for the code.raw is needed to work around # the strange metaprogramming in the decorator lib from pypi # which generates code objects that have hash/value equality #XXX needs a test @@ -361,14 +361,16 @@ showlocals: show locals per traceback entry style: long|short|no|native traceback style tbfilter: hide entries (where __tracebackhide__ is true) + + in case of style==native, tbfilter and showlocals is ignored. """ if style == 'native': - import traceback - return ''.join(traceback.format_exception( - self.type, - self.value, - self.traceback[0]._rawentry, - )) + return ReprExceptionInfo(ReprTracebackNative( + py.std.traceback.format_exception( + self.type, + self.value, + self.traceback[0]._rawentry, + )), self._getreprcrash()) fmt = FormattedExcinfo(showlocals=showlocals, style=style, abspath=abspath, tbfilter=tbfilter, funcargs=funcargs) @@ -612,6 +614,19 @@ if self.extraline: tw.line(self.extraline) +class ReprTracebackNative(ReprTraceback): + def __init__(self, tblines): + self.style = "native" + self.reprentries = [ReprEntryNative(tblines)] + self.extraline = None + +class ReprEntryNative(TerminalRepr): + def __init__(self, tblines): + self.lines = tblines + + def toterminal(self, tw): + tw.write("".join(self.lines)) + class ReprEntry(TerminalRepr): localssep = "_ " diff -r bb527bc1a4145d2531a0fb879aad610c04333605 -r 2366418b7ccc912749fc7ccb759cc057c55959ca setup.py --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ name='py', description='library with cross-python path, ini-parsing, io, code, log facilities', long_description = open('README.txt').read(), - version='1.4.6.dev3', + version='1.4.6.dev4', url='http://pylib.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff -r bb527bc1a4145d2531a0fb879aad610c04333605 -r 2366418b7ccc912749fc7ccb759cc057c55959ca testing/code/test_excinfo.py --- a/testing/code/test_excinfo.py +++ b/testing/code/test_excinfo.py @@ -157,7 +157,7 @@ def test_traceback_messy_recursion(self): #XXX: simplified locally testable version decorator = py.test.importorskip('decorator').decorator - + def log(f, *k, **kw): print('%s %s' % (k, kw)) f(*k, **kw) @@ -751,9 +751,11 @@ assert 0 """) repr = excinfo.getrepr(style='native') - assert repr.startswith('Traceback (most recent call last):\n File') - assert repr.endswith('\nAssertionError: assert 0\n') - assert 'exec (source.compile())' in repr + assert "assert 0" in str(repr.reprcrash) + s = str(repr) + assert s.startswith('Traceback (most recent call last):\n File') + assert s.endswith('\nAssertionError: assert 0') + assert 'exec (source.compile())' in s # python 2.4 fails to get the source line for the assert if py.std.sys.version_info >= (2, 5): - assert repr.count('assert 0') == 2 + assert s.count('assert 0') == 2 Repository URL: https://bitbucket.org/hpk42/py/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Mon Dec 12 13:11:34 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Mon, 12 Dec 2011 12:11:34 -0000 Subject: [py-svn] commit/py: RonnyPfannschmidt: propperly handle lists in xmlgen on python3 Message-ID: <20111212121134.6533.88032@bitbucket01.managed.contegix.com> 1 new commit in py: https://bitbucket.org/hpk42/py/changeset/117ea069b045/ changeset: 117ea069b045 user: RonnyPfannschmidt date: 2011-12-12 13:11:02 summary: propperly handle lists in xmlgen on python3 affected #: 3 files diff -r 2366418b7ccc912749fc7ccb759cc057c55959ca -r 117ea069b0458e10e61dabb84aa8f85cd9d701f5 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -14,6 +14,7 @@ about the eval magic of a decorator library - add py.builtin.next - iniconfig: add support for ; as comment starter +- properly handle lists in xmlgen on python3 Changes between 1.4.4 and 1.4.5 ================================================== diff -r 2366418b7ccc912749fc7ccb759cc057c55959ca -r 117ea069b0458e10e61dabb84aa8f85cd9d701f5 py/_xmlgen.py --- a/py/_xmlgen.py +++ b/py/_xmlgen.py @@ -136,7 +136,8 @@ def list(self, obj): assert id(obj) not in self.visited self.visited[id(obj)] = 1 - map(self.visit, obj) + for elem in obj: + self.visit(elem) def Tag(self, tag): assert id(tag) not in self.visited diff -r 2366418b7ccc912749fc7ccb759cc057c55959ca -r 117ea069b0458e10e61dabb84aa8f85cd9d701f5 testing/root/test_xmlgen.py --- a/testing/root/test_xmlgen.py +++ b/testing/root/test_xmlgen.py @@ -54,6 +54,11 @@ u = unicode(x) assert u == '' +def test_list_nested(): + x = ns.hello([ns.world()]) #pass in a list here + u = unicode(x) + assert u == '' + def test_tag_xmlname(): class my(ns.hello): xmlname = 'world' Repository URL: https://bitbucket.org/hpk42/py/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Mon Dec 12 13:40:20 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Mon, 12 Dec 2011 12:40:20 -0000 Subject: [py-svn] commit/py: hpk42: bump version Message-ID: <20111212124020.28936.22269@bitbucket13.managed.contegix.com> 1 new commit in py: https://bitbucket.org/hpk42/py/changeset/e284b86857e2/ changeset: e284b86857e2 user: hpk42 date: 2011-12-12 13:40:09 summary: bump version affected #: 2 files diff -r 117ea069b0458e10e61dabb84aa8f85cd9d701f5 -r e284b86857e2e3d975cac9c654a810434c9e5cfc py/__init__.py --- a/py/__init__.py +++ b/py/__init__.py @@ -8,7 +8,7 @@ (c) Holger Krekel and others, 2004-2010 """ -__version__ = '1.4.6.dev4' +__version__ = '1.4.6.dev5' from py import _apipkg diff -r 117ea069b0458e10e61dabb84aa8f85cd9d701f5 -r e284b86857e2e3d975cac9c654a810434c9e5cfc setup.py --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ name='py', description='library with cross-python path, ini-parsing, io, code, log facilities', long_description = open('README.txt').read(), - version='1.4.6.dev4', + version='1.4.6.dev5', url='http://pylib.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], Repository URL: https://bitbucket.org/hpk42/py/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Mon Dec 12 13:45:40 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Mon, 12 Dec 2011 12:45:40 -0000 Subject: [py-svn] commit/pytest: hpk42: bump version depend on new pylib Message-ID: <20111212124540.9144.70663@bitbucket01.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/983a07db9c5f/ changeset: 983a07db9c5f user: hpk42 date: 2011-12-12 13:45:28 summary: bump version depend on new pylib affected #: 4 files diff -r 88a2c2a4cf7097adb8579654bf7df8b6cc5c67cc -r 983a07db9c5f2830dc45475bd0ddc123ae44b00d CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -4,7 +4,7 @@ - fix issue99 (in pytest and py) internallerrors with resultlog now produce better output - fixed by normalizing pytest_internalerror input arguments. -- fix traceback issues (in pytest and py) improve traceback output +- fix issue97 / traceback issues (in pytest and py) improve traceback output in conjunction with jinja2 and cython which hack tracebacks - fix issue93 (in pytest and pytest-xdist) avoid "delayed teardowns": the final test in a test node will now run its teardown directly diff -r 88a2c2a4cf7097adb8579654bf7df8b6cc5c67cc -r 983a07db9c5f2830dc45475bd0ddc123ae44b00d _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.2.1.dev3' +__version__ = '2.2.1.dev4' diff -r 88a2c2a4cf7097adb8579654bf7df8b6cc5c67cc -r 983a07db9c5f2830dc45475bd0ddc123ae44b00d setup.py --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.2.1.dev3', + version='2.2.1.dev4', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], @@ -32,7 +32,7 @@ author_email='holger at merlinux.eu', entry_points= make_entry_points(), # the following should be enabled for release - install_requires=['py>=1.4.6.dev4'], + install_requires=['py>=1.4.6.dev5'], classifiers=['Development Status :: 6 - Mature', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', diff -r 88a2c2a4cf7097adb8579654bf7df8b6cc5c67cc -r 983a07db9c5f2830dc45475bd0ddc123ae44b00d tox.ini --- a/tox.ini +++ b/tox.ini @@ -51,8 +51,7 @@ make html [testenv:py31] -deps=py>1.4.0 - :pypi:nose>=1.0 +deps=:pypi:nose>=1.0 [testenv:py31-xdist] deps=pytest-xdist Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Mon Dec 12 22:13:02 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Mon, 12 Dec 2011 21:13:02 -0000 Subject: [py-svn] commit/pytest-xdist: hpk42: try py31/py32 environments in tox.ini Message-ID: <20111212211302.14352.82354@bitbucket01.managed.contegix.com> 1 new commit in pytest-xdist: https://bitbucket.org/hpk42/pytest-xdist/changeset/4c9af0621fae/ changeset: 4c9af0621fae user: hpk42 date: 2011-12-12 22:12:25 summary: try py31/py32 environments in tox.ini affected #: 1 file diff -r 6d23d5c1326f88b97066e5b1e950cc6950d9ee05 -r 4c9af0621fae3440b5e3e988e6b5fb2351fca3b7 tox.ini --- a/tox.ini +++ b/tox.ini @@ -9,10 +9,10 @@ deps=:testrun:pytest>=2.2.0.dev2 commands= py.test --junitxml={envlogdir}/junit-{envname}.xml [] -[testenv:py31] -deps=:pypi:pytest # XXX needed because ClueRelease/pip broken -[testenv:py32] -deps=:pypi:pytest # XXX needed because ClueRelease/pip broken +#[testenv:py31] +#deps=:pypi:pytest # XXX needed because ClueRelease/pip broken +#[testenv:py32] +#deps=:pypi:pytest # XXX needed because ClueRelease/pip broken [testenv:py26] deps= Repository URL: https://bitbucket.org/hpk42/pytest-xdist/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Dec 13 00:34:44 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Mon, 12 Dec 2011 23:34:44 -0000 Subject: [py-svn] commit/py: RonnyPfannschmidt: undo my addition of next in rev 214561f55dfc, this particular implementation was rather bad Message-ID: <20111212233444.28058.84963@bitbucket01.managed.contegix.com> 1 new commit in py: https://bitbucket.org/hpk42/py/changeset/44cff93787d6/ changeset: 44cff93787d6 user: RonnyPfannschmidt date: 2011-12-12 22:11:03 summary: undo my addition of next in rev 214561f55dfc, this particular implementation was rather bad affected #: 4 files diff -r e284b86857e2e3d975cac9c654a810434c9e5cfc -r 44cff93787d68267a2d2cb3f3f6c45a45ee352d5 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -12,7 +12,6 @@ (as seen from jnja2) - make trackeback recursion detection more resilent about the eval magic of a decorator library -- add py.builtin.next - iniconfig: add support for ; as comment starter - properly handle lists in xmlgen on python3 diff -r e284b86857e2e3d975cac9c654a810434c9e5cfc -r 44cff93787d68267a2d2cb3f3f6c45a45ee352d5 py/__init__.py --- a/py/__init__.py +++ b/py/__init__.py @@ -104,7 +104,6 @@ 'builtins' : '._builtin:builtins', 'execfile' : '._builtin:execfile', 'callable' : '._builtin:callable', - 'next' : '._builtin:next', }, # input-output helping diff -r e284b86857e2e3d975cac9c654a810434c9e5cfc -r 44cff93787d68267a2d2cb3f3f6c45a45ee352d5 py/_builtin.py --- a/py/_builtin.py +++ b/py/_builtin.py @@ -91,22 +91,6 @@ enumerate = enumerate try: - next = next -except NameError: - _next_noarg = object() - def next(it, default=_next_noarg): - try: - if hasattr(it, '__next__'): - return it.__next__() - else: - return it.next() - except StopIteration: - if default is _next_noarg: - raise - else: - return default - -try: BaseException = BaseException except NameError: BaseException = Exception diff -r e284b86857e2e3d975cac9c654a810434c9e5cfc -r 44cff93787d68267a2d2cb3f3f6c45a45ee352d5 testing/root/test_builtin.py --- a/testing/root/test_builtin.py +++ b/testing/root/test_builtin.py @@ -1,7 +1,7 @@ import sys import types import py -from py.builtin import set, frozenset, reversed, sorted, next +from py.builtin import set, frozenset, reversed, sorted def test_enumerate(): l = [0,1,2] @@ -160,22 +160,3 @@ code = py.builtin._getcode(test_getcode) assert isinstance(code, types.CodeType) assert py.builtin._getcode(4) is None - -def test_next(): - it = iter([]) - py.test.raises(StopIteraton, next, it) - it = iter('1') - n = next(it) - assert n == '1' - py.test.raises(StopIteraton, next, it) - - class new_next(object): - def __next__(self): - return 1 - assert next(new_next()) == 1 - - class old_next(object): - def next(self): - return 1 - assert next(old_next) == 1 - Repository URL: https://bitbucket.org/hpk42/py/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Wed Dec 14 11:53:29 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Wed, 14 Dec 2011 10:53:29 -0000 Subject: [py-svn] commit/py: hpk42: normalize getfslineno to always return (string, int) tuple Message-ID: <20111214105329.6303.38994@bitbucket01.managed.contegix.com> 1 new commit in py: https://bitbucket.org/hpk42/py/changeset/f14a0bda45eb/ changeset: f14a0bda45eb user: hpk42 date: 2011-12-14 11:53:01 summary: normalize getfslineno to always return (string, int) tuple affected #: 5 files diff -r 44cff93787d68267a2d2cb3f3f6c45a45ee352d5 -r f14a0bda45eb4e0891fb89b65ed72fe8a7b62471 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -14,6 +14,8 @@ about the eval magic of a decorator library - iniconfig: add support for ; as comment starter - properly handle lists in xmlgen on python3 +- normalize py.code.getfslineno(obj) to always return a (string, int) tuple + defaulting to ("", -1) respectively if no source code can be found for obj. Changes between 1.4.4 and 1.4.5 ================================================== diff -r 44cff93787d68267a2d2cb3f3f6c45a45ee352d5 -r f14a0bda45eb4e0891fb89b65ed72fe8a7b62471 py/__init__.py --- a/py/__init__.py +++ b/py/__init__.py @@ -8,7 +8,7 @@ (c) Holger Krekel and others, 2004-2010 """ -__version__ = '1.4.6.dev5' +__version__ = '1.4.6.dev6' from py import _apipkg diff -r 44cff93787d68267a2d2cb3f3f6c45a45ee352d5 -r f14a0bda45eb4e0891fb89b65ed72fe8a7b62471 py/_code/source.py --- a/py/_code/source.py +++ b/py/_code/source.py @@ -261,6 +261,9 @@ def getfslineno(obj): + """ Return source location (path, lineno) for the given object. + If the source cannot be determined return ("", -1) + """ try: code = py.code.Code(obj) except TypeError: @@ -268,19 +271,19 @@ fn = (py.std.inspect.getsourcefile(obj) or py.std.inspect.getfile(obj)) except TypeError: - return None, None + return "", -1 fspath = fn and py.path.local(fn) or None + lineno = -1 if fspath: try: _, lineno = findsource(obj) except IOError: - lineno = None - else: - lineno = None + pass else: fspath = code.path lineno = code.firstlineno + assert isinstance(lineno, int) return fspath, lineno # @@ -293,7 +296,7 @@ except py.builtin._sysex: raise except: - return None, None + return "", -1 source = Source() source.lines = [line.rstrip() for line in sourcelines] return source, lineno diff -r 44cff93787d68267a2d2cb3f3f6c45a45ee352d5 -r f14a0bda45eb4e0891fb89b65ed72fe8a7b62471 setup.py --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ name='py', description='library with cross-python path, ini-parsing, io, code, log facilities', long_description = open('README.txt').read(), - version='1.4.6.dev5', + version='1.4.6.dev6', url='http://pylib.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff -r 44cff93787d68267a2d2cb3f3f6c45a45ee352d5 -r f14a0bda45eb4e0891fb89b65ed72fe8a7b62471 testing/code/test_source.py --- a/testing/code/test_source.py +++ b/testing/code/test_source.py @@ -434,8 +434,11 @@ assert fspath.basename == "test_source.py" assert lineno == A_lineno - assert getfslineno(3) == (None, None) - + assert getfslineno(3) == ("", -1) + class B: + pass + B.__name__ = "B2" + assert getfslineno(B)[1] == -1 def test_code_of_object_instance_with_call(): class A: Repository URL: https://bitbucket.org/hpk42/py/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Wed Dec 14 11:57:38 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Wed, 14 Dec 2011 10:57:38 -0000 Subject: [py-svn] commit/pytest: hpk42: fix unorderable types as reported by Ralf Schmitt Message-ID: <20111214105738.25939.2935@bitbucket01.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/51640a2987b4/ changeset: 51640a2987b4 user: hpk42 date: 2011-12-14 11:56:51 summary: fix unorderable types as reported by Ralf Schmitt affected #: 7 files diff -r 983a07db9c5f2830dc45475bd0ddc123ae44b00d -r 51640a2987b4ab54ca3fdeca7235e34b3c548c8d CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -12,6 +12,8 @@ the good reporting and feedback. The pytest_runtest_protocol as well as the pytest_runtest_teardown hooks now have "nextitem" available which will be None indicating the end of the test run. +- fix collection crash due to unknown-source collected items, thanks + to Ralf Schmitt (fixed by depending on a more recent pylib) Changes between 2.1.3 and 2.2.0 ---------------------------------------- diff -r 983a07db9c5f2830dc45475bd0ddc123ae44b00d -r 51640a2987b4ab54ca3fdeca7235e34b3c548c8d _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.2.1.dev4' +__version__ = '2.2.1.dev5' diff -r 983a07db9c5f2830dc45475bd0ddc123ae44b00d -r 51640a2987b4ab54ca3fdeca7235e34b3c548c8d _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -156,6 +156,7 @@ obj = obj.place_as self._fslineno = py.code.getfslineno(obj) + assert isinstance(self._fslineno[1], int), obj return self._fslineno def reportinfo(self): @@ -173,6 +174,7 @@ else: fspath, lineno = self._getfslineno() modpath = self.getmodpath() + assert isinstance(lineno, int) return fspath, lineno, modpath class PyCollectorMixin(PyobjMixin, pytest.Collector): diff -r 983a07db9c5f2830dc45475bd0ddc123ae44b00d -r 51640a2987b4ab54ca3fdeca7235e34b3c548c8d setup.py --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.2.1.dev4', + version='2.2.1.dev5', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], @@ -32,7 +32,7 @@ author_email='holger at merlinux.eu', entry_points= make_entry_points(), # the following should be enabled for release - install_requires=['py>=1.4.6.dev5'], + install_requires=['py>=1.4.6.dev6'], classifiers=['Development Status :: 6 - Mature', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', @@ -70,4 +70,4 @@ return {'console_scripts': l} if __name__ == '__main__': - main() + main() \ No newline at end of file diff -r 983a07db9c5f2830dc45475bd0ddc123ae44b00d -r 51640a2987b4ab54ca3fdeca7235e34b3c548c8d testing/test_python.py --- a/testing/test_python.py +++ b/testing/test_python.py @@ -1517,3 +1517,20 @@ "*MyInstance*", "*MyFunction*test_hello*", ]) + + +def test_unorderable_types(testdir): + testdir.makepyfile(""" + class TestJoinEmpty: + pass + + def make_test(): + class Test: + pass + Test.__name__ = "TestFoo" + return Test + TestFoo = make_test() + """) + result = testdir.runpytest() + assert "TypeError" not in result.stdout.str() + assert result.ret == 0 diff -r 983a07db9c5f2830dc45475bd0ddc123ae44b00d -r 51640a2987b4ab54ca3fdeca7235e34b3c548c8d testing/test_unittest.py --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -38,7 +38,7 @@ assert self.foo2 == 1 def teardown_method(self, method): assert 0, "42" - + """) reprec = testdir.inline_run("-s", testpath) assert reprec.matchreport("test_both", when="call").passed @@ -431,3 +431,20 @@ """) res = testdir.runpytest() assert "failUnlessEqual" not in res.stdout.str() + +def test_unorderable_types(testdir): + testdir.makepyfile(""" + import unittest + class TestJoinEmpty(unittest.TestCase): + pass + + def make_test(): + class Test(unittest.TestCase): + pass + Test.__name__ = "TestFoo" + return Test + TestFoo = make_test() + """) + result = testdir.runpytest() + assert "TypeError" not in result.stdout.str() + assert result.ret == 0 diff -r 983a07db9c5f2830dc45475bd0ddc123ae44b00d -r 51640a2987b4ab54ca3fdeca7235e34b3c548c8d tox.ini --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,7 @@ indexserver= pypi = http://pypi.python.org/simple testrun = http://pypi.testrun.org - default = http://pypi.testrun.org +# default = http://pypi.testrun.org [testenv] changedir=testing @@ -50,8 +50,12 @@ commands= make html +;;[testenv:py31] +;;deps=:pypi:nose>=1.0 + [testenv:py31] -deps=:pypi:nose>=1.0 +deps= + {distshare}/py-1.4.6* [testenv:py31-xdist] deps=pytest-xdist Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Wed Dec 14 12:20:29 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Wed, 14 Dec 2011 11:20:29 -0000 Subject: [py-svn] commit/py: hpk42: fix tests / refine findsource Message-ID: <20111214112029.24774.35297@bitbucket01.managed.contegix.com> 1 new commit in py: https://bitbucket.org/hpk42/py/changeset/f9ce5c222142/ changeset: f9ce5c222142 user: hpk42 date: 2011-12-14 12:20:20 summary: fix tests / refine findsource affected #: 1 file diff -r f14a0bda45eb4e0891fb89b65ed72fe8a7b62471 -r f9ce5c222142aac5e838d2bd09fa0f8ab36a4dfa py/_code/source.py --- a/py/_code/source.py +++ b/py/_code/source.py @@ -296,7 +296,7 @@ except py.builtin._sysex: raise except: - return "", -1 + return None, -1 source = Source() source.lines = [line.rstrip() for line in sourcelines] return source, lineno Repository URL: https://bitbucket.org/hpk42/py/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Wed Dec 14 12:32:22 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Wed, 14 Dec 2011 11:32:22 -0000 Subject: [py-svn] commit/pytest: hpk42: remove debugging-changes to tox.ini Message-ID: <20111214113222.7370.29700@bitbucket01.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/c28026ca4112/ changeset: c28026ca4112 user: hpk42 date: 2011-12-14 12:29:25 summary: remove debugging-changes to tox.ini affected #: 1 file diff -r 51640a2987b4ab54ca3fdeca7235e34b3c548c8d -r c28026ca4112e14025794c9b55092d9660e5eb9f tox.ini --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,7 @@ indexserver= pypi = http://pypi.python.org/simple testrun = http://pypi.testrun.org -# default = http://pypi.testrun.org + default = http://pypi.testrun.org [testenv] changedir=testing @@ -50,12 +50,8 @@ commands= make html -;;[testenv:py31] -;;deps=:pypi:nose>=1.0 - [testenv:py31] -deps= - {distshare}/py-1.4.6* +deps=:pypi:nose>=1.0 [testenv:py31-xdist] deps=pytest-xdist Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Thu Dec 15 07:41:52 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Thu, 15 Dec 2011 06:41:52 -0000 Subject: [py-svn] commit/pytest-xdist: hpk42: fix tests by properly removing __pycache__ files Message-ID: <20111215064152.1244.11721@bitbucket03.managed.contegix.com> 1 new commit in pytest-xdist: https://bitbucket.org/hpk42/pytest-xdist/changeset/815039684ac9/ changeset: 815039684ac9 user: hpk42 date: 2011-12-15 07:41:09 summary: fix tests by properly removing __pycache__ files affected #: 2 files diff -r 4c9af0621fae3440b5e3e988e6b5fb2351fca3b7 -r 815039684ac977f374508103a48941b106dbb394 setup.py --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ packages = ['xdist'], entry_points = {'pytest11': ['xdist = xdist.plugin'],}, zip_safe=False, - install_requires = ['execnet>=1.0.8', 'pytest>=2.2.1.dev2'], + install_requires = ['execnet>=1.0.8', 'pytest>=2.2.1.dev5'], classifiers=[ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', diff -r 4c9af0621fae3440b5e3e988e6b5fb2351fca3b7 -r 815039684ac977f374508103a48941b106dbb394 testing/test_looponfail.py --- a/testing/test_looponfail.py +++ b/testing/test_looponfail.py @@ -88,16 +88,14 @@ assert not failures def test_failures_somewhere(self, testdir): - item = testdir.getitem("def test_func(): assert 0\n") + item = testdir.getitem("def test_func():\n assert 0\n") control = RemoteControl(item.config) control.setup() failures = control.runsession() assert failures control.setup() - item.fspath.write("def test_func(): assert 1\n") - pyc = item.fspath.new(ext=".pyc") - if pyc.check(): - pyc.remove() + item.fspath.write("def test_func():\n assert 1\n") + removepyc(item.fspath) topdir, failures = control.runsession()[:2] assert not failures @@ -115,9 +113,7 @@ def test_new(): assert 0 """)) - pyc = modcol.fspath.new(ext=".pyc") - if pyc.check(): - pyc.remove() + removepyc(modcol.fspath) control.loop_once() assert not control.failures control.loop_once() @@ -252,4 +248,7 @@ pyc = path + "c" if pyc.check(): pyc.remove() + c = path.dirpath("__pycache__") + if c.check(): + c.remove() Repository URL: https://bitbucket.org/hpk42/pytest-xdist/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Fri Dec 16 11:36:31 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Fri, 16 Dec 2011 10:36:31 -0000 Subject: [py-svn] commit/py: 2 new changesets Message-ID: <20111216103631.23005.82825@bitbucket13.managed.contegix.com> 2 new commits in py: https://bitbucket.org/hpk42/py/changeset/a91d73e5ba60/ changeset: a91d73e5ba60 user: hpk42 date: 2011-12-14 18:20:24 summary: raise a consistent IndexError when a statementrange cannot be determined affected #: 4 files diff -r f9ce5c222142aac5e838d2bd09fa0f8ab36a4dfa -r a91d73e5ba60f4c2fc577f2b349777f2fd5748d3 py/__init__.py --- a/py/__init__.py +++ b/py/__init__.py @@ -8,7 +8,7 @@ (c) Holger Krekel and others, 2004-2010 """ -__version__ = '1.4.6.dev6' +__version__ = '1.4.6' from py import _apipkg diff -r f9ce5c222142aac5e838d2bd09fa0f8ab36a4dfa -r a91d73e5ba60f4c2fc577f2b349777f2fd5748d3 py/_code/source.py --- a/py/_code/source.py +++ b/py/_code/source.py @@ -108,7 +108,7 @@ def getstatementrange(self, lineno, assertion=False): """ return (start, end) tuple which spans the minimal statement region which containing the given lineno. - raise a ValueError if no such statementrange can be found. + raise an IndexError if no such statementrange can be found. """ # XXX there must be a better than these heuristic ways ... # XXX there may even be better heuristics :-) @@ -142,7 +142,7 @@ if trysource.isparseable(): return start, end if end is None: - raise ValueError("no valid source range around line %d " % (lineno,)) + raise IndexError("no valid source range around line %d " % (lineno,)) return start, end def getblockend(self, lineno): diff -r f9ce5c222142aac5e838d2bd09fa0f8ab36a4dfa -r a91d73e5ba60f4c2fc577f2b349777f2fd5748d3 setup.py --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ name='py', description='library with cross-python path, ini-parsing, io, code, log facilities', long_description = open('README.txt').read(), - version='1.4.6.dev6', + version='1.4.6', url='http://pylib.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff -r f9ce5c222142aac5e838d2bd09fa0f8ab36a4dfa -r a91d73e5ba60f4c2fc577f2b349777f2fd5748d3 testing/code/test_source.py --- a/testing/code/test_source.py +++ b/testing/code/test_source.py @@ -238,7 +238,7 @@ def test_getstatementrange_with_syntaxerror_issue7(self): source = Source(":") - py.test.raises(ValueError, lambda: source.getstatementrange(0)) + py.test.raises(IndexError, lambda: source.getstatementrange(0)) @py.test.mark.skipif("sys.version_info < (2,6)") def test_compile_to_ast(self): https://bitbucket.org/hpk42/py/changeset/b827dd156a36/ changeset: b827dd156a36 user: hpk42 date: 2011-12-16 11:36:14 summary: finalize changelog for 1.4.6 affected #: 1 file diff -r a91d73e5ba60f4c2fc577f2b349777f2fd5748d3 -r b827dd156a36753e32c7f3f15ce82d6fe9e356c8 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -Changes between 1.4.5 and 1.4.x +Changes between 1.4.5 and 1.4.6 ================================================== - help to fix pytest issue99: unify output of Repository URL: https://bitbucket.org/hpk42/py/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Fri Dec 16 11:40:17 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Fri, 16 Dec 2011 10:40:17 -0000 Subject: [py-svn] commit/pytest: hpk42: regen docs, prepare release 2.2.1 Message-ID: <20111216104017.29662.10899@bitbucket12.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/7a9183c26b9e/ changeset: 7a9183c26b9e user: hpk42 date: 2011-12-16 11:38:34 summary: regen docs, prepare release 2.2.1 affected #: 21 files diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -Changes between 2.2.0 and 2.2.1.dev +Changes between 2.2.0 and 2.2.1 ---------------------------------------- - fix issue99 (in pytest and py) internallerrors with resultlog now diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.2.1.dev5' +__version__ = '2.2.1' diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 doc/announce/release-2.2.1.txt --- /dev/null +++ b/doc/announce/release-2.2.1.txt @@ -0,0 +1,37 @@ +pytest-2.2.1: bug fixes, perfect teardowns +=========================================================================== + +pytest-2.2.1 is a minor backward-compatible release of the the py.test +testing tool. It contains bug fixes and little improvements, including +documentation fixes. For general information see here: + + http://pytest.org/ + +To install or upgrade pytest: + + pip install -U pytest # or + easy_install -U pytest + +Special thanks for helping on this release to Ronny Pfannschmidt, Jurko +Gospodnetic and Ralf Schmitt. + +best, +holger krekel + + +Changes between 2.2.0 and 2.2.1 +---------------------------------------- + +- fix issue99 (in pytest and py) internallerrors with resultlog now + produce better output - fixed by normalizing pytest_internalerror + input arguments. +- fix issue97 / traceback issues (in pytest and py) improve traceback output + in conjunction with jinja2 and cython which hack tracebacks +- fix issue93 (in pytest and pytest-xdist) avoid "delayed teardowns": + the final test in a test node will now run its teardown directly + instead of waiting for the end of the session. Thanks Dave Hunt for + the good reporting and feedback. The pytest_runtest_protocol as well + as the pytest_runtest_teardown hooks now have "nextitem" available + which will be None indicating the end of the test run. +- fix collection crash due to unknown-source collected items, thanks + to Ralf Schmitt (fixed by depending on a more recent pylib) diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 doc/assert.txt --- a/doc/assert.txt +++ b/doc/assert.txt @@ -23,7 +23,7 @@ $ py.test test_assert1.py =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 1 items test_assert1.py F @@ -105,7 +105,7 @@ $ py.test test_assert2.py =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 1 items test_assert2.py F diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 doc/builtin.txt --- a/doc/builtin.txt +++ b/doc/builtin.txt @@ -28,7 +28,7 @@ $ py.test --funcargs =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collected 0 items pytestconfig the pytest config object with access to command line opts. diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 doc/capture.txt --- a/doc/capture.txt +++ b/doc/capture.txt @@ -64,7 +64,7 @@ $ py.test =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 2 items test_module.py .F @@ -78,8 +78,8 @@ test_module.py:9: AssertionError ----------------------------- Captured stdout ------------------------------ - setting up - ==================== 1 failed, 1 passed in 0.02 seconds ==================== + setting up + ==================== 1 failed, 1 passed in 0.03 seconds ==================== Accessing captured output from a test function --------------------------------------------------- diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 doc/doctest.txt --- a/doc/doctest.txt +++ b/doc/doctest.txt @@ -44,9 +44,10 @@ $ py.test =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 1 items mymodule.py . ========================= 1 passed in 0.05 seconds ========================= + [?1034h \ No newline at end of file diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 doc/example/markers.txt --- a/doc/example/markers.txt +++ b/doc/example/markers.txt @@ -25,26 +25,26 @@ You can then restrict a test run to only run tests marked with ``webtest``:: $ py.test -v -m webtest - ============================= test session starts ============================== - platform darwin -- Python 2.7.1 -- pytest-2.2.0 -- /Users/hpk/venv/1/bin/python + =========================== test session starts ============================ + platform darwin -- Python 2.7.1 -- pytest-2.2.1 -- /Users/hpk/venv/1/bin/python collecting ... collected 2 items test_server.py:3: test_send_http PASSED - ===================== 1 tests deselected by "-m 'webtest'" ===================== - ==================== 1 passed, 1 deselected in 0.01 seconds ==================== + =================== 1 tests deselected by "-m 'webtest'" =================== + ================== 1 passed, 1 deselected in 0.01 seconds ================== Or the inverse, running all tests except the webtest ones:: $ py.test -v -m "not webtest" - ============================= test session starts ============================== - platform darwin -- Python 2.7.1 -- pytest-2.2.0 -- /Users/hpk/venv/1/bin/python + =========================== test session starts ============================ + platform darwin -- Python 2.7.1 -- pytest-2.2.1 -- /Users/hpk/venv/1/bin/python collecting ... collected 2 items test_server.py:6: test_something_quick PASSED - =================== 1 tests deselected by "-m 'not webtest'" =================== - ==================== 1 passed, 1 deselected in 0.02 seconds ==================== + ================= 1 tests deselected by "-m 'not webtest'" ================= + ================== 1 passed, 1 deselected in 0.01 seconds ================== Registering markers ------------------------------------- @@ -141,39 +141,39 @@ the given argument:: $ py.test -k send_http # running with the above defined examples - ============================= test session starts ============================== - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + =========================== test session starts ============================ + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 4 items test_server.py . - ===================== 3 tests deselected by '-ksend_http' ====================== - ==================== 1 passed, 3 deselected in 0.02 seconds ==================== + =================== 3 tests deselected by '-ksend_http' ==================== + ================== 1 passed, 3 deselected in 0.02 seconds ================== And you can also run all tests except the ones that match the keyword:: $ py.test -k-send_http - ============================= test session starts ============================== - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + =========================== test session starts ============================ + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 4 items test_mark_classlevel.py .. test_server.py . - ===================== 1 tests deselected by '-k-send_http' ===================== - ==================== 3 passed, 1 deselected in 0.03 seconds ==================== + =================== 1 tests deselected by '-k-send_http' =================== + ================== 3 passed, 1 deselected in 0.03 seconds ================== Or to only select the class:: $ py.test -kTestClass - ============================= test session starts ============================== - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + =========================== test session starts ============================ + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 4 items test_mark_classlevel.py .. - ===================== 2 tests deselected by '-kTestClass' ====================== - ==================== 2 passed, 2 deselected in 0.02 seconds ==================== + =================== 2 tests deselected by '-kTestClass' ==================== + ================== 2 passed, 2 deselected in 0.02 seconds ================== .. _`adding a custom marker from a plugin`: @@ -221,24 +221,24 @@ the test needs:: $ py.test -E stage2 - ============================= test session starts ============================== - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + =========================== test session starts ============================ + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 1 items test_someenv.py s - ========================== 1 skipped in 0.02 seconds =========================== + ======================== 1 skipped in 0.02 seconds ========================= and here is one that specifies exactly the environment needed:: $ py.test -E stage1 - ============================= test session starts ============================== - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + =========================== test session starts ============================ + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 1 items test_someenv.py . - =========================== 1 passed in 0.02 seconds =========================== + ========================= 1 passed in 0.01 seconds ========================= The ``--markers`` option always gives you a list of available markers:: diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 doc/example/mysetup.txt --- a/doc/example/mysetup.txt +++ b/doc/example/mysetup.txt @@ -49,7 +49,7 @@ $ py.test test_sample.py =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 1 items test_sample.py F @@ -57,7 +57,7 @@ ================================= FAILURES ================================= _______________________________ test_answer ________________________________ - mysetup = + mysetup = def test_answer(mysetup): app = mysetup.myapp() @@ -122,12 +122,12 @@ $ py.test test_ssh.py -rs =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 1 items test_ssh.py s ========================= short test summary info ========================== - SKIP [1] /Users/hpk/tmp/doc-exec-625/conftest.py:22: specify ssh host with --ssh + SKIP [1] /Users/hpk/tmp/doc-exec-44/conftest.py:22: specify ssh host with --ssh ======================== 1 skipped in 0.02 seconds ========================= diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 doc/example/nonpython.txt --- a/doc/example/nonpython.txt +++ b/doc/example/nonpython.txt @@ -27,7 +27,7 @@ nonpython $ py.test test_simple.yml =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 2 items test_simple.yml .F @@ -37,7 +37,7 @@ usecase execution failed spec failed: 'some': 'other' no further details known at this point. - ==================== 1 failed, 1 passed in 0.10 seconds ==================== + ==================== 1 failed, 1 passed in 0.09 seconds ==================== You get one dot for the passing ``sub1: sub1`` check and one failure. Obviously in the above ``conftest.py`` you'll want to implement a more @@ -56,7 +56,7 @@ nonpython $ py.test -v =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 -- /Users/hpk/venv/1/bin/python + platform darwin -- Python 2.7.1 -- pytest-2.2.1 -- /Users/hpk/venv/1/bin/python collecting ... collected 2 items test_simple.yml:1: usecase: ok PASSED @@ -74,7 +74,7 @@ nonpython $ py.test --collectonly =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 2 items diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 doc/example/parametrize.txt --- a/doc/example/parametrize.txt +++ b/doc/example/parametrize.txt @@ -154,7 +154,7 @@ $ py.test test_scenarios.py =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 2 items test_scenarios.py .. @@ -166,7 +166,7 @@ $ py.test --collectonly test_scenarios.py =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 2 items @@ -222,7 +222,7 @@ $ py.test test_backends.py --collectonly =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 2 items @@ -238,7 +238,7 @@ ================================= FAILURES ================================= _________________________ test_db_initialized[d2] __________________________ - db = + db = def test_db_initialized(db): # a dummy test @@ -295,7 +295,7 @@ ================================= FAILURES ================================= ________________________ TestClass.test_equals[1-2] ________________________ - self = , a = 1, b = 2 + self = , a = 1, b = 2 def test_equals(self, a, b): > assert a == b @@ -326,4 +326,4 @@ ========================= short test summary info ========================== SKIP [24] /Users/hpk/p/pytest/doc/example/multipython.py:36: 'python2.8' not found SKIP [24] /Users/hpk/p/pytest/doc/example/multipython.py:36: 'python2.4' not found - 27 passed, 48 skipped in 3.03 seconds + 27 passed, 48 skipped in 3.01 seconds diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 doc/example/pythoncollection.txt --- a/doc/example/pythoncollection.txt +++ b/doc/example/pythoncollection.txt @@ -43,7 +43,7 @@ $ py.test --collectonly =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 2 items @@ -51,7 +51,7 @@ - ============================= in 0.02 seconds ============================= + ============================= in 0.01 seconds ============================= Interpreting cmdline arguments as Python packages ----------------------------------------------------- @@ -82,7 +82,7 @@ . $ py.test --collectonly pythoncollection.py =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 3 items diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 doc/example/reportingdemo.txt --- a/doc/example/reportingdemo.txt +++ b/doc/example/reportingdemo.txt @@ -13,7 +13,7 @@ assertion $ py.test failure_demo.py =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 39 items failure_demo.py FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF @@ -30,7 +30,7 @@ failure_demo.py:15: AssertionError _________________________ TestFailing.test_simple __________________________ - self = + self = def test_simple(self): def f(): @@ -40,13 +40,13 @@ > assert f() == g() E assert 42 == 43 - E + where 42 = () - E + and 43 = () + E + where 42 = () + E + and 43 = () failure_demo.py:28: AssertionError ____________________ TestFailing.test_simple_multiline _____________________ - self = + self = def test_simple_multiline(self): otherfunc_multi( @@ -66,19 +66,19 @@ failure_demo.py:11: AssertionError ___________________________ TestFailing.test_not ___________________________ - self = + self = def test_not(self): def f(): return 42 > assert not f() E assert not 42 - E + where 42 = () + E + where 42 = () failure_demo.py:38: AssertionError _________________ TestSpecialisedExplanations.test_eq_text _________________ - self = + self = def test_eq_text(self): > assert 'spam' == 'eggs' @@ -89,7 +89,7 @@ failure_demo.py:42: AssertionError _____________ TestSpecialisedExplanations.test_eq_similar_text _____________ - self = + self = def test_eq_similar_text(self): > assert 'foo 1 bar' == 'foo 2 bar' @@ -102,7 +102,7 @@ failure_demo.py:45: AssertionError ____________ TestSpecialisedExplanations.test_eq_multiline_text ____________ - self = + self = def test_eq_multiline_text(self): > assert 'foo\nspam\nbar' == 'foo\neggs\nbar' @@ -115,7 +115,7 @@ failure_demo.py:48: AssertionError ______________ TestSpecialisedExplanations.test_eq_long_text _______________ - self = + self = def test_eq_long_text(self): a = '1'*100 + 'a' + '2'*100 @@ -132,7 +132,7 @@ failure_demo.py:53: AssertionError _________ TestSpecialisedExplanations.test_eq_long_text_multiline __________ - self = + self = def test_eq_long_text_multiline(self): a = '1\n'*100 + 'a' + '2\n'*100 @@ -156,7 +156,7 @@ failure_demo.py:58: AssertionError _________________ TestSpecialisedExplanations.test_eq_list _________________ - self = + self = def test_eq_list(self): > assert [0, 1, 2] == [0, 1, 3] @@ -166,7 +166,7 @@ failure_demo.py:61: AssertionError ______________ TestSpecialisedExplanations.test_eq_list_long _______________ - self = + self = def test_eq_list_long(self): a = [0]*100 + [1] + [3]*100 @@ -178,7 +178,7 @@ failure_demo.py:66: AssertionError _________________ TestSpecialisedExplanations.test_eq_dict _________________ - self = + self = def test_eq_dict(self): > assert {'a': 0, 'b': 1} == {'a': 0, 'b': 2} @@ -191,7 +191,7 @@ failure_demo.py:69: AssertionError _________________ TestSpecialisedExplanations.test_eq_set __________________ - self = + self = def test_eq_set(self): > assert set([0, 10, 11, 12]) == set([0, 20, 21]) @@ -207,7 +207,7 @@ failure_demo.py:72: AssertionError _____________ TestSpecialisedExplanations.test_eq_longer_list ______________ - self = + self = def test_eq_longer_list(self): > assert [1,2] == [1,2,3] @@ -217,7 +217,7 @@ failure_demo.py:75: AssertionError _________________ TestSpecialisedExplanations.test_in_list _________________ - self = + self = def test_in_list(self): > assert 1 in [0, 2, 3, 4, 5] @@ -226,7 +226,7 @@ failure_demo.py:78: AssertionError __________ TestSpecialisedExplanations.test_not_in_text_multiline __________ - self = + self = def test_not_in_text_multiline(self): text = 'some multiline\ntext\nwhich\nincludes foo\nand a\ntail' @@ -244,7 +244,7 @@ failure_demo.py:82: AssertionError ___________ TestSpecialisedExplanations.test_not_in_text_single ____________ - self = + self = def test_not_in_text_single(self): text = 'single foo line' @@ -257,7 +257,7 @@ failure_demo.py:86: AssertionError _________ TestSpecialisedExplanations.test_not_in_text_single_long _________ - self = + self = def test_not_in_text_single_long(self): text = 'head ' * 50 + 'foo ' + 'tail ' * 20 @@ -270,7 +270,7 @@ failure_demo.py:90: AssertionError ______ TestSpecialisedExplanations.test_not_in_text_single_long_term _______ - self = + self = def test_not_in_text_single_long_term(self): text = 'head ' * 50 + 'f'*70 + 'tail ' * 20 @@ -289,7 +289,7 @@ i = Foo() > assert i.b == 2 E assert 1 == 2 - E + where 1 = .b + E + where 1 = .b failure_demo.py:101: AssertionError _________________________ test_attribute_instance __________________________ @@ -299,8 +299,8 @@ b = 1 > assert Foo().b == 2 E assert 1 == 2 - E + where 1 = .b - E + where = () + E + where 1 = .b + E + where = () failure_demo.py:107: AssertionError __________________________ test_attribute_failure __________________________ @@ -316,7 +316,7 @@ failure_demo.py:116: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ - self = + self = def _get_b(self): > raise Exception('Failed to get attrib') @@ -332,15 +332,15 @@ b = 2 > assert Foo().b == Bar().b E assert 1 == 2 - E + where 1 = .b - E + where = () - E + and 2 = .b - E + where = () + E + where 1 = .b + E + where = () + E + and 2 = .b + E + where = () failure_demo.py:124: AssertionError __________________________ TestRaises.test_raises __________________________ - self = + self = def test_raises(self): s = 'qwe' @@ -352,10 +352,10 @@ > int(s) E ValueError: invalid literal for int() with base 10: 'qwe' - <0-codegen /Users/hpk/p/pytest/_pytest/python.py:957>:1: ValueError + <0-codegen /Users/hpk/p/pytest/_pytest/python.py:958>:1: ValueError ______________________ TestRaises.test_raises_doesnt _______________________ - self = + self = def test_raises_doesnt(self): > raises(IOError, "int('3')") @@ -364,7 +364,7 @@ failure_demo.py:136: Failed __________________________ TestRaises.test_raise ___________________________ - self = + self = def test_raise(self): > raise ValueError("demo error") @@ -373,7 +373,7 @@ failure_demo.py:139: ValueError ________________________ TestRaises.test_tupleerror ________________________ - self = + self = def test_tupleerror(self): > a,b = [1] @@ -382,7 +382,7 @@ failure_demo.py:142: ValueError ______ TestRaises.test_reinterpret_fails_with_print_for_the_fun_of_it ______ - self = + self = def test_reinterpret_fails_with_print_for_the_fun_of_it(self): l = [1,2,3] @@ -395,7 +395,7 @@ l is [1, 2, 3] ________________________ TestRaises.test_some_error ________________________ - self = + self = def test_some_error(self): > if namenotexi: @@ -423,7 +423,7 @@ <2-codegen 'abc-123' /Users/hpk/p/pytest/doc/example/assertion/failure_demo.py:162>:2: AssertionError ____________________ TestMoreErrors.test_complex_error _____________________ - self = + self = def test_complex_error(self): def f(): @@ -452,7 +452,7 @@ failure_demo.py:5: AssertionError ___________________ TestMoreErrors.test_z1_unpack_error ____________________ - self = + self = def test_z1_unpack_error(self): l = [] @@ -462,7 +462,7 @@ failure_demo.py:179: ValueError ____________________ TestMoreErrors.test_z2_type_error _____________________ - self = + self = def test_z2_type_error(self): l = 3 @@ -472,19 +472,19 @@ failure_demo.py:183: TypeError ______________________ TestMoreErrors.test_startswith ______________________ - self = + self = def test_startswith(self): s = "123" g = "456" > assert s.startswith(g) - E assert ('456') - E + where = '123'.startswith + E assert ('456') + E + where = '123'.startswith failure_demo.py:188: AssertionError __________________ TestMoreErrors.test_startswith_nested ___________________ - self = + self = def test_startswith_nested(self): def f(): @@ -492,15 +492,15 @@ def g(): return "456" > assert f().startswith(g()) - E assert ('456') - E + where = '123'.startswith - E + where '123' = () - E + and '456' = () + E assert ('456') + E + where = '123'.startswith + E + where '123' = () + E + and '456' = () failure_demo.py:195: AssertionError _____________________ TestMoreErrors.test_global_func ______________________ - self = + self = def test_global_func(self): > assert isinstance(globf(42), float) @@ -510,18 +510,18 @@ failure_demo.py:198: AssertionError _______________________ TestMoreErrors.test_instance _______________________ - self = + self = def test_instance(self): self.x = 6*7 > assert self.x != 42 E assert 42 != 42 - E + where 42 = .x + E + where 42 = .x failure_demo.py:202: AssertionError _______________________ TestMoreErrors.test_compare ________________________ - self = + self = def test_compare(self): > assert globf(10) < 5 @@ -531,7 +531,7 @@ failure_demo.py:205: AssertionError _____________________ TestMoreErrors.test_try_finally ______________________ - self = + self = def test_try_finally(self): x = 1 diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 doc/example/simple.txt --- a/doc/example/simple.txt +++ b/doc/example/simple.txt @@ -109,13 +109,13 @@ $ py.test =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 gw0 I gw0 [0] scheduling tests via LoadScheduling - ============================= in 0.71 seconds ============================= + ============================= in 0.54 seconds ============================= .. _`excontrolskip`: @@ -156,12 +156,12 @@ $ py.test -rs # "-rs" means report details on the little 's' =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 2 items test_module.py .s ========================= short test summary info ========================== - SKIP [1] /Users/hpk/tmp/doc-exec-630/conftest.py:9: need --runslow option to run + SKIP [1] /Users/hpk/tmp/doc-exec-49/conftest.py:9: need --runslow option to run =================== 1 passed, 1 skipped in 0.02 seconds ==================== @@ -169,12 +169,12 @@ $ py.test --runslow =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 2 items test_module.py .. - ========================= 2 passed in 0.62 seconds ========================= + ========================= 2 passed in 0.02 seconds ========================= Writing well integrated assertion helpers -------------------------------------------------- @@ -261,7 +261,7 @@ $ py.test =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 project deps: mylib-1.1 collecting ... collected 0 items @@ -284,7 +284,7 @@ $ py.test -v =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 -- /Users/hpk/venv/1/bin/python + platform darwin -- Python 2.7.1 -- pytest-2.2.1 -- /Users/hpk/venv/1/bin/python info1: did you know that ... did you? collecting ... collected 0 items @@ -295,7 +295,7 @@ $ py.test =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 0 items ============================= in 0.00 seconds ============================= @@ -327,7 +327,7 @@ $ py.test --durations=3 =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 3 items test_some_are_slow.py ... diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 doc/funcargs.txt --- a/doc/funcargs.txt +++ b/doc/funcargs.txt @@ -62,7 +62,7 @@ $ py.test test_simplefactory.py =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 1 items test_simplefactory.py F @@ -77,7 +77,7 @@ E assert 42 == 17 test_simplefactory.py:5: AssertionError - ========================= 1 failed in 0.03 seconds ========================= + ========================= 1 failed in 0.02 seconds ========================= This means that indeed the test function was called with a ``myfuncarg`` argument value of ``42`` and the assert fails. Here is how py.test @@ -167,7 +167,7 @@ $ py.test test_example.py =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 10 items test_example.py .........F @@ -190,7 +190,7 @@ $ py.test --collectonly test_example.py =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 10 items @@ -210,7 +210,7 @@ $ py.test -v -k 7 test_example.py # or -k test_func[7] =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 -- /Users/hpk/venv/1/bin/python + platform darwin -- Python 2.7.1 -- pytest-2.2.1 -- /Users/hpk/venv/1/bin/python collecting ... collected 10 items test_example.py:5: test_func[7] PASSED diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 doc/getting-started.txt --- a/doc/getting-started.txt +++ b/doc/getting-started.txt @@ -22,9 +22,9 @@ To check your installation has installed the correct version:: $ py.test --version - This is py.test version 2.2.0, imported from /Users/hpk/p/pytest/pytest.pyc + This is py.test version 2.2.1, imported from /Users/hpk/p/pytest/pytest.pyc setuptools registered plugins: - pytest-xdist-1.7.dev1 at /Users/hpk/p/pytest-xdist/xdist/plugin.pyc + pytest-xdist-1.8.dev2 at /Users/hpk/p/pytest-xdist/xdist/plugin.pyc If you get an error checkout :ref:`installation issues`. @@ -46,7 +46,7 @@ $ py.test =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 1 items test_sample.py F @@ -60,7 +60,7 @@ E + where 4 = func(3) test_sample.py:5: AssertionError - ========================= 1 failed in 0.04 seconds ========================= + ========================= 1 failed in 0.02 seconds ========================= py.test found the ``test_answer`` function by following :ref:`standard test discovery rules `, basically detecting the ``test_`` prefixes. We got a failure report because our little ``func(3)`` call did not return ``5``. @@ -126,7 +126,7 @@ ================================= FAILURES ================================= ____________________________ TestClass.test_two ____________________________ - self = + self = def test_two(self): x = "hello" @@ -163,7 +163,7 @@ ================================= FAILURES ================================= _____________________________ test_needsfiles ______________________________ - tmpdir = local('/Users/hpk/tmp/pytest-1595/test_needsfiles0') + tmpdir = local('/Users/hpk/tmp/pytest-679/test_needsfiles0') def test_needsfiles(tmpdir): print tmpdir @@ -172,8 +172,8 @@ test_tmpdir.py:3: AssertionError ----------------------------- Captured stdout ------------------------------ - /Users/hpk/tmp/pytest-1595/test_needsfiles0 - 1 failed in 0.15 seconds + /Users/hpk/tmp/pytest-679/test_needsfiles0 + 1 failed in 0.16 seconds Before the test runs, a unique-per-test-invocation temporary directory was created. More info at :ref:`tmpdir handling`. diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 doc/monkeypatch.txt --- a/doc/monkeypatch.txt +++ b/doc/monkeypatch.txt @@ -39,10 +39,10 @@ .. background check: $ py.test =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 0 items - ============================= in 0.20 seconds ============================= + ============================= in 0.00 seconds ============================= Method reference of the monkeypatch function argument ----------------------------------------------------- diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 doc/skipping.txt --- a/doc/skipping.txt +++ b/doc/skipping.txt @@ -130,7 +130,7 @@ example $ py.test -rx xfail_demo.py =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 6 items xfail_demo.py xxxxxx diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 doc/tmpdir.txt --- a/doc/tmpdir.txt +++ b/doc/tmpdir.txt @@ -28,7 +28,7 @@ $ py.test test_tmpdir.py =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 1 items test_tmpdir.py F @@ -36,7 +36,7 @@ ================================= FAILURES ================================= _____________________________ test_create_file _____________________________ - tmpdir = local('/Users/hpk/tmp/pytest-1596/test_create_file0') + tmpdir = local('/Users/hpk/tmp/pytest-680/test_create_file0') def test_create_file(tmpdir): p = tmpdir.mkdir("sub").join("hello.txt") @@ -47,7 +47,7 @@ E assert 0 test_tmpdir.py:7: AssertionError - ========================= 1 failed in 0.20 seconds ========================= + ========================= 1 failed in 0.17 seconds ========================= .. _`base temporary directory`: diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 doc/unittest.txt --- a/doc/unittest.txt +++ b/doc/unittest.txt @@ -24,7 +24,7 @@ $ py.test test_unittest.py =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.0 + platform darwin -- Python 2.7.1 -- pytest-2.2.1 collecting ... collected 1 items test_unittest.py F @@ -42,7 +42,7 @@ test_unittest.py:8: AssertionError ----------------------------- Captured stdout ------------------------------ hello - ========================= 1 failed in 0.23 seconds ========================= + ========================= 1 failed in 0.04 seconds ========================= .. _`unittest.py style`: http://docs.python.org/library/unittest.html diff -r c28026ca4112e14025794c9b55092d9660e5eb9f -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 setup.py --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.2.1.dev5', + version='2.2.1', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], @@ -32,7 +32,7 @@ author_email='holger at merlinux.eu', entry_points= make_entry_points(), # the following should be enabled for release - install_requires=['py>=1.4.6.dev6'], + install_requires=['py>=1.4.6'], classifiers=['Development Status :: 6 - Mature', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', @@ -70,4 +70,4 @@ return {'console_scripts': l} if __name__ == '__main__': - main() \ No newline at end of file + main() Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Fri Dec 16 12:57:16 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Fri, 16 Dec 2011 11:57:16 -0000 Subject: [py-svn] commit/pytest: 2 new changesets Message-ID: <20111216115716.3268.885@bitbucket02.managed.contegix.com> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/changeset/3da8cec6c532/ changeset: 3da8cec6c532 user: hpk42 date: 2011-12-16 12:43:05 summary: mention pytest-xdist-1.8 affected #: 1 file diff -r 7a9183c26b9e3ce90c70ca9fefad2c0cb9d7f2f2 -r 3da8cec6c5326ed27c144c9b6d7a64a648370005 doc/announce/release-2.2.1.txt --- a/doc/announce/release-2.2.1.txt +++ b/doc/announce/release-2.2.1.txt @@ -1,9 +1,13 @@ pytest-2.2.1: bug fixes, perfect teardowns =========================================================================== + pytest-2.2.1 is a minor backward-compatible release of the the py.test testing tool. It contains bug fixes and little improvements, including -documentation fixes. For general information see here: +documentation fixes. If you are using the distributed testing +pluginmake sure to upgrade it to pytest-xdist-1.8. + +For general information see here: http://pytest.org/ https://bitbucket.org/hpk42/pytest/changeset/38d610a257f0/ changeset: 38d610a257f0 user: hpk42 date: 2011-12-16 12:56:44 summary: Added tag 2.2.1 for changeset 3da8cec6c532 affected #: 1 file diff -r 3da8cec6c5326ed27c144c9b6d7a64a648370005 -r 38d610a257f035d4a6edc02f6039468be6960e70 .hgtags --- a/.hgtags +++ b/.hgtags @@ -45,3 +45,4 @@ 5864412c6f3c903384243bd315639d101d7ebc67 2.1.2 12a05d59249f80276e25fd8b96e8e545b1332b7a 2.1.3 1522710369337d96bf9568569d5f0ca9b38a74e0 2.2.0 +3da8cec6c5326ed27c144c9b6d7a64a648370005 2.2.1 Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Fri Dec 16 12:57:21 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Fri, 16 Dec 2011 11:57:21 -0000 Subject: [py-svn] commit/py: hpk42: Added tag 1.4.6 for changeset b827dd156a36 Message-ID: <20111216115721.5467.48811@bitbucket02.managed.contegix.com> 1 new commit in py: https://bitbucket.org/hpk42/py/changeset/980c8d526463/ changeset: 980c8d526463 user: hpk42 date: 2011-12-16 12:57:09 summary: Added tag 1.4.6 for changeset b827dd156a36 affected #: 1 file diff -r b827dd156a36753e32c7f3f15ce82d6fe9e356c8 -r 980c8d526463958ee7cae678a7e4e9b054f36b94 .hgtags --- a/.hgtags +++ b/.hgtags @@ -36,3 +36,4 @@ 04ab22db4ff737cf31e91d75a0f5d7077f324167 1.4.2 9950bf9d684a984d511795013421c89c5cf88bef 1.4.3 d9951e3bdbc765e73835ae13012f6a074d13d8bf 1.4.4 +b827dd156a36753e32c7f3f15ce82d6fe9e356c8 1.4.6 Repository URL: https://bitbucket.org/hpk42/py/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Fri Dec 16 13:12:36 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Fri, 16 Dec 2011 12:12:36 -0000 Subject: [py-svn] commit/pytest: hpk42: add 2.2.1 announce to index Message-ID: <20111216121236.3268.97286@bitbucket02.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/a69c4555285c/ changeset: a69c4555285c user: hpk42 date: 2011-12-16 13:12:23 summary: add 2.2.1 announce to index affected #: 1 file diff -r 38d610a257f035d4a6edc02f6039468be6960e70 -r a69c4555285c888ec506db401a68c1100e1fe6bc doc/announce/index.txt --- a/doc/announce/index.txt +++ b/doc/announce/index.txt @@ -5,6 +5,7 @@ .. toctree:: :maxdepth: 2 + release-2.2.1 release-2.2.0 release-2.1.3 release-2.1.2 Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Fri Dec 16 23:49:49 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Fri, 16 Dec 2011 22:49:49 -0000 Subject: [py-svn] commit/pytest: hpk42: robustify monkeypatch Message-ID: <20111216224949.26865.38160@bitbucket12.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/52c436be8d63/ changeset: 52c436be8d63 user: hpk42 date: 2011-12-16 23:41:23 summary: robustify monkeypatch affected #: 5 files diff -r a69c4555285c888ec506db401a68c1100e1fe6bc -r 52c436be8d635a7f49f741b24f0bdc03d1de0036 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +Changes between 2.2.1 and 2.2.2.dev +---------------------------------------- + +- make monkeypatch more robust against intermediate dict/env deletions + Changes between 2.2.0 and 2.2.1 ---------------------------------------- diff -r a69c4555285c888ec506db401a68c1100e1fe6bc -r 52c436be8d635a7f49f741b24f0bdc03d1de0036 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.2.1' +__version__ = '2.2.2.dev1' diff -r a69c4555285c888ec506db401a68c1100e1fe6bc -r 52c436be8d635a7f49f741b24f0bdc03d1de0036 _pytest/monkeypatch.py --- a/_pytest/monkeypatch.py +++ b/_pytest/monkeypatch.py @@ -95,7 +95,7 @@ self._setattr[:] = [] for dictionary, name, value in self._setitem: if value is notset: - del dictionary[name] + dictionary.pop(name, None) else: dictionary[name] = value self._setitem[:] = [] diff -r a69c4555285c888ec506db401a68c1100e1fe6bc -r 52c436be8d635a7f49f741b24f0bdc03d1de0036 setup.py --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.2.1', + version='2.2.2.dev1', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], @@ -70,4 +70,4 @@ return {'console_scripts': l} if __name__ == '__main__': - main() + main() \ No newline at end of file diff -r a69c4555285c888ec506db401a68c1100e1fe6bc -r 52c436be8d635a7f49f741b24f0bdc03d1de0036 testing/test_monkeypatch.py --- a/testing/test_monkeypatch.py +++ b/testing/test_monkeypatch.py @@ -59,6 +59,20 @@ monkeypatch.undo() assert d['x'] == 5 +def test_setitem_deleted_meanwhile(): + d = {} + monkeypatch = MonkeyPatch() + monkeypatch.setitem(d, 'x', 2) + del d['x'] + monkeypatch.undo() + assert not d + +def test_setenv_deleted_meanwhile(): + monkeypatch = MonkeyPatch() + monkeypatch.setenv('XYZ123', 'hello') + monkeypatch.undo() + assert 'XYZ123' not in os.environ + def test_delitem(): d = {'x': 1} monkeypatch = MonkeyPatch() Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Sun Dec 18 11:56:48 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Sun, 18 Dec 2011 10:56:48 -0000 Subject: [py-svn] commit/pytest: hpk42: fix test to actually mean something useful (thanks Jurko) Message-ID: <20111218105648.402.95680@bitbucket02.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/e4d9933f66a9/ changeset: e4d9933f66a9 user: hpk42 date: 2011-12-18 11:56:39 summary: fix test to actually mean something useful (thanks Jurko) affected #: 1 file diff -r 52c436be8d635a7f49f741b24f0bdc03d1de0036 -r e4d9933f66a9ddb362c605ca73dbca3147c8174b testing/test_monkeypatch.py --- a/testing/test_monkeypatch.py +++ b/testing/test_monkeypatch.py @@ -70,6 +70,7 @@ def test_setenv_deleted_meanwhile(): monkeypatch = MonkeyPatch() monkeypatch.setenv('XYZ123', 'hello') + del os.environ['XYZ123'] monkeypatch.undo() assert 'XYZ123' not in os.environ Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Mon Dec 19 00:02:54 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Sun, 18 Dec 2011 23:02:54 -0000 Subject: [py-svn] commit/pytest: 2 new changesets Message-ID: <20111218230254.9064.60764@bitbucket12.managed.contegix.com> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/changeset/94d54871e6e1/ changeset: 94d54871e6e1 user: hpk42 date: 2011-12-18 20:01:43 summary: use newer distribute_setup.py affected #: 2 files diff -r e4d9933f66a9ddb362c605ca73dbca3147c8174b -r 94d54871e6e14406323e4e6ceb38fddbb4b15e3a CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ ---------------------------------------- - make monkeypatch more robust against intermediate dict/env deletions +- use distribute_setup script defaulting to 0.6.24 if no setuptools is installed Changes between 2.2.0 and 2.2.1 ---------------------------------------- diff -r e4d9933f66a9ddb362c605ca73dbca3147c8174b -r 94d54871e6e14406323e4e6ceb38fddbb4b15e3a distribute_setup.py --- a/distribute_setup.py +++ b/distribute_setup.py @@ -46,7 +46,7 @@ args = [quote(arg) for arg in args] return os.spawnl(os.P_WAIT, sys.executable, *args) == 0 -DEFAULT_VERSION = "0.6.19" +DEFAULT_VERSION = "0.6.24" DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/" SETUPTOOLS_FAKED_VERSION = "0.6c11" https://bitbucket.org/hpk42/pytest/changeset/5fc5f29c7e78/ changeset: 5fc5f29c7e78 user: hpk42 date: 2011-12-19 00:01:39 summary: fix issue101: wrong args to unittest.TestCase test function now produce better output affected #: 5 files diff -r 94d54871e6e14406323e4e6ceb38fddbb4b15e3a -r 5fc5f29c7e78fe1a3ac6dafd2ac26dcc9e21cf85 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,9 @@ - make monkeypatch more robust against intermediate dict/env deletions - use distribute_setup script defaulting to 0.6.24 if no setuptools is installed +- fix issue101: wrong args to unittest.TestCase test function now + produce better output + Changes between 2.2.0 and 2.2.1 ---------------------------------------- diff -r 94d54871e6e14406323e4e6ceb38fddbb4b15e3a -r 5fc5f29c7e78fe1a3ac6dafd2ac26dcc9e21cf85 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.2.2.dev1' +__version__ = '2.2.2.dev2' diff -r 94d54871e6e14406323e4e6ceb38fddbb4b15e3a -r 5fc5f29c7e78fe1a3ac6dafd2ac26dcc9e21cf85 _pytest/unittest.py --- a/_pytest/unittest.py +++ b/_pytest/unittest.py @@ -108,7 +108,10 @@ def _prunetraceback(self, excinfo): pytest.Function._prunetraceback(self, excinfo) - excinfo.traceback = excinfo.traceback.filter(lambda x:not x.frame.f_globals.get('__unittest')) + traceback = excinfo.traceback.filter( + lambda x:not x.frame.f_globals.get('__unittest')) + if traceback: + excinfo.traceback = traceback @pytest.mark.tryfirst def pytest_runtest_makereport(item, call): diff -r 94d54871e6e14406323e4e6ceb38fddbb4b15e3a -r 5fc5f29c7e78fe1a3ac6dafd2ac26dcc9e21cf85 setup.py --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.2.2.dev1', + version='2.2.2.dev2', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff -r 94d54871e6e14406323e4e6ceb38fddbb4b15e3a -r 5fc5f29c7e78fe1a3ac6dafd2ac26dcc9e21cf85 testing/test_unittest.py --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -448,3 +448,14 @@ result = testdir.runpytest() assert "TypeError" not in result.stdout.str() assert result.ret == 0 + +def test_unittest_typerror_traceback(testdir): + testdir.makepyfile(""" + import unittest + class TestJoinEmpty(unittest.TestCase): + def test_hello(self, arg1): + pass + """) + result = testdir.runpytest() + assert "TypeError" in result.stdout.str() + assert result.ret == 1 Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Mon Dec 19 17:50:42 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Mon, 19 Dec 2011 16:50:42 -0000 Subject: [py-svn] commit/py: gutworth: use an exception more consistent across python versions (fixes #11) Message-ID: <20111219165042.28451.53052@bitbucket05.managed.contegix.com> 1 new commit in py: https://bitbucket.org/hpk42/py/changeset/b092191fcb76/ changeset: b092191fcb76 user: gutworth date: 2011-12-19 17:50:31 summary: use an exception more consistent across python versions (fixes #11) affected #: 1 file diff -r 980c8d526463958ee7cae678a7e4e9b054f36b94 -r b092191fcb76d9b071f55e9eb19077284f47d100 testing/code/test_assertion.py --- a/testing/code/test_assertion.py +++ b/testing/code/test_assertion.py @@ -22,17 +22,14 @@ assert e.msg == 'hello' def test_assert_within_finally(): - class A: - def f(): - pass - excinfo = py.test.raises(TypeError, """ + excinfo = py.test.raises(ZeroDivisionError, """ try: - A().f() + 1/0 finally: i = 42 """) s = excinfo.exconly() - assert s.find("takes no argument") != -1 + assert py.std.re.search("division.+by zero", s) is not None #def g(): # A.f() Repository URL: https://bitbucket.org/hpk42/py/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Mon Dec 19 18:02:20 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Mon, 19 Dec 2011 17:02:20 -0000 Subject: [py-svn] commit/pytest: 2 new changesets Message-ID: <20111219170220.12235.29127@bitbucket03.managed.contegix.com> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/changeset/7d5e89abe2bf/ changeset: 7d5e89abe2bf user: gutworth date: 2011-12-19 17:56:22 summary: use an exception more consistent across python versions affected #: 1 file diff -r 5fc5f29c7e78fe1a3ac6dafd2ac26dcc9e21cf85 -r 7d5e89abe2bf46d96b199ffc383c359880162a4d testing/test_assertinterpret.py --- a/testing/test_assertinterpret.py +++ b/testing/test_assertinterpret.py @@ -28,17 +28,14 @@ assert e.msg == 'hello' def test_assert_within_finally(): - class A: - def f(): - pass - excinfo = py.test.raises(TypeError, """ + excinfo = py.test.raises(ZeroDivisionError, """ try: - A().f() + 1/0 finally: i = 42 """) s = excinfo.exconly() - assert s.find("takes no argument") != -1 + assert py.std.re.search("division.+by zero", s) is not None #def g(): # A.f() https://bitbucket.org/hpk42/pytest/changeset/21938d20c818/ changeset: 21938d20c818 user: gutworth date: 2011-12-19 18:02:07 summary: propogate current PYTHONPATH affected #: 1 file diff -r 7d5e89abe2bf46d96b199ffc383c359880162a4d -r 21938d20c818f50853787780e79695aab7182853 testing/acceptance_test.py --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -410,15 +410,20 @@ "*1 passed*" ]) + def join_pythonpath(what): + cur = py.std.os.environ.get('PYTHONPATH') + if cur: + return str(what) + ':' + cur + return what empty_package = testdir.mkpydir("empty_package") - monkeypatch.setenv('PYTHONPATH', empty_package) + monkeypatch.setenv('PYTHONPATH', join_pythonpath(empty_package)) result = testdir.runpytest("--pyargs", ".") assert result.ret == 0 result.stdout.fnmatch_lines([ "*2 passed*" ]) - monkeypatch.setenv('PYTHONPATH', testdir) + monkeypatch.setenv('PYTHONPATH', join_pythonpath(testdir)) path.join('test_hello.py').remove() result = testdir.runpytest("--pyargs", "tpkg.test_hello") assert result.ret != 0 Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Mon Dec 19 18:30:17 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Mon, 19 Dec 2011 17:30:17 -0000 Subject: [py-svn] commit/py: hpk42: bump version and add entry to changelog Message-ID: <20111219173017.13744.76926@bitbucket12.managed.contegix.com> 1 new commit in py: https://bitbucket.org/hpk42/py/changeset/76dd97f88b78/ changeset: 76dd97f88b78 user: hpk42 date: 2011-12-19 18:29:52 summary: bump version and add entry to changelog affected #: 3 files diff -r b092191fcb76d9b071f55e9eb19077284f47d100 -r 76dd97f88b789b6601363d3371456915ae38dbf0 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +Changes between 1.4.6 and NEXT +================================================== + +- fix issue11 - own test failure with python3.3 / Thanks Benjamin Peterson + Changes between 1.4.5 and 1.4.6 ================================================== diff -r b092191fcb76d9b071f55e9eb19077284f47d100 -r 76dd97f88b789b6601363d3371456915ae38dbf0 py/__init__.py --- a/py/__init__.py +++ b/py/__init__.py @@ -8,7 +8,7 @@ (c) Holger Krekel and others, 2004-2010 """ -__version__ = '1.4.6' +__version__ = '1.4.7.dev1' from py import _apipkg diff -r b092191fcb76d9b071f55e9eb19077284f47d100 -r 76dd97f88b789b6601363d3371456915ae38dbf0 setup.py --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ name='py', description='library with cross-python path, ini-parsing, io, code, log facilities', long_description = open('README.txt').read(), - version='1.4.6', + version='1.4.7.dev1', url='http://pylib.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], Repository URL: https://bitbucket.org/hpk42/py/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Mon Dec 19 20:38:55 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Mon, 19 Dec 2011 19:38:55 -0000 Subject: [py-svn] commit/pytest: gutworth: fix spacing Message-ID: <20111219193855.3317.80965@bitbucket03.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/0069195c13c9/ changeset: 0069195c13c9 user: gutworth date: 2011-12-19 20:23:39 summary: fix spacing affected #: 1 file diff -r 21938d20c818f50853787780e79695aab7182853 -r 0069195c13c9a5915fe1a28d088896ca6b591760 testing/test_python.py --- a/testing/test_python.py +++ b/testing/test_python.py @@ -477,7 +477,7 @@ out = result.stdout.str() assert out.find("conftest.py:2: ValueError") != -1 numentries = out.count("_ _ _ _") # separator for traceback entries - assert numentries >3 + assert numentries > 3 def test_traceback_error_during_import(self, testdir): testdir.makepyfile(""" Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Dec 20 08:51:31 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 20 Dec 2011 07:51:31 -0000 Subject: [py-svn] commit/py: hpk42: addresses issue10 - fix some of the failures on jython. Message-ID: <20111220075131.6904.52656@bitbucket05.managed.contegix.com> 1 new commit in py: https://bitbucket.org/hpk42/py/changeset/b2307ba5805f/ changeset: b2307ba5805f user: hpk42 date: 2011-12-20 08:50:13 summary: addresses issue10 - fix some of the failures on jython. affected #: 2 files diff -r 76dd97f88b789b6601363d3371456915ae38dbf0 -r b2307ba5805f75827cb1645ffbb70fda99a9192d testing/test_apipkg.py --- a/testing/test_apipkg.py +++ b/testing/test_apipkg.py @@ -3,6 +3,9 @@ import py import py._apipkg as apipkg import subprocess +import types + +ModuleType = types.ModuleType # # test support for importing modules # @@ -202,7 +205,7 @@ return ns def test_initpkg_replaces_sysmodules(monkeypatch): - mod = type(sys)('hello') + mod = ModuleType('hello') monkeypatch.setitem(sys.modules, 'hello', mod) apipkg.initpkg('hello', {'x': 'os.path:abspath'}) newmod = sys.modules['hello'] @@ -210,7 +213,7 @@ assert newmod.x == py.std.os.path.abspath def test_initpkg_transfers_attrs(monkeypatch): - mod = type(sys)('hello') + mod = ModuleType('hello') mod.__version__ = 10 mod.__file__ = "hello.py" mod.__loader__ = "loader" @@ -225,7 +228,7 @@ assert newmod.__doc__ == mod.__doc__ def test_initpkg_nodoc(monkeypatch): - mod = type(sys)('hello') + mod = ModuleType('hello') mod.__file__ = "hello.py" monkeypatch.setitem(sys.modules, 'hello', mod) apipkg.initpkg('hello', {}) @@ -233,7 +236,7 @@ assert not newmod.__doc__ def test_initpkg_overwrite_doc(monkeypatch): - hello = type(sys)('hello') + hello = ModuleType('hello') hello.__doc__ = "this is the documentation" monkeypatch.setitem(sys.modules, 'hello', hello) apipkg.initpkg('hello', {"__doc__": "sys:__doc__"}) @@ -242,7 +245,7 @@ assert newhello.__doc__ == sys.__doc__ def test_initpkg_not_transfers_not_existing_attrs(monkeypatch): - mod = type(sys)('hello') + mod = ModuleType('hello') mod.__file__ = "hello.py" monkeypatch.setitem(sys.modules, 'hello', mod) apipkg.initpkg('hello', {}) @@ -253,7 +256,7 @@ assert not hasattr(newmod, '__path__') def test_initpkg_defaults(monkeypatch): - mod = type(sys)('hello') + mod = ModuleType('hello') monkeypatch.setitem(sys.modules, 'hello', mod) apipkg.initpkg('hello', {}) newmod = sys.modules['hello'] diff -r 76dd97f88b789b6601363d3371456915ae38dbf0 -r b2307ba5805f75827cb1645ffbb70fda99a9192d tox.ini --- a/tox.ini +++ b/tox.ini @@ -20,7 +20,7 @@ [testenv:jython] changedir=testing commands= - {envpython} -m pytest --confcutdir=.. -rfsxX --junitxml={envlogdir}/junit-{envname}0.xml [io_ code] + {envpython} -m pytest --confcutdir=.. -rfsxX --junitxml={envlogdir}/junit-{envname}0.xml {posargs:io_ code} [testenv:external] deps= Repository URL: https://bitbucket.org/hpk42/py/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Dec 20 15:12:22 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 20 Dec 2011 14:12:22 -0000 Subject: [py-svn] commit/pytest: 2 new changesets Message-ID: <20111220141222.17303.48324@bitbucket03.managed.contegix.com> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/changeset/f06b4912b9a1/ changeset: f06b4912b9a1 user: hpk42 date: 2011-12-20 13:20:59 summary: fix issue102: report more useful errors and hints for when a test directory was renamed and some pyc/__pycache__ remain affected #: 4 files diff -r 0069195c13c9a5915fe1a28d088896ca6b591760 -r f06b4912b9a18bd83320cf37f8e4269eb6a0cc5f CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -5,7 +5,8 @@ - use distribute_setup script defaulting to 0.6.24 if no setuptools is installed - fix issue101: wrong args to unittest.TestCase test function now produce better output - +- fix issue102: report more useful errors and hints for when a + test directory was renamed and some pyc/__pycache__ remain Changes between 2.2.0 and 2.2.1 ---------------------------------------- diff -r 0069195c13c9a5915fe1a28d088896ca6b591760 -r f06b4912b9a18bd83320cf37f8e4269eb6a0cc5f _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.2.2.dev2' +__version__ = '2.2.2.dev3' diff -r 0069195c13c9a5915fe1a28d088896ca6b591760 -r f06b4912b9a18bd83320cf37f8e4269eb6a0cc5f _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -259,7 +259,8 @@ " %s\n" "which is not the same as the test file we want to collect:\n" " %s\n" - "HINT: use a unique basename for your test file modules" + "HINT: remove __pycache__ / .pyc files and/or use a " + "unique basename for your test file modules" % e.args ) #print "imported test module", mod diff -r 0069195c13c9a5915fe1a28d088896ca6b591760 -r f06b4912b9a18bd83320cf37f8e4269eb6a0cc5f setup.py --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.2.2.dev2', + version='2.2.2.dev3', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], @@ -32,7 +32,7 @@ author_email='holger at merlinux.eu', entry_points= make_entry_points(), # the following should be enabled for release - install_requires=['py>=1.4.6'], + install_requires=['py>=1.4.7.dev2'], classifiers=['Development Status :: 6 - Mature', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', @@ -70,4 +70,4 @@ return {'console_scripts': l} if __name__ == '__main__': - main() \ No newline at end of file + main() https://bitbucket.org/hpk42/pytest/changeset/00e07ab98f91/ changeset: 00e07ab98f91 user: hpk42 date: 2011-12-20 15:12:12 summary: fix typo, thanks jurko affected #: 1 file diff -r f06b4912b9a18bd83320cf37f8e4269eb6a0cc5f -r 00e07ab98f91eb96a6a94314cf7fd16910f3c8ee doc/customize.txt --- a/doc/customize.txt +++ b/doc/customize.txt @@ -94,7 +94,7 @@ [seq] matches any character in seq [!seq] matches any char not in seq - Default patterns are ``.* _* CVS {args}``. Setting a ``norecurse`` + Default patterns are ``.* _* CVS {args}``. Setting a ``norecursedir`` replaces the default. Here is an example of how to avoid certain directories:: Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Mon Dec 26 11:41:53 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Mon, 26 Dec 2011 10:41:53 -0000 Subject: [py-svn] commit/py: hpk42: help fix pytest issue 102 - the __file__ of a pyc file may not exist Message-ID: <20111226104153.16317.18955@bitbucket13.managed.contegix.com> 1 new commit in py: https://bitbucket.org/hpk42/py/changeset/bc37161ccd8c/ changeset: bc37161ccd8c user: hpk42 date: 2011-12-20 13:17:04 summary: help fix pytest issue 102 - the __file__ of a pyc file may not exist affected #: 5 files diff -r b2307ba5805f75827cb1645ffbb70fda99a9192d -r bc37161ccd8c2fb1ff19662ffe154e6151b73a55 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ ================================================== - fix issue11 - own test failure with python3.3 / Thanks Benjamin Peterson +- help fix pytest issue 102 Changes between 1.4.5 and 1.4.6 ================================================== diff -r b2307ba5805f75827cb1645ffbb70fda99a9192d -r bc37161ccd8c2fb1ff19662ffe154e6151b73a55 py/__init__.py --- a/py/__init__.py +++ b/py/__init__.py @@ -8,7 +8,7 @@ (c) Holger Krekel and others, 2004-2010 """ -__version__ = '1.4.7.dev1' +__version__ = '1.4.7.dev2' from py import _apipkg diff -r b2307ba5805f75827cb1645ffbb70fda99a9192d -r bc37161ccd8c2fb1ff19662ffe154e6151b73a55 py/_path/local.py --- a/py/_path/local.py +++ b/py/_path/local.py @@ -157,14 +157,16 @@ return str(self) < str(other) def samefile(self, other): - """ return True if 'other' references the same file as 'self'. """ - if not iswin32: - return py.error.checked_call( - os.path.samefile, str(self), str(other)) + """ return True if 'other' references the same file as 'self'. + """ + if not isinstance(other, py.path.local): + other = os.path.abspath(str(other)) if self == other: return True - other = os.path.abspath(str(other)) - return self == other + if iswin32: + return False # ther is no samefile + return py.error.checked_call( + os.path.samefile, str(self), str(other)) def remove(self, rec=1, ignore_errors=False): """ remove a file or directory (or a directory tree if rec=1). @@ -539,7 +541,11 @@ if self.basename != "__init__.py": modfile = modfile[:-12] - if not self.samefile(modfile): + try: + issame = self.samefile(modfile) + except py.error.ENOENT: + issame = False + if not issame: raise self.ImportMismatchError(modname, modfile, self) return mod else: diff -r b2307ba5805f75827cb1645ffbb70fda99a9192d -r bc37161ccd8c2fb1ff19662ffe154e6151b73a55 setup.py --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ name='py', description='library with cross-python path, ini-parsing, io, code, log facilities', long_description = open('README.txt').read(), - version='1.4.7.dev1', + version='1.4.7.dev2', url='http://pylib.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff -r b2307ba5805f75827cb1645ffbb70fda99a9192d -r bc37161ccd8c2fb1ff19662ffe154e6151b73a55 testing/path/test_local.py --- a/testing/path/test_local.py +++ b/testing/path/test_local.py @@ -1,4 +1,5 @@ import py +import pytest import sys from py.path import local import common @@ -312,6 +313,13 @@ assert obj.x == 42 assert obj.__name__ == 'execfile' + def test_pyimport_renamed_dir_creates_mismatch(self, tmpdir): + p = tmpdir.ensure("a", "test_x123.py") + p.pyimport() + tmpdir.join("a").move(tmpdir.join("b")) + pytest.raises(tmpdir.ImportMismatchError, + lambda: tmpdir.join("b", "test_x123.py").pyimport()) + def test_pyimport_messy_name(self, tmpdir): # http://bitbucket.org/hpk42/py-trunk/issue/129 path = tmpdir.ensure('foo__init__.py') Repository URL: https://bitbucket.org/hpk42/py/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Dec 27 22:03:26 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 27 Dec 2011 21:03:26 -0000 Subject: [py-svn] commit/pytest: hpk42: fix Jenkins test failures Message-ID: <20111227210326.14680.3892@bitbucket03.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/3b4ef649ab8e/ changeset: 3b4ef649ab8e user: hpk42 date: 2011-12-27 22:03:15 summary: fix Jenkins test failures affected #: 2 files diff -r 00e07ab98f91eb96a6a94314cf7fd16910f3c8ee -r 3b4ef649ab8eda3dd7b4d1b935c05641b22b5995 testing/test_core.py --- a/testing/test_core.py +++ b/testing/test_core.py @@ -87,6 +87,7 @@ # ok, we did not explode def test_pluginmanager_ENV_startup(self, testdir, monkeypatch): + return x500 = testdir.makepyfile(pytest_x500="#") p = testdir.makepyfile(""" import pytest diff -r 00e07ab98f91eb96a6a94314cf7fd16910f3c8ee -r 3b4ef649ab8eda3dd7b4d1b935c05641b22b5995 testing/test_runner.py --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -1,4 +1,4 @@ -import pytest, py, sys +import pytest, py, sys, os from _pytest import runner from py._code.code import ReprExceptionInfo @@ -423,23 +423,21 @@ py.test.fail("spurious skip") def test_importorskip_imports_last_module_part(): - import os ospath = py.test.importorskip("os.path") assert os.path == ospath def test_pytest_cmdline_main(testdir): p = testdir.makepyfile(""" - import sys - sys.path.insert(0, %r) import py def test_hello(): assert 1 if __name__ == '__main__': py.test.cmdline.main([__file__]) - """ % (str(py._pydir.dirpath()))) + """) import subprocess - popen = subprocess.Popen([sys.executable, str(p)], stdout=subprocess.PIPE) + popen = subprocess.Popen([sys.executable, str(p)], + stdout=subprocess.PIPE, env={}) s = popen.stdout.read() ret = popen.wait() assert ret == 0 Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Wed Dec 28 08:57:30 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Wed, 28 Dec 2011 07:57:30 -0000 Subject: [py-svn] commit/pytest: hpk42: fix wrongly committed line Message-ID: <20111228075730.5857.30843@bitbucket05.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/9d37772da0aa/ changeset: 9d37772da0aa user: hpk42 date: 2011-12-28 08:57:19 summary: fix wrongly committed line affected #: 1 file diff -r 3b4ef649ab8eda3dd7b4d1b935c05641b22b5995 -r 9d37772da0aa2c5627afa54ef14e1ead7f14de59 testing/test_core.py --- a/testing/test_core.py +++ b/testing/test_core.py @@ -87,7 +87,6 @@ # ok, we did not explode def test_pluginmanager_ENV_startup(self, testdir, monkeypatch): - return x500 = testdir.makepyfile(pytest_x500="#") p = testdir.makepyfile(""" import pytest Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Wed Dec 28 16:55:52 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Wed, 28 Dec 2011 15:55:52 -0000 Subject: [py-svn] commit/pytest: 4 new changesets Message-ID: <20111228155552.26126.84825@bitbucket01.managed.contegix.com> 4 new commits in pytest: https://bitbucket.org/hpk42/pytest/changeset/d98c5a3cbfca/ changeset: d98c5a3cbfca user: hpk42 date: 2011-12-28 16:47:18 summary: internally keep multiple applications of the same markers as separate entities such that the new iter() API can iterate over pytest.mark function attributes, getting all such applications. See added example for more info. affected #: 3 files diff -r 9d37772da0aa2c5627afa54ef14e1ead7f14de59 -r d98c5a3cbfca6a4791a212d4ccd8596e8c417359 _pytest/mark.py --- a/_pytest/mark.py +++ b/_pytest/mark.py @@ -191,8 +191,7 @@ holder = MarkInfo(self.markname, self.args, self.kwargs) setattr(func, self.markname, holder) else: - holder.kwargs.update(self.kwargs) - holder.args += self.args + holder.add(self.args, self.kwargs) return func kw = self.kwargs.copy() kw.update(kwargs) @@ -208,11 +207,23 @@ self.args = args #: keyword argument dictionary, empty if nothing specified self.kwargs = kwargs + self._arglist = [(args, kwargs.copy())] def __repr__(self): return "" % ( self.name, self.args, self.kwargs) + def add(self, args, kwargs): + """ add a MarkInfo with the given args and kwargs. """ + self._arglist.append((args, kwargs)) + self.args += args + self.kwargs.update(kwargs) + + def __iter__(self): + """ yield MarkInfo objects each relating to a marking-call. """ + for args, kwargs in self._arglist: + yield MarkInfo(self.name, args, kwargs) + def pytest_itemcollected(item): if not isinstance(item, pytest.Function): return diff -r 9d37772da0aa2c5627afa54ef14e1ead7f14de59 -r d98c5a3cbfca6a4791a212d4ccd8596e8c417359 doc/example/markers.txt --- a/doc/example/markers.txt +++ b/doc/example/markers.txt @@ -25,26 +25,26 @@ You can then restrict a test run to only run tests marked with ``webtest``:: $ py.test -v -m webtest - =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.1 -- /Users/hpk/venv/1/bin/python + ============================= test session starts ============================== + platform darwin -- Python 2.7.1 -- pytest-2.2.2.dev3 -- /Users/hpk/venv/1/bin/python collecting ... collected 2 items test_server.py:3: test_send_http PASSED - =================== 1 tests deselected by "-m 'webtest'" =================== - ================== 1 passed, 1 deselected in 0.01 seconds ================== + ===================== 1 tests deselected by "-m 'webtest'" ===================== + ==================== 1 passed, 1 deselected in 0.03 seconds ==================== Or the inverse, running all tests except the webtest ones:: $ py.test -v -m "not webtest" - =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.1 -- /Users/hpk/venv/1/bin/python + ============================= test session starts ============================== + platform darwin -- Python 2.7.1 -- pytest-2.2.2.dev3 -- /Users/hpk/venv/1/bin/python collecting ... collected 2 items test_server.py:6: test_something_quick PASSED - ================= 1 tests deselected by "-m 'not webtest'" ================= - ================== 1 passed, 1 deselected in 0.01 seconds ================== + =================== 1 tests deselected by "-m 'not webtest'" =================== + ==================== 1 passed, 1 deselected in 0.03 seconds ==================== Registering markers ------------------------------------- @@ -134,6 +134,7 @@ in which case it will be applied to all functions and methods defined in the module. + Using ``-k TEXT`` to select tests ---------------------------------------------------- @@ -141,39 +142,39 @@ the given argument:: $ py.test -k send_http # running with the above defined examples - =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.1 + ============================= test session starts ============================== + platform darwin -- Python 2.7.1 -- pytest-2.2.2.dev3 collecting ... collected 4 items test_server.py . - =================== 3 tests deselected by '-ksend_http' ==================== - ================== 1 passed, 3 deselected in 0.02 seconds ================== + ===================== 3 tests deselected by '-ksend_http' ====================== + ==================== 1 passed, 3 deselected in 0.06 seconds ==================== And you can also run all tests except the ones that match the keyword:: $ py.test -k-send_http - =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.1 + ============================= test session starts ============================== + platform darwin -- Python 2.7.1 -- pytest-2.2.2.dev3 collecting ... collected 4 items test_mark_classlevel.py .. test_server.py . - =================== 1 tests deselected by '-k-send_http' =================== - ================== 3 passed, 1 deselected in 0.03 seconds ================== + ===================== 1 tests deselected by '-k-send_http' ===================== + ==================== 3 passed, 1 deselected in 0.05 seconds ==================== Or to only select the class:: $ py.test -kTestClass - =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.1 + ============================= test session starts ============================== + platform darwin -- Python 2.7.1 -- pytest-2.2.2.dev3 collecting ... collected 4 items test_mark_classlevel.py .. - =================== 2 tests deselected by '-kTestClass' ==================== - ================== 2 passed, 2 deselected in 0.02 seconds ================== + ===================== 2 tests deselected by '-kTestClass' ====================== + ==================== 2 passed, 2 deselected in 0.04 seconds ==================== .. _`adding a custom marker from a plugin`: @@ -221,24 +222,24 @@ the test needs:: $ py.test -E stage2 - =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.1 + ============================= test session starts ============================== + platform darwin -- Python 2.7.1 -- pytest-2.2.2.dev3 collecting ... collected 1 items test_someenv.py s - ======================== 1 skipped in 0.02 seconds ========================= + ========================== 1 skipped in 0.03 seconds =========================== and here is one that specifies exactly the environment needed:: $ py.test -E stage1 - =========================== test session starts ============================ - platform darwin -- Python 2.7.1 -- pytest-2.2.1 + ============================= test session starts ============================== + platform darwin -- Python 2.7.1 -- pytest-2.2.2.dev3 collecting ... collected 1 items test_someenv.py . - ========================= 1 passed in 0.01 seconds ========================= + =========================== 1 passed in 0.03 seconds =========================== The ``--markers`` option always gives you a list of available markers:: @@ -254,4 +255,43 @@ @pytest.mark.tryfirst: mark a hook implementation function such that the plugin machinery will try to call it first/as early as possible. @pytest.mark.trylast: mark a hook implementation function such that the plugin machinery will try to call it last/as late as possible. + +Reading markers which were set from multiple places +---------------------------------------------------- + +.. versionadded: 2.2.2 + +If you are heavily using markers in your test suite you may encounter the case where a marker is applied several times to a test function. From plugin +code you can read over all such settings. Example:: + + # content of test_mark_three_times.py + import pytest + pytestmark = pytest.mark.glob("module", x=1) + + @pytest.mark.glob("class", x=2) + class TestClass: + @pytest.mark.glob("function", x=3) + def test_something(self): + pass + +Here we have the marker "glob" applied three times to the same +test function. From a conftest file we can read it like this:: + + # content of conftest.py + + def pytest_runtest_setup(item): + g = getattr(item.obj, 'glob', None) + if g is not None: + for info in g: + print ("glob args=%s kwargs=%s" %(info.args, info.kwargs)) + +Let's run this without capturing output and see what we get:: + + $ py.test -q -s + collecting ... collected 2 items + .. + 2 passed in 0.04 seconds + glob args=('function',) kwargs={'x': 3} + glob args=('module',) kwargs={'x': 1} + glob args=('class',) kwargs={'x': 2} diff -r 9d37772da0aa2c5627afa54ef14e1ead7f14de59 -r d98c5a3cbfca6a4791a212d4ccd8596e8c417359 testing/test_mark.py --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -230,6 +230,14 @@ assert marker.args == ("pos0", "pos1") assert marker.kwargs == {'x': 3, 'y': 2, 'z': 4} + # test the new __iter__ interface + l = list(marker) + assert len(l) == 3 + assert l[0].args == ("pos0",) + pytest.xfail(reason="needs reordering of parametrize transfermarks") + assert l[1].args == () + assert l[2].args == ("pos1", ) + def test_mark_other(self, testdir): pytest.raises(TypeError, ''' testdir.getitem(""" @@ -259,6 +267,23 @@ "keyword: *hello*" ]) + def test_merging_markers_two_functions(self, testdir): + p = testdir.makepyfile(""" + import pytest + @pytest.mark.hello("pos1", z=4) + @pytest.mark.hello("pos0", z=3) + def test_func(self): + pass + """) + items, rec = testdir.inline_genitems(p) + item, = items + keywords = item.keywords + marker = keywords['hello'] + l = list(marker) + assert len(l) == 2 + assert l[0].args == ("pos0",) + assert l[1].args == ("pos1",) + class TestKeywordSelection: def test_select_simple(self, testdir): https://bitbucket.org/hpk42/pytest/changeset/dd739069b446/ changeset: dd739069b446 user: hpk42 date: 2011-12-28 16:47:19 summary: fix issue106: allow parametrize to be applied per-class/per-module affected #: 5 files diff -r d98c5a3cbfca6a4791a212d4ccd8596e8c417359 -r dd739069b446c8edda62f3771962b503c5dab150 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,8 @@ produce better output - fix issue102: report more useful errors and hints for when a test directory was renamed and some pyc/__pycache__ remain +- fix issue106: allow parametrize to be applied multiple times + e.g. from module, class and at function level. Changes between 2.2.0 and 2.2.1 ---------------------------------------- diff -r d98c5a3cbfca6a4791a212d4ccd8596e8c417359 -r dd739069b446c8edda62f3771962b503c5dab150 _pytest/mark.py --- a/_pytest/mark.py +++ b/_pytest/mark.py @@ -224,22 +224,3 @@ for args, kwargs in self._arglist: yield MarkInfo(self.name, args, kwargs) -def pytest_itemcollected(item): - if not isinstance(item, pytest.Function): - return - try: - func = item.obj.__func__ - except AttributeError: - func = getattr(item.obj, 'im_func', item.obj) - pyclasses = (pytest.Class, pytest.Module) - for node in item.listchain(): - if isinstance(node, pyclasses): - marker = getattr(node.obj, 'pytestmark', None) - if marker is not None: - if isinstance(marker, list): - for mark in marker: - mark(func) - else: - marker(func) - node = node.parent - item.keywords.update(py.builtin._getfuncdict(func)) diff -r d98c5a3cbfca6a4791a212d4ccd8596e8c417359 -r dd739069b446c8edda62f3771962b503c5dab150 _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -33,7 +33,8 @@ param = metafunc.function.parametrize except AttributeError: return - metafunc.parametrize(*param.args, **param.kwargs) + for p in param: + metafunc.parametrize(*p.args, **p.kwargs) def pytest_configure(config): config.addinivalue_line("markers", @@ -222,6 +223,7 @@ cls = clscol and clscol.obj or None metafunc = Metafunc(funcobj, config=self.config, cls=cls, module=module) + transfer_markers(metafunc) gentesthook = self.config.hook.pytest_generate_tests extra = [module] if cls is not None: @@ -239,6 +241,20 @@ l.append(function) return l +def transfer_markers(metafunc): + # XXX this should rather be code in the mark plugin or the mark + # plugin should merge with the python plugin. + for holder in (metafunc.cls, metafunc.module): + try: + pytestmark = holder.pytestmark + except AttributeError: + continue + if isinstance(pytestmark, list): + for mark in pytestmark: + mark(metafunc.function) + else: + pytestmark(metafunc.function) + class Module(pytest.File, PyCollectorMixin): def _getobj(self): @@ -559,7 +575,7 @@ @property def id(self): - return "-".join(filter(None, self._idlist)) + return "-".join(map(str, filter(None, self._idlist))) def setmulti(self, valtype, argnames, valset, id): for arg,val in zip(argnames, valset): diff -r d98c5a3cbfca6a4791a212d4ccd8596e8c417359 -r dd739069b446c8edda62f3771962b503c5dab150 testing/test_mark.py --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -228,26 +228,26 @@ keywords = item.keywords marker = keywords['hello'] assert marker.args == ("pos0", "pos1") - assert marker.kwargs == {'x': 3, 'y': 2, 'z': 4} + assert marker.kwargs == {'x': 1, 'y': 2, 'z': 4} # test the new __iter__ interface l = list(marker) assert len(l) == 3 assert l[0].args == ("pos0",) - pytest.xfail(reason="needs reordering of parametrize transfermarks") assert l[1].args == () assert l[2].args == ("pos1", ) - def test_mark_other(self, testdir): - pytest.raises(TypeError, ''' - testdir.getitem(""" + def test_mark_with_wrong_marker(self, testdir): + reprec = testdir.inline_runsource(""" import pytest class pytestmark: pass def test_func(): pass - """) - ''') + """) + l = reprec.getfailedcollections() + assert len(l) == 1 + assert "TypeError" in str(l[0].longrepr) def test_mark_dynamically_in_funcarg(self, testdir): testdir.makeconftest(""" diff -r d98c5a3cbfca6a4791a212d4ccd8596e8c417359 -r dd739069b446c8edda62f3771962b503c5dab150 testing/test_python.py --- a/testing/test_python.py +++ b/testing/test_python.py @@ -1048,6 +1048,23 @@ assert metafunc._calls[1].funcargs == dict(x=3, y=4) assert metafunc._calls[1].id == "3-4" + def test_parametrize_multiple_times(self, testdir): + testdir.makepyfile(""" + import pytest + pytestmark = pytest.mark.parametrize("x", [1,2]) + def test_func(x): + assert 0, x + class TestClass: + pytestmark = pytest.mark.parametrize("y", [3,4]) + def test_meth(self, x, y): + assert 0, x + """) + result = testdir.runpytest() + assert result.ret == 1 + result.stdout.fnmatch_lines([ + "*6 fail*", + ]) + class TestMetafuncFunctional: def test_attributes(self, testdir): p = testdir.makepyfile(""" https://bitbucket.org/hpk42/pytest/changeset/f2760b862746/ changeset: f2760b862746 user: hpk42 date: 2011-12-28 16:49:13 summary: work around an apparent python2.4/python2.5 bug with subprocess.Popen, causing jenkins failures. Apparently "os.environ.popitem(name, None)" is not the same as:: try: del os.environ[name] except KeyError: pass affected #: 3 files diff -r dd739069b446c8edda62f3771962b503c5dab150 -r f2760b862746aa307482335dff28fb3cb99efda0 _pytest/monkeypatch.py --- a/_pytest/monkeypatch.py +++ b/_pytest/monkeypatch.py @@ -95,7 +95,10 @@ self._setattr[:] = [] for dictionary, name, value in self._setitem: if value is notset: - dictionary.pop(name, None) + try: + del dictionary[name] + except KeyError: + pass # was already deleted, so we have the desired state else: dictionary[name] = value self._setitem[:] = [] diff -r dd739069b446c8edda62f3771962b503c5dab150 -r f2760b862746aa307482335dff28fb3cb99efda0 testing/test_monkeypatch.py --- a/testing/test_monkeypatch.py +++ b/testing/test_monkeypatch.py @@ -67,12 +67,20 @@ monkeypatch.undo() assert not d -def test_setenv_deleted_meanwhile(): + at pytest.mark.parametrize("before", [True, False]) +def test_setenv_deleted_meanwhile(before): + key = "qwpeoip123" + if before: + os.environ[key] = "world" monkeypatch = MonkeyPatch() - monkeypatch.setenv('XYZ123', 'hello') - del os.environ['XYZ123'] + monkeypatch.setenv(key, 'hello') + del os.environ[key] monkeypatch.undo() - assert 'XYZ123' not in os.environ + if before: + assert os.environ[key] == "world" + del os.environ[key] + else: + assert key not in os.environ def test_delitem(): d = {'x': 1} diff -r dd739069b446c8edda62f3771962b503c5dab150 -r f2760b862746aa307482335dff28fb3cb99efda0 testing/test_runner.py --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -436,8 +436,7 @@ py.test.cmdline.main([__file__]) """) import subprocess - popen = subprocess.Popen([sys.executable, str(p)], - stdout=subprocess.PIPE, env={}) + popen = subprocess.Popen([sys.executable, str(p)], stdout=subprocess.PIPE) s = popen.stdout.read() ret = popen.wait() assert ret == 0 https://bitbucket.org/hpk42/pytest/changeset/d2ba1109c153/ changeset: d2ba1109c153 user: hpk42 date: 2011-12-28 16:49:35 summary: bump version affected #: 2 files diff -r f2760b862746aa307482335dff28fb3cb99efda0 -r d2ba1109c1530ae74036e08b68bc18d50e16397f _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.2.2.dev3' +__version__ = '2.2.2.dev4' diff -r f2760b862746aa307482335dff28fb3cb99efda0 -r d2ba1109c1530ae74036e08b68bc18d50e16397f setup.py --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.2.2.dev3', + version='2.2.2.dev4', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], @@ -70,4 +70,4 @@ return {'console_scripts': l} if __name__ == '__main__': - main() + main() \ No newline at end of file Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Wed Dec 28 17:51:17 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Wed, 28 Dec 2011 16:51:17 -0000 Subject: [py-svn] commit/pytest: hpk42: fix unittest/marker integration Message-ID: <20111228165117.29882.87259@bitbucket02.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/6cd04a7beadb/ changeset: 6cd04a7beadb user: hpk42 date: 2011-12-28 17:47:08 summary: fix unittest/marker integration affected #: 4 files diff -r d2ba1109c1530ae74036e08b68bc18d50e16397f -r 6cd04a7beadb4df14cf57e8f0f601cfd15613d5e _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.2.2.dev4' +__version__ = '2.2.2.dev5' diff -r d2ba1109c1530ae74036e08b68bc18d50e16397f -r 6cd04a7beadb4df14cf57e8f0f601cfd15613d5e _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -221,9 +221,9 @@ module = self.getparent(Module).obj clscol = self.getparent(Class) cls = clscol and clscol.obj or None + transfer_markers(funcobj, cls, module) metafunc = Metafunc(funcobj, config=self.config, cls=cls, module=module) - transfer_markers(metafunc) gentesthook = self.config.hook.pytest_generate_tests extra = [module] if cls is not None: @@ -241,20 +241,19 @@ l.append(function) return l -def transfer_markers(metafunc): +def transfer_markers(funcobj, cls, mod): # XXX this should rather be code in the mark plugin or the mark # plugin should merge with the python plugin. - for holder in (metafunc.cls, metafunc.module): + for holder in (cls, mod): try: pytestmark = holder.pytestmark except AttributeError: continue if isinstance(pytestmark, list): for mark in pytestmark: - mark(metafunc.function) + mark(funcobj) else: - pytestmark(metafunc.function) - + pytestmark(funcobj) class Module(pytest.File, PyCollectorMixin): def _getobj(self): diff -r d2ba1109c1530ae74036e08b68bc18d50e16397f -r 6cd04a7beadb4df14cf57e8f0f601cfd15613d5e _pytest/unittest.py --- a/_pytest/unittest.py +++ b/_pytest/unittest.py @@ -2,6 +2,9 @@ import pytest, py import sys, pdb +# for transfering markers +from _pytest.python import transfer_markers + def pytest_pycollect_makeitem(collector, name, obj): unittest = sys.modules.get('unittest') if unittest is None: @@ -19,7 +22,12 @@ class UnitTestCase(pytest.Class): def collect(self): loader = py.std.unittest.TestLoader() + module = self.getparent(pytest.Module).obj + cls = self.obj for name in loader.getTestCaseNames(self.obj): + x = getattr(self.obj, name) + funcobj = getattr(x, 'im_func', x) + transfer_markers(funcobj, cls, module) yield TestCaseFunction(name, parent=self) def setup(self): diff -r d2ba1109c1530ae74036e08b68bc18d50e16397f -r 6cd04a7beadb4df14cf57e8f0f601cfd15613d5e setup.py --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.2.2.dev4', + version='2.2.2.dev5', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Wed Dec 28 18:35:48 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Wed, 28 Dec 2011 17:35:48 -0000 Subject: [py-svn] commit/pytest: hpk42: fix trial test failure and simplify todo->xfail conversion Message-ID: <20111228173548.15380.3698@bitbucket03.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/990861605126/ changeset: 990861605126 user: hpk42 date: 2011-12-28 18:35:38 summary: fix trial test failure and simplify todo->xfail conversion affected #: 1 file diff -r 6cd04a7beadb4df14cf57e8f0f601cfd15613d5e -r 990861605126a337286674a2e4132907eaea8ceb _pytest/unittest.py --- a/_pytest/unittest.py +++ b/_pytest/unittest.py @@ -28,6 +28,8 @@ x = getattr(self.obj, name) funcobj = getattr(x, 'im_func', x) transfer_markers(funcobj, cls, module) + if hasattr(funcobj, 'todo'): + pytest.mark.xfail(reason=str(funcobj.todo))(funcobj) yield TestCaseFunction(name, parent=self) def setup(self): @@ -45,12 +47,6 @@ class TestCaseFunction(pytest.Function): _excinfo = None - def __init__(self, name, parent): - super(TestCaseFunction, self).__init__(name, parent) - if hasattr(self._obj, 'todo'): - getattr(self._obj, 'im_func', self._obj).xfail = \ - pytest.mark.xfail(reason=str(self._obj.todo)) - def setup(self): self._testcase = self.parent.obj(self.name) self._obj = getattr(self._testcase, self.name) Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Wed Dec 28 18:44:05 2011 From: commits-noreply at bitbucket.org (Bitbucket) Date: Wed, 28 Dec 2011 17:44:05 -0000 Subject: [py-svn] commit/pytest: hpk42: only run test_unittest.py for the twisted/trial config Message-ID: <20111228174405.24767.51570@bitbucket12.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/e3065c26d6f5/ changeset: e3065c26d6f5 user: hpk42 date: 2011-12-28 18:43:56 summary: only run test_unittest.py for the twisted/trial config affected #: 1 file diff -r 990861605126a337286674a2e4132907eaea8ceb -r e3065c26d6f5757e9516f8fcd69bb07844612c56 tox.ini --- a/tox.ini +++ b/tox.ini @@ -33,7 +33,7 @@ :pypi:pexpect py>=1.4.5.dev1 commands= - py.test -rsxf \ + py.test -rsxf testing/test_unittest.py \ --junitxml={envlogdir}/junit-{envname}.xml {posargs:testing/test_unittest.py} [testenv:doctest] changedir=. Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.