From issues-reply at bitbucket.org Mon Sep 1 00:37:02 2014 From: issues-reply at bitbucket.org (Oleg Sinyavskiy) Date: Sun, 31 Aug 2014 22:37:02 -0000 Subject: [Pytest-commit] Issue #575: junitxml: incorrect tagging of import errors (hpk42/pytest) Message-ID: <20140831223702.26683.45955@app07.ash-private.bitbucket.org> New issue 575: junitxml: incorrect tagging of import errors https://bitbucket.org/hpk42/pytest/issue/575/junitxml-incorrect-tagging-of-import Oleg Sinyavskiy: Hello, There are two kinds of failures you can get running py.test - "failure" and "error". When you have import errors, it supposed to be an "error" instead of "failure. However junit xml is inconsistent distinguishing those. I ran py.test on my suite and I've got 2 import errors and 2 pep8 failures. Here is a junit xml header: ``` #!xml ``` However import error files are still tagged as "failures" instead of "errors": ``` #!xml btest_battery_web_plugin.py:30: in from battery_web_plugin import BatteryWebService battery_web_plugin.py:24: in import abap E ImportError: No module named abap ``` This bug shows up itself during parsing with https://pypi.python.org/pypi/xunitparser. It has an assert: ``` #!python assert len(tr.errors) == int(root.attrib['errors']) ``` which check if header summary is consistent with parsed tests descriptions. From issues-reply at bitbucket.org Mon Sep 1 22:47:13 2014 From: issues-reply at bitbucket.org (pombredanne) Date: Mon, 01 Sep 2014 20:47:13 -0000 Subject: [Pytest-commit] Issue #576: Random test failures on windows after editing a python file (hpk42/pytest) Message-ID: <20140901204713.9576.72338@app01.ash-private.bitbucket.org> New issue 576: Random test failures on windows after editing a python file https://bitbucket.org/hpk42/pytest/issue/576/random-test-failures-on-windows-after pombredanne: I get random failures on windows only (not on mac and not on linux) with win7 and Python 2.7.8 and py.test 2.6.1. This heisenbug occurs some times after editing a file and running py.test. Somehow, I found that the previous version of the code was executed, not the one saved. Clearing the __pycache__ solved the issue each time. I reckon that I could disable bytecode creation (as per #200 ) However why should I need to worry about a special python flag or env var just for py.test? Note: the issue could be due to poor filesystem timestamps resolution on windows when files are updated. Could it make sense to have a flag disable caching? or only enable caching with a command flag? From commits-noreply at bitbucket.org Mon Sep 1 22:51:33 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 01 Sep 2014 20:51:33 -0000 Subject: [Pytest-commit] commit/pytest: gutworth: improvements to rewrite cache invalidation Message-ID: <20140901205133.24291.15633@app08.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/a433de9ca4f0/ Changeset: a433de9ca4f0 User: gutworth Date: 2014-09-01 22:51:27 Summary: improvements to rewrite cache invalidation - stat the source path before it is read. - Validate the source size in addition to mtime. Affected #: 3 files diff -r aed87f841a762133588d09f17f2ceb050d726569 -r a433de9ca4f04e4f4f433ef9e80a5d93790c2f4f CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,8 @@ NEXT ----------- +- Improve assertion rewriting cache invalidation precision. + - fixed issue561: adapt autouse fixture example for python3. - fixed issue453: assertion rewriting issue with __repr__ containing diff -r aed87f841a762133588d09f17f2ceb050d726569 -r a433de9ca4f04e4f4f433ef9e80a5d93790c2f4f _pytest/assertion/rewrite.py --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -134,12 +134,12 @@ co = _read_pyc(fn_pypath, pyc, state.trace) if co is None: state.trace("rewriting %r" % (fn,)) - co = _rewrite_test(state, fn_pypath) + source_stat, co = _rewrite_test(state, fn_pypath) if co is None: # Probably a SyntaxError in the test. return None if write: - _make_rewritten_pyc(state, fn_pypath, pyc, co) + _make_rewritten_pyc(state, source_stat, pyc, co) else: state.trace("found cached rewritten pyc for %r" % (fn,)) self.modules[name] = co, pyc @@ -192,13 +192,12 @@ pkg_resources.register_loader_type(cls, pkg_resources.DefaultProvider) -def _write_pyc(state, co, source_path, pyc): +def _write_pyc(state, co, source_stat, pyc): # Technically, we don't have to have the same pyc format as # (C)Python, since these "pycs" should never be seen by builtin # import. However, there's little reason deviate, and I hope # sometime to be able to use imp.load_compiled to load them. (See # the comment in load_module above.) - mtime = int(source_path.mtime()) try: fp = open(pyc, "wb") except IOError: @@ -210,7 +209,9 @@ return False try: fp.write(imp.get_magic()) - fp.write(struct.pack(" 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/570b7b6fd39f/ Changeset: 570b7b6fd39f User: gutworth Date: 2014-09-01 22:51:44 Summary: remove debugging turd Affected #: 1 file diff -r a433de9ca4f04e4f4f433ef9e80a5d93790c2f4f -r 570b7b6fd39fe56ca66d82dd8e3b533c5b4db105 _pytest/assertion/rewrite.py --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -322,7 +322,6 @@ if not isinstance(co, types.CodeType): trace('_read_pyc(%s): not a code object' % source) return None - open("/tmp/goop", "wb").write(b"hi") return co 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 issues-reply at bitbucket.org Mon Sep 1 23:35:37 2014 From: issues-reply at bitbucket.org (Ronny Pfannschmidt) Date: Mon, 01 Sep 2014 21:35:37 -0000 Subject: [Pytest-commit] Issue #577: assert rewritereinterp failure with tripple quotes (hpk42/pytest) Message-ID: <20140901213537.9576.73782@app01.ash-private.bitbucket.org> New issue 577: assert rewritereinterp failure with tripple quotes https://bitbucket.org/hpk42/pytest/issue/577/assert-rewritereinterp-failure-with Ronny Pfannschmidt: ``` #!python """ """ def test_wtf(): assert 0 """ """ a = 1 ``` yields a syntaxerror in any assert mode other than plain From commits-noreply at bitbucket.org Tue Sep 2 11:57:19 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 02 Sep 2014 09:57:19 -0000 Subject: [Pytest-commit] commit/py: hpk42: Merged in flub/py (pull request #20) Message-ID: <20140902095719.22065.83286@app05.ash-private.bitbucket.org> 1 new commit in py: https://bitbucket.org/hpk42/py/commits/4927b441e6e9/ Changeset: 4927b441e6e9 User: hpk42 Date: 2014-09-02 11:57:15 Summary: Merged in flub/py (pull request #20) Mark as a universal wheel Affected #: 1 file diff -r 5b72dc87470629b28be486be252b54a4fd3bcf13 -r 4927b441e6e93ffa70404cf836d80ccafbb215a7 setup.cfg --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[wheel] +universal = 1 \ No newline at end of file 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 Sep 2 11:57:18 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 02 Sep 2014 09:57:18 -0000 Subject: [Pytest-commit] commit/py: 2 new changesets Message-ID: <20140902095718.18262.17622@app14.ash-private.bitbucket.org> 2 new commits in py: https://bitbucket.org/hpk42/py/commits/48e3fa8ac1b1/ Changeset: 48e3fa8ac1b1 User: flub Date: 2014-08-12 00:54:11 Summary: Mark as a universal wheel This is single-source for python 2 & 3 so can be built in a universal wheel. Affected #: 1 file diff -r 591f6bfa83c0f26d503a57f60c3275d33a4208f0 -r 48e3fa8ac1b19b3978c99c60591cd0344ad7e460 setup.cfg --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[wheel] +universal = 1 \ No newline at end of file https://bitbucket.org/hpk42/py/commits/4927b441e6e9/ Changeset: 4927b441e6e9 User: hpk42 Date: 2014-09-02 11:57:15 Summary: Merged in flub/py (pull request #20) Mark as a universal wheel Affected #: 1 file diff -r 5b72dc87470629b28be486be252b54a4fd3bcf13 -r 4927b441e6e93ffa70404cf836d80ccafbb215a7 setup.cfg --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[wheel] +universal = 1 \ No newline at end of file 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 Sep 2 12:22:17 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 02 Sep 2014 10:22:17 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: fix issue572 - python3 compat of tmpdir example in docs. Message-ID: <20140902102217.25100.50984@app09.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/dea7f0ad9330/ Changeset: dea7f0ad9330 User: hpk42 Date: 2014-09-02 12:20:16 Summary: fix issue572 - python3 compat of tmpdir example in docs. Affected #: 3 files diff -r 570b7b6fd39fe56ca66d82dd8e3b533c5b4db105 -r dea7f0ad9330de94194522ea51bf686f2f8e0ef7 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -10,6 +10,8 @@ - Fix example in monkeypatch documentation, thanks t-8ch. +- fix issue572: correct tmpdir doc example for python3. + - Do not mark as universal wheel because Python 2.6 is different from other builds due to the extra argparse dependency. Fixes issue566. Thanks sontek. diff -r 570b7b6fd39fe56ca66d82dd8e3b533c5b4db105 -r dea7f0ad9330de94194522ea51bf686f2f8e0ef7 doc/en/getting-started.txt --- a/doc/en/getting-started.txt +++ b/doc/en/getting-started.txt @@ -51,17 +51,17 @@ =========================== test session starts ============================ platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 collected 1 items - + test_sample.py F - + ================================= FAILURES ================================= _______________________________ test_answer ________________________________ - + def test_answer(): > assert func(3) == 5 E assert 4 == 5 E + where 4 = func(3) - + test_sample.py:5: AssertionError ========================= 1 failed in 0.01 seconds ========================= @@ -126,14 +126,14 @@ .F ================================= FAILURES ================================= ____________________________ TestClass.test_two ____________________________ - + self = - + def test_two(self): x = "hello" > assert hasattr(x, 'check') E assert hasattr('hello', 'check') - + test_class.py:8: AssertionError 1 failed, 1 passed in 0.01 seconds @@ -151,7 +151,7 @@ # content of test_tmpdir.py def test_needsfiles(tmpdir): - print tmpdir + print (tmpdir) assert 0 We list the name ``tmpdir`` in the test function signature and @@ -159,7 +159,7 @@ before performing the test function call. Let's just run it:: $ py.test -q test_tmpdir.py - + ================================== ERRORS ================================== _____________________ ERROR collecting test_tmpdir.py ______________________ /home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/_pytest/python.py:463: in _importtestmodule diff -r 570b7b6fd39fe56ca66d82dd8e3b533c5b4db105 -r dea7f0ad9330de94194522ea51bf686f2f8e0ef7 doc/en/index.txt --- a/doc/en/index.txt +++ b/doc/en/index.txt @@ -11,7 +11,7 @@ **a mature full-featured Python testing tool** - - runs on Posix/Windows, Python 2.5-3.4, PyPy and Jython-2.5.1 + - runs on Posix/Windows, Python 2.6-3.4, PyPy and (possibly still) Jython-2.5.1 - **well tested** with more than a thousand tests against itself - **strict backward compatibility policy** for safe pytest upgrades - :ref:`comprehensive online ` and `PDF documentation `_ 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 Sep 2 12:34:55 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 02 Sep 2014 10:34:55 -0000 Subject: [Pytest-commit] commit/pytest: 3 new changesets Message-ID: <20140902103455.30935.45730@app02.ash-private.bitbucket.org> 3 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/a44059eb0f24/ Changeset: a44059eb0f24 User: flub Date: 2014-08-15 00:23:04 Summary: Depend on newer version of py This fixes issue560, a test for which is included here as well. Affected #: 3 files diff -r f0d4a70ab98a3f1e82f25531ed7e1c9979c12b13 -r a44059eb0f240f025db7caefaa2cfa495e046956 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,9 @@ - fixed issue561: adapt autouse fixture example for python3. +- fix issue560: correctly display code if an "else:" or "finally:" is + followed by statements on the same line. + 2.6.1 ----------------------------------- diff -r f0d4a70ab98a3f1e82f25531ed7e1c9979c12b13 -r a44059eb0f240f025db7caefaa2cfa495e046956 setup.py --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ def main(): - install_requires = ['py>=1.4.22'] + install_requires = ['py>=1.4.24.dev1'] if sys.version_info < (2, 7) or (3,) <= sys.version_info < (3, 2): install_requires.append('argparse') if sys.platform == 'win32': diff -r f0d4a70ab98a3f1e82f25531ed7e1c9979c12b13 -r a44059eb0f240f025db7caefaa2cfa495e046956 testing/test_runner.py --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -505,7 +505,6 @@ assert "UnicodeEncodeError" not in result.stderr.str() - def test_failure_in_setup(testdir): testdir.makepyfile(""" def setup_module(): @@ -515,3 +514,13 @@ """) result = testdir.runpytest("--tb=line") assert "def setup_module" not in result.stdout.str() + + +def test_makereport_getsource(testdir): + testdir.makepyfile(""" + def test_foo(): + if False: pass + else: assert False + """) + result = testdir.runpytest() + assert 'INTERNALERROR' not in result.stdout.str() https://bitbucket.org/hpk42/pytest/commits/d36ab7dd537a/ Changeset: d36ab7dd537a User: flub Date: 2014-08-30 22:57:01 Summary: Improve test by also matching expected output Affected #: 1 file diff -r a44059eb0f240f025db7caefaa2cfa495e046956 -r d36ab7dd537affc4f9ac93035a9aed50534c6a1d testing/test_runner.py --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -524,3 +524,4 @@ """) result = testdir.runpytest() assert 'INTERNALERROR' not in result.stdout.str() + result.stdout.fnmatch_lines(['*else: assert False*']) https://bitbucket.org/hpk42/pytest/commits/ec7b4b6844ff/ Changeset: ec7b4b6844ff User: hpk42 Date: 2014-09-02 12:33:19 Summary: merged in flub/pytest (PR #195) Affected #: 3 files diff -r dea7f0ad9330de94194522ea51bf686f2f8e0ef7 -r ec7b4b6844ff41b31bea9fd772562117de699d1d CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -8,6 +8,9 @@ - fixed issue453: assertion rewriting issue with __repr__ containing "\n{", "\n}" and "\n~". +- fix issue560: correctly display code if an "else:" or "finally:" is + followed by statements on the same line. + - Fix example in monkeypatch documentation, thanks t-8ch. - fix issue572: correct tmpdir doc example for python3. diff -r dea7f0ad9330de94194522ea51bf686f2f8e0ef7 -r ec7b4b6844ff41b31bea9fd772562117de699d1d setup.py --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ def main(): - install_requires = ['py>=1.4.22'] + install_requires = ['py>=1.4.24.dev1'] if sys.version_info < (2, 7) or (3,) <= sys.version_info < (3, 2): install_requires.append('argparse') if sys.platform == 'win32': diff -r dea7f0ad9330de94194522ea51bf686f2f8e0ef7 -r ec7b4b6844ff41b31bea9fd772562117de699d1d testing/test_runner.py --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -505,7 +505,6 @@ assert "UnicodeEncodeError" not in result.stderr.str() - def test_failure_in_setup(testdir): testdir.makepyfile(""" def setup_module(): @@ -515,3 +514,14 @@ """) result = testdir.runpytest("--tb=line") assert "def setup_module" not in result.stdout.str() + + +def test_makereport_getsource(testdir): + testdir.makepyfile(""" + def test_foo(): + if False: pass + else: assert False + """) + result = testdir.runpytest() + assert 'INTERNALERROR' not in result.stdout.str() + result.stdout.fnmatch_lines(['*else: assert False*']) 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 Sep 2 14:48:34 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 02 Sep 2014 12:48:34 -0000 Subject: [Pytest-commit] commit/tox: 4 new changesets Message-ID: <20140902124834.6571.44503@app05.ash-private.bitbucket.org> 4 new commits in tox: https://bitbucket.org/hpk42/tox/commits/35145c72c733/ Changeset: 35145c72c733 User: suor Date: 2014-08-09 14:55:53 Summary: Remove factor negation support Affected #: 2 files diff -r d835cca51418210730ba8c9cc88a8829bc7cb05d -r 35145c72c7334ddb0a7fd7f5d5e5e77353e09827 tests/test_config.py --- a/tests/test_config.py +++ b/tests/test_config.py @@ -835,20 +835,20 @@ def test_factors(self, newconfig): inisource=""" [tox] - envlist = a,b + envlist = a-x,b [testenv] deps= dep-all a: dep-a b: dep-b - !a: dep-not-a + x: dep-x """ conf = newconfig([], inisource) configs = conf.envconfigs - assert [dep.name for dep in configs['a'].deps] == ["dep-all", "dep-a"] - assert [dep.name for dep in configs['b'].deps] == \ - ["dep-all", "dep-b", "dep-not-a"] + assert [dep.name for dep in configs['a-x'].deps] == \ + ["dep-all", "dep-a", "dep-x"] + assert [dep.name for dep in configs['b'].deps] == ["dep-all", "dep-b"] def test_default_factors(self, newconfig): inisource=""" diff -r d835cca51418210730ba8c9cc88a8829bc7cb05d -r 35145c72c7334ddb0a7fd7f5d5e5e77353e09827 tox/_config.py --- a/tox/_config.py +++ b/tox/_config.py @@ -302,7 +302,7 @@ factors = set() if section in self._cfg: for _, value in self._cfg[section].items(): - factors.update(re.findall(r'^!?(\w+)\:\s+', value, re.M)) + factors.update(re.findall(r'^(\w+)\:\s+', value, re.M)) return factors def _makeenvconfig(self, name, section, subs, config): @@ -628,12 +628,12 @@ def _apply_factors(self, s): def factor_line(line): - m = re.search(r'^(!)?(\w+)\:\s+(.+)', line) + m = re.search(r'^(\w+)\:\s+(.+)', line) if not m: return line - negate, factor, line = m.groups() - if bool(negate) ^ (factor in self.factors): + factor, line = m.groups() + if factor in self.factors: return line lines = s.strip().splitlines() https://bitbucket.org/hpk42/tox/commits/34a35ffe5e17/ Changeset: 34a35ffe5e17 User: suor Date: 2014-08-09 16:19:09 Summary: Support boolean ops on factors Affected #: 2 files diff -r 35145c72c7334ddb0a7fd7f5d5e5e77353e09827 -r 34a35ffe5e17a0a162cc6b635c607573d7e39641 tests/test_config.py --- a/tests/test_config.py +++ b/tests/test_config.py @@ -850,6 +850,24 @@ ["dep-all", "dep-a", "dep-x"] assert [dep.name for dep in configs['b'].deps] == ["dep-all", "dep-b"] + def test_factor_ops(self, newconfig): + inisource=""" + [tox] + envlist = {a,b}-{x,y} + + [testenv] + deps= + a,b: dep-a-or-b + a-x: dep-a-and-x + {a,b}-y: dep-ab-and-y + """ + configs = newconfig([], inisource).envconfigs + get_deps = lambda env: [dep.name for dep in configs[env].deps] + assert get_deps("a-x") == ["dep-a-or-b", "dep-a-and-x"] + assert get_deps("a-y") == ["dep-a-or-b", "dep-ab-and-y"] + assert get_deps("b-x") == ["dep-a-or-b"] + assert get_deps("b-y") == ["dep-a-or-b", "dep-ab-and-y"] + def test_default_factors(self, newconfig): inisource=""" [tox] diff -r 35145c72c7334ddb0a7fd7f5d5e5e77353e09827 -r 34a35ffe5e17a0a162cc6b635c607573d7e39641 tox/_config.py --- a/tox/_config.py +++ b/tox/_config.py @@ -302,7 +302,8 @@ factors = set() if section in self._cfg: for _, value in self._cfg[section].items(): - factors.update(re.findall(r'^(\w+)\:\s+', value, re.M)) + exprs = re.findall(r'^([\w{},-]+)\:\s+', value, re.M) + factors.update(*mapcat(_split_factor_expr, exprs)) return factors def _makeenvconfig(self, name, section, subs, config): @@ -434,12 +435,17 @@ dep2_name = pkg_resources.Requirement.parse(dep2).project_name return dep1_name == dep2_name + def _split_env(env): """if handed a list, action="append" was used for -e """ if not isinstance(env, list): env = [env] return mapcat(_expand_envstr, env) +def _split_factor_expr(expr): + partial_envs = _expand_envstr(expr) + return [set(e.split('-')) for e in partial_envs] + def _expand_envstr(envstr): # split by commas not in groups tokens = re.split(r'(\{[^}]+\})|,', envstr) @@ -628,12 +634,12 @@ def _apply_factors(self, s): def factor_line(line): - m = re.search(r'^(\w+)\:\s+(.+)', line) + m = re.search(r'^([\w{},-]+)\:\s+(.+)', line) if not m: return line - factor, line = m.groups() - if factor in self.factors: + expr, line = m.groups() + if any(fs <= self.factors for fs in _split_factor_expr(expr)): return line lines = s.strip().splitlines() https://bitbucket.org/hpk42/tox/commits/d415689eb8ef/ Changeset: d415689eb8ef User: suor Date: 2014-08-09 16:44:41 Summary: Docs for factor expressions Affected #: 1 file diff -r 34a35ffe5e17a0a162cc6b635c607573d7e39641 -r d415689eb8ef671f6940a3e8c8c3d4677b153451 doc/config.txt --- a/doc/config.txt +++ b/doc/config.txt @@ -405,7 +405,7 @@ pytest django15: Django>=1.5,<1.6 django16: Django>=1.6,<1.7 - !py27: unittest2 + py26: unittest2 commands = py.test This uses two new facilities of tox-1.8: @@ -417,6 +417,7 @@ Let's go through this step by step. + Generative envlist +++++++++++++++++++++++ @@ -432,7 +433,7 @@ py27-django15 py27-django16 -You can still list environments explicitely along with generated ones:: +You can still list environments explicitly along with generated ones:: envlist = {py26,py27}-django{15,16}, docs, flake @@ -441,13 +442,13 @@ To help with understanding how the variants will produce section values, you can ask tox to show their expansion with a new option:: - $ tox -l - py26-django15 - py26-django16 - py27-django15 - py27-django16 - docs - flake + $ tox -l + py26-django15 + py26-django16 + py27-django15 + py27-django16 + docs + flake Factors and factor-conditional settings @@ -471,23 +472,14 @@ pytest django15: Django>=1.5,<1.6 django16: Django>=1.6,<1.7 - !py27: unittest2 + py26: unittest2 -The last line here uses negation of a factor, this means ``unittest2`` will be -in ``deps`` for all pythons except python2.7. The whole effect of this setting -definition could be described with a table: +Reading it line by line: -=============== ================================== -environment deps -=============== ================================== -py26-django15 pytest, Django>=1.5,<1.6, unitest2 -py26-django16 pytest, Django>=1.6,<1.7, unitest2 -py27-django15 pytest, Django>=1.5,<1.6 -py27-django16 pytest, Django>=1.6,<1.7 -=============== ================================== - -And this table can significantly grow as you have more dependencies and other -factors such as platform, python version and/or database. +- ``pytest`` will be included unconditionally, +- ``Django>=1.5,<1.6`` will be included for environments containing ``django15`` factor, +- ``Django>=1.6,<1.7`` similarly depends on ``django16`` factor, +- ``unittest`` will be loaded for Python 2.6 environments. .. note:: @@ -496,6 +488,34 @@ setting. +Complex factor conditions ++++++++++++++++++++++++++ + +Sometimes you need to specify same line for several factors or create a special case for +a combination of factors. Here is how you do it:: + + [tox] + envlist = py{25,26,27}-django{14,15,16}-{sqlite,mysql} + + [testenv] + deps = + py25-django14: simplejson ; use it only for this specific combination + py25,py26: unittest2 ; use it for both py25 and py26 + py{25,26}-django14: mock ; patching whatever in older python/django combo + +Take a look at first ``deps`` line. It shows how you can special case something +for a combination of factors, you just join combining factors with a hyphen. +This particular line states that ``simplejson`` will be loaded for python 2.5, django 1.4 +environments, e.g. ``py25-django14-sqlite`` and ``py25-django14-mysql``. + +The second line shows how you use same line for several factors - by listing them +delimited by commas. It's possible to list not only simple factors, but also their +combinations like ``py25-django14,py26-django14``. + +Finally, factor expressions are expanded the same way as envlist, so a last example +could be rewritten as ``py{25,26}-django14``. + + Other Rules and notes ===================== https://bitbucket.org/hpk42/tox/commits/8c6dbbf625b7/ Changeset: 8c6dbbf625b7 User: suor Date: 2014-08-11 12:17:59 Summary: Update complex factor docs Affected #: 1 file diff -r d415689eb8ef671f6940a3e8c8c3d4677b153451 -r 8c6dbbf625b7f41e851ea083faada2695bbdc1c0 doc/config.txt --- a/doc/config.txt +++ b/doc/config.txt @@ -491,29 +491,42 @@ Complex factor conditions +++++++++++++++++++++++++ -Sometimes you need to specify same line for several factors or create a special case for -a combination of factors. Here is how you do it:: +Sometimes you need to specify same line for several factors or create a special +case for a combination of factors. Here is how you do it:: [tox] - envlist = py{25,26,27}-django{14,15,16}-{sqlite,mysql} + envlist = py{26,27,33}-django{15,16}-{sqlite,mysql} [testenv] deps = - py25-django14: simplejson ; use it only for this specific combination - py25,py26: unittest2 ; use it for both py25 and py26 - py{25,26}-django14: mock ; patching whatever in older python/django combo + py33-mysql: PyMySQL ; use if both py33 and mysql are in an env name + py26,py27: urllib3 ; use if any of py26 or py27 are in an env name + py{26,27}-sqlite: mock ; mocking sqlite in python 2.x Take a look at first ``deps`` line. It shows how you can special case something for a combination of factors, you just join combining factors with a hyphen. -This particular line states that ``simplejson`` will be loaded for python 2.5, django 1.4 -environments, e.g. ``py25-django14-sqlite`` and ``py25-django14-mysql``. +This particular line states that ``PyMySQL`` will be loaded for python 3.3, +mysql environments, e.g. ``py33-django15-mysql`` and ``py33-django16-mysql``. -The second line shows how you use same line for several factors - by listing them -delimited by commas. It's possible to list not only simple factors, but also their -combinations like ``py25-django14,py26-django14``. +The second line shows how you use same line for several factors - by listing +them delimited by commas. It's possible to list not only simple factors, but +also their combinations like ``py26-sqlite,py27-sqlite``. -Finally, factor expressions are expanded the same way as envlist, so a last example -could be rewritten as ``py{25,26}-django14``. +Finally, factor expressions are expanded the same way as envlist, so last +example could be rewritten as ``py{26,27}-sqlite``. + +.. note:: + + Factors don't do substring matching against env name, instead every + hyphenated expression is split by ``-`` and if ALL the factors in an + expression are also factors of an env then that condition is considered + hold. + + For example, environment ``py26-mysql``: + + - could be matched with expressions ``py26``, ``py26-mysql``, + ``mysql-py26``, + - but not with ``py2`` or ``py26-sql``. Other Rules and notes Repository URL: https://bitbucket.org/hpk42/tox/ -- 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 Sep 2 14:52:15 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 02 Sep 2014 12:52:15 -0000 Subject: [Pytest-commit] commit/tox: hpk42: Merged in myint/tox (pull request #118) Message-ID: <20140902125215.31174.17912@app07.ash-private.bitbucket.org> 1 new commit in tox: https://bitbucket.org/hpk42/tox/commits/031118307d91/ Changeset: 031118307d91 User: hpk42 Date: 2014-09-02 14:52:12 Summary: Merged in myint/tox (pull request #118) Fix "__PYVENV_LAUNCHER__" problem Affected #: 1 file diff -r 8c6dbbf625b7f41e851ea083faada2695bbdc1c0 -r 031118307d9191807de402ddff95876eb694385b tox/_venv.py --- a/tox/_venv.py +++ b/tox/_venv.py @@ -272,7 +272,8 @@ if '{opts}' in argv: i = argv.index('{opts}') argv[i:i+1] = list(options) - for x in ('PIP_RESPECT_VIRTUALENV', 'PIP_REQUIRE_VIRTUALENV'): + for x in ('PIP_RESPECT_VIRTUALENV', 'PIP_REQUIRE_VIRTUALENV', + '__PYVENV_LAUNCHER__'): try: del os.environ[x] except KeyError: Repository URL: https://bitbucket.org/hpk42/tox/ -- 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 Sep 2 14:52:16 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 02 Sep 2014 12:52:16 -0000 Subject: [Pytest-commit] commit/tox: 2 new changesets Message-ID: <20140902125216.23649.65932@app12.ash-private.bitbucket.org> 2 new commits in tox: https://bitbucket.org/hpk42/tox/commits/e978c8c8935b/ Changeset: e978c8c8935b User: myint Date: 2014-09-01 17:12:16 Summary: Fix "__PYVENV_LAUNCHER__" problem This resolves the use of the non-virtualenv Python executable. This fixes #171. Affected #: 1 file diff -r d835cca51418210730ba8c9cc88a8829bc7cb05d -r e978c8c8935b841288385a87cd447ec5fe071c66 tox/_venv.py --- a/tox/_venv.py +++ b/tox/_venv.py @@ -272,7 +272,8 @@ if '{opts}' in argv: i = argv.index('{opts}') argv[i:i+1] = list(options) - for x in ('PIP_RESPECT_VIRTUALENV', 'PIP_REQUIRE_VIRTUALENV'): + for x in ('PIP_RESPECT_VIRTUALENV', 'PIP_REQUIRE_VIRTUALENV', + '__PYVENV_LAUNCHER__'): try: del os.environ[x] except KeyError: https://bitbucket.org/hpk42/tox/commits/031118307d91/ Changeset: 031118307d91 User: hpk42 Date: 2014-09-02 14:52:12 Summary: Merged in myint/tox (pull request #118) Fix "__PYVENV_LAUNCHER__" problem Affected #: 1 file diff -r 8c6dbbf625b7f41e851ea083faada2695bbdc1c0 -r 031118307d9191807de402ddff95876eb694385b tox/_venv.py --- a/tox/_venv.py +++ b/tox/_venv.py @@ -272,7 +272,8 @@ if '{opts}' in argv: i = argv.index('{opts}') argv[i:i+1] = list(options) - for x in ('PIP_RESPECT_VIRTUALENV', 'PIP_REQUIRE_VIRTUALENV'): + for x in ('PIP_RESPECT_VIRTUALENV', 'PIP_REQUIRE_VIRTUALENV', + '__PYVENV_LAUNCHER__'): try: del os.environ[x] except KeyError: Repository URL: https://bitbucket.org/hpk42/tox/ -- 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 Sep 2 14:56:46 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 02 Sep 2014 12:56:46 -0000 Subject: [Pytest-commit] commit/tox: hpk42: fix issue148: ignore __PYVENV_LAUNCHER__ for subproc Message-ID: <20140902125646.28650.58237@app05.ash-private.bitbucket.org> 1 new commit in tox: https://bitbucket.org/hpk42/tox/commits/7693f02ac23f/ Changeset: 7693f02ac23f User: hpk42 Date: 2014-09-02 14:55:16 Summary: fix issue148: ignore __PYVENV_LAUNCHER__ for subproc Affected #: 6 files diff -r 031118307d9191807de402ddff95876eb694385b -r 7693f02ac23fd4baa8acf7c5024bd0a36311b0d6 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,9 @@ - new multi-dimensional configuration support. Many thanks to Alexander Schepanovski for the complete PR with docs. +- fix issue148: remove "__PYVENV_LAUNCHER__" from os.environ when starting + subprocesses. Thanks Seven Myint. + 1.7.2 ----------- diff -r 031118307d9191807de402ddff95876eb694385b -r 7693f02ac23fd4baa8acf7c5024bd0a36311b0d6 doc/Makefile --- a/doc/Makefile +++ b/doc/Makefile @@ -37,7 +37,7 @@ -rm -rf $(BUILDDIR)/* install: clean html - @rsync -avz $(BUILDDIR)/html/ testrun.org:/www/testrun.org/tox/latest + @rsync -avz $(BUILDDIR)/html/ testrun.org:/www/testrun.org/tox/dev #latexpdf #@scp $(BUILDDIR)/latex/*.pdf testrun.org:www-tox/latest diff -r 031118307d9191807de402ddff95876eb694385b -r 7693f02ac23fd4baa8acf7c5024bd0a36311b0d6 doc/conf.py --- a/doc/conf.py +++ b/doc/conf.py @@ -48,7 +48,8 @@ # built documents. # # The short X.Y version. -release = version = "1.7.2" +release = "1.8" +version = "1.8.0.dev" # The full version, including alpha/beta/rc tags. # The language for content autogenerated by Sphinx. Refer to documentation diff -r 031118307d9191807de402ddff95876eb694385b -r 7693f02ac23fd4baa8acf7c5024bd0a36311b0d6 setup.py --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ description='virtualenv-based automation of test activities', long_description=open("README.rst").read(), url='http://tox.testrun.org/', - version='1.7.2', + version='1.8.0.dev1', license='http://opensource.org/licenses/MIT', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], author='holger krekel', diff -r 031118307d9191807de402ddff95876eb694385b -r 7693f02ac23fd4baa8acf7c5024bd0a36311b0d6 tests/test_venv.py --- a/tests/test_venv.py +++ b/tests/test_venv.py @@ -485,9 +485,11 @@ py.test.raises(ZeroDivisionError, "venv._pcall([1,2,3])") monkeypatch.setenv("PIP_RESPECT_VIRTUALENV", "1") monkeypatch.setenv("PIP_REQUIRE_VIRTUALENV", "1") + monkeypatch.setenv("__PYVENV_LAUNCHER__", "1") py.test.raises(ZeroDivisionError, "venv.run_install_command(['qwe'])") assert 'PIP_RESPECT_VIRTUALENV' not in os.environ assert 'PIP_REQUIRE_VIRTUALENV' not in os.environ + assert '__PYVENV_LAUNCHER__' not in os.environ def test_setenv_added_to_pcall(tmpdir, mocksession, newconfig): pkg = tmpdir.ensure("package.tar.gz") diff -r 031118307d9191807de402ddff95876eb694385b -r 7693f02ac23fd4baa8acf7c5024bd0a36311b0d6 tox/__init__.py --- a/tox/__init__.py +++ b/tox/__init__.py @@ -1,5 +1,5 @@ # -__version__ = '1.7.2' +__version__ = '1.8.0.dev1' class exception: class Error(Exception): Repository URL: https://bitbucket.org/hpk42/tox/ -- 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 Sep 2 14:59:38 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 02 Sep 2014 12:59:38 -0000 Subject: [Pytest-commit] commit/tox: hpk42: Merged in Pentusha/tox/Pentusha/docs-add-pypy3-support-1408431512815 (pull request #117) Message-ID: <20140902125938.12006.66087@app08.ash-private.bitbucket.org> 1 new commit in tox: https://bitbucket.org/hpk42/tox/commits/df113a6427cc/ Changeset: df113a6427cc User: hpk42 Date: 2014-09-02 14:59:34 Summary: Merged in Pentusha/tox/Pentusha/docs-add-pypy3-support-1408431512815 (pull request #117) add pypy3 support to docs Affected #: 1 file diff -r 7693f02ac23fd4baa8acf7c5024bd0a36311b0d6 -r df113a6427cc439fc53978e6e4022c97234756ed doc/example/basic.txt --- a/doc/example/basic.txt +++ b/doc/example/basic.txt @@ -41,6 +41,7 @@ py34 jython pypy + pypy3 However, you can also create your own test environment names, see some of the examples in :doc:`examples <../examples>`. Repository URL: https://bitbucket.org/hpk42/tox/ -- 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 Sep 2 14:59:38 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 02 Sep 2014 12:59:38 -0000 Subject: [Pytest-commit] commit/tox: 2 new changesets Message-ID: <20140902125938.22193.31627@app03.ash-private.bitbucket.org> 2 new commits in tox: https://bitbucket.org/hpk42/tox/commits/2eb1e2648b27/ Changeset: 2eb1e2648b27 Branch: Pentusha/docs-add-pypy3-support-1408431512815 User: Pentusha Date: 2014-08-19 08:58:35 Summary: docs add pypy3 support Affected #: 1 file diff -r d835cca51418210730ba8c9cc88a8829bc7cb05d -r 2eb1e2648b27f4f36a726a18693209967dd8f1dd doc/example/basic.txt --- a/doc/example/basic.txt +++ b/doc/example/basic.txt @@ -41,6 +41,7 @@ py34 jython pypy + pypy3 However, you can also create your own test environment names, see some of the examples in :doc:`examples <../examples>`. https://bitbucket.org/hpk42/tox/commits/df113a6427cc/ Changeset: df113a6427cc User: hpk42 Date: 2014-09-02 14:59:34 Summary: Merged in Pentusha/tox/Pentusha/docs-add-pypy3-support-1408431512815 (pull request #117) add pypy3 support to docs Affected #: 1 file diff -r 7693f02ac23fd4baa8acf7c5024bd0a36311b0d6 -r df113a6427cc439fc53978e6e4022c97234756ed doc/example/basic.txt --- a/doc/example/basic.txt +++ b/doc/example/basic.txt @@ -41,6 +41,7 @@ py34 jython pypy + pypy3 However, you can also create your own test environment names, see some of the examples in :doc:`examples <../examples>`. Repository URL: https://bitbucket.org/hpk42/tox/ -- 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 Sep 2 15:00:22 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 02 Sep 2014 13:00:22 -0000 Subject: [Pytest-commit] commit/tox: hpk42: fix typo in stevens name Message-ID: <20140902130022.11870.67410@app14.ash-private.bitbucket.org> 1 new commit in tox: https://bitbucket.org/hpk42/tox/commits/413683ebbed0/ Changeset: 413683ebbed0 User: hpk42 Date: 2014-09-02 15:00:04 Summary: fix typo in stevens name Affected #: 1 file diff -r df113a6427cc439fc53978e6e4022c97234756ed -r 413683ebbed09f1befde1219f3d02049b9818338 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -5,7 +5,7 @@ Alexander Schepanovski for the complete PR with docs. - fix issue148: remove "__PYVENV_LAUNCHER__" from os.environ when starting - subprocesses. Thanks Seven Myint. + subprocesses. Thanks Steven Myint. 1.7.2 Repository URL: https://bitbucket.org/hpk42/tox/ -- 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 issues-reply at bitbucket.org Tue Sep 2 23:22:35 2014 From: issues-reply at bitbucket.org (Anthony Sottile) Date: Tue, 02 Sep 2014 21:22:35 -0000 Subject: [Pytest-commit] Issue #578: UnicodeDecodeError masks SyntaxError on discovery (hpk42/pytest) Message-ID: <20140902212235.16936.83892@app06.ash-private.bitbucket.org> New issue 578: UnicodeDecodeError masks SyntaxError on discovery https://bitbucket.org/hpk42/pytest/issue/578/unicodedecodeerror-masks-syntaxerror-on Anthony Sottile: Here's a minimal reproduction, my case was obviously more complicated and harder to figure out :). ``` $ python --version Python 2.6.9 $ py.test --version This is pytest version 2.6.1, imported from /home/asottile/workspace/pre-commit/.tox/py26/lib/python2.6/site-packages/pytest.pyc $ cat test.py # -*- coding: UTF-8 -*- ? $ py.test !$ py.test test.py ============================= test session starts ============================== platform linux2 -- Python 2.6.9 -- py-1.4.23 -- pytest-2.6.1 collected 0 items / 1 errors ==================================== ERRORS ==================================== ___________________________ ERROR collecting test.py ___________________________ .tox/py26/lib/python2.6/site-packages/py/_code/code.py:412: in getrepr return fmt.repr_excinfo(self) .tox/py26/lib/python2.6/site-packages/py/_code/code.py:589: in repr_excinfo reprtraceback = self.repr_traceback(excinfo) .tox/py26/lib/python2.6/site-packages/py/_code/code.py:581: in repr_traceback reprentry = self.repr_traceback_entry(entry, einfo) .tox/py26/lib/python2.6/site-packages/py/_code/code.py:543: in repr_traceback_entry s = self.get_source(source, line_index, excinfo, short=short) .tox/py26/lib/python2.6/site-packages/py/_code/code.py:489: in get_source lines.extend(self.get_exconly(excinfo, indent=indent, markall=True)) .tox/py26/lib/python2.6/site-packages/py/_code/code.py:496: in get_exconly exlines = excinfo.exconly(tryshort=True).split('\n') .tox/py26/lib/python2.6/site-packages/py/_code/code.py:376: in exconly text = ''.join(lines) E UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 4: ordinal not in range(128) =========================== 1 error in 0.04 seconds ============================ $ python !$ python test.py File "test.py", line 3 ? ^ SyntaxError: invalid syntax ``` From issues-reply at bitbucket.org Wed Sep 3 10:26:39 2014 From: issues-reply at bitbucket.org (d3ph) Date: Wed, 03 Sep 2014 08:26:39 -0000 Subject: [Pytest-commit] Issue #579: Request the feature to modify parametrized fixture with indirect modification (hpk42/pytest) Message-ID: <20140903082639.7927.55537@app02.ash-private.bitbucket.org> New issue 579: Request the feature to modify parametrized fixture with indirect modification https://bitbucket.org/hpk42/pytest/issue/579/request-the-feature-to-modify-parametrized d3ph: It seems to me modifying already parametrized tests are reasonable: ``` #!python import pytest class SomeImpl: def __init__(self, name): self.name = name def get_name(self): return self.name @pytest.fixture(params=['SomeOne', 'SomeTwo']) def some(request): return SomeImpl(request.param) def test_default(some): assert some.get_name() @pytest.mark.parametrize('some', ['SomeOne'], indirect=True) def test_only_one(some): assert some.get_name() if __name__ == '__main__': pytest.main(args=[__file__]) ``` Responsible: flub From commits-noreply at bitbucket.org Wed Sep 3 15:15:24 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 03 Sep 2014 13:15:24 -0000 Subject: [Pytest-commit] commit/py: pmoore: Add {read, write}_{binary, text} methods to LocalPath instances Message-ID: <20140903131524.22687.46183@app10.ash-private.bitbucket.org> 1 new commit in py: https://bitbucket.org/hpk42/py/commits/764221efcef5/ Changeset: 764221efcef5 User: pmoore Date: 2014-09-02 15:53:51 Summary: Add {read,write}_{binary,text} methods to LocalPath instances Affected #: 3 files diff -r 4927b441e6e93ffa70404cf836d80ccafbb215a7 -r 764221efcef5bbc004e0e7f68ee5230dfa7168dc py/_path/common.py --- a/py/_path/common.py +++ b/py/_path/common.py @@ -115,6 +115,22 @@ """ return self.new(basename='').join(*args, **kwargs) + def read_binary(self): + """ read and return a bytestring from reading the path. """ + f = self.open('rb') + try: + return f.read() + finally: + f.close() + + def read_text(self, encoding=None): + """ read and return a Unicode string from reading the path. """ + f = self.open('r', encoding=encoding) + try: + return f.read() + finally: + f.close() + def read(self, mode='r'): """ read and return a bytestring from reading the path. """ if sys.version_info < (2,3): diff -r 4927b441e6e93ffa70404cf836d80ccafbb215a7 -r 764221efcef5bbc004e0e7f68ee5230dfa7168dc py/_path/local.py --- a/py/_path/local.py +++ b/py/_path/local.py @@ -2,7 +2,7 @@ local path implementation. """ from contextlib import contextmanager -import sys, os, re, atexit +import sys, os, re, atexit, io import py from py._path import common from stat import S_ISLNK, S_ISDIR, S_ISREG @@ -330,13 +330,15 @@ obj.strpath = normpath(strpath) return obj - def open(self, mode='r', ensure=False): + def open(self, mode='r', ensure=False, encoding=None): """ return an opened file with the given mode. If ensure is True, create parent directories if needed. """ if ensure: self.dirpath().ensure(dir=1) + if encoding: + return py.error.checked_call(io.open, self.strpath, mode, encoding=encoding) return py.error.checked_call(open, self.strpath, mode) def _fastjoin(self, name): @@ -434,6 +436,30 @@ py.error.checked_call(os.mkdir, getattr(p, "strpath", p)) return p + def write_binary(self, data, ensure=False): + """ write binary data into path. If ensure is True create + missing parent directories. + """ + if ensure: + self.dirpath().ensure(dir=1) + f = self.open('wb') + try: + f.write(data) + finally: + f.close() + + def write_text(self, data, ensure=False, encoding=None): + """ write binary data into path. If ensure is True create + missing parent directories. + """ + if ensure: + self.dirpath().ensure(dir=1) + f = self.open('w', encoding=encoding) + try: + f.write(data) + finally: + f.close() + def write(self, data, mode='w', ensure=False): """ write data into path. If ensure is True create missing parent directories. diff -r 4927b441e6e93ffa70404cf836d80ccafbb215a7 -r 764221efcef5bbc004e0e7f68ee5230dfa7168dc testing/path/test_local.py --- a/testing/path/test_local.py +++ b/testing/path/test_local.py @@ -801,3 +801,24 @@ x.write(part.encode(sys.getdefaultencoding())) assert x.read() == part.encode(sys.getdefaultencoding()) +class TestBinaryAndTextMethods: + def test_read_binwrite(self, tmpdir): + x = tmpdir.join("hello") + part = py.builtin._totext("h?llo", "utf8") + part_utf8 = part.encode("utf8") + x.write_binary(part_utf8) + assert x.read_binary() == part_utf8 + assert x.read_text(encoding="utf8") == part + def test_read_textwrite(self, tmpdir): + x = tmpdir.join("hello") + part = py.builtin._totext("h?llo", "utf8") + part_utf8 = part.encode("utf8") + x.write_text(part, encoding="utf8") + assert x.read_binary() == part_utf8 + assert x.read_text(encoding="utf8") == part + def test_default_encoding(self, tmpdir): + x = tmpdir.join("hello") + # Can't use UTF8 as the default encoding (ASCII) doesn't support it + part = py.builtin._totext("hello", "ascii") + x.write_text(part) + assert x.read_text() == part 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 Sep 3 15:41:45 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 03 Sep 2014 13:41:45 -0000 Subject: [Pytest-commit] commit/py: hpk42: implement text/bytes variants for local paths Message-ID: <20140903134145.8256.23428@app04.ash-private.bitbucket.org> 1 new commit in py: https://bitbucket.org/hpk42/py/commits/ca27187c337d/ Changeset: ca27187c337d User: hpk42 Date: 2014-09-03 15:41:35 Summary: implement text/bytes variants for local paths Affected #: 4 files diff -r 764221efcef5bbc004e0e7f68ee5230dfa7168dc -r ca27187c337d018186012ceb340d178a8adb893b CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,9 +1,13 @@ -1.4.24 +1.4.24.dev ================================================== - Fix retrieving source when an else: line has an other statement on the same line. +- add localpath read_text/write_text/read_bytes/write_bytes methods + as shortcuts and clearer bytes/text interfaces for read/write. + Adapted from a PR from Paul Moore. + 1.4.23 ================================================== diff -r 764221efcef5bbc004e0e7f68ee5230dfa7168dc -r ca27187c337d018186012ceb340d178a8adb893b py/_path/common.py --- a/py/_path/common.py +++ b/py/_path/common.py @@ -117,31 +117,19 @@ def read_binary(self): """ read and return a bytestring from reading the path. """ - f = self.open('rb') - try: + with self.open('rb') as f: return f.read() - finally: - f.close() - def read_text(self, encoding=None): + def read_text(self, encoding="utf8"): """ read and return a Unicode string from reading the path. """ - f = self.open('r', encoding=encoding) - try: + with self.open("r", encoding=encoding) as f: return f.read() - finally: - f.close() + def read(self, mode='r'): """ read and return a bytestring from reading the path. """ - if sys.version_info < (2,3): - for x in 'u', 'U': - if x in mode: - mode = mode.replace(x, '') - f = self.open(mode) - try: + with self.open(mode) as f: return f.read() - finally: - f.close() def readlines(self, cr=1): """ read and return a list of lines from the path. if cr is False, the diff -r 764221efcef5bbc004e0e7f68ee5230dfa7168dc -r ca27187c337d018186012ceb340d178a8adb893b py/_path/local.py --- a/py/_path/local.py +++ b/py/_path/local.py @@ -442,23 +442,17 @@ """ if ensure: self.dirpath().ensure(dir=1) - f = self.open('wb') - try: + with self.open('wb') as f: f.write(data) - finally: - f.close() - def write_text(self, data, ensure=False, encoding=None): - """ write binary data into path. If ensure is True create - missing parent directories. + def write_text(self, data, encoding="utf8", ensure=False): + """ write text data into path using the specified encoding. + If ensure is True create missing parent directories. """ if ensure: self.dirpath().ensure(dir=1) - f = self.open('w', encoding=encoding) - try: + with self.open('w', encoding=encoding) as f: f.write(data) - finally: - f.close() def write(self, data, mode='w', ensure=False): """ write data into path. If ensure is True create diff -r 764221efcef5bbc004e0e7f68ee5230dfa7168dc -r ca27187c337d018186012ceb340d178a8adb893b testing/path/test_local.py --- a/testing/path/test_local.py +++ b/testing/path/test_local.py @@ -808,7 +808,10 @@ part_utf8 = part.encode("utf8") x.write_binary(part_utf8) assert x.read_binary() == part_utf8 - assert x.read_text(encoding="utf8") == part + s = x.read_text(encoding="utf8") + assert s == part + assert py.builtin._istext(s) + def test_read_textwrite(self, tmpdir): x = tmpdir.join("hello") part = py.builtin._totext("h?llo", "utf8") @@ -816,9 +819,12 @@ x.write_text(part, encoding="utf8") assert x.read_binary() == part_utf8 assert x.read_text(encoding="utf8") == part + def test_default_encoding(self, tmpdir): x = tmpdir.join("hello") # Can't use UTF8 as the default encoding (ASCII) doesn't support it part = py.builtin._totext("hello", "ascii") x.write_text(part) - assert x.read_text() == part + s = x.read_text() + assert s == part + assert type(s) == type(part) 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 Sep 3 16:38:32 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 03 Sep 2014 14:38:32 -0000 Subject: [Pytest-commit] commit/py: hpk42: require encoding argument for read/write_text Message-ID: <20140903143832.21544.10441@app03.ash-private.bitbucket.org> 1 new commit in py: https://bitbucket.org/hpk42/py/commits/74b757aec58c/ Changeset: 74b757aec58c User: hpk42 Date: 2014-09-03 16:38:21 Summary: require encoding argument for read/write_text Affected #: 3 files diff -r ca27187c337d018186012ceb340d178a8adb893b -r 74b757aec58c65d8ba61eb5a4d91201e59012b50 py/_path/common.py --- a/py/_path/common.py +++ b/py/_path/common.py @@ -120,7 +120,7 @@ with self.open('rb') as f: return f.read() - def read_text(self, encoding="utf8"): + def read_text(self, encoding): """ read and return a Unicode string from reading the path. """ with self.open("r", encoding=encoding) as f: return f.read() diff -r ca27187c337d018186012ceb340d178a8adb893b -r 74b757aec58c65d8ba61eb5a4d91201e59012b50 py/_path/local.py --- a/py/_path/local.py +++ b/py/_path/local.py @@ -445,7 +445,7 @@ with self.open('wb') as f: f.write(data) - def write_text(self, data, encoding="utf8", ensure=False): + def write_text(self, data, encoding, ensure=False): """ write text data into path using the specified encoding. If ensure is True create missing parent directories. """ diff -r ca27187c337d018186012ceb340d178a8adb893b -r 74b757aec58c65d8ba61eb5a4d91201e59012b50 testing/path/test_local.py --- a/testing/path/test_local.py +++ b/testing/path/test_local.py @@ -824,7 +824,7 @@ x = tmpdir.join("hello") # Can't use UTF8 as the default encoding (ASCII) doesn't support it part = py.builtin._totext("hello", "ascii") - x.write_text(part) - s = x.read_text() + x.write_text(part, "ascii") + s = x.read_text("ascii") assert s == part assert type(s) == type(part) 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 Sep 3 22:57:48 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 03 Sep 2014 20:57:48 -0000 Subject: [Pytest-commit] commit/pytest: 11 new changesets Message-ID: <20140903205748.22001.71229@app08.ash-private.bitbucket.org> 11 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/016cdc38d5e9/ Changeset: 016cdc38d5e9 Branch: cx_freeze-support User: nicoddemus Date: 2014-07-31 00:16:51 Summary: first implementation and tox environment for cx-freeze support Affected #: 8 files diff -r 040c46f257331f1c4546246683a808668969c011 -r 016cdc38d5e9deaafffac07f0d8351d09e5b460c _pytest/cx_freeze_support.py --- /dev/null +++ b/_pytest/cx_freeze_support.py @@ -0,0 +1,52 @@ + + +def includes(): + return [ + '_pytest.assertion.newinterpret', + '_pytest.assertion.oldinterpret', + '_pytest.assertion.reinterpret', + '_pytest.assertion.rewrite', + '_pytest.assertion.util', + + '_pytest._argcomplete', + '_pytest.doctest', + '_pytest.pdb', + '_pytest.unittest', + '_pytest.capture', + '_pytest.config', + '_pytest.core', + '_pytest.genscript', + '_pytest.helpconfig', + '_pytest.hookspec', + '_pytest.junitxml', + '_pytest.main', + '_pytest.mark', + '_pytest.monkeypatch', + '_pytest.nose', + '_pytest.pastebin', + '_pytest.pytester', + '_pytest.python', + '_pytest.recwarn', + '_pytest.resultlog', + '_pytest.runner', + '_pytest.skipping', + '_pytest.standalonetemplate', + '_pytest.terminal', + '_pytest.tmpdir', + + 'py._builtin', + 'py._path.local', + 'py._io.capture', + 'py._io.saferepr', + 'py._iniconfig', + 'py._io.terminalwriter', + 'py._xmlgen', + 'py._error', + 'py._std', + + # builtin files imported by pytest using py.std implicit mechanism + 'argparse', + 'shlex', + 'warnings', + 'types', + ] \ No newline at end of file diff -r 040c46f257331f1c4546246683a808668969c011 -r 016cdc38d5e9deaafffac07f0d8351d09e5b460c pytest.py --- a/pytest.py +++ b/pytest.py @@ -13,6 +13,7 @@ from _pytest.config import main, UsageError, _preloadplugins, cmdline from _pytest import __version__ +from _pytest import cx_freeze_support _preloadplugins() # to populate pytest.* namespace so help(pytest) works diff -r 040c46f257331f1c4546246683a808668969c011 -r 016cdc38d5e9deaafffac07f0d8351d09e5b460c testing/cx_freeze/run.py --- /dev/null +++ b/testing/cx_freeze/run.py @@ -0,0 +1,7 @@ +import os +import sys + +executable = os.path.join(os.getcwd(), 'build', 'runtests_script') +if sys.platform.startswith('win'): + executable += '.exe' +sys.exit(os.system('%s tests' % executable)) \ No newline at end of file diff -r 040c46f257331f1c4546246683a808668969c011 -r 016cdc38d5e9deaafffac07f0d8351d09e5b460c testing/cx_freeze/runtests_script.py --- /dev/null +++ b/testing/cx_freeze/runtests_script.py @@ -0,0 +1,10 @@ +""" +Simple script that actually executes py.test runner when passed "--pytest" as +first argument; in this case, all other arguments are forwarded to pytest's +main(). +""" + +if __name__ == '__main__': + import sys + import pytest + sys.exit(pytest.main()) \ No newline at end of file diff -r 040c46f257331f1c4546246683a808668969c011 -r 016cdc38d5e9deaafffac07f0d8351d09e5b460c testing/cx_freeze/runtests_setup.py --- /dev/null +++ b/testing/cx_freeze/runtests_setup.py @@ -0,0 +1,11 @@ +from cx_Freeze import setup, Executable + +import pytest +setup( + name="runtests", + version="0.1", + description="exemple of how embedding py.test into an executable using cx_freeze", + executables=[Executable("runtests_script.py")], + options={"build_exe": {'includes': pytest.cx_freeze_support.includes()}}, +) + diff -r 040c46f257331f1c4546246683a808668969c011 -r 016cdc38d5e9deaafffac07f0d8351d09e5b460c testing/cx_freeze/tests/test_doctest.txt --- /dev/null +++ b/testing/cx_freeze/tests/test_doctest.txt @@ -0,0 +1,6 @@ + + +Testing doctest:: + + >>> 1 + 1 + 2 diff -r 040c46f257331f1c4546246683a808668969c011 -r 016cdc38d5e9deaafffac07f0d8351d09e5b460c testing/cx_freeze/tests/test_trivial.py --- /dev/null +++ b/testing/cx_freeze/tests/test_trivial.py @@ -0,0 +1,6 @@ + +def test_upper(): + assert 'foo'.upper() == 'FOO' + +def test_lower(): + assert 'FOO'.lower() == 'foo' \ No newline at end of file diff -r 040c46f257331f1c4546246683a808668969c011 -r 016cdc38d5e9deaafffac07f0d8351d09e5b460c tox.ini --- a/tox.ini +++ b/tox.ini @@ -123,6 +123,14 @@ {envpython} {envbindir}/py.test-jython \ -rfsxX --junitxml={envlogdir}/junit-{envname}2.xml [] +[testenv:py27-cxfreeze] +deps=cx_freeze +changedir=testing/cx_freeze +basepython=python2.7 +commands= + {envpython} runtests_setup.py build --build-exe build + {envpython} run.py + [pytest] minversion=2.0 plugins=pytester https://bitbucket.org/hpk42/pytest/commits/e014ae4ab62e/ Changeset: e014ae4ab62e Branch: cx_freeze-support User: nicoddemus Date: 2014-07-31 02:50:00 Summary: Docs about cx_freeze support and minor adjustments Affected #: 7 files diff -r 016cdc38d5e9deaafffac07f0d8351d09e5b460c -r e014ae4ab62ea71a8ec0a5b8045864423aeb63c0 _pytest/cx_freeze_support.py --- a/_pytest/cx_freeze_support.py +++ b/_pytest/cx_freeze_support.py @@ -1,52 +1,56 @@ +""" +Package to support embedding pytest runner into executable files. +.. note:: Since we are imported into pytest namespace, we use local imports to + be as cheap as possible. +""" def includes(): - return [ - '_pytest.assertion.newinterpret', - '_pytest.assertion.oldinterpret', - '_pytest.assertion.reinterpret', - '_pytest.assertion.rewrite', - '_pytest.assertion.util', + """ + Returns a list of module names used by py.test that should be + included by cx_freeze. + """ + import py + import _pytest - '_pytest._argcomplete', - '_pytest.doctest', - '_pytest.pdb', - '_pytest.unittest', - '_pytest.capture', - '_pytest.config', - '_pytest.core', - '_pytest.genscript', - '_pytest.helpconfig', - '_pytest.hookspec', - '_pytest.junitxml', - '_pytest.main', - '_pytest.mark', - '_pytest.monkeypatch', - '_pytest.nose', - '_pytest.pastebin', - '_pytest.pytester', - '_pytest.python', - '_pytest.recwarn', - '_pytest.resultlog', - '_pytest.runner', - '_pytest.skipping', - '_pytest.standalonetemplate', - '_pytest.terminal', - '_pytest.tmpdir', + result = list(_iter_all_modules(py)) + result += list(_iter_all_modules(_pytest)) - 'py._builtin', - 'py._path.local', - 'py._io.capture', - 'py._io.saferepr', - 'py._iniconfig', - 'py._io.terminalwriter', - 'py._xmlgen', - 'py._error', - 'py._std', - - # builtin files imported by pytest using py.std implicit mechanism + # builtin files imported by pytest using py.std implicit mechanism; + # should be removed if https://bitbucket.org/hpk42/pytest/pull-request/185 + # gets merged + result += [ 'argparse', 'shlex', 'warnings', 'types', - ] \ No newline at end of file + ] + return result + + +def _iter_all_modules(package, prefix=''): + """ + Iterates over the names of all modules that can be found in the given + package, recursively. + + Example: + _iter_all_modules(_pytest) -> + ['_pytest.assertion.newinterpret', + '_pytest.capture', + '_pytest.core', + ... + ] + """ + import pkgutil + import os + + if type(package) is not str: + path, prefix = package.__path__[0], package.__name__ + '.' + else: + path = package + for _, name, is_package in pkgutil.iter_modules([path]): + if is_package: + for m in _iter_all_modules(os.path.join(path, name), prefix=name + '.'): + yield prefix + m + else: + yield prefix + name diff -r 016cdc38d5e9deaafffac07f0d8351d09e5b460c -r e014ae4ab62ea71a8ec0a5b8045864423aeb63c0 doc/en/example/simple.txt --- a/doc/en/example/simple.txt +++ b/doc/en/example/simple.txt @@ -694,33 +694,26 @@ send test files to users so they can run them in their machines, which can be invaluable to obtain more information about a hard to reproduce bug. -Unfortunately embedding the ``pytest`` runner into a frozen executable using -``cx_freeze`` is not as straightforward as one would like, -because ``pytest`` makes heavy use of dynamic module loading which -``cx_freeze`` can't resolve by itself. - -To solve this, you have to manually include ``pytest`` and ``py`` -modules by using the ``build_exe`` option in your ``setup.py`` script, like this:: +Unfortunately ``cx_freeze`` can't discover them +automatically because of ``pytest``'s use of dynamic module loading, so you +must declare them explicitly by using ``pytest.cx_freeze_support.includes()``:: # contents of setup.py from cx_Freeze import setup, Executable + import pytest - includes = [ - '_pytest.doctest', - '_pytest.unittest', - # ... lots more - ] setup( name="runtests", - options={"build_exe": {'includes': includes}}, + options={"build_exe": + { + 'includes': pytest.cx_freeze_support.includes()} + }, # ... other options ) -(For the complete list, check out the modules under ``_pytest`` in your -site-packages). - -With that, you can make your program check for a certain flag and pass control -over to ``pytest``:: +If you don't want to ship a different executable just in order to run your tests, +you can make your program check for a certain flag and pass control +over to ``pytest`` instead. For example:: # contents of app_main.py import sys @@ -734,6 +727,6 @@ ... This makes it convenient to execute your tests from within your frozen -application, using standard ``py.test`` command-line:: +application, using standard ``py.test`` command-line options:: $ ./app_main --pytest --verbose --tb=long --junit-xml=results.xml test-suite/ \ No newline at end of file diff -r 016cdc38d5e9deaafffac07f0d8351d09e5b460c -r e014ae4ab62ea71a8ec0a5b8045864423aeb63c0 testing/cx_freeze/run.py --- a/testing/cx_freeze/run.py +++ /dev/null @@ -1,7 +0,0 @@ -import os -import sys - -executable = os.path.join(os.getcwd(), 'build', 'runtests_script') -if sys.platform.startswith('win'): - executable += '.exe' -sys.exit(os.system('%s tests' % executable)) \ No newline at end of file diff -r 016cdc38d5e9deaafffac07f0d8351d09e5b460c -r e014ae4ab62ea71a8ec0a5b8045864423aeb63c0 testing/cx_freeze/runtests_script.py --- a/testing/cx_freeze/runtests_script.py +++ b/testing/cx_freeze/runtests_script.py @@ -1,7 +1,6 @@ """ -Simple script that actually executes py.test runner when passed "--pytest" as -first argument; in this case, all other arguments are forwarded to pytest's -main(). +This is the script that is actually frozen into an executable: simply executes +py.test main(). """ if __name__ == '__main__': diff -r 016cdc38d5e9deaafffac07f0d8351d09e5b460c -r e014ae4ab62ea71a8ec0a5b8045864423aeb63c0 testing/cx_freeze/runtests_setup.py --- a/testing/cx_freeze/runtests_setup.py +++ b/testing/cx_freeze/runtests_setup.py @@ -1,6 +1,9 @@ +""" +Sample setup.py script that generates an executable with pytest runner embedded. +""" from cx_Freeze import setup, Executable +import pytest -import pytest setup( name="runtests", version="0.1", diff -r 016cdc38d5e9deaafffac07f0d8351d09e5b460c -r e014ae4ab62ea71a8ec0a5b8045864423aeb63c0 testing/cx_freeze/tox_run.py --- /dev/null +++ b/testing/cx_freeze/tox_run.py @@ -0,0 +1,14 @@ +""" +Called by tox.ini: uses the generated executable to run the tests in ./tests/ +directory. + +.. note:: somehow calling "build/runtests_script" directly from tox doesn't + seem to work (at least on Windows). +""" +import os +import sys + +executable = os.path.join(os.getcwd(), 'build', 'runtests_script') +if sys.platform.startswith('win'): + executable += '.exe' +sys.exit(os.system('%s tests' % executable)) \ No newline at end of file diff -r 016cdc38d5e9deaafffac07f0d8351d09e5b460c -r e014ae4ab62ea71a8ec0a5b8045864423aeb63c0 tox.ini --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] distshare={homedir}/.tox/distshare -envlist=flakes,py26,py27,py34,pypy,py27-pexpect,py33-pexpect,py27-nobyte,py32,py33,py27-xdist,py33-xdist,py27-trial,py33-trial,doctesting +envlist=flakes,py26,py27,py34,pypy,py27-pexpect,py33-pexpect,py27-nobyte,py32,py33,py27-xdist,py33-xdist,py27-trial,py33-trial,doctesting,py27-cxfreeze [testenv] changedir=testing @@ -129,7 +129,7 @@ basepython=python2.7 commands= {envpython} runtests_setup.py build --build-exe build - {envpython} run.py + {envpython} tox_run.py [pytest] minversion=2.0 https://bitbucket.org/hpk42/pytest/commits/42411297f4d7/ Changeset: 42411297f4d7 Branch: cx_freeze-support User: nicoddemus Date: 2014-07-31 02:57:19 Summary: fixed line endings for test_doctest.txt Affected #: 1 file diff -r e014ae4ab62ea71a8ec0a5b8045864423aeb63c0 -r 42411297f4d7348102dafd5cc0c986c94a825494 testing/cx_freeze/tests/test_doctest.txt --- a/testing/cx_freeze/tests/test_doctest.txt +++ b/testing/cx_freeze/tests/test_doctest.txt @@ -1,6 +1,6 @@ - - -Testing doctest:: - - >>> 1 + 1 - 2 + + +Testing doctest:: + + >>> 1 + 1 + 2 https://bitbucket.org/hpk42/pytest/commits/8b0cb61eb871/ Changeset: 8b0cb61eb871 Branch: cx_freeze-support User: nicoddemus Date: 2014-07-31 03:28:03 Summary: guarding scripts with __main__ and doc changes tox-flakes environment tries to import the modules for checking, and that may fail because of its dependencies Affected #: 3 files diff -r 42411297f4d7348102dafd5cc0c986c94a825494 -r 8b0cb61eb871dcd416520201b83b639b5bf718e7 doc/en/example/simple.txt --- a/doc/en/example/simple.txt +++ b/doc/en/example/simple.txt @@ -703,7 +703,8 @@ import pytest setup( - name="runtests", + name="app_main", + executables=[Executable("app_main.py")], options={"build_exe": { 'includes': pytest.cx_freeze_support.includes()} diff -r 42411297f4d7348102dafd5cc0c986c94a825494 -r 8b0cb61eb871dcd416520201b83b639b5bf718e7 testing/cx_freeze/runtests_setup.py --- a/testing/cx_freeze/runtests_setup.py +++ b/testing/cx_freeze/runtests_setup.py @@ -1,14 +1,15 @@ """ Sample setup.py script that generates an executable with pytest runner embedded. """ -from cx_Freeze import setup, Executable -import pytest +if __name__ == '__main__': + from cx_Freeze import setup, Executable + import pytest -setup( - name="runtests", - version="0.1", - description="exemple of how embedding py.test into an executable using cx_freeze", - executables=[Executable("runtests_script.py")], - options={"build_exe": {'includes': pytest.cx_freeze_support.includes()}}, -) + setup( + name="runtests", + version="0.1", + description="exemple of how embedding py.test into an executable using cx_freeze", + executables=[Executable("runtests_script.py")], + options={"build_exe": {'includes': pytest.cx_freeze_support.includes()}}, + ) diff -r 42411297f4d7348102dafd5cc0c986c94a825494 -r 8b0cb61eb871dcd416520201b83b639b5bf718e7 testing/cx_freeze/tox_run.py --- a/testing/cx_freeze/tox_run.py +++ b/testing/cx_freeze/tox_run.py @@ -5,10 +5,11 @@ .. note:: somehow calling "build/runtests_script" directly from tox doesn't seem to work (at least on Windows). """ -import os -import sys +if __name__ == '__main__': + import os + import sys -executable = os.path.join(os.getcwd(), 'build', 'runtests_script') -if sys.platform.startswith('win'): - executable += '.exe' -sys.exit(os.system('%s tests' % executable)) \ No newline at end of file + executable = os.path.join(os.getcwd(), 'build', 'runtests_script') + if sys.platform.startswith('win'): + executable += '.exe' + sys.exit(os.system('%s tests' % executable)) \ No newline at end of file https://bitbucket.org/hpk42/pytest/commits/4901560bef61/ Changeset: 4901560bef61 Branch: cx_freeze-support User: nicoddemus Date: 2014-08-12 01:03:14 Summary: Moved freeze_includes() to genscript Affected #: 5 files diff -r 8b0cb61eb871dcd416520201b83b639b5bf718e7 -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 _pytest/cx_freeze_support.py --- a/_pytest/cx_freeze_support.py +++ /dev/null @@ -1,56 +0,0 @@ -""" -Package to support embedding pytest runner into executable files. - -.. note:: Since we are imported into pytest namespace, we use local imports to - be as cheap as possible. -""" - -def includes(): - """ - Returns a list of module names used by py.test that should be - included by cx_freeze. - """ - import py - import _pytest - - result = list(_iter_all_modules(py)) - result += list(_iter_all_modules(_pytest)) - - # builtin files imported by pytest using py.std implicit mechanism; - # should be removed if https://bitbucket.org/hpk42/pytest/pull-request/185 - # gets merged - result += [ - 'argparse', - 'shlex', - 'warnings', - 'types', - ] - return result - - -def _iter_all_modules(package, prefix=''): - """ - Iterates over the names of all modules that can be found in the given - package, recursively. - - Example: - _iter_all_modules(_pytest) -> - ['_pytest.assertion.newinterpret', - '_pytest.capture', - '_pytest.core', - ... - ] - """ - import pkgutil - import os - - if type(package) is not str: - path, prefix = package.__path__[0], package.__name__ + '.' - else: - path = package - for _, name, is_package in pkgutil.iter_modules([path]): - if is_package: - for m in _iter_all_modules(os.path.join(path, name), prefix=name + '.'): - yield prefix + m - else: - yield prefix + name diff -r 8b0cb61eb871dcd416520201b83b639b5bf718e7 -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 _pytest/genscript.py --- a/_pytest/genscript.py +++ b/_pytest/genscript.py @@ -1,6 +1,12 @@ """ generate a single-file self-contained version of pytest """ +import os +import sys +import pkgutil + import py -import sys + +import _pytest + def find_toplevel(name): for syspath in py.std.sys.path: @@ -78,3 +84,52 @@ tw.line("generated pytest standalone script: %s" % genscript, bold=True) return 0 + + +def pytest_namespace(): + return {'freeze_includes': freeze_includes} + + +def freeze_includes(): + """ + Returns a list of module names used by py.test that should be + included by cx_freeze. + """ + result = list(_iter_all_modules(py)) + result += list(_iter_all_modules(_pytest)) + + # builtin files imported by pytest using py.std implicit mechanism; + # should be removed if https://bitbucket.org/hpk42/pytest/pull-request/185 + # gets merged + result += [ + 'argparse', + 'shlex', + 'warnings', + 'types', + ] + return result + + +def _iter_all_modules(package, prefix=''): + """ + Iterates over the names of all modules that can be found in the given + package, recursively. + + Example: + _iter_all_modules(_pytest) -> + ['_pytest.assertion.newinterpret', + '_pytest.capture', + '_pytest.core', + ... + ] + """ + if type(package) is not str: + path, prefix = package.__path__[0], package.__name__ + '.' + else: + path = package + for _, name, is_package in pkgutil.iter_modules([path]): + if is_package: + for m in _iter_all_modules(os.path.join(path, name), prefix=name + '.'): + yield prefix + m + else: + yield prefix + name diff -r 8b0cb61eb871dcd416520201b83b639b5bf718e7 -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 pytest.py --- a/pytest.py +++ b/pytest.py @@ -13,7 +13,6 @@ from _pytest.config import main, UsageError, _preloadplugins, cmdline from _pytest import __version__ -from _pytest import cx_freeze_support _preloadplugins() # to populate pytest.* namespace so help(pytest) works diff -r 8b0cb61eb871dcd416520201b83b639b5bf718e7 -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 testing/cx_freeze/runtests_setup.py --- a/testing/cx_freeze/runtests_setup.py +++ b/testing/cx_freeze/runtests_setup.py @@ -10,6 +10,6 @@ version="0.1", description="exemple of how embedding py.test into an executable using cx_freeze", executables=[Executable("runtests_script.py")], - options={"build_exe": {'includes': pytest.cx_freeze_support.includes()}}, + options={"build_exe": {'includes': pytest.freeze_includes()}}, ) diff -r 8b0cb61eb871dcd416520201b83b639b5bf718e7 -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 testing/test_genscript.py --- a/testing/test_genscript.py +++ b/testing/test_genscript.py @@ -36,3 +36,13 @@ result = standalone.run(anypython, testdir, p) assert result.ret != 0 + +def test_freeze_includes(): + """ + Smoke test for freeze_includes(), to ensure that it works across all + supported python versions. + """ + includes = pytest.freeze_includes() + assert len(includes) > 1 + assert '_pytest.genscript' in includes + https://bitbucket.org/hpk42/pytest/commits/b458501957a7/ Changeset: b458501957a7 Branch: cx_freeze-support User: nicoddemus Date: 2014-08-12 01:07:11 Summary: Merging with default Affected #: 49 files diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de .hgtags --- a/.hgtags +++ b/.hgtags @@ -69,3 +69,4 @@ 60725b17a9d1af4100abb8be3f9f4ddf6262bf34 2.6.0 60725b17a9d1af4100abb8be3f9f4ddf6262bf34 2.6.0 88af949b9611494e2c65d528f9e565b00fb7e8ca 2.6.0 +a4f9639702baa3eb4f3b16e162f74f7b69f3f9e1 2.6.1 diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,21 @@ NEXT +----------- + +- fixed issue561: adapt autouse fixture example for python3. + +2.6.1 ----------------------------------- +- No longer show line numbers in the --verbose output, the output is now + purely the nodeid. The line number is still shown in failure reports. + Thanks Floris Bruynooghe. + +- fix issue437 where assertion rewriting could cause pytest-xdist slaves + to collect different tests. Thanks Bruno Oliveira. + +- fix issue555: add "errors" attribute to capture-streams to satisfy + some distutils and possibly other code accessing sys.stdout.errors. + - fix issue547 capsys/capfd also work when output capturing ("-s") is disabled. - address issue170: allow pytest.mark.xfail(...) to specify expected exceptions via @@ -17,6 +32,9 @@ - fix issue544 by only removing "@NUM" at the end of "::" separated parts and if the part has an ".py" extension +- don't use py.std import helper, rather import things directly. + Thanks Bruno Oliveira. + 2.6 ----------------------------------- diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.6.1.dev1' +__version__ = '2.6.2.dev1' diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de _pytest/assertion/oldinterpret.py --- a/_pytest/assertion/oldinterpret.py +++ b/_pytest/assertion/oldinterpret.py @@ -1,3 +1,5 @@ +import traceback +import types import py import sys, inspect from compiler import parse, ast, pycodegen @@ -477,7 +479,7 @@ def interpret(source, frame, should_fail=False): module = Interpretable(parse(source, 'exec').node) #print "got module", module - if isinstance(frame, py.std.types.FrameType): + if isinstance(frame, types.FrameType): frame = py.code.Frame(frame) try: module.run(frame) @@ -487,7 +489,6 @@ except passthroughex: raise except: - import traceback traceback.print_exc() if should_fail: return ("(assertion failed, but when it was re-run for " diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de _pytest/assertion/rewrite.py --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -131,7 +131,7 @@ pyc = os.path.join(cache_dir, cache_name) # Notice that even if we're in a read-only directory, I'm going # to check for a cached pyc. This may not be optimal... - co = _read_pyc(fn_pypath, pyc) + co = _read_pyc(fn_pypath, pyc, state.trace) if co is None: state.trace("rewriting %r" % (fn,)) co = _rewrite_test(state, fn_pypath) @@ -289,7 +289,7 @@ if _write_pyc(state, co, fn, proc_pyc): os.rename(proc_pyc, pyc) -def _read_pyc(source, pyc): +def _read_pyc(source, pyc, trace=lambda x: None): """Possibly read a pytest pyc containing rewritten code. Return rewritten code if successful or None if not. @@ -298,23 +298,27 @@ fp = open(pyc, "rb") except IOError: return None - try: + with fp: try: mtime = int(source.mtime()) data = fp.read(8) - except EnvironmentError: + except EnvironmentError as e: + trace('_read_pyc(%s): EnvironmentError %s' % (source, e)) return None # Check for invalid or out of date pyc file. if (len(data) != 8 or data[:4] != imp.get_magic() or struct.unpack("", "PDB set_trace (IO-capturing turned off)") - py.std.pdb.Pdb().set_trace(frame) + pdb.Pdb().set_trace(frame) class PdbInvoke: @@ -74,7 +78,8 @@ def _postmortem_traceback(excinfo): # A doctest.UnexpectedException is not useful for post_mortem. # Use the underlying exception instead: - if isinstance(excinfo.value, py.std.doctest.UnexpectedException): + from doctest import UnexpectedException + if isinstance(excinfo.value, UnexpectedException): return excinfo.value.exc_info[2] else: return excinfo._excinfo[2] @@ -88,7 +93,6 @@ def post_mortem(t): - pdb = py.std.pdb class Pdb(pdb.Pdb): def get_stack(self, f, t): stack, i = pdb.Pdb.get_stack(self, f, t) diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de _pytest/pytester.py --- a/_pytest/pytester.py +++ b/_pytest/pytester.py @@ -1,15 +1,21 @@ """ (disabled by default) support for testing pytest and pytest plugins. """ - -import py, pytest -import sys, os +import inspect +import sys +import os import codecs import re import time +import platform from fnmatch import fnmatch -from _pytest.main import Session, EXIT_OK +import subprocess + +import py +import pytest from py.builtin import print_ from _pytest.core import HookRelay +from _pytest.main import Session, EXIT_OK + def get_public_names(l): """Only return names from iterator l without a leading underscore.""" @@ -87,10 +93,10 @@ def _makecallparser(self, method): name = method.__name__ - args, varargs, varkw, default = py.std.inspect.getargspec(method) + args, varargs, varkw, default = inspect.getargspec(method) if not args or args[0] != "self": args.insert(0, 'self') - fspec = py.std.inspect.formatargspec(args, varargs, varkw, default) + fspec = inspect.formatargspec(args, varargs, varkw, default) # we use exec because we want to have early type # errors on wrong input arguments, using # *args/**kwargs delays this and gives errors @@ -122,7 +128,7 @@ __tracebackhide__ = True i = 0 entries = list(entries) - backlocals = py.std.sys._getframe(1).f_locals + backlocals = sys._getframe(1).f_locals while entries: name, check = entries.pop(0) for ind, call in enumerate(self.calls[i:]): @@ -210,7 +216,7 @@ def finalize(self): for p in self._syspathremove: - py.std.sys.path.remove(p) + sys.path.remove(p) if hasattr(self, '_olddir'): self._olddir.chdir() # delete modules that have been loaded from tmpdir @@ -283,7 +289,7 @@ def syspathinsert(self, path=None): if path is None: path = self.tmpdir - py.std.sys.path.insert(0, str(path)) + sys.path.insert(0, str(path)) self._syspathremove.append(str(path)) def mkdir(self, name): @@ -426,9 +432,8 @@ env['PYTHONPATH'] = os.pathsep.join(filter(None, [ str(os.getcwd()), env.get('PYTHONPATH', '')])) kw['env'] = env - #print "env", env - return py.std.subprocess.Popen(cmdargs, - stdout=stdout, stderr=stderr, **kw) + return subprocess.Popen(cmdargs, + stdout=stdout, stderr=stderr, **kw) def run(self, *cmdargs): return self._run(*cmdargs) @@ -474,9 +479,9 @@ def _getpybinargs(self, scriptname): if not self.request.config.getvalue("notoolsonpath"): # XXX we rely on script referring to the correct environment - # we cannot use "(py.std.sys.executable,script)" + # we cannot use "(sys.executable,script)" # because on windows the script is e.g. a py.test.exe - return (py.std.sys.executable, _pytest_fullpath,) # noqa + return (sys.executable, _pytest_fullpath,) # noqa else: pytest.skip("cannot run %r with --no-tools-on-path" % scriptname) @@ -496,7 +501,7 @@ def runpython_c(self, command): command = self._getsysprepend() + command - return self.run(py.std.sys.executable, "-c", command) + return self.run(sys.executable, "-c", command) def runpytest(self, *args): p = py.path.local.make_numbered_dir(prefix="runpytest-", @@ -523,7 +528,7 @@ def spawn(self, cmd, expect_timeout=10.0): pexpect = pytest.importorskip("pexpect", "3.0") - if hasattr(sys, 'pypy_version_info') and '64' in py.std.platform.machine(): + if hasattr(sys, 'pypy_version_info') and '64' in platform.machine(): pytest.skip("pypy-64 bit not supported") if sys.platform == "darwin": pytest.xfail("pexpect does not work reliably on darwin?!") @@ -670,7 +675,7 @@ def fnmatch_lines(self, lines2): def show(arg1, arg2): - py.builtin.print_(arg1, arg2, file=py.std.sys.stderr) + py.builtin.print_(arg1, arg2, file=sys.stderr) lines2 = self._getlines(lines2) lines1 = self.lines[:] nextline = None diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de _pytest/recwarn.py --- a/_pytest/recwarn.py +++ b/_pytest/recwarn.py @@ -1,7 +1,8 @@ """ recording warnings during test function execution. """ -import py import sys +import warnings + def pytest_funcarg__recwarn(request): """Return a WarningsRecorder instance that provides these methods: @@ -13,7 +14,6 @@ on warning categories. """ if sys.version_info >= (2,7): - import warnings oldfilters = warnings.filters[:] warnings.simplefilter('default') def reset_filters(): @@ -30,26 +30,24 @@ """ assert that calling ``func(*args, **kwargs)`` triggers a DeprecationWarning. """ - warningmodule = py.std.warnings l = [] - oldwarn_explicit = getattr(warningmodule, 'warn_explicit') + oldwarn_explicit = getattr(warnings, 'warn_explicit') def warn_explicit(*args, **kwargs): l.append(args) oldwarn_explicit(*args, **kwargs) - oldwarn = getattr(warningmodule, 'warn') + oldwarn = getattr(warnings, 'warn') def warn(*args, **kwargs): l.append(args) oldwarn(*args, **kwargs) - warningmodule.warn_explicit = warn_explicit - warningmodule.warn = warn + warnings.warn_explicit = warn_explicit + warnings.warn = warn try: ret = func(*args, **kwargs) finally: - warningmodule.warn_explicit = warn_explicit - warningmodule.warn = warn + warnings.warn_explicit = warn_explicit + warnings.warn = warn if not l: - #print warningmodule __tracebackhide__ = True raise AssertionError("%r did not produce DeprecationWarning" %(func,)) return ret @@ -65,7 +63,6 @@ class WarningsRecorder: def __init__(self): - warningmodule = py.std.warnings self.list = [] def showwarning(message, category, filename, lineno, line=0): self.list.append(RecordedWarning( @@ -76,8 +73,8 @@ except TypeError: # < python2.6 self.old_showwarning(message, category, filename, lineno) - self.old_showwarning = warningmodule.showwarning - warningmodule.showwarning = showwarning + self.old_showwarning = warnings.showwarning + warnings.showwarning = showwarning def pop(self, cls=Warning): """ pop the first recorded warning, raise exception if not exists.""" @@ -88,7 +85,6 @@ assert 0, "%r not found in %r" %(cls, self.list) #def resetregistry(self): - # import warnings # warnings.onceregistry.clear() # warnings.__warningregistry__.clear() @@ -96,4 +92,4 @@ self.list[:] = [] def finalize(self): - py.std.warnings.showwarning = self.old_showwarning + warnings.showwarning = self.old_showwarning diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de _pytest/runner.py --- a/_pytest/runner.py +++ b/_pytest/runner.py @@ -1,9 +1,10 @@ """ basic collect and runtest protocol implementations """ +import bdb +import sys +from time import time import py import pytest -import sys -from time import time from py._code.code import TerminalRepr def pytest_namespace(): @@ -118,7 +119,7 @@ return call.excinfo and not ( hasattr(report, "wasxfail") or call.excinfo.errisinstance(skip.Exception) or - call.excinfo.errisinstance(py.std.bdb.BdbQuit)) + call.excinfo.errisinstance(bdb.BdbQuit)) def call_runtest_hook(item, when, **kwds): hookname = "pytest_runtest_" + when diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de _pytest/skipping.py --- a/_pytest/skipping.py +++ b/_pytest/skipping.py @@ -1,7 +1,10 @@ """ support for skip/xfail functions and markers. """ +import os +import sys +import traceback -import py, pytest -import sys +import py +import pytest def pytest_addoption(parser): group = parser.getgroup("general") @@ -79,7 +82,7 @@ msg = [" " * (self.exc[1].offset + 4) + "^",] msg.append("SyntaxError: invalid syntax") else: - msg = py.std.traceback.format_exception_only(*self.exc[:2]) + msg = traceback.format_exception_only(*self.exc[:2]) pytest.fail("Error evaluating %r expression\n" " %s\n" "%s" @@ -87,7 +90,7 @@ pytrace=False) def _getglobals(self): - d = {'os': py.std.os, 'sys': py.std.sys, 'config': self.item.config} + d = {'os': os, 'sys': sys, 'config': self.item.config} func = self.item.obj try: d.update(func.__globals__) diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de _pytest/terminal.py --- a/_pytest/terminal.py +++ b/_pytest/terminal.py @@ -5,6 +5,8 @@ import pytest import py import sys +import time + def pytest_addoption(parser): group = parser.getgroup("terminal reporting", "reporting", after="general") @@ -49,7 +51,7 @@ optvalue = config.option.report if optvalue: py.builtin.print_("DEPRECATED: use -r instead of --report option.", - file=py.std.sys.stderr) + file=sys.stderr) if optvalue: for setting in optvalue.split(","): setting = setting.strip() @@ -95,7 +97,7 @@ self.stats = {} self.startdir = self.curdir = py.path.local() if file is None: - file = py.std.sys.stdout + file = sys.stdout self._tw = self.writer = py.io.TerminalWriter(file) if self.config.option.color == 'yes': self._tw.hasmarkup = True @@ -265,7 +267,7 @@ @pytest.mark.trylast def pytest_sessionstart(self, session): - self._sessionstarttime = py.std.time.time() + self._sessionstarttime = time.time() if not self.showheader: return self.write_sep("=", "test session starts", bold=True) @@ -380,9 +382,6 @@ fspath = "%s <- %s" % (collect_fspath, fspath) if fspath: line = str(fspath) - if lineno is not None: - lineno += 1 - line += "@" + str(lineno) if domain: split = str(domain).split('[') split[0] = split[0].replace('.', '::') # don't replace '.' in params @@ -469,7 +468,7 @@ self._tw.line(content) def summary_stats(self): - session_duration = py.std.time.time() - self._sessionstarttime + session_duration = time.time() - self._sessionstarttime keys = ("failed passed skipped deselected " "xfailed xpassed warnings").split() diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de _pytest/tmpdir.py --- a/_pytest/tmpdir.py +++ b/_pytest/tmpdir.py @@ -1,7 +1,11 @@ """ support for providing temporary directories to test functions. """ -import pytest, py +import re + +import pytest +import py from _pytest.monkeypatch import monkeypatch + class TempdirHandler: def __init__(self, config): self.config = config @@ -63,7 +67,7 @@ path object. """ name = request.node.name - name = py.std.re.sub("[\W]", "_", name) + name = re.sub("[\W]", "_", name) MAXVAL = 30 if len(name) > MAXVAL: name = name[:MAXVAL] diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de _pytest/unittest.py --- a/_pytest/unittest.py +++ b/_pytest/unittest.py @@ -1,27 +1,25 @@ """ discovery and running of std-library "unittest" style tests. """ -import pytest, py +from __future__ import absolute_import +import traceback import sys +import pytest +import py + + # for transfering markers from _pytest.python import transfer_markers -def is_unittest(obj): - """Is obj a subclass of unittest.TestCase?""" - unittest = sys.modules.get('unittest') - if unittest is None: - return # nobody can have derived unittest.TestCase +def pytest_pycollect_makeitem(collector, name, obj): + # has unittest been imported and is obj a subclass of its TestCase? try: - return issubclass(obj, unittest.TestCase) - except KeyboardInterrupt: - raise - except: - return False - - -def pytest_pycollect_makeitem(collector, name, obj): - if is_unittest(obj): - return UnitTestCase(name, parent=collector) + if not issubclass(obj, sys.modules["unittest"].TestCase): + return + except Exception: + return + # yes, so let's collect it + return UnitTestCase(name, parent=collector) class UnitTestCase(pytest.Class): @@ -41,11 +39,12 @@ super(UnitTestCase, self).setup() def collect(self): + from unittest import TestLoader cls = self.obj if not getattr(cls, "__test__", True): return self.session._fixturemanager.parsefactories(self, unittest=True) - loader = py.std.unittest.TestLoader() + loader = TestLoader() module = self.getparent(pytest.Module).obj foundsomething = False for name in loader.getTestCaseNames(self.obj): @@ -90,7 +89,7 @@ except TypeError: try: try: - l = py.std.traceback.format_exception(*rawexcinfo) + l = traceback.format_exception(*rawexcinfo) l.insert(0, "NOTE: Incompatible Exception Representation, " "displaying natively:\n\n") pytest.fail("".join(l), pytrace=False) diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de doc/en/announce/release-2.6.1.txt --- /dev/null +++ b/doc/en/announce/release-2.6.1.txt @@ -0,0 +1,59 @@ +pytest-2.6.1: fixes and new xfail feature +=========================================================================== + +pytest is a mature Python testing tool with more than a 1100 tests +against itself, passing on many different interpreters and platforms. +The 2.6.1 release is drop-in compatible to 2.5.2 and actually fixes some +regressions introduced with 2.6.0. It also brings a little feature +to the xfail marker which now recognizes expected exceptions, +see the CHANGELOG below. + +See docs at: + + http://pytest.org + +As usual, you can upgrade from pypi via:: + + pip install -U pytest + +Thanks to all who contributed, among them: + + Floris Bruynooghe + Bruno Oliveira + Nicolas Delaby + +have fun, +holger krekel + +Changes 2.6.1 +================= + +- No longer show line numbers in the --verbose output, the output is now + purely the nodeid. The line number is still shown in failure reports. + Thanks Floris Bruynooghe. + +- fix issue437 where assertion rewriting could cause pytest-xdist slaves + to collect different tests. Thanks Bruno Oliveira. + +- fix issue555: add "errors" attribute to capture-streams to satisfy + some distutils and possibly other code accessing sys.stdout.errors. + +- fix issue547 capsys/capfd also work when output capturing ("-s") is disabled. + +- address issue170: allow pytest.mark.xfail(...) to specify expected exceptions via + an optional "raises=EXC" argument where EXC can be a single exception + or a tuple of exception classes. Thanks David Mohr for the complete + PR. + +- fix integration of pytest with unittest.mock.patch decorator when + it uses the "new" argument. Thanks Nicolas Delaby for test and PR. + +- fix issue with detecting conftest files if the arguments contain + "::" node id specifications (copy pasted from "-v" output) + +- fix issue544 by only removing "@NUM" at the end of "::" separated parts + and if the part has an ".py" extension + +- don't use py.std import helper, rather import things directly. + Thanks Bruno Oliveira. + diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de doc/en/assert.txt --- a/doc/en/assert.txt +++ b/doc/en/assert.txt @@ -26,7 +26,7 @@ $ py.test test_assert1.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 collected 1 items test_assert1.py F @@ -132,7 +132,7 @@ $ py.test test_assert2.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 collected 1 items test_assert2.py F diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de doc/en/attic_fixtures.txt --- a/doc/en/attic_fixtures.txt +++ /dev/null @@ -1,188 +0,0 @@ - -**Test classes, modules or whole projects can make use of -one or more fixtures**. All required fixture functions will execute -before a test from the specifying context executes. As You can use this -to make tests operate from a pre-initialized directory or with -certain environment variables or with pre-configured global application -settings. - -For example, the Django_ project requires database -initialization to be able to import from and use its model objects. -For that, the `pytest-django`_ plugin provides fixtures which your -project can then easily depend or extend on, simply by referencing the -name of the particular fixture. - -Fixture functions have limited visilibity which depends on where they -are defined. If they are defined on a test class, only its test methods -may use it. A fixture defined in a module can only be used -from that test module. A fixture defined in a conftest.py file -can only be used by the tests below the directory of that file. -Lastly, plugins can define fixtures which are available across all -projects. - - - - - -Python, Java and many other languages support a so called xUnit_ style -for providing a fixed state, `test fixtures`_, for running tests. It -typically involves calling a autouse function ahead and a teardown -function after test execute. In 2005 pytest introduced a scope-specific -model of automatically detecting and calling autouse and teardown -functions on a per-module, class or function basis. The Python unittest -package and nose have subsequently incorporated them. This model -remains supported by pytest as :ref:`classic xunit`. - -One property of xunit fixture functions is that they work implicitely -by preparing global state or setting attributes on TestCase objects. -By contrast, pytest provides :ref:`funcargs` which allow to -dependency-inject application test state into test functions or -methods as function arguments. If your application is sufficiently modular -or if you are creating a new project, we recommend you now rather head over to -:ref:`funcargs` instead because many pytest users agree that using this -paradigm leads to better application and test organisation. - -However, not all programs and frameworks work and can be tested in -a fully modular way. They rather require preparation of global state -like database autouse on which further fixtures like preparing application -specific tables or wrapping tests in transactions can take place. For those -needs, pytest-2.3 now supports new **fixture functions** which come with -a ton of improvements over classic xunit fixture writing. Fixture functions: - -- allow to separate different autouse concerns into multiple modular functions - -- can receive and fully interoperate with :ref:`funcargs `, - -- are called multiple times if its funcargs are parametrized, - -- don't need to be defined directly in your test classes or modules, - they can also be defined in a plugin or :ref:`conftest.py ` files and get called - -- are called on a per-session, per-module, per-class or per-function basis - by means of a simple "scope" declaration. - -- can access the :ref:`request ` object which allows to - introspect and interact with the (scoped) testcontext. - -- can add cleanup functions which will be invoked when the last test - of the fixture test context has finished executing. - -All of these features are now demonstrated by little examples. - - - - - -test modules accessing a global resource -------------------------------------------------------- - -.. note:: - - Relying on `global state is considered bad programming practise `_ but when you work with an application - that relies on it you often have no choice. - -If you want test modules to access a global resource, -you can stick the resource to the module globals in -a per-module autouse function. We use a :ref:`resource factory -<@pytest.fixture>` to create our global resource:: - - # content of conftest.py - import pytest - - class GlobalResource: - def __init__(self): - pass - - @pytest.fixture(scope="session") - def globresource(): - return GlobalResource() - - @pytest.fixture(scope="module") - def setresource(request, globresource): - request.module.globresource = globresource - -Now any test module can access ``globresource`` as a module global:: - - # content of test_glob.py - - def test_1(): - print ("test_1 %s" % globresource) - def test_2(): - print ("test_2 %s" % globresource) - -Let's run this module without output-capturing:: - - $ py.test -qs test_glob.py - FF - ================================= FAILURES ================================= - __________________________________ test_1 __________________________________ - - def test_1(): - > print ("test_1 %s" % globresource) - E NameError: global name 'globresource' is not defined - - test_glob.py:3: NameError - __________________________________ test_2 __________________________________ - - def test_2(): - > print ("test_2 %s" % globresource) - E NameError: global name 'globresource' is not defined - - test_glob.py:5: NameError - 2 failed in 0.01 seconds - -The two tests see the same global ``globresource`` object. - -Parametrizing the global resource -+++++++++++++++++++++++++++++++++++++++++++++++++ - -We extend the previous example and add parametrization to the globresource -factory and also add a finalizer:: - - # content of conftest.py - - import pytest - - class GlobalResource: - def __init__(self, param): - self.param = param - - @pytest.fixture(scope="session", params=[1,2]) - def globresource(request): - g = GlobalResource(request.param) - def fin(): - print "finalizing", g - request.addfinalizer(fin) - return g - - @pytest.fixture(scope="module") - def setresource(request, globresource): - request.module.globresource = globresource - -And then re-run our test module:: - - $ py.test -qs test_glob.py - FF - ================================= FAILURES ================================= - __________________________________ test_1 __________________________________ - - def test_1(): - > print ("test_1 %s" % globresource) - E NameError: global name 'globresource' is not defined - - test_glob.py:3: NameError - __________________________________ test_2 __________________________________ - - def test_2(): - > print ("test_2 %s" % globresource) - E NameError: global name 'globresource' is not defined - - test_glob.py:5: NameError - 2 failed in 0.01 seconds - -We are now running the two tests twice with two different global resource -instances. Note that the tests are ordered such that only -one instance is active at any given time: the finalizer of -the first globresource instance is called before the second -instance is created and sent to the autouse functions. - diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de doc/en/capture.txt --- a/doc/en/capture.txt +++ b/doc/en/capture.txt @@ -64,7 +64,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 collected 2 items test_module.py .F @@ -78,7 +78,7 @@ test_module.py:9: AssertionError -------------------------- Captured stdout setup --------------------------- - setting up + setting up ==================== 1 failed, 1 passed in 0.01 seconds ==================== Accessing captured output from a test function diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de doc/en/conf.py --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -18,7 +18,7 @@ # The full version, including alpha/beta/rc tags. # The short X.Y version. version = "2.6" -release = "2.6.0" +release = "2.6.1" import sys, os @@ -225,7 +225,7 @@ # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +latex_logo = 'img/pytest1.png' # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de doc/en/doctest.txt --- a/doc/en/doctest.txt +++ b/doc/en/doctest.txt @@ -44,12 +44,12 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 collected 1 items mymodule.py . - ========================= 1 passed in 0.04 seconds ========================= + ========================= 1 passed in 0.06 seconds ========================= It is possible to use fixtures using the ``getfixture`` helper:: diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de doc/en/example/markers.txt --- a/doc/en/example/markers.txt +++ b/doc/en/example/markers.txt @@ -31,10 +31,10 @@ $ py.test -v -m webtest =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 4 items - test_server.py at 3::test_send_http PASSED + test_server.py::test_send_http PASSED =================== 3 tests deselected by "-m 'webtest'" =================== ================== 1 passed, 3 deselected in 0.01 seconds ================== @@ -43,12 +43,12 @@ $ py.test -v -m "not webtest" =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 4 items - test_server.py at 6::test_something_quick PASSED - test_server.py at 8::test_another PASSED - test_server.py at 11::TestClass::test_method PASSED + test_server.py::test_something_quick PASSED + test_server.py::test_another PASSED + test_server.py::TestClass::test_method PASSED ================= 1 tests deselected by "-m 'not webtest'" ================= ================== 3 passed, 1 deselected in 0.01 seconds ================== @@ -62,10 +62,10 @@ $ py.test -v test_server.py::TestClass::test_method =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 5 items - test_server.py at 11::TestClass::test_method PASSED + test_server.py::TestClass::test_method PASSED ========================= 1 passed in 0.01 seconds ========================= @@ -73,10 +73,10 @@ $ py.test -v test_server.py::TestClass =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 4 items - test_server.py at 11::TestClass::test_method PASSED + test_server.py::TestClass::test_method PASSED ========================= 1 passed in 0.01 seconds ========================= @@ -84,11 +84,11 @@ $ py.test -v test_server.py::TestClass test_server.py::test_send_http =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 8 items - test_server.py at 11::TestClass::test_method PASSED - test_server.py at 3::test_send_http PASSED + test_server.py::TestClass::test_method PASSED + test_server.py::test_send_http PASSED ========================= 2 passed in 0.01 seconds ========================= @@ -120,10 +120,10 @@ $ py.test -v -k http # running with the above defined example module =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 4 items - test_server.py at 3::test_send_http PASSED + test_server.py::test_send_http PASSED ====================== 3 tests deselected by '-khttp' ====================== ================== 1 passed, 3 deselected in 0.01 seconds ================== @@ -132,12 +132,12 @@ $ py.test -k "not send_http" -v =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 4 items - test_server.py at 6::test_something_quick PASSED - test_server.py at 8::test_another PASSED - test_server.py at 11::TestClass::test_method PASSED + test_server.py::test_something_quick PASSED + test_server.py::test_another PASSED + test_server.py::TestClass::test_method PASSED ================= 1 tests deselected by '-knot send_http' ================== ================== 3 passed, 1 deselected in 0.01 seconds ================== @@ -146,11 +146,11 @@ $ py.test -k "http or quick" -v =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 4 items - test_server.py at 3::test_send_http PASSED - test_server.py at 6::test_something_quick PASSED + test_server.py::test_send_http PASSED + test_server.py::test_something_quick PASSED ================= 2 tests deselected by '-khttp or quick' ================== ================== 2 passed, 2 deselected in 0.01 seconds ================== @@ -187,7 +187,7 @@ @pytest.mark.skipif(condition): skip the given test function if eval(condition) results in a True value. Evaluation happens within the module global context. Example: skipif('sys.platform == "win32"') skips the test if we are on the win32 platform. see http://pytest.org/latest/skipping.html - @pytest.mark.xfail(condition, reason=None, run=True): mark the the test function as an expected failure if eval(condition) has a True value. Optionally specify a reason for better reporting and run=False if you don't even want to execute the test function. See http://pytest.org/latest/skipping.html + @pytest.mark.xfail(condition, reason=None, run=True, raises=None): mark the the test function as an expected failure if eval(condition) has a True value. Optionally specify a reason for better reporting and run=False if you don't even want to execute the test function. If only specific exception(s) are expected, you can list them in raises, and if the test fails in other ways, it will be reported as a true failure. See http://pytest.org/latest/skipping.html @pytest.mark.parametrize(argnames, argvalues): call a test function multiple times passing in different arguments in turn. argvalues generally needs to be a list of values if argnames specifies only one name or a list of tuples of values if argnames specifies multiple names. Example: @parametrize('arg1', [1,2]) would lead to two calls of the decorated test function, one with arg1=1 and another with arg1=2.see http://pytest.org/latest/parametrize.html for more info and examples. @@ -326,7 +326,7 @@ $ py.test -E stage2 =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 collected 1 items test_someenv.py s @@ -337,7 +337,7 @@ $ py.test -E stage1 =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 collected 1 items test_someenv.py . @@ -351,7 +351,7 @@ @pytest.mark.skipif(condition): skip the given test function if eval(condition) results in a True value. Evaluation happens within the module global context. Example: skipif('sys.platform == "win32"') skips the test if we are on the win32 platform. see http://pytest.org/latest/skipping.html - @pytest.mark.xfail(condition, reason=None, run=True): mark the the test function as an expected failure if eval(condition) has a True value. Optionally specify a reason for better reporting and run=False if you don't even want to execute the test function. See http://pytest.org/latest/skipping.html + @pytest.mark.xfail(condition, reason=None, run=True, raises=None): mark the the test function as an expected failure if eval(condition) has a True value. Optionally specify a reason for better reporting and run=False if you don't even want to execute the test function. If only specific exception(s) are expected, you can list them in raises, and if the test fails in other ways, it will be reported as a true failure. See http://pytest.org/latest/skipping.html @pytest.mark.parametrize(argnames, argvalues): call a test function multiple times passing in different arguments in turn. argvalues generally needs to be a list of values if argnames specifies only one name or a list of tuples of values if argnames specifies multiple names. Example: @parametrize('arg1', [1,2]) would lead to two calls of the decorated test function, one with arg1=1 and another with arg1=2.see http://pytest.org/latest/parametrize.html for more info and examples. @@ -455,26 +455,26 @@ $ py.test -rs # this option reports skip reasons =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 collected 4 items - test_plat.py s.s. + test_plat.py sss. ========================= short test summary info ========================== - SKIP [2] /tmp/doc-exec-142/conftest.py:12: cannot run on platform linux2 + SKIP [3] /tmp/doc-exec-238/conftest.py:12: cannot run on platform linux - =================== 2 passed, 2 skipped in 0.01 seconds ==================== + =================== 1 passed, 3 skipped in 0.01 seconds ==================== Note that if you specify a platform via the marker-command line option like this:: $ py.test -m linux2 =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 collected 4 items - test_plat.py . + test_plat.py s =================== 3 tests deselected by "-m 'linux2'" ==================== - ================== 1 passed, 3 deselected in 0.01 seconds ================== + ================= 1 skipped, 3 deselected in 0.01 seconds ================== then the unmarked-tests will not be run. It is thus a way to restrict the run to the specific tests. @@ -519,7 +519,7 @@ $ py.test -m interface --tb=short =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 collected 4 items test_module.py FF @@ -540,7 +540,7 @@ $ py.test -m "interface or event" --tb=short =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 collected 4 items test_module.py FFF @@ -559,4 +559,4 @@ assert 0 E assert 0 ============= 1 tests deselected by "-m 'interface or event'" ============== - ================== 3 failed, 1 deselected in 0.02 seconds ================== + ================== 3 failed, 1 deselected in 0.01 seconds ================== diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de doc/en/example/nonpython.txt --- a/doc/en/example/nonpython.txt +++ b/doc/en/example/nonpython.txt @@ -27,7 +27,7 @@ nonpython $ py.test test_simple.yml =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 collected 2 items test_simple.yml .F @@ -56,11 +56,11 @@ nonpython $ py.test -v =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 2 items - test_simple.yml at 1::usecase: ok PASSED - test_simple.yml at 1::usecase: hello FAILED + test_simple.yml::usecase: ok PASSED + test_simple.yml::usecase: hello FAILED ================================= FAILURES ================================= ______________________________ usecase: hello ______________________________ @@ -74,7 +74,7 @@ nonpython $ py.test --collect-only =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 collected 2 items diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de doc/en/example/parametrize.txt --- a/doc/en/example/parametrize.txt +++ b/doc/en/example/parametrize.txt @@ -106,7 +106,7 @@ $ py.test test_scenarios.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 collected 4 items test_scenarios.py .... @@ -118,7 +118,7 @@ $ py.test --collect-only test_scenarios.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 collected 4 items @@ -182,7 +182,7 @@ $ py.test test_backends.py --collect-only =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 collected 2 items @@ -197,7 +197,7 @@ ================================= FAILURES ================================= _________________________ test_db_initialized[d2] __________________________ - db = + db = def test_db_initialized(db): # a dummy test @@ -251,9 +251,9 @@ $ py.test -q F.. ================================= FAILURES ================================= - ________________________ TestClass.test_equals[1-2] ________________________ + ________________________ TestClass.test_equals[2-1] ________________________ - self = , a = 1, b = 2 + self = , a = 1, b = 2 def test_equals(self, a, b): > assert a == b @@ -281,10 +281,10 @@ . $ py.test -rs -q multipython.py ssssssssssssssssssssssssssssssssssss......sssssssss......ssssssssssssssssss ========================= short test summary info ========================== + SKIP [21] /home/hpk/p/pytest/doc/en/example/multipython.py:22: 'python2.5' not found + SKIP [21] /home/hpk/p/pytest/doc/en/example/multipython.py:22: 'python2.8' not found SKIP [21] /home/hpk/p/pytest/doc/en/example/multipython.py:22: 'python2.4' not found - SKIP [21] /home/hpk/p/pytest/doc/en/example/multipython.py:22: 'python2.8' not found - SKIP [21] /home/hpk/p/pytest/doc/en/example/multipython.py:22: 'python2.5' not found - 12 passed, 63 skipped in 0.66 seconds + 12 passed, 63 skipped in 0.65 seconds Indirect parametrization of optional implementations/imports -------------------------------------------------------------------- @@ -331,12 +331,12 @@ $ py.test -rs test_module.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 collected 2 items test_module.py .s ========================= short test summary info ========================== - SKIP [1] /tmp/doc-exec-144/conftest.py:10: could not import 'opt2' + SKIP [1] /tmp/doc-exec-240/conftest.py:10: could not import 'opt2' =================== 1 passed, 1 skipped in 0.01 seconds ==================== diff -r 4901560bef6150e161b31ac28ad0eb47c984ddf6 -r b458501957a79e8eada6b901e1e245fe664dc6de doc/en/example/pythoncollection.txt --- a/doc/en/example/pythoncollection.txt +++ b/doc/en/example/pythoncollection.txt @@ -43,7 +43,7 @@ $ py.test --collect-only =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 collected 2 items @@ -88,7 +88,7 @@ . $ py.test --collect-only pythoncollection.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 collected 3 items @@ -141,10 +141,8 @@ $ py.test --collect-only =========================== test session starts ============================ - platform linux2 -- Python 2.7.6 -- py-1.4.22 -- pytest-2.6.0 - collected 1 items - - + platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + collected 0 items ============================= in 0.01 seconds ============================= This diff is so big that we needed to truncate the remainder. https://bitbucket.org/hpk42/pytest/commits/1853e10fe16c/ Changeset: 1853e10fe16c Branch: cx_freeze-support User: nicoddemus Date: 2014-08-12 01:20:41 Summary: standard lib modules no longer required in freeze_includes() and updated docs Affected #: 2 files diff -r b458501957a79e8eada6b901e1e245fe664dc6de -r 1853e10fe16cdf967d228d2b3d1317eb97f958e5 _pytest/genscript.py --- a/_pytest/genscript.py +++ b/_pytest/genscript.py @@ -99,16 +99,6 @@ """ result = list(_iter_all_modules(py)) result += list(_iter_all_modules(_pytest)) - - # builtin files imported by pytest using py.std implicit mechanism; - # should be removed if https://bitbucket.org/hpk42/pytest/pull-request/185 - # gets merged - result += [ - 'argparse', - 'shlex', - 'warnings', - 'types', - ] return result diff -r b458501957a79e8eada6b901e1e245fe664dc6de -r 1853e10fe16cdf967d228d2b3d1317eb97f958e5 doc/en/example/simple.txt --- a/doc/en/example/simple.txt +++ b/doc/en/example/simple.txt @@ -684,7 +684,7 @@ Unfortunately ``cx_freeze`` can't discover them automatically because of ``pytest``'s use of dynamic module loading, so you -must declare them explicitly by using ``pytest.cx_freeze_support.includes()``:: +must declare them explicitly by using ``pytest.freeze_includes()``:: # contents of setup.py from cx_Freeze import setup, Executable @@ -695,7 +695,7 @@ executables=[Executable("app_main.py")], options={"build_exe": { - 'includes': pytest.cx_freeze_support.includes()} + 'includes': pytest.freeze_includes()} }, # ... other options ) @@ -718,5 +718,4 @@ This makes it convenient to execute your tests from within your frozen application, using standard ``py.test`` command-line options:: - $ ./app_main --pytest --verbose --tb=long --junit-xml=results.xml test-suite/ /bin/sh: 1: ./app_main: not found - /bin/sh: 1: ./app_main: not found + $ ./app_main --pytest --verbose --tb=long --junit-xml=results.xml test-suite/ https://bitbucket.org/hpk42/pytest/commits/a21b5e18c8c4/ Changeset: a21b5e18c8c4 Branch: cx_freeze-support User: nicoddemus Date: 2014-08-23 15:05:40 Summary: merging with default Affected #: 3 files diff -r 1853e10fe16cdf967d228d2b3d1317eb97f958e5 -r a21b5e18c8c42eec7c6c2ed797261c280399663d CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,12 @@ - fixed issue561: adapt autouse fixture example for python3. +- Fix example in monkeypatch documentation, thanks t-8ch. + +- Do not mark as universal wheel because Python 2.6 is different from + other builds due to the extra argparse dependency. Fixes issue566. + Thanks sontek. + 2.6.1 ----------------------------------- diff -r 1853e10fe16cdf967d228d2b3d1317eb97f958e5 -r a21b5e18c8c42eec7c6c2ed797261c280399663d doc/en/monkeypatch.txt --- a/doc/en/monkeypatch.txt +++ b/doc/en/monkeypatch.txt @@ -48,7 +48,7 @@ import pytest @pytest.fixture(autouse=True) def no_requests(monkeypatch): - monkeypatch.delattr("requests.session.Session.request") + monkeypatch.delattr("requests.sessions.Session.request") This autouse fixture will be executed for each test function and it will delete the method ``request.session.Session.request`` diff -r 1853e10fe16cdf967d228d2b3d1317eb97f958e5 -r a21b5e18c8c42eec7c6c2ed797261c280399663d setup.cfg --- a/setup.cfg +++ b/setup.cfg @@ -5,6 +5,3 @@ [upload_sphinx] upload-dir = doc/en/build/html - -[wheel] -universal = 1 \ No newline at end of file https://bitbucket.org/hpk42/pytest/commits/6a0c1f4622aa/ Changeset: 6a0c1f4622aa Branch: cx_freeze-support User: nicoddemus Date: 2014-08-23 15:10:32 Summary: Added changelog entry for freeze_includes() Affected #: 1 file diff -r a21b5e18c8c42eec7c6c2ed797261c280399663d -r 6a0c1f4622aa33becc1cdfd7c75b8c73ef962c95 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,10 @@ NEXT ----------- +- Added function pytest.freeze_includes(), which makes it easy to embed + pytest into executables using tools like cx_freeze. + See docs for examples and rationale. Thanks Bruno Oliveira. + - fixed issue561: adapt autouse fixture example for python3. - Fix example in monkeypatch documentation, thanks t-8ch. https://bitbucket.org/hpk42/pytest/commits/766d82ca8b71/ Changeset: 766d82ca8b71 User: flub Date: 2014-09-03 22:55:46 Summary: Merged in nocoddemus/pytest/cx_freeze-support (pull request #189) Affected #: 11 files diff -r ec7b4b6844ff41b31bea9fd772562117de699d1d -r 766d82ca8b71cd455e4d174f595bb71232143626 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,10 @@ NEXT ----------- +- Added function pytest.freeze_includes(), which makes it easy to embed + pytest into executables using tools like cx_freeze. + See docs for examples and rationale. Thanks Bruno Oliveira. + - Improve assertion rewriting cache invalidation precision. - fixed issue561: adapt autouse fixture example for python3. diff -r ec7b4b6844ff41b31bea9fd772562117de699d1d -r 766d82ca8b71cd455e4d174f595bb71232143626 _pytest/genscript.py --- a/_pytest/genscript.py +++ b/_pytest/genscript.py @@ -1,6 +1,12 @@ """ generate a single-file self-contained version of pytest """ +import os +import sys +import pkgutil + import py -import sys + +import _pytest + def find_toplevel(name): @@ -80,3 +86,42 @@ tw.line("generated pytest standalone script: %s" % genscript, bold=True) return 0 + + +def pytest_namespace(): + return {'freeze_includes': freeze_includes} + + +def freeze_includes(): + """ + Returns a list of module names used by py.test that should be + included by cx_freeze. + """ + result = list(_iter_all_modules(py)) + result += list(_iter_all_modules(_pytest)) + return result + + +def _iter_all_modules(package, prefix=''): + """ + Iterates over the names of all modules that can be found in the given + package, recursively. + + Example: + _iter_all_modules(_pytest) -> + ['_pytest.assertion.newinterpret', + '_pytest.capture', + '_pytest.core', + ... + ] + """ + if type(package) is not str: + path, prefix = package.__path__[0], package.__name__ + '.' + else: + path = package + for _, name, is_package in pkgutil.iter_modules([path]): + if is_package: + for m in _iter_all_modules(os.path.join(path, name), prefix=name + '.'): + yield prefix + m + else: + yield prefix + name diff -r ec7b4b6844ff41b31bea9fd772562117de699d1d -r 766d82ca8b71cd455e4d174f595bb71232143626 doc/en/example/simple.txt --- a/doc/en/example/simple.txt +++ b/doc/en/example/simple.txt @@ -682,33 +682,27 @@ send test files to users so they can run them in their machines, which can be invaluable to obtain more information about a hard to reproduce bug. -Unfortunately embedding the ``pytest`` runner into a frozen executable using -``cx_freeze`` is not as straightforward as one would like, -because ``pytest`` makes heavy use of dynamic module loading which -``cx_freeze`` can't resolve by itself. - -To solve this, you have to manually include ``pytest`` and ``py`` -modules by using the ``build_exe`` option in your ``setup.py`` script, like this:: +Unfortunately ``cx_freeze`` can't discover them +automatically because of ``pytest``'s use of dynamic module loading, so you +must declare them explicitly by using ``pytest.freeze_includes()``:: # contents of setup.py from cx_Freeze import setup, Executable + import pytest - includes = [ - '_pytest.doctest', - '_pytest.unittest', - # ... lots more - ] setup( - name="runtests", - options={"build_exe": {'includes': includes}}, + name="app_main", + executables=[Executable("app_main.py")], + options={"build_exe": + { + 'includes': pytest.freeze_includes()} + }, # ... other options ) -(For the complete list, check out the modules under ``_pytest`` in your -site-packages). - -With that, you can make your program check for a certain flag and pass control -over to ``pytest``:: +If you don't want to ship a different executable just in order to run your tests, +you can make your program check for a certain flag and pass control +over to ``pytest`` instead. For example:: # contents of app_main.py import sys @@ -722,7 +716,6 @@ ... This makes it convenient to execute your tests from within your frozen -application, using standard ``py.test`` command-line:: +application, using standard ``py.test`` command-line options:: - $ ./app_main --pytest --verbose --tb=long --junit-xml=results.xml test-suite/ /bin/sh: 1: ./app_main: not found - /bin/sh: 1: ./app_main: not found + $ ./app_main --pytest --verbose --tb=long --junit-xml=results.xml test-suite/ diff -r ec7b4b6844ff41b31bea9fd772562117de699d1d -r 766d82ca8b71cd455e4d174f595bb71232143626 testing/cx_freeze/runtests_script.py --- /dev/null +++ b/testing/cx_freeze/runtests_script.py @@ -0,0 +1,9 @@ +""" +This is the script that is actually frozen into an executable: simply executes +py.test main(). +""" + +if __name__ == '__main__': + import sys + import pytest + sys.exit(pytest.main()) \ No newline at end of file diff -r ec7b4b6844ff41b31bea9fd772562117de699d1d -r 766d82ca8b71cd455e4d174f595bb71232143626 testing/cx_freeze/runtests_setup.py --- /dev/null +++ b/testing/cx_freeze/runtests_setup.py @@ -0,0 +1,15 @@ +""" +Sample setup.py script that generates an executable with pytest runner embedded. +""" +if __name__ == '__main__': + from cx_Freeze import setup, Executable + import pytest + + setup( + name="runtests", + version="0.1", + description="exemple of how embedding py.test into an executable using cx_freeze", + executables=[Executable("runtests_script.py")], + options={"build_exe": {'includes': pytest.freeze_includes()}}, + ) + diff -r ec7b4b6844ff41b31bea9fd772562117de699d1d -r 766d82ca8b71cd455e4d174f595bb71232143626 testing/cx_freeze/tests/test_doctest.txt --- /dev/null +++ b/testing/cx_freeze/tests/test_doctest.txt @@ -0,0 +1,6 @@ + + +Testing doctest:: + + >>> 1 + 1 + 2 diff -r ec7b4b6844ff41b31bea9fd772562117de699d1d -r 766d82ca8b71cd455e4d174f595bb71232143626 testing/cx_freeze/tests/test_trivial.py --- /dev/null +++ b/testing/cx_freeze/tests/test_trivial.py @@ -0,0 +1,6 @@ + +def test_upper(): + assert 'foo'.upper() == 'FOO' + +def test_lower(): + assert 'FOO'.lower() == 'foo' \ No newline at end of file diff -r ec7b4b6844ff41b31bea9fd772562117de699d1d -r 766d82ca8b71cd455e4d174f595bb71232143626 testing/cx_freeze/tox_run.py --- /dev/null +++ b/testing/cx_freeze/tox_run.py @@ -0,0 +1,15 @@ +""" +Called by tox.ini: uses the generated executable to run the tests in ./tests/ +directory. + +.. note:: somehow calling "build/runtests_script" directly from tox doesn't + seem to work (at least on Windows). +""" +if __name__ == '__main__': + import os + import sys + + executable = os.path.join(os.getcwd(), 'build', 'runtests_script') + if sys.platform.startswith('win'): + executable += '.exe' + sys.exit(os.system('%s tests' % executable)) \ No newline at end of file diff -r ec7b4b6844ff41b31bea9fd772562117de699d1d -r 766d82ca8b71cd455e4d174f595bb71232143626 testing/test_genscript.py --- a/testing/test_genscript.py +++ b/testing/test_genscript.py @@ -36,3 +36,13 @@ result = standalone.run(anypython, testdir, p) assert result.ret != 0 + +def test_freeze_includes(): + """ + Smoke test for freeze_includes(), to ensure that it works across all + supported python versions. + """ + includes = pytest.freeze_includes() + assert len(includes) > 1 + assert '_pytest.genscript' in includes + diff -r ec7b4b6844ff41b31bea9fd772562117de699d1d -r 766d82ca8b71cd455e4d174f595bb71232143626 tox.ini --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] distshare={homedir}/.tox/distshare -envlist=flakes,py26,py27,py34,pypy,py27-pexpect,py33-pexpect,py27-nobyte,py32,py33,py27-xdist,py33-xdist,py27-trial,py33-trial,doctesting +envlist=flakes,py26,py27,py34,pypy,py27-pexpect,py33-pexpect,py27-nobyte,py32,py33,py27-xdist,py33-xdist,py27-trial,py33-trial,doctesting,py27-cxfreeze [testenv] changedir=testing @@ -123,6 +123,14 @@ {envpython} {envbindir}/py.test-jython \ -rfsxX --junitxml={envlogdir}/junit-{envname}2.xml [] +[testenv:py27-cxfreeze] +deps=cx_freeze +changedir=testing/cx_freeze +basepython=python2.7 +commands= + {envpython} runtests_setup.py build --build-exe build + {envpython} tox_run.py + [pytest] minversion=2.0 plugins=pytester https://bitbucket.org/hpk42/pytest/commits/77bbb3c8bcf4/ Changeset: 77bbb3c8bcf4 Branch: cx_freeze-support User: flub Date: 2014-09-03 22:56:59 Summary: Close cx_freeze-support branch Affected #: 0 files 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 issues-reply at bitbucket.org Thu Sep 4 13:23:26 2014 From: issues-reply at bitbucket.org (thiefmaster) Date: Thu, 04 Sep 2014 11:23:26 -0000 Subject: [Pytest-commit] Issue #580: OutcomeException should not be a subclass of Exception (hpk42/pytest) Message-ID: <20140904112326.22027.99279@app08.ash-private.bitbucket.org> New issue 580: OutcomeException should not be a subclass of Exception https://bitbucket.org/hpk42/pytest/issue/580/outcomeexception-should-not-be-a-subclass thiefmaster: Imagine this code: ``` def blackbox(callback, arg): # this is assumed to be application code try: callback(arg) except Exception: pass def test_callback(): def cb(x): if not x: import pytest pytest.fail('foo') blackbox(cb, True) blackbox(cb, False) ``` The testcase will pass since `except Exception` will catch the `Failed` raised by `pytest.fail`. However, I don't think there is *any* valid use-case for application code to prevent a testcase failure from propagating to the test runner. A more practical example where this is a major issue is monkeypatching a library function to fail when called. For example, one might want to monkeypatch `smtplib.SMTP.connect` to fail when code tries to send an email unexpectedly - but chances are good that the application is wrapping that code in a `try...except Exception` block to prevent an email sending failure from breaking things (e.g. because the email is not very important). So now the `pytest.fail` called in the monkeypatched method will never propagate since it's caught by application code. From commits-noreply at bitbucket.org Fri Sep 5 09:50:54 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Fri, 05 Sep 2014 07:50:54 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: strike python2.5 from test code cc @flub Message-ID: <20140905075054.19828.19522@app01.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/548f02cb5efa/ Changeset: 548f02cb5efa User: hpk42 Date: 2014-09-05 09:50:40 Summary: strike python2.5 from test code cc @flub Affected #: 3 files diff -r 766d82ca8b71cd455e4d174f595bb71232143626 -r 548f02cb5efaf71a280e2e21a3378e809652658a _pytest/genscript.py --- a/_pytest/genscript.py +++ b/_pytest/genscript.py @@ -72,11 +72,11 @@ deps = ['py', '_pytest', 'pytest'] if sys.version_info < (2,7): deps.append("argparse") - tw.line("generated script will run on python2.5-python3.3++") + tw.line("generated script will run on python2.6-python3.3++") else: tw.line("WARNING: generated script will not run on python2.6 " - "or below due to 'argparse' dependency. Use python2.6 " - "to generate a python2.5/6 compatible script", red=True) + "due to 'argparse' dependency. Use python2.6 " + "to generate a python2.6 compatible script", red=True) script = generate_script( 'import pytest; raise SystemExit(pytest.cmdline.main())', deps, diff -r 766d82ca8b71cd455e4d174f595bb71232143626 -r 548f02cb5efaf71a280e2e21a3378e809652658a doc/en/example/multipython.py --- a/doc/en/example/multipython.py +++ b/doc/en/example/multipython.py @@ -5,7 +5,7 @@ import py import pytest -pythonlist = ['python2.4', 'python2.5', 'python2.6', 'python2.7', 'python2.8'] +pythonlist = ['python2.6', 'python2.7', 'python3.4'] @pytest.fixture(params=pythonlist) def python1(request, tmpdir): picklefile = tmpdir.join("data.pickle") diff -r 766d82ca8b71cd455e4d174f595bb71232143626 -r 548f02cb5efaf71a280e2e21a3378e809652658a testing/conftest.py --- a/testing/conftest.py +++ b/testing/conftest.py @@ -77,12 +77,11 @@ winpymap = { 'python2.7': r'C:\Python27\python.exe', 'python2.6': r'C:\Python26\python.exe', - 'python2.5': r'C:\Python25\python.exe', - 'python2.4': r'C:\Python24\python.exe', 'python3.1': r'C:\Python31\python.exe', 'python3.2': r'C:\Python32\python.exe', 'python3.3': r'C:\Python33\python.exe', 'python3.4': r'C:\Python34\python.exe', + 'python3.5': r'C:\Python35\python.exe', } def getexecutable(name, cache={}): @@ -103,9 +102,8 @@ cache[name] = executable return executable - at pytest.fixture(params=['python2.5', 'python2.6', - 'python2.7', 'python3.2', "python3.3", - 'pypy', 'jython']) + at pytest.fixture(params=['python2.6', 'python2.7', 'python3.3', "python3.4", + 'pypy', 'pypy3', 'jython']) def anypython(request): name = request.param executable = getexecutable(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 Fri Sep 5 12:57:47 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Fri, 05 Sep 2014 10:57:47 -0000 Subject: [Pytest-commit] commit/py: 2 new changesets Message-ID: <20140905105747.21573.22626@app04.ash-private.bitbucket.org> 2 new commits in py: https://bitbucket.org/hpk42/py/commits/5ffd982f4dff/ Changeset: 5ffd982f4dff User: hpk42 Date: 2014-09-05 12:57:10 Summary: bump to 1.4.24, fix a test to work with newer colorama Affected #: 4 files diff -r 74b757aec58c65d8ba61eb5a4d91201e59012b50 -r 5ffd982f4dff60b588f309cd9bdc61036547282a CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -1.4.24.dev +1.4.24 ================================================== - Fix retrieving source when an else: line has an other statement on diff -r 74b757aec58c65d8ba61eb5a4d91201e59012b50 -r 5ffd982f4dff60b588f309cd9bdc61036547282a py/__init__.py --- a/py/__init__.py +++ b/py/__init__.py @@ -6,9 +6,9 @@ name->value mappings where value can be another namespace dictionary or an import path. -(c) Holger Krekel and others, 2004-2013 +(c) Holger Krekel and others, 2004-2014 """ -__version__ = '1.4.23' +__version__ = '1.4.24' from py import _apipkg diff -r 74b757aec58c65d8ba61eb5a4d91201e59012b50 -r 5ffd982f4dff60b588f309cd9bdc61036547282a setup.py --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ name='py', description='library with cross-python path, ini-parsing, io, code, log facilities', long_description = open('README.txt').read(), - version='1.4.24.dev1', + version='1.4.24', url='http://pylib.readthedocs.org/', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff -r 74b757aec58c65d8ba61eb5a4d91201e59012b50 -r 5ffd982f4dff60b588f309cd9bdc61036547282a testing/io_/test_terminalwriter.py --- a/testing/io_/test_terminalwriter.py +++ b/testing/io_/test_terminalwriter.py @@ -54,6 +54,7 @@ def test_terminalwriter_dumb_term_no_markup(monkeypatch): monkeypatch.setattr(os, 'environ', {'TERM': 'dumb', 'PATH': ''}) class MyFile: + closed = False def isatty(self): return True monkeypatch.setattr(sys, 'stdout', MyFile()) https://bitbucket.org/hpk42/py/commits/9373a488bf7e/ Changeset: 9373a488bf7e User: hpk42 Date: 2014-09-05 12:57:15 Summary: Added tag 1.4.24 for changeset 5ffd982f4dff Affected #: 1 file diff -r 5ffd982f4dff60b588f309cd9bdc61036547282a -r 9373a488bf7e7f5940a60ea6b491e067ae8fa93f .hgtags --- a/.hgtags +++ b/.hgtags @@ -56,3 +56,4 @@ a3e0626aa0c5aecf271367dc77e476ab216ea3c8 1.4.20 5e48016c4a3af8e7358a1267d33d021e71765bed 1.4.21 01ae2cfcc61c4fcb3aa5031349adb5b467c31018 1.4.23 +5ffd982f4dff60b588f309cd9bdc61036547282a 1.4.24 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 Sep 5 13:56:15 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Fri, 05 Sep 2014 11:56:15 -0000 Subject: [Pytest-commit] commit/pytest: 4 new changesets Message-ID: <20140905115615.20923.93904@app14.ash-private.bitbucket.org> 4 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/a4f25c5e6498/ Changeset: a4f25c5e6498 User: hpk42 Date: 2014-09-05 13:13:23 Summary: prepare 2.6.2, release announcement, also add HOWTORELEASE.rst Affected #: 7 files diff -r 548f02cb5efaf71a280e2e21a3378e809652658a -r a4f25c5e649892b5cc746d21be971e4773478af9 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -NEXT +2.6.2 ----------- - Added function pytest.freeze_includes(), which makes it easy to embed diff -r 548f02cb5efaf71a280e2e21a3378e809652658a -r a4f25c5e649892b5cc746d21be971e4773478af9 HOWTORELEASE.rst --- /dev/null +++ b/HOWTORELEASE.rst @@ -0,0 +1,44 @@ + +How to release pytest (draft) +-------------------------------------------- + +1. bump version numbers in setup.py and pytest/__init__.py + +2. check and finalize CHANGELOG + +3. write doc/en/announce/pytest-VERSION.txt and include + it in doc/en/announce/index.txt + +4. use devpi for uploading a release tarball to a staging area: + - ``devpi use https://devpi.net/USER/dev`` + - ``devpi upload`` + +5. run from multiple machines: + - ``devpi use https://devpi.net/USER/dev`` + - ``devpi test pytest-VERSION`` + +6. check that tests pass for relevant combinations with + ``devpi list pytest`` + or look at failures with "devpi list -f pytest". + There will be some failed environments like e.g. the py33-trial + or py27-pexpect tox environments on Win32 platforms + which is ok (tox does not support skipping on + per-platform basis yet). + +7. go to "doc/en" and upload docs with "make install" + (the latter requires ssh-login permissions on pytest.org + because it uses rsync). Note that the "install" target of + doc/en/Makefile defines where the rsync goes to, typically + to the "latest" section of pytest.org. + +8. publish to pypi "devpi push pytest-2.6.2 pypi:NAME" where NAME + is the name of pypi.python.org as configured in your + ~/.pypirc file -- it's the same you would use with + "setup.py upload -r NAME" + +9. send release announcement to mailing lists: + + pytest-dev + testing-in-python + python-announce-list at python.org + diff -r 548f02cb5efaf71a280e2e21a3378e809652658a -r a4f25c5e649892b5cc746d21be971e4773478af9 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.6.2.dev1' +__version__ = '2.6.2' diff -r 548f02cb5efaf71a280e2e21a3378e809652658a -r a4f25c5e649892b5cc746d21be971e4773478af9 doc/en/announce/index.txt --- a/doc/en/announce/index.txt +++ b/doc/en/announce/index.txt @@ -5,6 +5,9 @@ .. toctree:: :maxdepth: 2 + release-2.6.2 + release-2.6.1 + release-2.6.0 release-2.5.2 release-2.5.1 release-2.5.0 diff -r 548f02cb5efaf71a280e2e21a3378e809652658a -r a4f25c5e649892b5cc746d21be971e4773478af9 doc/en/announce/release-2.6.2.txt --- /dev/null +++ b/doc/en/announce/release-2.6.2.txt @@ -0,0 +1,52 @@ +pytest-2.6.2: few fixes and cx_freeze support +=========================================================================== + +pytest is a mature Python testing tool with more than a 1100 tests +against itself, passing on many different interpreters and platforms. +This release is drop-in compatible to 2.5.2 and 2.6.X. It also +brings support for including pytest with cx_freeze or similar +freezing tools into your single-file app distribution. For details +see the CHANGELOG below. + +See docs at: + + http://pytest.org + +As usual, you can upgrade from pypi via:: + + pip install -U pytest + +Thanks to all who contributed, among them: + + Floris Bruynooghe + Benjamin Peterson + Bruno Oliveira + +have fun, +holger krekel + +2.6.2 +----------- + +- Added function pytest.freeze_includes(), which makes it easy to embed + pytest into executables using tools like cx_freeze. + See docs for examples and rationale. Thanks Bruno Oliveira. + +- Improve assertion rewriting cache invalidation precision. + +- fixed issue561: adapt autouse fixture example for python3. + +- fixed issue453: assertion rewriting issue with __repr__ containing + "\n{", "\n}" and "\n~". + +- fix issue560: correctly display code if an "else:" or "finally:" is + followed by statements on the same line. + +- Fix example in monkeypatch documentation, thanks t-8ch. + +- fix issue572: correct tmpdir doc example for python3. + +- Do not mark as universal wheel because Python 2.6 is different from + other builds due to the extra argparse dependency. Fixes issue566. + Thanks sontek. + diff -r 548f02cb5efaf71a280e2e21a3378e809652658a -r a4f25c5e649892b5cc746d21be971e4773478af9 doc/en/conf.py --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -18,7 +18,7 @@ # The full version, including alpha/beta/rc tags. # The short X.Y version. version = "2.6" -release = "2.6.1" +release = "2.6.2" import sys, os diff -r 548f02cb5efaf71a280e2e21a3378e809652658a -r a4f25c5e649892b5cc746d21be971e4773478af9 setup.py --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ def main(): - install_requires = ['py>=1.4.24.dev1'] + install_requires = ['py>=1.4.24'] if sys.version_info < (2, 7) or (3,) <= sys.version_info < (3, 2): install_requires.append('argparse') if sys.platform == 'win32': @@ -27,7 +27,7 @@ name='pytest', description='pytest: simple powerful testing with Python', long_description=long_description, - version='2.6.2.dev1', + version='2.6.2', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], https://bitbucket.org/hpk42/pytest/commits/b2d567a5fe91/ Changeset: b2d567a5fe91 User: hpk42 Date: 2014-09-05 13:47:48 Summary: Added tag 2.6.2 for changeset a4f25c5e6498 Affected #: 1 file diff -r a4f25c5e649892b5cc746d21be971e4773478af9 -r b2d567a5fe91815ae55b3a7354be6eb38762683f .hgtags --- a/.hgtags +++ b/.hgtags @@ -70,3 +70,4 @@ 60725b17a9d1af4100abb8be3f9f4ddf6262bf34 2.6.0 88af949b9611494e2c65d528f9e565b00fb7e8ca 2.6.0 a4f9639702baa3eb4f3b16e162f74f7b69f3f9e1 2.6.1 +a4f25c5e649892b5cc746d21be971e4773478af9 2.6.2 https://bitbucket.org/hpk42/pytest/commits/16556bd3458e/ Changeset: 16556bd3458e User: hpk42 Date: 2014-09-05 13:55:00 Summary: regen docs for 2.6.2 Affected #: 15 files diff -r b2d567a5fe91815ae55b3a7354be6eb38762683f -r 16556bd3458e72e960b2a49aea319030cb119f6c doc/en/assert.txt --- a/doc/en/assert.txt +++ b/doc/en/assert.txt @@ -26,7 +26,7 @@ $ py.test test_assert1.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 1 items test_assert1.py F @@ -132,7 +132,7 @@ $ py.test test_assert2.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 1 items test_assert2.py F diff -r b2d567a5fe91815ae55b3a7354be6eb38762683f -r 16556bd3458e72e960b2a49aea319030cb119f6c doc/en/capture.txt --- a/doc/en/capture.txt +++ b/doc/en/capture.txt @@ -64,7 +64,7 @@ $ py.test =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 2 items test_module.py .F @@ -78,7 +78,7 @@ test_module.py:9: AssertionError -------------------------- Captured stdout setup --------------------------- - setting up + setting up ==================== 1 failed, 1 passed in 0.01 seconds ==================== Accessing captured output from a test function diff -r b2d567a5fe91815ae55b3a7354be6eb38762683f -r 16556bd3458e72e960b2a49aea319030cb119f6c doc/en/doctest.txt --- a/doc/en/doctest.txt +++ b/doc/en/doctest.txt @@ -44,12 +44,12 @@ $ py.test =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 1 items mymodule.py . - ========================= 1 passed in 0.06 seconds ========================= + ========================= 1 passed in 0.07 seconds ========================= It is possible to use fixtures using the ``getfixture`` helper:: diff -r b2d567a5fe91815ae55b3a7354be6eb38762683f -r 16556bd3458e72e960b2a49aea319030cb119f6c doc/en/example/markers.txt --- a/doc/en/example/markers.txt +++ b/doc/en/example/markers.txt @@ -31,7 +31,7 @@ $ py.test -v -m webtest =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 4 items test_server.py::test_send_http PASSED @@ -43,7 +43,7 @@ $ py.test -v -m "not webtest" =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 4 items test_server.py::test_something_quick PASSED @@ -62,7 +62,7 @@ $ py.test -v test_server.py::TestClass::test_method =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 5 items test_server.py::TestClass::test_method PASSED @@ -73,7 +73,7 @@ $ py.test -v test_server.py::TestClass =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 4 items test_server.py::TestClass::test_method PASSED @@ -84,7 +84,7 @@ $ py.test -v test_server.py::TestClass test_server.py::test_send_http =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 8 items test_server.py::TestClass::test_method PASSED @@ -120,7 +120,7 @@ $ py.test -v -k http # running with the above defined example module =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 4 items test_server.py::test_send_http PASSED @@ -132,7 +132,7 @@ $ py.test -k "not send_http" -v =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 4 items test_server.py::test_something_quick PASSED @@ -146,14 +146,14 @@ $ py.test -k "http or quick" -v =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 4 items test_server.py::test_send_http PASSED test_server.py::test_something_quick PASSED ================= 2 tests deselected by '-khttp or quick' ================== - ================== 2 passed, 2 deselected in 0.01 seconds ================== + ================== 2 passed, 2 deselected in 0.02 seconds ================== .. note:: @@ -326,7 +326,7 @@ $ py.test -E stage2 =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 1 items test_someenv.py s @@ -337,7 +337,7 @@ $ py.test -E stage1 =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 1 items test_someenv.py . @@ -455,12 +455,12 @@ $ py.test -rs # this option reports skip reasons =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 4 items test_plat.py sss. ========================= short test summary info ========================== - SKIP [3] /tmp/doc-exec-238/conftest.py:12: cannot run on platform linux + SKIP [3] /tmp/doc-exec-82/conftest.py:12: cannot run on platform linux =================== 1 passed, 3 skipped in 0.01 seconds ==================== @@ -468,7 +468,7 @@ $ py.test -m linux2 =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 4 items test_plat.py s @@ -519,7 +519,7 @@ $ py.test -m interface --tb=short =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 4 items test_module.py FF @@ -540,7 +540,7 @@ $ py.test -m "interface or event" --tb=short =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 4 items test_module.py FFF @@ -559,4 +559,4 @@ assert 0 E assert 0 ============= 1 tests deselected by "-m 'interface or event'" ============== - ================== 3 failed, 1 deselected in 0.01 seconds ================== + ================== 3 failed, 1 deselected in 0.02 seconds ================== diff -r b2d567a5fe91815ae55b3a7354be6eb38762683f -r 16556bd3458e72e960b2a49aea319030cb119f6c doc/en/example/nonpython.txt --- a/doc/en/example/nonpython.txt +++ b/doc/en/example/nonpython.txt @@ -27,7 +27,7 @@ nonpython $ py.test test_simple.yml =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 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.03 seconds ==================== + ==================== 1 failed, 1 passed in 0.04 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 linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 2 items test_simple.yml::usecase: ok PASSED @@ -67,17 +67,17 @@ usecase execution failed spec failed: 'some': 'other' no further details known at this point. - ==================== 1 failed, 1 passed in 0.03 seconds ==================== + ==================== 1 failed, 1 passed in 0.05 seconds ==================== While developing your custom test collection and execution it's also interesting to just look at the collection tree:: nonpython $ py.test --collect-only =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 2 items - ============================= in 0.03 seconds ============================= + ============================= in 0.04 seconds ============================= diff -r b2d567a5fe91815ae55b3a7354be6eb38762683f -r 16556bd3458e72e960b2a49aea319030cb119f6c doc/en/example/pythoncollection.txt --- a/doc/en/example/pythoncollection.txt +++ b/doc/en/example/pythoncollection.txt @@ -43,7 +43,7 @@ $ py.test --collect-only =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 2 items @@ -88,7 +88,7 @@ . $ py.test --collect-only pythoncollection.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 3 items @@ -141,7 +141,7 @@ $ py.test --collect-only =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 0 items ============================= in 0.01 seconds ============================= diff -r b2d567a5fe91815ae55b3a7354be6eb38762683f -r 16556bd3458e72e960b2a49aea319030cb119f6c doc/en/example/reportingdemo.txt --- a/doc/en/example/reportingdemo.txt +++ b/doc/en/example/reportingdemo.txt @@ -13,7 +13,7 @@ assertion $ py.test failure_demo.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 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 = .f at 0x2aec3e47b158>() - E + and 43 = .g at 0x2aec3e47b268>() + E + where 42 = .f at 0x2aab6e7559d8>() + E + and 43 = .g at 0x2aab6e755ea0>() 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 = .f at 0x2aec3e47e620>() + E + where 42 = .f at 0x2aab6e7617b8>() 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, 'c': 0} == {'a': 0, 'b': 2, 'd': 0} @@ -194,7 +194,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]) @@ -210,7 +210,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] @@ -220,7 +220,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] @@ -229,7 +229,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' @@ -247,7 +247,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' @@ -260,7 +260,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 @@ -273,7 +273,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 @@ -292,7 +292,7 @@ i = Foo() > assert i.b == 2 E assert 1 == 2 - E + where 1 = .Foo object at 0x2aec3e519c18>.b + E + where 1 = .Foo object at 0x2aab6e61ed30>.b failure_demo.py:101: AssertionError _________________________ test_attribute_instance __________________________ @@ -302,8 +302,8 @@ b = 1 > assert Foo().b == 2 E assert 1 == 2 - E + where 1 = .Foo object at 0x2aec3e52d898>.b - E + where .Foo object at 0x2aec3e52d898> = .Foo'>() + E + where 1 = .Foo object at 0x2aab6e80e400>.b + E + where .Foo object at 0x2aab6e80e400> = .Foo'>() failure_demo.py:107: AssertionError __________________________ test_attribute_failure __________________________ @@ -319,7 +319,7 @@ failure_demo.py:116: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ - self = .Foo object at 0x2aec3e4e0b38> + self = .Foo object at 0x2aab6e7fccc0> def _get_b(self): > raise Exception('Failed to get attrib') @@ -335,15 +335,15 @@ b = 2 > assert Foo().b == Bar().b E assert 1 == 2 - E + where 1 = .Foo object at 0x2aec3e4a5748>.b - E + where .Foo object at 0x2aec3e4a5748> = .Foo'>() - E + and 2 = .Bar object at 0x2aec3e4a51d0>.b - E + where .Bar object at 0x2aec3e4a51d0> = .Bar'>() + E + where 1 = .Foo object at 0x2aab6e81dbe0>.b + E + where .Foo object at 0x2aab6e81dbe0> = .Foo'>() + E + and 2 = .Bar object at 0x2aab6bf55fd0>.b + E + where .Bar object at 0x2aab6bf55fd0> = .Bar'>() failure_demo.py:124: AssertionError __________________________ TestRaises.test_raises __________________________ - self = + self = def test_raises(self): s = 'qwe' @@ -358,7 +358,7 @@ <0-codegen /home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/_pytest/python.py:1028>:1: ValueError ______________________ TestRaises.test_raises_doesnt _______________________ - self = + self = def test_raises_doesnt(self): > raises(IOError, "int('3')") @@ -367,7 +367,7 @@ failure_demo.py:136: Failed __________________________ TestRaises.test_raise ___________________________ - self = + self = def test_raise(self): > raise ValueError("demo error") @@ -376,7 +376,7 @@ failure_demo.py:139: ValueError ________________________ TestRaises.test_tupleerror ________________________ - self = + self = def test_tupleerror(self): > a,b = [1] @@ -385,7 +385,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] @@ -398,7 +398,7 @@ l is [1, 2, 3] ________________________ TestRaises.test_some_error ________________________ - self = + self = def test_some_error(self): > if namenotexi: @@ -426,7 +426,7 @@ <2-codegen 'abc-123' /home/hpk/p/pytest/doc/en/example/assertion/failure_demo.py:162>:2: AssertionError ____________________ TestMoreErrors.test_complex_error _____________________ - self = + self = def test_complex_error(self): def f(): @@ -450,7 +450,7 @@ failure_demo.py:5: AssertionError ___________________ TestMoreErrors.test_z1_unpack_error ____________________ - self = + self = def test_z1_unpack_error(self): l = [] @@ -460,7 +460,7 @@ failure_demo.py:179: ValueError ____________________ TestMoreErrors.test_z2_type_error _____________________ - self = + self = def test_z2_type_error(self): l = 3 @@ -470,19 +470,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(): @@ -490,15 +490,15 @@ def g(): return "456" > assert f().startswith(g()) - E assert ('456') - E + where = '123'.startswith - E + where '123' = .f at 0x2aec3e5572f0>() - E + and '456' = .g at 0x2aec3e557268>() + E assert ('456') + E + where = '123'.startswith + E + where '123' = .f at 0x2aab6e7e8730>() + E + and '456' = .g at 0x2aab6e7e86a8>() failure_demo.py:195: AssertionError _____________________ TestMoreErrors.test_global_func ______________________ - self = + self = def test_global_func(self): > assert isinstance(globf(42), float) @@ -508,18 +508,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 @@ -529,7 +529,7 @@ failure_demo.py:205: AssertionError _____________________ TestMoreErrors.test_try_finally ______________________ - self = + self = def test_try_finally(self): x = 1 @@ -538,4 +538,4 @@ E assert 1 == 0 failure_demo.py:210: AssertionError - ======================== 39 failed in 0.22 seconds ========================= + ======================== 39 failed in 0.25 seconds ========================= diff -r b2d567a5fe91815ae55b3a7354be6eb38762683f -r 16556bd3458e72e960b2a49aea319030cb119f6c doc/en/example/simple.txt --- a/doc/en/example/simple.txt +++ b/doc/en/example/simple.txt @@ -108,7 +108,7 @@ $ py.test =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 0 items ============================= in 0.00 seconds ============================= @@ -152,12 +152,12 @@ $ py.test -rs # "-rs" means report details on the little 's' =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 2 items test_module.py .s ========================= short test summary info ========================== - SKIP [1] /tmp/doc-exec-243/conftest.py:9: need --runslow option to run + SKIP [1] /tmp/doc-exec-87/conftest.py:9: need --runslow option to run =================== 1 passed, 1 skipped in 0.01 seconds ==================== @@ -165,7 +165,7 @@ $ py.test --runslow =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 2 items test_module.py .. @@ -256,7 +256,7 @@ $ py.test =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 project deps: mylib-1.1 collected 0 items @@ -279,7 +279,7 @@ $ py.test -v =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 info1: did you know that ... did you? collecting ... collected 0 items @@ -290,7 +290,7 @@ $ py.test =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 0 items ============================= in 0.00 seconds ============================= @@ -322,7 +322,7 @@ $ py.test --durations=3 =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 3 items test_some_are_slow.py ... @@ -383,7 +383,7 @@ $ py.test -rx =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 4 items test_step.py .Fx. @@ -391,7 +391,7 @@ ================================= FAILURES ================================= ____________________ TestUserHandling.test_modification ____________________ - self = + self = def test_modification(self): > assert 0 @@ -401,7 +401,7 @@ ========================= short test summary info ========================== XFAIL test_step.py::TestUserHandling::()::test_deletion reason: previous test failed (test_modification) - ============== 1 failed, 2 passed, 1 xfailed in 0.01 seconds =============== + ============== 1 failed, 2 passed, 1 xfailed in 0.02 seconds =============== We'll see that ``test_deletion`` was not executed because ``test_modification`` failed. It is reported as an "expected failure". @@ -453,7 +453,7 @@ $ py.test =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 7 items test_step.py .Fx. @@ -463,17 +463,17 @@ ================================== ERRORS ================================== _______________________ ERROR at setup of test_root ________________________ - file /tmp/doc-exec-243/b/test_error.py, line 1 + file /tmp/doc-exec-87/b/test_error.py, line 1 def test_root(db): # no db here, will error out fixture 'db' not found - available fixtures: tmpdir, monkeypatch, capsys, capfd, pytestconfig, recwarn + available fixtures: recwarn, monkeypatch, pytestconfig, capfd, capsys, tmpdir use 'py.test --fixtures [testpath]' for help on them. - /tmp/doc-exec-243/b/test_error.py:1 + /tmp/doc-exec-87/b/test_error.py:1 ================================= FAILURES ================================= ____________________ TestUserHandling.test_modification ____________________ - self = + self = def test_modification(self): > assert 0 @@ -482,23 +482,23 @@ test_step.py:9: AssertionError _________________________________ test_a1 __________________________________ - db = + db = def test_a1(db): > assert 0, db # to show value - E AssertionError: + E AssertionError: a/test_db.py:2: AssertionError _________________________________ test_a2 __________________________________ - db = + db = def test_a2(db): > assert 0, db # to show value - E AssertionError: + E AssertionError: a/test_db2.py:2: AssertionError - ========== 3 failed, 2 passed, 1 xfailed, 1 error in 0.03 seconds ========== + ========== 3 failed, 2 passed, 1 xfailed, 1 error in 0.04 seconds ========== The two test modules in the ``a`` directory see the same ``db`` fixture instance while the one test in the sister-directory ``b`` doesn't see it. We could of course @@ -553,7 +553,7 @@ $ py.test test_module.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 2 items test_module.py FF @@ -561,7 +561,7 @@ ================================= FAILURES ================================= ________________________________ test_fail1 ________________________________ - tmpdir = local('/tmp/pytest-509/test_fail10') + tmpdir = local('/tmp/pytest-15/test_fail10') def test_fail1(tmpdir): > assert 0 @@ -575,12 +575,12 @@ E assert 0 test_module.py:4: AssertionError - ========================= 2 failed in 0.02 seconds ========================= + ========================= 2 failed in 0.01 seconds ========================= you will have a "failures" file which contains the failing test ids:: $ cat failures - test_module.py::test_fail1 (/tmp/pytest-509/test_fail10) + test_module.py::test_fail1 (/tmp/pytest-15/test_fail10) test_module.py::test_fail2 Making test result information available in fixtures @@ -645,25 +645,25 @@ Traceback (most recent call last): File "/home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/_pytest/config.py", line 513, in getconftestmodules return self._path2confmods[path] - KeyError: local('/tmp/doc-exec-243/test_module.py') + KeyError: local('/tmp/doc-exec-87/test_module.py') During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/_pytest/config.py", line 537, in importconftest return self._conftestpath2mod[conftestpath] - KeyError: local('/tmp/doc-exec-243/conftest.py') + KeyError: local('/tmp/doc-exec-87/conftest.py') During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/_pytest/config.py", line 543, in importconftest mod = conftestpath.pyimport() - File "/home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/py/_path/local.py", line 620, in pyimport + File "/home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/py/_path/local.py", line 640, in pyimport __import__(modname) - File "/tmp/doc-exec-243/conftest.py", line 22 + File "/tmp/doc-exec-87/conftest.py", line 22 print "setting up a test failed!", request.node.nodeid ^ SyntaxError: invalid syntax - ERROR: could not load /tmp/doc-exec-243/conftest.py + ERROR: could not load /tmp/doc-exec-87/conftest.py You'll see that the fixture finalizers could use the precise reporting @@ -719,3 +719,4 @@ application, using standard ``py.test`` command-line options:: $ ./app_main --pytest --verbose --tb=long --junit-xml=results.xml test-suite/ + /bin/sh: 1: ./app_main: not found diff -r b2d567a5fe91815ae55b3a7354be6eb38762683f -r 16556bd3458e72e960b2a49aea319030cb119f6c doc/en/example/special.txt --- a/doc/en/example/special.txt +++ b/doc/en/example/special.txt @@ -63,23 +63,23 @@ Traceback (most recent call last): File "/home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/_pytest/config.py", line 513, in getconftestmodules return self._path2confmods[path] - KeyError: local('/tmp/doc-exec-244/test_module.py') + KeyError: local('/tmp/doc-exec-88/test_module.py') During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/_pytest/config.py", line 537, in importconftest return self._conftestpath2mod[conftestpath] - KeyError: local('/tmp/doc-exec-244/conftest.py') + KeyError: local('/tmp/doc-exec-88/conftest.py') During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/_pytest/config.py", line 543, in importconftest mod = conftestpath.pyimport() - File "/home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/py/_path/local.py", line 620, in pyimport + File "/home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/py/_path/local.py", line 640, in pyimport __import__(modname) - File "/tmp/doc-exec-244/conftest.py", line 6 + File "/tmp/doc-exec-88/conftest.py", line 6 print "callattr_ahead_of_alltests called" ^ SyntaxError: invalid syntax - ERROR: could not load /tmp/doc-exec-244/conftest.py + ERROR: could not load /tmp/doc-exec-88/conftest.py diff -r b2d567a5fe91815ae55b3a7354be6eb38762683f -r 16556bd3458e72e960b2a49aea319030cb119f6c doc/en/fixture.txt --- a/doc/en/fixture.txt +++ b/doc/en/fixture.txt @@ -76,7 +76,7 @@ $ py.test test_smtpsimple.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.2.dev1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 1 items test_smtpsimple.py F @@ -84,7 +84,7 @@ ================================= FAILURES ================================= ________________________________ test_ehlo _________________________________ - smtp = + smtp = def test_ehlo(smtp): response, msg = smtp.ehlo() @@ -93,7 +93,7 @@ E TypeError: Type str doesn't support the buffer API test_smtpsimple.py:11: TypeError - ========================= 1 failed in 0.18 seconds ========================= + ========================= 1 failed in 0.21 seconds ========================= In the failure traceback we see that the test function was called with a ``smtp`` argument, the ``smtplib.SMTP()`` instance created by the fixture @@ -193,7 +193,7 @@ $ py.test test_module.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.2.dev1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 2 items test_module.py FF @@ -201,7 +201,7 @@ ================================= FAILURES ================================= ________________________________ test_ehlo _________________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -212,7 +212,7 @@ test_module.py:5: TypeError ________________________________ test_noop _________________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -221,7 +221,7 @@ E assert 0 test_module.py:11: AssertionError - ========================= 2 failed in 0.18 seconds ========================= + ========================= 2 failed in 0.21 seconds ========================= You see the two ``assert 0`` failing and more importantly you can also see that the same (module-scoped) ``smtp`` object was passed into the two @@ -310,7 +310,7 @@ $ py.test -s -q --tb=no FF - 2 failed in 0.17 seconds + 2 failed in 0.16 seconds Let's quickly create another test module that actually sets the server URL in its module namespace:: @@ -377,7 +377,7 @@ ================================= FAILURES ================================= __________________________ test_ehlo[merlinux.eu] __________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -388,7 +388,7 @@ test_module.py:5: TypeError __________________________ test_noop[merlinux.eu] __________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -399,7 +399,7 @@ test_module.py:11: AssertionError ________________________ test_ehlo[mail.python.org] ________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -409,10 +409,10 @@ test_module.py:5: TypeError -------------------------- Captured stdout setup --------------------------- - finalizing + finalizing ________________________ test_noop[mail.python.org] ________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -461,13 +461,13 @@ $ py.test -v test_appsetup.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.2.dev1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 2 items test_appsetup.py::test_smtp_exists[merlinux.eu] PASSED test_appsetup.py::test_smtp_exists[mail.python.org] PASSED - ========================= 2 passed in 6.11 seconds ========================= + ========================= 2 passed in 6.37 seconds ========================= Due to the parametrization of ``smtp`` the test will run twice with two different ``App`` instances and respective smtp servers. There is no @@ -525,7 +525,7 @@ $ py.test -v -s test_module.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.2.dev1 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 8 items test_module.py::test_0[1] test0 1 @@ -675,7 +675,7 @@ $ py.test -q .. - 2 passed in 0.01 seconds + 2 passed in 0.02 seconds Here is how autouse fixtures work in other scopes: diff -r b2d567a5fe91815ae55b3a7354be6eb38762683f -r 16556bd3458e72e960b2a49aea319030cb119f6c doc/en/getting-started.txt --- a/doc/en/getting-started.txt +++ b/doc/en/getting-started.txt @@ -27,7 +27,7 @@ To check your installation has installed the correct version:: $ py.test --version - This is pytest version 2.6.1, imported from /home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/pytest.py + This is pytest version 2.6.2, imported from /home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/pytest.py If you get an error checkout :ref:`installation issues`. @@ -49,19 +49,19 @@ $ py.test =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 1 items - + test_sample.py F - + ================================= FAILURES ================================= _______________________________ test_answer ________________________________ - + def test_answer(): > assert func(3) == 5 E assert 4 == 5 E + where 4 = func(3) - + test_sample.py:5: AssertionError ========================= 1 failed in 0.01 seconds ========================= @@ -97,7 +97,7 @@ $ py.test -q test_sysexit.py . - 1 passed in 0.00 seconds + 1 passed in 0.01 seconds .. todo:: For further ways to assert exceptions see the `raises` @@ -126,16 +126,16 @@ .F ================================= FAILURES ================================= ____________________________ TestClass.test_two ____________________________ - - self = - + + self = + def test_two(self): x = "hello" > assert hasattr(x, 'check') E assert hasattr('hello', 'check') - + test_class.py:8: AssertionError - 1 failed, 1 passed in 0.01 seconds + 1 failed, 1 passed in 0.02 seconds The first test passed, the second failed. Again we can easily see the intermediate values used in the assertion, helping us to @@ -159,18 +159,21 @@ before performing the test function call. Let's just run it:: $ py.test -q test_tmpdir.py - - ================================== ERRORS ================================== - _____________________ ERROR collecting test_tmpdir.py ______________________ - /home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/_pytest/python.py:463: in _importtestmodule - mod = self.fspath.pyimport(ensuresyspath=True) - /home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/py/_path/local.py:620: in pyimport - __import__(modname) - E File "/tmp/doc-exec-187/test_tmpdir.py", line 2 - E print tmpdir - E ^ - E SyntaxError: invalid syntax - 1 error in 0.03 seconds + F + ================================= FAILURES ================================= + _____________________________ test_needsfiles ______________________________ + + tmpdir = local('/tmp/pytest-11/test_needsfiles0') + + def test_needsfiles(tmpdir): + print (tmpdir) + > assert 0 + E assert 0 + + test_tmpdir.py:3: AssertionError + --------------------------- Captured stdout call --------------------------- + /tmp/pytest-11/test_needsfiles0 + 1 failed in 0.32 seconds Before the test runs, a unique-per-test-invocation temporary directory was created. More info at :ref:`tmpdir handling`. diff -r b2d567a5fe91815ae55b3a7354be6eb38762683f -r 16556bd3458e72e960b2a49aea319030cb119f6c doc/en/parametrize.txt --- a/doc/en/parametrize.txt +++ b/doc/en/parametrize.txt @@ -53,7 +53,7 @@ $ py.test =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 3 items test_expectation.py ..F @@ -100,7 +100,7 @@ $ py.test =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 3 items test_expectation.py ..x @@ -170,8 +170,8 @@ def test_valid_string(stringinput): > assert stringinput.isalpha() - E assert () - E + where = '!'.isalpha + E assert () + E + where = '!'.isalpha test_strings.py:3: AssertionError 1 failed in 0.01 seconds @@ -185,7 +185,7 @@ $ py.test -q -rs test_strings.py s ========================= short test summary info ========================== - SKIP [1] /home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/_pytest/python.py:1139: got empty parameter set, function test_valid_string at /tmp/doc-exec-195/test_strings.py:1 + SKIP [1] /home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/_pytest/python.py:1139: got empty parameter set, function test_valid_string at /tmp/doc-exec-38/test_strings.py:1 1 skipped in 0.01 seconds For further examples, you might want to look at :ref:`more diff -r b2d567a5fe91815ae55b3a7354be6eb38762683f -r 16556bd3458e72e960b2a49aea319030cb119f6c doc/en/skipping.txt --- a/doc/en/skipping.txt +++ b/doc/en/skipping.txt @@ -164,7 +164,7 @@ example $ py.test -rx xfail_demo.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 7 items xfail_demo.py xxxxxxx diff -r b2d567a5fe91815ae55b3a7354be6eb38762683f -r 16556bd3458e72e960b2a49aea319030cb119f6c doc/en/tmpdir.txt --- a/doc/en/tmpdir.txt +++ b/doc/en/tmpdir.txt @@ -29,7 +29,7 @@ $ py.test test_tmpdir.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 1 items test_tmpdir.py F @@ -37,7 +37,7 @@ ================================= FAILURES ================================= _____________________________ test_create_file _____________________________ - tmpdir = local('/tmp/pytest-506/test_create_file0') + tmpdir = local('/tmp/pytest-12/test_create_file0') def test_create_file(tmpdir): p = tmpdir.mkdir("sub").join("hello.txt") @@ -48,7 +48,7 @@ E assert 0 test_tmpdir.py:7: AssertionError - ========================= 1 failed in 0.02 seconds ========================= + ========================= 1 failed in 0.01 seconds ========================= .. _`base temporary directory`: diff -r b2d567a5fe91815ae55b3a7354be6eb38762683f -r 16556bd3458e72e960b2a49aea319030cb119f6c doc/en/unittest.txt --- a/doc/en/unittest.txt +++ b/doc/en/unittest.txt @@ -88,7 +88,7 @@ $ py.test test_unittest_db.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 collected 2 items test_unittest_db.py FF @@ -101,7 +101,7 @@ def test_method1(self): assert hasattr(self, "db") > assert 0, self.db # fail for demo purposes - E AssertionError: .DummyDB object at 0x2b12849f90b8> + E AssertionError: .DummyDB object at 0x2ad7f12df240> test_unittest_db.py:9: AssertionError ___________________________ MyTest.test_method2 ____________________________ @@ -110,7 +110,7 @@ def test_method2(self): > assert 0, self.db # fail for demo purposes - E AssertionError: .DummyDB object at 0x2b12849f90b8> + E AssertionError: .DummyDB object at 0x2ad7f12df240> test_unittest_db.py:12: AssertionError ========================= 2 failed in 0.05 seconds ========================= @@ -160,7 +160,7 @@ $ py.test -q test_unittest_cleandir.py . - 1 passed in 0.05 seconds + 1 passed in 0.04 seconds ... gives us one passed test because the ``initdir`` fixture function was executed ahead of the ``test_method``. https://bitbucket.org/hpk42/pytest/commits/1a64df368b27/ Changeset: 1a64df368b27 User: hpk42 Date: 2014-09-05 13:55:58 Summary: mention XXX regendoc for release process Affected #: 1 file diff -r 16556bd3458e72e960b2a49aea319030cb119f6c -r 1a64df368b2746f35ac479cad426515283b25722 HOWTORELEASE.rst --- a/HOWTORELEASE.rst +++ b/HOWTORELEASE.rst @@ -25,18 +25,21 @@ which is ok (tox does not support skipping on per-platform basis yet). -7. go to "doc/en" and upload docs with "make install" +7. XXX "regen docs" (not easy to do currently as it requires + a development version of the regendoc tool from ronny) + +8. go to "doc/en" and upload docs with "make install" (the latter requires ssh-login permissions on pytest.org because it uses rsync). Note that the "install" target of doc/en/Makefile defines where the rsync goes to, typically to the "latest" section of pytest.org. -8. publish to pypi "devpi push pytest-2.6.2 pypi:NAME" where NAME +9. publish to pypi "devpi push pytest-2.6.2 pypi:NAME" where NAME is the name of pypi.python.org as configured in your ~/.pypirc file -- it's the same you would use with "setup.py upload -r NAME" -9. send release announcement to mailing lists: +10. send release announcement to mailing lists: pytest-dev testing-in-python 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 issues-reply at bitbucket.org Fri Sep 5 13:57:54 2014 From: issues-reply at bitbucket.org (thiefmaster) Date: Fri, 05 Sep 2014 11:57:54 -0000 Subject: [Pytest-commit] Issue #581: Provide skeletons for PyCharm (hpk42/pytest) Message-ID: <20140905115754.20278.29500@app02.ash-private.bitbucket.org> New issue 581: Provide skeletons for PyCharm https://bitbucket.org/hpk42/pytest/issue/581/provide-skeletons-for-pycharm thiefmaster: The PyCharm/IntelliJ IDEs don't understand the magic used by py.test to populate the `pytest` module, so all the nice IDE features like parameter completion do not work and inspections actually show things like `pytest.mark` as invalid. This could be avoided by providing skeletons as described here: https://github.com/JetBrains/python-skeletons From commits-noreply at bitbucket.org Fri Sep 5 14:55:24 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Fri, 05 Sep 2014 12:55:24 -0000 Subject: [Pytest-commit] commit/py: 2 new changesets Message-ID: <20140905125524.32337.42546@app13.ash-private.bitbucket.org> 2 new commits in py: https://bitbucket.org/hpk42/py/commits/68a09c47feb4/ Changeset: 68a09c47feb4 User: hpk42 Date: 2014-09-05 14:54:37 Summary: 1.4.25.dev ================================================== ifix issue52: vaguely fix py25 compat of py.path.local (it's not officially supported) Affected #: 2 files diff -r 9373a488bf7e7f5940a60ea6b491e067ae8fa93f -r 68a09c47feb4e792cfc71ff003f59e0c63f4c661 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +1.4.25.dev +================================================== + +- ifix issue52: vaguely fix py25 compat of py.path.local (it's not + officially supported) + 1.4.24 ================================================== diff -r 9373a488bf7e7f5940a60ea6b491e067ae8fa93f -r 68a09c47feb4e792cfc71ff003f59e0c63f4c661 py/_path/local.py --- a/py/_path/local.py +++ b/py/_path/local.py @@ -1,6 +1,8 @@ """ local path implementation. """ +from __future__ import with_statement + from contextlib import contextmanager import sys, os, re, atexit, io import py https://bitbucket.org/hpk42/py/commits/75ef6111820e/ Changeset: 75ef6111820e User: hpk42 Date: 2014-09-05 14:55:05 Summary: fix issue52: vaguely fix py25 compat of py.path.local (it's not officially supported) Affected #: 3 files diff -r 68a09c47feb4e792cfc71ff003f59e0c63f4c661 -r 75ef6111820efd0bd3dd250e069056c219511a43 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,7 @@ 1.4.25.dev ================================================== -- ifix issue52: vaguely fix py25 compat of py.path.local (it's not +- fix issue52: vaguely fix py25 compat of py.path.local (it's not officially supported) 1.4.24 diff -r 68a09c47feb4e792cfc71ff003f59e0c63f4c661 -r 75ef6111820efd0bd3dd250e069056c219511a43 py/__init__.py --- a/py/__init__.py +++ b/py/__init__.py @@ -8,7 +8,7 @@ (c) Holger Krekel and others, 2004-2014 """ -__version__ = '1.4.24' +__version__ = '1.4.25.dev' from py import _apipkg diff -r 68a09c47feb4e792cfc71ff003f59e0c63f4c661 -r 75ef6111820efd0bd3dd250e069056c219511a43 setup.py --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ name='py', description='library with cross-python path, ini-parsing, io, code, log facilities', long_description = open('README.txt').read(), - version='1.4.24', + version='1.4.25.dev', url='http://pylib.readthedocs.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 issues-reply at bitbucket.org Fri Sep 5 15:24:54 2014 From: issues-reply at bitbucket.org (Laszlo Papp) Date: Fri, 05 Sep 2014 13:24:54 -0000 Subject: [Pytest-commit] Issue #582: setup.py test documentation is broken (hpk42/pytest) Message-ID: <20140905132454.4876.41494@app07.ash-private.bitbucket.org> New issue 582: setup.py test documentation is broken https://bitbucket.org/hpk42/pytest/issue/582/setuppy-test-documentation-is-broken Laszlo Papp: Details can be read here: http://lists.idyll.org/pipermail/testing-in-python/2014-September/006085.html Responsible: RonnyPfannschmidt From commits-noreply at bitbucket.org Fri Sep 5 15:34:45 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Fri, 05 Sep 2014 13:34:45 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: fix issue582: fix setuptools example, thanks Laszlo Papp and Ronny Message-ID: <20140905133445.27644.16911@app13.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/2cf48d77a376/ Changeset: 2cf48d77a376 User: hpk42 Date: 2014-09-05 15:34:01 Summary: fix issue582: fix setuptools example, thanks Laszlo Papp and Ronny Pfannschmidt. Affected #: 4 files diff -r 1a64df368b2746f35ac479cad426515283b25722 -r 2cf48d77a3764a1c3cf47ec3c63a972d35ad63d4 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,10 @@ +NEXT +----------- + +- fix issue582: fix setuptools example, thanks Laszlo Papp and Ronny + Pfannschmidt. + + 2.6.2 ----------- diff -r 1a64df368b2746f35ac479cad426515283b25722 -r 2cf48d77a3764a1c3cf47ec3c63a972d35ad63d4 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.6.2' +__version__ = '2.6.3.dev' diff -r 1a64df368b2746f35ac479cad426515283b25722 -r 2cf48d77a3764a1c3cf47ec3c63a972d35ad63d4 doc/en/goodpractises.txt --- a/doc/en/goodpractises.txt +++ b/doc/en/goodpractises.txt @@ -233,7 +233,7 @@ def initialize_options(self): TestCommand.initialize_options(self) - self.pytest_args = None + self.pytest_args = [] def finalize_options(self): TestCommand.finalize_options(self) diff -r 1a64df368b2746f35ac479cad426515283b25722 -r 2cf48d77a3764a1c3cf47ec3c63a972d35ad63d4 setup.py --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ name='pytest', description='pytest: simple powerful testing with Python', long_description=long_description, - version='2.6.2', + version='2.6.3.dev', 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 issues-reply at bitbucket.org Fri Sep 5 16:40:14 2014 From: issues-reply at bitbucket.org (Laszlo Papp) Date: Fri, 05 Sep 2014 14:40:14 -0000 Subject: [Pytest-commit] Issue #583: Add a class example for Setup/TearDown with fixtures (hpk42/pytest) Message-ID: <20140905144014.12868.99651@app06.ash-private.bitbucket.org> New issue 583: Add a class example for Setup/TearDown with fixtures https://bitbucket.org/hpk42/pytest/issue/583/add-a-class-example-for-setup-teardown Laszlo Papp: Discussion can be found here: http://lists.idyll.org/pipermail/testing-in-python/2014-September/006086.html Responsible: hpk42 From commits-noreply at bitbucket.org Sat Sep 6 01:08:32 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Fri, 05 Sep 2014 23:08:32 -0000 Subject: [Pytest-commit] commit/pytest: 9 new changesets Message-ID: <20140905230832.11241.68739@app03.ash-private.bitbucket.org> 9 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/ce7494cefd35/ Changeset: ce7494cefd35 User: uweschmitt Date: 2014-08-07 16:13:12 Summary: fixed strange infinite recursion bug Affected #: 1 file diff -r 737cf55acf3c5401b44f13239fa3d9e87031d8a3 -r ce7494cefd35ea88a35ed39562d0df4685645f7c _pytest/capture.py --- a/_pytest/capture.py +++ b/_pytest/capture.py @@ -238,7 +238,8 @@ self.write(data) def __getattr__(self, name): - return getattr(self.buffer, name) + if name != "buffer": + return getattr(self.buffer, name) class MultiCapture(object): https://bitbucket.org/hpk42/pytest/commits/8a57dee643d7/ Changeset: 8a57dee643d7 User: uweschmitt Date: 2014-08-07 16:56:45 Summary: better fix as replacement for last commit Affected #: 1 file diff -r ce7494cefd35ea88a35ed39562d0df4685645f7c -r 8a57dee643d74783a9cb8fdb696d83eae6e9370d _pytest/capture.py --- a/_pytest/capture.py +++ b/_pytest/capture.py @@ -238,8 +238,12 @@ self.write(data) def __getattr__(self, name): - if name != "buffer": - return getattr(self.buffer, name) + return getattr(self.buffer, name) + + def __setattr__(self, dd): + """default implementation for __setattr__ because unpickling causes infinite + recursion if only __getattr__ is overloaded and __setattr__ is missing""" + self.__dict__ = dd class MultiCapture(object): https://bitbucket.org/hpk42/pytest/commits/e52c087c5ef2/ Changeset: e52c087c5ef2 User: uweschmitt Date: 2014-08-07 17:17:05 Summary: even better fix as replacement for last commit which was wrong Affected #: 1 file diff -r 8a57dee643d74783a9cb8fdb696d83eae6e9370d -r e52c087c5ef2bb1de11b2e9eb119024af16bd425 _pytest/capture.py --- a/_pytest/capture.py +++ b/_pytest/capture.py @@ -240,9 +240,9 @@ def __getattr__(self, name): return getattr(self.buffer, name) - def __setattr__(self, dd): - """default implementation for __setattr__ because unpickling causes infinite - recursion if only __getattr__ is overloaded and __setattr__ is missing""" + def __setstate__(self, dd): + """default implementation for __setstate__ because unpickling causes infinite + recursion if only __getattr__ is overloaded and __setstate__ is missing""" self.__dict__ = dd https://bitbucket.org/hpk42/pytest/commits/d5df0a29b5e4/ Changeset: d5df0a29b5e4 User: uweschmitt Date: 2014-08-11 12:42:36 Summary: hopefully final fix for strange infinite recursion bug Affected #: 1 file diff -r e52c087c5ef2bb1de11b2e9eb119024af16bd425 -r d5df0a29b5e469f793b146b8d5c50ff5eb1da8f9 _pytest/capture.py --- a/_pytest/capture.py +++ b/_pytest/capture.py @@ -238,12 +238,8 @@ self.write(data) def __getattr__(self, name): - return getattr(self.buffer, name) - - def __setstate__(self, dd): - """default implementation for __setstate__ because unpickling causes infinite - recursion if only __getattr__ is overloaded and __setstate__ is missing""" - self.__dict__ = dd + if hasattr(self, "buffer"): + return getattr(self.buffer, name) class MultiCapture(object): https://bitbucket.org/hpk42/pytest/commits/dc070608b6d1/ Changeset: dc070608b6d1 User: uweschmitt Date: 2014-08-11 12:57:47 Summary: hopefully final fix for strange infinite recursion bug Affected #: 2 files diff -r d5df0a29b5e469f793b146b8d5c50ff5eb1da8f9 -r dc070608b6d1a2d2269f7daaa3bde48d02a9a8bd _pytest/capture.py --- a/_pytest/capture.py +++ b/_pytest/capture.py @@ -240,6 +240,8 @@ def __getattr__(self, name): if hasattr(self, "buffer"): return getattr(self.buffer, name) + else: + raise AttributeError("attribute buffer of %r not set" % self) class MultiCapture(object): diff -r d5df0a29b5e469f793b146b8d5c50ff5eb1da8f9 -r dc070608b6d1a2d2269f7daaa3bde48d02a9a8bd _pytest/main.py --- a/_pytest/main.py +++ b/_pytest/main.py @@ -159,6 +159,8 @@ self.config = config def __getattr__(self, name): + if not hasattr(self, "config"): + raise AttributeError("attribute config of %r not set" % self) hookmethod = getattr(self.config.hook, name) def call_matching_hooks(**kwargs): https://bitbucket.org/hpk42/pytest/commits/0a13140a9bf7/ Changeset: 0a13140a9bf7 User: uweschmitt Date: 2014-08-19 12:57:37 Summary: added smoke test for bug fixed in 3716:dc080608b6d1 Affected #: 1 file diff -r dc070608b6d1a2d2269f7daaa3bde48d02a9a8bd -r 0a13140a9bf7fdaddad3d067d9a6ba75b9d5758c testing/test_capture.py --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -1,6 +1,7 @@ # note: py.io capture tests where copied from # pylib 1.4.20.dev2 (rev 13d9af95547e) from __future__ import with_statement +import cPickle import os import sys import py @@ -1022,3 +1023,12 @@ """) reprec = testdir.inline_run() reprec.assertoutcome(passed=1) + + +def test_pickling_and_unpickling_enocded_file(): + # see + # https://bitbucket.org/hpk42/pytest/pull-request/194/fixed-strange-infinite-recursion-bug/diff + ef = capture.EncodedFile(None, None) + ef_as_str = cPickle.dumps(ef) + # this raises infinite recursion if EncodedFile.__getattr__ is not implemented properly: + cPickle.loads(ef_as_str) https://bitbucket.org/hpk42/pytest/commits/b87ba201ec47/ Changeset: b87ba201ec47 User: flub Date: 2014-09-06 00:55:14 Summary: Use py3k compatible .__getattr__() code >From the python-dev thread it seemed like using object.__getattribute__(self, 'name') is the cleanest way of implementing a class wich uses .__getattr__() and should be pickelable. That only works on new-style classes so this also turns HookProxy into a new-style class on py2. This also re-writes the test to not use cPickle so it runs on py3k. Affected #: 4 files diff -r 0a13140a9bf7fdaddad3d067d9a6ba75b9d5758c -r b87ba201ec47b0ba251ecf4f1a7e31f0cd99e29a _pytest/assertion/oldinterpret.py --- a/_pytest/assertion/oldinterpret.py +++ b/_pytest/assertion/oldinterpret.py @@ -57,7 +57,7 @@ def __getattr__(self, attr): # attributes not found in the normal hierarchy rooted on View # are looked up in the object's real class - return getattr(self.__obj__, attr) + return getattr(object.__getattribute__(self, '__obj__'), attr) def __viewkey__(self): return self.__obj__.__class__ diff -r 0a13140a9bf7fdaddad3d067d9a6ba75b9d5758c -r b87ba201ec47b0ba251ecf4f1a7e31f0cd99e29a _pytest/capture.py --- a/_pytest/capture.py +++ b/_pytest/capture.py @@ -238,10 +238,7 @@ self.write(data) def __getattr__(self, name): - if hasattr(self, "buffer"): - return getattr(self.buffer, name) - else: - raise AttributeError("attribute buffer of %r not set" % self) + return getattr(object.__getattribute__(self, "buffer"), name) class MultiCapture(object): diff -r 0a13140a9bf7fdaddad3d067d9a6ba75b9d5758c -r b87ba201ec47b0ba251ecf4f1a7e31f0cd99e29a _pytest/main.py --- a/_pytest/main.py +++ b/_pytest/main.py @@ -153,15 +153,14 @@ ignore_paths.extend([py.path.local(x) for x in excludeopt]) return path in ignore_paths -class HookProxy: +class HookProxy(object): def __init__(self, fspath, config): self.fspath = fspath self.config = config def __getattr__(self, name): - if not hasattr(self, "config"): - raise AttributeError("attribute config of %r not set" % self) - hookmethod = getattr(self.config.hook, name) + config = object.__getattribute__(self, "config") + hookmethod = getattr(config.hook, name) def call_matching_hooks(**kwargs): plugins = self.config._getmatchingplugins(self.fspath) diff -r 0a13140a9bf7fdaddad3d067d9a6ba75b9d5758c -r b87ba201ec47b0ba251ecf4f1a7e31f0cd99e29a testing/test_capture.py --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -1,7 +1,7 @@ # note: py.io capture tests where copied from # pylib 1.4.20.dev2 (rev 13d9af95547e) from __future__ import with_statement -import cPickle +import pickle import os import sys import py @@ -1026,9 +1026,9 @@ def test_pickling_and_unpickling_enocded_file(): - # see - # https://bitbucket.org/hpk42/pytest/pull-request/194/fixed-strange-infinite-recursion-bug/diff + # See https://bitbucket.org/hpk42/pytest/pull-request/194 + # pickle.loads() raises infinite recursion if + # EncodedFile.__getattr__ is not implemented properly ef = capture.EncodedFile(None, None) - ef_as_str = cPickle.dumps(ef) - # this raises infinite recursion if EncodedFile.__getattr__ is not implemented properly: - cPickle.loads(ef_as_str) + ef_as_str = pickle.dumps(ef) + pickle.loads(ef_as_str) https://bitbucket.org/hpk42/pytest/commits/787f4b5a1fa1/ Changeset: 787f4b5a1fa1 User: flub Date: 2014-09-06 00:57:18 Summary: Merged in uweschmitt/pytest/default (pull request #194) Affected #: 4 files diff -r 2cf48d77a3764a1c3cf47ec3c63a972d35ad63d4 -r 787f4b5a1fa1c72fc513da39661f4dcc340844bd _pytest/assertion/oldinterpret.py --- a/_pytest/assertion/oldinterpret.py +++ b/_pytest/assertion/oldinterpret.py @@ -57,7 +57,7 @@ def __getattr__(self, attr): # attributes not found in the normal hierarchy rooted on View # are looked up in the object's real class - return getattr(self.__obj__, attr) + return getattr(object.__getattribute__(self, '__obj__'), attr) def __viewkey__(self): return self.__obj__.__class__ diff -r 2cf48d77a3764a1c3cf47ec3c63a972d35ad63d4 -r 787f4b5a1fa1c72fc513da39661f4dcc340844bd _pytest/capture.py --- a/_pytest/capture.py +++ b/_pytest/capture.py @@ -238,7 +238,7 @@ self.write(data) def __getattr__(self, name): - return getattr(self.buffer, name) + return getattr(object.__getattribute__(self, "buffer"), name) class MultiCapture(object): diff -r 2cf48d77a3764a1c3cf47ec3c63a972d35ad63d4 -r 787f4b5a1fa1c72fc513da39661f4dcc340844bd _pytest/main.py --- a/_pytest/main.py +++ b/_pytest/main.py @@ -153,13 +153,14 @@ ignore_paths.extend([py.path.local(x) for x in excludeopt]) return path in ignore_paths -class HookProxy: +class HookProxy(object): def __init__(self, fspath, config): self.fspath = fspath self.config = config def __getattr__(self, name): - hookmethod = getattr(self.config.hook, name) + config = object.__getattribute__(self, "config") + hookmethod = getattr(config.hook, name) def call_matching_hooks(**kwargs): plugins = self.config._getmatchingplugins(self.fspath) diff -r 2cf48d77a3764a1c3cf47ec3c63a972d35ad63d4 -r 787f4b5a1fa1c72fc513da39661f4dcc340844bd testing/test_capture.py --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -1,6 +1,7 @@ # note: py.io capture tests where copied from # pylib 1.4.20.dev2 (rev 13d9af95547e) from __future__ import with_statement +import pickle import os import sys import py @@ -1022,3 +1023,12 @@ """) reprec = testdir.inline_run() reprec.assertoutcome(passed=1) + + +def test_pickling_and_unpickling_enocded_file(): + # See https://bitbucket.org/hpk42/pytest/pull-request/194 + # pickle.loads() raises infinite recursion if + # EncodedFile.__getattr__ is not implemented properly + ef = capture.EncodedFile(None, None) + ef_as_str = pickle.dumps(ef) + pickle.loads(ef_as_str) https://bitbucket.org/hpk42/pytest/commits/faacab838caf/ Changeset: faacab838caf User: flub Date: 2014-09-06 01:00:43 Summary: Mention PR #194 in the changelog Affected #: 1 file diff -r 787f4b5a1fa1c72fc513da39661f4dcc340844bd -r faacab838caf54f0f67f7a05b4741516aa5306db CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,9 @@ - fix issue582: fix setuptools example, thanks Laszlo Papp and Ronny Pfannschmidt. +- Fix infinite recursion bug when pickling capture.EncodedFile, thanks + Uwe Schmitt. + 2.6.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 issues-reply at bitbucket.org Sat Sep 6 02:16:03 2014 From: issues-reply at bitbucket.org (Bruno Oliveira) Date: Sat, 06 Sep 2014 00:16:03 -0000 Subject: [Pytest-commit] Issue #584: example/special documentation seems incorrect (hpk42/pytest) Message-ID: <20140906001603.2125.36948@app12.ash-private.bitbucket.org> New issue 584: example/special documentation seems incorrect https://bitbucket.org/hpk42/pytest/issue/584/example-special-documentation-seems Bruno Oliveira: The documentation at http://pytest.org/latest/example/special.html was written in Python 2 because uses `print` as statement, but was generated with Python 3 producing `SyntaxErrors` which don't seem to be intentional. It seems that documentation was generated by some automated process which I'm not familiar with (otherwise the author would have noticed the error), but if someone gives a pointer I will be happy to produce a PR. From commits-noreply at bitbucket.org Sat Sep 6 02:37:58 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 06 Sep 2014 00:37:58 -0000 Subject: [Pytest-commit] commit/pytest: bubenkoff: detalize the plugin development proposal Message-ID: <20140906003758.571.17459@app08.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/18369ad10e3f/ Changeset: 18369ad10e3f Branch: contributing-community User: bubenkoff Date: 2014-09-06 02:37:48 Summary: detalize the plugin development proposal Affected #: 1 file diff -r a71457338b8b8147e1aa138a28c7fb1859a9e995 -r 18369ad10e3f3559dde25a4748c689153be5f64a doc/en/plugins.txt --- a/doc/en/plugins.txt +++ b/doc/en/plugins.txt @@ -123,14 +123,38 @@ External plugin development --------------------------- -Pytest community cares about pytest users, in particular, it's important for the community -to keep all pieces of the pytest ecosystem supported. External plugins are important for +Pytest community cares about pytest users, in particular, it's crucial for the community +to keep all pieces of the pytest ecosystem well supported. External plugins are important for pytest users, as they implement many useful, and sometimes critical features which the pytest core does not implement. +To simplify the plugin development and/or support, it was decided to create teams(companies) on popular code hosting +services (at the moment it's github and bitbucket): + +* ``_: + probably the most popular hosting for pytest plugins + the name ``pytestorg`` is choosen because ``pytest`` was already taken by + some unknown person, who's not active on the github or just doesn't check the email used to register + that organization. +* ``_: + pytest is hosted on the bitbucket, also a lot of pytest plugins are hosted there. + +More code hosting services can be added in the future. + +Community encourages pytest plugin developers to move their plugins under those organizations (eg transfer ownership), +paying with a better support, faster feedback, better discoverability, etc. + +Generic workflow of the ownership transfer looks like: + +* If not a member already, developer asks for a membership in the `pytest plugin developers community` organizations listed above, sending an email to ``_. + +* Developer transfers the ownership of his plugin repository to the organization listed above. + +* Existing organization members will make sure proper write permissions are set up for developer who transfered the ownership to the organization. + Writing a plugin by looking at examples ------------------------------------------------------- +--------------------------------------- .. _`Distribute`: http://pypi.python.org/pypi/distribute .. _`setuptools`: http://pypi.python.org/pypi/setuptools @@ -302,10 +326,10 @@ .. _`well specified hooks`: pytest hook reference -==================================== +===================== Hook specification and validation ------------------------------------------ +--------------------------------- ``pytest`` calls hook functions to implement initialization, running, test execution and reporting. When ``pytest`` loads a plugin it validates 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 Sep 8 10:44:58 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 08 Sep 2014 08:44:58 -0000 Subject: [Pytest-commit] commit/py: hpk42: remove py25 in docs (refs issue52) Message-ID: <20140908084458.16902.3138@app12.ash-private.bitbucket.org> 1 new commit in py: https://bitbucket.org/hpk42/py/commits/53a7bc2b43b8/ Changeset: 53a7bc2b43b8 User: hpk42 Date: 2014-09-08 10:44:49 Summary: remove py25 in docs (refs issue52) Affected #: 2 files diff -r 75ef6111820efd0bd3dd250e069056c219511a43 -r 53a7bc2b43b83211a022f14b3e84bbf9794b14a8 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -2,7 +2,7 @@ ================================================== - fix issue52: vaguely fix py25 compat of py.path.local (it's not - officially supported) + officially supported), also fix docs 1.4.24 ================================================== diff -r 75ef6111820efd0bd3dd250e069056c219511a43 -r 53a7bc2b43b83211a022f14b3e84bbf9794b14a8 doc/install.txt --- a/doc/install.txt +++ b/doc/install.txt @@ -7,7 +7,7 @@ **PyPI name**: py_ -**Pythons**: 2.5, 2.6, 2.7, 3.2, 3.3, Jython-2.5.1, PyPy-2.0 +**Pythons**: CPython 2.6, 2.7, 3.3, 3.4, PyPy-2.3 **Operating systems**: Linux, Windows, OSX, Unix @@ -29,7 +29,7 @@ will trigger an upgrade if you already have an older version installed. .. note:: - + As of version 1.4 py does not contain py.test anymore - you need to install the new `pytest`_ distribution. 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 Sep 8 11:33:19 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 08 Sep 2014 09:33:19 -0000 Subject: [Pytest-commit] commit/pytest: flub: Remove jython from tested python versions Message-ID: <20140908093319.7756.98492@app10.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/c07682cb75eb/ Changeset: c07682cb75eb User: flub Date: 2014-09-06 19:44:18 Summary: Remove jython from tested python versions After testing with the jython 2.7 beta it seems it will require some work to get jython back working. So for now remove it from this list so it doesn't get picked up by normal test runs. Affected #: 1 file diff -r faacab838caf54f0f67f7a05b4741516aa5306db -r c07682cb75ebe46ad79de86b9689cefb4b69f78d testing/conftest.py --- a/testing/conftest.py +++ b/testing/conftest.py @@ -103,7 +103,7 @@ return executable @pytest.fixture(params=['python2.6', 'python2.7', 'python3.3', "python3.4", - 'pypy', 'pypy3', 'jython']) + 'pypy', 'pypy3']) def anypython(request): name = request.param executable = getexecutable(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 issues-reply at bitbucket.org Mon Sep 8 12:37:38 2014 From: issues-reply at bitbucket.org (Barry Fitzgerald) Date: Mon, 08 Sep 2014 10:37:38 -0000 Subject: [Pytest-commit] Issue #585: Add support for exclusive tests (hpk42/pytest) Message-ID: <20140908103738.20021.66277@app01.ash-private.bitbucket.org> New issue 585: Add support for exclusive tests https://bitbucket.org/hpk42/pytest/issue/585/add-support-for-exclusive-tests Barry Fitzgerald: Allowing exclusive tests can give a quicker workflow when debugging a single failing test. This would work like this - if I appended "only_" to any of my test functions only these tests in the current module would be run. Would this functionality be accepted as a pull request? See: http://tobyho.com/2012/09/12/better-tdd-workflow-via-exclusive-tests-in-jasmine-and-mocha/ for example of this in other test frameworks. From issues-reply at bitbucket.org Mon Sep 8 15:22:36 2014 From: issues-reply at bitbucket.org (Laszlo Papp) Date: Mon, 08 Sep 2014 13:22:36 -0000 Subject: [Pytest-commit] Issue #586: python.raises examples are unclear (hpk42/pytest) Message-ID: <20140908132236.11459.15566@app13.ash-private.bitbucket.org> New issue 586: python.raises examples are unclear https://bitbucket.org/hpk42/pytest/issue/586/pythonraises-examples-are-unclear Laszlo Papp: >From the following page: http://pytest.org/latest/assert.html ``` #!python import pytest with pytest.raises(ZeroDivisionError): 1 / 0 ``` and ``` #!python with pytest.raises(RuntimeError) as excinfo: def f(): f() f() # do checks related to excinfo.type, excinfo.value, excinfo.traceback ``` My first thoughts have been: * Is it really a good idea to use global "with" context management here? * If yes, because it is better to wrap the 'f' function around in one place rather than at each call, why is it not done like a decorator, nicely? But then, I was enlightened that this ought to be inside a test function, yet it has not been clear to me, especially since the former example was right after an import. Yes, I am aware of that import can happen anywhere in python, but it was not my first thought that pytest would be imported somewhere in a test function rather than outside "globally". I think it would be nice to make these examples a bit clearer. Responsible: flub From commits-noreply at bitbucket.org Mon Sep 8 15:53:00 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 08 Sep 2014 13:53:00 -0000 Subject: [Pytest-commit] commit/pytest: flub: Improve pytest.raises examples Message-ID: <20140908135300.29058.96231@app12.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/bbc15902ae03/ Changeset: bbc15902ae03 User: flub Date: 2014-09-08 15:26:31 Summary: Improve pytest.raises examples Fixes issue #586. Affected #: 1 file diff -r c07682cb75ebe46ad79de86b9689cefb4b69f78d -r bbc15902ae03b5efe0b0afdfb37cd1796426ba0a doc/en/assert.txt --- a/doc/en/assert.txt +++ b/doc/en/assert.txt @@ -66,20 +66,23 @@ ``pytest.raises`` as a context manager like this:: import pytest - with pytest.raises(ZeroDivisionError): - 1 / 0 + + def test_zero_division(): + with pytest.raises(ZeroDivisionError): + 1 / 0 and if you need to have access to the actual exception info you may use:: - with pytest.raises(RuntimeError) as excinfo: - def f(): + def test_recursion_depth(): + with pytest.raises(RuntimeError) as excinfo: + def f(): + f() f() - f() - - # do checks related to excinfo.type, excinfo.value, excinfo.traceback + assert 'maximum recursion' in str(excinfo.value) ``excinfo`` is a `py.code.ExceptionInfo`_ instance, which is a wrapper around -the actual exception raised. +the actual exception raised. The main attributes of interest are +``.type``, ``.value`` and ``.traceback``. .. _py.code.ExceptionInfo: http://pylib.readthedocs.org/en/latest/code.html#py-code-exceptioninfo 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 issues-reply at bitbucket.org Mon Sep 8 17:32:45 2014 From: issues-reply at bitbucket.org (Alex Corcoles) Date: Mon, 08 Sep 2014 15:32:45 -0000 Subject: [Pytest-commit] Issue #186: Exclude generative environments (hpk42/tox) Message-ID: <20140908153245.6043.52437@app05.ash-private.bitbucket.org> New issue 186: Exclude generative environments https://bitbucket.org/hpk42/tox/issue/186/exclude-generative-environments Alex Corcoles: Hi, We're using the tox 1.8 prerelease to take advantage of generative environments, in order to for instance test our apps on py26 and py27 x django16 and django17 However, due to django17 not being supported on py26, we've had to resort to changing 'commands' for that environment to true so that it succeeds. Would it be possible to exclude some combinations from being considered in a cleaner way? Cheers, ?lex From issues-reply at bitbucket.org Mon Sep 8 23:37:27 2014 From: issues-reply at bitbucket.org (sscarwell) Date: Mon, 08 Sep 2014 21:37:27 -0000 Subject: [Pytest-commit] Issue #587: type "byte" is incompatible with python 2.5 (hpk42/pytest) Message-ID: <20140908213727.18595.83605@app12.ash-private.bitbucket.org> New issue 587: type "byte" is incompatible with python 2.5 https://bitbucket.org/hpk42/pytest/issue/587/type-byte-is-incompatible-with-python-25 sscarwell: The code contains the new keyword/alias **bytes**. In file ./pytest-2.6.2/_pytest/capture.py(line 355): ``` #!python isinstance(res, bytes) ``` The type "bytes" is not recognised by python 2.5.2. Everywhere else in the code, **bytes** is referenced as **py.builtin.bytes**. So I think a fix would be to replace bytes by py.builtin.bytes in capture.py. From commits-noreply at bitbucket.org Tue Sep 9 11:22:48 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 09 Sep 2014 09:22:48 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: fix issue587: claim only python2.6 compat in README/pypi project page, thanks sscarwell Message-ID: <20140909092248.29801.35989@app07.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/013e13382011/ Changeset: 013e13382011 User: hpk42 Date: 2014-09-09 11:22:39 Summary: fix issue587: claim only python2.6 compat in README/pypi project page, thanks sscarwell Affected #: 1 file diff -r bbc15902ae03b5efe0b0afdfb37cd1796426ba0a -r 013e1338201118fb7399f6a3c29d8f754502ba92 README.rst --- a/README.rst +++ b/README.rst @@ -19,8 +19,9 @@ - multi-paradigm support: you can use ``pytest`` to run test suites based on `unittest `_ (or trial), `nose `_ -- single-source compatibility to Python2.5 all the way up to Python3.4, - PyPy-2.3 and Jython-2.5.1. +- single-source compatibility from Python2.6 all the way up to + Python3.4, PyPy-2.3, (jython-2.5 untested) + - many `external plugins `_. 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 Sep 10 02:10:35 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 10 Sep 2014 00:10:35 -0000 Subject: [Pytest-commit] commit/pytest-xdist: bubenkoff: Merged in nicoddemus/pytest-xdist/log-collection-diff (pull request #9) Message-ID: <20140910001035.5402.2603@app10.ash-private.bitbucket.org> 1 new commit in pytest-xdist: https://bitbucket.org/hpk42/pytest-xdist/commits/84adc54b0ce9/ Changeset: 84adc54b0ce9 User: bubenkoff Date: 2014-09-10 02:10:32 Summary: Merged in nicoddemus/pytest-xdist/log-collection-diff (pull request #9) Log different tests collected by slaves instead of an error Affected #: 3 files diff -r 4c6c3926603135015691bcf537ed8dfe15b59874 -r 84adc54b0ce93d037ce3cac06a623bce3f599107 testing/acceptance_test.py --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -310,9 +310,9 @@ """) result = testdir.runpytest("-n1", "-v") result.stdout.fnmatch_lines_random([ - "*PASS*test_pass_skip_fail.py?2*test_ok*", - "*SKIP*test_pass_skip_fail.py?4*test_skip*", - "*FAIL*test_pass_skip_fail.py?6*test_func*", + "*PASS*test_pass_skip_fail.py*test_ok*", + "*SKIP*test_pass_skip_fail.py*test_skip*", + "*FAIL*test_pass_skip_fail.py*test_func*", ]) result.stdout.fnmatch_lines([ "*def test_func():", @@ -327,7 +327,7 @@ """) result = testdir.runpytest("-n1", "-v") result.stdout.fnmatch_lines([ - "*FAIL*test_fail_platinfo.py*1*test_func*", + "*FAIL*test_fail_platinfo.py*test_func*", "*0*Python*", "*def test_func():", "> assert 0", diff -r 4c6c3926603135015691bcf537ed8dfe15b59874 -r 84adc54b0ce93d037ce3cac06a623bce3f599107 testing/test_dsession.py --- a/testing/test_dsession.py +++ b/testing/test_dsession.py @@ -146,6 +146,25 @@ crashitem = sched.remove_node(node) assert crashitem == collection[0] + def test_schedule_different_tests_collected(self): + """ + Test that LoadScheduling is logging different tests were + collected by slaves when that happens. + """ + node1 = MockNode() + node2 = MockNode() + sched = LoadScheduling(2) + logged_messages = [] + py.log.setconsumer('loadsched', logged_messages.append) + sched.addnode(node1) + sched.addnode(node2) + sched.addnode_collection(node1, ["a.py::test_1"]) + sched.addnode_collection(node2, ["a.py::test_2"]) + sched.init_distribute() + logged_content = ''.join(x.content() for x in logged_messages) + assert 'Different tests were collected between' in logged_content + assert 'Different tests collected, aborting run' in logged_content + class TestDistReporter: @@ -181,7 +200,7 @@ def test_report_collection_diff_equal(): """Test reporting of equal collections.""" from_collection = to_collection = ['aaa', 'bbb', 'ccc'] - assert report_collection_diff(from_collection, to_collection, 1, 2) + assert report_collection_diff(from_collection, to_collection, 1, 2) is None def test_report_collection_diff_different(): @@ -204,10 +223,8 @@ '-YYY' ) - try: - report_collection_diff(from_collection, to_collection, 1, 2) - except AssertionError as e: - assert py.builtin._totext(e) == error_message + msg = report_collection_diff(from_collection, to_collection, 1, 2) + assert msg == error_message @pytest.mark.xfail(reason="duplicate test ids not supported yet") def test_pytest_issue419(testdir): diff -r 4c6c3926603135015691bcf537ed8dfe15b59874 -r 84adc54b0ce93d037ce3cac06a623bce3f599107 xdist/dsession.py --- a/xdist/dsession.py +++ b/xdist/dsession.py @@ -17,7 +17,7 @@ if log is None: self.log = py.log.Producer("eachsched") else: - self.log = log.loadsched + self.log = log.eachsched self.collection_is_completed = False def hasnodes(self): @@ -139,22 +139,17 @@ def init_distribute(self): assert self.collection_is_completed # XXX allow nodes to have different collections - node_collection_items = list(self.node2collection.items()) - first_node, col = node_collection_items[0] - for node, collection in node_collection_items[1:]: - report_collection_diff( - col, - collection, - first_node.gateway.id, - node.gateway.id, - ) + if not self._check_nodes_have_same_collection(): + self.log('**Different tests collected, aborting run**') + return # all collections are the same, good. # we now create an index - self.collection = col - self.pending[:] = range(len(col)) - if not col: + self.collection = list(self.node2collection.values())[0] + self.pending[:] = range(len(self.collection)) + if not self.collection: return + # how many items per node do we have about? items_per_node = len(self.collection) // len(self.node2pending) # take a fraction of tests for initial distribution @@ -172,17 +167,36 @@ self.node2pending[node].extend(tests_per_node) node.send_runtest_some(tests_per_node) + def _check_nodes_have_same_collection(self): + """ + Return True if all nodes have collected the same items, False otherwise. + This method also logs the collection differences as they are found. + """ + node_collection_items = list(self.node2collection.items()) + first_node, col = node_collection_items[0] + same_collection = True + for node, collection in node_collection_items[1:]: + msg = report_collection_diff( + col, + collection, + first_node.gateway.id, + node.gateway.id, + ) + if msg: + self.log(msg) + same_collection = False + + return same_collection + + def report_collection_diff(from_collection, to_collection, from_id, to_id): """Report the collected test difference between two nodes. - :returns: True if collections are equal. - - :raises: AssertionError with a detailed error message describing the - difference between the collections. - + :returns: detailed message describing the difference between the given + collections, or None if they are equal. """ if from_collection == to_collection: - return True + return None diff = difflib.unified_diff( from_collection, @@ -196,7 +210,7 @@ '{diff}' ).format(from_id=from_id, to_id=to_id, diff='\n'.join(diff)) msg = "\n".join([x.rstrip() for x in error_message.split("\n")]) - raise AssertionError(msg) + return msg class Interrupted(KeyboardInterrupt): 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 Wed Sep 10 02:10:35 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 10 Sep 2014 00:10:35 -0000 Subject: [Pytest-commit] commit/pytest-xdist: 3 new changesets Message-ID: <20140910001035.27077.67838@app08.ash-private.bitbucket.org> 3 new commits in pytest-xdist: https://bitbucket.org/hpk42/pytest-xdist/commits/09aa37340244/ Changeset: 09aa37340244 Branch: log-collection-diff User: nicoddemus Date: 2014-08-03 01:59:45 Summary: Log different tests collected by slaves instead of an error This is a proposal to fix #556. Affected #: 2 files diff -r 4c6c3926603135015691bcf537ed8dfe15b59874 -r 09aa37340244997f7f32621ece15094f582da482 testing/test_dsession.py --- a/testing/test_dsession.py +++ b/testing/test_dsession.py @@ -146,6 +146,25 @@ crashitem = sched.remove_node(node) assert crashitem == collection[0] + def test_schedule_different_tests_collected(self): + """ + Test that LoadScheduling is logging different tests were + collected by slaves when that happens. + """ + node1 = MockNode() + node2 = MockNode() + sched = LoadScheduling(2) + logged_messages = [] + py.log.setconsumer('loadsched', logged_messages.append) + sched.addnode(node1) + sched.addnode(node2) + sched.addnode_collection(node1, ["a.py::test_1"]) + sched.addnode_collection(node2, ["a.py::test_2"]) + sched.init_distribute() + logged_content = ''.join(x.content() for x in logged_messages) + assert 'Different tests were collected between' in logged_content + assert 'Different tests collected, aborting run' in logged_content + class TestDistReporter: @@ -181,7 +200,7 @@ def test_report_collection_diff_equal(): """Test reporting of equal collections.""" from_collection = to_collection = ['aaa', 'bbb', 'ccc'] - assert report_collection_diff(from_collection, to_collection, 1, 2) + assert report_collection_diff(from_collection, to_collection, 1, 2) is None def test_report_collection_diff_different(): @@ -204,10 +223,8 @@ '-YYY' ) - try: - report_collection_diff(from_collection, to_collection, 1, 2) - except AssertionError as e: - assert py.builtin._totext(e) == error_message + msg = report_collection_diff(from_collection, to_collection, 1, 2) + assert msg == error_message @pytest.mark.xfail(reason="duplicate test ids not supported yet") def test_pytest_issue419(testdir): diff -r 4c6c3926603135015691bcf537ed8dfe15b59874 -r 09aa37340244997f7f32621ece15094f582da482 xdist/dsession.py --- a/xdist/dsession.py +++ b/xdist/dsession.py @@ -17,7 +17,7 @@ if log is None: self.log = py.log.Producer("eachsched") else: - self.log = log.loadsched + self.log = log.eachsched self.collection_is_completed = False def hasnodes(self): @@ -139,22 +139,17 @@ def init_distribute(self): assert self.collection_is_completed # XXX allow nodes to have different collections - node_collection_items = list(self.node2collection.items()) - first_node, col = node_collection_items[0] - for node, collection in node_collection_items[1:]: - report_collection_diff( - col, - collection, - first_node.gateway.id, - node.gateway.id, - ) + if not self._check_nodes_have_same_collection(): + self.log('**Different tests collected, aborting run**') + return # all collections are the same, good. # we now create an index - self.collection = col - self.pending[:] = range(len(col)) - if not col: + self.collection = list(self.node2collection.values())[0] + self.pending[:] = range(len(self.collection)) + if not self.collection: return + # how many items per node do we have about? items_per_node = len(self.collection) // len(self.node2pending) # take a fraction of tests for initial distribution @@ -172,17 +167,36 @@ self.node2pending[node].extend(tests_per_node) node.send_runtest_some(tests_per_node) + def _check_nodes_have_same_collection(self): + """ + Return True if all nodes have collected the same items, False otherwise. + This method also logs the collection differences as they are found. + """ + node_collection_items = list(self.node2collection.items()) + first_node, col = node_collection_items[0] + same_collection = True + for node, collection in node_collection_items[1:]: + msg = report_collection_diff( + col, + collection, + first_node.gateway.id, + node.gateway.id, + ) + if msg: + self.log(msg) + same_collection = False + + return same_collection + + def report_collection_diff(from_collection, to_collection, from_id, to_id): """Report the collected test difference between two nodes. - :returns: True if collections are equal. - - :raises: AssertionError with a detailed error message describing the - difference between the collections. - + :returns: detailed message describing the difference between the given + collections, or None if they are equal. """ if from_collection == to_collection: - return True + return None diff = difflib.unified_diff( from_collection, @@ -196,7 +210,7 @@ '{diff}' ).format(from_id=from_id, to_id=to_id, diff='\n'.join(diff)) msg = "\n".join([x.rstrip() for x in error_message.split("\n")]) - raise AssertionError(msg) + return msg class Interrupted(KeyboardInterrupt): https://bitbucket.org/hpk42/pytest-xdist/commits/70087ffdd1f8/ Changeset: 70087ffdd1f8 Branch: log-collection-diff User: nicoddemus Date: 2014-09-10 01:28:16 Summary: fixed tests removing line numbers from output Pytest no longer show line numbers in the --verbose output Affected #: 1 file diff -r 09aa37340244997f7f32621ece15094f582da482 -r 70087ffdd1f8ef180e9edfa182e71c0e6fb02520 testing/acceptance_test.py --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -310,9 +310,9 @@ """) result = testdir.runpytest("-n1", "-v") result.stdout.fnmatch_lines_random([ - "*PASS*test_pass_skip_fail.py?2*test_ok*", - "*SKIP*test_pass_skip_fail.py?4*test_skip*", - "*FAIL*test_pass_skip_fail.py?6*test_func*", + "*PASS*test_pass_skip_fail.py*test_ok*", + "*SKIP*test_pass_skip_fail.py*test_skip*", + "*FAIL*test_pass_skip_fail.py*test_func*", ]) result.stdout.fnmatch_lines([ "*def test_func():", @@ -327,7 +327,7 @@ """) result = testdir.runpytest("-n1", "-v") result.stdout.fnmatch_lines([ - "*FAIL*test_fail_platinfo.py*1*test_func*", + "*FAIL*test_fail_platinfo.py*test_func*", "*0*Python*", "*def test_func():", "> assert 0", https://bitbucket.org/hpk42/pytest-xdist/commits/84adc54b0ce9/ Changeset: 84adc54b0ce9 User: bubenkoff Date: 2014-09-10 02:10:32 Summary: Merged in nicoddemus/pytest-xdist/log-collection-diff (pull request #9) Log different tests collected by slaves instead of an error Affected #: 3 files diff -r 4c6c3926603135015691bcf537ed8dfe15b59874 -r 84adc54b0ce93d037ce3cac06a623bce3f599107 testing/acceptance_test.py --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -310,9 +310,9 @@ """) result = testdir.runpytest("-n1", "-v") result.stdout.fnmatch_lines_random([ - "*PASS*test_pass_skip_fail.py?2*test_ok*", - "*SKIP*test_pass_skip_fail.py?4*test_skip*", - "*FAIL*test_pass_skip_fail.py?6*test_func*", + "*PASS*test_pass_skip_fail.py*test_ok*", + "*SKIP*test_pass_skip_fail.py*test_skip*", + "*FAIL*test_pass_skip_fail.py*test_func*", ]) result.stdout.fnmatch_lines([ "*def test_func():", @@ -327,7 +327,7 @@ """) result = testdir.runpytest("-n1", "-v") result.stdout.fnmatch_lines([ - "*FAIL*test_fail_platinfo.py*1*test_func*", + "*FAIL*test_fail_platinfo.py*test_func*", "*0*Python*", "*def test_func():", "> assert 0", diff -r 4c6c3926603135015691bcf537ed8dfe15b59874 -r 84adc54b0ce93d037ce3cac06a623bce3f599107 testing/test_dsession.py --- a/testing/test_dsession.py +++ b/testing/test_dsession.py @@ -146,6 +146,25 @@ crashitem = sched.remove_node(node) assert crashitem == collection[0] + def test_schedule_different_tests_collected(self): + """ + Test that LoadScheduling is logging different tests were + collected by slaves when that happens. + """ + node1 = MockNode() + node2 = MockNode() + sched = LoadScheduling(2) + logged_messages = [] + py.log.setconsumer('loadsched', logged_messages.append) + sched.addnode(node1) + sched.addnode(node2) + sched.addnode_collection(node1, ["a.py::test_1"]) + sched.addnode_collection(node2, ["a.py::test_2"]) + sched.init_distribute() + logged_content = ''.join(x.content() for x in logged_messages) + assert 'Different tests were collected between' in logged_content + assert 'Different tests collected, aborting run' in logged_content + class TestDistReporter: @@ -181,7 +200,7 @@ def test_report_collection_diff_equal(): """Test reporting of equal collections.""" from_collection = to_collection = ['aaa', 'bbb', 'ccc'] - assert report_collection_diff(from_collection, to_collection, 1, 2) + assert report_collection_diff(from_collection, to_collection, 1, 2) is None def test_report_collection_diff_different(): @@ -204,10 +223,8 @@ '-YYY' ) - try: - report_collection_diff(from_collection, to_collection, 1, 2) - except AssertionError as e: - assert py.builtin._totext(e) == error_message + msg = report_collection_diff(from_collection, to_collection, 1, 2) + assert msg == error_message @pytest.mark.xfail(reason="duplicate test ids not supported yet") def test_pytest_issue419(testdir): diff -r 4c6c3926603135015691bcf537ed8dfe15b59874 -r 84adc54b0ce93d037ce3cac06a623bce3f599107 xdist/dsession.py --- a/xdist/dsession.py +++ b/xdist/dsession.py @@ -17,7 +17,7 @@ if log is None: self.log = py.log.Producer("eachsched") else: - self.log = log.loadsched + self.log = log.eachsched self.collection_is_completed = False def hasnodes(self): @@ -139,22 +139,17 @@ def init_distribute(self): assert self.collection_is_completed # XXX allow nodes to have different collections - node_collection_items = list(self.node2collection.items()) - first_node, col = node_collection_items[0] - for node, collection in node_collection_items[1:]: - report_collection_diff( - col, - collection, - first_node.gateway.id, - node.gateway.id, - ) + if not self._check_nodes_have_same_collection(): + self.log('**Different tests collected, aborting run**') + return # all collections are the same, good. # we now create an index - self.collection = col - self.pending[:] = range(len(col)) - if not col: + self.collection = list(self.node2collection.values())[0] + self.pending[:] = range(len(self.collection)) + if not self.collection: return + # how many items per node do we have about? items_per_node = len(self.collection) // len(self.node2pending) # take a fraction of tests for initial distribution @@ -172,17 +167,36 @@ self.node2pending[node].extend(tests_per_node) node.send_runtest_some(tests_per_node) + def _check_nodes_have_same_collection(self): + """ + Return True if all nodes have collected the same items, False otherwise. + This method also logs the collection differences as they are found. + """ + node_collection_items = list(self.node2collection.items()) + first_node, col = node_collection_items[0] + same_collection = True + for node, collection in node_collection_items[1:]: + msg = report_collection_diff( + col, + collection, + first_node.gateway.id, + node.gateway.id, + ) + if msg: + self.log(msg) + same_collection = False + + return same_collection + + def report_collection_diff(from_collection, to_collection, from_id, to_id): """Report the collected test difference between two nodes. - :returns: True if collections are equal. - - :raises: AssertionError with a detailed error message describing the - difference between the collections. - + :returns: detailed message describing the difference between the given + collections, or None if they are equal. """ if from_collection == to_collection: - return True + return None diff = difflib.unified_diff( from_collection, @@ -196,7 +210,7 @@ '{diff}' ).format(from_id=from_id, to_id=to_id, diff='\n'.join(diff)) msg = "\n".join([x.rstrip() for x in error_message.split("\n")]) - raise AssertionError(msg) + return msg class Interrupted(KeyboardInterrupt): 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 Wed Sep 10 09:57:22 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 10 Sep 2014 07:57:22 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: fix a broken link Message-ID: <20140910075722.20938.49523@app03.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/ac71ee79ffa7/ Changeset: ac71ee79ffa7 User: hpk42 Date: 2014-09-10 09:57:12 Summary: fix a broken link Affected #: 1 file diff -r 013e1338201118fb7399f6a3c29d8f754502ba92 -r ac71ee79ffa764c925f2d72ea13b9d2e68eb83de doc/en/goodpractises.txt --- a/doc/en/goodpractises.txt +++ b/doc/en/goodpractises.txt @@ -276,7 +276,7 @@ * collection starts from the initial command line arguments which may be directories, filenames or test ids. * recurse into directories, unless they match :confval:`norecursedirs` -* ``test_*.py`` or ``*_test.py`` files, imported by their `package name`_. +* ``test_*.py`` or ``*_test.py`` files, imported by their `test package name`_. * ``Test`` prefixed test classes (without an ``__init__`` method) * ``test_`` prefixed test functions or methods are test items 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 issues-reply at bitbucket.org Thu Sep 11 13:44:13 2014 From: issues-reply at bitbucket.org (Ib Lundgren) Date: Thu, 11 Sep 2014 11:44:13 -0000 Subject: [Pytest-commit] Issue #187: Use tox to run tests on downstream libraries (hpk42/tox) Message-ID: <20140911114413.31803.52010@app05.ash-private.bitbucket.org> New issue 187: Use tox to run tests on downstream libraries https://bitbucket.org/hpk42/tox/issue/187/use-tox-to-run-tests-on-downstream Ib Lundgren: Hello, I currently use tox for testing across Python versions and it's great. Now I would like to make sure that when I update my library I don't break downstream libraries or at least know in what way they break. For example, if I develop django and want to check if my changes break django-rest-framework I'd have a tox.ini with something like ``` [downstream] repositories= github.com/tomchristie/django-rest-framework bitbucket.org/foo/django-bar ``` Tox could then clone each repo and run a "sub-tox" inside each so all results are collected together (main lib + downstream). Naturally, the "sub-tox" would install the repo dependencies as specified in respective tox.ini with the exception of my library for which it would use the local version. Suggestions for how I may achieve this? Update tox with these features? If so where? Or rather let tox be and roll a shell script? Already possible but I don't know how? Cheers From issues-reply at bitbucket.org Thu Sep 11 16:23:18 2014 From: issues-reply at bitbucket.org (Jeff Weiss) Date: Thu, 11 Sep 2014 14:23:18 -0000 Subject: [Pytest-commit] Issue #588: pytest_exception_interact runs AFTER finally clauses, should be before (hpk42/pytest) Message-ID: <20140911142318.18890.2485@app03.ash-private.bitbucket.org> New issue 588: pytest_exception_interact runs AFTER finally clauses, should be before https://bitbucket.org/hpk42/pytest/issue/588/pytest_exception_interact-runs-after Jeff Weiss: def test_mytest(): try: errorprone() finally: cleanup() If I define a pytest_exception_interact, it runs AFTER the cleanup(), should be before. From issues-reply at bitbucket.org Fri Sep 12 19:10:13 2014 From: issues-reply at bitbucket.org (Charles Cloud) Date: Fri, 12 Sep 2014 17:10:13 -0000 Subject: [Pytest-commit] Issue #589: pytest incorrectly considers NotImplementedError when detecting recursion (hpk42/pytest) Message-ID: <20140912171013.14124.83811@app04.ash-private.bitbucket.org> New issue 589: pytest incorrectly considers NotImplementedError when detecting recursion https://bitbucket.org/hpk42/pytest/issue/589/pytest-incorrectly-considers Charles Cloud: Here's an example where this happens: ```python import operator class EqList(list): def __init__(self, *args): super(EqList, self).__init__(*args) def __nonzero__(self): raise ValueError('this is what numpy does') def __bool__(self): if len(self) > 1: return self.__nonzero__() return bool(len(self)) def __eq__(self, other): if not isinstance(other, EqList): return EqList([False] * len(self)) return EqList(map(operator.eq, list(self), list(other))) _typecache = {} def dispatch(*types): def wrapper(f): _typecache[types] = f def wrapped(*args, **kwargs): func = _typecache[tuple(map(type, args))] return func(*args, **kwargs) return wrapped return wrapper @dispatch(object) def flatten(o): return [o] @dispatch(tuple) def flatten(t): return flatten(list(t)) @dispatch(EqList) def flatten(s): raise NotImplementedError('EqList bork') @dispatch(list) def flatten(lst): for el in lst: for e in flatten(el): yield e def test_flatten(): r = EqList([1, 2, 3]) x = list(flatten([(r,)])) assert x is not None if __name__ == '__main__': test_flatten() ``` The issue is the interaction between 1. `py.test` checking for `NotImplementedError` when detecting recursion followed by 2. comparison of variables in scope between a function appearing to be recursive and 3. any variables in said scopes that do not return a scalar `bool` from their `__eq__` method. The above code should raise `NotImplementedError`, not a huge `INTERNALERROR` traceback because it couldn't compare variables when trying to detect recursion. Running with ```sh $ python above_file.py ``` does the right thing, while ```sh $ py.test above_file.py ``` yields a huge `INTERNALERROR` traceback ending in: ``` INTERNALERROR> File "/Users/pcloud/test_pytest.py", line 15, in __bool__ INTERNALERROR> return self.__nonzero__() INTERNALERROR> File "/Users/pcloud/test_pytest.py", line 11, in __nonzero__ INTERNALERROR> raise ValueError('this is what numpy does') INTERNALERROR> ValueError: this is what numpy does ``` I propose that instead of checking for general `RuntimeError`s (which includes subclasses), that `py.test` check for the *exact* type of `RuntimeError`. `NotImplementedError` doesn't seem like an exception that would indicate recursion. From issues-reply at bitbucket.org Sat Sep 13 16:09:45 2014 From: issues-reply at bitbucket.org (Wolfgang Schnerring) Date: Sat, 13 Sep 2014 14:09:45 -0000 Subject: [Pytest-commit] Issue #590: Remove stale bytecode files (hpk42/pytest) Message-ID: <20140913140945.6494.74211@app11.ash-private.bitbucket.org> New issue 590: Remove stale bytecode files https://bitbucket.org/hpk42/pytest/issue/590/remove-stale-bytecode-files Wolfgang Schnerring: The situation is rather rare (when switching between branches for example) that you get obsolete .pyc/.pyo files, i.e. without corresponding .py files, but when it occurs it can lead to obscure and really hard to detect problems. So it might be a worthwile feature to clean those up automatically ([zope.testrunner does this](https://github.com/zopefoundation/zope.testrunner/blob/master/src/zope/testrunner/find.py#L348) for example). From commits-noreply at bitbucket.org Sun Sep 14 17:25:11 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sun, 14 Sep 2014 15:25:11 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: fix issue589: fix bad interaction with numpy and others when showing Message-ID: <20140914152511.12652.83866@app14.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/2ae2ef6e63fc/ Changeset: 2ae2ef6e63fc User: hpk42 Date: 2014-09-14 17:24:27 Summary: fix issue589: fix bad interaction with numpy and others when showing exceptions. check for precise "maximum recursion depth exceed" exception instead of presuming any RuntimeError is that one (implemented in py dep) Thanks Charles Cloud for analysing the issue. Affected #: 2 files diff -r ac71ee79ffa764c925f2d72ea13b9d2e68eb83de -r 2ae2ef6e63fc0f25ef44cca9d4c2ddcebd41ffc9 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,11 @@ - Fix infinite recursion bug when pickling capture.EncodedFile, thanks Uwe Schmitt. +- fix issue589: fix bad interaction with numpy and others when showing + exceptions. Check for precise "maximum recursion depth exceed" exception + instead of presuming any RuntimeError is that one (implemented in py + dep). Thanks Charles Cloud for analysing the issue. + 2.6.2 ----------- diff -r ac71ee79ffa764c925f2d72ea13b9d2e68eb83de -r 2ae2ef6e63fc0f25ef44cca9d4c2ddcebd41ffc9 setup.py --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ def main(): - install_requires = ['py>=1.4.24'] + install_requires = ['py>=1.4.25.dev2'] if sys.version_info < (2, 7) or (3,) <= sys.version_info < (3, 2): install_requires.append('argparse') if sys.platform == '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 issues-reply at bitbucket.org Sun Sep 14 17:35:52 2014 From: issues-reply at bitbucket.org (Mike Bayer) Date: Sun, 14 Sep 2014 15:35:52 -0000 Subject: [Pytest-commit] Issue #188: multi-dimensional syntax doesn't work for recreate (others?) (hpk42/tox) Message-ID: <20140914153552.21640.88360@app13.ash-private.bitbucket.org> New issue 188: multi-dimensional syntax doesn't work for recreate (others?) https://bitbucket.org/hpk42/tox/issue/188/multi-dimensional-syntax-doesnt-work-for Mike Bayer: Doing well with 1.8's multidimensional feature. However it does not seem to work for the "recreate" flag- this is a scalar, not a list, key, but as the docs say the feature should work for "basepython" it would seem this should work: ``` #! [tox] minversion=1.8.dev1 envlist = py{27,33}-sqla{079,084,09,10}, coverage [testenv] deps=pytest mock sqla079: git+http://git.sqlalchemy.org/sqlalchemy.git at rel_0_7_9 sqla084: git+http://git.sqlalchemy.org/sqlalchemy.git at rel_0_8_4 sqla09: git+http://git.sqlalchemy.org/sqlalchemy.git at rel_0_9 sqla10: git+http://git.sqlalchemy.org/sqlalchemy.git at master # this is the part that fails, tried py{27,33}-sqla{10}, etc. and many # other combinations, tried fixing in _config.py source... no dice recreate= sqla10: True sitepackages=True usedevelop=True commands= py{27,33}-sqla{084,09,10}: python -m pytest -n 4 {posargs} py{27,33}-sqla{079}: python -m pytest {posargs} ``` with the recreate directive using a multidimensional value I get: ``` #! Traceback (most recent call last): File "/Library/Frameworks/Python.framework/Versions/2.7/bin/tox", line 9, in load_entry_point('tox==1.8.0.dev1', 'console_scripts', 'tox')() File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tox/_cmdline.py", line 25, in main config = parseconfig(args, 'tox') File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tox/_config.py", line 42, in parseconfig parseini(config, inipath) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tox/_config.py", line 293, in __init__ self._makeenvconfig(name, section, reader._subs, config) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tox/_config.py", line 337, in _makeenvconfig vc.recreate = reader.getbool(section, "recreate", False) File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tox/_config.py", line 609, in getbool "boolean value %r needs to be 'True' or 'False'") tox.ConfigError: ConfigError: boolean value %r needs to be 'True' or 'False' ``` not sure if there's some syntactical trick to make it work but I tried pretty hard. everything works great if I just go oldschool with that one directive: ``` #! [tox] minversion=1.8.dev1 envlist = py{27,33}-sqla{079,084,09,10}, coverage [testenv] deps=pytest mock sqla079: git+http://git.sqlalchemy.org/sqlalchemy.git at rel_0_7_9 sqla084: git+http://git.sqlalchemy.org/sqlalchemy.git at rel_0_8_4 sqla09: git+http://git.sqlalchemy.org/sqlalchemy.git at rel_0_9 sqla10: git+http://git.sqlalchemy.org/sqlalchemy.git at master sitepackages=True usedevelop=True commands= py{27,33}-sqla{084,09,10}: python -m pytest -n 4 {posargs} py{27,33}-sqla{079}: python -m pytest {posargs} [testenv:py27-sqla10] recreate=True [testenv:py27-sqla09] recreate=True [testenv:py33-sqla10] recreate=True [testenv:py33-sqla09] recreate=True ``` From issues-reply at bitbucket.org Sun Sep 14 23:40:19 2014 From: issues-reply at bitbucket.org (Tom V) Date: Sun, 14 Sep 2014 21:40:19 -0000 Subject: [Pytest-commit] Issue #591: Typo in "Assertions about expected exceptions" docs (hpk42/pytest) Message-ID: <20140914214019.11982.65017@app09.ash-private.bitbucket.org> New issue 591: Typo in "Assertions about expected exceptions" docs https://bitbucket.org/hpk42/pytest/issue/591/typo-in-assertions-about-expected Tom V: The [code block explaining accessing "actual exception info"](http://pytest.org/latest/assert.html#assertions-about-expected-exceptions) looks like it contains too many `f()`s. I think a single `f()` is all that's required here: *and if you need to have access to the actual exception info you may use::* with pytest.raises(RuntimeError) as excinfo: def f(): f() f() # do checks related to excinfo.type, excinfo.value, excinfo.traceback Happy to make a PR is we can agree what this is supposed to look like. (I also found a few spelling mistake in the docs, that could be fixed at the same time?) From commits-noreply at bitbucket.org Mon Sep 15 12:44:29 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 15 Sep 2014 10:44:29 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: fix conftest related fixture visibility issue: when running with a Message-ID: <20140915104429.22488.66419@app11.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/4b8f938b224f/ Changeset: 4b8f938b224f Branch: conftest-nodeid User: hpk42 Date: 2014-09-15 12:44:16 Summary: fix conftest related fixture visibility issue: when running with a CWD outside a test package pytest would get fixture discovery wrong. Thanks to Wolfgang Schnerring for figuring out a reproducable example. Affected #: 5 files diff -r 2ae2ef6e63fc0f25ef44cca9d4c2ddcebd41ffc9 -r 4b8f938b224f93005993113bd012598bfb898734 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -12,6 +12,10 @@ instead of presuming any RuntimeError is that one (implemented in py dep). Thanks Charles Cloud for analysing the issue. +- fix conftest related fixture visibility issue: when running with a + CWD outside a test package pytest would get fixture discovery wrong. + Thanks to Wolfgang Schnerring for figuring out a reproducable example. + 2.6.2 ----------- diff -r 2ae2ef6e63fc0f25ef44cca9d4c2ddcebd41ffc9 -r 4b8f938b224f93005993113bd012598bfb898734 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.6.3.dev' +__version__ = '2.6.3.dev3' diff -r 2ae2ef6e63fc0f25ef44cca9d4c2ddcebd41ffc9 -r 4b8f938b224f93005993113bd012598bfb898734 _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1611,10 +1611,15 @@ except AttributeError: pass else: + # construct the base nodeid which is later used to check + # what fixtures are visible for particular tests (as denoted + # by their test id) if p.basename.startswith("conftest.py"): - nodeid = p.dirpath().relto(self.session.fspath) + nodeid = self.session.fspath.bestrelpath(p.dirpath()) if p.sep != "/": nodeid = nodeid.replace(p.sep, "/") + if nodeid == ".": + nodeid = "" self.parsefactories(plugin, nodeid) self._seenplugins.add(plugin) diff -r 2ae2ef6e63fc0f25ef44cca9d4c2ddcebd41ffc9 -r 4b8f938b224f93005993113bd012598bfb898734 setup.py --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ name='pytest', description='pytest: simple powerful testing with Python', long_description=long_description, - version='2.6.3.dev', + version='2.6.3.dev3', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff -r 2ae2ef6e63fc0f25ef44cca9d4c2ddcebd41ffc9 -r 4b8f938b224f93005993113bd012598bfb898734 testing/python/fixture.py --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -1001,6 +1001,40 @@ reprec = testdir.inline_run("-s") reprec.assertoutcome(passed=1) + def test_parsefactories_relative_node_ids(self, testdir): + # example mostly taken from: + # https://mail.python.org/pipermail/pytest-dev/2014-September/002617.html + runner = testdir.mkdir("runner") + package = testdir.mkdir("package") + package.join("conftest.py").write(dedent("""\ + import pytest + @pytest.fixture + def one(): + return 1 + """)) + package.join("test_x.py").write(dedent("""\ + def test_x(one): + assert one == 1 + """)) + sub = package.mkdir("sub") + sub.join("__init__.py").ensure() + sub.join("conftest.py").write(dedent("""\ + import pytest + @pytest.fixture + def one(): + return 2 + """)) + sub.join("test_y.py").write(dedent("""\ + def test_x(one): + assert one == 2 + """)) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=2) + with runner.as_cwd(): + reprec = testdir.inline_run("..") + reprec.assertoutcome(passed=2) + + class TestAutouseDiscovery: def pytest_funcarg__testdir(self, testdir): testdir.makeconftest(""" 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 Sep 15 13:04:12 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 15 Sep 2014 11:04:12 -0000 Subject: [Pytest-commit] commit/pytest: bubenkoff: Close branch conftest-nodeid Message-ID: <20140915110412.5088.5604@app08.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/c23503264835/ Changeset: c23503264835 Branch: conftest-nodeid User: bubenkoff Date: 2014-09-15 13:04:07 Summary: Close branch conftest-nodeid Affected #: 0 files 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 Sep 15 13:04:12 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 15 Sep 2014 11:04:12 -0000 Subject: [Pytest-commit] commit/pytest: bubenkoff: Merged in conftest-nodeid (pull request #202) Message-ID: <20140915110412.21055.5265@app06.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/a75e1258eed6/ Changeset: a75e1258eed6 User: bubenkoff Date: 2014-09-15 13:04:07 Summary: Merged in conftest-nodeid (pull request #202) fix conftest related fixture visibility issue Affected #: 5 files diff -r 2ae2ef6e63fc0f25ef44cca9d4c2ddcebd41ffc9 -r a75e1258eed60f5c7c648d9813a03ca6fd664406 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -12,6 +12,10 @@ instead of presuming any RuntimeError is that one (implemented in py dep). Thanks Charles Cloud for analysing the issue. +- fix conftest related fixture visibility issue: when running with a + CWD outside a test package pytest would get fixture discovery wrong. + Thanks to Wolfgang Schnerring for figuring out a reproducable example. + 2.6.2 ----------- diff -r 2ae2ef6e63fc0f25ef44cca9d4c2ddcebd41ffc9 -r a75e1258eed60f5c7c648d9813a03ca6fd664406 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.6.3.dev' +__version__ = '2.6.3.dev3' diff -r 2ae2ef6e63fc0f25ef44cca9d4c2ddcebd41ffc9 -r a75e1258eed60f5c7c648d9813a03ca6fd664406 _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1611,10 +1611,15 @@ except AttributeError: pass else: + # construct the base nodeid which is later used to check + # what fixtures are visible for particular tests (as denoted + # by their test id) if p.basename.startswith("conftest.py"): - nodeid = p.dirpath().relto(self.session.fspath) + nodeid = self.session.fspath.bestrelpath(p.dirpath()) if p.sep != "/": nodeid = nodeid.replace(p.sep, "/") + if nodeid == ".": + nodeid = "" self.parsefactories(plugin, nodeid) self._seenplugins.add(plugin) diff -r 2ae2ef6e63fc0f25ef44cca9d4c2ddcebd41ffc9 -r a75e1258eed60f5c7c648d9813a03ca6fd664406 setup.py --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ name='pytest', description='pytest: simple powerful testing with Python', long_description=long_description, - version='2.6.3.dev', + version='2.6.3.dev3', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff -r 2ae2ef6e63fc0f25ef44cca9d4c2ddcebd41ffc9 -r a75e1258eed60f5c7c648d9813a03ca6fd664406 testing/python/fixture.py --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -1001,6 +1001,40 @@ reprec = testdir.inline_run("-s") reprec.assertoutcome(passed=1) + def test_parsefactories_relative_node_ids(self, testdir): + # example mostly taken from: + # https://mail.python.org/pipermail/pytest-dev/2014-September/002617.html + runner = testdir.mkdir("runner") + package = testdir.mkdir("package") + package.join("conftest.py").write(dedent("""\ + import pytest + @pytest.fixture + def one(): + return 1 + """)) + package.join("test_x.py").write(dedent("""\ + def test_x(one): + assert one == 1 + """)) + sub = package.mkdir("sub") + sub.join("__init__.py").ensure() + sub.join("conftest.py").write(dedent("""\ + import pytest + @pytest.fixture + def one(): + return 2 + """)) + sub.join("test_y.py").write(dedent("""\ + def test_x(one): + assert one == 2 + """)) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=2) + with runner.as_cwd(): + reprec = testdir.inline_run("..") + reprec.assertoutcome(passed=2) + + class TestAutouseDiscovery: def pytest_funcarg__testdir(self, testdir): testdir.makeconftest(""" 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 Sep 15 13:07:31 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 15 Sep 2014 11:07:31 -0000 Subject: [Pytest-commit] commit/pytest: bubenkoff: add badges to the readme Message-ID: <20140915110731.10656.72436@app08.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/43d9ff3a8563/ Changeset: 43d9ff3a8563 User: bubenkoff Date: 2014-09-15 13:07:28 Summary: add badges to the readme Affected #: 1 file diff -r a75e1258eed60f5c7c648d9813a03ca6fd664406 -r 43d9ff3a856344fb91818a97e2330f9afab54fb5 README.rst --- a/README.rst +++ b/README.rst @@ -1,3 +1,7 @@ +.. image:: https://drone.io/bitbucket.org/hpk42/pytest/status.png + :target: https://drone.io/bitbucket.org/hpk42/pytest/latest +.. image:: https://pypip.in/v/pytest/badge.png + :target: https://crate.io/packages/pytest/ Documentation: http://pytest.org/latest/ 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 Sep 15 14:04:38 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 15 Sep 2014 12:04:38 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: fix link to pylib Message-ID: <20140915120438.31375.89874@app03.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/307f949cb4ca/ Changeset: 307f949cb4ca User: hpk42 Date: 2014-09-15 14:04:31 Summary: fix link to pylib Affected #: 1 file diff -r 43d9ff3a856344fb91818a97e2330f9afab54fb5 -r 307f949cb4ca0d6ebd9abc5e7759d31f0a2d7d40 doc/en/links.inc --- a/doc/en/links.inc +++ b/doc/en/links.inc @@ -18,4 +18,4 @@ .. _hudson: http://hudson-ci.org/ .. _jenkins: http://jenkins-ci.org/ .. _tox: http://testrun.org/tox -.. _pylib: http://pylib.org +.. _pylib: http://py.readthedocs.org/en/latest/ 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 Sep 15 15:04:22 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 15 Sep 2014 13:04:22 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: fix issue584: fix py3 syntax errors for example/special.txt. Message-ID: <20140915130422.21524.61639@app06.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/81d45151f455/ Changeset: 81d45151f455 User: hpk42 Date: 2014-09-15 15:04:09 Summary: fix issue584: fix py3 syntax errors for example/special.txt. Thanks Bruno Oliveira. Affected #: 1 file diff -r 307f949cb4ca0d6ebd9abc5e7759d31f0a2d7d40 -r 81d45151f455fd7ca06501bb2a895ac0feb54bd2 doc/en/example/special.txt --- a/doc/en/example/special.txt +++ b/doc/en/example/special.txt @@ -1,7 +1,7 @@ A session-fixture which can look at all collected tests ---------------------------------------------------------------- -A session-scoped fixture effectively has access to all +A session-scoped fixture effectively has access to all collected test items. Here is an example of a fixture function which walks all collected tests and looks if their test class defines a ``callme`` method and @@ -13,7 +13,7 @@ @pytest.fixture(scope="session", autouse=True) def callattr_ahead_of_alltests(request): - print "callattr_ahead_of_alltests called" + print ("callattr_ahead_of_alltests called") seen = set([None]) session = request.node for item in session.items: @@ -31,55 +31,42 @@ class TestHello: @classmethod def callme(cls): - print "callme called!" + print ("callme called!") def test_method1(self): - print "test_method1 called" - + print ("test_method1 called") + def test_method2(self): - print "test_method1 called" + print ("test_method1 called") class TestOther: @classmethod def callme(cls): - print "callme other called" + print ("callme other called") def test_other(self): - print "test other" + print ("test other") # works with unittest as well ... import unittest - + class SomeTest(unittest.TestCase): @classmethod def callme(self): - print "SomeTest callme called" + print ("SomeTest callme called") def test_unit1(self): - print "test_unit1 method called" + print ("test_unit1 method called") If you run this without output capturing:: - $ py.test -q -s test_module.py - Traceback (most recent call last): - File "/home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/_pytest/config.py", line 513, in getconftestmodules - return self._path2confmods[path] - KeyError: local('/tmp/doc-exec-88/test_module.py') - - During handling of the above exception, another exception occurred: - Traceback (most recent call last): - File "/home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/_pytest/config.py", line 537, in importconftest - return self._conftestpath2mod[conftestpath] - KeyError: local('/tmp/doc-exec-88/conftest.py') - - During handling of the above exception, another exception occurred: - Traceback (most recent call last): - File "/home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/_pytest/config.py", line 543, in importconftest - mod = conftestpath.pyimport() - File "/home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/py/_path/local.py", line 640, in pyimport - __import__(modname) - File "/tmp/doc-exec-88/conftest.py", line 6 - print "callattr_ahead_of_alltests called" - ^ - SyntaxError: invalid syntax - ERROR: could not load /tmp/doc-exec-88/conftest.py - + $ py.test -q -s test_module.py + callattr_ahead_of_alltests called + callme called! + callme other called + SomeTest callme called + test_method1 called + .test_method1 called + .test other + .test_unit1 method called + . + 4 passed in 0.05 seconds 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 issues-reply at bitbucket.org Tue Sep 16 15:47:29 2014 From: issues-reply at bitbucket.org (=?utf-8?q?Thomas_G=C3=BCttler?=) Date: Tue, 16 Sep 2014 13:47:29 -0000 Subject: [Pytest-commit] Issue #592: py.test hangs after update from 2.5 to 2.6.2 (hpk42/pytest) Message-ID: <20140916134729.15878.99139@app14.ash-private.bitbucket.org> New issue 592: py.test hangs after update from 2.5 to 2.6.2 https://bitbucket.org/hpk42/pytest/issue/592/pytest-hangs-after-update-from-25-to-262 Thomas G?ttler: After updating from 2.5.2 to 2.6.2 py.test hangs in os.system(). The very strange thing: If I use the "-s" option for py.test, the tests passes and does not hang. Before I waste hours if debugging I want to ask here if you have seen something like this before. From issues-reply at bitbucket.org Thu Sep 18 11:49:33 2014 From: issues-reply at bitbucket.org (Martin Myrseth) Date: Thu, 18 Sep 2014 09:49:33 -0000 Subject: [Pytest-commit] Issue #593: xdist incompatible with multiprocessing on Python 3.4 (hpk42/pytest) Message-ID: <20140918094933.13391.82511@app08.ash-private.bitbucket.org> New issue 593: xdist incompatible with multiprocessing on Python 3.4 https://bitbucket.org/hpk42/pytest/issue/593/xdist-incompatible-with-multiprocessing-on Martin Myrseth: It seems like importing `multiprocessing` while running `py.test -f` breaks on Python 3.4.0. A minimal reproduction: ``` #!python import multiprocessing def test_case(): assert True ``` This works as expected without the unused multiprocessing import. Python presents the following stack trace: ``` #! ==================================== ERRORS ==================================== ___________________________ ERROR collecting test.py ___________________________ test.py:1: in import multiprocessing /usr/lib/python3.4/multiprocessing/__init__.py:16: in from . import context /usr/lib/python3.4/multiprocessing/context.py:5: in from . import process /usr/lib/python3.4/multiprocessing/process.py:316: in _current_process = _MainProcess() /usr/lib/python3.4/multiprocessing/process.py:303: in __init__ self._config = {'authkey': AuthenticationString(os.urandom(32)), E RuntimeError: Failed to read 32 bytes from /dev/urandom ``` Pytest version dump: ``` #!bash (pytest-xdist) $ py.test --version This is pytest version 2.6.2, imported from <..>/.virtualenvs/pytest-xdist/lib/python3.4/site-packages/pytest.py setuptools registered plugins: pytest-xdist-1.10 at <..>/.virtualenvs/pytest-xdist/lib/python3.4/site-packages/xdist/plugin.py ``` From issues-reply at bitbucket.org Mon Sep 22 08:15:10 2014 From: issues-reply at bitbucket.org (pytry) Date: Mon, 22 Sep 2014 06:15:10 -0000 Subject: [Pytest-commit] Issue #594: py.test with xdist is not executing tests parametrized with random values (hpk42/pytest) Message-ID: <20140922061510.9563.44349@app08.ash-private.bitbucket.org> New issue 594: py.test with xdist is not executing tests parametrized with random values https://bitbucket.org/hpk42/pytest/issue/594/pytest-with-xdist-is-not-executing-tests pytry: I have noticed the following strange behaviour for pytest and xdist. When trying to run the test that is parametrized with some randomly selected values the test are not actually run. The same test is executed without any problems if xdist is not used. Following code can be used to reproduce this. ``` #!python import pytest import random PARAMS_NUMBER = 3 PARAMS = [] for i in range(PARAMS_NUMBER): PARAMS.append(random.randrange(0, 1000)) @pytest.mark.parametrize('rand_par', PARAMS) def test_random_param(rand_par): assert 500 > rand_par ``` Without xdists it works fine. With xdist no test is executed at all with the following output ``` #!console ============================= test session starts ============================= platform win32 -- Python 2.7.3 -- py-1.4.24 -- pytest-2.6.2 plugins: xdist gw0 [3] / gw1 [3] / gw2 [3] / gw3 [3] scheduling tests via LoadScheduling ============================== in 1.93 seconds =============================== ``` Versions I'm using: python 2.7.3 pytest 2.6.2 pytest-xdist 1.11 Additional note: With some older versions (xdist 1.8 and pytest 2.4.X or 2.5.X do not remember exactly) the xdist was stopping on assertion in dsession.py ``` #!python assert collection == col ``` Thanks in advance for any help :) From commits-noreply at bitbucket.org Mon Sep 22 13:34:54 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 22 Sep 2014 11:34:54 -0000 Subject: [Pytest-commit] commit/pytest: 2 new changesets Message-ID: <20140922113454.13594.69005@app09.ash-private.bitbucket.org> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/7426c3938174/ Changeset: 7426c3938174 Branch: dontreadfrominput-encoding User: davidszotten Date: 2014-09-22 11:19:27+00:00 Summary: add `encoding` attr to DontReadFromInput required by https://docs.python.org/2/library/stdtypes.html#file.encoding and used e.g. by ipdb at _import_ time Affected #: 2 files diff -r 81d45151f455fd7ca06501bb2a895ac0feb54bd2 -r 7426c3938174a2129587f44cc55cee66f450a65c _pytest/capture.py --- a/_pytest/capture.py +++ b/_pytest/capture.py @@ -428,6 +428,9 @@ because in automated test runs it is better to crash than hang indefinitely. """ + + encoding = None + def read(self, *args): raise IOError("reading from stdin while output is captured") readline = read diff -r 81d45151f455fd7ca06501bb2a895ac0feb54bd2 -r 7426c3938174a2129587f44cc55cee66f450a65c testing/test_capture.py --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -1025,6 +1025,18 @@ reprec.assertoutcome(passed=1) +def test_dontreadfrominput_has_encoding(testdir): + testdir.makepyfile(""" + import sys + def test_capattr(): + # should not raise AttributeError + assert sys.stdout.encoding + assert sys.stderr.encoding + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + + def test_pickling_and_unpickling_enocded_file(): # See https://bitbucket.org/hpk42/pytest/pull-request/194 # pickle.loads() raises infinite recursion if https://bitbucket.org/hpk42/pytest/commits/f58d81b9d2c2/ Changeset: f58d81b9d2c2 User: hpk42 Date: 2014-09-22 11:34:50+00:00 Summary: Merged in davidszotten/pytest/dontreadfrominput-encoding (pull request #205) add `encoding` attr to DontReadFromInput Affected #: 2 files diff -r 81d45151f455fd7ca06501bb2a895ac0feb54bd2 -r f58d81b9d2c2e382ecdfcb09677f742f37a5840d _pytest/capture.py --- a/_pytest/capture.py +++ b/_pytest/capture.py @@ -428,6 +428,9 @@ because in automated test runs it is better to crash than hang indefinitely. """ + + encoding = None + def read(self, *args): raise IOError("reading from stdin while output is captured") readline = read diff -r 81d45151f455fd7ca06501bb2a895ac0feb54bd2 -r f58d81b9d2c2e382ecdfcb09677f742f37a5840d testing/test_capture.py --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -1025,6 +1025,18 @@ reprec.assertoutcome(passed=1) +def test_dontreadfrominput_has_encoding(testdir): + testdir.makepyfile(""" + import sys + def test_capattr(): + # should not raise AttributeError + assert sys.stdout.encoding + assert sys.stderr.encoding + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + + def test_pickling_and_unpickling_enocded_file(): # See https://bitbucket.org/hpk42/pytest/pull-request/194 # pickle.loads() raises infinite recursion if 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 Sep 22 13:34:54 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 22 Sep 2014 11:34:54 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: Merged in davidszotten/pytest/dontreadfrominput-encoding (pull request #205) Message-ID: <20140922113454.1648.40576@app02.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/f58d81b9d2c2/ Changeset: f58d81b9d2c2 User: hpk42 Date: 2014-09-22 11:34:50+00:00 Summary: Merged in davidszotten/pytest/dontreadfrominput-encoding (pull request #205) add `encoding` attr to DontReadFromInput Affected #: 2 files diff -r 81d45151f455fd7ca06501bb2a895ac0feb54bd2 -r f58d81b9d2c2e382ecdfcb09677f742f37a5840d _pytest/capture.py --- a/_pytest/capture.py +++ b/_pytest/capture.py @@ -428,6 +428,9 @@ because in automated test runs it is better to crash than hang indefinitely. """ + + encoding = None + def read(self, *args): raise IOError("reading from stdin while output is captured") readline = read diff -r 81d45151f455fd7ca06501bb2a895ac0feb54bd2 -r f58d81b9d2c2e382ecdfcb09677f742f37a5840d testing/test_capture.py --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -1025,6 +1025,18 @@ reprec.assertoutcome(passed=1) +def test_dontreadfrominput_has_encoding(testdir): + testdir.makepyfile(""" + import sys + def test_capattr(): + # should not raise AttributeError + assert sys.stdout.encoding + assert sys.stderr.encoding + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + + def test_pickling_and_unpickling_enocded_file(): # See https://bitbucket.org/hpk42/pytest/pull-request/194 # pickle.loads() raises infinite recursion if 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 Sep 22 15:02:53 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 22 Sep 2014 13:02:53 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: Merged in davidszotten/pytest/stop_leaking_fds (pull request #206) Message-ID: <20140922130253.17091.51744@app02.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/6b38010df14c/ Changeset: 6b38010df14c User: hpk42 Date: 2014-09-22 13:02:48+00:00 Summary: Merged in davidszotten/pytest/stop_leaking_fds (pull request #206) stop leaking file descriptors Affected #: 1 file diff -r f58d81b9d2c2e382ecdfcb09677f742f37a5840d -r 6b38010df14cc3c57c5034313a1edace19451d52 testing/test_capture.py --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -744,6 +744,7 @@ cap.done() pytest.raises(AttributeError, cap.suspend) + @contextlib.contextmanager def saved_fd(fd): new_fd = os.dup(fd) @@ -751,6 +752,7 @@ yield finally: os.dup2(new_fd, fd) + os.close(new_fd) class TestStdCapture: 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 Sep 22 15:02:54 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 22 Sep 2014 13:02:54 -0000 Subject: [Pytest-commit] commit/pytest: 2 new changesets Message-ID: <20140922130254.12252.29169@app03.ash-private.bitbucket.org> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/4ee98979bc6f/ Changeset: 4ee98979bc6f Branch: stop_leaking_fds User: davidszotten Date: 2014-09-22 12:56:07+00:00 Summary: stop leaking file descriptors tripps --lsof on os x but not on linux. there's possibly a bug in the leak detector (not investigated here) Affected #: 1 file diff -r f58d81b9d2c2e382ecdfcb09677f742f37a5840d -r 4ee98979bc6f60164be35efd87e127fdf46a4985 testing/test_capture.py --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -744,6 +744,7 @@ cap.done() pytest.raises(AttributeError, cap.suspend) + @contextlib.contextmanager def saved_fd(fd): new_fd = os.dup(fd) @@ -751,6 +752,7 @@ yield finally: os.dup2(new_fd, fd) + os.close(new_fd) class TestStdCapture: https://bitbucket.org/hpk42/pytest/commits/6b38010df14c/ Changeset: 6b38010df14c User: hpk42 Date: 2014-09-22 13:02:48+00:00 Summary: Merged in davidszotten/pytest/stop_leaking_fds (pull request #206) stop leaking file descriptors Affected #: 1 file diff -r f58d81b9d2c2e382ecdfcb09677f742f37a5840d -r 6b38010df14cc3c57c5034313a1edace19451d52 testing/test_capture.py --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -744,6 +744,7 @@ cap.done() pytest.raises(AttributeError, cap.suspend) + @contextlib.contextmanager def saved_fd(fd): new_fd = os.dup(fd) @@ -751,6 +752,7 @@ yield finally: os.dup2(new_fd, fd) + os.close(new_fd) class TestStdCapture: 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 Sep 22 16:46:47 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 22 Sep 2014 14:46:47 -0000 Subject: [Pytest-commit] commit/pytest: 2 new changesets Message-ID: <20140922144647.7760.77569@app01.ash-private.bitbucket.org> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/09ed9840ffa9/ Changeset: 09ed9840ffa9 Branch: stop_leaking_fds User: flub Date: 2014-09-22 14:39:40+00:00 Summary: closing branch Affected #: 0 files https://bitbucket.org/hpk42/pytest/commits/33256ea7c58b/ Changeset: 33256ea7c58b Branch: dontreadfrominput-encoding User: flub Date: 2014-09-22 14:42:06+00:00 Summary: closing branch Affected #: 0 files 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 Sep 22 19:16:15 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 22 Sep 2014 17:16:15 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: Merged in flub/pytest (pull request #207) Message-ID: <20140922171615.27463.86671@app09.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/95428e0c36e1/ Changeset: 95428e0c36e1 User: hpk42 Date: 2014-09-22 17:16:10+00:00 Summary: Merged in flub/pytest (pull request #207) Show both user assertion msg as explanation (issue549) Affected #: 7 files diff -r 6b38010df14cc3c57c5034313a1edace19451d52 -r 95428e0c36e169596f8370c6663a99e960c01612 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -42,6 +42,10 @@ other builds due to the extra argparse dependency. Fixes issue566. Thanks sontek. +- Implement issue549: user-provided assertion messages now no longer + replace the py.test instrospection message but are shown in addition + to them. + 2.6.1 ----------------------------------- diff -r 6b38010df14cc3c57c5034313a1edace19451d52 -r 95428e0c36e169596f8370c6663a99e960c01612 _pytest/assertion/rewrite.py --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -351,6 +351,33 @@ from _pytest.assertion.util import format_explanation as _format_explanation # noqa +def _format_assertmsg(obj): + """Format the custom assertion message given. + + For strings this simply replaces newlines with '\n~' so that + util.format_explanation() will preserve them instead of escaping + newlines. For other objects py.io.saferepr() is used first. + + """ + # reprlib appears to have a bug which means that if a string + # contains a newline it gets escaped, however if an object has a + # .__repr__() which contains newlines it does not get escaped. + # However in either case we want to preserve the newline. + if py.builtin._istext(obj) or py.builtin._isbytes(obj): + s = obj + is_repr = False + else: + s = py.io.saferepr(obj) + is_repr = True + if py.builtin._istext(s): + t = py.builtin.text + else: + t = py.builtin.bytes + s = s.replace(t("\n"), t("\n~")) + if is_repr: + s = s.replace(t("\\n"), t("\n~")) + return s + def _should_repr_global_name(obj): return not hasattr(obj, "__name__") and not py.builtin.callable(obj) @@ -419,6 +446,56 @@ class AssertionRewriter(ast.NodeVisitor): + """Assertion rewriting implementation. + + The main entrypoint is to call .run() with an ast.Module instance, + this will then find all the assert statements and re-write them to + provide intermediate values and a detailed assertion error. See + http://pybites.blogspot.be/2011/07/behind-scenes-of-pytests-new-assertion.html + for an overview of how this works. + + The entry point here is .run() which will iterate over all the + statenemts in an ast.Module and for each ast.Assert statement it + finds call .visit() with it. Then .visit_Assert() takes over and + is responsible for creating new ast statements to replace the + original assert statement: it re-writes the test of an assertion + to provide intermediate values and replace it with an if statement + which raises an assertion error with a detailed explanation in + case the expression is false. + + For this .visit_Assert() uses the visitor pattern to visit all the + AST nodes of the ast.Assert.test field, each visit call returning + an AST node and the corresponding explanation string. During this + state is kept in several instance attributes: + + :statements: All the AST statements which will replace the assert + statement. + + :variables: This is populated by .variable() with each variable + used by the statements so that they can all be set to None at + the end of the statements. + + :variable_counter: Counter to create new unique variables needed + by statements. Variables are created using .variable() and + have the form of "@py_assert0". + + :on_failure: The AST statements which will be executed if the + assertion test fails. This is the code which will construct + the failure message and raises the AssertionError. + + :explanation_specifiers: A dict filled by .explanation_param() + with %-formatting placeholders and their corresponding + expressions to use in the building of an assertion message. + This is used by .pop_format_context() to build a message. + + :stack: A stack of the explanation_specifiers dicts maintained by + .push_format_context() and .pop_format_context() which allows + to build another %-formatted string while already building one. + + This state is reset on every new assert statement visited and used + by the other visitors. + + """ def run(self, mod): """Find all assert statements in *mod* and rewrite them.""" @@ -500,15 +577,41 @@ return ast.Attribute(builtin_name, name, ast.Load()) def explanation_param(self, expr): + """Return a new named %-formatting placeholder for expr. + + This creates a %-formatting placeholder for expr in the + current formatting context, e.g. ``%(py0)s``. The placeholder + and expr are placed in the current format context so that it + can be used on the next call to .pop_format_context(). + + """ specifier = "py" + str(next(self.variable_counter)) self.explanation_specifiers[specifier] = expr return "%(" + specifier + ")s" def push_format_context(self): + """Create a new formatting context. + + The format context is used for when an explanation wants to + have a variable value formatted in the assertion message. In + this case the value required can be added using + .explanation_param(). Finally .pop_format_context() is used + to format a string of %-formatted values as added by + .explanation_param(). + + """ self.explanation_specifiers = {} self.stack.append(self.explanation_specifiers) def pop_format_context(self, expl_expr): + """Format the %-formatted string with current format context. + + The expl_expr should be an ast.Str instance constructed from + the %-placeholders created by .explanation_param(). This will + add the required code to format said string to .on_failure and + return the ast.Name instance of the formatted string. + + """ current = self.stack.pop() if self.stack: self.explanation_specifiers = self.stack[-1] @@ -526,11 +629,15 @@ return res, self.explanation_param(self.display(res)) def visit_Assert(self, assert_): - if assert_.msg: - # There's already a message. Don't mess with it. - return [assert_] + """Return the AST statements to replace the ast.Assert instance. + + This re-writes the test of an assertion to provide + intermediate values and replace it with an if statement which + raises an assertion error with a detailed explanation in case + the expression is false. + + """ self.statements = [] - self.cond_chain = () self.variables = [] self.variable_counter = itertools.count() self.stack = [] @@ -542,8 +649,13 @@ body = self.on_failure negation = ast.UnaryOp(ast.Not(), top_condition) self.statements.append(ast.If(negation, body, [])) - explanation = "assert " + explanation - template = ast.Str(explanation) + if assert_.msg: + assertmsg = self.helper('format_assertmsg', assert_.msg) + explanation = "\n>assert " + explanation + else: + assertmsg = ast.Str("") + explanation = "assert " + explanation + template = ast.BinOp(assertmsg, ast.Add(), ast.Str(explanation)) msg = self.pop_format_context(template) fmt = self.helper("format_explanation", msg) err_name = ast.Name("AssertionError", ast.Load()) diff -r 6b38010df14cc3c57c5034313a1edace19451d52 -r 95428e0c36e169596f8370c6663a99e960c01612 _pytest/assertion/util.py --- a/_pytest/assertion/util.py +++ b/_pytest/assertion/util.py @@ -73,7 +73,7 @@ raw_lines = (explanation or u('')).split('\n') lines = [raw_lines[0]] for l in raw_lines[1:]: - if l.startswith('{') or l.startswith('}') or l.startswith('~'): + if l and l[0] in ['{', '}', '~', '>']: lines.append(l) else: lines[-1] += '\\n' + l @@ -103,13 +103,14 @@ stackcnt.append(0) result.append(u(' +') + u(' ')*(len(stack)-1) + s + line[1:]) elif line.startswith('}'): - assert line.startswith('}') stack.pop() stackcnt.pop() result[stack[-1]] += line[1:] else: - assert line.startswith('~') - result.append(u(' ')*len(stack) + line[1:]) + assert line[0] in ['~', '>'] + stack[-1] += 1 + indent = len(stack) if line.startswith('~') else len(stack) - 1 + result.append(u(' ')*indent + line[1:]) assert len(stack) == 1 return result diff -r 6b38010df14cc3c57c5034313a1edace19451d52 -r 95428e0c36e169596f8370c6663a99e960c01612 doc/en/example/assertion/failure_demo.py --- a/doc/en/example/assertion/failure_demo.py +++ b/doc/en/example/assertion/failure_demo.py @@ -211,3 +211,27 @@ finally: x = 0 + +class TestCustomAssertMsg: + + def test_single_line(self): + class A: + a = 1 + b = 2 + assert A.a == b, "A.a appears not to be b" + + def test_multiline(self): + class A: + a = 1 + b = 2 + assert A.a == b, "A.a appears not to be b\n" \ + "or does not appear to be b\none of those" + + def test_custom_repr(self): + class JSON: + a = 1 + def __repr__(self): + return "This is JSON\n{\n 'foo': 'bar'\n}" + a = JSON() + b = 2 + assert a.a == b, a diff -r 6b38010df14cc3c57c5034313a1edace19451d52 -r 95428e0c36e169596f8370c6663a99e960c01612 doc/en/example/assertion/test_failures.py --- a/doc/en/example/assertion/test_failures.py +++ b/doc/en/example/assertion/test_failures.py @@ -9,6 +9,6 @@ failure_demo.copy(testdir.tmpdir.join(failure_demo.basename)) result = testdir.runpytest(target) result.stdout.fnmatch_lines([ - "*39 failed*" + "*42 failed*" ]) assert result.ret != 0 diff -r 6b38010df14cc3c57c5034313a1edace19451d52 -r 95428e0c36e169596f8370c6663a99e960c01612 testing/test_assertion.py --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -4,6 +4,7 @@ import py, pytest import _pytest.assertion as plugin from _pytest.assertion import reinterpret +from _pytest.assertion import util needsnewassert = pytest.mark.skipif("sys.version_info < (2,6)") @@ -201,7 +202,7 @@ class TestFormatExplanation: - def test_speical_chars_full(self, testdir): + def test_special_chars_full(self, testdir): # Issue 453, for the bug this would raise IndexError testdir.makepyfile(""" def test_foo(): @@ -213,6 +214,83 @@ "*AssertionError*", ]) + def test_fmt_simple(self): + expl = 'assert foo' + assert util.format_explanation(expl) == 'assert foo' + + def test_fmt_where(self): + expl = '\n'.join(['assert 1', + '{1 = foo', + '} == 2']) + res = '\n'.join(['assert 1 == 2', + ' + where 1 = foo']) + assert util.format_explanation(expl) == res + + def test_fmt_and(self): + expl = '\n'.join(['assert 1', + '{1 = foo', + '} == 2', + '{2 = bar', + '}']) + res = '\n'.join(['assert 1 == 2', + ' + where 1 = foo', + ' + and 2 = bar']) + assert util.format_explanation(expl) == res + + def test_fmt_where_nested(self): + expl = '\n'.join(['assert 1', + '{1 = foo', + '{foo = bar', + '}', + '} == 2']) + res = '\n'.join(['assert 1 == 2', + ' + where 1 = foo', + ' + where foo = bar']) + assert util.format_explanation(expl) == res + + def test_fmt_newline(self): + expl = '\n'.join(['assert "foo" == "bar"', + '~- foo', + '~+ bar']) + res = '\n'.join(['assert "foo" == "bar"', + ' - foo', + ' + bar']) + assert util.format_explanation(expl) == res + + def test_fmt_newline_escaped(self): + expl = '\n'.join(['assert foo == bar', + 'baz']) + res = 'assert foo == bar\\nbaz' + assert util.format_explanation(expl) == res + + def test_fmt_newline_before_where(self): + expl = '\n'.join(['the assertion message here', + '>assert 1', + '{1 = foo', + '} == 2', + '{2 = bar', + '}']) + res = '\n'.join(['the assertion message here', + 'assert 1 == 2', + ' + where 1 = foo', + ' + and 2 = bar']) + assert util.format_explanation(expl) == res + + def test_fmt_multi_newline_before_where(self): + expl = '\n'.join(['the assertion', + '~message here', + '>assert 1', + '{1 = foo', + '} == 2', + '{2 = bar', + '}']) + res = '\n'.join(['the assertion', + ' message here', + 'assert 1 == 2', + ' + where 1 = foo', + ' + and 2 = bar']) + assert util.format_explanation(expl) == res + def test_python25_compile_issue257(testdir): testdir.makepyfile(""" diff -r 6b38010df14cc3c57c5034313a1edace19451d52 -r 95428e0c36e169596f8370c6663a99e960c01612 testing/test_assertrewrite.py --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -121,7 +121,56 @@ def test_assert_already_has_message(self): def f(): assert False, "something bad!" - assert getmsg(f) == "AssertionError: something bad!" + assert getmsg(f) == "AssertionError: something bad!\nassert False" + + def test_assertion_message(self, testdir): + testdir.makepyfile(""" + def test_foo(): + assert 1 == 2, "The failure message" + """) + result = testdir.runpytest() + assert result.ret == 1 + result.stdout.fnmatch_lines([ + "*AssertionError*The failure message*", + "*assert 1 == 2*", + ]) + + def test_assertion_message_multiline(self, testdir): + testdir.makepyfile(""" + def test_foo(): + assert 1 == 2, "A multiline\\nfailure message" + """) + result = testdir.runpytest() + assert result.ret == 1 + result.stdout.fnmatch_lines([ + "*AssertionError*A multiline*", + "*failure message*", + "*assert 1 == 2*", + ]) + + def test_assertion_message_tuple(self, testdir): + testdir.makepyfile(""" + def test_foo(): + assert 1 == 2, (1, 2) + """) + result = testdir.runpytest() + assert result.ret == 1 + result.stdout.fnmatch_lines([ + "*AssertionError*%s*" % repr((1, 2)), + "*assert 1 == 2*", + ]) + + def test_assertion_message_expr(self, testdir): + testdir.makepyfile(""" + def test_foo(): + assert 1 == 2, 1 + 2 + """) + result = testdir.runpytest() + assert result.ret == 1 + result.stdout.fnmatch_lines([ + "*AssertionError*3*", + "*assert 1 == 2*", + ]) def test_boolop(self): def f(): 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 Sep 22 19:16:15 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 22 Sep 2014 17:16:15 -0000 Subject: [Pytest-commit] commit/pytest: 3 new changesets Message-ID: <20140922171615.2113.62726@app14.ash-private.bitbucket.org> 3 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/f21d976ea15b/ Changeset: f21d976ea15b User: flub Date: 2014-08-23 16:14:25+00:00 Summary: Show user assertion messages and instrospection together User provided messages, or any valid expression given as second argument to the assert statement, are now shown in addition to the py.test introspection details. Formerly any user provided message would entirely replace the introspection details. Fixes issue549. Affected #: 6 files diff -r 9baf836b29b58c72ffccc113bca3ac54c883caf8 -r f21d976ea15b6819a834ea6dda112e0da9d57d14 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -9,6 +9,10 @@ other builds due to the extra argparse dependency. Fixes issue566. Thanks sontek. +- Implement issue549: user-provided assertion messages now no longer + replace the py.test instrospection message but are shown in addition + to them. + 2.6.1 ----------------------------------- diff -r 9baf836b29b58c72ffccc113bca3ac54c883caf8 -r f21d976ea15b6819a834ea6dda112e0da9d57d14 _pytest/assertion/rewrite.py --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -329,6 +329,33 @@ _saferepr = py.io.saferepr from _pytest.assertion.util import format_explanation as _format_explanation # noqa +def _format_assertmsg(obj): + """Format the custom assertion message given. + + For strings this simply replaces newlines with '\n~' so that + util.format_explanation() will preserve them instead of escaping + newlines. For other objects py.io.saferepr() is used first. + + """ + # reprlib appears to have a bug which means that if a string + # contains a newline it gets escaped, however if an object has a + # .__repr__() which contains newlines it does not get escaped. + # However in either case we want to preserve the newline. + if py.builtin._istext(obj) or py.builtin._isbytes(obj): + s = obj + is_repr = False + else: + s = py.io.saferepr(obj) + is_repr = True + if py.builtin._istext(s): + t = py.builtin.text + else: + t = py.builtin.bytes + s = s.replace(t("\n"), t("\n~")) + if is_repr: + s = s.replace(t("\\n"), t("\n~")) + return s + def _should_repr_global_name(obj): return not hasattr(obj, "__name__") and not py.builtin.callable(obj) @@ -397,6 +424,56 @@ class AssertionRewriter(ast.NodeVisitor): + """Assertion rewriting implementation. + + The main entrypoint is to call .run() with an ast.Module instance, + this will then find all the assert statements and re-write them to + provide intermediate values and a detailed assertion error. See + http://pybites.blogspot.be/2011/07/behind-scenes-of-pytests-new-assertion.html + for an overview of how this works. + + The entry point here is .run() which will iterate over all the + statenemts in an ast.Module and for each ast.Assert statement it + finds call .visit() with it. Then .visit_Assert() takes over and + is responsible for creating new ast statements to replace the + original assert statement: it re-writes the test of an assertion + to provide intermediate values and replace it with an if statement + which raises an assertion error with a detailed explanation in + case the expression is false. + + For this .visit_Assert() uses the visitor pattern to visit all the + AST nodes of the ast.Assert.test field, each visit call returning + an AST node and the corresponding explanation string. During this + state is kept in several instance attributes: + + :statements: All the AST statements which will replace the assert + statement. + + :variables: This is populated by .variable() with each variable + used by the statements so that they can all be set to None at + the end of the statements. + + :variable_counter: Counter to create new unique variables needed + by statements. Variables are created using .variable() and + have the form of "@py_assert0". + + :on_failure: The AST statements which will be executed if the + assertion test fails. This is the code which will construct + the failure message and raises the AssertionError. + + :explanation_specifiers: A dict filled by .explanation_param() + with %-formatting placeholders and their corresponding + expressions to use in the building of an assertion message. + This is used by .pop_format_context() to build a message. + + :stack: A stack of the explanation_specifiers dicts maintained by + .push_format_context() and .pop_format_context() which allows + to build another %-formatted string while already building one. + + This state is reset on every new assert statement visited and used + by the other visitors. + + """ def run(self, mod): """Find all assert statements in *mod* and rewrite them.""" @@ -478,15 +555,41 @@ return ast.Attribute(builtin_name, name, ast.Load()) def explanation_param(self, expr): + """Return a new named %-formatting placeholder for expr. + + This creates a %-formatting placeholder for expr in the + current formatting context, e.g. ``%(py0)s``. The placeholder + and expr are placed in the current format context so that it + can be used on the next call to .pop_format_context(). + + """ specifier = "py" + str(next(self.variable_counter)) self.explanation_specifiers[specifier] = expr return "%(" + specifier + ")s" def push_format_context(self): + """Create a new formatting context. + + The format context is used for when an explanation wants to + have a variable value formatted in the assertion message. In + this case the value required can be added using + .explanation_param(). Finally .pop_format_context() is used + to format a string of %-formatted values as added by + .explanation_param(). + + """ self.explanation_specifiers = {} self.stack.append(self.explanation_specifiers) def pop_format_context(self, expl_expr): + """Format the %-formatted string with current format context. + + The expl_expr should be an ast.Str instance constructed from + the %-placeholders created by .explanation_param(). This will + add the required code to format said string to .on_failure and + return the ast.Name instance of the formatted string. + + """ current = self.stack.pop() if self.stack: self.explanation_specifiers = self.stack[-1] @@ -504,11 +607,15 @@ return res, self.explanation_param(self.display(res)) def visit_Assert(self, assert_): - if assert_.msg: - # There's already a message. Don't mess with it. - return [assert_] + """Return the AST statements to replace the ast.Assert instance. + + This re-writes the test of an assertion to provide + intermediate values and replace it with an if statement which + raises an assertion error with a detailed explanation in case + the expression is false. + + """ self.statements = [] - self.cond_chain = () self.variables = [] self.variable_counter = itertools.count() self.stack = [] @@ -520,8 +627,13 @@ body = self.on_failure negation = ast.UnaryOp(ast.Not(), top_condition) self.statements.append(ast.If(negation, body, [])) - explanation = "assert " + explanation - template = ast.Str(explanation) + if assert_.msg: + assertmsg = self.helper('format_assertmsg', assert_.msg) + explanation = "\n>assert " + explanation + else: + assertmsg = ast.Str("") + explanation = "assert " + explanation + template = ast.BinOp(assertmsg, ast.Add(), ast.Str(explanation)) msg = self.pop_format_context(template) fmt = self.helper("format_explanation", msg) err_name = ast.Name("AssertionError", ast.Load()) diff -r 9baf836b29b58c72ffccc113bca3ac54c883caf8 -r f21d976ea15b6819a834ea6dda112e0da9d57d14 _pytest/assertion/util.py --- a/_pytest/assertion/util.py +++ b/_pytest/assertion/util.py @@ -73,7 +73,7 @@ raw_lines = (explanation or u('')).split('\n') lines = [raw_lines[0]] for l in raw_lines[1:]: - if l.startswith('{') or l.startswith('}') or l.startswith('~'): + if l and l[0] in ['{', '}', '~', '>']: lines.append(l) else: lines[-1] += '\\n' + l @@ -103,13 +103,14 @@ stackcnt.append(0) result.append(u(' +') + u(' ')*(len(stack)-1) + s + line[1:]) elif line.startswith('}'): - assert line.startswith('}') stack.pop() stackcnt.pop() result[stack[-1]] += line[1:] else: - assert line.startswith('~') - result.append(u(' ')*len(stack) + line[1:]) + assert line[0] in ['~', '>'] + stack[-1] += 1 + indent = len(stack) if line.startswith('~') else len(stack) - 1 + result.append(u(' ')*indent + line[1:]) assert len(stack) == 1 return result diff -r 9baf836b29b58c72ffccc113bca3ac54c883caf8 -r f21d976ea15b6819a834ea6dda112e0da9d57d14 doc/en/example/assertion/failure_demo.py --- a/doc/en/example/assertion/failure_demo.py +++ b/doc/en/example/assertion/failure_demo.py @@ -211,3 +211,27 @@ finally: x = 0 + +class TestCustomAssertMsg: + + def test_single_line(self): + class A: + a = 1 + b = 2 + assert A.a == b, "A.a appears not to be b" + + def test_multiline(self): + class A: + a = 1 + b = 2 + assert A.a == b, "A.a appears not to be b\n" \ + "or does not appear to be b\none of those" + + def test_custom_repr(self): + class JSON: + a = 1 + def __repr__(self): + return "This is JSON\n{\n 'foo': 'bar'\n}" + a = JSON() + b = 2 + assert a.a == b, a diff -r 9baf836b29b58c72ffccc113bca3ac54c883caf8 -r f21d976ea15b6819a834ea6dda112e0da9d57d14 testing/test_assertion.py --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -4,6 +4,7 @@ import py, pytest import _pytest.assertion as plugin from _pytest.assertion import reinterpret +from _pytest.assertion import util needsnewassert = pytest.mark.skipif("sys.version_info < (2,6)") @@ -201,7 +202,7 @@ class TestFormatExplanation: - def test_speical_chars_full(self, testdir): + def test_special_chars_full(self, testdir): # Issue 453, for the bug this would raise IndexError testdir.makepyfile(""" def test_foo(): @@ -213,6 +214,83 @@ "*AssertionError*", ]) + def test_fmt_simple(self): + expl = 'assert foo' + assert util.format_explanation(expl) == 'assert foo' + + def test_fmt_where(self): + expl = '\n'.join(['assert 1', + '{1 = foo', + '} == 2']) + res = '\n'.join(['assert 1 == 2', + ' + where 1 = foo']) + assert util.format_explanation(expl) == res + + def test_fmt_and(self): + expl = '\n'.join(['assert 1', + '{1 = foo', + '} == 2', + '{2 = bar', + '}']) + res = '\n'.join(['assert 1 == 2', + ' + where 1 = foo', + ' + and 2 = bar']) + assert util.format_explanation(expl) == res + + def test_fmt_where_nested(self): + expl = '\n'.join(['assert 1', + '{1 = foo', + '{foo = bar', + '}', + '} == 2']) + res = '\n'.join(['assert 1 == 2', + ' + where 1 = foo', + ' + where foo = bar']) + assert util.format_explanation(expl) == res + + def test_fmt_newline(self): + expl = '\n'.join(['assert "foo" == "bar"', + '~- foo', + '~+ bar']) + res = '\n'.join(['assert "foo" == "bar"', + ' - foo', + ' + bar']) + assert util.format_explanation(expl) == res + + def test_fmt_newline_escaped(self): + expl = '\n'.join(['assert foo == bar', + 'baz']) + res = 'assert foo == bar\\nbaz' + assert util.format_explanation(expl) == res + + def test_fmt_newline_before_where(self): + expl = '\n'.join(['the assertion message here', + '>assert 1', + '{1 = foo', + '} == 2', + '{2 = bar', + '}']) + res = '\n'.join(['the assertion message here', + 'assert 1 == 2', + ' + where 1 = foo', + ' + and 2 = bar']) + assert util.format_explanation(expl) == res + + def test_fmt_multi_newline_before_where(self): + expl = '\n'.join(['the assertion', + '~message here', + '>assert 1', + '{1 = foo', + '} == 2', + '{2 = bar', + '}']) + res = '\n'.join(['the assertion', + ' message here', + 'assert 1 == 2', + ' + where 1 = foo', + ' + and 2 = bar']) + assert util.format_explanation(expl) == res + def test_python25_compile_issue257(testdir): testdir.makepyfile(""" diff -r 9baf836b29b58c72ffccc113bca3ac54c883caf8 -r f21d976ea15b6819a834ea6dda112e0da9d57d14 testing/test_assertrewrite.py --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -121,7 +121,56 @@ def test_assert_already_has_message(self): def f(): assert False, "something bad!" - assert getmsg(f) == "AssertionError: something bad!" + assert getmsg(f) == "AssertionError: something bad!\nassert False" + + def test_assertion_message(self, testdir): + testdir.makepyfile(""" + def test_foo(): + assert 1 == 2, "The failure message" + """) + result = testdir.runpytest() + assert result.ret == 1 + result.stdout.fnmatch_lines([ + "*AssertionError*The failure message*", + "*assert 1 == 2*", + ]) + + def test_assertion_message_multiline(self, testdir): + testdir.makepyfile(""" + def test_foo(): + assert 1 == 2, "A multiline\\nfailure message" + """) + result = testdir.runpytest() + assert result.ret == 1 + result.stdout.fnmatch_lines([ + "*AssertionError*A multiline*", + "*failure message*", + "*assert 1 == 2*", + ]) + + def test_assertion_message_tuple(self, testdir): + testdir.makepyfile(""" + def test_foo(): + assert 1 == 2, (1, 2) + """) + result = testdir.runpytest() + assert result.ret == 1 + result.stdout.fnmatch_lines([ + "*AssertionError*%s*" % repr((1, 2)), + "*assert 1 == 2*", + ]) + + def test_assertion_message_expr(self, testdir): + testdir.makepyfile(""" + def test_foo(): + assert 1 == 2, 1 + 2 + """) + result = testdir.runpytest() + assert result.ret == 1 + result.stdout.fnmatch_lines([ + "*AssertionError*3*", + "*assert 1 == 2*", + ]) def test_boolop(self): def f(): https://bitbucket.org/hpk42/pytest/commits/6368cc4ac5dc/ Changeset: 6368cc4ac5dc User: flub Date: 2014-08-23 17:01:26+00:00 Summary: Fix doctest tox run The new failures in the failure demo apparently affect the doctests tox run. Affected #: 1 file diff -r f21d976ea15b6819a834ea6dda112e0da9d57d14 -r 6368cc4ac5dc8f9745450861147056437c03df7f doc/en/example/assertion/test_failures.py --- a/doc/en/example/assertion/test_failures.py +++ b/doc/en/example/assertion/test_failures.py @@ -9,6 +9,6 @@ failure_demo.copy(testdir.tmpdir.join(failure_demo.basename)) result = testdir.runpytest(target) result.stdout.fnmatch_lines([ - "*39 failed*" + "*42 failed*" ]) assert result.ret != 0 https://bitbucket.org/hpk42/pytest/commits/95428e0c36e1/ Changeset: 95428e0c36e1 User: hpk42 Date: 2014-09-22 17:16:10+00:00 Summary: Merged in flub/pytest (pull request #207) Show both user assertion msg as explanation (issue549) Affected #: 7 files diff -r 6b38010df14cc3c57c5034313a1edace19451d52 -r 95428e0c36e169596f8370c6663a99e960c01612 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -42,6 +42,10 @@ other builds due to the extra argparse dependency. Fixes issue566. Thanks sontek. +- Implement issue549: user-provided assertion messages now no longer + replace the py.test instrospection message but are shown in addition + to them. + 2.6.1 ----------------------------------- diff -r 6b38010df14cc3c57c5034313a1edace19451d52 -r 95428e0c36e169596f8370c6663a99e960c01612 _pytest/assertion/rewrite.py --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -351,6 +351,33 @@ from _pytest.assertion.util import format_explanation as _format_explanation # noqa +def _format_assertmsg(obj): + """Format the custom assertion message given. + + For strings this simply replaces newlines with '\n~' so that + util.format_explanation() will preserve them instead of escaping + newlines. For other objects py.io.saferepr() is used first. + + """ + # reprlib appears to have a bug which means that if a string + # contains a newline it gets escaped, however if an object has a + # .__repr__() which contains newlines it does not get escaped. + # However in either case we want to preserve the newline. + if py.builtin._istext(obj) or py.builtin._isbytes(obj): + s = obj + is_repr = False + else: + s = py.io.saferepr(obj) + is_repr = True + if py.builtin._istext(s): + t = py.builtin.text + else: + t = py.builtin.bytes + s = s.replace(t("\n"), t("\n~")) + if is_repr: + s = s.replace(t("\\n"), t("\n~")) + return s + def _should_repr_global_name(obj): return not hasattr(obj, "__name__") and not py.builtin.callable(obj) @@ -419,6 +446,56 @@ class AssertionRewriter(ast.NodeVisitor): + """Assertion rewriting implementation. + + The main entrypoint is to call .run() with an ast.Module instance, + this will then find all the assert statements and re-write them to + provide intermediate values and a detailed assertion error. See + http://pybites.blogspot.be/2011/07/behind-scenes-of-pytests-new-assertion.html + for an overview of how this works. + + The entry point here is .run() which will iterate over all the + statenemts in an ast.Module and for each ast.Assert statement it + finds call .visit() with it. Then .visit_Assert() takes over and + is responsible for creating new ast statements to replace the + original assert statement: it re-writes the test of an assertion + to provide intermediate values and replace it with an if statement + which raises an assertion error with a detailed explanation in + case the expression is false. + + For this .visit_Assert() uses the visitor pattern to visit all the + AST nodes of the ast.Assert.test field, each visit call returning + an AST node and the corresponding explanation string. During this + state is kept in several instance attributes: + + :statements: All the AST statements which will replace the assert + statement. + + :variables: This is populated by .variable() with each variable + used by the statements so that they can all be set to None at + the end of the statements. + + :variable_counter: Counter to create new unique variables needed + by statements. Variables are created using .variable() and + have the form of "@py_assert0". + + :on_failure: The AST statements which will be executed if the + assertion test fails. This is the code which will construct + the failure message and raises the AssertionError. + + :explanation_specifiers: A dict filled by .explanation_param() + with %-formatting placeholders and their corresponding + expressions to use in the building of an assertion message. + This is used by .pop_format_context() to build a message. + + :stack: A stack of the explanation_specifiers dicts maintained by + .push_format_context() and .pop_format_context() which allows + to build another %-formatted string while already building one. + + This state is reset on every new assert statement visited and used + by the other visitors. + + """ def run(self, mod): """Find all assert statements in *mod* and rewrite them.""" @@ -500,15 +577,41 @@ return ast.Attribute(builtin_name, name, ast.Load()) def explanation_param(self, expr): + """Return a new named %-formatting placeholder for expr. + + This creates a %-formatting placeholder for expr in the + current formatting context, e.g. ``%(py0)s``. The placeholder + and expr are placed in the current format context so that it + can be used on the next call to .pop_format_context(). + + """ specifier = "py" + str(next(self.variable_counter)) self.explanation_specifiers[specifier] = expr return "%(" + specifier + ")s" def push_format_context(self): + """Create a new formatting context. + + The format context is used for when an explanation wants to + have a variable value formatted in the assertion message. In + this case the value required can be added using + .explanation_param(). Finally .pop_format_context() is used + to format a string of %-formatted values as added by + .explanation_param(). + + """ self.explanation_specifiers = {} self.stack.append(self.explanation_specifiers) def pop_format_context(self, expl_expr): + """Format the %-formatted string with current format context. + + The expl_expr should be an ast.Str instance constructed from + the %-placeholders created by .explanation_param(). This will + add the required code to format said string to .on_failure and + return the ast.Name instance of the formatted string. + + """ current = self.stack.pop() if self.stack: self.explanation_specifiers = self.stack[-1] @@ -526,11 +629,15 @@ return res, self.explanation_param(self.display(res)) def visit_Assert(self, assert_): - if assert_.msg: - # There's already a message. Don't mess with it. - return [assert_] + """Return the AST statements to replace the ast.Assert instance. + + This re-writes the test of an assertion to provide + intermediate values and replace it with an if statement which + raises an assertion error with a detailed explanation in case + the expression is false. + + """ self.statements = [] - self.cond_chain = () self.variables = [] self.variable_counter = itertools.count() self.stack = [] @@ -542,8 +649,13 @@ body = self.on_failure negation = ast.UnaryOp(ast.Not(), top_condition) self.statements.append(ast.If(negation, body, [])) - explanation = "assert " + explanation - template = ast.Str(explanation) + if assert_.msg: + assertmsg = self.helper('format_assertmsg', assert_.msg) + explanation = "\n>assert " + explanation + else: + assertmsg = ast.Str("") + explanation = "assert " + explanation + template = ast.BinOp(assertmsg, ast.Add(), ast.Str(explanation)) msg = self.pop_format_context(template) fmt = self.helper("format_explanation", msg) err_name = ast.Name("AssertionError", ast.Load()) diff -r 6b38010df14cc3c57c5034313a1edace19451d52 -r 95428e0c36e169596f8370c6663a99e960c01612 _pytest/assertion/util.py --- a/_pytest/assertion/util.py +++ b/_pytest/assertion/util.py @@ -73,7 +73,7 @@ raw_lines = (explanation or u('')).split('\n') lines = [raw_lines[0]] for l in raw_lines[1:]: - if l.startswith('{') or l.startswith('}') or l.startswith('~'): + if l and l[0] in ['{', '}', '~', '>']: lines.append(l) else: lines[-1] += '\\n' + l @@ -103,13 +103,14 @@ stackcnt.append(0) result.append(u(' +') + u(' ')*(len(stack)-1) + s + line[1:]) elif line.startswith('}'): - assert line.startswith('}') stack.pop() stackcnt.pop() result[stack[-1]] += line[1:] else: - assert line.startswith('~') - result.append(u(' ')*len(stack) + line[1:]) + assert line[0] in ['~', '>'] + stack[-1] += 1 + indent = len(stack) if line.startswith('~') else len(stack) - 1 + result.append(u(' ')*indent + line[1:]) assert len(stack) == 1 return result diff -r 6b38010df14cc3c57c5034313a1edace19451d52 -r 95428e0c36e169596f8370c6663a99e960c01612 doc/en/example/assertion/failure_demo.py --- a/doc/en/example/assertion/failure_demo.py +++ b/doc/en/example/assertion/failure_demo.py @@ -211,3 +211,27 @@ finally: x = 0 + +class TestCustomAssertMsg: + + def test_single_line(self): + class A: + a = 1 + b = 2 + assert A.a == b, "A.a appears not to be b" + + def test_multiline(self): + class A: + a = 1 + b = 2 + assert A.a == b, "A.a appears not to be b\n" \ + "or does not appear to be b\none of those" + + def test_custom_repr(self): + class JSON: + a = 1 + def __repr__(self): + return "This is JSON\n{\n 'foo': 'bar'\n}" + a = JSON() + b = 2 + assert a.a == b, a diff -r 6b38010df14cc3c57c5034313a1edace19451d52 -r 95428e0c36e169596f8370c6663a99e960c01612 doc/en/example/assertion/test_failures.py --- a/doc/en/example/assertion/test_failures.py +++ b/doc/en/example/assertion/test_failures.py @@ -9,6 +9,6 @@ failure_demo.copy(testdir.tmpdir.join(failure_demo.basename)) result = testdir.runpytest(target) result.stdout.fnmatch_lines([ - "*39 failed*" + "*42 failed*" ]) assert result.ret != 0 diff -r 6b38010df14cc3c57c5034313a1edace19451d52 -r 95428e0c36e169596f8370c6663a99e960c01612 testing/test_assertion.py --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -4,6 +4,7 @@ import py, pytest import _pytest.assertion as plugin from _pytest.assertion import reinterpret +from _pytest.assertion import util needsnewassert = pytest.mark.skipif("sys.version_info < (2,6)") @@ -201,7 +202,7 @@ class TestFormatExplanation: - def test_speical_chars_full(self, testdir): + def test_special_chars_full(self, testdir): # Issue 453, for the bug this would raise IndexError testdir.makepyfile(""" def test_foo(): @@ -213,6 +214,83 @@ "*AssertionError*", ]) + def test_fmt_simple(self): + expl = 'assert foo' + assert util.format_explanation(expl) == 'assert foo' + + def test_fmt_where(self): + expl = '\n'.join(['assert 1', + '{1 = foo', + '} == 2']) + res = '\n'.join(['assert 1 == 2', + ' + where 1 = foo']) + assert util.format_explanation(expl) == res + + def test_fmt_and(self): + expl = '\n'.join(['assert 1', + '{1 = foo', + '} == 2', + '{2 = bar', + '}']) + res = '\n'.join(['assert 1 == 2', + ' + where 1 = foo', + ' + and 2 = bar']) + assert util.format_explanation(expl) == res + + def test_fmt_where_nested(self): + expl = '\n'.join(['assert 1', + '{1 = foo', + '{foo = bar', + '}', + '} == 2']) + res = '\n'.join(['assert 1 == 2', + ' + where 1 = foo', + ' + where foo = bar']) + assert util.format_explanation(expl) == res + + def test_fmt_newline(self): + expl = '\n'.join(['assert "foo" == "bar"', + '~- foo', + '~+ bar']) + res = '\n'.join(['assert "foo" == "bar"', + ' - foo', + ' + bar']) + assert util.format_explanation(expl) == res + + def test_fmt_newline_escaped(self): + expl = '\n'.join(['assert foo == bar', + 'baz']) + res = 'assert foo == bar\\nbaz' + assert util.format_explanation(expl) == res + + def test_fmt_newline_before_where(self): + expl = '\n'.join(['the assertion message here', + '>assert 1', + '{1 = foo', + '} == 2', + '{2 = bar', + '}']) + res = '\n'.join(['the assertion message here', + 'assert 1 == 2', + ' + where 1 = foo', + ' + and 2 = bar']) + assert util.format_explanation(expl) == res + + def test_fmt_multi_newline_before_where(self): + expl = '\n'.join(['the assertion', + '~message here', + '>assert 1', + '{1 = foo', + '} == 2', + '{2 = bar', + '}']) + res = '\n'.join(['the assertion', + ' message here', + 'assert 1 == 2', + ' + where 1 = foo', + ' + and 2 = bar']) + assert util.format_explanation(expl) == res + def test_python25_compile_issue257(testdir): testdir.makepyfile(""" diff -r 6b38010df14cc3c57c5034313a1edace19451d52 -r 95428e0c36e169596f8370c6663a99e960c01612 testing/test_assertrewrite.py --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -121,7 +121,56 @@ def test_assert_already_has_message(self): def f(): assert False, "something bad!" - assert getmsg(f) == "AssertionError: something bad!" + assert getmsg(f) == "AssertionError: something bad!\nassert False" + + def test_assertion_message(self, testdir): + testdir.makepyfile(""" + def test_foo(): + assert 1 == 2, "The failure message" + """) + result = testdir.runpytest() + assert result.ret == 1 + result.stdout.fnmatch_lines([ + "*AssertionError*The failure message*", + "*assert 1 == 2*", + ]) + + def test_assertion_message_multiline(self, testdir): + testdir.makepyfile(""" + def test_foo(): + assert 1 == 2, "A multiline\\nfailure message" + """) + result = testdir.runpytest() + assert result.ret == 1 + result.stdout.fnmatch_lines([ + "*AssertionError*A multiline*", + "*failure message*", + "*assert 1 == 2*", + ]) + + def test_assertion_message_tuple(self, testdir): + testdir.makepyfile(""" + def test_foo(): + assert 1 == 2, (1, 2) + """) + result = testdir.runpytest() + assert result.ret == 1 + result.stdout.fnmatch_lines([ + "*AssertionError*%s*" % repr((1, 2)), + "*assert 1 == 2*", + ]) + + def test_assertion_message_expr(self, testdir): + testdir.makepyfile(""" + def test_foo(): + assert 1 == 2, 1 + 2 + """) + result = testdir.runpytest() + assert result.ret == 1 + result.stdout.fnmatch_lines([ + "*AssertionError*3*", + "*assert 1 == 2*", + ]) def test_boolop(self): def f(): 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 Sep 22 19:25:40 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 22 Sep 2014 17:25:40 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: Merged in nicoddemus/pytest (pull request #203) Message-ID: <20140922172540.22929.77711@app06.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/68fd027f0037/ Changeset: 68fd027f0037 User: hpk42 Date: 2014-09-22 17:25:34+00:00 Summary: Merged in nicoddemus/pytest (pull request #203) fix issue575: xunit-xml reporting collection errors as failures Affected #: 3 files diff -r 95428e0c36e169596f8370c6663a99e960c01612 -r 68fd027f00370ce8ddb5d1912d80ee0d8c63cbf5 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,9 @@ NEXT ----------- +- fix issue575: xunit-xml was reporting collection errors as failures + instead of errors, thanks Oleg Sinyavskiy. + - fix issue582: fix setuptools example, thanks Laszlo Papp and Ronny Pfannschmidt. diff -r 95428e0c36e169596f8370c6663a99e960c01612 -r 68fd027f00370ce8ddb5d1912d80ee0d8c63cbf5 _pytest/junitxml.py --- a/_pytest/junitxml.py +++ b/_pytest/junitxml.py @@ -129,10 +129,10 @@ self.failed += 1 self._write_captured_output(report) - def append_collect_failure(self, report): + def append_collect_error(self, report): #msg = str(report.longrepr.reprtraceback.extraline) - self.append(Junit.failure(bin_xml_escape(report.longrepr), - message="collection failure")) + self.append(Junit.error(bin_xml_escape(report.longrepr), + message="collection failure")) self.errors += 1 def append_collect_skipped(self, report): @@ -181,7 +181,7 @@ if not report.passed: self._opentestcase(report) if report.failed: - self.append_collect_failure(report) + self.append_collect_error(report) else: self.append_collect_skipped(report) diff -r 95428e0c36e169596f8370c6663a99e960c01612 -r 68fd027f00370ce8ddb5d1912d80ee0d8c63cbf5 testing/test_junitxml.py --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -252,7 +252,7 @@ assert_attr(tnode, #classname="test_collect_error", name="test_collect_error") - fnode = tnode.getElementsByTagName("failure")[0] + fnode = tnode.getElementsByTagName("error")[0] assert_attr(fnode, message="collection failure") assert "SyntaxError" in fnode.toxml() @@ -489,7 +489,7 @@ log.pytest_sessionstart() log._opentestcase(report) log.append_failure(report) - log.append_collect_failure(report) + log.append_collect_error(report) log.append_collect_skipped(report) log.append_error(report) report.longrepr = "filename", 1, ustr 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 Sep 22 19:25:40 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 22 Sep 2014 17:25:40 -0000 Subject: [Pytest-commit] commit/pytest: 2 new changesets Message-ID: <20140922172540.16370.40219@app08.ash-private.bitbucket.org> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/789f64c851d5/ Changeset: 789f64c851d5 User: nicoddemus Date: 2014-09-16 01:04:46+00:00 Summary: fix issue575: xunit-xml reporting collection errors as failures Affected #: 3 files diff -r 81d45151f455fd7ca06501bb2a895ac0feb54bd2 -r 789f64c851d59e38a5860d198b5d71e96963ffe5 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,9 @@ NEXT ----------- +- fix issue575: xunit-xml was reporting collection errors as failures + instead of errors, thanks Oleg Sinyavskiy. + - fix issue582: fix setuptools example, thanks Laszlo Papp and Ronny Pfannschmidt. diff -r 81d45151f455fd7ca06501bb2a895ac0feb54bd2 -r 789f64c851d59e38a5860d198b5d71e96963ffe5 _pytest/junitxml.py --- a/_pytest/junitxml.py +++ b/_pytest/junitxml.py @@ -129,10 +129,10 @@ self.failed += 1 self._write_captured_output(report) - def append_collect_failure(self, report): + def append_collect_error(self, report): #msg = str(report.longrepr.reprtraceback.extraline) - self.append(Junit.failure(bin_xml_escape(report.longrepr), - message="collection failure")) + self.append(Junit.error(bin_xml_escape(report.longrepr), + message="collection failure")) self.errors += 1 def append_collect_skipped(self, report): @@ -181,7 +181,7 @@ if not report.passed: self._opentestcase(report) if report.failed: - self.append_collect_failure(report) + self.append_collect_error(report) else: self.append_collect_skipped(report) diff -r 81d45151f455fd7ca06501bb2a895ac0feb54bd2 -r 789f64c851d59e38a5860d198b5d71e96963ffe5 testing/test_junitxml.py --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -252,7 +252,7 @@ assert_attr(tnode, #classname="test_collect_error", name="test_collect_error") - fnode = tnode.getElementsByTagName("failure")[0] + fnode = tnode.getElementsByTagName("error")[0] assert_attr(fnode, message="collection failure") assert "SyntaxError" in fnode.toxml() @@ -489,7 +489,7 @@ log.pytest_sessionstart() log._opentestcase(report) log.append_failure(report) - log.append_collect_failure(report) + log.append_collect_error(report) log.append_collect_skipped(report) log.append_error(report) report.longrepr = "filename", 1, ustr https://bitbucket.org/hpk42/pytest/commits/68fd027f0037/ Changeset: 68fd027f0037 User: hpk42 Date: 2014-09-22 17:25:34+00:00 Summary: Merged in nicoddemus/pytest (pull request #203) fix issue575: xunit-xml reporting collection errors as failures Affected #: 3 files diff -r 95428e0c36e169596f8370c6663a99e960c01612 -r 68fd027f00370ce8ddb5d1912d80ee0d8c63cbf5 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,9 @@ NEXT ----------- +- fix issue575: xunit-xml was reporting collection errors as failures + instead of errors, thanks Oleg Sinyavskiy. + - fix issue582: fix setuptools example, thanks Laszlo Papp and Ronny Pfannschmidt. diff -r 95428e0c36e169596f8370c6663a99e960c01612 -r 68fd027f00370ce8ddb5d1912d80ee0d8c63cbf5 _pytest/junitxml.py --- a/_pytest/junitxml.py +++ b/_pytest/junitxml.py @@ -129,10 +129,10 @@ self.failed += 1 self._write_captured_output(report) - def append_collect_failure(self, report): + def append_collect_error(self, report): #msg = str(report.longrepr.reprtraceback.extraline) - self.append(Junit.failure(bin_xml_escape(report.longrepr), - message="collection failure")) + self.append(Junit.error(bin_xml_escape(report.longrepr), + message="collection failure")) self.errors += 1 def append_collect_skipped(self, report): @@ -181,7 +181,7 @@ if not report.passed: self._opentestcase(report) if report.failed: - self.append_collect_failure(report) + self.append_collect_error(report) else: self.append_collect_skipped(report) diff -r 95428e0c36e169596f8370c6663a99e960c01612 -r 68fd027f00370ce8ddb5d1912d80ee0d8c63cbf5 testing/test_junitxml.py --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -252,7 +252,7 @@ assert_attr(tnode, #classname="test_collect_error", name="test_collect_error") - fnode = tnode.getElementsByTagName("failure")[0] + fnode = tnode.getElementsByTagName("error")[0] assert_attr(fnode, message="collection failure") assert "SyntaxError" in fnode.toxml() @@ -489,7 +489,7 @@ log.pytest_sessionstart() log._opentestcase(report) log.append_failure(report) - log.append_collect_failure(report) + log.append_collect_error(report) log.append_collect_skipped(report) log.append_error(report) report.longrepr = "filename", 1, ustr 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 issues-reply at bitbucket.org Tue Sep 23 12:59:32 2014 From: issues-reply at bitbucket.org (David Szotten) Date: Tue, 23 Sep 2014 10:59:32 -0000 Subject: [Pytest-commit] Issue #595: junitxml make verbose output opt-in (hpk42/pytest) Message-ID: <20140923105932.11147.63961@app05.ash-private.bitbucket.org> New issue 595: junitxml make verbose output opt-in https://bitbucket.org/hpk42/pytest/issue/595/junitxml-make-verbose-output-opt-in David Szotten: 6954363 changed junitxml to include captured output for passing and skipped tests in the output by default. this makes the xml unnecessarily large for our use cases i think this behaviour should become opt-in (or at the very least add opt-out) feature is easy to add, but my issue was with giving this a good option name. i was also slightly concerned with growing the already large list of options with parameters that only apply when already using --junitxml are there any plans for grouping/namespacing options (so that a top level --help would be less verbose) and setting aside the digression, any thoughts on making this opt-in (and if so, of a good option name. so far considered junitxml-verbose-output, junitxml-always-include-output; just using the --verbose flag (don't like that)) thanks From commits-noreply at bitbucket.org Tue Sep 23 14:04:52 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 23 Sep 2014 12:04:52 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: Merged in wosc/pytest (pull request #204) Message-ID: <20140923120452.8447.68393@app09.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/0bef852667d6/ Changeset: 0bef852667d6 User: hpk42 Date: 2014-09-23 12:04:47+00:00 Summary: Merged in wosc/pytest (pull request #204) Introduce pytest_enter_pdb hook Affected #: 4 files diff -r 68fd027f00370ce8ddb5d1912d80ee0d8c63cbf5 -r 0bef852667d6893f66fb9015000bb88642c704e4 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,8 @@ CWD outside a test package pytest would get fixture discovery wrong. Thanks to Wolfgang Schnerring for figuring out a reproducable example. +- Introduce pytest_enter_pdb hook (needed e.g. by pytest_timeout to cancel the + timeout when interactively entering pdb). 2.6.2 ----------- diff -r 68fd027f00370ce8ddb5d1912d80ee0d8c63cbf5 -r 0bef852667d6893f66fb9015000bb88642c704e4 _pytest/hookspec.py --- a/_pytest/hookspec.py +++ b/_pytest/hookspec.py @@ -262,3 +262,5 @@ that is not an internal exception like "skip.Exception". """ +def pytest_enter_pdb(): + """ called upon pdb.set_trace()""" diff -r 68fd027f00370ce8ddb5d1912d80ee0d8c63cbf5 -r 0bef852667d6893f66fb9015000bb88642c704e4 _pytest/pdb.py --- a/_pytest/pdb.py +++ b/_pytest/pdb.py @@ -42,6 +42,7 @@ tw = py.io.TerminalWriter() tw.line() tw.sep(">", "PDB set_trace (IO-capturing turned off)") + self._pluginmanager.hook.pytest_enter_pdb() pdb.Pdb().set_trace(frame) diff -r 68fd027f00370ce8ddb5d1912d80ee0d8c63cbf5 -r 0bef852667d6893f66fb9015000bb88642c704e4 testing/test_pdb.py --- a/testing/test_pdb.py +++ b/testing/test_pdb.py @@ -267,3 +267,21 @@ "*NameError*xxx*", "*1 error*", ]) + + def test_enter_pdb_hook_is_called(self, testdir): + testdir.makeconftest(""" + def pytest_enter_pdb(): + print 'enter_pdb_hook' + """) + p1 = testdir.makepyfile(""" + import pytest + + def test_foo(): + pytest.set_trace() + """) + child = testdir.spawn_pytest(str(p1)) + child.expect("enter_pdb_hook") + child.send('c\n') + child.sendeof() + if child.isalive(): + child.wait() 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 Sep 23 14:04:52 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 23 Sep 2014 12:04:52 -0000 Subject: [Pytest-commit] commit/pytest: 2 new changesets Message-ID: <20140923120452.30866.53304@app07.ash-private.bitbucket.org> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/1db438ef3aa1/ Changeset: 1db438ef3aa1 User: wosc Date: 2014-09-18 12:58:42+00:00 Summary: Introduce pytest_enter_pdb hook Affected #: 4 files diff -r 81d45151f455fd7ca06501bb2a895ac0feb54bd2 -r 1db438ef3aa1246cd457dc0fa0815a245e6ecb8a CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -16,6 +16,8 @@ CWD outside a test package pytest would get fixture discovery wrong. Thanks to Wolfgang Schnerring for figuring out a reproducable example. +- Introduce pytest_enter_pdb hook (needed e.g. by pytest_timeout to cancel the + timeout when interactively entering pdb). 2.6.2 ----------- diff -r 81d45151f455fd7ca06501bb2a895ac0feb54bd2 -r 1db438ef3aa1246cd457dc0fa0815a245e6ecb8a _pytest/hookspec.py --- a/_pytest/hookspec.py +++ b/_pytest/hookspec.py @@ -262,3 +262,5 @@ that is not an internal exception like "skip.Exception". """ +def pytest_enter_pdb(): + """ called upon pdb.set_trace()""" diff -r 81d45151f455fd7ca06501bb2a895ac0feb54bd2 -r 1db438ef3aa1246cd457dc0fa0815a245e6ecb8a _pytest/pdb.py --- a/_pytest/pdb.py +++ b/_pytest/pdb.py @@ -42,6 +42,7 @@ tw = py.io.TerminalWriter() tw.line() tw.sep(">", "PDB set_trace (IO-capturing turned off)") + self._pluginmanager.hook.pytest_enter_pdb() pdb.Pdb().set_trace(frame) diff -r 81d45151f455fd7ca06501bb2a895ac0feb54bd2 -r 1db438ef3aa1246cd457dc0fa0815a245e6ecb8a testing/test_pdb.py --- a/testing/test_pdb.py +++ b/testing/test_pdb.py @@ -267,3 +267,21 @@ "*NameError*xxx*", "*1 error*", ]) + + def test_enter_pdb_hook_is_called(self, testdir): + testdir.makeconftest(""" + def pytest_enter_pdb(): + print 'enter_pdb_hook' + """) + p1 = testdir.makepyfile(""" + import pytest + + def test_foo(): + pytest.set_trace() + """) + child = testdir.spawn_pytest(str(p1)) + child.expect("enter_pdb_hook") + child.send('c\n') + child.sendeof() + if child.isalive(): + child.wait() https://bitbucket.org/hpk42/pytest/commits/0bef852667d6/ Changeset: 0bef852667d6 User: hpk42 Date: 2014-09-23 12:04:47+00:00 Summary: Merged in wosc/pytest (pull request #204) Introduce pytest_enter_pdb hook Affected #: 4 files diff -r 68fd027f00370ce8ddb5d1912d80ee0d8c63cbf5 -r 0bef852667d6893f66fb9015000bb88642c704e4 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,8 @@ CWD outside a test package pytest would get fixture discovery wrong. Thanks to Wolfgang Schnerring for figuring out a reproducable example. +- Introduce pytest_enter_pdb hook (needed e.g. by pytest_timeout to cancel the + timeout when interactively entering pdb). 2.6.2 ----------- diff -r 68fd027f00370ce8ddb5d1912d80ee0d8c63cbf5 -r 0bef852667d6893f66fb9015000bb88642c704e4 _pytest/hookspec.py --- a/_pytest/hookspec.py +++ b/_pytest/hookspec.py @@ -262,3 +262,5 @@ that is not an internal exception like "skip.Exception". """ +def pytest_enter_pdb(): + """ called upon pdb.set_trace()""" diff -r 68fd027f00370ce8ddb5d1912d80ee0d8c63cbf5 -r 0bef852667d6893f66fb9015000bb88642c704e4 _pytest/pdb.py --- a/_pytest/pdb.py +++ b/_pytest/pdb.py @@ -42,6 +42,7 @@ tw = py.io.TerminalWriter() tw.line() tw.sep(">", "PDB set_trace (IO-capturing turned off)") + self._pluginmanager.hook.pytest_enter_pdb() pdb.Pdb().set_trace(frame) diff -r 68fd027f00370ce8ddb5d1912d80ee0d8c63cbf5 -r 0bef852667d6893f66fb9015000bb88642c704e4 testing/test_pdb.py --- a/testing/test_pdb.py +++ b/testing/test_pdb.py @@ -267,3 +267,21 @@ "*NameError*xxx*", "*1 error*", ]) + + def test_enter_pdb_hook_is_called(self, testdir): + testdir.makeconftest(""" + def pytest_enter_pdb(): + print 'enter_pdb_hook' + """) + p1 = testdir.makepyfile(""" + import pytest + + def test_foo(): + pytest.set_trace() + """) + child = testdir.spawn_pytest(str(p1)) + child.expect("enter_pdb_hook") + child.send('c\n') + child.sendeof() + if child.isalive(): + child.wait() 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 Sep 23 15:44:16 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 23 Sep 2014 13:44:16 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: mention Wolfang wrt pytest_enter_pdb Message-ID: <20140923134416.24199.40322@app10.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/fcfcf15459f0/ Changeset: fcfcf15459f0 User: hpk42 Date: 2014-09-23 13:43:46+00:00 Summary: mention Wolfang wrt pytest_enter_pdb Affected #: 1 file diff -r 0bef852667d6893f66fb9015000bb88642c704e4 -r fcfcf15459f0e4ab43e8784befcd83ded913c8b2 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -20,7 +20,7 @@ Thanks to Wolfgang Schnerring for figuring out a reproducable example. - Introduce pytest_enter_pdb hook (needed e.g. by pytest_timeout to cancel the - timeout when interactively entering pdb). + timeout when interactively entering pdb). Thanks Wolfgang Schnerring. 2.6.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 issues-reply at bitbucket.org Tue Sep 23 15:55:51 2014 From: issues-reply at bitbucket.org (liori) Date: Tue, 23 Sep 2014 13:55:51 -0000 Subject: [Pytest-commit] Issue #596: xdist is not executing tests if their parametrizations were collected in a different order (hpk42/pytest) Message-ID: <20140923135551.15995.97340@app12.ash-private.bitbucket.org> New issue 596: xdist is not executing tests if their parametrizations were collected in a different order https://bitbucket.org/hpk42/pytest/issue/596/xdist-is-not-executing-tests-if-their liori: Related to #594, but slightly different. I generated by parametrizations by iterating over a set of strings. However, this iteration depends on the specific values the strings hash to, and these values might be different for every process. Therefore, whereas I was always generating exactly the same parametrizations, they were in different order. A simple test case that shows the problem: ``` #!python import pytest my_names = {'john', 'kate', 'alfred', 'paul', 'mary'} @pytest.mark.parametrize('name', list(my_names), ids=list(my_names)) def test_is_name_short(name): assert len(name) < 7 ``` Run with `PYTHONHASHSEED=random py.test -n 4` to make sure you trigger randomized hashing for strings. I think that a simple `sort` in `report_collection_diff` before running `unified_diff` might help with this problem. From commits-noreply at bitbucket.org Tue Sep 23 16:05:59 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 23 Sep 2014 14:05:59 -0000 Subject: [Pytest-commit] commit/tox: hpk42: fix issue188 make boolean config vars use the default if the config file Message-ID: <20140923140559.23581.79047@app13.ash-private.bitbucket.org> 1 new commit in tox: https://bitbucket.org/hpk42/tox/commits/c32a8d4463f5/ Changeset: c32a8d4463f5 User: hpk42 Date: 2014-09-23 14:04:03+00:00 Summary: fix issue188 make boolean config vars use the default if the config file specifies an empty string Affected #: 5 files diff -r 413683ebbed09f1befde1219f3d02049b9818338 -r c32a8d4463f5f38036c7d86c25f2f51ffdc4bdd4 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -3,11 +3,13 @@ - new multi-dimensional configuration support. Many thanks to Alexander Schepanovski for the complete PR with docs. + And to Mike Bayer for filing an issue wrt to setting booleans. - fix issue148: remove "__PYVENV_LAUNCHER__" from os.environ when starting subprocesses. Thanks Steven Myint. + 1.7.2 ----------- diff -r 413683ebbed09f1befde1219f3d02049b9818338 -r c32a8d4463f5f38036c7d86c25f2f51ffdc4bdd4 setup.py --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ description='virtualenv-based automation of test activities', long_description=open("README.rst").read(), url='http://tox.testrun.org/', - version='1.8.0.dev1', + version='1.8.0.dev2', license='http://opensource.org/licenses/MIT', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], author='holger krekel', diff -r 413683ebbed09f1befde1219f3d02049b9818338 -r c32a8d4463f5f38036c7d86c25f2f51ffdc4bdd4 tests/test_config.py --- a/tests/test_config.py +++ b/tests/test_config.py @@ -882,6 +882,21 @@ for name, config in configs.items(): assert config.basepython == 'python%s.%s' % (name[2], name[3]) + @pytest.mark.issue188 + def test_factors_in_boolean(self, newconfig): + inisource=""" + [tox] + envlist = py{27,33} + + [testenv] + recreate = + py27: True + """ + configs = newconfig([], inisource).envconfigs + assert configs["py27"].recreate + assert not configs["py33"].recreate + + class TestGlobalOptions: def test_notest(self, newconfig): config = newconfig([], "") diff -r 413683ebbed09f1befde1219f3d02049b9818338 -r c32a8d4463f5f38036c7d86c25f2f51ffdc4bdd4 tox/__init__.py --- a/tox/__init__.py +++ b/tox/__init__.py @@ -1,5 +1,5 @@ # -__version__ = '1.8.0.dev1' +__version__ = '1.8.0.dev2' class exception: class Error(Exception): diff -r 413683ebbed09f1befde1219f3d02049b9818338 -r c32a8d4463f5f38036c7d86c25f2f51ffdc4bdd4 tox/_config.py --- a/tox/_config.py +++ b/tox/_config.py @@ -596,9 +596,12 @@ def getbool(self, section, name, default=None): s = self.getdefault(section, name, default) + if not s: + s = default if s is None: raise KeyError("no config value [%s] %s found" % ( section, name)) + if not isinstance(s, bool): if s.lower() == "true": s = True Repository URL: https://bitbucket.org/hpk42/tox/ -- 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 Sep 23 16:09:00 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 23 Sep 2014 14:09:00 -0000 Subject: [Pytest-commit] commit/tox: 2 new changesets Message-ID: <20140923140900.12388.94942@app11.ash-private.bitbucket.org> 2 new commits in tox: https://bitbucket.org/hpk42/tox/commits/f4d318abc49f/ Changeset: f4d318abc49f User: ludwigf Date: 2014-07-24 15:31:35+00:00 Summary: set VIRTUAL_ENV for test commands Affected #: 1 file diff -r 27b38ca7904a514f5b9e51e3570fac218b522737 -r f4d318abc49fc52617628d7568dfdb22f355784a tox/_venv.py --- a/tox/_venv.py +++ b/tox/_venv.py @@ -320,6 +320,7 @@ setenv = self.envconfig.setenv if setenv: env.update(setenv) + env['VIRTUAL_ENV'] = str(self.path) env.update(extraenv) return env https://bitbucket.org/hpk42/tox/commits/399ecae24b33/ Changeset: 399ecae24b33 User: hpk42 Date: 2014-09-23 14:08:54+00:00 Summary: Merged in ludwigf/tox (pull request #114) set VIRTUAL_ENV for test commands Affected #: 1 file diff -r c32a8d4463f5f38036c7d86c25f2f51ffdc4bdd4 -r 399ecae24b33db95199de1a64849f7c15610303d tox/_venv.py --- a/tox/_venv.py +++ b/tox/_venv.py @@ -324,6 +324,7 @@ setenv = self.envconfig.setenv if setenv: env.update(setenv) + env['VIRTUAL_ENV'] = str(self.path) env.update(extraenv) return env Repository URL: https://bitbucket.org/hpk42/tox/ -- 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 Sep 23 16:09:00 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 23 Sep 2014 14:09:00 -0000 Subject: [Pytest-commit] commit/tox: hpk42: Merged in ludwigf/tox (pull request #114) Message-ID: <20140923140900.20354.95363@app05.ash-private.bitbucket.org> 1 new commit in tox: https://bitbucket.org/hpk42/tox/commits/399ecae24b33/ Changeset: 399ecae24b33 User: hpk42 Date: 2014-09-23 14:08:54+00:00 Summary: Merged in ludwigf/tox (pull request #114) set VIRTUAL_ENV for test commands Affected #: 1 file diff -r c32a8d4463f5f38036c7d86c25f2f51ffdc4bdd4 -r 399ecae24b33db95199de1a64849f7c15610303d tox/_venv.py --- a/tox/_venv.py +++ b/tox/_venv.py @@ -324,6 +324,7 @@ setenv = self.envconfig.setenv if setenv: env.update(setenv) + env['VIRTUAL_ENV'] = str(self.path) env.update(extraenv) return env Repository URL: https://bitbucket.org/hpk42/tox/ -- 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 Sep 23 16:21:09 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 23 Sep 2014 14:21:09 -0000 Subject: [Pytest-commit] commit/tox: hpk42: fix issue152: set VIRTUAL_ENV when running test commands, Message-ID: <20140923142109.22542.20632@app12.ash-private.bitbucket.org> 1 new commit in tox: https://bitbucket.org/hpk42/tox/commits/35e3076d3c77/ Changeset: 35e3076d3c77 User: hpk42 Date: 2014-09-23 14:20:43+00:00 Summary: fix issue152: set VIRTUAL_ENV when running test commands, thanks Florian Ludwig. Affected #: 2 files diff -r 399ecae24b33db95199de1a64849f7c15610303d -r 35e3076d3c770b0180da25bedb66a21e82b75994 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -8,6 +8,8 @@ - fix issue148: remove "__PYVENV_LAUNCHER__" from os.environ when starting subprocesses. Thanks Steven Myint. +- fix issue152: set VIRTUAL_ENV when running test commands, + thanks Florian Ludwig. 1.7.2 diff -r 399ecae24b33db95199de1a64849f7c15610303d -r 35e3076d3c770b0180da25bedb66a21e82b75994 tests/test_venv.py --- a/tests/test_venv.py +++ b/tests/test_venv.py @@ -513,6 +513,7 @@ assert env is not None assert 'ENV_VAR' in env assert env['ENV_VAR'] == 'value' + assert env['VIRTUAL_ENV'] == str(venv.path) for e in os.environ: assert e in env Repository URL: https://bitbucket.org/hpk42/tox/ -- 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 Sep 23 16:36:43 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 23 Sep 2014 14:36:43 -0000 Subject: [Pytest-commit] commit/tox: 2 new changesets Message-ID: <20140923143643.16303.20081@app07.ash-private.bitbucket.org> 2 new commits in tox: https://bitbucket.org/hpk42/tox/commits/085b6e2547b3/ Changeset: 085b6e2547b3 User: flub Date: 2014-09-08 21:24:36+00:00 Summary: Better error reporting for a bad interpreter When an interpreter's binary exists but no valid version_info is extracted the error message right now simply says <2.5 is not supported which is not very helpful. This tries to improve the error reporting for this case. Affected #: 1 file diff -r 413683ebbed09f1befde1219f3d02049b9818338 -r 085b6e2547b393671e445739a5d693041668a8b2 tox/_config.py --- a/tox/_config.py +++ b/tox/_config.py @@ -184,6 +184,9 @@ info = self.config.interpreters.get_info(self.basepython) if not info.executable: raise tox.exception.InterpreterNotFound(self.basepython) + if not info.version_info: + raise tox.exception.InvocationError( + 'Failed to get version_info for %s: %s' % (info.name, info.err)) if info.version_info < (2,6): raise tox.exception.UnsupportedInterpreter( "python2.5 is not supported anymore, sorry") https://bitbucket.org/hpk42/tox/commits/9dd51ef1cdbb/ Changeset: 9dd51ef1cdbb User: hpk42 Date: 2014-09-23 14:36:38+00:00 Summary: Merged in flub/tox (pull request #119) Better error reporting for a bad interpreter Affected #: 1 file diff -r 35e3076d3c770b0180da25bedb66a21e82b75994 -r 9dd51ef1cdbb000809b509dffd79288453155e85 tox/_config.py --- a/tox/_config.py +++ b/tox/_config.py @@ -184,6 +184,9 @@ info = self.config.interpreters.get_info(self.basepython) if not info.executable: raise tox.exception.InterpreterNotFound(self.basepython) + if not info.version_info: + raise tox.exception.InvocationError( + 'Failed to get version_info for %s: %s' % (info.name, info.err)) if info.version_info < (2,6): raise tox.exception.UnsupportedInterpreter( "python2.5 is not supported anymore, sorry") Repository URL: https://bitbucket.org/hpk42/tox/ -- 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 Sep 23 16:36:44 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 23 Sep 2014 14:36:44 -0000 Subject: [Pytest-commit] commit/tox: hpk42: Merged in flub/tox (pull request #119) Message-ID: <20140923143644.17893.29966@app14.ash-private.bitbucket.org> 1 new commit in tox: https://bitbucket.org/hpk42/tox/commits/9dd51ef1cdbb/ Changeset: 9dd51ef1cdbb User: hpk42 Date: 2014-09-23 14:36:38+00:00 Summary: Merged in flub/tox (pull request #119) Better error reporting for a bad interpreter Affected #: 1 file diff -r 35e3076d3c770b0180da25bedb66a21e82b75994 -r 9dd51ef1cdbb000809b509dffd79288453155e85 tox/_config.py --- a/tox/_config.py +++ b/tox/_config.py @@ -184,6 +184,9 @@ info = self.config.interpreters.get_info(self.basepython) if not info.executable: raise tox.exception.InterpreterNotFound(self.basepython) + if not info.version_info: + raise tox.exception.InvocationError( + 'Failed to get version_info for %s: %s' % (info.name, info.err)) if info.version_info < (2,6): raise tox.exception.UnsupportedInterpreter( "python2.5 is not supported anymore, sorry") Repository URL: https://bitbucket.org/hpk42/tox/ -- 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 Sep 23 16:38:27 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 23 Sep 2014 14:38:27 -0000 Subject: [Pytest-commit] commit/tox: hpk42: add test and changelog for better report if we can't get version_info Message-ID: <20140923143827.4388.95554@app11.ash-private.bitbucket.org> 1 new commit in tox: https://bitbucket.org/hpk42/tox/commits/ad8d6e2e7690/ Changeset: ad8d6e2e7690 User: hpk42 Date: 2014-09-23 14:38:01+00:00 Summary: add test and changelog for better report if we can't get version_info from an interpreter executable. Affected #: 2 files diff -r 9dd51ef1cdbb000809b509dffd79288453155e85 -r ad8d6e2e76902db255b858d2c08a461d9b104e99 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -11,6 +11,9 @@ - fix issue152: set VIRTUAL_ENV when running test commands, thanks Florian Ludwig. +- better report if we can't get version_info from an interpreter + executable. Thanks Floris Bruynooghe. + 1.7.2 ----------- diff -r 9dd51ef1cdbb000809b509dffd79288453155e85 -r ad8d6e2e76902db255b858d2c08a461d9b104e99 tests/test_venv.py --- a/tests/test_venv.py +++ b/tests/test_venv.py @@ -4,6 +4,7 @@ import os, sys import tox._config from tox._venv import * # noqa +from tox.interpreters import NoInterpreterInfo #def test_global_virtualenv(capfd): # v = VirtualEnv() @@ -34,6 +35,12 @@ monkeypatch.setattr(venv.envconfig, 'basepython', 'notexistingpython') py.test.raises(tox.exception.InterpreterNotFound, venv.getsupportedinterpreter) + monkeypatch.undo() + # check that we properly report when no version_info is present + info = NoInterpreterInfo(name=venv.name) + info.executable = "something" + monkeypatch.setattr(config.interpreters, "get_info", lambda *args: info) + pytest.raises(tox.exception.InvocationError, venv.getsupportedinterpreter) def test_create(monkeypatch, mocksession, newconfig): Repository URL: https://bitbucket.org/hpk42/tox/ -- 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 issues-reply at bitbucket.org Tue Sep 23 18:50:26 2014 From: issues-reply at bitbucket.org (=?utf-8?q?Daniel_Neuh=C3=A4user?=) Date: Tue, 23 Sep 2014 16:50:26 -0000 Subject: [Pytest-commit] Issue #189: Allow parametrization of any testenv (hpk42/tox) Message-ID: <20140923165026.7596.54716@app14.ash-private.bitbucket.org> New issue 189: Allow parametrization of any testenv https://bitbucket.org/hpk42/tox/issue/189/allow-parametrization-of-any-testenv Daniel Neuh?user: As discussed on IRC with @hpk42, I would like the ability to parametrize any testenv and not just the normal [testenv] one. One use case I have is a testenv for testing doctests on different Python interpreters, so basically I would like the following to work: ``` #!ini [tox] envlist = docs-examples-{py27,py33,py34} [testenv:docs-examples] changedir = docs deps = sphinx commands = sphinx-build -W -b doctest -d {envtmpdir}/doctrees . {envtmpdir}/doctest ``` /cc @suor From commits-noreply at bitbucket.org Tue Sep 23 23:23:13 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 23 Sep 2014 21:23:13 -0000 Subject: [Pytest-commit] commit/pytest: bubenkoff: simpler and more verbose assertions Message-ID: <20140923212313.20464.48016@app05.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/cf8da540f4ed/ Changeset: cf8da540f4ed Branch: better-diff User: bubenkoff Date: 2014-09-23 21:22:57+00:00 Summary: simpler and more verbose assertions Affected #: 2 files diff -r fcfcf15459f0e4ab43e8784befcd83ded913c8b2 -r cf8da540f4ed1c305e128cd627933afa2034e710 _pytest/assertion/util.py --- a/_pytest/assertion/util.py +++ b/_pytest/assertion/util.py @@ -1,4 +1,5 @@ """Utilities for assertion debugging""" +import difflib import pprint import py @@ -129,11 +130,14 @@ right_repr = py.io.saferepr(right, maxsize=width-len(left_repr)) summary = u('%s %s %s') % (left_repr, op, right_repr) - issequence = lambda x: (isinstance(x, (list, tuple, Sequence)) - and not isinstance(x, basestring)) istext = lambda x: isinstance(x, basestring) - isdict = lambda x: isinstance(x, dict) - isset = lambda x: isinstance(x, (set, frozenset)) + + def issequence(obj): + try: + iter(obj) + return not istext(obj) + except TypeError: + return False verbose = config.getoption('verbose') explanation = None @@ -142,11 +146,7 @@ if istext(left) and istext(right): explanation = _diff_text(left, right, verbose) elif issequence(left) and issequence(right): - explanation = _compare_eq_sequence(left, right, verbose) - elif isset(left) and isset(right): - explanation = _compare_eq_set(left, right, verbose) - elif isdict(left) and isdict(right): - explanation = _compare_eq_dict(left, right, verbose) + explanation = _compare_eq(left, right, verbose) elif op == 'not in': if istext(left) and istext(right): explanation = _notin_text(left, right, verbose) @@ -203,68 +203,6 @@ return explanation -def _compare_eq_sequence(left, right, verbose=False): - explanation = [] - for i in range(min(len(left), len(right))): - if left[i] != right[i]: - explanation += [u('At index %s diff: %r != %r') - % (i, left[i], right[i])] - break - if len(left) > len(right): - explanation += [u('Left contains more items, first extra item: %s') - % py.io.saferepr(left[len(right)],)] - elif len(left) < len(right): - explanation += [ - u('Right contains more items, first extra item: %s') % - py.io.saferepr(right[len(left)],)] - return explanation # + _diff_text(pprint.pformat(left), - # pprint.pformat(right)) - - -def _compare_eq_set(left, right, verbose=False): - explanation = [] - diff_left = left - right - diff_right = right - left - if diff_left: - explanation.append(u('Extra items in the left set:')) - for item in diff_left: - explanation.append(py.io.saferepr(item)) - if diff_right: - explanation.append(u('Extra items in the right set:')) - for item in diff_right: - explanation.append(py.io.saferepr(item)) - return explanation - - -def _compare_eq_dict(left, right, verbose=False): - explanation = [] - common = set(left).intersection(set(right)) - same = dict((k, left[k]) for k in common if left[k] == right[k]) - if same and not verbose: - explanation += [u('Omitting %s identical items, use -v to show') % - len(same)] - elif same: - explanation += [u('Common items:')] - explanation += pprint.pformat(same).splitlines() - diff = set(k for k in common if left[k] != right[k]) - if diff: - explanation += [u('Differing items:')] - for k in diff: - explanation += [py.io.saferepr({k: left[k]}) + ' != ' + - py.io.saferepr({k: right[k]})] - extra_left = set(left) - set(right) - if extra_left: - explanation.append(u('Left contains more items:')) - explanation.extend(pprint.pformat( - dict((k, left[k]) for k in extra_left)).splitlines()) - extra_right = set(right) - set(left) - if extra_right: - explanation.append(u('Right contains more items:')) - explanation.extend(pprint.pformat( - dict((k, right[k]) for k in extra_right)).splitlines()) - return explanation - - def _notin_text(term, text, verbose=False): index = text.find(term) head = text[:index] @@ -282,3 +220,10 @@ else: newdiff.append(line) return newdiff + + +def _compare_eq(left, right, verbose=False): + left = pprint.pformat(left).splitlines() + right = pprint.pformat(right).splitlines() + return list(line.strip() for line in difflib.ndiff(left, right)) + diff -r fcfcf15459f0e4ab43e8784befcd83ded913c8b2 -r cf8da540f4ed1c305e128cd627933afa2034e710 testing/test_assertion.py --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -96,19 +96,6 @@ expl = callequal({'a': 0}, {'a': 1}) assert len(expl) > 1 - def test_dict_omitting(self): - lines = callequal({'a': 0, 'b': 1}, {'a': 1, 'b': 1}) - assert lines[1].startswith('Omitting 1 identical item') - assert 'Common items' not in lines - for line in lines[1:]: - assert 'b' not in line - - def test_dict_omitting_verbose(self): - lines = callequal({'a': 0, 'b': 1}, {'a': 1, 'b': 1}, verbose=True) - assert lines[1].startswith('Common items:') - assert 'Omitting' not in lines[1] - assert lines[2] == "{'b': 1}" - def test_set(self): expl = callequal(set([0, 1]), set([0, 2])) assert len(expl) > 1 @@ -370,7 +357,6 @@ "*truncated*use*-vv*", ]) - result = testdir.runpytest('-vv') result.stdout.fnmatch_lines([ "*- 197", 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 Sep 24 12:53:11 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 24 Sep 2014 10:53:11 -0000 Subject: [Pytest-commit] commit/pytest: bubenkoff: rename orgname to pytest-dev Message-ID: <20140924105311.9429.23371@app14.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/1e6cd7e84537/ Changeset: 1e6cd7e84537 Branch: contributing-community User: bubenkoff Date: 2014-09-24 10:53:08+00:00 Summary: rename orgname to pytest-dev Affected #: 1 file diff -r 18369ad10e3f3559dde25a4748c689153be5f64a -r 1e6cd7e84537354a406bae6e130a7daf5e9dd4cd doc/en/plugins.txt --- a/doc/en/plugins.txt +++ b/doc/en/plugins.txt @@ -131,12 +131,12 @@ To simplify the plugin development and/or support, it was decided to create teams(companies) on popular code hosting services (at the moment it's github and bitbucket): -* ``_: +* ``_: probably the most popular hosting for pytest plugins - the name ``pytestorg`` is choosen because ``pytest`` was already taken by + the name ``pytest-dev`` is choosen because ``pytest`` was already taken by some unknown person, who's not active on the github or just doesn't check the email used to register that organization. -* ``_: +* ``_: pytest is hosted on the bitbucket, also a lot of pytest plugins are hosted there. More code hosting services can be added in the future. 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 Sep 24 13:52:03 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 24 Sep 2014 11:52:03 -0000 Subject: [Pytest-commit] commit/pytest: flub: Let xfail work on non-python Items Message-ID: <20140924115203.669.8738@app05.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/79d43914cf2f/ Changeset: 79d43914cf2f User: flub Date: 2014-09-23 22:55:26+00:00 Summary: Let xfail work on non-python Items For some reason xfail was only implemented on non-python Item instances. This removes this guard which means plugins creating new items can raise pytest.xfail.Exception and it will work as expected. Affected #: 2 files diff -r fcfcf15459f0e4ab43e8784befcd83ded913c8b2 -r 79d43914cf2f99b25a3b65f90a07a036b33e165f _pytest/skipping.py --- a/_pytest/skipping.py +++ b/_pytest/skipping.py @@ -58,6 +58,7 @@ @property def holder(self): return self.item.keywords.get(self.name, None) + def __bool__(self): return bool(self.holder) __nonzero__ = __bool__ @@ -136,8 +137,6 @@ @pytest.mark.tryfirst def pytest_runtest_setup(item): - if not isinstance(item, pytest.Function): - return evalskip = MarkEvaluator(item, 'skipif') if evalskip.istrue(): pytest.skip(evalskip.getexplanation()) @@ -155,8 +154,6 @@ pytest.xfail("[NOTRUN] " + evalxfail.getexplanation()) def pytest_runtest_makereport(__multicall__, item, call): - if not isinstance(item, pytest.Function): - return # unitttest special case, see setting of _unexpectedsuccess if hasattr(item, '_unexpectedsuccess'): rep = __multicall__.execute() diff -r fcfcf15459f0e4ab43e8784befcd83ded913c8b2 -r 79d43914cf2f99b25a3b65f90a07a036b33e165f testing/test_skipping.py --- a/testing/test_skipping.py +++ b/testing/test_skipping.py @@ -678,3 +678,23 @@ *True123* *1 xfail* """) + + +def test_xfail_item(testdir): + # Ensure pytest.xfail works with non-Python Item + testdir.makeconftest(""" + import pytest + + class MyItem(pytest.Item): + nodeid = 'foo' + def runtest(self): + pytest.xfail("Expected Failure") + + def pytest_collect_file(path, parent): + return MyItem("foo", parent) + """) + result = testdir.inline_run() + passed, skipped, failed = result.listoutcomes() + assert not failed + xfailed = [r for r in skipped if hasattr(r, 'wasxfail')] + assert xfailed 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 Sep 24 13:56:21 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 24 Sep 2014 11:56:21 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: add changelog: check xfail/skip also with non-python function test items. Thanks Message-ID: <20140924115621.26895.29353@app02.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/87957f518901/ Changeset: 87957f518901 User: hpk42 Date: 2014-09-24 11:55:55+00:00 Summary: add changelog: check xfail/skip also with non-python function test items. Thanks Floris Bruynooghe. Affected #: 1 file diff -r 79d43914cf2f99b25a3b65f90a07a036b33e165f -r 87957f5189015ae7e8e7d60aaed0bf47a08d2779 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -22,6 +22,9 @@ - Introduce pytest_enter_pdb hook (needed e.g. by pytest_timeout to cancel the timeout when interactively entering pdb). Thanks Wolfgang Schnerring. +- check xfail/skip also with non-python function test items. Thanks + Floris Bruynooghe. + 2.6.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 Wed Sep 24 15:00:31 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 24 Sep 2014 13:00:31 -0000 Subject: [Pytest-commit] commit/pytest: 3 new changesets Message-ID: <20140924130031.32384.485@app03.ash-private.bitbucket.org> 3 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/d058775f29a2/ Changeset: d058775f29a2 User: hpk42 Date: 2014-09-24 12:46:56+00:00 Summary: regen and fix some docs (tox -e regen) bump versions, depend on already released py-1.4.25 Affected #: 19 files diff -r 87957f5189015ae7e8e7d60aaed0bf47a08d2779 -r d058775f29a2abc276b206227c218041c9ba0771 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -NEXT +2.6.3 ----------- - fix issue575: xunit-xml was reporting collection errors as failures diff -r 87957f5189015ae7e8e7d60aaed0bf47a08d2779 -r d058775f29a2abc276b206227c218041c9ba0771 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.6.3.dev3' +__version__ = '2.6.3' diff -r 87957f5189015ae7e8e7d60aaed0bf47a08d2779 -r d058775f29a2abc276b206227c218041c9ba0771 doc/en/announce/release-2.6.3.txt --- /dev/null +++ b/doc/en/announce/release-2.6.3.txt @@ -0,0 +1,52 @@ +pytest-2.6.3: fixes and little improvements +=========================================================================== + +pytest is a mature Python testing tool with more than a 1100 tests +against itself, passing on many different interpreters and platforms. +This release is drop-in compatible to 2.5.2 and 2.6.X. +See below for the changes and see docs at: + + http://pytest.org + +As usual, you can upgrade from pypi via:: + + pip install -U pytest + +Thanks to all who contributed, among them: + + Floris Bruynooghe + Oleg Sinyavskiy + Uwe Schmitt + Charles Cloud + Wolfgang Schnerring + +have fun, +holger krekel + +Changes 2.6.3 +====================== + +- fix issue575: xunit-xml was reporting collection errors as failures + instead of errors, thanks Oleg Sinyavskiy. + +- fix issue582: fix setuptools example, thanks Laszlo Papp and Ronny + Pfannschmidt. + +- Fix infinite recursion bug when pickling capture.EncodedFile, thanks + Uwe Schmitt. + +- fix issue589: fix bad interaction with numpy and others when showing + exceptions. Check for precise "maximum recursion depth exceed" exception + instead of presuming any RuntimeError is that one (implemented in py + dep). Thanks Charles Cloud for analysing the issue. + +- fix conftest related fixture visibility issue: when running with a + CWD outside a test package pytest would get fixture discovery wrong. + Thanks to Wolfgang Schnerring for figuring out a reproducable example. + +- Introduce pytest_enter_pdb hook (needed e.g. by pytest_timeout to cancel the + timeout when interactively entering pdb). Thanks Wolfgang Schnerring. + +- check xfail/skip also with non-python function test items. Thanks + Floris Bruynooghe. + diff -r 87957f5189015ae7e8e7d60aaed0bf47a08d2779 -r d058775f29a2abc276b206227c218041c9ba0771 doc/en/assert.txt --- a/doc/en/assert.txt +++ b/doc/en/assert.txt @@ -26,7 +26,7 @@ $ py.test test_assert1.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 1 items test_assert1.py F @@ -135,7 +135,7 @@ $ py.test test_assert2.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 1 items test_assert2.py F diff -r 87957f5189015ae7e8e7d60aaed0bf47a08d2779 -r d058775f29a2abc276b206227c218041c9ba0771 doc/en/capture.txt --- a/doc/en/capture.txt +++ b/doc/en/capture.txt @@ -64,7 +64,7 @@ $ py.test =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 2 items test_module.py .F @@ -78,7 +78,7 @@ test_module.py:9: AssertionError -------------------------- Captured stdout setup --------------------------- - setting up + setting up ==================== 1 failed, 1 passed in 0.01 seconds ==================== Accessing captured output from a test function diff -r 87957f5189015ae7e8e7d60aaed0bf47a08d2779 -r d058775f29a2abc276b206227c218041c9ba0771 doc/en/doctest.txt --- a/doc/en/doctest.txt +++ b/doc/en/doctest.txt @@ -44,12 +44,12 @@ $ py.test =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 1 items mymodule.py . - ========================= 1 passed in 0.07 seconds ========================= + ========================= 1 passed in 0.05 seconds ========================= It is possible to use fixtures using the ``getfixture`` helper:: diff -r 87957f5189015ae7e8e7d60aaed0bf47a08d2779 -r d058775f29a2abc276b206227c218041c9ba0771 doc/en/example/markers.txt --- a/doc/en/example/markers.txt +++ b/doc/en/example/markers.txt @@ -31,7 +31,7 @@ $ py.test -v -m webtest =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 4 items test_server.py::test_send_http PASSED @@ -43,7 +43,7 @@ $ py.test -v -m "not webtest" =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 4 items test_server.py::test_something_quick PASSED @@ -62,7 +62,7 @@ $ py.test -v test_server.py::TestClass::test_method =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 5 items test_server.py::TestClass::test_method PASSED @@ -73,7 +73,7 @@ $ py.test -v test_server.py::TestClass =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 4 items test_server.py::TestClass::test_method PASSED @@ -84,7 +84,7 @@ $ py.test -v test_server.py::TestClass test_server.py::test_send_http =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 8 items test_server.py::TestClass::test_method PASSED @@ -120,7 +120,7 @@ $ py.test -v -k http # running with the above defined example module =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 4 items test_server.py::test_send_http PASSED @@ -132,7 +132,7 @@ $ py.test -k "not send_http" -v =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 4 items test_server.py::test_something_quick PASSED @@ -140,20 +140,20 @@ test_server.py::TestClass::test_method PASSED ================= 1 tests deselected by '-knot send_http' ================== - ================== 3 passed, 1 deselected in 0.01 seconds ================== + ================== 3 passed, 1 deselected in 0.02 seconds ================== Or to select "http" and "quick" tests:: $ py.test -k "http or quick" -v =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 4 items test_server.py::test_send_http PASSED test_server.py::test_something_quick PASSED ================= 2 tests deselected by '-khttp or quick' ================== - ================== 2 passed, 2 deselected in 0.02 seconds ================== + ================== 2 passed, 2 deselected in 0.01 seconds ================== .. note:: @@ -326,7 +326,7 @@ $ py.test -E stage2 =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 1 items test_someenv.py s @@ -337,7 +337,7 @@ $ py.test -E stage1 =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 1 items test_someenv.py . @@ -455,12 +455,12 @@ $ py.test -rs # this option reports skip reasons =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 4 items test_plat.py sss. ========================= short test summary info ========================== - SKIP [3] /tmp/doc-exec-82/conftest.py:12: cannot run on platform linux + SKIP [3] /tmp/doc-exec-224/conftest.py:12: cannot run on platform linux =================== 1 passed, 3 skipped in 0.01 seconds ==================== @@ -468,7 +468,7 @@ $ py.test -m linux2 =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 4 items test_plat.py s @@ -519,7 +519,7 @@ $ py.test -m interface --tb=short =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 4 items test_module.py FF @@ -540,7 +540,7 @@ $ py.test -m "interface or event" --tb=short =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 4 items test_module.py FFF @@ -559,4 +559,4 @@ assert 0 E assert 0 ============= 1 tests deselected by "-m 'interface or event'" ============== - ================== 3 failed, 1 deselected in 0.02 seconds ================== + ================== 3 failed, 1 deselected in 0.01 seconds ================== diff -r 87957f5189015ae7e8e7d60aaed0bf47a08d2779 -r d058775f29a2abc276b206227c218041c9ba0771 doc/en/example/nonpython.txt --- a/doc/en/example/nonpython.txt +++ b/doc/en/example/nonpython.txt @@ -27,7 +27,7 @@ nonpython $ py.test test_simple.yml =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 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.04 seconds ==================== + ==================== 1 failed, 1 passed in 0.03 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 linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 2 items test_simple.yml::usecase: ok PASSED @@ -67,17 +67,17 @@ usecase execution failed spec failed: 'some': 'other' no further details known at this point. - ==================== 1 failed, 1 passed in 0.05 seconds ==================== + ==================== 1 failed, 1 passed in 0.03 seconds ==================== While developing your custom test collection and execution it's also interesting to just look at the collection tree:: nonpython $ py.test --collect-only =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 2 items - ============================= in 0.04 seconds ============================= + ============================= in 0.03 seconds ============================= diff -r 87957f5189015ae7e8e7d60aaed0bf47a08d2779 -r d058775f29a2abc276b206227c218041c9ba0771 doc/en/example/parametrize.txt --- a/doc/en/example/parametrize.txt +++ b/doc/en/example/parametrize.txt @@ -106,7 +106,7 @@ $ py.test test_scenarios.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 4 items test_scenarios.py .... @@ -118,7 +118,7 @@ $ py.test --collect-only test_scenarios.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 4 items @@ -182,7 +182,7 @@ $ py.test test_backends.py --collect-only =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 2 items @@ -197,7 +197,7 @@ ================================= FAILURES ================================= _________________________ test_db_initialized[d2] __________________________ - db = + db = def test_db_initialized(db): # a dummy test @@ -206,7 +206,7 @@ E Failed: deliberately failing for demo purposes test_backends.py:6: Failed - 1 failed, 1 passed in 0.01 seconds + 1 failed, 1 passed in 0.02 seconds The first invocation with ``db == "DB1"`` passed while the second with ``db == "DB2"`` failed. Our ``db`` fixture function has instantiated each of the DB values during the setup phase while the ``pytest_generate_tests`` generated two according calls to the ``test_db_initialized`` during the collection phase. @@ -251,16 +251,16 @@ $ py.test -q F.. ================================= FAILURES ================================= - ________________________ TestClass.test_equals[2-1] ________________________ + ________________________ TestClass.test_equals[1-2] ________________________ - self = , a = 1, b = 2 + self = , a = 1, b = 2 def test_equals(self, a, b): > assert a == b E assert 1 == 2 test_parametrize.py:18: AssertionError - 1 failed, 2 passed in 0.01 seconds + 1 failed, 2 passed in 0.02 seconds Indirect parametrization with multiple fixtures -------------------------------------------------------------- @@ -279,12 +279,345 @@ Running it results in some skips if we don't have all the python interpreters installed and otherwise runs all combinations (5 interpreters times 5 interpreters times 3 objects to serialize/deserialize):: . $ py.test -rs -q multipython.py - ssssssssssssssssssssssssssssssssssss......sssssssss......ssssssssssssssssss - ========================= short test summary info ========================== - SKIP [21] /home/hpk/p/pytest/doc/en/example/multipython.py:22: 'python2.5' not found - SKIP [21] /home/hpk/p/pytest/doc/en/example/multipython.py:22: 'python2.8' not found - SKIP [21] /home/hpk/p/pytest/doc/en/example/multipython.py:22: 'python2.4' not found - 12 passed, 63 skipped in 0.65 seconds + ..................FFFFFF... + ================================= FAILURES ================================= + ________________ test_basic_objects[python3.4-python2.6-42] ________________ + + python1 = + python2 = , obj = 42 + + @pytest.mark.parametrize("obj", [42, {}, {1:3},]) + def test_basic_objects(python1, python2, obj): + python1.dumps(obj) + > python2.load_and_is_true("obj == %s" % obj) + + multipython.py:51: + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + multipython.py:46: in load_and_is_true + py.process.cmdexec("%s %s" %(self.pythonpath, loadfile)) + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + + cmd = '/home/hpk/bin/python2.6 /tmp/pytest-21/test_basic_objects_python3_4_p0/load.py' + + def cmdexec(cmd): + """ return unicode output of executing 'cmd' in a separate process. + + raise cmdexec.Error exeception if the command failed. + the exception will provide an 'err' attribute containing + the error-output from the command. + if the subprocess module does not provide a proper encoding/unicode strings + sys.getdefaultencoding() will be used, if that does not exist, 'UTF-8'. + """ + process = subprocess.Popen(cmd, shell=True, + universal_newlines=True, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = process.communicate() + if sys.version_info[0] < 3: # on py3 we get unicode strings, on py2 not + try: + default_encoding = sys.getdefaultencoding() # jython may not have it + except AttributeError: + default_encoding = sys.stdout.encoding or 'UTF-8' + out = unicode(out, process.stdout.encoding or default_encoding) + err = unicode(err, process.stderr.encoding or default_encoding) + status = process.poll() + if status: + > raise ExecutionFailed(status, status, cmd, out, err) + E py.process.cmdexec.Error: ExecutionFailed: 1 /home/hpk/bin/python2.6 /tmp/pytest-21/test_basic_objects_python3_4_p0/load.py + E Traceback (most recent call last): + E File "/tmp/pytest-21/test_basic_objects_python3_4_p0/load.py", line 4, in + E obj = pickle.load(f) + E File "/usr/lib/python2.6/pickle.py", line 1370, in load + E return Unpickler(file).load() + E File "/usr/lib/python2.6/pickle.py", line 858, in load + E dispatch[key](self) + E File "/usr/lib/python2.6/pickle.py", line 886, in load_proto + E raise ValueError, "unsupported pickle protocol: %d" % proto + E ValueError: unsupported pickle protocol: 3 + + ../../../.tox/regen/lib/python3.4/site-packages/py/_process/cmdexec.py:28: Error + --------------------------- Captured stdout call --------------------------- + /tmp/pytest-21/test_basic_objects_python3_4_p0/load.py + _______________ test_basic_objects[python3.4-python2.6-obj1] _______________ + + python1 = + python2 = , obj = {} + + @pytest.mark.parametrize("obj", [42, {}, {1:3},]) + def test_basic_objects(python1, python2, obj): + python1.dumps(obj) + > python2.load_and_is_true("obj == %s" % obj) + + multipython.py:51: + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + multipython.py:46: in load_and_is_true + py.process.cmdexec("%s %s" %(self.pythonpath, loadfile)) + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + + cmd = '/home/hpk/bin/python2.6 /tmp/pytest-21/test_basic_objects_python3_4_p1/load.py' + + def cmdexec(cmd): + """ return unicode output of executing 'cmd' in a separate process. + + raise cmdexec.Error exeception if the command failed. + the exception will provide an 'err' attribute containing + the error-output from the command. + if the subprocess module does not provide a proper encoding/unicode strings + sys.getdefaultencoding() will be used, if that does not exist, 'UTF-8'. + """ + process = subprocess.Popen(cmd, shell=True, + universal_newlines=True, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = process.communicate() + if sys.version_info[0] < 3: # on py3 we get unicode strings, on py2 not + try: + default_encoding = sys.getdefaultencoding() # jython may not have it + except AttributeError: + default_encoding = sys.stdout.encoding or 'UTF-8' + out = unicode(out, process.stdout.encoding or default_encoding) + err = unicode(err, process.stderr.encoding or default_encoding) + status = process.poll() + if status: + > raise ExecutionFailed(status, status, cmd, out, err) + E py.process.cmdexec.Error: ExecutionFailed: 1 /home/hpk/bin/python2.6 /tmp/pytest-21/test_basic_objects_python3_4_p1/load.py + E Traceback (most recent call last): + E File "/tmp/pytest-21/test_basic_objects_python3_4_p1/load.py", line 4, in + E obj = pickle.load(f) + E File "/usr/lib/python2.6/pickle.py", line 1370, in load + E return Unpickler(file).load() + E File "/usr/lib/python2.6/pickle.py", line 858, in load + E dispatch[key](self) + E File "/usr/lib/python2.6/pickle.py", line 886, in load_proto + E raise ValueError, "unsupported pickle protocol: %d" % proto + E ValueError: unsupported pickle protocol: 3 + + ../../../.tox/regen/lib/python3.4/site-packages/py/_process/cmdexec.py:28: Error + --------------------------- Captured stdout call --------------------------- + /tmp/pytest-21/test_basic_objects_python3_4_p1/load.py + _______________ test_basic_objects[python3.4-python2.6-obj2] _______________ + + python1 = + python2 = , obj = {1: 3} + + @pytest.mark.parametrize("obj", [42, {}, {1:3},]) + def test_basic_objects(python1, python2, obj): + python1.dumps(obj) + > python2.load_and_is_true("obj == %s" % obj) + + multipython.py:51: + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + multipython.py:46: in load_and_is_true + py.process.cmdexec("%s %s" %(self.pythonpath, loadfile)) + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + + cmd = '/home/hpk/bin/python2.6 /tmp/pytest-21/test_basic_objects_python3_4_p2/load.py' + + def cmdexec(cmd): + """ return unicode output of executing 'cmd' in a separate process. + + raise cmdexec.Error exeception if the command failed. + the exception will provide an 'err' attribute containing + the error-output from the command. + if the subprocess module does not provide a proper encoding/unicode strings + sys.getdefaultencoding() will be used, if that does not exist, 'UTF-8'. + """ + process = subprocess.Popen(cmd, shell=True, + universal_newlines=True, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = process.communicate() + if sys.version_info[0] < 3: # on py3 we get unicode strings, on py2 not + try: + default_encoding = sys.getdefaultencoding() # jython may not have it + except AttributeError: + default_encoding = sys.stdout.encoding or 'UTF-8' + out = unicode(out, process.stdout.encoding or default_encoding) + err = unicode(err, process.stderr.encoding or default_encoding) + status = process.poll() + if status: + > raise ExecutionFailed(status, status, cmd, out, err) + E py.process.cmdexec.Error: ExecutionFailed: 1 /home/hpk/bin/python2.6 /tmp/pytest-21/test_basic_objects_python3_4_p2/load.py + E Traceback (most recent call last): + E File "/tmp/pytest-21/test_basic_objects_python3_4_p2/load.py", line 4, in + E obj = pickle.load(f) + E File "/usr/lib/python2.6/pickle.py", line 1370, in load + E return Unpickler(file).load() + E File "/usr/lib/python2.6/pickle.py", line 858, in load + E dispatch[key](self) + E File "/usr/lib/python2.6/pickle.py", line 886, in load_proto + E raise ValueError, "unsupported pickle protocol: %d" % proto + E ValueError: unsupported pickle protocol: 3 + + ../../../.tox/regen/lib/python3.4/site-packages/py/_process/cmdexec.py:28: Error + --------------------------- Captured stdout call --------------------------- + /tmp/pytest-21/test_basic_objects_python3_4_p2/load.py + ________________ test_basic_objects[python3.4-python2.7-42] ________________ + + python1 = + python2 = , obj = 42 + + @pytest.mark.parametrize("obj", [42, {}, {1:3},]) + def test_basic_objects(python1, python2, obj): + python1.dumps(obj) + > python2.load_and_is_true("obj == %s" % obj) + + multipython.py:51: + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + multipython.py:46: in load_and_is_true + py.process.cmdexec("%s %s" %(self.pythonpath, loadfile)) + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + + cmd = '/home/hpk/bin/python2.7 /tmp/pytest-21/test_basic_objects_python3_4_p3/load.py' + + def cmdexec(cmd): + """ return unicode output of executing 'cmd' in a separate process. + + raise cmdexec.Error exeception if the command failed. + the exception will provide an 'err' attribute containing + the error-output from the command. + if the subprocess module does not provide a proper encoding/unicode strings + sys.getdefaultencoding() will be used, if that does not exist, 'UTF-8'. + """ + process = subprocess.Popen(cmd, shell=True, + universal_newlines=True, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = process.communicate() + if sys.version_info[0] < 3: # on py3 we get unicode strings, on py2 not + try: + default_encoding = sys.getdefaultencoding() # jython may not have it + except AttributeError: + default_encoding = sys.stdout.encoding or 'UTF-8' + out = unicode(out, process.stdout.encoding or default_encoding) + err = unicode(err, process.stderr.encoding or default_encoding) + status = process.poll() + if status: + > raise ExecutionFailed(status, status, cmd, out, err) + E py.process.cmdexec.Error: ExecutionFailed: 1 /home/hpk/bin/python2.7 /tmp/pytest-21/test_basic_objects_python3_4_p3/load.py + E Traceback (most recent call last): + E File "/tmp/pytest-21/test_basic_objects_python3_4_p3/load.py", line 4, in + E obj = pickle.load(f) + E File "/usr/lib/python2.7/pickle.py", line 1378, in load + E return Unpickler(file).load() + E File "/usr/lib/python2.7/pickle.py", line 858, in load + E dispatch[key](self) + E File "/usr/lib/python2.7/pickle.py", line 886, in load_proto + E raise ValueError, "unsupported pickle protocol: %d" % proto + E ValueError: unsupported pickle protocol: 3 + + ../../../.tox/regen/lib/python3.4/site-packages/py/_process/cmdexec.py:28: Error + --------------------------- Captured stdout call --------------------------- + /tmp/pytest-21/test_basic_objects_python3_4_p3/load.py + _______________ test_basic_objects[python3.4-python2.7-obj1] _______________ + + python1 = + python2 = , obj = {} + + @pytest.mark.parametrize("obj", [42, {}, {1:3},]) + def test_basic_objects(python1, python2, obj): + python1.dumps(obj) + > python2.load_and_is_true("obj == %s" % obj) + + multipython.py:51: + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + multipython.py:46: in load_and_is_true + py.process.cmdexec("%s %s" %(self.pythonpath, loadfile)) + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + + cmd = '/home/hpk/bin/python2.7 /tmp/pytest-21/test_basic_objects_python3_4_p4/load.py' + + def cmdexec(cmd): + """ return unicode output of executing 'cmd' in a separate process. + + raise cmdexec.Error exeception if the command failed. + the exception will provide an 'err' attribute containing + the error-output from the command. + if the subprocess module does not provide a proper encoding/unicode strings + sys.getdefaultencoding() will be used, if that does not exist, 'UTF-8'. + """ + process = subprocess.Popen(cmd, shell=True, + universal_newlines=True, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = process.communicate() + if sys.version_info[0] < 3: # on py3 we get unicode strings, on py2 not + try: + default_encoding = sys.getdefaultencoding() # jython may not have it + except AttributeError: + default_encoding = sys.stdout.encoding or 'UTF-8' + out = unicode(out, process.stdout.encoding or default_encoding) + err = unicode(err, process.stderr.encoding or default_encoding) + status = process.poll() + if status: + > raise ExecutionFailed(status, status, cmd, out, err) + E py.process.cmdexec.Error: ExecutionFailed: 1 /home/hpk/bin/python2.7 /tmp/pytest-21/test_basic_objects_python3_4_p4/load.py + E Traceback (most recent call last): + E File "/tmp/pytest-21/test_basic_objects_python3_4_p4/load.py", line 4, in + E obj = pickle.load(f) + E File "/usr/lib/python2.7/pickle.py", line 1378, in load + E return Unpickler(file).load() + E File "/usr/lib/python2.7/pickle.py", line 858, in load + E dispatch[key](self) + E File "/usr/lib/python2.7/pickle.py", line 886, in load_proto + E raise ValueError, "unsupported pickle protocol: %d" % proto + E ValueError: unsupported pickle protocol: 3 + + ../../../.tox/regen/lib/python3.4/site-packages/py/_process/cmdexec.py:28: Error + --------------------------- Captured stdout call --------------------------- + /tmp/pytest-21/test_basic_objects_python3_4_p4/load.py + _______________ test_basic_objects[python3.4-python2.7-obj2] _______________ + + python1 = + python2 = , obj = {1: 3} + + @pytest.mark.parametrize("obj", [42, {}, {1:3},]) + def test_basic_objects(python1, python2, obj): + python1.dumps(obj) + > python2.load_and_is_true("obj == %s" % obj) + + multipython.py:51: + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + multipython.py:46: in load_and_is_true + py.process.cmdexec("%s %s" %(self.pythonpath, loadfile)) + _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + + cmd = '/home/hpk/bin/python2.7 /tmp/pytest-21/test_basic_objects_python3_4_p5/load.py' + + def cmdexec(cmd): + """ return unicode output of executing 'cmd' in a separate process. + + raise cmdexec.Error exeception if the command failed. + the exception will provide an 'err' attribute containing + the error-output from the command. + if the subprocess module does not provide a proper encoding/unicode strings + sys.getdefaultencoding() will be used, if that does not exist, 'UTF-8'. + """ + process = subprocess.Popen(cmd, shell=True, + universal_newlines=True, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = process.communicate() + if sys.version_info[0] < 3: # on py3 we get unicode strings, on py2 not + try: + default_encoding = sys.getdefaultencoding() # jython may not have it + except AttributeError: + default_encoding = sys.stdout.encoding or 'UTF-8' + out = unicode(out, process.stdout.encoding or default_encoding) + err = unicode(err, process.stderr.encoding or default_encoding) + status = process.poll() + if status: + > raise ExecutionFailed(status, status, cmd, out, err) + E py.process.cmdexec.Error: ExecutionFailed: 1 /home/hpk/bin/python2.7 /tmp/pytest-21/test_basic_objects_python3_4_p5/load.py + E Traceback (most recent call last): + E File "/tmp/pytest-21/test_basic_objects_python3_4_p5/load.py", line 4, in + E obj = pickle.load(f) + E File "/usr/lib/python2.7/pickle.py", line 1378, in load + E return Unpickler(file).load() + E File "/usr/lib/python2.7/pickle.py", line 858, in load + E dispatch[key](self) + E File "/usr/lib/python2.7/pickle.py", line 886, in load_proto + E raise ValueError, "unsupported pickle protocol: %d" % proto + E ValueError: unsupported pickle protocol: 3 + + ../../../.tox/regen/lib/python3.4/site-packages/py/_process/cmdexec.py:28: Error + --------------------------- Captured stdout call --------------------------- + /tmp/pytest-21/test_basic_objects_python3_4_p5/load.py + 6 failed, 21 passed in 1.36 seconds Indirect parametrization of optional implementations/imports -------------------------------------------------------------------- @@ -331,12 +664,12 @@ $ py.test -rs test_module.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.23 -- pytest-2.6.1 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 2 items test_module.py .s ========================= short test summary info ========================== - SKIP [1] /tmp/doc-exec-240/conftest.py:10: could not import 'opt2' + SKIP [1] /tmp/doc-exec-226/conftest.py:10: could not import 'opt2' =================== 1 passed, 1 skipped in 0.01 seconds ==================== diff -r 87957f5189015ae7e8e7d60aaed0bf47a08d2779 -r d058775f29a2abc276b206227c218041c9ba0771 doc/en/example/pythoncollection.txt --- a/doc/en/example/pythoncollection.txt +++ b/doc/en/example/pythoncollection.txt @@ -43,7 +43,7 @@ $ py.test --collect-only =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 2 items @@ -88,7 +88,7 @@ . $ py.test --collect-only pythoncollection.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 3 items @@ -141,7 +141,7 @@ $ py.test --collect-only =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 0 items ============================= in 0.01 seconds ============================= diff -r 87957f5189015ae7e8e7d60aaed0bf47a08d2779 -r d058775f29a2abc276b206227c218041c9ba0771 doc/en/example/reportingdemo.txt --- a/doc/en/example/reportingdemo.txt +++ b/doc/en/example/reportingdemo.txt @@ -13,10 +13,10 @@ assertion $ py.test failure_demo.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 - collected 39 items + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 + collected 42 items - failure_demo.py FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + failure_demo.py FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ================================= FAILURES ================================= ____________________________ test_generative[0] ____________________________ @@ -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 = .f at 0x2aab6e7559d8>() - E + and 43 = .g at 0x2aab6e755ea0>() + E + where 42 = .f at 0x2adb9887e6a8>() + E + and 43 = .g at 0x2adb9887e598>() 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 = .f at 0x2aab6e7617b8>() + E + where 42 = .f at 0x2adb9887e840>() 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, 'c': 0} == {'a': 0, 'b': 2, 'd': 0} @@ -194,7 +194,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]) @@ -210,7 +210,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] @@ -220,7 +220,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] @@ -229,7 +229,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' @@ -247,7 +247,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' @@ -260,7 +260,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 @@ -273,7 +273,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 @@ -292,7 +292,7 @@ i = Foo() > assert i.b == 2 E assert 1 == 2 - E + where 1 = .Foo object at 0x2aab6e61ed30>.b + E + where 1 = .Foo object at 0x2adb987b5470>.b failure_demo.py:101: AssertionError _________________________ test_attribute_instance __________________________ @@ -302,8 +302,8 @@ b = 1 > assert Foo().b == 2 E assert 1 == 2 - E + where 1 = .Foo object at 0x2aab6e80e400>.b - E + where .Foo object at 0x2aab6e80e400> = .Foo'>() + E + where 1 = .Foo object at 0x2adb987d0390>.b + E + where .Foo object at 0x2adb987d0390> = .Foo'>() failure_demo.py:107: AssertionError __________________________ test_attribute_failure __________________________ @@ -319,7 +319,7 @@ failure_demo.py:116: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ - self = .Foo object at 0x2aab6e7fccc0> + self = .Foo object at 0x2adb98822cf8> def _get_b(self): > raise Exception('Failed to get attrib') @@ -335,15 +335,15 @@ b = 2 > assert Foo().b == Bar().b E assert 1 == 2 - E + where 1 = .Foo object at 0x2aab6e81dbe0>.b - E + where .Foo object at 0x2aab6e81dbe0> = .Foo'>() - E + and 2 = .Bar object at 0x2aab6bf55fd0>.b - E + where .Bar object at 0x2aab6bf55fd0> = .Bar'>() + E + where 1 = .Foo object at 0x2adb98841dd8>.b + E + where .Foo object at 0x2adb98841dd8> = .Foo'>() + E + and 2 = .Bar object at 0x2adb98841a90>.b + E + where .Bar object at 0x2adb98841a90> = .Bar'>() failure_demo.py:124: AssertionError __________________________ TestRaises.test_raises __________________________ - self = + self = def test_raises(self): s = 'qwe' @@ -358,7 +358,7 @@ <0-codegen /home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/_pytest/python.py:1028>:1: ValueError ______________________ TestRaises.test_raises_doesnt _______________________ - self = + self = def test_raises_doesnt(self): > raises(IOError, "int('3')") @@ -367,7 +367,7 @@ failure_demo.py:136: Failed __________________________ TestRaises.test_raise ___________________________ - self = + self = def test_raise(self): > raise ValueError("demo error") @@ -376,7 +376,7 @@ failure_demo.py:139: ValueError ________________________ TestRaises.test_tupleerror ________________________ - self = + self = def test_tupleerror(self): > a,b = [1] @@ -385,7 +385,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] @@ -398,7 +398,7 @@ l is [1, 2, 3] ________________________ TestRaises.test_some_error ________________________ - self = + self = def test_some_error(self): > if namenotexi: @@ -426,7 +426,7 @@ <2-codegen 'abc-123' /home/hpk/p/pytest/doc/en/example/assertion/failure_demo.py:162>:2: AssertionError ____________________ TestMoreErrors.test_complex_error _____________________ - self = + self = def test_complex_error(self): def f(): @@ -450,7 +450,7 @@ failure_demo.py:5: AssertionError ___________________ TestMoreErrors.test_z1_unpack_error ____________________ - self = + self = def test_z1_unpack_error(self): l = [] @@ -460,7 +460,7 @@ failure_demo.py:179: ValueError ____________________ TestMoreErrors.test_z2_type_error _____________________ - self = + self = def test_z2_type_error(self): l = 3 @@ -470,19 +470,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(): @@ -490,15 +490,15 @@ def g(): return "456" > assert f().startswith(g()) - E assert ('456') - E + where = '123'.startswith - E + where '123' = .f at 0x2aab6e7e8730>() - E + and '456' = .g at 0x2aab6e7e86a8>() + E assert ('456') + E + where = '123'.startswith + E + where '123' = .f at 0x2adb9887e9d8>() + E + and '456' = .g at 0x2adb9887e7b8>() failure_demo.py:195: AssertionError _____________________ TestMoreErrors.test_global_func ______________________ - self = + self = def test_global_func(self): > assert isinstance(globf(42), float) @@ -508,18 +508,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 @@ -529,7 +529,7 @@ failure_demo.py:205: AssertionError _____________________ TestMoreErrors.test_try_finally ______________________ - self = + self = def test_try_finally(self): x = 1 @@ -538,4 +538,55 @@ E assert 1 == 0 failure_demo.py:210: AssertionError - ======================== 39 failed in 0.25 seconds ========================= + ___________________ TestCustomAssertMsg.test_single_line ___________________ + + self = + + def test_single_line(self): + class A: + a = 1 + b = 2 + > assert A.a == b, "A.a appears not to be b" + E AssertionError: A.a appears not to be b + E assert 1 == 2 + E + where 1 = .A'>.a + + failure_demo.py:221: AssertionError + ____________________ TestCustomAssertMsg.test_multiline ____________________ + + self = + + def test_multiline(self): + class A: + a = 1 + b = 2 + > assert A.a == b, "A.a appears not to be b\n" \ + "or does not appear to be b\none of those" + E AssertionError: A.a appears not to be b + E or does not appear to be b + E one of those + E assert 1 == 2 + E + where 1 = .A'>.a + + failure_demo.py:227: AssertionError + ___________________ TestCustomAssertMsg.test_custom_repr ___________________ + + self = + + def test_custom_repr(self): + class JSON: + a = 1 + def __repr__(self): + return "This is JSON\n{\n 'foo': 'bar'\n}" + a = JSON() + b = 2 + > assert a.a == b, a + E AssertionError: This is JSON + E { + E 'foo': 'bar' + E } + E assert 1 == 2 + E + where 1 = This is JSON\n{\n 'foo': 'bar'\n}.a + + failure_demo.py:237: AssertionError + ======================== 42 failed in 0.29 seconds ========================= diff -r 87957f5189015ae7e8e7d60aaed0bf47a08d2779 -r d058775f29a2abc276b206227c218041c9ba0771 doc/en/example/simple.txt --- a/doc/en/example/simple.txt +++ b/doc/en/example/simple.txt @@ -55,7 +55,7 @@ test_sample.py:6: AssertionError --------------------------- Captured stdout call --------------------------- first - 1 failed in 0.01 seconds + 1 failed in 0.02 seconds And now with supplying a command line option:: @@ -63,9 +63,9 @@ F ================================= FAILURES ================================= _______________________________ test_answer ________________________________ - + cmdopt = 'type2' - + def test_answer(cmdopt): if cmdopt == "type1": print ("first") @@ -73,7 +73,7 @@ print ("second") > assert 0 # to see what was printed E assert 0 - + test_sample.py:6: AssertionError --------------------------- Captured stdout call --------------------------- second @@ -108,9 +108,9 @@ $ py.test =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 0 items - + ============================= in 0.00 seconds ============================= .. _`excontrolskip`: @@ -152,12 +152,12 @@ $ py.test -rs # "-rs" means report details on the little 's' =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 2 items test_module.py .s ========================= short test summary info ========================== - SKIP [1] /tmp/doc-exec-87/conftest.py:9: need --runslow option to run + SKIP [1] /tmp/doc-exec-229/conftest.py:9: need --runslow option to run =================== 1 passed, 1 skipped in 0.01 seconds ==================== @@ -165,11 +165,11 @@ $ py.test --runslow =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 2 items - + test_module.py .. - + ========================= 2 passed in 0.01 seconds ========================= Writing well integrated assertion helpers @@ -256,10 +256,10 @@ $ py.test =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 project deps: mylib-1.1 collected 0 items - + ============================= in 0.00 seconds ============================= .. regendoc:wipe @@ -279,20 +279,20 @@ $ py.test -v =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 info1: did you know that ... did you? collecting ... collected 0 items - + ============================= in 0.00 seconds ============================= and nothing when run plainly:: $ py.test =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 0 items - + ============================= in 0.00 seconds ============================= profiling test duration @@ -322,7 +322,7 @@ $ py.test --durations=3 =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 3 items test_some_are_slow.py ... @@ -330,8 +330,8 @@ ========================= slowest 3 test durations ========================= 0.20s call test_some_are_slow.py::test_funcslow2 0.10s call test_some_are_slow.py::test_funcslow1 - 0.00s setup test_some_are_slow.py::test_funcslow2 - ========================= 3 passed in 0.31 seconds ========================= + 0.00s teardown test_some_are_slow.py::test_funcslow1 + ========================= 3 passed in 0.32 seconds ========================= incremental testing - test steps --------------------------------------------------- @@ -383,7 +383,7 @@ $ py.test -rx =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 4 items test_step.py .Fx. @@ -391,7 +391,7 @@ ================================= FAILURES ================================= ____________________ TestUserHandling.test_modification ____________________ - self = + self = def test_modification(self): > assert 0 @@ -401,7 +401,7 @@ ========================= short test summary info ========================== XFAIL test_step.py::TestUserHandling::()::test_deletion reason: previous test failed (test_modification) - ============== 1 failed, 2 passed, 1 xfailed in 0.02 seconds =============== + ============== 1 failed, 2 passed, 1 xfailed in 0.01 seconds =============== We'll see that ``test_deletion`` was not executed because ``test_modification`` failed. It is reported as an "expected failure". @@ -453,7 +453,7 @@ $ py.test =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 7 items test_step.py .Fx. @@ -463,17 +463,17 @@ ================================== ERRORS ================================== _______________________ ERROR at setup of test_root ________________________ - file /tmp/doc-exec-87/b/test_error.py, line 1 + file /tmp/doc-exec-229/b/test_error.py, line 1 def test_root(db): # no db here, will error out fixture 'db' not found - available fixtures: recwarn, monkeypatch, pytestconfig, capfd, capsys, tmpdir + available fixtures: capsys, pytestconfig, monkeypatch, tmpdir, recwarn, capfd use 'py.test --fixtures [testpath]' for help on them. - /tmp/doc-exec-87/b/test_error.py:1 + /tmp/doc-exec-229/b/test_error.py:1 ================================= FAILURES ================================= ____________________ TestUserHandling.test_modification ____________________ - self = + self = def test_modification(self): > assert 0 @@ -482,20 +482,22 @@ test_step.py:9: AssertionError _________________________________ test_a1 __________________________________ - db = + db = def test_a1(db): > assert 0, db # to show value - E AssertionError: + E AssertionError: + E assert 0 a/test_db.py:2: AssertionError _________________________________ test_a2 __________________________________ - db = + db = def test_a2(db): > assert 0, db # to show value - E AssertionError: + E AssertionError: + E assert 0 a/test_db2.py:2: AssertionError ========== 3 failed, 2 passed, 1 xfailed, 1 error in 0.04 seconds ========== @@ -553,7 +555,7 @@ $ py.test test_module.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 2 items test_module.py FF @@ -561,7 +563,7 @@ ================================= FAILURES ================================= ________________________________ test_fail1 ________________________________ - tmpdir = local('/tmp/pytest-15/test_fail10') + tmpdir = local('/tmp/pytest-22/test_fail10') def test_fail1(tmpdir): > assert 0 @@ -580,7 +582,7 @@ you will have a "failures" file which contains the failing test ids:: $ cat failures - test_module.py::test_fail1 (/tmp/pytest-15/test_fail10) + test_module.py::test_fail1 (/tmp/pytest-22/test_fail10) test_module.py::test_fail2 Making test result information available in fixtures @@ -613,10 +615,10 @@ # request.node is an "item" because we use the default # "function" scope if request.node.rep_setup.failed: - print "setting up a test failed!", request.node.nodeid + print ("setting up a test failed!", request.node.nodeid) elif request.node.rep_setup.passed: if request.node.rep_call.failed: - print "executing test failed", request.node.nodeid + print ("executing test failed", request.node.nodeid) request.addfinalizer(fin) @@ -642,29 +644,41 @@ and run it:: $ py.test -s test_module.py - Traceback (most recent call last): - File "/home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/_pytest/config.py", line 513, in getconftestmodules - return self._path2confmods[path] - KeyError: local('/tmp/doc-exec-87/test_module.py') + =========================== test session starts ============================ + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 + collected 3 items - During handling of the above exception, another exception occurred: - Traceback (most recent call last): - File "/home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/_pytest/config.py", line 537, in importconftest - return self._conftestpath2mod[conftestpath] - KeyError: local('/tmp/doc-exec-87/conftest.py') + test_module.py Esetting up a test failed! test_module.py::test_setup_fails + Fexecuting test failed test_module.py::test_call_fails + F - During handling of the above exception, another exception occurred: - Traceback (most recent call last): - File "/home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/_pytest/config.py", line 543, in importconftest - mod = conftestpath.pyimport() - File "/home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/py/_path/local.py", line 640, in pyimport - __import__(modname) - File "/tmp/doc-exec-87/conftest.py", line 22 - print "setting up a test failed!", request.node.nodeid - ^ - SyntaxError: invalid syntax - ERROR: could not load /tmp/doc-exec-87/conftest.py + ================================== ERRORS ================================== + ____________________ ERROR at setup of test_setup_fails ____________________ + @pytest.fixture + def other(): + > assert 0 + E assert 0 + + test_module.py:6: AssertionError + ================================= FAILURES ================================= + _____________________________ test_call_fails ______________________________ + + something = None + + def test_call_fails(something): + > assert 0 + E assert 0 + + test_module.py:12: AssertionError + ________________________________ test_fail2 ________________________________ + + def test_fail2(): + > assert 0 + E assert 0 + + test_module.py:15: AssertionError + ==================== 2 failed, 1 error in 0.01 seconds ===================== You'll see that the fixture finalizers could use the precise reporting information. diff -r 87957f5189015ae7e8e7d60aaed0bf47a08d2779 -r d058775f29a2abc276b206227c218041c9ba0771 doc/en/fixture.txt --- a/doc/en/fixture.txt +++ b/doc/en/fixture.txt @@ -76,7 +76,7 @@ $ py.test test_smtpsimple.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 1 items test_smtpsimple.py F @@ -84,7 +84,7 @@ ================================= FAILURES ================================= ________________________________ test_ehlo _________________________________ - smtp = + smtp = def test_ehlo(smtp): response, msg = smtp.ehlo() @@ -93,7 +93,7 @@ E TypeError: Type str doesn't support the buffer API test_smtpsimple.py:11: TypeError - ========================= 1 failed in 0.21 seconds ========================= + ========================= 1 failed in 0.20 seconds ========================= In the failure traceback we see that the test function was called with a ``smtp`` argument, the ``smtplib.SMTP()`` instance created by the fixture @@ -193,7 +193,7 @@ $ py.test test_module.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 2 items test_module.py FF @@ -201,7 +201,7 @@ ================================= FAILURES ================================= ________________________________ test_ehlo _________________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -212,7 +212,7 @@ test_module.py:5: TypeError ________________________________ test_noop _________________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -221,7 +221,7 @@ E assert 0 test_module.py:11: AssertionError - ========================= 2 failed in 0.21 seconds ========================= + ========================= 2 failed in 0.17 seconds ========================= You see the two ``assert 0`` failing and more importantly you can also see that the same (module-scoped) ``smtp`` object was passed into the two @@ -331,6 +331,7 @@ test_anothersmtp.py:5: in test_showhelo assert 0, smtp.helo() E AssertionError: (250, b'mail.python.org') + E assert 0 voila! The ``smtp`` fixture function picked up our mail server name from the module namespace. @@ -377,7 +378,7 @@ ================================= FAILURES ================================= __________________________ test_ehlo[merlinux.eu] __________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -388,7 +389,7 @@ test_module.py:5: TypeError __________________________ test_noop[merlinux.eu] __________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -399,7 +400,7 @@ test_module.py:11: AssertionError ________________________ test_ehlo[mail.python.org] ________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -409,10 +410,10 @@ test_module.py:5: TypeError -------------------------- Captured stdout setup --------------------------- - finalizing + finalizing ________________________ test_noop[mail.python.org] ________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -421,7 +422,7 @@ E assert 0 test_module.py:11: AssertionError - 4 failed in 6.37 seconds + 4 failed in 6.02 seconds We see that our two test functions each ran twice, against the different ``smtp`` instances. Note also, that with the ``mail.python.org`` @@ -461,13 +462,13 @@ $ py.test -v test_appsetup.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 2 items test_appsetup.py::test_smtp_exists[merlinux.eu] PASSED test_appsetup.py::test_smtp_exists[mail.python.org] PASSED - ========================= 2 passed in 6.37 seconds ========================= + ========================= 2 passed in 5.45 seconds ========================= Due to the parametrization of ``smtp`` the test will run twice with two different ``App`` instances and respective smtp servers. There is no @@ -525,7 +526,7 @@ $ py.test -v -s test_module.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 -- /home/hpk/p/pytest/.tox/regen/bin/python3.4 collecting ... collected 8 items test_module.py::test_0[1] test0 1 @@ -675,7 +676,7 @@ $ py.test -q .. - 2 passed in 0.02 seconds + 2 passed in 0.01 seconds Here is how autouse fixtures work in other scopes: diff -r 87957f5189015ae7e8e7d60aaed0bf47a08d2779 -r d058775f29a2abc276b206227c218041c9ba0771 doc/en/getting-started.txt --- a/doc/en/getting-started.txt +++ b/doc/en/getting-started.txt @@ -27,7 +27,7 @@ To check your installation has installed the correct version:: $ py.test --version - This is pytest version 2.6.2, imported from /home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/pytest.py + This is pytest version 2.6.3, imported from /home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/pytest.py If you get an error checkout :ref:`installation issues`. @@ -49,7 +49,7 @@ $ py.test =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 1 items test_sample.py F @@ -97,7 +97,7 @@ $ py.test -q test_sysexit.py . - 1 passed in 0.01 seconds + 1 passed in 0.00 seconds .. todo:: For further ways to assert exceptions see the `raises` @@ -127,7 +127,7 @@ ================================= FAILURES ================================= ____________________________ TestClass.test_two ____________________________ - self = + self = def test_two(self): x = "hello" @@ -135,7 +135,7 @@ E assert hasattr('hello', 'check') test_class.py:8: AssertionError - 1 failed, 1 passed in 0.02 seconds + 1 failed, 1 passed in 0.01 seconds The first test passed, the second failed. Again we can easily see the intermediate values used in the assertion, helping us to @@ -163,7 +163,7 @@ ================================= FAILURES ================================= _____________________________ test_needsfiles ______________________________ - tmpdir = local('/tmp/pytest-11/test_needsfiles0') + tmpdir = local('/tmp/pytest-18/test_needsfiles0') def test_needsfiles(tmpdir): print (tmpdir) @@ -172,8 +172,8 @@ test_tmpdir.py:3: AssertionError --------------------------- Captured stdout call --------------------------- - /tmp/pytest-11/test_needsfiles0 - 1 failed in 0.32 seconds + /tmp/pytest-18/test_needsfiles0 + 1 failed in 0.01 seconds Before the test runs, a unique-per-test-invocation temporary directory was created. More info at :ref:`tmpdir handling`. diff -r 87957f5189015ae7e8e7d60aaed0bf47a08d2779 -r d058775f29a2abc276b206227c218041c9ba0771 doc/en/parametrize.txt --- a/doc/en/parametrize.txt +++ b/doc/en/parametrize.txt @@ -53,7 +53,7 @@ $ py.test =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 3 items test_expectation.py ..F @@ -100,12 +100,12 @@ $ py.test =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 3 items test_expectation.py ..x - =================== 2 passed, 1 xfailed in 0.01 seconds ==================== + =================== 2 passed, 1 xfailed in 0.02 seconds ==================== The one parameter set which caused a failure previously now shows up as an "xfailed (expected to fail)" test. @@ -170,8 +170,8 @@ def test_valid_string(stringinput): > assert stringinput.isalpha() - E assert () - E + where = '!'.isalpha + E assert () + E + where = '!'.isalpha test_strings.py:3: AssertionError 1 failed in 0.01 seconds @@ -185,7 +185,7 @@ $ py.test -q -rs test_strings.py s ========================= short test summary info ========================== - SKIP [1] /home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/_pytest/python.py:1139: got empty parameter set, function test_valid_string at /tmp/doc-exec-38/test_strings.py:1 + SKIP [1] /home/hpk/p/pytest/.tox/regen/lib/python3.4/site-packages/_pytest/python.py:1139: got empty parameter set, function test_valid_string at /tmp/doc-exec-180/test_strings.py:1 1 skipped in 0.01 seconds For further examples, you might want to look at :ref:`more diff -r 87957f5189015ae7e8e7d60aaed0bf47a08d2779 -r d058775f29a2abc276b206227c218041c9ba0771 doc/en/skipping.txt --- a/doc/en/skipping.txt +++ b/doc/en/skipping.txt @@ -164,7 +164,7 @@ example $ py.test -rx xfail_demo.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 7 items xfail_demo.py xxxxxxx diff -r 87957f5189015ae7e8e7d60aaed0bf47a08d2779 -r d058775f29a2abc276b206227c218041c9ba0771 doc/en/tmpdir.txt --- a/doc/en/tmpdir.txt +++ b/doc/en/tmpdir.txt @@ -29,7 +29,7 @@ $ py.test test_tmpdir.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 1 items test_tmpdir.py F @@ -37,7 +37,7 @@ ================================= FAILURES ================================= _____________________________ test_create_file _____________________________ - tmpdir = local('/tmp/pytest-12/test_create_file0') + tmpdir = local('/tmp/pytest-19/test_create_file0') def test_create_file(tmpdir): p = tmpdir.mkdir("sub").join("hello.txt") diff -r 87957f5189015ae7e8e7d60aaed0bf47a08d2779 -r d058775f29a2abc276b206227c218041c9ba0771 doc/en/unittest.txt --- a/doc/en/unittest.txt +++ b/doc/en/unittest.txt @@ -88,7 +88,7 @@ $ py.test test_unittest_db.py =========================== test session starts ============================ - platform linux -- Python 3.4.0 -- py-1.4.24 -- pytest-2.6.2 + platform linux -- Python 3.4.0 -- py-1.4.25 -- pytest-2.6.3 collected 2 items test_unittest_db.py FF @@ -101,7 +101,8 @@ def test_method1(self): assert hasattr(self, "db") > assert 0, self.db # fail for demo purposes - E AssertionError: .DummyDB object at 0x2ad7f12df240> + E AssertionError: .DummyDB object at 0x2b938b865208> + E assert 0 test_unittest_db.py:9: AssertionError ___________________________ MyTest.test_method2 ____________________________ @@ -110,7 +111,8 @@ def test_method2(self): > assert 0, self.db # fail for demo purposes - E AssertionError: .DummyDB object at 0x2ad7f12df240> + E AssertionError: .DummyDB object at 0x2b938b865208> + E assert 0 test_unittest_db.py:12: AssertionError ========================= 2 failed in 0.05 seconds ========================= @@ -160,7 +162,7 @@ $ py.test -q test_unittest_cleandir.py . - 1 passed in 0.04 seconds + 1 passed in 0.05 seconds ... gives us one passed test because the ``initdir`` fixture function was executed ahead of the ``test_method``. diff -r 87957f5189015ae7e8e7d60aaed0bf47a08d2779 -r d058775f29a2abc276b206227c218041c9ba0771 setup.py --- a/setup.py +++ b/setup.py @@ -17,7 +17,7 @@ def main(): - install_requires = ['py>=1.4.25.dev2'] + install_requires = ['py>=1.4.25'] if sys.version_info < (2, 7) or (3,) <= sys.version_info < (3, 2): install_requires.append('argparse') if sys.platform == 'win32': @@ -27,7 +27,7 @@ name='pytest', description='pytest: simple powerful testing with Python', long_description=long_description, - version='2.6.3.dev3', + version='2.6.3', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], https://bitbucket.org/hpk42/pytest/commits/2967aa416a4f/ Changeset: 2967aa416a4f User: hpk42 Date: 2014-09-24 12:59:55+00:00 Summary: fix doc release version Affected #: 1 file diff -r d058775f29a2abc276b206227c218041c9ba0771 -r 2967aa416a4f3cdb65fc75073a2a148e1f372742 doc/en/conf.py --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -18,7 +18,7 @@ # The full version, including alpha/beta/rc tags. # The short X.Y version. version = "2.6" -release = "2.6.2" +release = "2.6.3" import sys, os https://bitbucket.org/hpk42/pytest/commits/43d374de24a8/ Changeset: 43d374de24a8 User: hpk42 Date: 2014-09-24 12:59:57+00:00 Summary: Added tag 2.6.3 for changeset 2967aa416a4f Affected #: 1 file diff -r 2967aa416a4f3cdb65fc75073a2a148e1f372742 -r 43d374de24a8644e3d27563832175a510f83a870 .hgtags --- a/.hgtags +++ b/.hgtags @@ -71,3 +71,4 @@ 88af949b9611494e2c65d528f9e565b00fb7e8ca 2.6.0 a4f9639702baa3eb4f3b16e162f74f7b69f3f9e1 2.6.1 a4f25c5e649892b5cc746d21be971e4773478af9 2.6.2 +2967aa416a4f3cdb65fc75073a2a148e1f372742 2.6.3 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 Sep 24 15:49:47 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 24 Sep 2014 13:49:47 -0000 Subject: [Pytest-commit] commit/tox: hpk42: bump versions, add announcement Message-ID: <20140924134947.1441.21407@app10.ash-private.bitbucket.org> 1 new commit in tox: https://bitbucket.org/hpk42/tox/commits/b7374e501bde/ Changeset: b7374e501bde User: hpk42 Date: 2014-09-24 13:12:16+00:00 Summary: bump versions, add announcement Affected #: 6 files diff -r ad8d6e2e76902db255b858d2c08a461d9b104e99 -r b7374e501bde055c5c2b572e6512d22e10f60088 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,9 +1,9 @@ -1.8.0.dev1 +1.8.0 ----------- - new multi-dimensional configuration support. Many thanks to Alexander Schepanovski for the complete PR with docs. - And to Mike Bayer for filing an issue wrt to setting booleans. + And to Mike Bayer and others for testing and feedback. - fix issue148: remove "__PYVENV_LAUNCHER__" from os.environ when starting subprocesses. Thanks Steven Myint. diff -r ad8d6e2e76902db255b858d2c08a461d9b104e99 -r b7374e501bde055c5c2b572e6512d22e10f60088 doc/Makefile --- a/doc/Makefile +++ b/doc/Makefile @@ -37,7 +37,7 @@ -rm -rf $(BUILDDIR)/* install: clean html - @rsync -avz $(BUILDDIR)/html/ testrun.org:/www/testrun.org/tox/dev + @rsync -avz $(BUILDDIR)/html/ testrun.org:/www/testrun.org/tox/latest #latexpdf #@scp $(BUILDDIR)/latex/*.pdf testrun.org:www-tox/latest diff -r ad8d6e2e76902db255b858d2c08a461d9b104e99 -r b7374e501bde055c5c2b572e6512d22e10f60088 doc/announce/release-1.8.txt --- /dev/null +++ b/doc/announce/release-1.8.txt @@ -0,0 +1,54 @@ +tox 1.8: Generative/combinatorial environments specs +============================================================================= + +I am happy to announce tox 1.8 which implements parametrized environments. + +See https://tox.testrun.org/config.html#generating-environments-conditional-settings +for examples and the new backward compatible syntax in your tox.ini file. + +Many thanks to Alexander Schepanovski for implementing and refining +it based on the specifcation draft. + +More documentation about tox in general: + + http://tox.testrun.org/ + +Installation: + + pip install -U tox + +code hosting and issue tracking on bitbucket: + + https://bitbucket.org/hpk42/tox + +What is tox? +---------------- + +tox standardizes and automates tedious test activities driven from a +simple ``tox.ini`` file, including: + +* creation and management of different virtualenv environments + with different Python interpreters +* packaging and installing your package into each of them +* running your test tool of choice, be it nose, py.test or unittest2 or other tools such as "sphinx" doc checks +* testing dev packages against each other without needing to upload to PyPI + +best, +Holger Krekel, merlinux GmbH + + +Changes 1.8 (compared to 1.7.2) +--------------------------------------- + +- new multi-dimensional configuration support. Many thanks to + Alexander Schepanovski for the complete PR with docs. + And to Mike Bayer and others for testing and feedback. + +- fix issue148: remove "__PYVENV_LAUNCHER__" from os.environ when starting + subprocesses. Thanks Steven Myint. + +- fix issue152: set VIRTUAL_ENV when running test commands, + thanks Florian Ludwig. + +- better report if we can't get version_info from an interpreter + executable. Thanks Floris Bruynooghe. diff -r ad8d6e2e76902db255b858d2c08a461d9b104e99 -r b7374e501bde055c5c2b572e6512d22e10f60088 doc/conf.py --- a/doc/conf.py +++ b/doc/conf.py @@ -49,7 +49,7 @@ # # The short X.Y version. release = "1.8" -version = "1.8.0.dev" +version = "1.8.0" # The full version, including alpha/beta/rc tags. # The language for content autogenerated by Sphinx. Refer to documentation diff -r ad8d6e2e76902db255b858d2c08a461d9b104e99 -r b7374e501bde055c5c2b572e6512d22e10f60088 setup.py --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ description='virtualenv-based automation of test activities', long_description=open("README.rst").read(), url='http://tox.testrun.org/', - version='1.8.0.dev2', + version='1.8.0', license='http://opensource.org/licenses/MIT', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], author='holger krekel', diff -r ad8d6e2e76902db255b858d2c08a461d9b104e99 -r b7374e501bde055c5c2b572e6512d22e10f60088 tox/__init__.py --- a/tox/__init__.py +++ b/tox/__init__.py @@ -1,5 +1,5 @@ # -__version__ = '1.8.0.dev2' +__version__ = '1.8.0' class exception: class Error(Exception): Repository URL: https://bitbucket.org/hpk42/tox/ -- 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 Sep 24 15:53:59 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 24 Sep 2014 13:53:59 -0000 Subject: [Pytest-commit] commit/tox: 2 new changesets Message-ID: <20140924135359.27040.5486@app03.ash-private.bitbucket.org> 2 new commits in tox: https://bitbucket.org/hpk42/tox/commits/991225a686cd/ Changeset: 991225a686cd User: hpk42 Date: 2014-09-24 13:53:42+00:00 Summary: Added tag 1.8.0 for changeset b7374e501bde Affected #: 1 file diff -r b7374e501bde055c5c2b572e6512d22e10f60088 -r 991225a686cd2d1dd152b4cb727a4c9eae41d709 .hgtags --- a/.hgtags +++ b/.hgtags @@ -18,3 +18,4 @@ 5b4e536b8d3810c791b742b2a8723c53b8d3d720 1.7.0 c7155565c89d1bb3684c881ca774d921188223a0 1.7.1 e319e464470a5885505ab3e1da1a3a7abe5f86e2 1.7.2 +b7374e501bde055c5c2b572e6512d22e10f60088 1.8.0 https://bitbucket.org/hpk42/tox/commits/2da3bf39df59/ Changeset: 2da3bf39df59 User: hpk42 Date: 2014-09-24 13:53:48+00:00 Summary: fix release announce Affected #: 1 file diff -r 991225a686cd2d1dd152b4cb727a4c9eae41d709 -r 2da3bf39df5974a533f721da9b015e0b146ef927 doc/announce/release-1.8.txt --- a/doc/announce/release-1.8.txt +++ b/doc/announce/release-1.8.txt @@ -3,7 +3,7 @@ I am happy to announce tox 1.8 which implements parametrized environments. -See https://tox.testrun.org/config.html#generating-environments-conditional-settings +See https://tox.testrun.org/latest/config.html#generating-environments-conditional-settings for examples and the new backward compatible syntax in your tox.ini file. Many thanks to Alexander Schepanovski for implementing and refining Repository URL: https://bitbucket.org/hpk42/tox/ -- 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 Sep 24 16:27:46 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 24 Sep 2014 14:27:46 -0000 Subject: [Pytest-commit] commit/pytest: 2 new changesets Message-ID: <20140924142746.6201.77562@app08.ash-private.bitbucket.org> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/9982cf39dba1/ Changeset: 9982cf39dba1 User: hpk42 Date: 2014-09-24 14:00:06+00:00 Summary: add release announce Affected #: 1 file diff -r 43d374de24a8644e3d27563832175a510f83a870 -r 9982cf39dba19b3382d4589a83b7bfd9b82d5987 doc/en/announce/index.txt --- a/doc/en/announce/index.txt +++ b/doc/en/announce/index.txt @@ -5,6 +5,7 @@ .. toctree:: :maxdepth: 2 + release-2.6.3 release-2.6.2 release-2.6.1 release-2.6.0 https://bitbucket.org/hpk42/pytest/commits/f829d42dd9f7/ Changeset: f829d42dd9f7 User: hpk42 Date: 2014-09-24 14:27:34+00:00 Summary: bump version to 2.6.4.dev Affected #: 2 files diff -r 9982cf39dba19b3382d4589a83b7bfd9b82d5987 -r f829d42dd9f7a5deb4a4e497d8ca08c08fdeba9c _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.6.3' +__version__ = '2.6.4.dev1' diff -r 9982cf39dba19b3382d4589a83b7bfd9b82d5987 -r f829d42dd9f7a5deb4a4e497d8ca08c08fdeba9c setup.py --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ name='pytest', description='pytest: simple powerful testing with Python', long_description=long_description, - version='2.6.3', + version='2.6.4.dev1', 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 Sep 24 16:28:04 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 24 Sep 2014 14:28:04 -0000 Subject: [Pytest-commit] commit/tox: hpk42: bump to dev version Message-ID: <20140924142804.2346.70196@app06.ash-private.bitbucket.org> 1 new commit in tox: https://bitbucket.org/hpk42/tox/commits/73185db55d67/ Changeset: 73185db55d67 User: hpk42 Date: 2014-09-24 14:27:55+00:00 Summary: bump to dev version Affected #: 2 files diff -r 2da3bf39df5974a533f721da9b015e0b146ef927 -r 73185db55d671a386d617958076d95a88f602328 setup.py --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ description='virtualenv-based automation of test activities', long_description=open("README.rst").read(), url='http://tox.testrun.org/', - version='1.8.0', + version='1.8.1.dev1', license='http://opensource.org/licenses/MIT', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], author='holger krekel', diff -r 2da3bf39df5974a533f721da9b015e0b146ef927 -r 73185db55d671a386d617958076d95a88f602328 tox/__init__.py --- a/tox/__init__.py +++ b/tox/__init__.py @@ -1,5 +1,5 @@ # -__version__ = '1.8.0' +__version__ = '1.8.1.dev1' class exception: class Error(Exception): Repository URL: https://bitbucket.org/hpk42/tox/ -- 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 Sep 24 19:53:24 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 24 Sep 2014 17:53:24 -0000 Subject: [Pytest-commit] commit/pytest: bubenkoff: Close branch better-diff. Message-ID: <20140924175324.11982.17394@app13.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/60863defa8d7/ Changeset: 60863defa8d7 Branch: better-diff User: bubenkoff Date: 2014-09-24 17:53:21+00:00 Summary: Close branch better-diff. Affected #: 0 files 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 issues-reply at bitbucket.org Wed Sep 24 21:30:33 2014 From: issues-reply at bitbucket.org (Chakra Medavarapu) Date: Wed, 24 Sep 2014 19:30:33 -0000 Subject: [Pytest-commit] Issue #597: TypeError: compile() expected string without null bytes (hpk42/pytest) Message-ID: <20140924193033.6244.70448@app10.ash-private.bitbucket.org> New issue 597: TypeError: compile() expected string without null bytes https://bitbucket.org/hpk42/pytest/issue/597/typeerror-compile-expected-string-without Chakra Medavarapu: We are seeing this error on Windows and linux with pytest-2.6.1 and 2.6.2. Let me know if you need more information. {code} INTERNALERROR> Traceback (most recent call last): INTERNALERROR> File "c:\testtools\pytest-2.6.2\_pytest\main.py", line 84, in wrap_session INTERNALERROR> doit(config, session) INTERNALERROR> File "c:\testtools\pytest-2.6.2\_pytest\main.py", line 122, in _main INTERNALERROR> config.hook.pytest_runtestloop(session=session) INTERNALERROR> File "c:\testtools\pytest-2.6.2\_pytest\core.py", line 413, in __call__ INTERNALERROR> return self._docall(methods, kwargs) INTERNALERROR> File "c:\testtools\pytest-2.6.2\_pytest\core.py", line 424, in _docall INTERNALERROR> res = mc.execute() INTERNALERROR> File "c:\testtools\pytest-2.6.2\_pytest\core.py", line 315, in execute INTERNALERROR> res = method(**kwargs) INTERNALERROR> File "c:\testtools\pytest-2.6.2\_pytest\main.py", line 142, in pytest_runtestloop INTERNALERROR> item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem) INTERNALERROR> File "c:\testtools\pytest-2.6.2\_pytest\core.py", line 413, in __call__ INTERNALERROR> return self._docall(methods, kwargs) INTERNALERROR> File "c:\testtools\pytest-2.6.2\_pytest\core.py", line 424, in _docall INTERNALERROR> res = mc.execute() INTERNALERROR> File "c:\testtools\pytest-2.6.2\_pytest\core.py", line 315, in execute INTERNALERROR> res = method(**kwargs) INTERNALERROR> File "c:\testtools\pytest-2.6.2\_pytest\runner.py", line 65, in pytest_runtest_protocol INTERNALERROR> runtestprotocol(item, nextitem=nextitem) INTERNALERROR> File "c:\testtools\pytest-2.6.2\_pytest\runner.py", line 72, in runtestprotocol INTERNALERROR> rep = call_and_report(item, "setup", log) INTERNALERROR> File "c:\testtools\pytest-2.6.2\_pytest\runner.py", line 111, in call_and_report INTERNALERROR> report = hook.pytest_runtest_makereport(item=item, call=call) INTERNALERROR> File "c:\testtools\pytest-2.6.2\_pytest\main.py", line 166, in call_matching_hooks INTERNALERROR> return hookmethod.pcall(plugins, **kwargs) INTERNALERROR> File "c:\testtools\pytest-2.6.2\_pytest\core.py", line 417, in pcall INTERNALERROR> return self._docall(methods, kwargs) INTERNALERROR> File "c:\testtools\pytest-2.6.2\_pytest\core.py", line 424, in _docall INTERNALERROR> res = mc.execute() INTERNALERROR> File "c:\testtools\pytest-2.6.2\_pytest\core.py", line 315, in execute INTERNALERROR> res = method(**kwargs) INTERNALERROR> File "c:\testtools\pytest-2.6.2\_pytest\runner.py", line 217, in pytest_runtest_makereport INTERNALERROR> style=item.config.option.tbstyle) INTERNALERROR> File "c:\testtools\pytest-2.6.2\_pytest\python.py", line 593, in _repr_failure_py INTERNALERROR> style=style) INTERNALERROR> File "c:\testtools\pytest-2.6.2\_pytest\main.py", line 411, in _repr_failure_py INTERNALERROR> style=style, tbfilter=tbfilter) INTERNALERROR> File "c:\testtools\Python27\lib\site-packages\py-1.4.24-py2.7.egg\py\_code\code.py", line 412, in getrepr INTERNALERROR> return fmt.repr_excinfo(self) INTERNALERROR> File "c:\testtools\Python27\lib\site-packages\py-1.4.24-py2.7.egg\py\_code\code.py", line 589, in repr_excinfo INTERNALERROR> reprtraceback = self.repr_traceback(excinfo) INTERNALERROR> File "c:\testtools\Python27\lib\site-packages\py-1.4.24-py2.7.egg\py\_code\code.py", line 581, in repr_traceback INTERNALERROR> reprentry = self.repr_traceback_entry(entry, einfo) INTERNALERROR> File "c:\testtools\Python27\lib\site-packages\py-1.4.24-py2.7.egg\py\_code\code.py", line 528, in repr_traceback_entry INTERNALERROR> source = self._getentrysource(entry) INTERNALERROR> File "c:\testtools\Python27\lib\site-packages\py-1.4.24-py2.7.egg\py\_code\code.py", line 455, in _getentrysource INTERNALERROR> source = entry.getsource(self.astcache) INTERNALERROR> File "c:\testtools\Python27\lib\site-packages\py-1.4.24-py2.7.egg\py\_code\code.py", line 204, in getsource INTERNALERROR> astnode=astnode) INTERNALERROR> File "c:\testtools\Python27\lib\site-packages\py-1.4.24-py2.7.egg\py\_code\source.py", line 367, in getstatementrange_ast INTERNALERROR> astnode = compile(content, "source", "exec", 1024) # 1024 for AST INTERNALERROR> TypeError: compile() expected string without null bytes {code} From issues-reply at bitbucket.org Thu Sep 25 14:58:11 2014 From: issues-reply at bitbucket.org (Hynek Schlawack) Date: Thu, 25 Sep 2014 12:58:11 -0000 Subject: [Pytest-commit] =?utf-8?q?Issue_=23190=3A_Generative_setenv_fails?= =?utf-8?q?_if_there=E2=80=99s_only_one_variable_=28hpk42/tox=29?= Message-ID: <20140925125811.20600.90278@app14.ash-private.bitbucket.org> New issue 190: Generative setenv fails if there?s only one variable https://bitbucket.org/hpk42/tox/issue/190/generative-setenv-fails-if-there-s-only Hynek Schlawack: Consider this minimal tox.ini: ```ini [tox] envlist = py27-{a,b} [testenv] deps = b: pytest setenv = a: A = 1 commands = true ``` Running `tox -l` on it fails with ``` Traceback (most recent call last): File "/Users/hynek/.local/bin/tox", line 9, in load_entry_point('tox==1.8.0', 'console_scripts', 'tox')() File "/Users/hynek/.local/venvs/tox/lib/python2.7/site-packages/tox/_cmdline.py", line 25, in main config = parseconfig(args, 'tox') File "/Users/hynek/.local/venvs/tox/lib/python2.7/site-packages/tox/_config.py", line 42, in parseconfig parseini(config, inipath) File "/Users/hynek/.local/venvs/tox/lib/python2.7/site-packages/tox/_config.py", line 296, in __init__ self._makeenvconfig(name, section, reader._subs, config) File "/Users/hynek/.local/venvs/tox/lib/python2.7/site-packages/tox/_config.py", line 354, in _makeenvconfig setenv.update(reader.getdict(section, 'setenv')) File "/Users/hynek/.local/venvs/tox/lib/python2.7/site-packages/tox/_config.py", line 529, in getdict name, rest = line.split('=', 1) ValueError: need more than 1 value to unpack ``` while ```ini [tox] envlist = py27-{a,b} [testenv] setenv = a: A = 1 b: B = 1 commands = true ``` and ```ini [tox] envlist = py27 [testenv] setenv = A = 1 commands = true ``` work just fine. From issues-reply at bitbucket.org Thu Sep 25 15:31:40 2014 From: issues-reply at bitbucket.org (Hynek Schlawack) Date: Thu, 25 Sep 2014 13:31:40 -0000 Subject: [Pytest-commit] Issue #191: Generative environments are only created if the fragment is used (hpk42/tox) Message-ID: <20140925133140.11606.89413@app03.ash-private.bitbucket.org> New issue 191: Generative environments are only created if the fragment is used https://bitbucket.org/hpk42/tox/issue/191/generative-environments-are-only-created Hynek Schlawack: Example: ```init [tox] envlist = py27-{a,b} [testenv] deps = b: pytest commands = true ``` Makes `tox -l` complain: `ERROR: unknown environment 'py27-a'` My current workaround is to conditionally set some bogus env variable (which let me run int o #190 :)). Having unused fragments is useful, I do it for example in https://github.com/hynek/structlog/blob/master/tox.ini to be more explicit and save myself listing ?bare? environments. From commits-noreply at bitbucket.org Thu Sep 25 16:01:01 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 25 Sep 2014 14:01:01 -0000 Subject: [Pytest-commit] commit/tox: 3 new changesets Message-ID: <20140925140101.23649.48366@app14.ash-private.bitbucket.org> 3 new commits in tox: https://bitbucket.org/hpk42/tox/commits/81a452f9aee1/ Changeset: 81a452f9aee1 User: hpk42 Date: 2014-09-25 13:38:44+00:00 Summary: py25 not supported anymore Affected #: 1 file diff -r 73185db55d671a386d617958076d95a88f602328 -r 81a452f9aee1722b22d7b32b8c39ae1602d4184e setup.py --- a/setup.py +++ b/setup.py @@ -19,10 +19,8 @@ def main(): version = sys.version_info[:2] install_requires = ['virtualenv>=1.11.2', 'py>=1.4.17', ] - if version < (2, 7) or (3, 0) <= version <= (3, 1): + if version < (2, 7): install_requires += ['argparse'] - if version < (2,6): - install_requires += ["simplejson"] setup( name='tox', description='virtualenv-based automation of test activities', https://bitbucket.org/hpk42/tox/commits/69a69d68fc46/ Changeset: 69a69d68fc46 User: hpk42 Date: 2014-09-25 13:43:21+00:00 Summary: fix issue190: allow setenv to be empty Affected #: 3 files diff -r 81a452f9aee1722b22d7b32b8c39ae1602d4184e -r 69a69d68fc4679616daed127e8f5fd66085805c6 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +1.8.1.dev +----------- + +- fix issue190: allow setenv to be empty. + + 1.8.0 ----------- diff -r 81a452f9aee1722b22d7b32b8c39ae1602d4184e -r 69a69d68fc4679616daed127e8f5fd66085805c6 tests/test_config.py --- a/tests/test_config.py +++ b/tests/test_config.py @@ -896,6 +896,20 @@ assert configs["py27"].recreate assert not configs["py33"].recreate + @pytest.mark.issue190 + def test_factors_in_setenv(self, newconfig): + inisource=""" + [tox] + envlist = py27,py26 + + [testenv] + setenv = + py27: X = 1 + """ + configs = newconfig([], inisource).envconfigs + assert configs["py27"].setenv["X"] == "1" + assert "X" not in configs["py26"].setenv + class TestGlobalOptions: def test_notest(self, newconfig): diff -r 81a452f9aee1722b22d7b32b8c39ae1602d4184e -r 69a69d68fc4679616daed127e8f5fd66085805c6 tox/_config.py --- a/tox/_config.py +++ b/tox/_config.py @@ -526,6 +526,8 @@ value = {} for line in s.split(sep): + if not line.strip(): + continue name, rest = line.split('=', 1) value[name.strip()] = rest.strip() https://bitbucket.org/hpk42/tox/commits/9aae06bf4a78/ Changeset: 9aae06bf4a78 Branch: issue191 User: hpk42 Date: 2014-09-25 14:00:32+00:00 Summary: fix issue191: factors are now defined by the "envlist" and you don't need to use them in the testenv section anymore. Affected #: 3 files diff -r 69a69d68fc4679616daed127e8f5fd66085805c6 -r 9aae06bf4a784026e853365821f19bd4a4fb7716 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,8 @@ - fix issue190: allow setenv to be empty. +- fix issue191: factors are now defined by the "envlist" and + you don't need to use them in the testenv section anymore. 1.8.0 ----------- diff -r 69a69d68fc4679616daed127e8f5fd66085805c6 -r 9aae06bf4a784026e853365821f19bd4a4fb7716 tests/test_config.py --- a/tests/test_config.py +++ b/tests/test_config.py @@ -910,6 +910,20 @@ assert configs["py27"].setenv["X"] == "1" assert "X" not in configs["py26"].setenv + @pytest.mark.issue191 + def test_conditional_factors_not_neccessary(self, newconfig): + inisource=""" + [tox] + envlist = py27-{thread,greenlet} + + [testenv] + commands = echo {envname} + """ + configs = newconfig([], inisource).envconfigs + assert "py27-thread" in str(configs["py27-thread"].commands) + assert "py27-greenlet" in str(configs["py27-greenlet"].commands) + assert len(configs) == 2 + class TestGlobalOptions: def test_notest(self, newconfig): diff -r 69a69d68fc4679616daed127e8f5fd66085805c6 -r 9aae06bf4a784026e853365821f19bd4a4fb7716 tox/_config.py --- a/tox/_config.py +++ b/tox/_config.py @@ -285,8 +285,8 @@ config.envlist, all_envs = self._getenvdata(reader, toxsection) # configure testenvs - known_factors = self._list_section_factors("testenv") - known_factors.update(default_factors) + known_factors = set(default_factors) + map(known_factors.update, [x.split("-") for x in config.envlist]) known_factors.add("python") for name in all_envs: section = testenvprefix + name @@ -301,14 +301,6 @@ config.skipsdist = reader.getbool(toxsection, "skipsdist", all_develop) - def _list_section_factors(self, section): - factors = set() - if section in self._cfg: - for _, value in self._cfg[section].items(): - exprs = re.findall(r'^([\w{},-]+)\:\s+', value, re.M) - factors.update(*mapcat(_split_factor_expr, exprs)) - return factors - def _makeenvconfig(self, name, section, subs, config): vc = VenvConfig(envname=name) vc.config = config Repository URL: https://bitbucket.org/hpk42/tox/ -- 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 issues-reply at bitbucket.org Thu Sep 25 18:29:33 2014 From: issues-reply at bitbucket.org (liori) Date: Thu, 25 Sep 2014 16:29:33 -0000 Subject: [Pytest-commit] Issue #598: Ability to randomize testing order (hpk42/pytest) Message-ID: <20140925162933.8647.26269@app07.ash-private.bitbucket.org> New issue 598: Ability to randomize testing order https://bitbucket.org/hpk42/pytest/issue/598/ability-to-randomize-testing-order liori: I have two types of tests: CPU-bound and IO-bound. When playing with `xdist` I realized that these tests tend to cluster, ie. there's a huge block of CPU-bound tests, then a block of IO-bound tests, etc. I assumed that if I could interleave these blocks of tests, the test suite will execute faster. So I hacked up `pytest` to hardcode a simple randomization scheme; I changed `pytest.main.Session.perform_collect` to have the following code: ``` #!python def perform_collect(self, args=None, genitems=True): hook = self.config.hook try: items = self._perform_collect(args, genitems) hook.pytest_collection_modifyitems(session=self, config=self.config, items=items) finally: import random random.Random(42).shuffle(self.items) hook.pytest_collection_finish(session=self) return items ``` Before this change my test suite executed with `py.test -n 4` took 60 seconds to complete. Now it's about 40 seconds, which means I saved ~1/3 of the time. I hope this proves that such an option would be useful. From issues-reply at bitbucket.org Thu Sep 25 23:53:45 2014 From: issues-reply at bitbucket.org (m27315) Date: Thu, 25 Sep 2014 21:53:45 -0000 Subject: [Pytest-commit] Issue #599: internal error at unknown location (hpk42/pytest) Message-ID: <20140925215345.10250.28745@app12.ash-private.bitbucket.org> New issue 599: internal error at unknown location https://bitbucket.org/hpk42/pytest/issue/599/internal-error-at-unknown-location m27315: I have a large pytest suite with 10,000+tests, many due to the power of parameterization! (Thanks!) Recently, I changed the backend driver to connect via pipes for processes on localhost instead of telnet. Anyway, after switching out the backend connection method, I receive the following backtrace: ``` #!python test_elmo_smoke/test_elmo_smoke.py::TestELMO_Smoke::test_smoke2 methods: [, , ] kwargs: {'report': } methods: [>, >] kwargs: {'excrepr': , 'excinfo': } INTERNALERROR> Traceback (most recent call last): INTERNALERROR> File "/lib/python2.7/_pytest/main.py", line 84, in wrap_session INTERNALERROR> doit(config, session) INTERNALERROR> File "/lib/python2.7/_pytest/main.py", line 122, in _main INTERNALERROR> config.hook.pytest_runtestloop(session=session) INTERNALERROR> File "/lib/python2.7/_pytest/core.py", line 414, in __call__ INTERNALERROR> return self._docall(methods, kwargs) INTERNALERROR> File "/lib/python2.7/_pytest/core.py", line 425, in _docall INTERNALERROR> res = mc.execute() INTERNALERROR> File "/lib/python2.7/_pytest/core.py", line 315, in execute INTERNALERROR> res = method(**kwargs) INTERNALERROR> File "/lib/python2.7/_pytest/main.py", line 142, in pytest_runtestloop INTERNALERROR> item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem) INTERNALERROR> File "/lib/python2.7/_pytest/core.py", line 414, in __call__ INTERNALERROR> return self._docall(methods, kwargs) INTERNALERROR> AttributeError: 'TracebackEntry' object has no attribute 'set_repr_style' methods: [, , >] kwargs: {'session': , 'exitstatus': 3} =========================================================== 1 tests deselected by "-m 'smoke2'" ============================================================ ============================================================== 1 deselected in 63.29 seconds =============================================================== methods: [, >, , , , , >] kwargs: {'config': <_pytest.config.Config object at 0x480e4f70>} ``` I added the print statements are _docall to help with the backtrace's lack of information. This seems like a bug in pytest. Most likely there is a bug in my test, but I cannot even begin to debug this. I wish it could tell me what line in my test caused this issue. (It's a BIG test.) Plus, this should result in a fail, not a pass. Thanks for an awesome tool! From issues-reply at bitbucket.org Fri Sep 26 13:38:04 2014 From: issues-reply at bitbucket.org (Marius Gedminas) Date: Fri, 26 Sep 2014 11:38:04 -0000 Subject: [Pytest-commit] Issue #192: Report subprocess exit code when invocation fails (hpk42/tox) Message-ID: <20140926113804.19560.47216@app09.ash-private.bitbucket.org> New issue 192: Report subprocess exit code when invocation fails https://bitbucket.org/hpk42/tox/issue/192/report-subprocess-exit-code-when Marius Gedminas: Story: A Jenkins job running tox [failed](https://jenkins.gedmin.as/job/zodbbrowser/62/console) in the 'pip install' step, without a clear error message. After some headscratching I decided to look at dmesg and saw that the server ran out of memory and the OOM killer decided to kill some processes. Now if tox reported actual exit statuses instead of just saying "invocation failed", I might've seen that pip did not exit with an error code but rather was killed by a signal. That would've been a useful Clue to have. From issues-reply at bitbucket.org Sat Sep 27 02:31:44 2014 From: issues-reply at bitbucket.org (Ldiary Translations) Date: Sat, 27 Sep 2014 00:31:44 -0000 Subject: [Pytest-commit] Issue #600: python_class suffix (hpk42/pytest) Message-ID: <20140927003144.13989.7110@app12.ash-private.bitbucket.org> New issue 600: python_class suffix https://bitbucket.org/hpk42/pytest/issue/600/python_class-suffix Ldiary Translations: Is there a way to specify a suffix instead of a prefix for python_classes defined in pytest.ini? Here's basically what I want my pytest.ini to become: [pytest] python_files=*Tests.py python_classes=*Suite python_functions=test Is there a way to make it work just like how it works for python_files? From commits-noreply at bitbucket.org Sat Sep 27 10:09:20 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 27 Sep 2014 08:09:20 -0000 Subject: [Pytest-commit] commit/pytest: flub: Merged in bubenkoff/pytest/better-diff-on-verbose-2 (pull request #213) Message-ID: <20140927080920.17659.61688@app02.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/4f8cc52f3fbd/ Changeset: 4f8cc52f3fbd User: flub Date: 2014-09-27 08:09:16+00:00 Summary: Merged in bubenkoff/pytest/better-diff-on-verbose-2 (pull request #213) Improve assertion failure reporting on iterables, by using ndiff and pprint. Affected #: 3 files diff -r f829d42dd9f7a5deb4a4e497d8ca08c08fdeba9c -r 4f8cc52f3fbd64384a8e9ea2c0d7ff34bfb42629 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +Unreleased +---------- + +- Improve assertion failure reporting on iterables, by using ndiff and pprint. + 2.6.3 ----------- @@ -80,7 +85,7 @@ - fix issue with detecting conftest files if the arguments contain "::" node id specifications (copy pasted from "-v" output) -- fix issue544 by only removing "@NUM" at the end of "::" separated parts +- fix issue544 by only removing "@NUM" at the end of "::" separated parts and if the part has an ".py" extension - don't use py.std import helper, rather import things directly. @@ -93,7 +98,7 @@ - fix issue537: Avoid importing old assertion reinterpretation code by default. -- fix issue364: shorten and enhance tracebacks representation by default. +- fix issue364: shorten and enhance tracebacks representation by default. The new "--tb=auto" option (default) will only display long tracebacks for the first and last entry. You can get the old behaviour of printing all entries as long entries with "--tb=long". Also short entries by @@ -119,14 +124,14 @@ - fix issue473: work around mock putting an unbound method into a class dict when double-patching. -- fix issue498: if a fixture finalizer fails, make sure that +- fix issue498: if a fixture finalizer fails, make sure that the fixture is still invalidated. - fix issue453: the result of the pytest_assertrepr_compare hook now gets it's newlines escaped so that format_exception does not blow up. - internal new warning system: pytest will now produce warnings when - it detects oddities in your test collection or execution. + it detects oddities in your test collection or execution. Warnings are ultimately sent to a new pytest_logwarning hook which is currently only implemented by the terminal plugin which displays warnings in the summary line and shows more details when -rw (report on @@ -170,7 +175,7 @@ - fix issue492: avoid leak in test_writeorg. Thanks Marc Abramowitz. -- fix issue493: don't run tests in doc directory with ``python setup.py test`` +- fix issue493: don't run tests in doc directory with ``python setup.py test`` (use tox -e doctesting for that) - fix issue486: better reporting and handling of early conftest loading failures @@ -184,8 +189,8 @@ Groenholm. - support nose-style ``__test__`` attribute on modules, classes and - functions, including unittest-style Classes. If set to False, the - test will not be collected. + functions, including unittest-style Classes. If set to False, the + test will not be collected. - fix issue512: show "" for arguments which might not be set in monkeypatch plugin. Improves output in documentation. @@ -195,11 +200,11 @@ ----------------------------------- - fix issue409 -- better interoperate with cx_freeze by not - trying to import from collections.abc which causes problems + trying to import from collections.abc which causes problems for py27/cx_freeze. Thanks Wolfgang L. for reporting and tracking it down. - fixed docs and code to use "pytest" instead of "py.test" almost everywhere. - Thanks Jurko Gospodnetic for the complete PR. + Thanks Jurko Gospodnetic for the complete PR. - fix issue425: mention at end of "py.test -h" that --markers and --fixtures work according to specified test path (or current dir) @@ -210,7 +215,7 @@ - copy, cleanup and integrate py.io capture from pylib 1.4.20.dev2 (rev 13d9af95547e) - + - address issue416: clarify docs as to conftest.py loading semantics - fix issue429: comparing byte strings with non-ascii chars in assert @@ -230,7 +235,7 @@ - Allow parameterized fixtures to specify the ID of the parameters by adding an ids argument to pytest.fixture() and pytest.yield_fixture(). - Thanks Floris Bruynooghe. + Thanks Floris Bruynooghe. - fix issue404 by always using the binary xml escape in the junitxml plugin. Thanks Ronny Pfannschmidt. diff -r f829d42dd9f7a5deb4a4e497d8ca08c08fdeba9c -r 4f8cc52f3fbd64384a8e9ea2c0d7ff34bfb42629 _pytest/assertion/util.py --- a/_pytest/assertion/util.py +++ b/_pytest/assertion/util.py @@ -135,18 +135,32 @@ isdict = lambda x: isinstance(x, dict) isset = lambda x: isinstance(x, (set, frozenset)) + def isiterable(obj): + try: + iter(obj) + return not istext(obj) + except TypeError: + return False + verbose = config.getoption('verbose') explanation = None try: if op == '==': if istext(left) and istext(right): explanation = _diff_text(left, right, verbose) - elif issequence(left) and issequence(right): - explanation = _compare_eq_sequence(left, right, verbose) - elif isset(left) and isset(right): - explanation = _compare_eq_set(left, right, verbose) - elif isdict(left) and isdict(right): - explanation = _compare_eq_dict(left, right, verbose) + else: + if issequence(left) and issequence(right): + explanation = _compare_eq_sequence(left, right, verbose) + elif isset(left) and isset(right): + explanation = _compare_eq_set(left, right, verbose) + elif isdict(left) and isdict(right): + explanation = _compare_eq_dict(left, right, verbose) + if isiterable(left) and isiterable(right): + expl = _compare_eq_iterable(left, right, verbose) + if explanation is not None: + explanation.extend(expl) + else: + explanation = expl elif op == 'not in': if istext(left) and istext(right): explanation = _notin_text(left, right, verbose) @@ -203,6 +217,19 @@ return explanation +def _compare_eq_iterable(left, right, verbose=False): + if not verbose: + return [u('Use -v to get the full diff')] + # dynamic import to speedup pytest + import difflib + + left = pprint.pformat(left).splitlines() + right = pprint.pformat(right).splitlines() + explanation = [u('Full diff:')] + explanation.extend(line.strip() for line in difflib.ndiff(left, right)) + return explanation + + def _compare_eq_sequence(left, right, verbose=False): explanation = [] for i in range(min(len(left), len(right))): diff -r f829d42dd9f7a5deb4a4e497d8ca08c08fdeba9c -r 4f8cc52f3fbd64384a8e9ea2c0d7ff34bfb42629 testing/test_assertion.py --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -1,11 +1,14 @@ # -*- coding: utf-8 -*- import sys +import textwrap import py, pytest import _pytest.assertion as plugin from _pytest.assertion import reinterpret from _pytest.assertion import util + needsnewassert = pytest.mark.skipif("sys.version_info < (2,6)") +PY3 = sys.version_info >= (3, 0) @pytest.fixture @@ -86,6 +89,48 @@ expl = callequal([0, 1], [0, 2]) assert len(expl) > 1 + @pytest.mark.parametrize( + ['left', 'right', 'expected'], [ + ([0, 1], [0, 2], """ + Full diff: + - [0, 1] + ? ^ + + [0, 2] + ? ^ + """), + ({0: 1}, {0: 2}, """ + Full diff: + - {0: 1} + ? ^ + + {0: 2} + ? ^ + """), + (set([0, 1]), set([0, 2]), """ + Full diff: + - set([0, 1]) + ? ^ + + set([0, 2]) + ? ^ + """ if not PY3 else """ + Full diff: + - {0, 1} + ? ^ + + {0, 2} + ? ^ + """) + ] + ) + def test_iterable_full_diff(self, left, right, expected): + """Test the full diff assertion failure explanation. + + When verbose is False, then just a -v notice to get the diff is rendered, + when verbose is True, then ndiff of the pprint is returned. + """ + expl = callequal(left, right, verbose=False) + assert expl[-1] == 'Use -v to get the full diff' + expl = '\n'.join(callequal(left, right, verbose=True)) + assert expl.endswith(textwrap.dedent(expected).strip()) + def test_list_different_lenghts(self): expl = callequal([0, 1], [0, 1, 2]) assert len(expl) > 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 Sat Sep 27 10:09:20 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 27 Sep 2014 08:09:20 -0000 Subject: [Pytest-commit] commit/pytest: 2 new changesets Message-ID: <20140927080920.32723.75926@app14.ash-private.bitbucket.org> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/23a70aa66ddf/ Changeset: 23a70aa66ddf Branch: better-diff-on-verbose-2 User: bubenkoff Date: 2014-09-27 01:29:47+00:00 Summary: Improve assertion failure reporting on iterables, by using ndiff and pprint. Affected #: 3 files diff -r f829d42dd9f7a5deb4a4e497d8ca08c08fdeba9c -r 23a70aa66ddfe1c7d7f6ce9e431a31a4895443ab CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +Unreleased +---------- + +- Improve assertion failure reporting on iterables, by using ndiff and pprint. + 2.6.3 ----------- @@ -80,7 +85,7 @@ - fix issue with detecting conftest files if the arguments contain "::" node id specifications (copy pasted from "-v" output) -- fix issue544 by only removing "@NUM" at the end of "::" separated parts +- fix issue544 by only removing "@NUM" at the end of "::" separated parts and if the part has an ".py" extension - don't use py.std import helper, rather import things directly. @@ -93,7 +98,7 @@ - fix issue537: Avoid importing old assertion reinterpretation code by default. -- fix issue364: shorten and enhance tracebacks representation by default. +- fix issue364: shorten and enhance tracebacks representation by default. The new "--tb=auto" option (default) will only display long tracebacks for the first and last entry. You can get the old behaviour of printing all entries as long entries with "--tb=long". Also short entries by @@ -119,14 +124,14 @@ - fix issue473: work around mock putting an unbound method into a class dict when double-patching. -- fix issue498: if a fixture finalizer fails, make sure that +- fix issue498: if a fixture finalizer fails, make sure that the fixture is still invalidated. - fix issue453: the result of the pytest_assertrepr_compare hook now gets it's newlines escaped so that format_exception does not blow up. - internal new warning system: pytest will now produce warnings when - it detects oddities in your test collection or execution. + it detects oddities in your test collection or execution. Warnings are ultimately sent to a new pytest_logwarning hook which is currently only implemented by the terminal plugin which displays warnings in the summary line and shows more details when -rw (report on @@ -170,7 +175,7 @@ - fix issue492: avoid leak in test_writeorg. Thanks Marc Abramowitz. -- fix issue493: don't run tests in doc directory with ``python setup.py test`` +- fix issue493: don't run tests in doc directory with ``python setup.py test`` (use tox -e doctesting for that) - fix issue486: better reporting and handling of early conftest loading failures @@ -184,8 +189,8 @@ Groenholm. - support nose-style ``__test__`` attribute on modules, classes and - functions, including unittest-style Classes. If set to False, the - test will not be collected. + functions, including unittest-style Classes. If set to False, the + test will not be collected. - fix issue512: show "" for arguments which might not be set in monkeypatch plugin. Improves output in documentation. @@ -195,11 +200,11 @@ ----------------------------------- - fix issue409 -- better interoperate with cx_freeze by not - trying to import from collections.abc which causes problems + trying to import from collections.abc which causes problems for py27/cx_freeze. Thanks Wolfgang L. for reporting and tracking it down. - fixed docs and code to use "pytest" instead of "py.test" almost everywhere. - Thanks Jurko Gospodnetic for the complete PR. + Thanks Jurko Gospodnetic for the complete PR. - fix issue425: mention at end of "py.test -h" that --markers and --fixtures work according to specified test path (or current dir) @@ -210,7 +215,7 @@ - copy, cleanup and integrate py.io capture from pylib 1.4.20.dev2 (rev 13d9af95547e) - + - address issue416: clarify docs as to conftest.py loading semantics - fix issue429: comparing byte strings with non-ascii chars in assert @@ -230,7 +235,7 @@ - Allow parameterized fixtures to specify the ID of the parameters by adding an ids argument to pytest.fixture() and pytest.yield_fixture(). - Thanks Floris Bruynooghe. + Thanks Floris Bruynooghe. - fix issue404 by always using the binary xml escape in the junitxml plugin. Thanks Ronny Pfannschmidt. diff -r f829d42dd9f7a5deb4a4e497d8ca08c08fdeba9c -r 23a70aa66ddfe1c7d7f6ce9e431a31a4895443ab _pytest/assertion/util.py --- a/_pytest/assertion/util.py +++ b/_pytest/assertion/util.py @@ -135,18 +135,32 @@ isdict = lambda x: isinstance(x, dict) isset = lambda x: isinstance(x, (set, frozenset)) + def isiterable(obj): + try: + iter(obj) + return not istext(obj) + except TypeError: + return False + verbose = config.getoption('verbose') explanation = None try: if op == '==': if istext(left) and istext(right): explanation = _diff_text(left, right, verbose) - elif issequence(left) and issequence(right): - explanation = _compare_eq_sequence(left, right, verbose) - elif isset(left) and isset(right): - explanation = _compare_eq_set(left, right, verbose) - elif isdict(left) and isdict(right): - explanation = _compare_eq_dict(left, right, verbose) + else: + if issequence(left) and issequence(right): + explanation = _compare_eq_sequence(left, right, verbose) + elif isset(left) and isset(right): + explanation = _compare_eq_set(left, right, verbose) + elif isdict(left) and isdict(right): + explanation = _compare_eq_dict(left, right, verbose) + if isiterable(left) and isiterable(right): + expl = _compare_eq_iterable(left, right, verbose) + if explanation is not None: + explanation.extend(expl) + else: + explanation = expl elif op == 'not in': if istext(left) and istext(right): explanation = _notin_text(left, right, verbose) @@ -203,6 +217,19 @@ return explanation +def _compare_eq_iterable(left, right, verbose=False): + if not verbose: + return [u('Use -v to get the full diff')] + # dynamic import to speedup pytest + import difflib + + left = pprint.pformat(left).splitlines() + right = pprint.pformat(right).splitlines() + explanation = [u('Full diff:')] + explanation.extend(line.strip() for line in difflib.ndiff(left, right)) + return explanation + + def _compare_eq_sequence(left, right, verbose=False): explanation = [] for i in range(min(len(left), len(right))): diff -r f829d42dd9f7a5deb4a4e497d8ca08c08fdeba9c -r 23a70aa66ddfe1c7d7f6ce9e431a31a4895443ab testing/test_assertion.py --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -1,11 +1,14 @@ # -*- coding: utf-8 -*- import sys +import textwrap import py, pytest import _pytest.assertion as plugin from _pytest.assertion import reinterpret from _pytest.assertion import util + needsnewassert = pytest.mark.skipif("sys.version_info < (2,6)") +PY3 = sys.version_info >= (3, 0) @pytest.fixture @@ -86,6 +89,48 @@ expl = callequal([0, 1], [0, 2]) assert len(expl) > 1 + @pytest.mark.parametrize( + ['left', 'right', 'expected'], [ + ([0, 1], [0, 2], """ + Full diff: + - [0, 1] + ? ^ + + [0, 2] + ? ^ + """), + ({0: 1}, {0: 2}, """ + Full diff: + - {0: 1} + ? ^ + + {0: 2} + ? ^ + """), + (set([0, 1]), set([0, 2]), """ + Full diff: + - set([0, 1]) + ? ^ + + set([0, 2]) + ? ^ + """ if not PY3 else """ + Full diff: + - {0, 1} + ? ^ + + {0, 2} + ? ^ + """) + ] + ) + def test_iterable_full_diff(self, left, right, expected): + """Test the full diff assertion failure explanation. + + When verbose is False, then just a -v notice to get the diff is rendered, + when verbose is True, then ndiff of the pprint is returned. + """ + expl = callequal(left, right, verbose=False) + assert expl[-1] == 'Use -v to get the full diff' + expl = '\n'.join(callequal(left, right, verbose=True)) + assert expl.endswith(textwrap.dedent(expected).strip()) + def test_list_different_lenghts(self): expl = callequal([0, 1], [0, 1, 2]) assert len(expl) > 1 https://bitbucket.org/hpk42/pytest/commits/4f8cc52f3fbd/ Changeset: 4f8cc52f3fbd User: flub Date: 2014-09-27 08:09:16+00:00 Summary: Merged in bubenkoff/pytest/better-diff-on-verbose-2 (pull request #213) Improve assertion failure reporting on iterables, by using ndiff and pprint. Affected #: 3 files diff -r f829d42dd9f7a5deb4a4e497d8ca08c08fdeba9c -r 4f8cc52f3fbd64384a8e9ea2c0d7ff34bfb42629 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +Unreleased +---------- + +- Improve assertion failure reporting on iterables, by using ndiff and pprint. + 2.6.3 ----------- @@ -80,7 +85,7 @@ - fix issue with detecting conftest files if the arguments contain "::" node id specifications (copy pasted from "-v" output) -- fix issue544 by only removing "@NUM" at the end of "::" separated parts +- fix issue544 by only removing "@NUM" at the end of "::" separated parts and if the part has an ".py" extension - don't use py.std import helper, rather import things directly. @@ -93,7 +98,7 @@ - fix issue537: Avoid importing old assertion reinterpretation code by default. -- fix issue364: shorten and enhance tracebacks representation by default. +- fix issue364: shorten and enhance tracebacks representation by default. The new "--tb=auto" option (default) will only display long tracebacks for the first and last entry. You can get the old behaviour of printing all entries as long entries with "--tb=long". Also short entries by @@ -119,14 +124,14 @@ - fix issue473: work around mock putting an unbound method into a class dict when double-patching. -- fix issue498: if a fixture finalizer fails, make sure that +- fix issue498: if a fixture finalizer fails, make sure that the fixture is still invalidated. - fix issue453: the result of the pytest_assertrepr_compare hook now gets it's newlines escaped so that format_exception does not blow up. - internal new warning system: pytest will now produce warnings when - it detects oddities in your test collection or execution. + it detects oddities in your test collection or execution. Warnings are ultimately sent to a new pytest_logwarning hook which is currently only implemented by the terminal plugin which displays warnings in the summary line and shows more details when -rw (report on @@ -170,7 +175,7 @@ - fix issue492: avoid leak in test_writeorg. Thanks Marc Abramowitz. -- fix issue493: don't run tests in doc directory with ``python setup.py test`` +- fix issue493: don't run tests in doc directory with ``python setup.py test`` (use tox -e doctesting for that) - fix issue486: better reporting and handling of early conftest loading failures @@ -184,8 +189,8 @@ Groenholm. - support nose-style ``__test__`` attribute on modules, classes and - functions, including unittest-style Classes. If set to False, the - test will not be collected. + functions, including unittest-style Classes. If set to False, the + test will not be collected. - fix issue512: show "" for arguments which might not be set in monkeypatch plugin. Improves output in documentation. @@ -195,11 +200,11 @@ ----------------------------------- - fix issue409 -- better interoperate with cx_freeze by not - trying to import from collections.abc which causes problems + trying to import from collections.abc which causes problems for py27/cx_freeze. Thanks Wolfgang L. for reporting and tracking it down. - fixed docs and code to use "pytest" instead of "py.test" almost everywhere. - Thanks Jurko Gospodnetic for the complete PR. + Thanks Jurko Gospodnetic for the complete PR. - fix issue425: mention at end of "py.test -h" that --markers and --fixtures work according to specified test path (or current dir) @@ -210,7 +215,7 @@ - copy, cleanup and integrate py.io capture from pylib 1.4.20.dev2 (rev 13d9af95547e) - + - address issue416: clarify docs as to conftest.py loading semantics - fix issue429: comparing byte strings with non-ascii chars in assert @@ -230,7 +235,7 @@ - Allow parameterized fixtures to specify the ID of the parameters by adding an ids argument to pytest.fixture() and pytest.yield_fixture(). - Thanks Floris Bruynooghe. + Thanks Floris Bruynooghe. - fix issue404 by always using the binary xml escape in the junitxml plugin. Thanks Ronny Pfannschmidt. diff -r f829d42dd9f7a5deb4a4e497d8ca08c08fdeba9c -r 4f8cc52f3fbd64384a8e9ea2c0d7ff34bfb42629 _pytest/assertion/util.py --- a/_pytest/assertion/util.py +++ b/_pytest/assertion/util.py @@ -135,18 +135,32 @@ isdict = lambda x: isinstance(x, dict) isset = lambda x: isinstance(x, (set, frozenset)) + def isiterable(obj): + try: + iter(obj) + return not istext(obj) + except TypeError: + return False + verbose = config.getoption('verbose') explanation = None try: if op == '==': if istext(left) and istext(right): explanation = _diff_text(left, right, verbose) - elif issequence(left) and issequence(right): - explanation = _compare_eq_sequence(left, right, verbose) - elif isset(left) and isset(right): - explanation = _compare_eq_set(left, right, verbose) - elif isdict(left) and isdict(right): - explanation = _compare_eq_dict(left, right, verbose) + else: + if issequence(left) and issequence(right): + explanation = _compare_eq_sequence(left, right, verbose) + elif isset(left) and isset(right): + explanation = _compare_eq_set(left, right, verbose) + elif isdict(left) and isdict(right): + explanation = _compare_eq_dict(left, right, verbose) + if isiterable(left) and isiterable(right): + expl = _compare_eq_iterable(left, right, verbose) + if explanation is not None: + explanation.extend(expl) + else: + explanation = expl elif op == 'not in': if istext(left) and istext(right): explanation = _notin_text(left, right, verbose) @@ -203,6 +217,19 @@ return explanation +def _compare_eq_iterable(left, right, verbose=False): + if not verbose: + return [u('Use -v to get the full diff')] + # dynamic import to speedup pytest + import difflib + + left = pprint.pformat(left).splitlines() + right = pprint.pformat(right).splitlines() + explanation = [u('Full diff:')] + explanation.extend(line.strip() for line in difflib.ndiff(left, right)) + return explanation + + def _compare_eq_sequence(left, right, verbose=False): explanation = [] for i in range(min(len(left), len(right))): diff -r f829d42dd9f7a5deb4a4e497d8ca08c08fdeba9c -r 4f8cc52f3fbd64384a8e9ea2c0d7ff34bfb42629 testing/test_assertion.py --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -1,11 +1,14 @@ # -*- coding: utf-8 -*- import sys +import textwrap import py, pytest import _pytest.assertion as plugin from _pytest.assertion import reinterpret from _pytest.assertion import util + needsnewassert = pytest.mark.skipif("sys.version_info < (2,6)") +PY3 = sys.version_info >= (3, 0) @pytest.fixture @@ -86,6 +89,48 @@ expl = callequal([0, 1], [0, 2]) assert len(expl) > 1 + @pytest.mark.parametrize( + ['left', 'right', 'expected'], [ + ([0, 1], [0, 2], """ + Full diff: + - [0, 1] + ? ^ + + [0, 2] + ? ^ + """), + ({0: 1}, {0: 2}, """ + Full diff: + - {0: 1} + ? ^ + + {0: 2} + ? ^ + """), + (set([0, 1]), set([0, 2]), """ + Full diff: + - set([0, 1]) + ? ^ + + set([0, 2]) + ? ^ + """ if not PY3 else """ + Full diff: + - {0, 1} + ? ^ + + {0, 2} + ? ^ + """) + ] + ) + def test_iterable_full_diff(self, left, right, expected): + """Test the full diff assertion failure explanation. + + When verbose is False, then just a -v notice to get the diff is rendered, + when verbose is True, then ndiff of the pprint is returned. + """ + expl = callequal(left, right, verbose=False) + assert expl[-1] == 'Use -v to get the full diff' + expl = '\n'.join(callequal(left, right, verbose=True)) + assert expl.endswith(textwrap.dedent(expected).strip()) + def test_list_different_lenghts(self): expl = callequal([0, 1], [0, 1, 2]) assert len(expl) > 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 issues-reply at bitbucket.org Sat Sep 27 13:54:55 2014 From: issues-reply at bitbucket.org (Anatoly Bubenkov) Date: Sat, 27 Sep 2014 11:54:55 -0000 Subject: [Pytest-commit] Issue #601: pep8 and pep257 compliance of the pytest code (hpk42/pytest) Message-ID: <20140927115455.22664.83890@app02.ash-private.bitbucket.org> New issue 601: pep8 and pep257 compliance of the pytest code https://bitbucket.org/hpk42/pytest/issue/601/pep8-and-pep257-compliance-of-the-pytest Anatoly Bubenkov: Hi it was already discussed a bit during the implementation of the https://bitbucket.org/hpk42/pytest/pull-request/193/fix-for-issue-557-running-a-specific-test/diff In general, i would like pytest to be fully compliant with pep8 and pep257, and then add pytest-pep8 checker to the tox.ini so we can automatically ensure it will stay like this. The reason of this is simple - pep8 and pep257 dramatically increases readability of the code, which is in not in good shape in that sense ATM. Im willing to make that happen in one single PR, but the question to the developers is - will it be approved, if so, i will start working on that. From commits-noreply at bitbucket.org Sat Sep 27 17:06:07 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 27 Sep 2014 15:06:07 -0000 Subject: [Pytest-commit] commit/pytest: nicoddemus: Fixed minor typo in plugins.txt Message-ID: <20140927150607.28621.37568@app14.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/54a2dfe63116/ Changeset: 54a2dfe63116 User: nicoddemus Date: 2014-09-27 14:59:59+00:00 Summary: Fixed minor typo in plugins.txt Affected #: 1 file diff -r 4f8cc52f3fbd64384a8e9ea2c0d7ff34bfb42629 -r 54a2dfe63116b5e6e0600d5bd41aba752eaa3ef5 doc/en/plugins.txt --- a/doc/en/plugins.txt +++ b/doc/en/plugins.txt @@ -29,7 +29,7 @@ # called for running each test in 'a' directory print ("setting up", item) - a/test_in_subdir.py: + a/test_sub.py: def test_sub(): pass 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 issues-reply at bitbucket.org Sun Sep 28 18:43:05 2014 From: issues-reply at bitbucket.org (Dario Bertini) Date: Sun, 28 Sep 2014 16:43:05 -0000 Subject: [Pytest-commit] Issue #193: Remove the --pre pip option by default (hpk42/tox) Message-ID: <20140928164305.17475.2313@app01.ash-private.bitbucket.org> New issue 193: Remove the --pre pip option by default https://bitbucket.org/hpk42/tox/issue/193/remove-the-pre-pip-option-by-default Dario Bertini: This can [break some builds](http://nedbatchelder.com/blog/201409/how_should_i_distribute_coveragepy_alphas.html#commentform) I looked at the Changelog for when this change was introduced, and apparently pip would refuse to install the exactly specified prerelease dependencies unless the `--pre` flag was supplied ``` #!text Also the default [py25] environment modifies the default installer_command (new config option) to use pip without the "--pre" which was introduced with pip-1.4 and is required if you want to install non-stable releases. (tox defaults to install with "--pre" otherwise). ``` This is understandable, but apparently it's not the case anymore, since if you run `pip install coverage==4.0a1` it will install the package without making a fuss I don't know when pip changed its behavior, but it'd be nice to take it into account now From commits-noreply at bitbucket.org Mon Sep 29 10:11:14 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 29 Sep 2014 08:11:14 -0000 Subject: [Pytest-commit] commit/tox: 2 new changesets Message-ID: <20140929081114.11523.94535@app06.ash-private.bitbucket.org> 2 new commits in tox: https://bitbucket.org/hpk42/tox/commits/25efae2240bf/ Changeset: 25efae2240bf User: mgedmin Date: 2014-09-26 12:39:24+00:00 Summary: Report subprocess exit code when invocation fails Fixes #192 Affected #: 2 files diff -r 69a69d68fc4679616daed127e8f5fd66085805c6 -r 25efae2240bfc9c0cc5f63f472a77814a6bf2327 tests/test_z_cmdline.py --- a/tests/test_z_cmdline.py +++ b/tests/test_z_cmdline.py @@ -200,7 +200,7 @@ }) result = cmd.run("tox") result.stdout.fnmatch_lines([ - "ERROR: invocation failed, args: ['*/tox.ini*", + "ERROR: invocation failed (errno 13), args: ['*/tox.ini*", ]) assert result.ret diff -r 69a69d68fc4679616daed127e8f5fd66085805c6 -r 25efae2240bfc9c0cc5f63f472a77814a6bf2327 tox/_cmdline.py --- a/tox/_cmdline.py +++ b/tox/_cmdline.py @@ -95,9 +95,9 @@ try: popen = self._popen(args, cwd, env=env, stdout=f, stderr=STDOUT) - except OSError: - self.report.error("invocation failed, args: %s, cwd: %s" % - (args, cwd)) + except OSError as e: + self.report.error("invocation failed (errno %d), args: %s, cwd: %s" % + (e.errno, args, cwd)) raise popen.outpath = outpath popen.args = [str(x) for x in args] @@ -118,8 +118,8 @@ if ret: invoked = " ".join(map(str, popen.args)) if outpath: - self.report.error("invocation failed, logfile: %s" % - outpath) + self.report.error("invocation failed (exit code %d), logfile: %s" % + (ret, outpath)) out = outpath.read() self.report.error(out) if hasattr(self, "commandlog"): https://bitbucket.org/hpk42/tox/commits/e89dddec56e6/ Changeset: e89dddec56e6 User: mgedmin Date: 2014-09-28 09:25:50+00:00 Summary: Do not rely on specific errno numbers in tests The error number differs on different platforms (Windows vs Linux). Affected #: 1 file diff -r 25efae2240bfc9c0cc5f63f472a77814a6bf2327 -r e89dddec56e6c5844aeb6cc50ea5e2956f53bca6 tests/test_z_cmdline.py --- a/tests/test_z_cmdline.py +++ b/tests/test_z_cmdline.py @@ -200,7 +200,7 @@ }) result = cmd.run("tox") result.stdout.fnmatch_lines([ - "ERROR: invocation failed (errno 13), args: ['*/tox.ini*", + "ERROR: invocation failed (errno *), args: ['*/tox.ini*", ]) assert result.ret Repository URL: https://bitbucket.org/hpk42/tox/ -- 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 Sep 29 12:33:09 2014 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 29 Sep 2014 10:33:09 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: removed outdated japanese docs from source tree. Message-ID: <20140929103309.25187.98699@app08.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/25aa56b376c1/ Changeset: 25aa56b376c1 User: hpk42 Date: 2014-09-29 10:31:15+00:00 Summary: removed outdated japanese docs from source tree. Affected #: 98 files diff -r 54a2dfe63116b5e6e0600d5bd41aba752eaa3ef5 -r 25aa56b376c11b083ccc6d49057b765bc5e4b87a CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,8 @@ - Improve assertion failure reporting on iterables, by using ndiff and pprint. +- removed outdated japanese docs from source tree. + 2.6.3 ----------- diff -r 54a2dfe63116b5e6e0600d5bd41aba752eaa3ef5 -r 25aa56b376c11b083ccc6d49057b765bc5e4b87a doc/ja/Makefile --- a/doc/ja/Makefile +++ /dev/null @@ -1,159 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest - -regen: - PYTHONDONTWRITEBYTECODE=1 COLUMNS=76 regendoc --update *.txt */*.txt - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -install: html - rsync -avz _build/html/ pytest.org:/www/pytest.org/latest-ja - -installpdf: latexpdf - @scp $(BUILDDIR)/latex/pytest.pdf pytest.org:/www/pytest.org/latest - -installall: clean install installpdf - @echo "done" - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/pytest.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/pytest.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/pytest" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/pytest" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - make -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -texinfo: - mkdir -p $(BUILDDIR)/texinfo - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - mkdir -p $(BUILDDIR)/texinfo - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." diff -r 54a2dfe63116b5e6e0600d5bd41aba752eaa3ef5 -r 25aa56b376c11b083ccc6d49057b765bc5e4b87a doc/ja/_static/sphinxdoc.css --- a/doc/ja/_static/sphinxdoc.css +++ /dev/null @@ -1,343 +0,0 @@ -/* - * sphinxdoc.css_t - * ~~~~~~~~~~~~~~~ - * - * Sphinx stylesheet -- sphinxdoc theme. Originally created by - * Armin Ronacher for Werkzeug. - * - * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - - at import url("basic.css"); - -/* -- page layout ----------------------------------------------------------- */ - -body { - font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', - 'Verdana', sans-serif; - font-size: 1.1em; - letter-spacing: -0.01em; - line-height: 150%; - text-align: center; - background-color: #BFD1D4; - color: black; - padding: 0; - border: 1px solid #aaa; - - margin: 0px 80px 0px 80px; - min-width: 740px; -} - -div.document { - background-color: white; - text-align: left; - background-image: url(contents.png); - background-repeat: repeat-x; -} - -div.bodywrapper { - margin: 0 290px 0 0; - border-right: 1px solid #ccc; -} - -div.body { - margin: 0; - padding: 0.5em 20px 20px 20px; -} - -div.related { - font-size: 0.8em; -} - -div.related ul { - background-image: url(navigation.png); - height: 2em; - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; -} - -div.related ul li { - margin: 0; - padding: 0; - height: 2em; - float: left; -} - -div.related ul li.right { - float: right; - margin-right: 5px; -} - -div.related ul li a { - margin: 0; - padding: 0 5px 0 5px; - line-height: 1.75em; - color: #EE9816; -} - -div.related ul li a:hover { - color: #3CA8E7; -} - -div.sphinxsidebarwrapper { - padding: 0; -} - -div.sphinxsidebar { - margin: 0; - padding: 0.5em 15px 15px 0; - width: 260px; - float: right; - font-size: 1em; - text-align: left; -} - -div.sphinxsidebar h3, div.sphinxsidebar h4 { - margin: 1em 0 0.5em 0; - font-size: 1em; - padding: 0.1em 0 0.1em 0.5em; - color: white; - border: 1px solid #86989B; - background-color: #AFC1C4; -} - -div.sphinxsidebar h3 a { - color: white; -} - -div.sphinxsidebar ul { - padding-left: 1.5em; - margin-top: 7px; - padding: 0; - line-height: 130%; -} - -div.sphinxsidebar ul ul { - margin-left: 20px; -} - -div.sphinxsidebar #searchbox input[type="submit"] { - width: 55px; -} - -div.footer { - background-color: #E3EFF1; - color: #86989B; - padding: 3px 8px 3px 0; - clear: both; - font-size: 0.8em; - text-align: right; -} - -div.footer a { - color: #86989B; - text-decoration: underline; -} - -/* -- body styles ----------------------------------------------------------- */ - -p { - margin: 0.8em 0 0.5em 0; -} - -a { - color: #CA7900; - text-decoration: none; -} - -a:hover { - color: #2491CF; -} - -div.body a { - text-decoration: underline; -} - -h1 { - margin: 0; - padding: 0.7em 0 0.3em 0; - font-size: 1.5em; - color: #11557C; -} - -h2 { - margin: 1.3em 0 0.2em 0; - font-size: 1.35em; - padding: 0; -} - -h3 { - margin: 1em 0 -0.3em 0; - font-size: 1.2em; -} - -div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a { - color: black!important; -} - -h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor { - display: none; - margin: 0 0 0 0.3em; - padding: 0 0.2em 0 0.2em; - color: #aaa!important; -} - -h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, -h5:hover a.anchor, h6:hover a.anchor { - display: inline; -} - -h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover, -h5 a.anchor:hover, h6 a.anchor:hover { - color: #777; - background-color: #eee; -} - -a.headerlink { - color: #c60f0f!important; - font-size: 1em; - margin-left: 6px; - padding: 0 4px 0 4px; - text-decoration: none!important; -} - -a.headerlink:hover { - background-color: #ccc; - color: white!important; -} - -cite, code, tt { - font-family: 'Consolas', 'Deja Vu Sans Mono', - 'Bitstream Vera Sans Mono', monospace; - font-size: 0.95em; - letter-spacing: 0.01em; -} - -tt { - background-color: #f2f2f2; - border-bottom: 1px solid #ddd; - color: #333; -} - -tt.descname, tt.descclassname, tt.xref { - border: 0; -} - -hr { - border: 1px solid #abc; - margin: 2em; -} - -a tt { - border: 0; - color: #CA7900; -} - -a tt:hover { - color: #2491CF; -} - -pre { - font-family: 'Consolas', 'Deja Vu Sans Mono', - 'Bitstream Vera Sans Mono', monospace; - font-size: 0.95em; - letter-spacing: 0.015em; - line-height: 120%; - padding: 0.5em; - border: 1px solid #ccc; - background-color: #f8f8f8; -} - -pre a { - color: inherit; - text-decoration: underline; -} - -td.linenos pre { - padding: 0.5em 0; -} - -div.quotebar { - background-color: #f8f8f8; - max-width: 250px; - float: right; - padding: 2px 7px; - border: 1px solid #ccc; -} - -div.topic { - background-color: #f8f8f8; -} - -table { - border-collapse: collapse; - margin: 0 -0.5em 0 -0.5em; -} - -table td, table th { - padding: 0.2em 0.5em 0.2em 0.5em; -} - -div.admonition, div.warning { - font-size: 0.9em; - margin: 1em 0 1em 0; - border: 1px solid #86989B; - background-color: #f7f7f7; - padding: 0; -} - -div.admonition p, div.warning p { - margin: 0.5em 1em 0.5em 1em; - padding: 0; -} - -div.admonition pre, div.warning pre { - margin: 0.4em 1em 0.4em 1em; -} - -div.admonition p.admonition-title, -div.warning p.admonition-title { - margin: 0; - padding: 0.1em 0 0.1em 0.5em; - color: white; - border-bottom: 1px solid #86989B; - font-weight: bold; - background-color: #AFC1C4; -} - -div.warning { - border: 1px solid #940000; -} - -div.warning p.admonition-title { - background-color: #CF0000; - border-bottom-color: #940000; -} - -div.admonition ul, div.admonition ol, -div.warning ul, div.warning ol { - margin: 0.1em 0.5em 0.5em 3em; - padding: 0; -} - -div.versioninfo { - margin: 1em 0 0 0; - border: 1px solid #ccc; - background-color: #DDEAF0; - padding: 8px; - line-height: 1.3em; - font-size: 0.9em; -} - -.viewcode-back { - font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', - 'Verdana', sans-serif; -} - -div.viewcode-block:target { - background-color: #f4debf; - border-top: 1px solid #ac9; - border-bottom: 1px solid #ac9; -} diff -r 54a2dfe63116b5e6e0600d5bd41aba752eaa3ef5 -r 25aa56b376c11b083ccc6d49057b765bc5e4b87a doc/ja/announce/index.txt --- a/doc/ja/announce/index.txt +++ /dev/null @@ -1,24 +0,0 @@ - -.. - Release announcements - =========================================== - -????????? -================== - -.. toctree:: - :maxdepth: 2 - - release-2.2.4 - release-2.2.2 - release-2.2.1 - release-2.2.0 - release-2.1.3 - release-2.1.2 - release-2.1.1 - release-2.1.0 - release-2.0.3 - release-2.0.2 - release-2.0.1 - release-2.0.0 - diff -r 54a2dfe63116b5e6e0600d5bd41aba752eaa3ef5 -r 25aa56b376c11b083ccc6d49057b765bc5e4b87a doc/ja/announce/release-2.0.0.txt --- a/doc/ja/announce/release-2.0.0.txt +++ /dev/null @@ -1,129 +0,0 @@ -py.test 2.0.0: asserts++, unittest++, reporting++, config++, docs++ -=========================================================================== - -Welcome to pytest-2.0.0, a major new release of "py.test", the rapid -easy Python testing tool. There are many new features and enhancements, -see below for summary and detailed lists. A lot of long-deprecated code -has been removed, resulting in a much smaller and cleaner -implementation. See the new docs with examples here: - - http://pytest.org/2.0.0/index.html - -A note on packaging: pytest used to part of the "py" distribution up -until version py-1.3.4 but this has changed now: pytest-2.0.0 only -contains py.test related code and is expected to be backward-compatible -to existing test code. If you want to install pytest, just type one of:: - - pip install -U pytest - easy_install -U pytest - -Many thanks to all issue reporters and people asking questions or -complaining. Particular thanks to Floris Bruynooghe and Ronny Pfannschmidt -for their great coding contributions and many others for feedback and help. - -best, -holger krekel - - -New Features ------------------------ - -- new invocations through Python interpreter and from Python:: - - python -m pytest # on all pythons >= 2.5 - - or from a python program:: - - import pytest ; pytest.main(arglist, pluginlist) - - see http://pytest.org/2.0.0/usage.html for details. - -- new and better reporting information in assert expressions - if comparing lists, sequences or strings. - - see http://pytest.org/2.0.0/assert.html#newreport - -- new configuration through ini-files (setup.cfg or tox.ini recognized), - for example:: - - [pytest] - norecursedirs = .hg data* # don't ever recurse in such dirs - addopts = -x --pyargs # add these command line options by default - - see http://pytest.org/2.0.0/customize.html - -- improved standard unittest support. In general py.test should now - better be able to run custom unittest.TestCases like twisted trial - or Django based TestCases. Also you can now run the tests of an - installed 'unittest' package with py.test:: - - py.test --pyargs unittest - -- new "-q" option which decreases verbosity and prints a more - nose/unittest-style "dot" output. - -- many many more detailed improvements details - -Fixes ------------------------ - -- fix issue126 - introduce py.test.set_trace() to trace execution via - PDB during the running of tests even if capturing is ongoing. -- fix issue124 - make reporting more resilient against tests opening - files on filedescriptor 1 (stdout). -- fix issue109 - sibling conftest.py files will not be loaded. - (and Directory collectors cannot be customized anymore from a Directory's - conftest.py - this needs to happen at least one level up). -- fix issue88 (finding custom test nodes from command line arg) -- fix issue93 stdout/stderr is captured while importing conftest.py -- fix bug: unittest collected functions now also can have "pytestmark" - applied at class/module level - -Important Notes --------------------- - -* The usual way in pre-2.0 times to use py.test in python code was - to import "py" and then e.g. use "py.test.raises" for the helper. - This remains valid and is not planned to be deprecated. However, - in most examples and internal code you'll find "import pytest" - and "pytest.raises" used as the recommended default way. - -* pytest now first performs collection of the complete test suite - before running any test. This changes for example the semantics of when - pytest_collectstart/pytest_collectreport are called. Some plugins may - need upgrading. - -* The pytest package consists of a 400 LOC core.py and about 20 builtin plugins, - summing up to roughly 5000 LOCs, including docstrings. To be fair, it also - uses generic code from the "pylib", and the new "py" package to help - with filesystem and introspection/code manipulation. - -(Incompatible) Removals ------------------------------ - -- py.test.config is now only available if you are in a test run. - -- the following (mostly already deprecated) functionality was removed: - - - removed support for Module/Class/... collection node definitions - in conftest.py files. They will cause nothing special. - - removed support for calling the pre-1.0 collection API of "run()" and "join" - - removed reading option values from conftest.py files or env variables. - This can now be done much much better and easier through the ini-file - mechanism and the "addopts" entry in particular. - - removed the "disabled" attribute in test classes. Use the skipping - and pytestmark mechanism to skip or xfail a test class. - -- py.test.collect.Directory does not exist anymore and it - is not possible to provide an own "Directory" object. - If you have used this and don't know what to do, get - in contact. We'll figure something out. - - Note that pytest_collect_directory() is still called but - any return value will be ignored. This allows to keep - old code working that performed for example "py.test.skip()" - in collect() to prevent recursion into directory trees - if a certain dependency or command line option is missing. - - -see :ref:`changelog` for more detailed changes. diff -r 54a2dfe63116b5e6e0600d5bd41aba752eaa3ef5 -r 25aa56b376c11b083ccc6d49057b765bc5e4b87a doc/ja/announce/release-2.0.1.txt --- a/doc/ja/announce/release-2.0.1.txt +++ /dev/null @@ -1,67 +0,0 @@ -py.test 2.0.1: bug fixes -=========================================================================== - -Welcome to pytest-2.0.1, a maintenance and bug fix release of pytest, -a mature testing tool for Python, supporting CPython 2.4-3.2, Jython -and latest PyPy interpreters. See extensive docs with tested examples here: - - http://pytest.org/ - -If you want to install or upgrade pytest, just type one of:: - - pip install -U pytest # or - easy_install -U pytest - -Many thanks to all issue reporters and people asking questions or -complaining. Particular thanks to Floris Bruynooghe and Ronny Pfannschmidt -for their great coding contributions and many others for feedback and help. - -best, -holger krekel - -Changes between 2.0.0 and 2.0.1 ----------------------------------------------- - -- refine and unify initial capturing so that it works nicely - even if the logging module is used on an early-loaded conftest.py - file or plugin. -- fix issue12 - show plugin versions with "--version" and - "--traceconfig" and also document how to add extra information - to reporting test header -- fix issue17 (import-* reporting issue on python3) by - requiring py>1.4.0 (1.4.1 is going to include it) -- fix issue10 (numpy arrays truth checking) by refining - assertion interpretation in py lib -- fix issue15: make nose compatibility tests compatible - with python3 (now that nose-1.0 supports python3) -- remove somewhat surprising "same-conftest" detection because - it ignores conftest.py when they appear in several subdirs. -- improve assertions ("not in"), thanks Floris Bruynooghe -- improve behaviour/warnings when running on top of "python -OO" - (assertions and docstrings are turned off, leading to potential - false positives) -- introduce a pytest_cmdline_processargs(args) hook - to allow dynamic computation of command line arguments. - This fixes a regression because py.test prior to 2.0 - allowed to set command line options from conftest.py - files which so far pytest-2.0 only allowed from ini-files now. -- fix issue7: assert failures in doctest modules. - unexpected failures in doctests will not generally - show nicer, i.e. within the doctest failing context. -- fix issue9: setup/teardown functions for an xfail-marked - test will report as xfail if they fail but report as normally - passing (not xpassing) if they succeed. This only is true - for "direct" setup/teardown invocations because teardown_class/ - teardown_module cannot closely relate to a single test. -- fix issue14: no logging errors at process exit -- refinements to "collecting" output on non-ttys -- refine internal plugin registration and --traceconfig output -- introduce a mechanism to prevent/unregister plugins from the - command line, see http://pytest.org/plugins.html#cmdunregister -- activate resultlog plugin by default -- fix regression wrt yielded tests which due to the - collection-before-running semantics were not - setup as with pytest 1.3.4. Note, however, that - the recommended and much cleaner way to do test - parametrization remains the "pytest_generate_tests" - mechanism, see the docs. diff -r 54a2dfe63116b5e6e0600d5bd41aba752eaa3ef5 -r 25aa56b376c11b083ccc6d49057b765bc5e4b87a doc/ja/announce/release-2.0.2.txt --- a/doc/ja/announce/release-2.0.2.txt +++ /dev/null @@ -1,73 +0,0 @@ -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, -a mature testing tool for Python, supporting CPython 2.4-3.2, Jython -and latest PyPy interpreters. See the extensive docs with tested examples here: - - http://pytest.org/ - -If you want to install or upgrade pytest, just type one of:: - - pip install -U pytest # or - easy_install -U pytest - -Many thanks to all issue reporters and people asking questions -or complaining, particularly Jurko for his insistence, -Laura, Victor and Brianna for helping with improving -and Ronny for his general advise. - -best, -holger krekel - -Changes between 2.0.1 and 2.0.2 ----------------------------------------------- - -- tackle issue32 - speed up test runs of very quick test functions - by reducing the relative overhead - -- fix issue30 - extended xfail/skipif handling and improved reporting. - If you have a syntax error in your skip/xfail - expressions you now get nice error reports. - - 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 - 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 - (or xfail-ing) tests. - -- fix issue28 - setup_method and pytest_generate_tests work together - The setup_method fixture method now gets called also for - test function invocations generated from the pytest_generate_tests - hook. - -- fix issue27 - collectonly and keyword-selection (-k) now work together - Also, if you do "py.test --collectonly -q" you now get a flat list - of test ids that you can use to paste to the py.test commandline - in order to execute a particular test. - -- fix issue25 avoid reported problems with --pdb and python3.2/encodings output - -- fix issue23 - tmpdir argument now works on Python3.2 and WindowsXP - Starting with Python3.2 os.symlink may be supported. By requiring - a newer py lib version the py.path.local() implementation acknowledges - this. - -- 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 - (thanks Amaury) - -- more precise (avoiding of) deprecation warnings for node.Class|Function accesses - -- avoid std unittest assertion helper code in tracebacks (thanks Ronny) diff -r 54a2dfe63116b5e6e0600d5bd41aba752eaa3ef5 -r 25aa56b376c11b083ccc6d49057b765bc5e4b87a doc/ja/announce/release-2.0.3.txt --- a/doc/ja/announce/release-2.0.3.txt +++ /dev/null @@ -1,40 +0,0 @@ -py.test 2.0.3: bug fixes and speed ups -=========================================================================== - -Welcome to pytest-2.0.3, a maintenance and bug fix release of pytest, -a mature testing tool for Python, supporting CPython 2.4-3.2, Jython -and latest PyPy interpreters. See the extensive docs with tested examples here: - - http://pytest.org/ - -If you want to install or upgrade pytest, just type one of:: - - pip install -U pytest # or - easy_install -U pytest - -There also is a bugfix release 1.6 of pytest-xdist, the plugin -that enables seemless distributed and "looponfail" testing for Python. - -best, -holger krekel - -Changes between 2.0.2 and 2.0.3 ----------------------------------------------- - -- fix issue38: nicer tracebacks on calls to hooks, particularly early - configure/sessionstart ones - -- fix missing skip reason/meta information in junitxml files, reported - via http://lists.idyll.org/pipermail/testing-in-python/2011-March/003928.html - -- fix issue34: avoid collection failure with "test" prefixed classes - deriving from object. - -- don't require zlib (and other libs) for genscript plugin without - --genscript actually being used. - -- speed up skips (by not doing a full traceback represenation - internally) - -- fix issue37: avoid invalid characters in junitxml's output - diff -r 54a2dfe63116b5e6e0600d5bd41aba752eaa3ef5 -r 25aa56b376c11b083ccc6d49057b765bc5e4b87a doc/ja/announce/release-2.1.0.txt --- a/doc/ja/announce/release-2.1.0.txt +++ /dev/null @@ -1,47 +0,0 @@ -py.test 2.1.0: perfected assertions and bug fixes -=========================================================================== - -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: - - http://pytest.org/ - -The single biggest news about this release are **perfected assertions** -courtesy of Benjamin Peterson. You can now safely use ``assert`` -statements in test modules without having to worry about side effects -or python optimization ("-OO") options. This is achieved by rewriting -assert statements in test modules upon import, using a PEP302 hook. -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:: - - pip install -U pytest # or - easy_install -U pytest - -best, -holger krekel / http://merlinux.eu - -Changes between 2.0.3 and 2.1.0 ----------------------------------------------- - -- fix issue53 call nosestyle setup functions with correct ordering -- fix issue58 and issue59: new assertion code fixes -- merge Benjamin's assertionrewrite branch: now assertions - for test modules on python 2.6 and above are done by rewriting - the AST and saving the pyc file before the test module is imported. - see doc/assert.txt for more info. -- fix issue43: improve doctests with better traceback reporting on - 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 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 54a2dfe63116b5e6e0600d5bd41aba752eaa3ef5 -r 25aa56b376c11b083ccc6d49057b765bc5e4b87a doc/ja/announce/release-2.1.1.txt --- a/doc/ja/announce/release-2.1.1.txt +++ /dev/null @@ -1,37 +0,0 @@ -py.test 2.1.1: assertion fixes and improved junitxml output -=========================================================================== - -pytest-2.1.1 is a backward compatible maintenance release of the -popular py.test testing tool. See extensive docs with examples here: - - http://pytest.org/ - -Most bug fixes address remaining issues with the perfected assertions -introduced with 2.1.0 - many thanks to the bug reporters and to Benjamin -Peterson for helping to fix them. Also, junitxml output now produces -system-out/err tags which lead to better displays of tracebacks with Jenkins. - -Also a quick note to package maintainers and others interested: there now -is a "pytest" man page which can be generated with "make man" in doc/. - -If you want to install or upgrade pytest, just type one of:: - - pip install -U pytest # or - easy_install -U pytest - -best, -holger krekel / http://merlinux.eu - -Changes between 2.1.0 and 2.1.1 ----------------------------------------------- - -- fix issue64 / pytest.set_trace now works within pytest_generate_tests hooks -- fix issue60 / fix error conditions involving the creation of __pycache__ -- fix issue63 / assertion rewriting on inserts involving strings containing '%' -- fix assertion rewriting on calls with a ** arg -- don't cache rewritten modules if bytecode generation is disabled -- fix assertion rewriting in read-only directories -- fix issue59: provide system-out/err tags for junitxml output -- fix issue61: assertion rewriting on boolean operations with 3 or more operands -- you can now build a man page with "cd doc ; make man" - diff -r 54a2dfe63116b5e6e0600d5bd41aba752eaa3ef5 -r 25aa56b376c11b083ccc6d49057b765bc5e4b87a doc/ja/announce/release-2.1.2.txt --- a/doc/ja/announce/release-2.1.2.txt +++ /dev/null @@ -1,33 +0,0 @@ -py.test 2.1.2: bug fixes and fixes for jython -=========================================================================== - -pytest-2.1.2 is a minor backward compatible maintenance release of the -popular py.test testing tool. pytest is commonly used for unit, -functional- and integration testing. See extensive docs with examples -here: - - http://pytest.org/ - -Most bug fixes address remaining issues with the perfected assertions -introduced in the 2.1 series - many thanks to the bug reporters and to Benjamin -Peterson for helping to fix them. pytest should also work better with -Jython-2.5.1 (and Jython trunk). - -If you want to install or upgrade pytest, just type one of:: - - pip install -U pytest # or - easy_install -U pytest - -best, -holger krekel / http://merlinux.eu - -Changes between 2.1.1 and 2.1.2 ----------------------------------------- - -- fix assertion rewriting on files with windows newlines on some Python versions -- refine test discovery by package/module name (--pyargs), thanks Florian Mayer -- fix issue69 / assertion rewriting fixed on some boolean operations -- fix issue68 / packages now work with assertion rewriting -- fix issue66: use different assertion rewriting caches when the -O option is passed -- don't try assertion rewriting on Jython, use reinterp - diff -r 54a2dfe63116b5e6e0600d5bd41aba752eaa3ef5 -r 25aa56b376c11b083ccc6d49057b765bc5e4b87a doc/ja/announce/release-2.1.3.txt --- a/doc/ja/announce/release-2.1.3.txt +++ /dev/null @@ -1,32 +0,0 @@ -py.test 2.1.3: just some more fixes -=========================================================================== - -pytest-2.1.3 is a minor backward compatible maintenance release of the -popular py.test testing tool. It is commonly used for unit, functional- -and integration testing. See extensive docs with examples here: - - http://pytest.org/ - -The release contains another fix to the perfected assertions introduced -with the 2.1 series as well as the new possibility to customize reporting -for assertion expressions on a per-directory level. - -If you want to install or upgrade pytest, just type one of:: - - pip install -U pytest # or - easy_install -U pytest - -Thanks to the bug reporters and to Ronny Pfannschmidt, Benjamin Peterson -and Floris Bruynooghe who implemented the fixes. - -best, -holger krekel - -Changes between 2.1.2 and 2.1.3 ----------------------------------------- - -- fix issue79: assertion rewriting failed on some comparisons in boolops, -- correctly handle zero length arguments (a la pytest '') -- fix issue67 / junitxml now contains correct test durations -- fix issue75 / skipping test failure on jython -- fix issue77 / Allow assertrepr_compare hook to apply to a subset of tests diff -r 54a2dfe63116b5e6e0600d5bd41aba752eaa3ef5 -r 25aa56b376c11b083ccc6d49057b765bc5e4b87a doc/ja/announce/release-2.2.0.txt --- a/doc/ja/announce/release-2.2.0.txt +++ /dev/null @@ -1,95 +0,0 @@ -py.test 2.2.0: test marking++, parametrization++ and duration profiling -=========================================================================== - -pytest-2.2.0 is a test-suite compatible release of the popular -py.test testing tool. Plugins might need upgrades. It comes -with these improvements: - -* easier and more powerful parametrization of tests: - - - new @pytest.mark.parametrize decorator to run tests with different arguments - - new metafunc.parametrize() API for parametrizing arguments independently - - see examples at http://pytest.org/latest/example/parametrize.html - - NOTE that parametrize() related APIs are still a bit experimental - and might change in future releases. - -* improved handling of test markers and refined marking mechanism: - - - "-m markexpr" option for selecting tests according to their mark - - a new "markers" ini-variable for registering test markers for your project - - 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 - 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 - resulting in better and more accurate reporting when they fail - -Besides there is the usual set of bug fixes along with a cleanup of -pytest's own test suite allowing it to run on a wider range of environments. - -For general information, see extensive docs with examples here: - - http://pytest.org/ - -If you want to install or upgrade pytest you might just type:: - - pip install -U pytest # or - easy_install -U pytest - -Thanks to Ronny Pfannschmidt, David Burns, Jeff Donner, Daniel Nouri, Alfredo Deza and all who gave feedback or sent bug reports. - -best, -holger krekel - - -notes on incompatibility ------------------------------- - -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. - -* 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 - 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. - - -Changes between 2.1.3 and 2.2.0 ----------------------------------------- - -- 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 - parametrize test function arguments in multiple steps and therefore - 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 - 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 - will treat unregistered markers as errors - allowing to avoid typos and maintain a well described set of markers - 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" - 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 - 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 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 54a2dfe63116b5e6e0600d5bd41aba752eaa3ef5 -r 25aa56b376c11b083ccc6d49057b765bc5e4b87a doc/ja/announce/release-2.2.1.txt --- a/doc/ja/announce/release-2.2.1.txt +++ /dev/null @@ -1,41 +0,0 @@ -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. 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/ - -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 54a2dfe63116b5e6e0600d5bd41aba752eaa3ef5 -r 25aa56b376c11b083ccc6d49057b765bc5e4b87a doc/ja/announce/release-2.2.2.txt --- a/doc/ja/announce/release-2.2.2.txt +++ /dev/null @@ -1,43 +0,0 @@ -pytest-2.2.2: bug fixes -=========================================================================== - -pytest-2.2.2 (updated to 2.2.3 to fix packaging issues) is a minor -backward-compatible release of the versatile py.test testing tool. It -contains bug fixes and a few refinements particularly to reporting with -"--collectonly", see below for betails. - -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 -and Ralf Schmitt and the contributors of issues. - -best, -holger krekel - - -Changes between 2.2.1 and 2.2.2 ----------------------------------------- - -- 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 -- fix issue106: allow parametrize to be applied multiple times - e.g. from module, class and at function level. -- fix issue107: actually perform session scope finalization -- don't check in parametrize if indirect parameters are funcarg names -- add chdir method to monkeypatch funcarg -- fix crash resulting from calling monkeypatch undo a second time -- fix issue115: make --collectonly robust against early failure - (missing files/directories) -- "-qq --collectonly" now shows only files and the number of tests in them -- "-q --collectonly" now shows test ids -- allow adding of attributes to test reports such that it also works - with distributed testing (no upgrade of pytest-xdist needed) diff -r 54a2dfe63116b5e6e0600d5bd41aba752eaa3ef5 -r 25aa56b376c11b083ccc6d49057b765bc5e4b87a doc/ja/announce/release-2.2.4.txt --- a/doc/ja/announce/release-2.2.4.txt +++ /dev/null @@ -1,39 +0,0 @@ -pytest-2.2.4: bug fixes, better junitxml/unittest/python3 compat -=========================================================================== - -pytest-2.2.4 is a minor backward-compatible release of the versatile -py.test testing tool. It contains bug fixes and a few refinements -to junitxml reporting, better unittest- and python3 compatibility. - -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 -and Benjamin Peterson and the contributors of issues. - -best, -holger krekel - -Changes between 2.2.3 and 2.2.4 ------------------------------------ - -- fix error message for rewritten assertions involving the % operator -- fix issue 126: correctly match all invalid xml characters for junitxml - binary escape -- fix issue with unittest: now @unittest.expectedFailure markers should - be processed correctly (you can also use @pytest.mark markers) -- document integration with the extended distribute/setuptools test commands -- fix issue 140: propperly get the real functions - of bound classmethods for setup/teardown_class -- fix issue #141: switch from the deceased paste.pocoo.org to bpaste.net -- fix issue #143: call unconfigure/sessionfinish always when - configure/sessionstart where called -- fix issue #144: better mangle test ids to junitxml classnames -- upgrade distribute_setup.py to 0.6.27 - diff -r 54a2dfe63116b5e6e0600d5bd41aba752eaa3ef5 -r 25aa56b376c11b083ccc6d49057b765bc5e4b87a doc/ja/apiref.txt --- a/doc/ja/apiref.txt +++ /dev/null @@ -1,29 +0,0 @@ - -.. _apiref: - -py.test ???????????? -================================ - -.. - py.test reference documentation - ================================================ - -.. toctree:: - :maxdepth: 2 - - builtin.txt - customize.txt - assert.txt - funcargs.txt - xunit_setup.txt - capture.txt - monkeypatch.txt - xdist.txt - tmpdir.txt - skipping.txt - mark.txt - recwarn.txt - unittest.txt - nose.txt - doctest.txt - diff -r 54a2dfe63116b5e6e0600d5bd41aba752eaa3ef5 -r 25aa56b376c11b083ccc6d49057b765bc5e4b87a doc/ja/assert.txt --- a/doc/ja/assert.txt +++ /dev/null @@ -1,362 +0,0 @@ - -.. - The writing and reporting of assertions in tests - ================================================== - -??????????????????????? -============================================== - -.. _`assert with the assert statement`: - -``assert`` ?????????? -------------------------------- - -.. - Asserting with the ``assert`` statement - --------------------------------------------------------- - -.. - ``py.test`` allows you to use the standard python ``assert`` for verifying - expectations and values in Python tests. For example, you can write the - following:: - -``py.test`` ????????????????????? Python ??? ``assert`` ?????????????????????????:: - - # test_assert1.py ??? - def f(): - return 3 - - def test_function(): - assert f() == 4 - -.. - to assert that your function returns a certain value. If this assertion fails - you will see the return value of the function call:: - -?????????????????????????????????????????????????????????????:: - - $ py.test test_assert1.py - =========================== test session starts ============================ - platform linux2 -- Python 2.7.1 -- pytest-2.2.4 - collecting ... collected 1 items - - test_assert1.py F - - ================================= FAILURES ================================= - ______________________________ test_function _______________________________ - - def test_function(): - > assert f() == 4 - E assert 3 == 4 - E + where 3 = f() - - test_assert1.py:5: AssertionError - ========================= 1 failed in 0.01 seconds ========================= - -.. - py.test has support for showing the values of the most common subexpressions - including calls, attributes, comparisons, and binary and unary - operators. (See :ref:`tbreportdemo`). This allows you to use the - idiomatic python constructs without boilerplate code while not losing - introspection information. - -py.test ?????????????????????????????????????????????????????? (:ref:`tbreportdemo` ???) ???????????????????????Python ????????????????????????????????????????????? - -.. - However, if you specify a message with the assertion like this:: - -??????????????????????????????:: - - assert a % 2 == 0, "value was odd, should be even" - -.. - then no assertion introspection takes places at all and the message - will be simply shown in the traceback. - -???????????????????????????????????????????????? - -.. - See :ref:`assert-details` for more information on assertion introspection. - -?????????????????????? :ref:`assert-details` ?????????? - -.. - Assertions about expected exceptions - ------------------------------------------ - -??????????????? ------------------------------- - -.. - In order to write assertions about raised exceptions, you can use - ``pytest.raises`` as a context manager like this:: - -?????????????????????????????? ????????? ``pytest.raises`` ?????:: - - import pytest - with pytest.raises(ZeroDivisionError): - 1 / 0 - -.. - and if you need to have access to the actual exception info you may use:: - -???????????????????????????????:: - - with pytest.raises(RuntimeError) as excinfo: - def f(): - f() - f() - - # excinfo.type, excinfo.value, excinfo.traceback ?????????????? - -.. - 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:: - -Python 2.4 ?????????????????????????????????????????????2?????:: - - pytest.raises(ExpectedException, func, *args, **kwargs) - pytest.raises(ExpectedException, "func(*args, **kwargs)") - -.. - both of which execute the specified function with args and kwargs and - asserts that the given ``ExpectedException`` is raised. The reporter will - provide you with helpful output in case of failures such as *no - exception* or *wrong exception*. - -??????????? args ? kwargs ???????????????? ``ExpectedException`` ??????????????????????? *no exception* ??? *wrong exception* ?????????????????????????????? - -.. _newreport: - -???????????????? --------------------------------- - -.. - Making use of context-sensitive comparisons - ------------------------------------------------- - -.. versionadded:: 2.0 - -.. - py.test has rich support for providing context-sensitive information - when it encounters comparisons. For example:: - -py.test ?????????????????????????????????????:: - - # test_assert2.py ??? - - def test_set_comparison(): - set1 = set("1308") - set2 = set("8035") - assert set1 == set2 - -.. - if you run this module:: - -?????????????:: - - $ py.test test_assert2.py - =========================== test session starts ============================ - platform linux2 -- Python 2.7.1 -- pytest-2.2.4 - collecting ... collected 1 items - - test_assert2.py F - - ================================= FAILURES ================================= - ___________________________ test_set_comparison ____________________________ - - def test_set_comparison(): - set1 = set("1308") - set2 = set("8035") - > assert set1 == set2 - E assert set(['0', '1', '3', '8']) == set(['0', '3', '5', '8']) - E Extra items in the left set: - E '1' - E Extra items in the right set: - E '5' - - test_assert2.py:5: AssertionError - ========================= 1 failed in 0.01 seconds ========================= - -.. - Special comparisons are done for a number of cases: - -??????????????????????: - -.. - * comparing long strings: a context diff is shown - * comparing long sequences: first failing indices - * comparing dicts: different entries - -* ????????: ?????? diff ??? -* ??????????: ????????????? -* ??????????: ??????? - -.. - See the :ref:`reporting demo ` for many more examples. - -?????????????? :ref:`??????? ` ????????? - -.. - Defining your own assertion comparison - ---------------------------------------------- - -??????????? ----------------------- - -.. - It is possible to add your own detailed explanations by implementing - the ``pytest_assertrepr_compare`` hook. - -``pytest_assertrepr_compare`` ?????????????????????????? - -.. autofunction:: _pytest.hookspec.pytest_assertrepr_compare - -.. - As an example consider adding the following hook in a conftest.py which - provides an alternative explanation for ``Foo`` objects:: - -?????conftest.py ?????????????????? ``Foo`` ?????????????????:: - - # conftest.py ??? - from test_foocompare import Foo - def pytest_assertrepr_compare(op, left, right): - if isinstance(left, Foo) and isinstance(right, Foo) and op == "==": - return ['Comparing Foo instances:', - ' vals: %s != %s' % (left.val, right.val)] - -.. - now, given this test module:: - -??????????????????:: - - # test_foocompare.py ??? - class Foo: - def __init__(self, val): - self.val = val - - def test_compare(): - f1 = Foo(1) - f2 = Foo(2) - assert f1 == f2 - -.. - you can run the test module and get the custom output defined in - the conftest file:: - -?????????????????conftest ???????????????????????:: - - $ py.test -q test_foocompare.py - collecting ... collected 1 items - F - ================================= FAILURES ================================= - _______________________________ test_compare _______________________________ - - def test_compare(): - f1 = Foo(1) - f2 = Foo(2) - > assert f1 == f2 - E assert Comparing Foo instances: - E vals: 1 != 2 - - test_foocompare.py:8: AssertionError - 1 failed in 0.01 seconds - -.. _assert-details: -.. _`assert introspection`: - -????????????????? ----------------------------------- - -.. - Advanced assertion introspection - ---------------------------------- - -.. versionadded:: 2.1 - -.. - Reporting details about a failing assertion is achieved either by rewriting - assert statements before they are run or re-evaluating the assert expression and - recording the intermediate values. Which technique is used depends on the - location of the assert, py.test's configuration, and Python version being used - to run py.test. Note that for assert statements with a manually provided - message, i.e. ``assert expr, message``, no assertion introspection takes place - and the manually provided message will be rendered in tracebacks. - -??????????????????????????? assert ???????????? assert ?????????????????????????????????????????? assert ????pytest ????pytest ??????????? Python ???????????? ``assert expr, message`` ????????????????????? assert ?????????????????????????????????????????????????????????? - -.. - By default, if the Python version is greater than or equal to 2.6, py.test - rewrites assert statements in test modules. Rewritten assert statements put - introspection information into the assertion failure message. py.test only - rewrites test modules directly discovered by its test collection process, so - asserts in supporting modules which are not themselves test modules will not be - rewritten. - -????????Python ?????? 2.6 ??????py.test ?????????? assert ???????????????? assert ?????????????????????????????????????py.test ????????????????????????????????????????????????????????????????? assert ???????????? - -.. note:: - - .. - py.test rewrites test modules on import. It does this by using an import hook - to write a new pyc files. Most of the time this works transparently. However, - if you are messing with import yourself, the import hook may interfere. If - this is the case, simply use ``--assert=reinterp`` or - ``--assert=plain``. Additionally, rewriting will fail silently if it cannot - write new pycs, i.e. in a read-only filesystem or a zipfile. - - py.test ???????????????????????????? pyc ?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ``--assert=reinterp`` ? ``--assert=plain`` ???????????????? pyc ????????????????????????????????????????????????????? zip ??????????????? - -.. - If an assert statement has not been rewritten or the Python version is less than - 2.6, py.test falls back on assert reinterpretation. In assert reinterpretation, - py.test walks the frame of the function containing the assert statement to - discover sub-expression results of the failing assert statement. You can force - py.test to always use assertion reinterpretation by passing the - ``--assert=reinterp`` option. - -assert ?????????????? Python ????? 2.6 ?????????py.test ??????????????????????????????py.test ??assert ????????????????? assert ?????????????????py.test ?????????????????????? ``--assert=reinterp`` ???????????? - -.. - Assert reinterpretation has a caveat not present with assert rewriting: If - evaluating the assert expression has side effects you may get a warning that the - intermediate values could not be determined safely. A common example of this - issue is an assertion which reads from a file:: - -????????????assert ?????????????????????: ??? assert ??????????????????????????????????????????????????????????????????????????????:: - - assert f.read() != '...' - -.. - If this assertion fails then the re-evaluation will probably succeed! - This is because ``f.read()`` will return an empty string when it is - called the second time during the re-evaluation. However, it is - easy to rewrite the assertion and avoid any trouble:: - -??????????????????????????????????????????2???????????? ``f.read()`` ?????????????????????????????????????????????????????:: - - content = f.read() - assert content != '...' - -.. - All assert introspection can be turned off by passing ``--assert=plain``. - -????????????????????????? ``--assert=plain`` ??????? - -.. - For further information, Benjamin Peterson wrote up `Behind the scenes of py.test's new assertion rewriting `_. - -????????Benjamin Peterson ???????? `Behind the scenes of py.test's new assertion rewriting `_ ?????????? - -.. - Add assert rewriting as an alternate introspection technique. - -.. versionadded:: 2.1 - ????????????????? assert ????????? - -.. - Introduce the ``--assert`` option. Deprecate ``--no-assert`` and - ``--nomagic``. - -.. versionchanged:: 2.1 - ``--assert`` ????????? ``--no-assert`` ? ``--nomagic`` ???? diff -r 54a2dfe63116b5e6e0600d5bd41aba752eaa3ef5 -r 25aa56b376c11b083ccc6d49057b765bc5e4b87a doc/ja/builtin.txt --- a/doc/ja/builtin.txt +++ /dev/null @@ -1,152 +0,0 @@ - -.. _`pytest helpers`: - -Pytest ?????????? -=========================== - -.. - Pytest builtin helpers - ================================================ - -.. - builtin pytest.* functions and helping objects - ----------------------------------------------------- - -????? pytest.* ????????????? ----------------------------------------------- - -.. - You can always use an interactive Python prompt and type:: - -Python ??????????????????????????:: - - import pytest - help(pytest) - -.. - to get an overview on the globally available helpers. - -???????????????????????????? - -.. automodule:: pytest - :members: - - -.. _builtinfuncargs: - -????????? ------------------- - -.. - Builtin function arguments - ----------------------------------------------------- - -.. - You can ask for available builtin or project-custom - :ref:`function arguments ` by typing:: - -????????????????????????????????? :ref:`????? ` ???????? - - | $ py.test --fixtures - | ====================== test session starts ======================= - | platform linux2 -- Python 2.7.1 -- pytest-2.2.4 - | collected 0 items - | pytestconfig - | pytest ? config ????????????????????????? - | - | capsys - | sys.stdout/sys.stderr ?????????????? - | ???????????? ``(out, err)`` ??????? - | ``capsys.readouterr()`` ?????????? - | - | capfd - | ??????????? 1 ? 2 ????????????? - | ???????????? ``(out, err)`` ??????? - | ``capsys.readouterr()`` ?????????? - | - | tmpdir - | ?????????????????????????????? - | ??????????????????????????????? - | ??? py.path.local ?????????????? - | - | monkeypatch - | ???????????????os.environ ????? - | ??????????????? ``monkeypatch`` ??????????? - | - | monkeypatch.setattr(obj, name, value, raising=True) - | monkeypatch.delattr(obj, name, raising=True) - | monkeypatch.setitem(mapping, name, value) - | monkeypatch.delitem(obj, name, raising=True) - | monkeypatch.setenv(name, value, prepend=False) - | monkeypatch.delenv(name, value, raising=True) - | monkeypatch.syspath_prepend(path) - | monkeypatch.chdir(path) - | - | ????????????????????????????? - | ``raising`` ????????????????????????? - | KeyError ? AttributeError ??????????????? - | - | recwarn - | ??????????? WarningsRecorder ????????? - | - | * ``pop(category=None)``: category ????????????? - | * ``clear()``: ??????????? - | - | ??????? http://docs.python.org/library/warnings.html ? - | ???????? - | - | ======================== in 0.00 seconds ======================== - -.. - $ py.test --fixtures - =========================== test session starts ============================ - platform linux2 -- Python 2.7.1 -- pytest-2.2.4 - collected 0 items - pytestconfig - the pytest config object with access to command line opts. - capsys - enables capturing of writes to sys.stdout/sys.stderr and makes - captured output available via ``capsys.readouterr()`` method calls - which return a ``(out, err)`` tuple. - - capfd - enables capturing of writes to file descriptors 1 and 2 and makes - captured output available via ``capsys.readouterr()`` method calls - which return a ``(out, err)`` tuple. - - tmpdir - return a temporary directory path object - which is unique to each test function invocation, - created as a sub directory of the base temporary - directory. The returned object is a `py.path.local`_ - path object. - - monkeypatch - The returned ``monkeypatch`` funcarg provides these - helper methods to modify objects, dictionaries or os.environ:: - - monkeypatch.setattr(obj, name, value, raising=True) - monkeypatch.delattr(obj, name, raising=True) - monkeypatch.setitem(mapping, name, value) - monkeypatch.delitem(obj, name, raising=True) - monkeypatch.setenv(name, value, prepend=False) - monkeypatch.delenv(name, value, raising=True) - monkeypatch.syspath_prepend(path) - monkeypatch.chdir(path) - - All modifications will be undone after the requesting - test function has finished. The ``raising`` - parameter determines if a KeyError or AttributeError - will be raised if the set/deletion operation has no target. - - recwarn - Return a WarningsRecorder instance that provides these methods: - - * ``pop(category=None)``: return last warning matching the category. - * ``clear()``: clear list of warnings - - See http://docs.python.org/library/warnings.html for information - on warning categories. - - - ============================= in 0.00 seconds ============================= This diff is so big that we needed to truncate the remainder. 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 issues-reply at bitbucket.org Mon Sep 29 14:59:40 2014 From: issues-reply at bitbucket.org (Dinu Gherman) Date: Mon, 29 Sep 2014 12:59:40 -0000 Subject: [Pytest-commit] Issue #194: Mailinglist available? (hpk42/tox) Message-ID: <20140929125940.32141.76417@app01.ash-private.bitbucket.org> New issue 194: Mailinglist available? https://bitbucket.org/hpk42/tox/issue/194/mailinglist-available Dinu Gherman: I wonder if there is a mailing list available for tox and friends? If so, I haven't found it, yet. In any case I might have some questions which I don't want to raise necessarily as issues here in BitBucket, especially since others might be able to respond more easily on a list. So, if there is no mailing list yet, it might be an idea to create one. From builds at drone.io Mon Sep 29 20:32:36 2014 From: builds at drone.io (Drone.io Build) Date: Mon, 29 Sep 2014 18:32:36 +0000 Subject: [Pytest-commit] [SUCCESS] pytest - # 335 Message-ID: <20140929104011.1235.77927@drone.io> Build was Successful Build : https://drone.io/bitbucket.org/hpk42/pytest/335 Project : https://drone.io/bitbucket.org/hpk42/pytest Repository : https://bitbucket.org/hpk42/pytest Version : 3800:25aa56b376c1 Author : holger krekel Branch : default Message: removed outdated japanese docs from source tree. -------------- next part -------------- An HTML attachment was scrubbed... URL: From issues-reply at bitbucket.org Tue Sep 30 09:10:31 2014 From: issues-reply at bitbucket.org (Andreas Pelme) Date: Tue, 30 Sep 2014 07:10:31 -0000 Subject: [Pytest-commit] Issue #602: xdist does not report warnings (hpk42/pytest) Message-ID: <20140930071031.7055.54226@app06.ash-private.bitbucket.org> New issue 602: xdist does not report warnings https://bitbucket.org/hpk42/pytest/issue/602/xdist-does-not-report-warnings Andreas Pelme: Warnings raised with `request.node.warn` does not show warnings. `-rw` does not give any warning output either. Here is the same test run without and with xdist: ``` $ py.test unit_tests/ .............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................. ............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................. ........................................................................................................................................................................................... 2166 passed, 78 warnings in 46.73 seconds ``` ``` $ py.test unit_tests/ -n1 gw0 [2166] scheduling tests via LoadScheduling .............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................. ............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................. ........................................................................................................................................................................................... 2166 passed in 48.02 seconds ``` From issues-reply at bitbucket.org Tue Sep 30 17:16:01 2014 From: issues-reply at bitbucket.org (Marco Chomut) Date: Tue, 30 Sep 2014 15:16:01 -0000 Subject: [Pytest-commit] Issue #603: monkeypatch does not work on already-imported function (hpk42/pytest) Message-ID: <20140930151601.11271.6560@app11.ash-private.bitbucket.org> New issue 603: monkeypatch does not work on already-imported function https://bitbucket.org/hpk42/pytest/issue/603/monkeypatch-does-not-work-on-already Marco Chomut: Given the following tests file: ``` #!python from project.main import foo def test_foo(monkeypatch): monkeypatch.setattr('project.bar.zoo', lambda x: 0) assert foo() == 0 ``` And this system under test: ``` #!python # project/main.py from project.bar import zoo def foo(): return zoo('lion') ``` ``` #!python # project/bar.py def zoo(animal): if animal == 'lion': return 7 ``` Then the ``zoo`` that's already been imported in ``main.py`` remains unpatched. Moving the imports around to be local to the test function would fix the problem, unless ``main.py`` is imported by other files at any point during the test suite running. Alternatively, if ``main.py`` instead does ``import project.bar`` and calls its dependency with ``project.bar.zoo('lion')``, then the test passes again. But this is cumbersome and difficult to enforce across an entire project. From bubenkoff at gmail.com Tue Sep 30 17:18:22 2014 From: bubenkoff at gmail.com (Anatoly Bubenkov) Date: Tue, 30 Sep 2014 17:18:22 +0200 Subject: [Pytest-commit] Issue #603: monkeypatch does not work on already-imported function (hpk42/pytest) In-Reply-To: <20140930151601.11271.6560@app11.ash-private.bitbucket.org> References: <20140930151601.11271.6560@app11.ash-private.bitbucket.org> Message-ID: monkeypatch receives the object, not the dotted name of the object to mock so: ``` #!python from project import bar def test_foo(monkeypatch): monkeypatch.setattr(bar, 'zoo', lambda x: 0) assert foo() == 0 ``` On 30 September 2014 17:16, Marco Chomut wrote: > New issue 603: monkeypatch does not work on already-imported function > > https://bitbucket.org/hpk42/pytest/issue/603/monkeypatch-does-not-work-on-already > > Marco Chomut: > > Given the following tests file: > > ``` > #!python > > from project.main import foo > > def test_foo(monkeypatch): > monkeypatch.setattr('project.bar.zoo', lambda x: 0) > assert foo() == 0 > > ``` > > And this system under test: > > ``` > #!python > > # project/main.py > > from project.bar import zoo > > def foo(): > return zoo('lion') > > ``` > > ``` > #!python > > # project/bar.py > > def zoo(animal): > if animal == 'lion': > return 7 > > ``` > > Then the ``zoo`` that's already been imported in ``main.py`` remains > unpatched. Moving the imports around to be local to the test function would > fix the problem, unless ``main.py`` is imported by other files at any point > during the test suite running. Alternatively, if ``main.py`` instead does > ``import project.bar`` and calls its dependency with > ``project.bar.zoo('lion')``, then the test passes again. But this is > cumbersome and difficult to enforce across an entire project. > > > _______________________________________________ > pytest-commit mailing list > pytest-commit at python.org > https://mail.python.org/mailman/listinfo/pytest-commit > -- Anatoly Bubenkov -------------- next part -------------- An HTML attachment was scrubbed... URL: