From commits-noreply at bitbucket.org Tue Oct 1 12:39:25 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 01 Oct 2013 10:39:25 -0000 Subject: [Pytest-commit] commit/pytest: 3 new changesets Message-ID: <20131001103925.11706.34556@app04.ash-private.bitbucket.org> 3 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/af860de70cc3/ Changeset: af860de70cc3 User: hpk42 Date: 2013-10-01 10:43:36 Summary: bump version to 2.4.0 Affected #: 3 files diff -r b2058c24af7a3cc8d64d037abc7622cac4c5d446 -r af860de70cc3f157ac34ca1d4bf557a057bff775 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -Changes between 2.3.5 and 2.4.DEV +Changes between 2.3.5 and 2.4 ----------------------------------- known incompatibilities: diff -r b2058c24af7a3cc8d64d037abc7622cac4c5d446 -r af860de70cc3f157ac34ca1d4bf557a057bff775 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.4.0.dev14' +__version__ = '2.4.0' diff -r b2058c24af7a3cc8d64d037abc7622cac4c5d446 -r af860de70cc3f157ac34ca1d4bf557a057bff775 setup.py --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ long_description = open("README.rst").read() def main(): - install_requires = ["py>=1.4.15"] + install_requires = ["py>=1.4.16"] if sys.version_info < (2,7): install_requires.append("argparse") @@ -11,7 +11,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.4.0.dev14', + version='2.4.0', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], https://bitbucket.org/hpk42/pytest/commits/49b10f86e351/ Changeset: 49b10f86e351 User: hpk42 Date: 2013-10-01 10:43:40 Summary: Added tag 2.4.0 for changeset af860de70cc3 Affected #: 1 file diff -r af860de70cc3f157ac34ca1d4bf557a057bff775 -r 49b10f86e35114a851957723058328e2f45e2657 .hgtags --- a/.hgtags +++ b/.hgtags @@ -60,3 +60,4 @@ 0000000000000000000000000000000000000000 1.4.14 0000000000000000000000000000000000000000 1.4.14 0000000000000000000000000000000000000000 1.4.14 +af860de70cc3f157ac34ca1d4bf557a057bff775 2.4.0 https://bitbucket.org/hpk42/pytest/commits/4a3891297f91/ Changeset: 4a3891297f91 User: hpk42 Date: 2013-10-01 12:37:11 Summary: release announcement, bump version numbers, some test adapatations because of random win32 test failures. Affected #: 9 files diff -r 49b10f86e35114a851957723058328e2f45e2657 -r 4a3891297f9131f1e4944bfc68bb23d1a29c75cf _pytest/pytester.py --- a/_pytest/pytester.py +++ b/_pytest/pytester.py @@ -661,6 +661,12 @@ else: raise ValueError("line %r not found in output" % line) + def get_lines_after(self, fnline): + for i, line in enumerate(self.lines): + if fnline == line or fnmatch(line, fnline): + return self.lines[i+1:] + raise ValueError("line %r not found in output" % fnline) + def fnmatch_lines(self, lines2): def show(arg1, arg2): py.builtin.print_(arg1, arg2, file=py.std.sys.stderr) diff -r 49b10f86e35114a851957723058328e2f45e2657 -r 4a3891297f9131f1e4944bfc68bb23d1a29c75cf doc/en/Makefile --- a/doc/en/Makefile +++ b/doc/en/Makefile @@ -12,7 +12,7 @@ PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -SITETARGET=dev +SITETARGET=latest .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest diff -r 49b10f86e35114a851957723058328e2f45e2657 -r 4a3891297f9131f1e4944bfc68bb23d1a29c75cf 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.4.0 release-2.3.5 release-2.3.4 release-2.3.3 diff -r 49b10f86e35114a851957723058328e2f45e2657 -r 4a3891297f9131f1e4944bfc68bb23d1a29c75cf doc/en/announce/release-2.4.0.txt --- /dev/null +++ b/doc/en/announce/release-2.4.0.txt @@ -0,0 +1,225 @@ +pytest-2.4.0: new fixture features/hooks and bug fixes +=========================================================================== + +The just released pytest-2.4.0 brings many improvements and numerous +bug fixes while remaining plugin- and test-suite compatible apart +from a few supposedly very minor incompatibilities. See below for +a full list of details. A few feature highlights: + +- new yield-style fixtures `pytest.yield_fixture + `_, allowing to use + existing with-style context managers in fixture functions. + +- improved pdb support: ``import pdb ; pdb.set_trace()`` now works + without requiring prior disabling of stdout/stderr capturing. + Also the ``--pdb`` options works now on collection and internal errors + and we introduced a new experimental hook for IDEs/plugins to + intercept debugging: ``pytest_exception_interact(node, call, report)``. + +- shorter monkeypatch variant to allow specifying an import path as + a target, for example: ``monkeypatch.setattr("requests.get", myfunc)`` + +- better unittest/nose compatibility: all teardown methods are now only + called if the corresponding setup method succeeded. + +- integrate tab-completion on command line options if you + have `argcomplete `_ + configured. + +- allow boolean expression directly with skipif/xfail + if a "reason" is also specified. + +- a new hook ``pytest_load_initial_conftests`` allows plugins like + `pytest-django `_ to + influence the environment before conftest files import ``django``. + +- reporting: color the last line red or green depending if + failures/errors occured or everything passed. + +The documentation has been updated to accomodate the changes, +see `http://pytest.org `_ + +To install or upgrade pytest:: + + pip install -U pytest # or + easy_install -U pytest + + +**Many thanks to all who helped, including Floris Bruynooghe, +Brianna Laugher, Andreas Pelme, Anthon van der Neut, Anatoly Bubenkoff, +Vladimir Keleshev, Mathieu Agopian, Ronny Pfannschmidt, Christian +Theunert and many others.** + +may passing tests be with you, + +holger krekel + +Changes between 2.3.5 and 2.4 +----------------------------------- + +known incompatibilities: + +- if calling --genscript from python2.7 or above, you only get a + standalone script which works on python2.7 or above. Use Python2.6 + to also get a python2.5 compatible version. + +- all xunit-style teardown methods (nose-style, pytest-style, + unittest-style) will not be called if the corresponding setup method failed, + see issue322 below. + +- the pytest_plugin_unregister hook wasn't ever properly called + and there is no known implementation of the hook - so it got removed. + +- pytest.fixture-decorated functions cannot be generators (i.e. use + yield) anymore. This change might be reversed in 2.4.1 if it causes + unforeseen real-life issues. However, you can always write and return + an inner function/generator and change the fixture consumer to iterate + over the returned generator. This change was done in lieu of the new + ``pytest.yield_fixture`` decorator, see below. + +new features: + +- experimentally introduce a new ``pytest.yield_fixture`` decorator + which accepts exactly the same parameters as pytest.fixture but + mandates a ``yield`` statement instead of a ``return statement`` from + fixture functions. This allows direct integration with "with-style" + context managers in fixture functions and generally avoids registering + of finalization callbacks in favour of treating the "after-yield" as + teardown code. Thanks Andreas Pelme, Vladimir Keleshev, Floris + Bruynooghe, Ronny Pfannschmidt and many others for discussions. + +- allow boolean expression directly with skipif/xfail + if a "reason" is also specified. Rework skipping documentation + to recommend "condition as booleans" because it prevents surprises + when importing markers between modules. Specifying conditions + as strings will remain fully supported. + +- reporting: color the last line red or green depending if + failures/errors occured or everything passed. thanks Christian + Theunert. + +- make "import pdb ; pdb.set_trace()" work natively wrt capturing (no + "-s" needed anymore), making ``pytest.set_trace()`` a mere shortcut. + +- fix issue181: --pdb now also works on collect errors (and + on internal errors) . This was implemented by a slight internal + refactoring and the introduction of a new hook + ``pytest_exception_interact`` hook (see next item). + +- fix issue341: introduce new experimental hook for IDEs/terminals to + intercept debugging: ``pytest_exception_interact(node, call, report)``. + +- new monkeypatch.setattr() variant to provide a shorter + invocation for patching out classes/functions from modules: + + monkeypatch.setattr("requests.get", myfunc) + + will replace the "get" function of the "requests" module with ``myfunc``. + +- fix issue322: tearDownClass is not run if setUpClass failed. Thanks + Mathieu Agopian for the initial fix. Also make all of pytest/nose + finalizer mimick the same generic behaviour: if a setupX exists and + fails, don't run teardownX. This internally introduces a new method + "node.addfinalizer()" helper which can only be called during the setup + phase of a node. + +- simplify pytest.mark.parametrize() signature: allow to pass a + CSV-separated string to specify argnames. For example: + ``pytest.mark.parametrize("input,expected", [(1,2), (2,3)])`` + works as well as the previous: + ``pytest.mark.parametrize(("input", "expected"), ...)``. + +- add support for setUpModule/tearDownModule detection, thanks Brian Okken. + +- integrate tab-completion on options through use of "argcomplete". + Thanks Anthon van der Neut for the PR. + +- change option names to be hyphen-separated long options but keep the + old spelling backward compatible. py.test -h will only show the + hyphenated version, for example "--collect-only" but "--collectonly" + will remain valid as well (for backward-compat reasons). Many thanks to + Anthon van der Neut for the implementation and to Hynek Schlawack for + pushing us. + +- fix issue 308 - allow to mark/xfail/skip individual parameter sets + when parametrizing. Thanks Brianna Laugher. + +- call new experimental pytest_load_initial_conftests hook to allow + 3rd party plugins to do something before a conftest is loaded. + +Bug fixes: + +- fix issue358 - capturing options are now parsed more properly + by using a new parser.parse_known_args method. + +- pytest now uses argparse instead of optparse (thanks Anthon) which + means that "argparse" is added as a dependency if installing into python2.6 + environments or below. + +- fix issue333: fix a case of bad unittest/pytest hook interaction. + +- PR27: correctly handle nose.SkipTest during collection. Thanks + Antonio Cuni, Ronny Pfannschmidt. + +- fix issue355: junitxml puts name="pytest" attribute to testsuite tag. + +- fix issue336: autouse fixture in plugins should work again. + +- fix issue279: improve object comparisons on assertion failure + for standard datatypes and recognise collections.abc. Thanks to + Brianna Laugher and Mathieu Agopian. + +- fix issue317: assertion rewriter support for the is_package method + +- fix issue335: document py.code.ExceptionInfo() object returned + from pytest.raises(), thanks Mathieu Agopian. + +- remove implicit distribute_setup support from setup.py. + +- fix issue305: ignore any problems when writing pyc files. + +- SO-17664702: call fixture finalizers even if the fixture function + partially failed (finalizers would not always be called before) + +- fix issue320 - fix class scope for fixtures when mixed with + module-level functions. Thanks Anatloy Bubenkoff. + +- you can specify "-q" or "-qq" to get different levels of "quieter" + reporting (thanks Katarzyna Jachim) + +- fix issue300 - Fix order of conftest loading when starting py.test + in a subdirectory. + +- fix issue323 - sorting of many module-scoped arg parametrizations + +- make sessionfinish hooks execute with the same cwd-context as at + session start (helps fix plugin behaviour which write output files + with relative path such as pytest-cov) + +- fix issue316 - properly reference collection hooks in docs + +- fix issue 306 - cleanup of -k/-m options to only match markers/test + names/keywords respectively. Thanks Wouter van Ackooy. + +- improved doctest counting for doctests in python modules -- + files without any doctest items will not show up anymore + and doctest examples are counted as separate test items. + thanks Danilo Bellini. + +- fix issue245 by depending on the released py-1.4.14 + which fixes py.io.dupfile to work with files with no + mode. Thanks Jason R. Coombs. + +- fix junitxml generation when test output contains control characters, + addressing issue267, thanks Jaap Broekhuizen + +- fix issue338: honor --tb style for setup/teardown errors as well. Thanks Maho. + +- fix issue307 - use yaml.safe_load in example, thanks Mark Eichin. + +- better parametrize error messages, thanks Brianna Laugher + +- pytest_terminal_summary(terminalreporter) hooks can now use + ".section(title)" and ".line(msg)" methods to print extra + information at the end of a test run. + diff -r 49b10f86e35114a851957723058328e2f45e2657 -r 4a3891297f9131f1e4944bfc68bb23d1a29c75cf doc/en/conf.py --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -17,7 +17,7 @@ # # The full version, including alpha/beta/rc tags. # The short X.Y version. -version = release = "2.4.0.dev" +version = release = "2.4.0" import sys, os diff -r 49b10f86e35114a851957723058328e2f45e2657 -r 4a3891297f9131f1e4944bfc68bb23d1a29c75cf doc/en/faq.txt --- a/doc/en/faq.txt +++ b/doc/en/faq.txt @@ -3,9 +3,10 @@ .. note:: - If you don't find an answer here, you may checkout + This FAQ is here only mostly for historic reasons. Checkout `pytest Q&A at Stackoverflow `_ - or other :ref:`contact channels` to get help. + for many questions and answers related to pytest and/or use + :ref:`contact channels` to get help. On naming, nosetests, licensing and magic ------------------------------------------------ @@ -94,12 +95,12 @@ is another tool named "pytest" we just decided to stick with ``py.test`` for now. -Function arguments, parametrized tests and setup +pytest fixtures, parametrized tests ------------------------------------------------------- .. _funcargs: funcargs.html -Is using funcarg- versus xUnit setup a style question? +Is using pytest fixtures versus xUnit setup a style question? +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ For simple applications and for people experienced with nose_ or @@ -117,20 +118,6 @@ .. _`why pytest_pyfuncarg__ methods?`: -Why the ``pytest_funcarg__*`` name for funcarg factories? -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -We like `Convention over Configuration`_ and didn't see much point -in allowing a more flexible or abstract mechanism. Moreover, -it is nice to be able to search for ``pytest_funcarg__MYARG`` in -source code and safely find all factory functions for -the ``MYARG`` function argument. - -.. note:: - - With pytest-2.3 you can use the :ref:`@pytest.fixture` decorator - to mark a function as a fixture function. - .. _`Convention over Configuration`: http://en.wikipedia.org/wiki/Convention_over_Configuration Can I yield multiple values from a fixture function function? @@ -139,16 +126,16 @@ There are two conceptual reasons why yielding from a factory function is not possible: +* If multiple factories yielded values there would + be no natural place to determine the combination + policy - in real-world examples some combinations + often should not run. + * Calling factories for obtaining test function arguments is part of setting up and running a test. At that point it is not possible to add new test calls to the test collection anymore. -* If multiple factories yielded values there would - be no natural place to determine the combination - policy - in real-world examples some combinations - often should not run. - However, with pytest-2.3 you can use the :ref:`@pytest.fixture` decorator and specify ``params`` so that all tests depending on the factory-created resource will run multiple times with different parameters. diff -r 49b10f86e35114a851957723058328e2f45e2657 -r 4a3891297f9131f1e4944bfc68bb23d1a29c75cf doc/en/fixture.txt --- a/doc/en/fixture.txt +++ b/doc/en/fixture.txt @@ -34,6 +34,12 @@ prefer. You can also start out from existing :ref:`unittest.TestCase style ` or :ref:`nose based ` projects. +.. note:: + + pytest-2.4 introduced an additional experimental + :ref:`yield fixture mechanism ` for easier context manager + integration and more linear writing of teardown code. + .. _`funcargs`: .. _`funcarg mechanism`: .. _`fixture function`: @@ -275,9 +281,6 @@ module itself does not need to change or know about these details of fixture setup. -Note that pytest-2.4 introduced an experimental alternative -:ref:`yield fixture mechanism ` for easier context manager -integration and more linear writing of teardown code. .. _`request-context`: diff -r 49b10f86e35114a851957723058328e2f45e2657 -r 4a3891297f9131f1e4944bfc68bb23d1a29c75cf testing/acceptance_test.py --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -504,7 +504,7 @@ class TestDurations: source = """ import time - frag = 0.02 + frag = 0.002 def test_something(): pass def test_2(): @@ -519,7 +519,7 @@ testdir.makepyfile(self.source) result = testdir.runpytest("--durations=10") assert result.ret == 0 - result.stdout.fnmatch_lines([ + result.stdout.fnmatch_lines_random([ "*durations*", "*call*test_3*", "*call*test_2*", @@ -530,12 +530,8 @@ testdir.makepyfile(self.source) result = testdir.runpytest("--durations=2") assert result.ret == 0 - result.stdout.fnmatch_lines([ - "*durations*", - "*call*test_3*", - "*call*test_2*", - ]) - assert "test_1" not in result.stdout.str() + lines = result.stdout.get_lines_after("*slowest*durations*") + assert "4 passed" in lines[2] def test_calls_showall(self, testdir): testdir.makepyfile(self.source) @@ -573,7 +569,7 @@ class TestDurationWithFixture: source = """ import time - frag = 0.01 + frag = 0.001 def setup_function(func): time.sleep(frag * 3) def test_1(): diff -r 49b10f86e35114a851957723058328e2f45e2657 -r 4a3891297f9131f1e4944bfc68bb23d1a29c75cf testing/test_junitxml.py --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -1,4 +1,4 @@ - +import pytest from xml.dom import minidom import py, sys, os @@ -427,16 +427,16 @@ def test_logxml_path_expansion(tmpdir, monkeypatch): from _pytest.junitxml import LogXML - home_tilde = os.path.normpath(os.path.expanduser('~/test.xml')) + home_tilde = py.path.local(os.path.expanduser('~')).join('test.xml') - xml_tilde = LogXML('~/test.xml', None) + xml_tilde = LogXML('~%stest.xml' % tmpdir.sep, None) assert xml_tilde.logfile == home_tilde # this is here for when $HOME is not set correct monkeypatch.setenv("HOME", tmpdir) home_var = os.path.normpath(os.path.expandvars('$HOME/test.xml')) - xml_var = LogXML('$HOME/test.xml', None) + xml_var = LogXML('$HOME%stest.xml' % tmpdir.sep, None) assert xml_var.logfile == home_var def test_logxml_changingdir(testdir): 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 Oct 1 12:51:58 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 01 Oct 2013 10:51:58 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: bump version to dev again, new CHANGELOG section for 2.4.1.dev. Message-ID: <20131001105158.28809.32001@app13.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/aba49b1a860f/ Changeset: aba49b1a860f User: hpk42 Date: 2013-10-01 12:51:52 Summary: bump version to dev again, new CHANGELOG section for 2.4.1.dev. Affected #: 3 files diff -r 4a3891297f9131f1e4944bfc68bb23d1a29c75cf -r aba49b1a860f2b5914770841d0410ae3e357ad75 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +Changes between 2.4.0 and X +----------------------------------- + + + Changes between 2.3.5 and 2.4 ----------------------------------- diff -r 4a3891297f9131f1e4944bfc68bb23d1a29c75cf -r aba49b1a860f2b5914770841d0410ae3e357ad75 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.4.0' +__version__ = '2.4.1.dev1' diff -r 4a3891297f9131f1e4944bfc68bb23d1a29c75cf -r aba49b1a860f2b5914770841d0410ae3e357ad75 setup.py --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.4.0', + version='2.4.1.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 Tue Oct 1 14:20:33 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 01 Oct 2013 12:20:33 -0000 Subject: [Pytest-commit] commit/pytest: flub: Allow unicode strings in parser.add_argument() Message-ID: <20131001122033.18677.83448@app08.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/3de02d55a78f/ Changeset: 3de02d55a78f User: flub Date: 2013-10-01 14:20:20 Summary: Allow unicode strings in parser.add_argument() This fixes issue360 by also converting unicode strings to the argparse syntax instead of just native strings. Affected #: 3 files diff -r aba49b1a860f2b5914770841d0410ae3e357ad75 -r 3de02d55a78f36b45982627b5ecb9825bb0d8ca2 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,8 @@ Changes between 2.4.0 and X ----------------------------------- - +- fix issue360: When using parser.addoption() unicode arguments to the + "type" keyword should also be converted to the respective types. Changes between 2.3.5 and 2.4 ----------------------------------- diff -r aba49b1a860f2b5914770841d0410ae3e357ad75 -r 3de02d55a78f36b45982627b5ecb9825bb0d8ca2 _pytest/config.py --- a/_pytest/config.py +++ b/_pytest/config.py @@ -238,7 +238,7 @@ pass else: # this might raise a keyerror as well, don't want to catch that - if isinstance(typ, str): + if isinstance(typ, py.builtin._basestring): if typ == 'choice': if self.TYPE_WARN: py.std.warnings.warn( diff -r aba49b1a860f2b5914770841d0410ae3e357ad75 -r 3de02d55a78f36b45982627b5ecb9825bb0d8ca2 testing/test_config.py --- a/testing/test_config.py +++ b/testing/test_config.py @@ -113,6 +113,17 @@ assert config.getoption(x) == "this" pytest.raises(ValueError, "config.getoption('qweqwe')") + @pytest.mark.skipif('sys.version_info[:2] not in [(2, 6), (2, 7)]') + def test_config_getoption_unicode(self, testdir): + testdir.makeconftest(""" + from __future__ import unicode_literals + + def pytest_addoption(parser): + parser.addoption('--hello', type='string') + """) + config = testdir.parseconfig('--hello=this') + assert config.getoption('hello') == 'this' + def test_config_getvalueorskip(self, testdir): config = testdir.parseconfig() pytest.raises(pytest.skip.Exception, 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 Oct 1 14:26:07 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 01 Oct 2013 12:26:07 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: strike wrong yield_fixture paragraph Message-ID: <20131001122607.27005.18131@app05.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/5fe4b94c395d/ Changeset: 5fe4b94c395d User: hpk42 Date: 2013-10-01 14:25:59 Summary: strike wrong yield_fixture paragraph Affected #: 1 file diff -r 3de02d55a78f36b45982627b5ecb9825bb0d8ca2 -r 5fe4b94c395dce2a857408cc2a7e478138388dcb doc/en/yieldfixture.txt --- a/doc/en/yieldfixture.txt +++ b/doc/en/yieldfixture.txt @@ -119,13 +119,6 @@ Others can start experimenting with writing yield-style fixtures and possibly help evolving them further. -Some developers also expressed their preference for -rather introduce a new ``@pytest.yieldfixture`` decorator -instead of a keyword argument, or for assuming the above -yield-semantics automatically by introspecting if a fixture -function is a generator. Depending on more experiences and -feedback during the 2.4 cycle, we revisit theses issues. - If you want to feedback or participate in the ongoing discussion, please join our :ref:`contact channels`. you are most welcome. 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 Oct 1 14:31:01 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 01 Oct 2013 12:31:01 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: fix typos (thanks @faassen) Message-ID: <20131001123101.25815.3037@app07.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/6720c03fd0da/ Changeset: 6720c03fd0da User: hpk42 Date: 2013-10-01 14:30:53 Summary: fix typos (thanks @faassen) Affected #: 1 file diff -r 5fe4b94c395dce2a857408cc2a7e478138388dcb -r 6720c03fd0dafceda84710d6958bf5f6708bb032 doc/en/yieldfixture.txt --- a/doc/en/yieldfixture.txt +++ b/doc/en/yieldfixture.txt @@ -8,7 +8,7 @@ .. regendoc:wipe -pytest-2.4 allows fixture functions to seemlessly use a ``yield`` instead +pytest-2.4 allows fixture functions to seamlessly use a ``yield`` instead of a ``return`` statement to provide a fixture value while otherwise fully supporting all other fixture features. @@ -92,7 +92,7 @@ However, there are also limitations or foreseeable irritations: -- usually ``yield`` is typically used for producing multiple values. +- usually ``yield`` is used for producing multiple values. But fixture functions can only yield exactly one value. Yielding a second fixture value will get you an error. It's possible we can evolve pytest to allow for producing 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 Oct 1 17:19:06 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 01 Oct 2013 15:19:06 -0000 Subject: [Pytest-commit] commit/pytest: Anthon van der Neut: complete_dotted: fix for #361, filecompleter on dot files had differing behaviour from bash Message-ID: <20131001151906.1000.66608@app04.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/8124b841c6ca/ Changeset: 8124b841c6ca User: Anthon van der Neut Date: 2013-10-01 16:33:15 Summary: complete_dotted: fix for #361, filecompleter on dot files had differing behaviour from bash Now if the prefix to expands ends in the directory seperator, then '..../.*' is globbed as well. Affected #: 1 file diff -r 6720c03fd0dafceda84710d6958bf5f6708bb032 -r 8124b841c6ca8c40963d4650143c32304932a3ec _pytest/_argcomplete.py --- a/_pytest/_argcomplete.py +++ b/_pytest/_argcomplete.py @@ -74,9 +74,13 @@ else: prefix_dir = 0 completion = [] + globbed = [] if '*' not in prefix and '?' not in prefix: + if prefix[-1] == os.path.sep: # we are on unix, otherwise no bash + globbed.extend(glob(prefix + '.*')) prefix += '*' - for x in sorted(glob(prefix)): + globbed.extend(glob(prefix)) + for x in sorted(globbed): if os.path.isdir(x): x += '/' # append stripping the prefix (like bash, not like compgen) 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 Oct 2 07:48:44 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 02 Oct 2013 05:48:44 -0000 Subject: [Pytest-commit] commit/pytest: 2 new changesets Message-ID: <20131002054844.25656.43458@app04.ash-private.bitbucket.org> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/29f985647e12/ Changeset: 29f985647e12 Branch: dirn/adjust-syntax-for-parametrize-documentat-1380671670976 User: dirn Date: 2013-10-02 01:54:34 Summary: Adjust syntax for parametrize documentation Without the double colon, reStructuredText won't display treat the block that follows as pre-formatted text. Also, with this change comes the need to change a tab to spaces to align it with the adjacent lines. Affected #: 1 file diff -r 8124b841c6ca8c40963d4650143c32304932a3ec -r 29f985647e123d9f236b011abdbfebbc22da814d doc/en/skipping.txt --- a/doc/en/skipping.txt +++ b/doc/en/skipping.txt @@ -183,7 +183,7 @@ --------------------------- It is possible to apply markers like skip and xfail to individual -test instances when using parametrize: +test instances when using parametrize:: import pytest @@ -191,7 +191,7 @@ (1, 2), pytest.mark.xfail((1, 0)), pytest.mark.xfail(reason="some bug")((1, 3)), - (2, 3), + (2, 3), (3, 4), (4, 5), pytest.mark.skipif("sys.version_info >= (3,0)")((10, 11)), https://bitbucket.org/hpk42/pytest/commits/a7926e988749/ Changeset: a7926e988749 User: hpk42 Date: 2013-10-02 07:48:41 Summary: Merged in dirn/pytest/dirn/adjust-syntax-for-parametrize-documentat-1380671670976 (pull request #72) Adjust syntax for parametrize documentation Affected #: 1 file diff -r 8124b841c6ca8c40963d4650143c32304932a3ec -r a7926e9887491c75330d414becd2b69ab6eb07a8 doc/en/skipping.txt --- a/doc/en/skipping.txt +++ b/doc/en/skipping.txt @@ -183,7 +183,7 @@ --------------------------- It is possible to apply markers like skip and xfail to individual -test instances when using parametrize: +test instances when using parametrize:: import pytest @@ -191,7 +191,7 @@ (1, 2), pytest.mark.xfail((1, 0)), pytest.mark.xfail(reason="some bug")((1, 3)), - (2, 3), + (2, 3), (3, 4), (4, 5), pytest.mark.skipif("sys.version_info >= (3,0)")((10, 11)), 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 Oct 2 07:49:19 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 02 Oct 2013 05:49:19 -0000 Subject: [Pytest-commit] commit/pytest: 2 new changesets Message-ID: <20131002054919.13835.52645@app02.ash-private.bitbucket.org> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/887225d5a16d/ Changeset: 887225d5a16d User: hpk42 Date: 2013-10-01 22:39:23 Summary: add to CHANGELOG Affected #: 1 file diff -r 6720c03fd0dafceda84710d6958bf5f6708bb032 -r 887225d5a16d46df2cbf3526b6c060faa54f8b82 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,11 @@ - fix issue360: When using parser.addoption() unicode arguments to the "type" keyword should also be converted to the respective types. + thanks Floris Bruynooghe. + +- fix issue361: fix filename completion when using argcomplete + thanks Anthon van der Neuth. + Changes between 2.3.5 and 2.4 ----------------------------------- https://bitbucket.org/hpk42/pytest/commits/1dd933cfa077/ Changeset: 1dd933cfa077 User: hpk42 Date: 2013-10-02 07:49:11 Summary: merge Affected #: 2 files diff -r 887225d5a16d46df2cbf3526b6c060faa54f8b82 -r 1dd933cfa0777413ea70c1cd7a98c5514222f43f _pytest/_argcomplete.py --- a/_pytest/_argcomplete.py +++ b/_pytest/_argcomplete.py @@ -74,9 +74,13 @@ else: prefix_dir = 0 completion = [] + globbed = [] if '*' not in prefix and '?' not in prefix: + if prefix[-1] == os.path.sep: # we are on unix, otherwise no bash + globbed.extend(glob(prefix + '.*')) prefix += '*' - for x in sorted(glob(prefix)): + globbed.extend(glob(prefix)) + for x in sorted(globbed): if os.path.isdir(x): x += '/' # append stripping the prefix (like bash, not like compgen) diff -r 887225d5a16d46df2cbf3526b6c060faa54f8b82 -r 1dd933cfa0777413ea70c1cd7a98c5514222f43f doc/en/skipping.txt --- a/doc/en/skipping.txt +++ b/doc/en/skipping.txt @@ -183,7 +183,7 @@ --------------------------- It is possible to apply markers like skip and xfail to individual -test instances when using parametrize: +test instances when using parametrize:: import pytest @@ -191,7 +191,7 @@ (1, 2), pytest.mark.xfail((1, 0)), pytest.mark.xfail(reason="some bug")((1, 3)), - (2, 3), + (2, 3), (3, 4), (4, 5), pytest.mark.skipif("sys.version_info >= (3,0)")((10, 11)), 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 Oct 2 07:57:36 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 02 Oct 2013 05:57:36 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: adapt changelog Message-ID: <20131002055736.12738.87638@app04.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/00aface0eb28/ Changeset: 00aface0eb28 User: hpk42 Date: 2013-10-02 07:56:30 Summary: adapt changelog Affected #: 1 file diff -r 1dd933cfa0777413ea70c1cd7a98c5514222f43f -r 00aface0eb2874e70545a09f71edf73a3753feb5 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,13 +1,14 @@ -Changes between 2.4.0 and X +Changes between 2.4.0 and 2.4.1 ----------------------------------- -- fix issue360: When using parser.addoption() unicode arguments to the +- When using parser.addoption() unicode arguments to the "type" keyword should also be converted to the respective types. - thanks Floris Bruynooghe. + thanks Floris Bruynooghe, @dnozay. (fixes issue360 and issue362) -- fix issue361: fix filename completion when using argcomplete - thanks Anthon van der Neuth. - +- fix dotted filename completion when using argcomplete + thanks Anthon van der Neuth. (fixes issue361) + +- merge doc typo fixes, thanks Andy Dirnberger Changes between 2.3.5 and 2.4 ----------------------------------- 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 Oct 2 08:09:21 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 02 Oct 2013 06:09:21 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: fix regression reported by dstufft: regression when a 1-tuple ("arg", ) is used Message-ID: <20131002060921.10656.47522@app12.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/8f9abe7698e2/ Changeset: 8f9abe7698e2 User: hpk42 Date: 2013-10-02 08:08:26 Summary: fix regression reported by dstufft: regression when a 1-tuple ("arg",) is used for specifying parametrization (the values of the parametrization were passed nested in a tuple). Affected #: 3 files diff -r 00aface0eb2874e70545a09f71edf73a3753feb5 -r 8f9abe7698e264a3ef3d2c58678537ace8017cde CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -8,6 +8,10 @@ - fix dotted filename completion when using argcomplete thanks Anthon van der Neuth. (fixes issue361) +- fix regression when a 1-tuple ("arg",) is used for specifying + parametrization (the values of the parametrization were passed + nested in a tuple). Thanks Donald Stufft. + - merge doc typo fixes, thanks Andy Dirnberger Changes between 2.3.5 and 2.4 diff -r 00aface0eb2874e70545a09f71edf73a3753feb5 -r 8f9abe7698e264a3ef3d2c58678537ace8017cde _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -710,8 +710,8 @@ if not isinstance(argnames, (tuple, list)): argnames = [x.strip() for x in argnames.split(",") if x.strip()] - if len(argnames) == 1: - argvalues = [(val,) for val in argvalues] + if len(argnames) == 1: + argvalues = [(val,) for val in argvalues] if not argvalues: argvalues = [(_notexists,) * len(argnames)] diff -r 00aface0eb2874e70545a09f71edf73a3753feb5 -r 8f9abe7698e264a3ef3d2c58678537ace8017cde testing/python/collect.py --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -316,6 +316,16 @@ reprec = testdir.inline_run() reprec.assertoutcome(skipped=1) + def test_single_tuple_unwraps_values(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.mark.parametrize(('arg',), [(1,)]) + def test_function(arg): + assert arg == 1 + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + def test_issue213_parametrize_value_no_equal(self, testdir): testdir.makepyfile(""" import pytest Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Wed Oct 2 12:39:43 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 02 Oct 2013 10:39:43 -0000 Subject: [Pytest-commit] commit/pytest: 3 new changesets Message-ID: <20131002103943.30642.19002@app02.ash-private.bitbucket.org> 3 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/8828c924acae/ Changeset: 8828c924acae User: hpk42 Date: 2013-10-02 09:16:51 Summary: 2.4.1 release preps Affected #: 4 files diff -r 8f9abe7698e264a3ef3d2c58678537ace8017cde -r 8828c924acae0b4cad2e2cb92943d51da7cb744a _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.4.1.dev1' +__version__ = '2.4.1' diff -r 8f9abe7698e264a3ef3d2c58678537ace8017cde -r 8828c924acae0b4cad2e2cb92943d51da7cb744a doc/en/announce/release-2.4.1.txt --- /dev/null +++ b/doc/en/announce/release-2.4.1.txt @@ -0,0 +1,25 @@ +pytest-2.4.1: fixing three regressions compared to 2.3.5 +=========================================================================== + +pytest-2.4.1 is a quick follow up release to fix three regressions +compared to 2.3.5 before they hit more people: + +- When using parser.addoption() unicode arguments to the + "type" keyword should also be converted to the respective types. + thanks Floris Bruynooghe, @dnozay. (fixes issue360 and issue362) + +- fix dotted filename completion when using argcomplete + thanks Anthon van der Neuth. (fixes issue361) + +- fix regression when a 1-tuple ("arg",) is used for specifying + parametrization (the values of the parametrization were passed + nested in a tuple). Thanks Donald Stufft. + +- also merge doc typo fixes, thanks Andy Dirnberger + +as usual, docs at http://pytest.org and upgrades via:: + + pip install -U pytest + +have fun, +holger krekel diff -r 8f9abe7698e264a3ef3d2c58678537ace8017cde -r 8828c924acae0b4cad2e2cb92943d51da7cb744a doc/en/conf.py --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -17,7 +17,8 @@ # # The full version, including alpha/beta/rc tags. # The short X.Y version. -version = release = "2.4.0" +version = "2.4.1" +release = "2.4.1" import sys, os diff -r 8f9abe7698e264a3ef3d2c58678537ace8017cde -r 8828c924acae0b4cad2e2cb92943d51da7cb744a setup.py --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.4.1.dev1', + version='2.4.1', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], https://bitbucket.org/hpk42/pytest/commits/42e0e9d8db2e/ Changeset: 42e0e9d8db2e User: hpk42 Date: 2013-10-02 12:09:19 Summary: reference CHANGELOG Affected #: 1 file diff -r 8828c924acae0b4cad2e2cb92943d51da7cb744a -r 42e0e9d8db2e172ec6588acafa8102e343979375 README.rst --- a/README.rst +++ b/README.rst @@ -1,3 +1,6 @@ + +Changelog: http://pytest.org/latest/changelog.html + The ``py.test`` testing tool makes it easy to write small tests, yet scales to support complex functional testing. It provides https://bitbucket.org/hpk42/pytest/commits/6d1e3a0d4746/ Changeset: 6d1e3a0d4746 User: hpk42 Date: 2013-10-02 12:39:01 Summary: avoid "IOError: Bad Filedescriptor" on pytest shutdown by not closing the internal dupped stdout (fix is slightly hand-wavy but work). Affected #: 5 files diff -r 42e0e9d8db2e172ec6588acafa8102e343979375 -r 6d1e3a0d474693b63a9ada2b4cac0283c90f0f45 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +Changes between 2.4.1 and 2.4.2 +----------------------------------- + +- avoid "IOError: Bad Filedescriptor" on pytest shutdown by not closing + the internal dupped stdout (fix is slightly hand-wavy but work). + Changes between 2.4.0 and 2.4.1 ----------------------------------- diff -r 42e0e9d8db2e172ec6588acafa8102e343979375 -r 6d1e3a0d474693b63a9ada2b4cac0283c90f0f45 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.4.1' +__version__ = '2.4.2.dev1' diff -r 42e0e9d8db2e172ec6588acafa8102e343979375 -r 6d1e3a0d474693b63a9ada2b4cac0283c90f0f45 _pytest/capture.py --- a/_pytest/capture.py +++ b/_pytest/capture.py @@ -29,7 +29,7 @@ except ValueError: pass early_config.pluginmanager.add_shutdown(teardown) - # make sure logging does not raise exceptions if it is imported + # make sure logging does not raise exceptions at the end def silence_logging_at_shutdown(): if "logging" in sys.modules: sys.modules["logging"].raiseExceptions = False diff -r 42e0e9d8db2e172ec6588acafa8102e343979375 -r 6d1e3a0d474693b63a9ada2b4cac0283c90f0f45 _pytest/terminal.py --- a/_pytest/terminal.py +++ b/_pytest/terminal.py @@ -33,20 +33,23 @@ def pytest_configure(config): config.option.verbose -= config.option.quiet + # we try hard to make printing resilient against - # later changes on FD level. (unless capturing is turned off) - stdout = py.std.sys.stdout - capture = config.option.capture != "no" - if capture and hasattr(os, 'dup') and hasattr(stdout, 'fileno'): + # later changes on FD level. (unless capturing is off/sys) + stdout = sys.stdout + if config.option.capture == "fd" and hasattr(os, "dup"): try: newstdout = py.io.dupfile(stdout, buffering=1, encoding=stdout.encoding) except ValueError: pass else: - config._cleanup.append(lambda: newstdout.close()) assert stdout.encoding == newstdout.encoding stdout = newstdout + #we don't close on shutdown because this can + #cause logging to fail on a second close + #(not really clear to me how it happens exactly, though) + #config.pluginmanager.add_shutdown(fin) reporter = TerminalReporter(config, stdout) config.pluginmanager.register(reporter, 'terminalreporter') diff -r 42e0e9d8db2e172ec6588acafa8102e343979375 -r 6d1e3a0d474693b63a9ada2b4cac0283c90f0f45 setup.py --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.4.1', + version='2.4.2.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 Oct 2 12:41:16 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 02 Oct 2013 10:41:16 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: Added tag 2.4.1 for changeset 8828c924acae Message-ID: <20131002104116.12920.21952@app05.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/f9516c998c1d/ Changeset: f9516c998c1d User: hpk42 Date: 2013-10-02 12:41:03 Summary: Added tag 2.4.1 for changeset 8828c924acae Affected #: 1 file diff -r 6d1e3a0d474693b63a9ada2b4cac0283c90f0f45 -r f9516c998c1dd33b2130ad4ddc649fb0394cee10 .hgtags --- a/.hgtags +++ b/.hgtags @@ -61,3 +61,4 @@ 0000000000000000000000000000000000000000 1.4.14 0000000000000000000000000000000000000000 1.4.14 af860de70cc3f157ac34ca1d4bf557a057bff775 2.4.0 +8828c924acae0b4cad2e2cb92943d51da7cb744a 2.4.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 Wed Oct 2 14:33:05 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 02 Oct 2013 12:33:05 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: remove unused imports (using "importchecker" project) Message-ID: <20131002123305.17943.89860@app02.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/10b3d5df19ab/ Changeset: 10b3d5df19ab User: hpk42 Date: 2013-10-02 14:32:40 Summary: remove unused imports (using "importchecker" project) Affected #: 8 files diff -r f9516c998c1dd33b2130ad4ddc649fb0394cee10 -r 10b3d5df19ab31daca4bca40ef848049d7f6298b _pytest/assertion/__init__.py --- a/_pytest/assertion/__init__.py +++ b/_pytest/assertion/__init__.py @@ -3,7 +3,6 @@ """ import py import sys -import pytest from _pytest.monkeypatch import monkeypatch from _pytest.assertion import util @@ -19,7 +18,7 @@ to provide assert expression information. """) group.addoption('--no-assert', action="store_true", default=False, dest="noassert", help="DEPRECATED equivalent to --assert=plain") - group.addoption('--nomagic', '--no-magic', action="store_true", + group.addoption('--nomagic', '--no-magic', action="store_true", default=False, help="DEPRECATED equivalent to --assert=plain") class AssertionState: diff -r f9516c998c1dd33b2130ad4ddc649fb0394cee10 -r 10b3d5df19ab31daca4bca40ef848049d7f6298b _pytest/core.py --- a/_pytest/core.py +++ b/_pytest/core.py @@ -1,7 +1,7 @@ """ pytest PluginManager, basic initialization and tracing. """ -import sys, os +import sys import inspect import py diff -r f9516c998c1dd33b2130ad4ddc649fb0394cee10 -r 10b3d5df19ab31daca4bca40ef848049d7f6298b _pytest/main.py --- a/_pytest/main.py +++ b/_pytest/main.py @@ -2,14 +2,12 @@ import py import pytest, _pytest -import inspect import os, sys, imp try: from collections import MutableMapping as MappingMixin except ImportError: from UserDict import DictMixin as MappingMixin -from _pytest.mark import MarkInfo from _pytest.runner import collect_one_node, Skipped tracebackcutdir = py.path.local(_pytest.__file__).dirpath() diff -r f9516c998c1dd33b2130ad4ddc649fb0394cee10 -r 10b3d5df19ab31daca4bca40ef848049d7f6298b _pytest/nose.py --- a/_pytest/nose.py +++ b/_pytest/nose.py @@ -1,7 +1,6 @@ """ run test suites written for nose. """ import pytest, py -import inspect import sys from _pytest import unittest diff -r f9516c998c1dd33b2130ad4ddc649fb0394cee10 -r 10b3d5df19ab31daca4bca40ef848049d7f6298b _pytest/pytester.py --- a/_pytest/pytester.py +++ b/_pytest/pytester.py @@ -4,7 +4,6 @@ import sys, os import codecs import re -import inspect import time from fnmatch import fnmatch from _pytest.main import Session, EXIT_OK diff -r f9516c998c1dd33b2130ad4ddc649fb0394cee10 -r 10b3d5df19ab31daca4bca40ef848049d7f6298b _pytest/recwarn.py --- a/_pytest/recwarn.py +++ b/_pytest/recwarn.py @@ -1,14 +1,14 @@ """ recording warnings during test function execution. """ import py -import sys, os +import sys def pytest_funcarg__recwarn(request): """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. """ diff -r f9516c998c1dd33b2130ad4ddc649fb0394cee10 -r 10b3d5df19ab31daca4bca40ef848049d7f6298b _pytest/standalonetemplate.py --- a/_pytest/standalonetemplate.py +++ b/_pytest/standalonetemplate.py @@ -6,7 +6,6 @@ import sys import base64 import zlib -import imp class DictImporter(object): def __init__(self, sources): diff -r f9516c998c1dd33b2130ad4ddc649fb0394cee10 -r 10b3d5df19ab31daca4bca40ef848049d7f6298b _pytest/unittest.py --- a/_pytest/unittest.py +++ b/_pytest/unittest.py @@ -1,6 +1,6 @@ """ discovery and running of std-library "unittest" style tests. """ import pytest, py -import sys, pdb +import sys # for transfering markers from _pytest.python import transfer_markers 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 Oct 2 16:09:42 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 02 Oct 2013 14:09:42 -0000 Subject: [Pytest-commit] commit/pytest: witsch: allow test items to not be associated with a test function Message-ID: <20131002140942.17235.7697@app09.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/ac9232a10ef4/ Changeset: ac9232a10ef4 User: witsch Date: 2013-10-02 15:55:28 Summary: allow test items to not be associated with a test function this is needed for plugins like `pytest-pep8` or `pytest-flakes` Affected #: 1 file diff -r 10b3d5df19ab31daca4bca40ef848049d7f6298b -r ac9232a10ef45dc510f1b33102b1b8ac501429c8 _pytest/mark.py --- a/_pytest/mark.py +++ b/_pytest/mark.py @@ -139,8 +139,9 @@ mapped_names.add(name) # Add the names attached to the current function through direct assignment - for name in colitem.function.__dict__: - mapped_names.add(name) + if hasattr(colitem, 'function'): + for name in colitem.function.__dict__: + mapped_names.add(name) return eval(keywordexpr, {}, KeywordMapping(mapped_names)) Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Thu Oct 3 12:35:21 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 03 Oct 2013 10:35:21 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: add setup.cfg for building sphinx_docs Message-ID: <20131003103521.1140.97531@app01.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/6ce6602773ac/ Changeset: 6ce6602773ac User: hpk42 Date: 2013-10-03 12:35:13 Summary: add setup.cfg for building sphinx_docs Affected #: 1 file diff -r ac9232a10ef45dc510f1b33102b1b8ac501429c8 -r 6ce6602773ace1949b47d09c7bcff384530dbfb5 setup.cfg --- /dev/null +++ b/setup.cfg @@ -0,0 +1,8 @@ +[build_sphinx] +source-dir = doc/en/ +build-dir = doc/build +all_files = 1 + +[upload_sphinx] +upload-dir = doc/en/build/html + Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Thu Oct 3 13:53:30 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 03 Oct 2013 11:53:30 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: simplify the implementation of NodeKeywords getting rid of __ descriptors appearing there. Message-ID: <20131003115330.9089.47191@app08.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/0e4482f0ba67/ Changeset: 0e4482f0ba67 User: hpk42 Date: 2013-10-03 13:53:22 Summary: simplify the implementation of NodeKeywords getting rid of __ descriptors appearing there. Affected #: 4 files diff -r 6ce6602773ace1949b47d09c7bcff384530dbfb5 -r 0e4482f0ba672ae3e31d21cd12d5f06b15e621d7 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,10 @@ Changes between 2.4.1 and 2.4.2 ----------------------------------- +- fix "-k" matching of tests where "repr" and "attr" and other names would + cause wrong matches because of an internal implementation quirk + (don't ask) which is now properly implemented. fixes issue345. + - avoid "IOError: Bad Filedescriptor" on pytest shutdown by not closing the internal dupped stdout (fix is slightly hand-wavy but work). diff -r 6ce6602773ace1949b47d09c7bcff384530dbfb5 -r 0e4482f0ba672ae3e31d21cd12d5f06b15e621d7 _pytest/main.py --- a/_pytest/main.py +++ b/_pytest/main.py @@ -170,30 +170,39 @@ class NodeKeywords(MappingMixin): def __init__(self, node): - parent = node.parent - bases = parent and (parent.keywords._markers,) or () - self._markers = type("dynmarker", bases, {node.name: True}) + self.node = node + self.parent = node.parent + self._markers = {node.name: True} def __getitem__(self, key): try: - return getattr(self._markers, key) - except AttributeError: - raise KeyError(key) + return self._markers[key] + except KeyError: + if self.parent is None: + raise + return self.parent.keywords[key] def __setitem__(self, key, value): - setattr(self._markers, key, value) + self._markers[key] = value def __delitem__(self, key): - delattr(self._markers, key) + raise ValueError("cannot delete key in keywords dict") def __iter__(self): - return iter(self.keys()) + seen = set(self._markers) + if self.parent is not None: + seen.update(self.parent.keywords) + return iter(seen) def __len__(self): - return len(self.keys()) + return len(self.__iter__()) def keys(self): - return dir(self._markers) + return list(self) + + def __repr__(self): + return "" % (self.node, ) + class Node(object): """ base class for Collector and Item the test collection tree. diff -r 6ce6602773ace1949b47d09c7bcff384530dbfb5 -r 0e4482f0ba672ae3e31d21cd12d5f06b15e621d7 bench/bench.py --- a/bench/bench.py +++ b/bench/bench.py @@ -7,4 +7,4 @@ p = pstats.Stats("prof") p.strip_dirs() p.sort_stats('cumulative') - print(p.print_stats(30)) + print(p.print_stats(50)) diff -r 6ce6602773ace1949b47d09c7bcff384530dbfb5 -r 0e4482f0ba672ae3e31d21cd12d5f06b15e621d7 testing/test_collection.py --- a/testing/test_collection.py +++ b/testing/test_collection.py @@ -566,4 +566,25 @@ ]) +class TestNodekeywords: + def test_no_under(self, testdir): + modcol = testdir.getmodulecol(""" + def test_pass(): pass + def test_fail(): assert 0 + """) + l = list(modcol.keywords) + assert modcol.name in l + for x in l: + assert not x.startswith("_") + assert modcol.name in repr(modcol.keywords) + def test_issue345(self, testdir): + testdir.makepyfile(""" + def test_should_not_be_selected(): + assert False, 'I should not have been selected to run' + + def test___repr__(): + pass + """) + reprec = testdir.inline_run("-k repr") + reprec.assertoutcome(passed=1, failed=0) Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Thu Oct 3 14:23:03 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 03 Oct 2013 12:23:03 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: fix issue354: avoid tmpdir fixture to create too long filenames especially Message-ID: <20131003122303.18233.96705@app09.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/ebcecaa7d610/ Changeset: ebcecaa7d610 User: hpk42 Date: 2013-10-03 14:22:54 Summary: fix issue354: avoid tmpdir fixture to create too long filenames especially when parametrization is used Affected #: 3 files diff -r 0e4482f0ba672ae3e31d21cd12d5f06b15e621d7 -r ebcecaa7d610a5ec2aa5b3367169bffc1b50415f CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -8,6 +8,9 @@ - avoid "IOError: Bad Filedescriptor" on pytest shutdown by not closing the internal dupped stdout (fix is slightly hand-wavy but work). +- avoid tmpdir fixture to create too long filenames especially + when parametrization is used (issue354) + Changes between 2.4.0 and 2.4.1 ----------------------------------- diff -r 0e4482f0ba672ae3e31d21cd12d5f06b15e621d7 -r ebcecaa7d610a5ec2aa5b3367169bffc1b50415f _pytest/tmpdir.py --- a/_pytest/tmpdir.py +++ b/_pytest/tmpdir.py @@ -64,5 +64,8 @@ """ name = request.node.name name = py.std.re.sub("[\W]", "_", name) + MAXVAL = 30 + if len(name) > MAXVAL: + name = name[:MAXVAL] x = request.config._tmpdirhandler.mktemp(name, numbered=True) return x diff -r 0e4482f0ba672ae3e31d21cd12d5f06b15e621d7 -r ebcecaa7d610a5ec2aa5b3367169bffc1b50415f testing/test_tmpdir.py --- a/testing/test_tmpdir.py +++ b/testing/test_tmpdir.py @@ -91,3 +91,12 @@ result = testdir.runpytest("-s", p, '--basetemp=%s/bt' % linktemp) assert not result.ret +def test_tmpdir_too_long_on_parametrization(testdir): + testdir.makepyfile(""" + import pytest + @pytest.mark.parametrize("arg", ["1"*1000]) + def test_some(arg, tmpdir): + tmpdir.ensure("hello") + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Thu Oct 3 15:44:38 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 03 Oct 2013 13:44:38 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: more fixes regarding marking, in particular plugins should use add_marker/get_marker now. Message-ID: <20131003134438.740.63670@app06.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/bc620a10f932/ Changeset: bc620a10f932 User: hpk42 Date: 2013-10-03 15:43:56 Summary: more fixes regarding marking, in particular plugins should use add_marker/get_marker now. Affected #: 6 files diff -r ebcecaa7d610a5ec2aa5b3367169bffc1b50415f -r bc620a10f932bc0d961b92f2c0b741e2ae1c8715 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -11,6 +11,16 @@ - avoid tmpdir fixture to create too long filenames especially when parametrization is used (issue354) +- fix pytest-pep8 and pytest-flakes / pytest interactions + (collection names in mark plugin was assuming an item always + has a function which is not true for those plugins etc.) + Thanks Andi Zeidler. + +- introduce node.get_marker/node.add_marker API for plugins + like pytest-pep8 and pytest-flakes to avoid the messy + details of the node.keywords pseudo-dicts. Adapated + docs. + Changes between 2.4.0 and 2.4.1 ----------------------------------- diff -r ebcecaa7d610a5ec2aa5b3367169bffc1b50415f -r bc620a10f932bc0d961b92f2c0b741e2ae1c8715 _pytest/main.py --- a/_pytest/main.py +++ b/_pytest/main.py @@ -321,6 +321,27 @@ chain.reverse() return chain + def add_marker(self, marker): + """ dynamically add a marker object to the node. + + ``marker`` can be a string or pytest.mark.* instance. + """ + from _pytest.mark import MarkDecorator + if isinstance(marker, py.builtin._basestring): + marker = MarkDecorator(marker) + elif not isinstance(marker, MarkDecorator): + raise ValueError("is not a string or pytest.mark.* Marker") + self.keywords[marker.name] = marker + + def get_marker(self, name): + """ get a marker object from this node or None if + the node doesn't have a marker with that name. """ + val = self.keywords.get(name, None) + if val is not None: + from _pytest.mark import MarkInfo, MarkDecorator + if isinstance(val, (MarkDecorator, MarkInfo)): + return val + def listextrakeywords(self): """ Return a set of all extra keywords in self and any parents.""" extra_keywords = set() diff -r ebcecaa7d610a5ec2aa5b3367169bffc1b50415f -r bc620a10f932bc0d961b92f2c0b741e2ae1c8715 _pytest/mark.py --- a/_pytest/mark.py +++ b/_pytest/mark.py @@ -81,11 +81,8 @@ class MarkMapping: - """Provides a local mapping for markers. - Only the marker names from the given :class:`NodeKeywords` will be mapped, - so the names are taken only from :class:`MarkInfo` or - :class:`MarkDecorator` items. - """ + """Provides a local mapping for markers where item access + resolves to True if the marker is present. """ def __init__(self, keywords): mymarks = set() for key, value in keywords.items(): @@ -93,8 +90,8 @@ mymarks.add(key) self._mymarks = mymarks - def __getitem__(self, markname): - return markname in self._mymarks + def __getitem__(self, name): + return name in self._mymarks class KeywordMapping: @@ -202,13 +199,17 @@ pass """ def __init__(self, name, args=None, kwargs=None): - self.markname = name + self.name = name self.args = args or () self.kwargs = kwargs or {} + @property + def markname(self): + return self.name # for backward-compat (2.4.1 had this attr) + def __repr__(self): d = self.__dict__.copy() - name = d.pop('markname') + name = d.pop('name') return "" % (name, d) def __call__(self, *args, **kwargs): @@ -228,19 +229,19 @@ else: func.pytestmark = [self] else: - holder = getattr(func, self.markname, None) + holder = getattr(func, self.name, None) if holder is None: holder = MarkInfo( - self.markname, self.args, self.kwargs + self.name, self.args, self.kwargs ) - setattr(func, self.markname, holder) + setattr(func, self.name, holder) else: holder.add(self.args, self.kwargs) return func kw = self.kwargs.copy() kw.update(kwargs) args = self.args + args - return self.__class__(self.markname, args=args, kwargs=kw) + return self.__class__(self.name, args=args, kwargs=kw) class MarkInfo: diff -r ebcecaa7d610a5ec2aa5b3367169bffc1b50415f -r bc620a10f932bc0d961b92f2c0b741e2ae1c8715 doc/en/example/markers.txt --- a/doc/en/example/markers.txt +++ b/doc/en/example/markers.txt @@ -235,7 +235,7 @@ "env(name): mark test to run only on named environment") def pytest_runtest_setup(item): - envmarker = item.keywords.get("env", None) + envmarker = item.get_marker("env") if envmarker is not None: envname = envmarker.args[0] if envname != item.config.getoption("-E"): @@ -318,7 +318,7 @@ import sys def pytest_runtest_setup(item): - g = item.keywords.get("glob", None) + g = item.get_marker("glob") if g is not None: for info in g: print ("glob args=%s kwargs=%s" %(info.args, info.kwargs)) @@ -353,7 +353,7 @@ def pytest_runtest_setup(item): if isinstance(item, item.Function): plat = sys.platform - if plat not in item.keywords: + if not item.get_marker(plat): if ALL.intersection(item.keywords): pytest.skip("cannot run on platform %s" %(plat)) @@ -439,9 +439,9 @@ def pytest_collection_modifyitems(items): for item in items: if "interface" in item.nodeid: - item.keywords["interface"] = pytest.mark.interface + item.add_marker(pytest.mark.interface) elif "event" in item.nodeid: - item.keywords["event"] = pytest.mark.event + item.add_marker(pytest.mark.event) We can now use the ``-m option`` to select one set:: diff -r ebcecaa7d610a5ec2aa5b3367169bffc1b50415f -r bc620a10f932bc0d961b92f2c0b741e2ae1c8715 plugin-test.sh --- /dev/null +++ b/plugin-test.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# this assumes plugins are installed as sister directories + +set -e +cd ../pytest-pep8 +py.test +cd ../pytest-instafail +py.test +cd ../pytest-cache +py.test +#cd ../pytest-cov +#py.test +cd ../pytest-xdist +py.test + diff -r ebcecaa7d610a5ec2aa5b3367169bffc1b50415f -r bc620a10f932bc0d961b92f2c0b741e2ae1c8715 testing/test_mark.py --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -180,6 +180,7 @@ assert len(passed) == len(passed_result) assert list(passed) == list(passed_result) + class TestFunctional: def test_mark_per_function(self, testdir): @@ -362,7 +363,6 @@ deselected_tests = dlist[0].items assert len(deselected_tests) == 2 - def test_keywords_at_node_level(self, testdir): p = testdir.makepyfile(""" import pytest @@ -383,6 +383,30 @@ reprec = testdir.inline_run() reprec.assertoutcome(passed=1) + def test_keyword_added_for_session(self, testdir): + testdir.makeconftest(""" + import pytest + def pytest_collection_modifyitems(session): + session.add_marker("mark1") + session.add_marker(pytest.mark.mark2) + session.add_marker(pytest.mark.mark3) + pytest.raises(ValueError, lambda: + session.add_marker(10)) + """) + testdir.makepyfile(""" + def test_some(request): + assert "mark1" in request.keywords + assert "mark2" in request.keywords + assert "mark3" in request.keywords + assert 10 not in request.keywords + marker = request.node.get_marker("mark1") + assert marker.name == "mark1" + assert marker.args == () + assert marker.kwargs == {} + """) + reprec = testdir.inline_run("-m", "mark1") + reprec.assertoutcome(passed=1) + class TestKeywordSelection: def test_select_simple(self, testdir): file_test = testdir.makepyfile(""" Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Thu Oct 3 18:04:57 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 03 Oct 2013 16:04:57 -0000 Subject: [Pytest-commit] commit/pytest: 3 new changesets Message-ID: <20131003160457.21241.46363@app10.ash-private.bitbucket.org> 3 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/04096e391ef1/ Changeset: 04096e391ef1 User: hpk42 Date: 2013-10-03 16:47:55 Summary: always dupfile if os.dup is available Affected #: 2 files diff -r bc620a10f932bc0d961b92f2c0b741e2ae1c8715 -r 04096e391ef16aa7b7b492a2677b4cd0f3e0fc52 _pytest/terminal.py --- a/_pytest/terminal.py +++ b/_pytest/terminal.py @@ -37,7 +37,7 @@ # we try hard to make printing resilient against # later changes on FD level. (unless capturing is off/sys) stdout = sys.stdout - if config.option.capture == "fd" and hasattr(os, "dup"): + if hasattr(os, "dup"): try: newstdout = py.io.dupfile(stdout, buffering=1, encoding=stdout.encoding) diff -r bc620a10f932bc0d961b92f2c0b741e2ae1c8715 -r 04096e391ef16aa7b7b492a2677b4cd0f3e0fc52 testing/test_terminal.py --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -677,14 +677,6 @@ "*2 passed*" ]) -def test_nofd_manipulation_with_capture_disabled(testdir): - from _pytest.terminal import pytest_configure - config = testdir.parseconfig("--capture=no") - stdout = sys.stdout - pytest_configure(config) - reporter = config.pluginmanager.getplugin('terminalreporter') - assert reporter._tw._file == stdout - def test_tbstyle_native_setup_error(testdir): p = testdir.makepyfile(""" import pytest @@ -712,3 +704,14 @@ *==== hello ====* world """) + + at pytest.mark.xfail("not hasattr(os, 'dup')") +def test_fd_fixing(testdir): + testdir.makepyfile(""" + import os + os.close(1) + def test_fdclose(): + os.close(2) + """) + result = testdir.runpytest("-s") + result.stdout.fnmatch_lines("*1 pass*") https://bitbucket.org/hpk42/pytest/commits/ebceac32c5cd/ Changeset: ebceac32c5cd User: hpk42 Date: 2013-10-03 17:46:36 Summary: fix issue365 and depend on a newer py versions which uses colorama for coloring instead of its own ctypes hacks. Affected #: 3 files diff -r 04096e391ef16aa7b7b492a2677b4cd0f3e0fc52 -r ebceac32c5cdaec80fe3005af9618916068b4fa2 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,12 +1,15 @@ Changes between 2.4.1 and 2.4.2 ----------------------------------- +- on Windows require colorama and a newer py lib so that py.io.TerminalWriter() + now uses colorama instead of its own ctypes hacks. (fixes issue365) + - fix "-k" matching of tests where "repr" and "attr" and other names would cause wrong matches because of an internal implementation quirk (don't ask) which is now properly implemented. fixes issue345. - avoid "IOError: Bad Filedescriptor" on pytest shutdown by not closing - the internal dupped stdout (fix is slightly hand-wavy but work). + the internal dupped stdout (fix is slightly hand-wavy but works). - avoid tmpdir fixture to create too long filenames especially when parametrization is used (issue354) @@ -21,6 +24,7 @@ details of the node.keywords pseudo-dicts. Adapated docs. + Changes between 2.4.0 and 2.4.1 ----------------------------------- diff -r 04096e391ef16aa7b7b492a2677b4cd0f3e0fc52 -r ebceac32c5cdaec80fe3005af9618916068b4fa2 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.4.2.dev1' +__version__ = '2.4.2' diff -r 04096e391ef16aa7b7b492a2677b4cd0f3e0fc52 -r ebceac32c5cdaec80fe3005af9618916068b4fa2 setup.py --- a/setup.py +++ b/setup.py @@ -3,15 +3,17 @@ long_description = open("README.rst").read() def main(): - install_requires = ["py>=1.4.16"] + install_requires = ["py>=1.4.17.dev2"] if sys.version_info < (2,7): install_requires.append("argparse") + if sys.platform == "win32": + install_requires.append("colorama") setup( name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.4.2.dev1', + version='2.4.2', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], https://bitbucket.org/hpk42/pytest/commits/d5a0e8a77e0f/ Changeset: d5a0e8a77e0f User: hpk42 Date: 2013-10-03 18:02:54 Summary: fix argcomplete-test to use sys.argv[0] if it looks like a py.test executable Affected #: 1 file diff -r ebceac32c5cdaec80fe3005af9618916068b4fa2 -r d5a0e8a77e0f2ccfea495c44a80b5a1409a0e832 testing/test_parseopt.py --- a/testing/test_parseopt.py +++ b/testing/test_parseopt.py @@ -1,4 +1,6 @@ from __future__ import with_statement +import sys +import os import py, pytest from _pytest import config as parseopt from textwrap import dedent @@ -250,14 +252,16 @@ def test_argcomplete(testdir, monkeypatch): if not py.path.local.sysfind('bash'): pytest.skip("bash not available") - import os script = str(testdir.tmpdir.join("test_argcomplete")) + pytest_bin = sys.argv[0] + if "py.test" not in os.path.basename(pytest_bin): + pytest.skip("need to be run with py.test executable, not %s" %(pytest_bin,)) + with open(str(script), 'w') as fp: # redirect output from argcomplete to stdin and stderr is not trivial # http://stackoverflow.com/q/12589419/1307905 # so we use bash - fp.write('COMP_WORDBREAKS="$COMP_WORDBREAKS" $(which py.test) ' - '8>&1 9>&2') + fp.write('COMP_WORDBREAKS="$COMP_WORDBREAKS" %s 8>&1 9>&2' % pytest_bin) # alternative would be exteneded Testdir.{run(),_run(),popen()} to be able # to handle a keyword argument env that replaces os.environ in popen or # extends the copy, advantage: could not forget to restore Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Thu Oct 3 18:30:06 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 03 Oct 2013 16:30:06 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: fix python2.5 issues Message-ID: <20131003163006.30095.11744@app01.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/009eb952c0d1/ Changeset: 009eb952c0d1 User: hpk42 Date: 2013-10-03 18:25:03 Summary: fix python2.5 issues Affected #: 2 files diff -r d5a0e8a77e0f2ccfea495c44a80b5a1409a0e832 -r 009eb952c0d159faddf41113f4b211bd11b8aa3b _pytest/monkeypatch.py --- a/_pytest/monkeypatch.py +++ b/_pytest/monkeypatch.py @@ -1,7 +1,6 @@ """ monkeypatching and mocking functionality. """ -import os, sys, inspect -import pytest +import os, sys def pytest_funcarg__monkeypatch(request): """The returned ``monkeypatch`` funcarg provides these @@ -28,6 +27,7 @@ def derive_importpath(import_path): + import pytest if not isinstance(import_path, str) or "." not in import_path: raise TypeError("must be absolute import path string, not %r" % (import_path,)) @@ -82,6 +82,7 @@ which means it will raise). """ __tracebackhide__ = True + import inspect if value is notset: if not isinstance(target, str): diff -r d5a0e8a77e0f2ccfea495c44a80b5a1409a0e832 -r 009eb952c0d159faddf41113f4b211bd11b8aa3b _pytest/terminal.py --- a/_pytest/terminal.py +++ b/_pytest/terminal.py @@ -37,11 +37,11 @@ # we try hard to make printing resilient against # later changes on FD level. (unless capturing is off/sys) stdout = sys.stdout - if hasattr(os, "dup"): + if hasattr(os, "dup") and hasattr(stdout, "fileno"): try: newstdout = py.io.dupfile(stdout, buffering=1, encoding=stdout.encoding) - except ValueError: + except (AttributeError, ValueError): pass else: assert stdout.encoding == newstdout.encoding 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 Oct 4 12:20:08 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Fri, 04 Oct 2013 10:20:08 -0000 Subject: [Pytest-commit] commit/pytest: 3 new changesets Message-ID: <20131004102008.21816.55577@app05.ash-private.bitbucket.org> 3 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/c49f06ea5122/ Changeset: c49f06ea5122 User: hpk42 Date: 2013-10-03 18:53:40 Summary: remove fd-fixing attempt at startup of pytest. It's not clear it's actually needed and it's not nice to still do FD-dupping when "-s" is specified. Affected #: 3 files diff -r 009eb952c0d159faddf41113f4b211bd11b8aa3b -r c49f06ea512202da18c2568f815da5fb3902084d CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -25,6 +25,10 @@ docs. +- remove attempt to "dup" stdout at startup. + the normal capturing should catch enough possibilities + of tests messing up standard FDs. + Changes between 2.4.0 and 2.4.1 ----------------------------------- diff -r 009eb952c0d159faddf41113f4b211bd11b8aa3b -r c49f06ea512202da18c2568f815da5fb3902084d _pytest/terminal.py --- a/_pytest/terminal.py +++ b/_pytest/terminal.py @@ -33,25 +33,7 @@ def pytest_configure(config): config.option.verbose -= config.option.quiet - - # we try hard to make printing resilient against - # later changes on FD level. (unless capturing is off/sys) - stdout = sys.stdout - if hasattr(os, "dup") and hasattr(stdout, "fileno"): - try: - newstdout = py.io.dupfile(stdout, buffering=1, - encoding=stdout.encoding) - except (AttributeError, ValueError): - pass - else: - assert stdout.encoding == newstdout.encoding - stdout = newstdout - #we don't close on shutdown because this can - #cause logging to fail on a second close - #(not really clear to me how it happens exactly, though) - #config.pluginmanager.add_shutdown(fin) - - reporter = TerminalReporter(config, stdout) + reporter = TerminalReporter(config, sys.stdout) config.pluginmanager.register(reporter, 'terminalreporter') if config.option.debug or config.option.traceconfig: def mywriter(tags, args): diff -r 009eb952c0d159faddf41113f4b211bd11b8aa3b -r c49f06ea512202da18c2568f815da5fb3902084d testing/test_terminal.py --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -704,14 +704,3 @@ *==== hello ====* world """) - - at pytest.mark.xfail("not hasattr(os, 'dup')") -def test_fd_fixing(testdir): - testdir.makepyfile(""" - import os - os.close(1) - def test_fdclose(): - os.close(2) - """) - result = testdir.runpytest("-s") - result.stdout.fnmatch_lines("*1 pass*") https://bitbucket.org/hpk42/pytest/commits/266b3bcad027/ Changeset: 266b3bcad027 User: hpk42 Date: 2013-10-03 19:09:18 Summary: bump version to 2.4.2, regen docs Affected #: 22 files diff -r c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -8,9 +8,6 @@ cause wrong matches because of an internal implementation quirk (don't ask) which is now properly implemented. fixes issue345. -- avoid "IOError: Bad Filedescriptor" on pytest shutdown by not closing - the internal dupped stdout (fix is slightly hand-wavy but works). - - avoid tmpdir fixture to create too long filenames especially when parametrization is used (issue354) @@ -25,7 +22,7 @@ docs. -- remove attempt to "dup" stdout at startup. +- remove attempt to "dup" stdout at startup as it's icky. the normal capturing should catch enough possibilities of tests messing up standard FDs. diff -r c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 doc/en/announce/index.txt --- a/doc/en/announce/index.txt +++ b/doc/en/announce/index.txt @@ -5,6 +5,8 @@ .. toctree:: :maxdepth: 2 + release-2.4.2 + release-2.4.1 release-2.4.0 release-2.3.5 release-2.3.4 diff -r c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 doc/en/announce/release-2.4.2.txt --- /dev/null +++ b/doc/en/announce/release-2.4.2.txt @@ -0,0 +1,32 @@ +pytest-2.4.2: colorama on windows, plugin/tmpdir fixes +=========================================================================== + +pytest-2.4.2 is another bug-fixing release: + +- fix "-k" matching of tests where "repr" and "attr" and other names would + cause wrong matches because of an internal implementation quirk + (don't ask) which is now properly implemented. fixes issue345. + +- avoid tmpdir fixture to create too long filenames especially + when parametrization is used (issue354) + +- fix pytest-pep8 and pytest-flakes / pytest interactions + (collection names in mark plugin was assuming an item always + has a function which is not true for those plugins etc.) + Thanks Andi Zeidler. + +- introduce node.get_marker/node.add_marker API for plugins + like pytest-pep8 and pytest-flakes to avoid the messy + details of the node.keywords pseudo-dicts. Adapated + docs. + +- remove attempt to "dup" stdout at startup as it's icky. + the normal capturing should catch enough possibilities + of tests messing up standard FDs. + +as usual, docs at http://pytest.org and upgrades via:: + + pip install -U pytest + +have fun, +holger krekel diff -r c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 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.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 1 items test_assert1.py F @@ -116,7 +116,7 @@ $ py.test test_assert2.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 1 items test_assert2.py F @@ -191,6 +191,7 @@ E vals: 1 != 2 test_foocompare.py:8: AssertionError + 1 failed in 0.01 seconds .. _assert-details: .. _`assert introspection`: diff -r c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 doc/en/attic_fixtures.txt --- a/doc/en/attic_fixtures.txt +++ b/doc/en/attic_fixtures.txt @@ -129,6 +129,7 @@ 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. @@ -177,6 +178,7 @@ 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 diff -r c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 doc/en/builtin.txt --- a/doc/en/builtin.txt +++ b/doc/en/builtin.txt @@ -120,3 +120,4 @@ path object. + in 0.00 seconds diff -r c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 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.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 2 items test_module.py .F @@ -78,7 +78,7 @@ test_module.py:9: AssertionError ----------------------------- Captured stdout ------------------------------ - setting up + setting up ==================== 1 failed, 1 passed in 0.01 seconds ==================== Accessing captured output from a test function diff -r c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 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.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 1 items mymodule.py . - ========================= 1 passed in 0.02 seconds ========================= + ========================= 1 passed in 0.01 seconds ========================= It is possible to use fixtures using the ``getfixture`` helper:: diff -r c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 doc/en/example/markers.txt --- a/doc/en/example/markers.txt +++ b/doc/en/example/markers.txt @@ -28,7 +28,7 @@ $ py.test -v -m webtest =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 3 items test_server.py:3: test_send_http PASSED @@ -40,7 +40,7 @@ $ py.test -v -m "not webtest" =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 3 items test_server.py:6: test_something_quick PASSED @@ -61,7 +61,7 @@ $ py.test -v -k http # running with the above defined example module =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 3 items test_server.py:3: test_send_http PASSED @@ -73,7 +73,7 @@ $ py.test -k "not send_http" -v =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 3 items test_server.py:6: test_something_quick PASSED @@ -86,7 +86,7 @@ $ py.test -k "http or quick" -v =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 3 items test_server.py:3: test_send_http PASSED @@ -255,7 +255,7 @@ $ py.test -E stage2 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 1 items test_someenv.py s @@ -266,7 +266,7 @@ $ py.test -E stage1 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 1 items test_someenv.py . @@ -331,6 +331,7 @@ glob args=('class',) kwargs={'x': 2} glob args=('module',) kwargs={'x': 1} . + 1 passed in 0.01 seconds marking platform specific tests with pytest -------------------------------------------------------------- @@ -383,12 +384,12 @@ $ py.test -rs # this option reports skip reasons =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 4 items test_plat.py s.s. ========================= short test summary info ========================== - SKIP [2] /tmp/doc-exec-273/conftest.py:12: cannot run on platform linux2 + SKIP [2] /tmp/doc-exec-598/conftest.py:12: cannot run on platform linux2 =================== 2 passed, 2 skipped in 0.01 seconds ==================== @@ -396,7 +397,7 @@ $ py.test -m linux2 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 4 items test_plat.py . @@ -447,7 +448,7 @@ $ py.test -m interface --tb=short =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 4 items test_module.py FF @@ -468,7 +469,7 @@ $ py.test -m "interface or event" --tb=short =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 4 items test_module.py FFF diff -r c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 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.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.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.05 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 linux2 -- Python 2.7.3 -- pytest-2.3.5 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 2 items test_simple.yml:1: 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 linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 2 items - ============================= in 0.05 seconds ============================= + ============================= in 0.03 seconds ============================= diff -r c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 doc/en/example/parametrize.txt --- a/doc/en/example/parametrize.txt +++ b/doc/en/example/parametrize.txt @@ -46,6 +46,7 @@ $ py.test -q test_compute.py .. + 2 passed in 0.01 seconds We run only two computations, so we see two dots. let's run the full monty:: @@ -62,6 +63,7 @@ E assert 4 < 4 test_compute.py:3: AssertionError + 1 failed, 4 passed in 0.01 seconds As expected when running the full range of ``param1`` values we'll get an error on the last one. @@ -104,7 +106,7 @@ $ py.test test_scenarios.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 4 items test_scenarios.py .... @@ -116,7 +118,7 @@ $ py.test --collect-only test_scenarios.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 4 items @@ -180,7 +182,7 @@ $ py.test test_backends.py --collect-only =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 2 items @@ -195,7 +197,7 @@ ================================= FAILURES ================================= _________________________ test_db_initialized[d2] __________________________ - db = + db = def test_db_initialized(db): # a dummy test @@ -204,6 +206,7 @@ E Failed: deliberately failing for demo purposes test_backends.py:6: Failed + 1 failed, 1 passed in 0.01 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. @@ -250,13 +253,14 @@ ================================= FAILURES ================================= ________________________ TestClass.test_equals[1-2] ________________________ - self = , a = 1, b = 2 + self = , a = 1, b = 2 def test_equals(self, a, b): > assert a == b E assert 1 == 2 test_parametrize.py:18: AssertionError + 1 failed, 2 passed in 0.02 seconds Indirect parametrization with multiple fixtures -------------------------------------------------------------- @@ -278,6 +282,7 @@ ............sss............sss............sss............ssssssssssssssssss ========================= short test summary info ========================== SKIP [27] /home/hpk/p/pytest/doc/en/example/multipython.py:21: 'python2.8' not found + 48 passed, 27 skipped in 1.37 seconds Indirect parametrization of optional implementations/imports -------------------------------------------------------------------- @@ -324,12 +329,12 @@ $ py.test -rs test_module.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 2 items - test_module.py .s + test_module.py s. ========================= short test summary info ========================== - SKIP [1] /tmp/doc-exec-275/conftest.py:10: could not import 'opt2' + SKIP [1] /tmp/doc-exec-600/conftest.py:10: could not import 'opt2' =================== 1 passed, 1 skipped in 0.01 seconds ==================== diff -r c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 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.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 2 items @@ -82,7 +82,7 @@ . $ py.test --collect-only pythoncollection.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 3 items @@ -135,7 +135,7 @@ $ py.test --collect-only =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 1 items diff -r c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 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 linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.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 = () - E + and 43 = () + E + where 42 = () + E + and 43 = () failure_demo.py:28: AssertionError ____________________ TestFailing.test_simple_multiline _____________________ - self = + self = def test_simple_multiline(self): otherfunc_multi( @@ -66,19 +66,19 @@ failure_demo.py:11: AssertionError ___________________________ TestFailing.test_not ___________________________ - self = + self = def test_not(self): def f(): return 42 > assert not f() E assert not 42 - E + where 42 = () + E + where 42 = () failure_demo.py:38: AssertionError _________________ TestSpecialisedExplanations.test_eq_text _________________ - self = + self = def test_eq_text(self): > assert 'spam' == 'eggs' @@ -89,7 +89,7 @@ failure_demo.py:42: AssertionError _____________ TestSpecialisedExplanations.test_eq_similar_text _____________ - self = + self = def test_eq_similar_text(self): > assert 'foo 1 bar' == 'foo 2 bar' @@ -102,7 +102,7 @@ failure_demo.py:45: AssertionError ____________ TestSpecialisedExplanations.test_eq_multiline_text ____________ - self = + self = def test_eq_multiline_text(self): > assert 'foo\nspam\nbar' == 'foo\neggs\nbar' @@ -115,7 +115,7 @@ failure_demo.py:48: AssertionError ______________ TestSpecialisedExplanations.test_eq_long_text _______________ - self = + self = def test_eq_long_text(self): a = '1'*100 + 'a' + '2'*100 @@ -132,7 +132,7 @@ failure_demo.py:53: AssertionError _________ TestSpecialisedExplanations.test_eq_long_text_multiline __________ - self = + self = def test_eq_long_text_multiline(self): a = '1\n'*100 + 'a' + '2\n'*100 @@ -156,7 +156,7 @@ failure_demo.py:58: AssertionError _________________ TestSpecialisedExplanations.test_eq_list _________________ - self = + self = def test_eq_list(self): > assert [0, 1, 2] == [0, 1, 3] @@ -166,7 +166,7 @@ failure_demo.py:61: AssertionError ______________ TestSpecialisedExplanations.test_eq_list_long _______________ - self = + self = def test_eq_list_long(self): a = [0]*100 + [1] + [3]*100 @@ -178,12 +178,12 @@ 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} E assert {'a': 0, 'b': 1, 'c': 0} == {'a': 0, 'b': 2, 'd': 0} - E Hiding 1 identical items, use -v to show + E Omitting 1 identical items, use -v to show E Differing items: E {'b': 1} != {'b': 2} E Left contains more items: @@ -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 = .b + E + where 1 = .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 = .b - E + where = () + E + where 1 = .b + E + where = () failure_demo.py:107: AssertionError __________________________ test_attribute_failure __________________________ @@ -319,7 +319,7 @@ failure_demo.py:116: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ - self = + self = 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 = .b - E + where = () - E + and 2 = .b - E + where = () + E + where 1 = .b + E + where = () + E + and 2 = .b + E + where = () failure_demo.py:124: AssertionError __________________________ TestRaises.test_raises __________________________ - self = + self = def test_raises(self): s = 'qwe' @@ -355,10 +355,10 @@ > int(s) E ValueError: invalid literal for int() with base 10: 'qwe' - <0-codegen /home/hpk/p/pytest/.tox/regen/local/lib/python2.7/site-packages/_pytest/python.py:858>:1: ValueError + <0-codegen /home/hpk/p/pytest/.tox/regen/local/lib/python2.7/site-packages/_pytest/python.py:905>: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(): @@ -455,7 +455,7 @@ failure_demo.py:5: AssertionError ___________________ TestMoreErrors.test_z1_unpack_error ____________________ - self = + self = def test_z1_unpack_error(self): l = [] @@ -465,7 +465,7 @@ failure_demo.py:179: ValueError ____________________ TestMoreErrors.test_z2_type_error _____________________ - self = + self = def test_z2_type_error(self): l = 3 @@ -475,19 +475,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(): @@ -495,15 +495,15 @@ def g(): return "456" > assert f().startswith(g()) - E assert ('456') - E + where = '123'.startswith - E + where '123' = () - E + and '456' = () + E assert ('456') + E + where = '123'.startswith + E + where '123' = () + E + and '456' = () failure_demo.py:195: AssertionError _____________________ TestMoreErrors.test_global_func ______________________ - self = + self = def test_global_func(self): > assert isinstance(globf(42), float) @@ -513,18 +513,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 @@ -534,7 +534,7 @@ failure_demo.py:205: AssertionError _____________________ TestMoreErrors.test_try_finally ______________________ - self = + self = def test_try_finally(self): x = 1 @@ -543,4 +543,4 @@ E assert 1 == 0 failure_demo.py:210: AssertionError - ======================== 39 failed in 0.21 seconds ========================= + ======================== 39 failed in 0.26 seconds ========================= diff -r c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 doc/en/example/simple.txt --- a/doc/en/example/simple.txt +++ b/doc/en/example/simple.txt @@ -55,6 +55,7 @@ test_sample.py:6: AssertionError ----------------------------- Captured stdout ------------------------------ first + 1 failed in 0.01 seconds And now with supplying a command line option:: @@ -76,6 +77,7 @@ test_sample.py:6: AssertionError ----------------------------- Captured stdout ------------------------------ second + 1 failed in 0.01 seconds You can see that the command line option arrived in our test. This completes the basic pattern. However, one often rather wants to process @@ -106,7 +108,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 0 items ============================= in 0.00 seconds ============================= @@ -150,12 +152,12 @@ $ py.test -rs # "-rs" means report details on the little 's' =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 2 items test_module.py .s ========================= short test summary info ========================== - SKIP [1] /tmp/doc-exec-278/conftest.py:9: need --runslow option to run + SKIP [1] /tmp/doc-exec-603/conftest.py:9: need --runslow option to run =================== 1 passed, 1 skipped in 0.01 seconds ==================== @@ -163,7 +165,7 @@ $ py.test --runslow =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 2 items test_module.py .. @@ -206,6 +208,7 @@ E Failed: not configured: 42 test_checkconfig.py:8: Failed + 1 failed in 0.01 seconds Detect if running from within a py.test run -------------------------------------------------------------- @@ -253,7 +256,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 project deps: mylib-1.1 collected 0 items @@ -276,7 +279,7 @@ $ py.test -v =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 -- /home/hpk/p/pytest/.tox/regen/bin/python info1: did you know that ... did you? collecting ... collected 0 items @@ -287,7 +290,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 0 items ============================= in 0.00 seconds ============================= @@ -319,7 +322,7 @@ $ py.test --durations=3 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 3 items test_some_are_slow.py ... @@ -380,7 +383,7 @@ $ py.test -rx =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 4 items test_step.py .Fx. @@ -388,7 +391,7 @@ ================================= FAILURES ================================= ____________________ TestUserHandling.test_modification ____________________ - self = + self = def test_modification(self): > assert 0 @@ -398,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". @@ -450,7 +453,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 7 items test_step.py .Fx. @@ -460,17 +463,17 @@ ================================== ERRORS ================================== _______________________ ERROR at setup of test_root ________________________ - file /tmp/doc-exec-278/b/test_error.py, line 1 + file /tmp/doc-exec-603/b/test_error.py, line 1 def test_root(db): # no db here, will error out fixture 'db' not found available fixtures: pytestconfig, recwarn, monkeypatch, capfd, capsys, tmpdir use 'py.test --fixtures [testpath]' for help on them. - /tmp/doc-exec-278/b/test_error.py:1 + /tmp/doc-exec-603/b/test_error.py:1 ================================= FAILURES ================================= ____________________ TestUserHandling.test_modification ____________________ - self = + self = def test_modification(self): > assert 0 @@ -479,20 +482,20 @@ 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 ========== @@ -550,7 +553,7 @@ $ py.test test_module.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 2 items test_module.py FF @@ -558,7 +561,7 @@ ================================= FAILURES ================================= ________________________________ test_fail1 ________________________________ - tmpdir = local('/tmp/pytest-326/test_fail10') + tmpdir = local('/tmp/pytest-190/test_fail10') def test_fail1(tmpdir): > assert 0 @@ -572,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-326/test_fail10) + test_module.py::test_fail1 (/tmp/pytest-190/test_fail10) test_module.py::test_fail2 Making test result information available in fixtures @@ -640,10 +643,12 @@ $ py.test -s test_module.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 3 items - test_module.py EFF + test_module.py Esetting up a test failed! test_module.py::test_setup_fails + Fexecuting test failed test_module.py::test_call_fails + F ================================== ERRORS ================================== ____________________ ERROR at setup of test_setup_fails ____________________ @@ -671,9 +676,7 @@ E assert 0 test_module.py:15: AssertionError - ==================== 2 failed, 1 error in 0.01 seconds ===================== - setting up a test failed! test_module.py::test_setup_fails - executing test failed test_module.py::test_call_fails + ==================== 2 failed, 1 error in 0.02 seconds ===================== You'll see that the fixture finalizers could use the precise reporting information. diff -r c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 doc/en/example/special.txt --- a/doc/en/example/special.txt +++ b/doc/en/example/special.txt @@ -61,12 +61,13 @@ If you run this without output capturing:: $ 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 + .test_method1 called + .test other + .test_unit1 method called + . + 4 passed in 0.02 seconds diff -r c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 doc/en/fixture.txt --- a/doc/en/fixture.txt +++ b/doc/en/fixture.txt @@ -76,8 +76,7 @@ $ py.test test_smtpsimple.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.0.dev12 - plugins: xdist, pep8, cov, cache, capturelog, instafail + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 1 items test_smtpsimple.py F @@ -85,7 +84,7 @@ ================================= FAILURES ================================= ________________________________ test_ehlo _________________________________ - smtp = + smtp = def test_ehlo(smtp): response, msg = smtp.ehlo() @@ -95,7 +94,7 @@ E assert 0 test_smtpsimple.py:12: AssertionError - ========================= 1 failed in 0.17 seconds ========================= + ========================= 1 failed in 0.18 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 @@ -195,8 +194,7 @@ $ py.test test_module.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.0.dev12 - plugins: xdist, pep8, cov, cache, capturelog, instafail + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 2 items test_module.py FF @@ -204,7 +202,7 @@ ================================= FAILURES ================================= ________________________________ test_ehlo _________________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -216,7 +214,7 @@ test_module.py:6: AssertionError ________________________________ test_noop _________________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -225,7 +223,7 @@ E assert 0 test_module.py:11: AssertionError - ========================= 2 failed in 0.18 seconds ========================= + ========================= 2 failed in 0.16 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 @@ -271,8 +269,9 @@ Let's execute it:: $ py.test -s -q --tb=no - FF - 2 failed in 0.20 seconds + FFteardown smtp + + 2 failed in 0.15 seconds We see that the ``smtp`` instance is finalized after the two tests finished execution. Note that if we decorated our fixture @@ -313,7 +312,7 @@ $ py.test -s -q --tb=no FF - 2 failed in 0.18 seconds + 2 failed in 0.16 seconds Let's quickly create another test module that actually sets the server URL in its module namespace:: @@ -380,7 +379,7 @@ ================================= FAILURES ================================= __________________________ test_ehlo[merlinux.eu] __________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -392,7 +391,7 @@ test_module.py:6: AssertionError __________________________ test_noop[merlinux.eu] __________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -403,7 +402,7 @@ test_module.py:11: AssertionError ________________________ test_ehlo[mail.python.org] ________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -414,7 +413,7 @@ test_module.py:5: AssertionError ________________________ test_noop[mail.python.org] ________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -423,7 +422,7 @@ E assert 0 test_module.py:11: AssertionError - 4 failed in 6.47 seconds + 4 failed in 6.32 seconds We see that our two test functions each ran twice, against the different ``smtp`` instances. Note also, that with the ``mail.python.org`` @@ -463,15 +462,13 @@ $ py.test -v test_appsetup.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.0.dev12 -- /home/hpk/venv/0/bin/python - cachedir: /tmp/doc-exec-127/.cache - plugins: xdist, pep8, cov, cache, capturelog, instafail + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 2 items test_appsetup.py:12: test_smtp_exists[mail.python.org] PASSED test_appsetup.py:12: test_smtp_exists[merlinux.eu] PASSED - ========================= 2 passed in 6.07 seconds ========================= + ========================= 2 passed in 5.75 seconds ========================= Due to the parametrization of ``smtp`` the test will run twice with two different ``App`` instances and respective smtp servers. There is no @@ -529,9 +526,7 @@ $ py.test -v -s test_module.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.0.dev12 -- /home/hpk/venv/0/bin/python - cachedir: /tmp/doc-exec-127/.cache - plugins: xdist, pep8, cov, cache, capturelog, instafail + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 8 items test_module.py:15: test_0[1] test0 1 @@ -553,7 +548,7 @@ test_module.py:19: test_2[2-mod2] test2 2 mod2 PASSED - ========================= 8 passed in 0.02 seconds ========================= + ========================= 8 passed in 0.01 seconds ========================= You can see that the parametrized module-scoped ``modarg`` resource caused an ordering of test execution that lead to the fewest possible "active" resources. The finalizer for the ``mod1`` parametrized resource was executed @@ -609,7 +604,7 @@ $ py.test -q .. - 2 passed in 0.02 seconds + 2 passed in 0.01 seconds You can specify multiple fixtures like this:: @@ -680,7 +675,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 c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 doc/en/getting-started.txt --- a/doc/en/getting-started.txt +++ b/doc/en/getting-started.txt @@ -23,7 +23,7 @@ To check your installation has installed the correct version:: $ py.test --version - This is py.test version 2.3.5, imported from /home/hpk/p/pytest/.tox/regen/local/lib/python2.7/site-packages/pytest.py + This is py.test version 2.4.2, imported from /home/hpk/p/pytest/.tox/regen/local/lib/python2.7/site-packages/pytest.pyc If you get an error checkout :ref:`installation issues`. @@ -45,7 +45,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 1 items test_sample.py F @@ -93,6 +93,7 @@ $ py.test -q test_sysexit.py . + 1 passed in 0.01 seconds .. todo:: For further ways to assert exceptions see the `raises` @@ -122,7 +123,7 @@ ================================= FAILURES ================================= ____________________________ TestClass.test_two ____________________________ - self = + self = def test_two(self): x = "hello" @@ -130,6 +131,7 @@ E assert hasattr('hello', 'check') test_class.py:8: AssertionError + 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 @@ -157,7 +159,7 @@ ================================= FAILURES ================================= _____________________________ test_needsfiles ______________________________ - tmpdir = local('/tmp/pytest-322/test_needsfiles0') + tmpdir = local('/tmp/pytest-186/test_needsfiles0') def test_needsfiles(tmpdir): print tmpdir @@ -166,7 +168,8 @@ test_tmpdir.py:3: AssertionError ----------------------------- Captured stdout ------------------------------ - /tmp/pytest-322/test_needsfiles0 + /tmp/pytest-186/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 c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 doc/en/parametrize.txt --- a/doc/en/parametrize.txt +++ b/doc/en/parametrize.txt @@ -52,15 +52,14 @@ them in turn:: $ py.test - ============================= test session starts ============================== - platform linux2 -- Python 2.7.3 -- pytest-2.4.0.dev3 - plugins: xdist, cache, cli, pep8, xprocess, cov, capturelog, bdd-splinter, rerunfailures, instafail, localserver + =========================== test session starts ============================ + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 3 items test_expectation.py ..F - =================================== FAILURES =================================== - ______________________________ test_eval[6*9-42] _______________________________ + ================================= FAILURES ================================= + ____________________________ test_eval[6*9-42] _____________________________ input = '6*9', expected = 42 @@ -75,7 +74,7 @@ E + where 54 = eval('6*9') test_expectation.py:8: AssertionError - ====================== 1 failed, 2 passed in 0.02 seconds ====================== + ==================== 1 failed, 2 passed in 0.01 seconds ==================== As designed in this example, only one pair of input/output values fails the simple test function. And as usual with test function arguments, @@ -100,14 +99,13 @@ Let's run this:: $ py.test - ============================= test session starts ============================== - platform linux2 -- Python 2.7.3 -- pytest-2.4.0.dev3 - plugins: xdist, cache, cli, pep8, xprocess, cov, capturelog, bdd-splinter, rerunfailures, instafail, localserver + =========================== test session starts ============================ + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 3 items test_expectation.py ..x - ===================== 2 passed, 1 xfailed in 0.02 seconds ====================== + =================== 2 passed, 1 xfailed in 0.01 seconds ==================== The one parameter set which caused a failure previously now shows up as an "xfailed (expected to fail)" test. @@ -159,22 +157,24 @@ $ py.test -q --stringinput="hello" --stringinput="world" test_strings.py .. + 2 passed in 0.01 seconds Let's also run with a stringinput that will lead to a failing test:: $ py.test -q --stringinput="!" test_strings.py F - =================================== FAILURES =================================== - _____________________________ test_valid_string[!] _____________________________ + ================================= FAILURES ================================= + ___________________________ test_valid_string[!] ___________________________ stringinput = '!' 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 As expected our test function fails. @@ -184,8 +184,9 @@ $ py.test -q -rs test_strings.py s - =========================== short test summary info ============================ - SKIP [1] /home/hpk/p/pytest/_pytest/python.py:999: got empty parameter set, function test_valid_string at /tmp/doc-exec-2/test_strings.py:1 + ========================= short test summary info ========================== + SKIP [1] /home/hpk/p/pytest/.tox/regen/local/lib/python2.7/site-packages/_pytest/python.py:1024: got empty parameter set, function test_valid_string at /tmp/doc-exec-561/test_strings.py:1 + 1 skipped in 0.01 seconds For further examples, you might want to look at :ref:`more parametrization examples `. diff -r c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 doc/en/skipping.txt --- a/doc/en/skipping.txt +++ b/doc/en/skipping.txt @@ -158,14 +158,14 @@ example $ py.test -rx xfail_demo.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 6 items - + xfail_demo.py xxxxxx ========================= short test summary info ========================== XFAIL xfail_demo.py::test_hello XFAIL xfail_demo.py::test_hello2 - reason: [NOTRUN] + reason: [NOTRUN] XFAIL xfail_demo.py::test_hello3 condition: hasattr(os, 'sep') XFAIL xfail_demo.py::test_hello4 @@ -174,7 +174,7 @@ condition: pytest.__version__[0] != "17" XFAIL xfail_demo.py::test_hello6 reason: reason - + ======================== 6 xfailed in 0.05 seconds ========================= .. _`skip/xfail with parametrize`: diff -r c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 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 linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.2 collected 1 items test_tmpdir.py F @@ -37,7 +37,7 @@ ================================= FAILURES ================================= _____________________________ test_create_file _____________________________ - tmpdir = local('/tmp/pytest-323/test_create_file0') + tmpdir = local('/tmp/pytest-187/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 c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 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 linux2 -- Python 2.7.3 -- pytest-2.3.5 + platform linux2 -- Python 2.7.3 -- pytest-2.4.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: + E AssertionError: 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: + E AssertionError: test_unittest_db.py:12: AssertionError ========================= 2 failed in 0.02 seconds ========================= @@ -160,6 +160,7 @@ $ py.test -q test_unittest_cleandir.py . + 1 passed in 0.02 seconds ... gives us one passed test because the ``initdir`` fixture function was executed ahead of the ``test_method``. diff -r c49f06ea512202da18c2568f815da5fb3902084d -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 doc/en/usage.txt --- a/doc/en/usage.txt +++ b/doc/en/usage.txt @@ -188,7 +188,7 @@ hook was invoked:: $ python myinvoke.py + *** test run reporting finishing - *** test run reporting finishing .. include:: links.inc https://bitbucket.org/hpk42/pytest/commits/0fed53542881/ Changeset: 0fed53542881 User: hpk42 Date: 2013-10-04 11:36:45 Summary: add pluginmanager.do_configure(config) as a link to config.do_configure() for plugin-compatibility add some more plugins to plugin-test.sh Affected #: 4 files diff -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 -r 0fed535428811de1a080cae08a1b0ef2c4ec203a CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -21,11 +21,13 @@ details of the node.keywords pseudo-dicts. Adapated docs. - - remove attempt to "dup" stdout at startup as it's icky. the normal capturing should catch enough possibilities of tests messing up standard FDs. +- add pluginmanager.do_configure(config) as a link to + config.do_configure() for plugin-compatibility + Changes between 2.4.0 and 2.4.1 ----------------------------------- diff -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 -r 0fed535428811de1a080cae08a1b0ef2c4ec203a _pytest/core.py --- a/_pytest/core.py +++ b/_pytest/core.py @@ -76,6 +76,10 @@ self._shutdown = [] self.hook = HookRelay(hookspecs or [], pm=self) + def do_configure(self, config): + # backward compatibility + config.do_configure() + def set_register_callback(self, callback): assert not hasattr(self, "_registercallback") self._registercallback = callback diff -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 -r 0fed535428811de1a080cae08a1b0ef2c4ec203a plugin-test.sh --- a/plugin-test.sh +++ b/plugin-test.sh @@ -9,8 +9,12 @@ py.test cd ../pytest-cache py.test +cd ../pytest-xprocess +py.test #cd ../pytest-cov #py.test +cd ../pytest-capturelog +py.test cd ../pytest-xdist py.test diff -r 266b3bcad0277f0e069bc6fc8273efd85eb05ac2 -r 0fed535428811de1a080cae08a1b0ef2c4ec203a setup.py --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ long_description = open("README.rst").read() def main(): - install_requires = ["py>=1.4.17.dev2"] + install_requires = ["py>=1.4.17"] if sys.version_info < (2,7): 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 commits-noreply at bitbucket.org Fri Oct 4 12:35:01 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Fri, 04 Oct 2013 10:35:01 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: finalize release announcement, changelog Message-ID: <20131004103501.25788.76271@app02.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/8f52541bc0c3/ Changeset: 8f52541bc0c3 User: hpk42 Date: 2013-10-04 12:34:47 Summary: finalize release announcement, changelog Affected #: 2 files diff -r 0fed535428811de1a080cae08a1b0ef2c4ec203a -r 8f52541bc0c32a1b7286bd7bcc853e8f3fd32508 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,7 @@ - on Windows require colorama and a newer py lib so that py.io.TerminalWriter() now uses colorama instead of its own ctypes hacks. (fixes issue365) + thanks Paul Moore for bringing it up. - fix "-k" matching of tests where "repr" and "attr" and other names would cause wrong matches because of an internal implementation quirk diff -r 0fed535428811de1a080cae08a1b0ef2c4ec203a -r 8f52541bc0c32a1b7286bd7bcc853e8f3fd32508 doc/en/announce/release-2.4.2.txt --- a/doc/en/announce/release-2.4.2.txt +++ b/doc/en/announce/release-2.4.2.txt @@ -3,6 +3,10 @@ pytest-2.4.2 is another bug-fixing release: +- on Windows require colorama and a newer py lib so that py.io.TerminalWriter() + now uses colorama instead of its own ctypes hacks. (fixes issue365) + thanks Paul Moore for bringing it up. + - fix "-k" matching of tests where "repr" and "attr" and other names would cause wrong matches because of an internal implementation quirk (don't ask) which is now properly implemented. fixes issue345. @@ -24,6 +28,9 @@ the normal capturing should catch enough possibilities of tests messing up standard FDs. +- add pluginmanager.do_configure(config) as a link to + config.do_configure() for plugin-compatibility + as usual, docs at http://pytest.org and upgrades via:: pip install -U pytest Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From notifications at travis-ci.org Fri Oct 4 12:29:26 2013 From: notifications at travis-ci.org (Travis CI) Date: Fri, 04 Oct 2013 10:29:26 +0000 Subject: [Pytest-commit] [Broken] hpk42/pytest#45 (master - b94f69e) Message-ID: <524e98862f9b8_229803209ca@52948db8-18d9-44f3-905d-a7416d395125.mail> Build Update for hpk42/pytest ------------------------------------- Build: #45 Status: Broken Duration: 30 seconds Commit: b94f69e (master) Author: holger krekel Message: add pluginmanager.do_configure(config) as a link to config.do_configure() for plugin-compatibility add some more plugins to plugin-test.sh View the changeset: https://github.com/hpk42/pytest/compare/bfe9fe355632...b94f69ec5129 View the full build log and details: https://travis-ci.org/hpk42/pytest/builds/12128127 -- You can configure recipients for build notifications in your .travis.yml file. See http://about.travis-ci.org/docs/user/build-configuration -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits-noreply at bitbucket.org Fri Oct 4 14:35:48 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Fri, 04 Oct 2013 12:35:48 -0000 Subject: [Pytest-commit] commit/pytest: 2 new changesets Message-ID: <20131004123548.10937.63868@app02.ash-private.bitbucket.org> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/8d051f89184b/ Changeset: 8d051f89184b User: hpk42 Date: 2013-10-04 13:59:44 Summary: bump version of docs Affected #: 1 file diff -r 8f52541bc0c32a1b7286bd7bcc853e8f3fd32508 -r 8d051f89184bfa3033f5e59819dff9f32a612941 doc/en/conf.py --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -17,8 +17,8 @@ # # The full version, including alpha/beta/rc tags. # The short X.Y version. -version = "2.4.1" -release = "2.4.1" +version = "2.4.2" +release = "2.4.2" import sys, os https://bitbucket.org/hpk42/pytest/commits/e669246287ee/ Changeset: e669246287ee User: hpk42 Date: 2013-10-04 14:33:12 Summary: Added tag 2.4.2 for changeset 8d051f89184b Affected #: 1 file diff -r 8d051f89184bfa3033f5e59819dff9f32a612941 -r e669246287ee862e662587c29341174418a987c4 .hgtags --- a/.hgtags +++ b/.hgtags @@ -62,3 +62,4 @@ 0000000000000000000000000000000000000000 1.4.14 af860de70cc3f157ac34ca1d4bf557a057bff775 2.4.0 8828c924acae0b4cad2e2cb92943d51da7cb744a 2.4.1 +8d051f89184bfa3033f5e59819dff9f32a612941 2.4.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 notifications at travis-ci.org Sat Oct 5 08:19:12 2013 From: notifications at travis-ci.org (Travis CI) Date: Sat, 05 Oct 2013 06:19:12 +0000 Subject: [Pytest-commit] [Fixed] hpk42/pytest#46 (master - e2bee53) Message-ID: <524faf600_217789c282833@026533b5-233e-4a2c-8ad3-25ff831d5250.mail> Build Update for hpk42/pytest ------------------------------------- Build: #46 Status: Fixed Duration: 4 minutes and 16 seconds Commit: e2bee53 (master) Author: holger krekel Message: Added tag 2.4.2 for changeset 8d051f89184b View the changeset: https://github.com/hpk42/pytest/compare/b94f69ec5129...e2bee532eded View the full build log and details: https://travis-ci.org/hpk42/pytest/builds/12160372 -- You can configure recipients for build notifications in your .travis.yml file. See http://about.travis-ci.org/docs/user/build-configuration -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits-noreply at bitbucket.org Sat Oct 5 21:03:17 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 05 Oct 2013 19:03:17 -0000 Subject: [Pytest-commit] commit/pytest: gutworth: fix coding cookie detection logic Message-ID: <20131005190317.26397.71200@app01.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/95fc848e108a/ Changeset: 95fc848e108a User: gutworth Date: 2013-10-05 21:03:04 Summary: fix coding cookie detection logic Affected #: 3 files diff -r e669246287ee862e662587c29341174418a987c4 -r 95fc848e108a9917b2261593e8b3ca26147b42db CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +Changes between 2.4.2 and 2.4.3 +----------------------------------- + +- In assertion rewriting mode on Python 2, fix the detection of coding cookies. + Changes between 2.4.1 and 2.4.2 ----------------------------------- diff -r e669246287ee862e662587c29341174418a987c4 -r 95fc848e108a9917b2261593e8b3ca26147b42db _pytest/assertion/rewrite.py --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -196,7 +196,7 @@ RN = "\r\n".encode("utf-8") N = "\n".encode("utf-8") -cookie_re = re.compile("coding[:=]\s*[-\w.]+") +cookie_re = re.compile(r"^[ \t\f]*#.*coding[:=][ \t]*[-\w.]+") BOM_UTF8 = '\xef\xbb\xbf' def _rewrite_test(state, fn): @@ -220,8 +220,8 @@ end1 = source.find("\n") end2 = source.find("\n", end1 + 1) if (not source.startswith(BOM_UTF8) and - (not cookie_re.match(source[0:end1]) or - not cookie_re.match(source[end1:end2]))): + cookie_re.match(source[0:end1]) is None and + cookie_re.match(source[end1:end2]) is None): if hasattr(state, "_indecode"): return None # encodings imported us again, we don't rewrite state._indecode = True diff -r e669246287ee862e662587c29341174418a987c4 -r 95fc848e108a9917b2261593e8b3ca26147b42db testing/test_assertrewrite.py --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -441,7 +441,6 @@ '* 3 passed*', ]) - @pytest.mark.skipif("sys.version_info[0] >= 3") def test_assume_ascii(self, testdir): content = "u'\xe2\x99\xa5'" @@ -450,6 +449,13 @@ assert res.ret != 0 assert "SyntaxError: Non-ASCII character" in res.stdout.str() + @pytest.mark.skipif("sys.version_info[0] >= 3") + def test_detect_coding_cookie(self, testdir): + testdir.tmpdir.join("test_utf8.py").write("""# -*- coding: utf-8 -*- +u"St\xc3\xa4d" +def test_rewritten(): + assert "@py_builtins" in globals()""", "wb") + assert testdir.runpytest().ret == 0 def test_write_pyc(self, testdir, tmpdir, monkeypatch): from _pytest.assertion.rewrite import _write_pyc 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 Oct 5 21:30:24 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 05 Oct 2013 19:30:24 -0000 Subject: [Pytest-commit] commit/pytest: 2 new changesets Message-ID: <20131005193024.19853.68587@app06.ash-private.bitbucket.org> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/b04d97dfa5e2/ Changeset: b04d97dfa5e2 User: gutworth Date: 2013-10-05 21:16:08 Summary: fix detection of the coding cookie when it is on the second line of the file (fixes #330) Affected #: 3 files diff -r 95fc848e108a9917b2261593e8b3ca26147b42db -r b04d97dfa5e2dea918a83c907c4d836053f18d75 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,8 @@ Changes between 2.4.2 and 2.4.3 ----------------------------------- -- In assertion rewriting mode on Python 2, fix the detection of coding cookies. +- In assertion rewriting mode on Python 2, fix the detection of coding + cookies. See issue #330. Changes between 2.4.1 and 2.4.2 ----------------------------------- diff -r 95fc848e108a9917b2261593e8b3ca26147b42db -r b04d97dfa5e2dea918a83c907c4d836053f18d75 _pytest/assertion/rewrite.py --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -221,7 +221,7 @@ end2 = source.find("\n", end1 + 1) if (not source.startswith(BOM_UTF8) and cookie_re.match(source[0:end1]) is None and - cookie_re.match(source[end1:end2]) is None): + cookie_re.match(source[end1 + 1:end2]) is None): if hasattr(state, "_indecode"): return None # encodings imported us again, we don't rewrite state._indecode = True diff -r 95fc848e108a9917b2261593e8b3ca26147b42db -r b04d97dfa5e2dea918a83c907c4d836053f18d75 testing/test_assertrewrite.py --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -451,7 +451,16 @@ @pytest.mark.skipif("sys.version_info[0] >= 3") def test_detect_coding_cookie(self, testdir): - testdir.tmpdir.join("test_utf8.py").write("""# -*- coding: utf-8 -*- + testdir.tmpdir.join("test_cookie.py").write("""# -*- coding: utf-8 -*- +u"St\xc3\xa4d" +def test_rewritten(): + assert "@py_builtins" in globals()""", "wb") + assert testdir.runpytest().ret == 0 + + @pytest.mark.skipif("sys.version_info[0] >= 3") + def test_detect_coding_cookie_second_line(self, testdir): + testdir.tmpdir.join("test_cookie.py").write("""#!/usr/bin/env python +# -*- coding: utf-8 -*- u"St\xc3\xa4d" def test_rewritten(): assert "@py_builtins" in globals()""", "wb") https://bitbucket.org/hpk42/pytest/commits/f71c46c34d48/ Changeset: f71c46c34d48 User: gutworth Date: 2013-10-05 21:20:32 Summary: add test for detecting coding cookie with CRLF newlines Affected #: 1 file diff -r b04d97dfa5e2dea918a83c907c4d836053f18d75 -r f71c46c34d4879fd13d2f30ba22e18f6c604bc91 testing/test_assertrewrite.py --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -466,6 +466,15 @@ assert "@py_builtins" in globals()""", "wb") assert testdir.runpytest().ret == 0 + @pytest.mark.skipif("sys.version_info[0] >= 3") + def test_detect_coding_cookie_crlf(self, testdir): + testdir.tmpdir.join("test_cookie.py").write("""#!/usr/bin/env python +# -*- coding: utf-8 -*- +u"St\xc3\xa4d" +def test_rewritten(): + assert "@py_builtins" in globals()""".replace("\n", "\r\n"), "wb") + assert testdir.runpytest().ret == 0 + def test_write_pyc(self, testdir, tmpdir, monkeypatch): from _pytest.assertion.rewrite import _write_pyc from _pytest.assertion import AssertionState 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 Oct 5 21:39:25 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 05 Oct 2013 19:39:25 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: bump version to 2.3.3.dev1 Message-ID: <20131005193925.9247.91015@app06.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/abb2eaf10864/ Changeset: abb2eaf10864 User: hpk42 Date: 2013-10-05 21:39:16 Summary: bump version to 2.3.3.dev1 Affected #: 2 files diff -r f71c46c34d4879fd13d2f30ba22e18f6c604bc91 -r abb2eaf10864ef237380150cb61dace37dad2ad7 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.4.2' +__version__ = '2.4.3.dev1' diff -r f71c46c34d4879fd13d2f30ba22e18f6c604bc91 -r abb2eaf10864ef237380150cb61dace37dad2ad7 setup.py --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.4.2', + version='2.4.3.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 issues-reply at bitbucket.org Tue Oct 8 17:33:39 2013 From: issues-reply at bitbucket.org (Marc Abramowitz) Date: Tue, 08 Oct 2013 15:33:39 -0000 Subject: [Pytest-commit] Issue #127: Possible problem with python3.4? (hpk42/tox) Message-ID: <20131008153339.12716.54434@app07.ash-private.bitbucket.org> New issue 127: Possible problem with python3.4? https://bitbucket.org/hpk42/tox/issue/127/possible-problem-with-python34 Marc Abramowitz: I just installed python 3.4a3 this morning and when I try to use it with tox, I get some strange errors: ``` marca at marca-mac:~/dev/git-repos/tox-test$ tox -e py27,py33,py34 GLOB sdist-make: /Users/marca/dev/git-repos/tox-test/setup.py py27 inst-nodeps: /Users/marca/dev/git-repos/tox-test/.tox/dist/foo-0.0.0.zip py27 runtests: commands[0] | py.test -v ============================================================================== test session starts =============================================================================== platform darwin -- Python 2.7.3 -- pytest-2.4.2 -- /Users/marca/dev/git-repos/tox-test/.tox/py27/bin/python collected 1 items test_foo.py:3: test_foo PASSED ============================================================================ 1 passed in 0.01 seconds ============================================================================ py33 create: /Users/marca/dev/git-repos/tox-test/.tox/py33 py33 installdeps: pytest py33 inst: /Users/marca/dev/git-repos/tox-test/.tox/dist/foo-0.0.0.zip py33 runtests: commands[0] | py.test -v ============================================================================== test session starts =============================================================================== platform darwin -- Python 3.3.2 -- pytest-2.4.2 -- /Users/marca/dev/git-repos/tox-test/.tox/py33/bin/python3.3 collected 1 items test_foo.py:3: test_foo PASSED ============================================================================ 1 passed in 0.03 seconds ============================================================================ py34 create: /Users/marca/dev/git-repos/tox-test/.tox/py34 ERROR: invocation failed, logfile: /Users/marca/dev/git-repos/tox-test/.tox/py34/log/py34-0.log ERROR: actionid=py34 msg=getenv cmdargs=['/usr/local/bin/python3.4', '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/virtualenv.py', '--setuptools', '--python', '/usr/local/bin/python3.4', 'py34'] env={'HISTFILE': '/Users/marca/.bash_history-', 'PYMSSQL_TEST_DATABASE': 'pymssql_dev', 'TDSPWDPWD': 'M0nk3y$', 'LOGNAME': 'marca', 'USER': 'marca', 'TDSPWDSRV': 'localhost', 'TDSPWDUID': 'sa_monkey', 'HOME': '/Users/marca', 'PS1': '${debian_chroot:+($debian_chroot)}\\u@\\h:\\w\\$ ', 'DISPLAY': '/tmp/launch-3QN6DX/org.macosforge.xquartz:0', 'TERM_PROGRAM': 'iTerm.app', 'LANG': 'en_US.UTF-8', '__CF_USER_TEXT_ENCODING': '0x1F6:0:0', 'TERM': 'xterm-256color', 'Apple_PubSub_Socket_Render': '/tmp/launch-3zOWu2/Render', 'COLORFGBG': '7;0', 'SHLVL': '1', 'SHMUX_SSH_OPTS': '', 'LESS': '-ich4MP%t?f%f :stdin .?pb%pb\\%:?lbLine %lb:?bbByte %bb:-...', 'SECURITYSESSIONID': '186a4', 'TDSPWDDB': 'pymssql_dev', 'ITERM_SESSION_ID': 'w0t6p0', 'EDITOR': 'vim', 'HISTIGNORE': '&:ls:mutt:[bf]g:exit', 'SSH_AUTH_SOCK': '/tmp/launch-4nnSVt/Listeners', 'PYMSSQL_TEST_SERVER': 'localhost', 'PATH': '/Users/marca/dev/git-repos/tox-test/.tox/py34/bin:/Library/Frameworks/Python.framework/Versions/Current/bi n:/Users/marca/bin:/usr/local/opt/ruby/bin:/Library/Frameworks/Python.framework/Versions/2.7/bin:/Library/Frameworks/Python.framework/Versions/3.3/bin:/Library/Frameworks/Python.framework/Versions/3.2/bin:/Users/marca/ruby/bin:/sbin:/bin:/usr/sbin/:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/X11R6/bin:/Library/Frameworks/Python.framework/Versions/3.3/bin', 'SHELL': '/bin/bash', 'P4CONFIG': '.p4config', 'CLICOLOR': 'true', 'ITERM_PROFILE': 'Default', '_': '/Library/Frameworks/Python.framework/Versions/2.7/bin/tox', 'CVSEDITOR': 'vim', 'PERL5LIB': '/Users/marca/lib/perl', 'LSCOLORS': 'ExGxCxDxCxegedabagacad', 'PYMSSQL_TEST_USERNAME': 'sa_monkey', 'TMPDIR': '/var/folders/nk/8f8f6wjn7v3b9cb2gjqf6vph0000gp/T/', 'OLDPWD': '/Users/marca/dev/git-repos', 'NODE_PATH': '/usr/local/lib/node', 'PYMSSQL_TEST_IPADDRESS': '127.0.0.1', 'Apple_Ubiquity_Message': '/tmp/launch-9ggFY6/Apple_Ubiquity_Message', 'PWD': '/Users/marca/dev/git-repos/tox-test', 'PIP_DOWNLOAD_CACHE': '/Users/marca/.pip /download-cache', 'PYMSSQL_TEST_PASSWORD': 'M0nk3y$', 'TDSPWDSKIPCOMPUTE': '1', 'PAGER': 'less', 'COMMAND_MODE': 'unix2003'} Fatal Python error: Py_Initialize: can't initialize sys standard streams Traceback (most recent call last): File "/Users/marca/dev/git-repos/tox-test/.tox/py34/bin/../lib/python3.4/locale.py", line 17, in import re File "/Users/marca/dev/git-repos/tox-test/.tox/py34/bin/../lib/python3.4/re.py", line 124, in import functools File "/Users/marca/dev/git-repos/tox-test/.tox/py34/bin/../lib/python3.4/functools.py", line 21, in from collections import namedtuple File "/Users/marca/dev/git-repos/tox-test/.tox/py34/bin/../lib/python3.4/collections/__init__.py", line 8, in __all__ += collections.abc.__all__ AttributeError: 'module' object has no attribute 'abc' Already using interpreter /usr/local/bin/python3.4 Using base prefix '/Library/Frameworks/Python.framework/Versions/3.4' New python executable in py34/bin/python3.4 Also creating executable in py34/bin/python ERROR: The executable py34/bin/python3.4 is not functioning ERROR: It thinks sys.prefix is '/Users/marca/dev/git-repos/tox-test/.tox' (should be '/Users/marca/dev/git-repos/tox-test/.tox/py34') ERROR: virtualenv is not compatible with this system or executable ERROR: InvocationError: /usr/local/bin/python3.4 /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/virtualenv.py --setuptools --python /usr/local/bin/python3.4 py34 (see /Users/marca/dev/git-repos/tox-test/.tox/py34/log/py34-0.log) ____________________________________________________________________________________ summary _____________________________________________________________________________________ py27: commands succeeded py33: commands succeeded ERROR: py34: InvocationError: /usr/local/bin/python3.4 /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/virtualenv.py --setuptools --python /usr/local/bin/python3.4 py34 (see /Users/marca/dev/git-repos/tox-test/.tox/py34/log/py34-0.log) ``` Here's the tiny little test package that I was testing with: https://github.com/msabramo/tox-test From commits-noreply at bitbucket.org Tue Oct 8 23:04:49 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 08 Oct 2013 21:04:49 -0000 Subject: [Pytest-commit] commit/tox: Ronald Evers: config documentation typo fixup Message-ID: <20131008210449.18620.37252@app07.ash-private.bitbucket.org> 1 new commit in tox: https://bitbucket.org/hpk42/tox/commits/8f5203930869/ Changeset: 8f5203930869 User: Ronald Evers Date: 2013-10-08 22:56:21 Summary: config documentation typo fixup Affected #: 1 file diff -r f7f70c5ce0b49656688bb78f8b4f5a1a8f489d7f -r 8f520393086916e5939f13c25b9474f7548249d0 doc/config.txt --- a/doc/config.txt +++ b/doc/config.txt @@ -122,10 +122,10 @@ .. confval:: deps=MULTI-LINE-LIST - test-specific dependencies -.to be installed into the environment prior to project + test-specific dependencies - to be installed into the environment prior to project package installation. Each line defines a dependency, which will be - passed to the installer command for processing. A line specify a file, - an URL or a package name. You can additionally specify + passed to the installer command for processing. Each line specifies a file, + a URL or a package name. You can additionally specify an :confval:`indexserver` to use for installing this dependency. All derived dependencies (deps required by the dep) will then be retrieved from the specified indexserver:: 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 Oct 8 23:42:31 2013 From: issues-reply at bitbucket.org (Ronald Evers) Date: Tue, 08 Oct 2013 21:42:31 -0000 Subject: [Pytest-commit] Issue #128: install_command doesnt interpolate {toxinidir} (hpk42/tox) Message-ID: <20131008214231.10018.56613@app06.ash-private.bitbucket.org> New issue 128: install_command doesnt interpolate {toxinidir} https://bitbucket.org/hpk42/tox/issue/128/install_command-doesnt-interpolate Ronald Evers: I'm running into a wall trying to make pip use a custom ssl ca bundle with tox. I ended up trying to customize the install_command like so: install_command=pip install --pre --cert={toxinidir}/my_ca_store.pem {opts} {packages} But it appears tox is not interpolating the {toxinidir} construct in there and is just the command with "--cert={toxinidir}" in the command literally. See the output below. Am I missing something or is this a bug? By the way, it does work when I use an explicit and absolute path like so: "--cert=/Users/ronald/.../my_ca_store.pem". ``` #!python (scratch)[ronald at thing] ~/hg/tox # tox GLOB sdist-make: /Users/ronald/hg/tox/setup.py py27 create: /Users/ronald/hg/tox/.tox/py27 py27 installdeps: pytest ERROR: invocation failed, logfile: /Users/ronald/hg/tox/.tox/py27/log/py27-1.log ERROR: actionid=py27 msg=getenv cmdargs=[local('/Users/ronald/hg/tox/.tox/py27/bin/pip'), 'install', '--pre', '--cert={toxinidir}/my_ca_store.pem', 'pytest'] env={} Downloading/unpacking pytest Could not fetch URL https://pypi.python.org/simple/pytest/: There was a problem confirming the ssl certificate: ``` As you can see, it does interpolate the "{packages}" but not the "{toxinidir}". From commits-noreply at bitbucket.org Wed Oct 9 22:32:01 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Wed, 09 Oct 2013 20:32:01 -0000 Subject: [Pytest-commit] commit/tox: evers: substitute substition for substitution Message-ID: <20131009203201.27376.15052@app06.ash-private.bitbucket.org> 1 new commit in tox: https://bitbucket.org/hpk42/tox/commits/cfa57eaab6db/ Changeset: cfa57eaab6db User: evers Date: 2013-10-09 21:37:33 Summary: substitute substition for substitution Affected #: 4 files diff -r 8f520393086916e5939f13c25b9474f7548249d0 -r cfa57eaab6db525c3035d473ab308b729b73e24c doc/announce/release-1.4.txt --- a/doc/announce/release-1.4.txt +++ b/doc/announce/release-1.4.txt @@ -4,7 +4,7 @@ I am happy to announce tox 1.4 which brings: - improvements with configuration file syntax, now allowing re-using - selected settings across config file sections. see http://testrun.org/tox/latest/config.html#substition-for-values-from-other-sections + selected settings across config file sections. see http://testrun.org/tox/latest/config.html#substitution-for-values-from-other-sections - terminal reporting was simplified and streamlined. Now with verbosity==0 (the default), less information will be shown diff -r 8f520393086916e5939f13c25b9474f7548249d0 -r cfa57eaab6db525c3035d473ab308b729b73e24c doc/config.txt --- a/doc/config.txt +++ b/doc/config.txt @@ -1,7 +1,7 @@ .. be in -*- rst -*- mode! tox configuration specification -================================ +=============================== .. _ConfigParser: http://docs.python.org/library/configparser.html @@ -10,7 +10,7 @@ :doc:`examples` first and use this page as a reference. Tox global settings ----------------------- +------------------- List of optional global options:: @@ -34,7 +34,7 @@ envlist setting -+++++++++++++++++++++++++ ++++++++++++++++ Determining the environment list that ``tox`` is to operate on happens in this order: @@ -45,7 +45,7 @@ Virtualenv test environment settings -------------------------------------------- +------------------------------------ Test environments are defined by a:: @@ -236,13 +236,13 @@ Substitutions ---------------------- +------------- Any ``key=value`` setting in an ini-file can make use of value substitution through the ``{...}`` string-substitution pattern. Globally available substitutions -+++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++ ``{toxinidir}`` the directory where tox.ini is located @@ -262,7 +262,7 @@ they may be accessed by other processes or tox runs. substitutions for virtualenv-related sections -++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++ ``{envname}`` the name of the virtual environment @@ -282,7 +282,7 @@ environment variable substitutions -+++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++ If you specify a substitution string like this:: @@ -296,7 +296,7 @@ .. _`positional substitution`: substitutions for positional arguments in commands -++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++ .. versionadded:: 1.0 @@ -330,7 +330,7 @@ Use ``{posargs:DEFAULTS}`` to specify those. -Substition for values from other sections +Substitution for values from other sections +++++++++++++++++++++++++++++++++++++++++++ .. versionadded:: 1.4 @@ -361,7 +361,7 @@ Other Rules and notes -========================= +===================== * ``path`` specifications: if a specified ``path`` is a relative path it will be considered as relative to the ``toxinidir``, the directory diff -r 8f520393086916e5939f13c25b9474f7548249d0 -r cfa57eaab6db525c3035d473ab308b729b73e24c tests/test_config.py --- a/tests/test_config.py +++ b/tests/test_config.py @@ -156,7 +156,7 @@ key={value} """) reader = IniReader(config._cfg, fallbacksections=['mydefault']) - reader.addsubstitions(value="newvalue", value2="newvalue2") + reader.addsubstitutions(value="newvalue", value2="newvalue2") x = reader.getdefault("section", "key2") assert x == "newvalue2" x = reader.getdefault("section", "key3") @@ -172,7 +172,7 @@ {item2} """) reader = IniReader(config._cfg) - reader.addsubstitions(item1="not", item2="grr") + reader.addsubstitutions(item1="not", item2="grr") x = reader.getlist("section", "key2") assert x == ['item1', 'grr'] @@ -184,7 +184,7 @@ key2={item2} """) reader = IniReader(config._cfg) - reader.addsubstitions(item1="not", item2="grr") + reader.addsubstitutions(item1="not", item2="grr") x = reader.getdict("section", "key2") assert 'key1' in x assert 'key2' in x @@ -235,7 +235,7 @@ cmd2 {item2} """) reader = IniReader(config._cfg) - reader.addsubstitions(item1="with space", item2="grr") + reader.addsubstitutions(item1="with space", item2="grr") #py.test.raises(tox.exception.ConfigError, # "reader.getargvlist('section', 'key1')") assert reader.getargvlist('section', 'key1') == [] @@ -251,7 +251,7 @@ {item2} """) reader = IniReader(config._cfg) - reader.addsubstitions(item1="with space", item2="grr") + reader.addsubstitutions(item1="with space", item2="grr") #py.test.raises(tox.exception.ConfigError, # "reader.getargvlist('section', 'key1')") assert reader.getargvlist('section', 'key1') == [] @@ -281,7 +281,7 @@ """) reader = IniReader(config._cfg) posargs = ['hello', 'world'] - reader.addsubstitions(posargs, item2="value2") + reader.addsubstitutions(posargs, item2="value2") #py.test.raises(tox.exception.ConfigError, # "reader.getargvlist('section', 'key1')") assert reader.getargvlist('section', 'key1') == [] @@ -290,7 +290,7 @@ assert argvlist[1] == ["cmd2"] + posargs reader = IniReader(config._cfg) - reader.addsubstitions([], item2="value2") + reader.addsubstitutions([], item2="value2") #py.test.raises(tox.exception.ConfigError, # "reader.getargvlist('section', 'key1')") assert reader.getargvlist('section', 'key1') == [] @@ -309,7 +309,7 @@ """) reader = IniReader(config._cfg) posargs = ['hello', 'world'] - reader.addsubstitions(posargs) + reader.addsubstitutions(posargs) argvlist = reader.getargvlist('section', 'key') assert argvlist[0] == ['cmd0'] + posargs @@ -317,7 +317,7 @@ assert argvlist[2] == ['cmd2', '-m', "something"] + posargs assert argvlist[3] == ['cmd3', 'something[]else'] - def test_substition_with_multiple_words(self, newconfig): + def test_substitution_with_multiple_words(self, newconfig): inisource = """ [section] key = py.test -n5 --junitxml={envlogdir}/junit-{envname}.xml [] @@ -325,7 +325,7 @@ config = newconfig(inisource) reader = IniReader(config._cfg) posargs = ['hello', 'world'] - reader.addsubstitions(posargs, envlogdir='ENV_LOG_DIR', envname='ENV_NAME') + reader.addsubstitutions(posargs, envlogdir='ENV_LOG_DIR', envname='ENV_NAME') expected = ['py.test', '-n5', '--junitxml=ENV_LOG_DIR/junit-ENV_NAME.xml', 'hello', 'world'] assert reader.getargvlist('section', 'key')[0] == expected @@ -347,7 +347,7 @@ path1={HELLO} """) reader = IniReader(config._cfg) - reader.addsubstitions(toxinidir=tmpdir, HELLO="mypath") + reader.addsubstitutions(toxinidir=tmpdir, HELLO="mypath") x = reader.getpath("section", "path1", tmpdir) assert x == tmpdir.join("mypath") diff -r 8f520393086916e5939f13c25b9474f7548249d0 -r cfa57eaab6db525c3035d473ab308b729b73e24c tox/_config.py --- a/tox/_config.py +++ b/tox/_config.py @@ -117,7 +117,7 @@ "pass-through output from running test commands which is " "instead captured into the json result file.") parser.add_argument("args", nargs="*", - help="additional arguments available to command positional substition") + help="additional arguments available to command positional substitution") return parser class Config(object): @@ -200,8 +200,8 @@ raise ValueError("invalid context") - reader.addsubstitions(toxinidir=config.toxinidir, - homedir=config.homedir) + reader.addsubstitutions(toxinidir=config.toxinidir, + homedir=config.homedir) config.toxworkdir = reader.getpath(toxsection, "toxworkdir", "{toxinidir}/.tox") config.minversion = reader.getdefault(toxsection, "minversion", None) @@ -233,13 +233,13 @@ for name in config.indexserver: config.indexserver[name] = IndexServerConfig(name, override) - reader.addsubstitions(toxworkdir=config.toxworkdir) + reader.addsubstitutions(toxworkdir=config.toxworkdir) config.distdir = reader.getpath(toxsection, "distdir", "{toxworkdir}/dist") - reader.addsubstitions(distdir=config.distdir) + reader.addsubstitutions(distdir=config.distdir) config.distshare = reader.getpath(toxsection, "distshare", distshare_default) - reader.addsubstitions(distshare=config.distshare) + reader.addsubstitutions(distshare=config.distshare) config.sdistsrc = reader.getpath(toxsection, "sdistsrc", None) config.setupdir = reader.getpath(toxsection, "setupdir", "{toxinidir}") config.logdir = config.toxworkdir.join("log") @@ -270,7 +270,7 @@ vc = VenvConfig(envname=name) vc.config = config reader = IniReader(self._cfg, fallbacksections=["testenv"]) - reader.addsubstitions(**subs) + reader.addsubstitutions(**subs) vc.develop = reader.getbool(section, "usedevelop", config.option.develop) vc.envdir = reader.getpath(section, "envdir", "{toxworkdir}/%s" % name) vc.args_are_paths = reader.getbool(section, "args_are_paths", True) @@ -283,12 +283,12 @@ bp = sys.executable vc.basepython = reader.getdefault(section, "basepython", bp) vc._basepython_info = config.interpreters.get_info(vc.basepython) - reader.addsubstitions(envdir=vc.envdir, envname=vc.envname, - envbindir=vc.envbindir, envpython=vc.envpython, - envsitepackagesdir=vc.envsitepackagesdir) + reader.addsubstitutions(envdir=vc.envdir, envname=vc.envname, + envbindir=vc.envbindir, envpython=vc.envpython, + envsitepackagesdir=vc.envsitepackagesdir) vc.envtmpdir = reader.getpath(section, "tmpdir", "{envdir}/tmp") vc.envlogdir = reader.getpath(section, "envlogdir", "{envdir}/log") - reader.addsubstitions(envlogdir=vc.envlogdir, envtmpdir=vc.envtmpdir) + reader.addsubstitutions(envlogdir=vc.envlogdir, envtmpdir=vc.envtmpdir) vc.changedir = reader.getpath(section, "changedir", "{toxinidir}") if config.option.recreate: vc.recreate = True @@ -303,7 +303,7 @@ if origpath.check(): arg = vc.changedir.bestrelpath(origpath) args.append(arg) - reader.addsubstitions(args) + reader.addsubstitutions(args) vc.setenv = reader.getdict(section, 'setenv') if not vc.setenv: vc.setenv = None @@ -410,7 +410,7 @@ self._subs = {} self._subststack = [] - def addsubstitions(self, _posargs=None, **kw): + def addsubstitutions(self, _posargs=None, **kw): self._subs.update(kw) if _posargs: self._subs['_posargs'] = _posargs 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 Thu Oct 10 11:03:20 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 10 Oct 2013 09:03:20 -0000 Subject: [Pytest-commit] commit/tox: 4 new changesets Message-ID: <20131010090320.27913.68481@app11.ash-private.bitbucket.org> 4 new commits in tox: https://bitbucket.org/hpk42/tox/commits/1f451606af67/ Changeset: 1f451606af67 User: evers Date: 2013-10-09 23:20:42 Summary: remove unused kwarg rexpattern from IniReader._replace Affected #: 1 file diff -r cfa57eaab6db525c3035d473ab308b729b73e24c -r 1f451606af676fc7dc93cafde8d4916954ac9d2b tox/_config.py --- a/tox/_config.py +++ b/tox/_config.py @@ -621,14 +621,13 @@ def _replace_match_no_quote(self, match): return self._replace_match(match, quote=False) - def _replace(self, x, rexpattern=RE_ITEM_REF, quote=False): - # XXX is rexpattern used by callers? can it be removed? + def _replace(self, x, quote=False): if '{' in x: if quote: replace_func = self._replace_match_quote else: replace_func = self._replace_match_no_quote - return rexpattern.sub(replace_func, x) + return RE_ITEM_REF.sub(replace_func, x) return x def _parse_command(self, command): https://bitbucket.org/hpk42/tox/commits/bb2943b51122/ Changeset: bb2943b51122 User: evers Date: 2013-10-10 00:04:16 Summary: use substitution in install_command Affected #: 2 files diff -r 1f451606af676fc7dc93cafde8d4916954ac9d2b -r bb2943b51122e0fee77f9787d795965904881f7d tests/test_config.py --- a/tests/test_config.py +++ b/tests/test_config.py @@ -529,6 +529,15 @@ install_command=pip install """) + def test_install_command_substitutions(self, newconfig): + config = newconfig(""" + [testenv] + install_command=some_install {toxinidir} {envname} {packages} + """) + envconfig = config.envconfigs['python'] + assert envconfig.install_command == [ + 'some_install', config.toxinidir, 'python', '{packages}'] + def test_downloadcache(self, newconfig, monkeypatch): monkeypatch.delenv("PIP_DOWNLOAD_CACHE", raising=False) config = newconfig(""" diff -r 1f451606af676fc7dc93cafde8d4916954ac9d2b -r bb2943b51122e0fee77f9787d795965904881f7d tox/_config.py --- a/tox/_config.py +++ b/tox/_config.py @@ -341,7 +341,7 @@ section, "install_command", "pip install " + " ".join(pip_default_opts), - replace=False, + replace=True, ) if '{packages}' not in vc.install_command: raise tox.exception.ConfigError( @@ -597,6 +597,13 @@ if self._is_bare_posargs(g): return self._do_replace_posargs(lambda: '') + # special case: opts and packages. Leave {opts} and + # {packages} intact, they are replaced manually in + # _venv.VirtualEnv.run_install_command. + sub_value = g['substitution_value'] + if sub_value in ('opts', 'packages'): + return '{%s}' % sub_value + handlers = { 'posargs' : self._replace_posargs, 'env' : self._replace_env, https://bitbucket.org/hpk42/tox/commits/07a696f394d2/ Changeset: 07a696f394d2 User: evers Date: 2013-10-10 00:08:42 Summary: remove replace kwarg in install_command handling, True is the default Affected #: 1 file diff -r bb2943b51122e0fee77f9787d795965904881f7d -r 07a696f394d27c0cefeef318092b3ecba76694ee tox/_config.py --- a/tox/_config.py +++ b/tox/_config.py @@ -341,7 +341,6 @@ section, "install_command", "pip install " + " ".join(pip_default_opts), - replace=True, ) if '{packages}' not in vc.install_command: raise tox.exception.ConfigError( https://bitbucket.org/hpk42/tox/commits/5973025ae7f9/ Changeset: 5973025ae7f9 User: evers Date: 2013-10-10 00:21:11 Summary: expand install_command_substitutions test case Affected #: 1 file diff -r 07a696f394d27c0cefeef318092b3ecba76694ee -r 5973025ae7f92c103d063e79b367afd43a348d4b tests/test_config.py --- a/tests/test_config.py +++ b/tests/test_config.py @@ -532,11 +532,13 @@ def test_install_command_substitutions(self, newconfig): config = newconfig(""" [testenv] - install_command=some_install {toxinidir} {envname} {packages} + install_command=some_install --arg={toxinidir}/foo \ + {envname} {opts} {packages} """) envconfig = config.envconfigs['python'] assert envconfig.install_command == [ - 'some_install', config.toxinidir, 'python', '{packages}'] + 'some_install', '--arg=%s/foo' % config.toxinidir, 'python', + '{opts}', '{packages}'] def test_downloadcache(self, newconfig, monkeypatch): monkeypatch.delenv("PIP_DOWNLOAD_CACHE", raising=False) 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 Thu Oct 10 11:07:55 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 10 Oct 2013 09:07:55 -0000 Subject: [Pytest-commit] commit/tox: hpk42: fix issue128: enable full substitution in install_command, Message-ID: <20131010090755.13970.59897@app06.ash-private.bitbucket.org> 1 new commit in tox: https://bitbucket.org/hpk42/tox/commits/df35850bb8d3/ Changeset: df35850bb8d3 User: hpk42 Date: 2013-10-10 11:07:50 Summary: fix issue128: enable full substitution in install_command, thanks for the PR to Ronald Evers Affected #: 3 files diff -r 5973025ae7f92c103d063e79b367afd43a348d4b -r df35850bb8d3d8a482f4415a6cab86dad23c951a CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +1.6.2.dev +--------- + +- fix issue128: enable full substitution in install_command, + thanks for the PR to Ronald Evers + 1.6.1 ----- diff -r 5973025ae7f92c103d063e79b367afd43a348d4b -r df35850bb8d3d8a482f4415a6cab86dad23c951a 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.6.1', + version='1.6.2.dev1', license='http://opensource.org/licenses/MIT', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], author='holger krekel', diff -r 5973025ae7f92c103d063e79b367afd43a348d4b -r df35850bb8d3d8a482f4415a6cab86dad23c951a tox/__init__.py --- a/tox/__init__.py +++ b/tox/__init__.py @@ -1,5 +1,5 @@ # -__version__ = '1.6.1' +__version__ = '1.6.2.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 notifications at travis-ci.org Fri Oct 11 00:09:14 2013 From: notifications at travis-ci.org (Travis CI) Date: Thu, 10 Oct 2013 22:09:14 +0000 Subject: [Pytest-commit] [Fixed] jaraco/pytest#3 (master - 41ab848) Message-ID: <5257258a1c520_2d31930428440@8bd1cd19-02ab-411e-92e4-6a560a90201a.mail> Build Update for jaraco/pytest ------------------------------------- Build: #3 Status: Fixed Duration: 4 minutes and 57 seconds Commit: 41ab848 (master) Author: Jason R. Coombs Message: Fix bytes/string mismatch in test on Python 3 View the changeset: https://github.com/jaraco/pytest/compare/7b92e8798605...41ab848fa671 View the full build log and details: https://travis-ci.org/jaraco/pytest/builds/12392429 -- You can configure recipients for build notifications in your .travis.yml file. See http://about.travis-ci.org/docs/user/build-configuration -------------- next part -------------- An HTML attachment was scrubbed... URL: From notifications at travis-ci.org Fri Oct 11 00:01:02 2013 From: notifications at travis-ci.org (Travis CI) Date: Thu, 10 Oct 2013 22:01:02 +0000 Subject: [Pytest-commit] [Failed] jaraco/pytest#2 (master - 7b92e87) Message-ID: <5257239e3e8_25c500a213382@d79b2a25-e58f-4492-af20-cb4640338d96.mail> Build Update for jaraco/pytest ------------------------------------- Build: #2 Status: Failed Duration: 7 minutes and 9 seconds Commit: 7b92e87 (master) Author: Jason R. Coombs Message: Implement suggestions by HPK View the changeset: https://github.com/jaraco/pytest/compare/5992a8ef2142^...7b92e8798605 View the full build log and details: https://travis-ci.org/jaraco/pytest/builds/12392076 -- You can configure recipients for build notifications in your .travis.yml file. See http://about.travis-ci.org/docs/user/build-configuration -------------- next part -------------- An HTML attachment was scrubbed... URL: From notifications at travis-ci.org Thu Oct 10 23:57:40 2013 From: notifications at travis-ci.org (Travis CI) Date: Thu, 10 Oct 2013 21:57:40 +0000 Subject: [Pytest-commit] [Failed] jaraco/pytest#1 (master - 7b92e87) Message-ID: <525722d3ae8f8_24c03d62121e4@d79b2a25-e58f-4492-af20-cb4640338d96.mail> Build Update for jaraco/pytest ------------------------------------- Build: #1 Status: Failed Duration: 5 minutes and 26 seconds Commit: 7b92e87 (master) Author: Jason R. Coombs Message: Implement suggestions by HPK View the changeset: https://github.com/jaraco/pytest/compare/1ce3f7dfd06f...7b92e8798605 View the full build log and details: https://travis-ci.org/jaraco/pytest/builds/12391999 -- You can configure recipients for build notifications in your .travis.yml file. See http://about.travis-ci.org/docs/user/build-configuration -------------- next part -------------- An HTML attachment was scrubbed... URL: From commits-noreply at bitbucket.org Fri Oct 11 09:27:04 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Fri, 11 Oct 2013 07:27:04 -0000 Subject: [Pytest-commit] commit/pytest: 4 new changesets Message-ID: <20131011072704.7089.38394@app05.ash-private.bitbucket.org> 4 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/2c2048157a12/ Changeset: 2c2048157a12 User: jaraco Date: 2013-10-10 17:40:31 Summary: Adding test capturing #366 where an error occurs when package resources are loaded from the test package. Affected #: 1 file diff -r abb2eaf10864ef237380150cb61dace37dad2ad7 -r 2c2048157a121db03d3bc06121629b9d98ba4a93 testing/test_assertrewrite.py --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -493,3 +493,34 @@ raise e monkeypatch.setattr(b, "open", open) assert not _write_pyc(state, [1], source_path, pycpath) + + def test_resources_provider_for_loader(self, testdir): + """ + Attempts to load resources from a package should succeed normally, + even when the AssertionRewriteHook is used to load the modules. + + See #366 for details. + """ + pytest.importorskip("pkg_resources") + + testdir.mkpydir('testpkg') + contents = { + 'testpkg/test_pkg': """ + import pkg_resources + + import pytest + from _pytest.assertion.rewrite import AssertionRewritingHook + + def test_load_resource(): + assert isinstance(__loader__, AssertionRewritingHook) + res = pkg_resources.resource_string(__name__, 'resource.txt') + assert res == 'Load me please.' + """, + } + testdir.makepyfile(**contents) + testdir.maketxtfile(**{'testpkg/resource': "Load me please."}) + + result = testdir.runpytest() + result.stdout.fnmatch_lines([ + '* 1 passed*', + ]) https://bitbucket.org/hpk42/pytest/commits/9ce7380eb99c/ Changeset: 9ce7380eb99c User: jaraco Date: 2013-10-10 17:56:12 Summary: Register the AssertionRewritingHook loader with pkg_resources; fixes #366. Affected #: 1 file diff -r 2c2048157a121db03d3bc06121629b9d98ba4a93 -r 9ce7380eb99c7d30ca3d4cfdae6782bc0ecfbd15 _pytest/assertion/rewrite.py --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -41,6 +41,7 @@ def __init__(self): self.session = None self.modules = {} + self._register_with_pkg_resources() def set_session(self, session): self.fnpats = session.config.getini("python_files") @@ -169,6 +170,23 @@ tp = desc[2] return tp == imp.PKG_DIRECTORY + @classmethod + def _register_with_pkg_resources(cls): + """ + Ensure package resources can be loaded from this loader. + """ + try: + pkg_resources = __import__('pkg_resources') + # access an attribute in case a deferred importer is present + pkg_resources.__name__ + except ImportError: + return + + # Since pytest tests are always located in the file system, the + # DefaultProvider is appropriate. + pkg_resources.register_loader_type(cls, pkg_resources.DefaultProvider) + + def _write_pyc(state, co, source_path, pyc): # Technically, we don't have to have the same pyc format as # (C)Python, since these "pycs" should never be seen by builtin https://bitbucket.org/hpk42/pytest/commits/7bd3084ea722/ Changeset: 7bd3084ea722 User: jaraco Date: 2013-10-10 23:39:37 Summary: Implement suggestions by HPK Affected #: 1 file diff -r 9ce7380eb99c7d30ca3d4cfdae6782bc0ecfbd15 -r 7bd3084ea72250eec2d03952c43d9e4de47753d4 _pytest/assertion/rewrite.py --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -173,10 +173,11 @@ @classmethod def _register_with_pkg_resources(cls): """ - Ensure package resources can be loaded from this loader. + Ensure package resources can be loaded from this loader. May be called + multiple times, as the operation is idempotent. """ try: - pkg_resources = __import__('pkg_resources') + import pkg_resources # access an attribute in case a deferred importer is present pkg_resources.__name__ except ImportError: https://bitbucket.org/hpk42/pytest/commits/70020cf2651b/ Changeset: 70020cf2651b User: jaraco Date: 2013-10-11 00:01:56 Summary: Fix bytes/string mismatch in test on Python 3 Affected #: 1 file diff -r 7bd3084ea72250eec2d03952c43d9e4de47753d4 -r 70020cf2651ba7bc717586d43dc715c059a71d9a testing/test_assertrewrite.py --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -514,6 +514,7 @@ def test_load_resource(): assert isinstance(__loader__, AssertionRewritingHook) res = pkg_resources.resource_string(__name__, 'resource.txt') + res = res.decode('ascii') assert res == 'Load me please.' """, } 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 Oct 11 09:34:35 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Fri, 11 Oct 2013 07:34:35 -0000 Subject: [Pytest-commit] commit/pytest: 3 new changesets Message-ID: <20131011073435.22025.22349@app13.ash-private.bitbucket.org> 3 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/24cadf785ead/ Changeset: 24cadf785ead User: hpk42 Date: 2013-10-09 22:55:20 Summary: make "--runxfail" turn imperative pytest.xfail calls into no ops (it already did neutralize pytest.mark.xfail markers) Affected #: 4 files diff -r abb2eaf10864ef237380150cb61dace37dad2ad7 -r 24cadf785eadf26d6533479c676467b0a102b3ac CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,9 @@ - In assertion rewriting mode on Python 2, fix the detection of coding cookies. See issue #330. +- make "--runxfail" turn imperative pytest.xfail calls into no ops + (it already did neutralize pytest.mark.xfail markers) + Changes between 2.4.1 and 2.4.2 ----------------------------------- diff -r abb2eaf10864ef237380150cb61dace37dad2ad7 -r 24cadf785eadf26d6533479c676467b0a102b3ac _pytest/skipping.py --- a/_pytest/skipping.py +++ b/_pytest/skipping.py @@ -10,6 +10,14 @@ help="run tests even if they are marked xfail") def pytest_configure(config): + if config.option.runxfail: + old = pytest.xfail + config._cleanup.append(lambda: setattr(pytest, "xfail", old)) + def nop(*args, **kwargs): + pass + nop.Exception = XFailed + setattr(pytest, "xfail", nop) + config.addinivalue_line("markers", "skipif(condition): skip the given test function if eval(condition) " "results in a True value. Evaluation happens within the " diff -r abb2eaf10864ef237380150cb61dace37dad2ad7 -r 24cadf785eadf26d6533479c676467b0a102b3ac setup.py --- a/setup.py +++ b/setup.py @@ -1,6 +1,20 @@ import os, sys from setuptools import setup, Command +classifiers=['Development Status :: 6 - Mature', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: MIT License', + 'Operating System :: POSIX', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: MacOS :: MacOS X', + 'Topic :: Software Development :: Testing', + 'Topic :: Software Development :: Libraries', + 'Topic :: Utilities', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 3'] + [ + ("Programming Language :: Python :: %s" % x) for x in + "2.4 2.5 2.6 2.7 3.0 3.1 3.2 3.3".split()] + long_description = open("README.rst").read() def main(): install_requires = ["py>=1.4.17"] @@ -20,22 +34,10 @@ author='Holger Krekel, Benjamin Peterson, Ronny Pfannschmidt, Floris Bruynooghe and others', author_email='holger at merlinux.eu', entry_points= make_entry_points(), + classifiers=classifiers, cmdclass = {'test': PyTest}, # the following should be enabled for release install_requires=install_requires, - classifiers=['Development Status :: 6 - Mature', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: MIT License', - 'Operating System :: POSIX', - 'Operating System :: Microsoft :: Windows', - 'Operating System :: MacOS :: MacOS X', - 'Topic :: Software Development :: Testing', - 'Topic :: Software Development :: Libraries', - 'Topic :: Utilities', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 3'] + [ - ("Programming Language :: Python :: %s" % x) for x in - "2.4 2.5 2.6 2.7 3.0 3.1 3.2 3.3".split()], packages=['_pytest', '_pytest.assertion'], py_modules=['pytest'], zip_safe=False, diff -r abb2eaf10864ef237380150cb61dace37dad2ad7 -r 24cadf785eadf26d6533479c676467b0a102b3ac testing/test_skipping.py --- a/testing/test_skipping.py +++ b/testing/test_skipping.py @@ -159,13 +159,14 @@ @pytest.mark.xfail def test_func(): assert 0 + def test_func2(): + pytest.xfail("hello") """) result = testdir.runpytest("--runxfail") - assert result.ret == 1 result.stdout.fnmatch_lines([ "*def test_func():*", "*assert 0*", - "*1 failed*", + "*1 failed*1 pass*", ]) def test_xfail_evalfalse_but_fails(self, testdir): @@ -261,10 +262,7 @@ "*reason:*hello*", ]) result = testdir.runpytest(p, "--runxfail") - result.stdout.fnmatch_lines([ - "*def test_this():*", - "*pytest.xfail*", - ]) + result.stdout.fnmatch_lines("*1 pass*") def test_xfail_imperative_in_setup_function(self, testdir): p = testdir.makepyfile(""" @@ -285,10 +283,10 @@ "*reason:*hello*", ]) result = testdir.runpytest(p, "--runxfail") - result.stdout.fnmatch_lines([ - "*def setup_function(function):*", - "*pytest.xfail*", - ]) + result.stdout.fnmatch_lines(""" + *def test_this* + *1 fail* + """) def xtest_dynamic_xfail_set_during_setup(self, testdir): p = testdir.makepyfile(""" https://bitbucket.org/hpk42/pytest/commits/c7856bb810f1/ Changeset: c7856bb810f1 User: hpk42 Date: 2013-10-11 09:30:08 Summary: merge Affected #: 2 files diff -r 24cadf785eadf26d6533479c676467b0a102b3ac -r c7856bb810f19c52f48c008811154f9907593427 _pytest/assertion/rewrite.py --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -41,6 +41,7 @@ def __init__(self): self.session = None self.modules = {} + self._register_with_pkg_resources() def set_session(self, session): self.fnpats = session.config.getini("python_files") @@ -169,6 +170,24 @@ tp = desc[2] return tp == imp.PKG_DIRECTORY + @classmethod + def _register_with_pkg_resources(cls): + """ + Ensure package resources can be loaded from this loader. May be called + multiple times, as the operation is idempotent. + """ + try: + import pkg_resources + # access an attribute in case a deferred importer is present + pkg_resources.__name__ + except ImportError: + return + + # Since pytest tests are always located in the file system, the + # DefaultProvider is appropriate. + pkg_resources.register_loader_type(cls, pkg_resources.DefaultProvider) + + def _write_pyc(state, co, source_path, pyc): # Technically, we don't have to have the same pyc format as # (C)Python, since these "pycs" should never be seen by builtin diff -r 24cadf785eadf26d6533479c676467b0a102b3ac -r c7856bb810f19c52f48c008811154f9907593427 testing/test_assertrewrite.py --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -493,3 +493,35 @@ raise e monkeypatch.setattr(b, "open", open) assert not _write_pyc(state, [1], source_path, pycpath) + + def test_resources_provider_for_loader(self, testdir): + """ + Attempts to load resources from a package should succeed normally, + even when the AssertionRewriteHook is used to load the modules. + + See #366 for details. + """ + pytest.importorskip("pkg_resources") + + testdir.mkpydir('testpkg') + contents = { + 'testpkg/test_pkg': """ + import pkg_resources + + import pytest + from _pytest.assertion.rewrite import AssertionRewritingHook + + def test_load_resource(): + assert isinstance(__loader__, AssertionRewritingHook) + res = pkg_resources.resource_string(__name__, 'resource.txt') + res = res.decode('ascii') + assert res == 'Load me please.' + """, + } + testdir.makepyfile(**contents) + testdir.maketxtfile(**{'testpkg/resource': "Load me please."}) + + result = testdir.runpytest() + result.stdout.fnmatch_lines([ + '* 1 passed*', + ]) https://bitbucket.org/hpk42/pytest/commits/9931e8b59b66/ Changeset: 9931e8b59b66 User: hpk42 Date: 2013-10-11 09:29:28 Summary: add changelog entry: refine pytest / pkg_resources interactions: The AssertionRewritingHook PEP302 compliant loader now registers itself with setuptools/pkg_resources properly so that the pkg_resources.resource_stream method works properly. Fixes issue366. Thanks for the investigations and full PR to Jason R. Coombs. Affected #: 1 file diff -r c7856bb810f19c52f48c008811154f9907593427 -r 9931e8b59b66c7dca504db56a1ed87066383c0fe CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,11 @@ - make "--runxfail" turn imperative pytest.xfail calls into no ops (it already did neutralize pytest.mark.xfail markers) +- refine pytest / pkg_resources interactions: The AssertionRewritingHook + PEP302 compliant loader now registers itself with setuptools/pkg_resources + properly so that the pkg_resources.resource_stream method works properly. + Fixes issue366. Thanks for the investigations and full PR to Jason R. Coombs. + Changes between 2.4.1 and 2.4.2 ----------------------------------- Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Fri Oct 11 14:37:48 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Fri, 11 Oct 2013 12:37:48 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: avoid one surprising case of marker malfunction/confusion:: Message-ID: <20131011123748.27484.18918@app13.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/76a2baa4837d/ Changeset: 76a2baa4837d User: hpk42 Date: 2013-10-11 14:36:54 Summary: avoid one surprising case of marker malfunction/confusion:: @pytest.mark.some(lambda arg: ...) def test_function(): would not work correctly because pytest assumes @pytest.mark.some gets a function to be decorated already. We now at least detect if this arg is an lambda and thus the example will work. Thanks Alex Gaynor for bringing it up. Affected #: 3 files diff -r 9931e8b59b66c7dca504db56a1ed87066383c0fe -r 76a2baa4837dfeacdeaca326b74dd918c0d031d9 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -12,6 +12,16 @@ properly so that the pkg_resources.resource_stream method works properly. Fixes issue366. Thanks for the investigations and full PR to Jason R. Coombs. +- avoid one surprising case of marker malfunction/confusion:: + + @pytest.mark.some(lambda arg: ...) + def test_function(): + + would not work correctly because pytest assumes @pytest.mark.some + gets a function to be decorated already. We now at least detect if this + arg is an lambda and thus the example will work. Thanks Alex Gaynor + for bringing it up. + Changes between 2.4.1 and 2.4.2 ----------------------------------- diff -r 9931e8b59b66c7dca504db56a1ed87066383c0fe -r 76a2baa4837dfeacdeaca326b74dd918c0d031d9 _pytest/mark.py --- a/_pytest/mark.py +++ b/_pytest/mark.py @@ -182,6 +182,9 @@ if name not in self._markers: raise AttributeError("%r not a registered marker" % (name,)) +def istestfunc(func): + return hasattr(func, "__call__") and \ + getattr(func, "__name__", "") != "" class MarkDecorator: """ A decorator for test functions and test classes. When applied @@ -217,8 +220,8 @@ otherwise add *args/**kwargs in-place to mark information. """ if args: func = args[0] - if len(args) == 1 and hasattr(func, '__call__') or \ - hasattr(func, '__bases__'): + if len(args) == 1 and (istestfunc(func) or + hasattr(func, '__bases__')): if hasattr(func, '__bases__'): if hasattr(func, 'pytestmark'): l = func.pytestmark diff -r 9931e8b59b66c7dca504db56a1ed87066383c0fe -r 76a2baa4837dfeacdeaca326b74dd918c0d031d9 testing/test_mark.py --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -100,6 +100,16 @@ "*a1some*another marker", ]) +def test_mark_on_pseudo_function(testdir): + testdir.makepyfile(""" + import pytest + + @pytest.mark.r(lambda x: 0/0) + def test_hello(): + pass + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) def test_strict_prohibits_unregistered_markers(testdir): testdir.makepyfile(""" @@ -510,3 +520,4 @@ assert_test_is_not_selected("__") assert_test_is_not_selected("()") + 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 Oct 12 14:27:46 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 12 Oct 2013 12:27:46 -0000 Subject: [Pytest-commit] commit/pytest: 5 new changesets Message-ID: <20131012122746.25915.14573@app09.ash-private.bitbucket.org> 5 new commits in pytest: https://bitbucket.org/hpk42/pytest/commits/14d113eaff10/ Changeset: 14d113eaff10 Branch: plugins-index User: nicoddemus Date: 2013-10-12 00:14:22 Summary: adding first version of plugins_index script Affected #: 1 file diff -r abb2eaf10864ef237380150cb61dace37dad2ad7 -r 14d113eaff10b5fbf63c44e8513e54e952ba6256 doc/en/plugins_index.py --- /dev/null +++ b/doc/en/plugins_index.py @@ -0,0 +1,120 @@ +from collections import namedtuple +from distutils.version import LooseVersion +import itertools +import os +import sys +import xmlrpclib + + +#=================================================================================================== +# iter_pypi_plugins +#=================================================================================================== +def iter_pypi_plugins(client): + for plug_data in client.search({'name' : 'pytest-'}): + yield plug_data['name'], plug_data['version'] + + +#=================================================================================================== +# get_latest_versions +#=================================================================================================== +def get_latest_versions(plugins): + plugins = [(name, LooseVersion(version)) for (name, version) in plugins] + for name, grouped_plugins in itertools.groupby(plugins, key=lambda x: x[0]): + name, loose_version = list(grouped_plugins)[-1] + yield name, str(loose_version) + + +#=================================================================================================== +# obtain_plugins_table +#=================================================================================================== +def obtain_plugins_table(plugins, client): + rows = [] + RowData = namedtuple('RowData', 'text link') + headers = ['Name', 'Version', 'Author', 'Summary'] + + # pluginname and latest version, pypi link, maintainer/author, repository link, + # one-line description, test status py27/py33 + for package_name, version in plugins: + release_data = client.release_data(package_name, version) + row = ( + RowData(package_name, release_data['package_url']), + RowData(version, release_data['release_url']), + RowData(release_data['author'], release_data['author_email']), + RowData(release_data['summary'], None), + ) + assert len(row) == len(headers) + rows.append(row) + + return headers, rows + + +#=================================================================================================== +# generate_plugins_index_from_table +#=================================================================================================== +def generate_plugins_index_from_table(headers, rows, basename): + + def get_row_limiter(char): + return ' '.join(char * length for length in column_lengths) + + def ref(s, link): + return s + '_' if link else s + + table_texts = [] + for row in rows: + row_texts = [] + for i, row_data in enumerate(row): + text = '`%s <%s>`_' % (row_data.text, row_data.link) if row_data.link else row_data.text + row_texts.append(text) + table_texts.append(row_texts) + + column_lengths = [len(x) for x in headers] + for row_texts in table_texts: + for i, row_text in enumerate(row_texts): + column_lengths[i] = max(column_lengths[i], len(row_text) + 2) + + with file(basename, 'w') as f: + print >> f, '.. _plugins_index:' + print >> f + print >> f, 'List of Third-Party Plugins' + print >> f, '===========================' + print >> f + print >> f + print >> f, get_row_limiter('=') + for i, header in enumerate(headers): + print >> f, '{:^{fill}}'.format(header, fill=column_lengths[i]), + print >> f + print >> f, get_row_limiter('=') + + for row_texts in table_texts: + for i, row_text in enumerate(row_texts): + print >> f, '{:^{fill}}'.format(row_text, fill=column_lengths[i]), + print >> f + print >> f + print >> f, get_row_limiter('=') + print >> f + + +#=================================================================================================== +# generate_plugins_index +#=================================================================================================== +def generate_plugins_index(client, basename): + plugins = get_latest_versions(iter_pypi_plugins(client)) + headers, rows = obtain_plugins_table(plugins, client) + generate_plugins_index_from_table(headers, rows, basename) + + +#=================================================================================================== +# main +#=================================================================================================== +def main(argv): + client = xmlrpclib.ServerProxy('http://pypi.python.org/pypi') + basename = os.path.join(os.path.dirname(__file__), 'plugins_index.txt') + generate_plugins_index(client, basename) + print 'OK' + return 0 + +#=================================================================================================== +# main +#=================================================================================================== +if __name__ == '__main__': + sys.exit(main(sys.argv)) https://bitbucket.org/hpk42/pytest/commits/7d55b2079a6c/ Changeset: 7d55b2079a6c Branch: plugins-index User: nicoddemus Date: 2013-10-12 00:47:40 Summary: added plugins_index documentation and generated plugins_index file Affected #: 2 files diff -r 14d113eaff10b5fbf63c44e8513e54e952ba6256 -r 7d55b2079a6c4805c8468727da3952bc3ac974dd doc/en/plugins_index.py --- a/doc/en/plugins_index.py +++ b/doc/en/plugins_index.py @@ -1,4 +1,11 @@ +''' +Script to generate the file `plugins_index.txt` with information about pytest plugins taken directly +from a live pypi server. + +This will evolve to include test compatibility (pythons and pytest versions) information also. +''' from collections import namedtuple +import datetime from distutils.version import LooseVersion import itertools import os @@ -7,10 +14,16 @@ #=================================================================================================== -# iter_pypi_plugins +# iter_plugins #=================================================================================================== -def iter_pypi_plugins(client): - for plug_data in client.search({'name' : 'pytest-'}): +def iter_plugins(client, search='pytest-'): + ''' + Returns an iterator of (name, version) from pypi. + + :param client: xmlrpclib.ServerProxy + :param search: package names to search for + ''' + for plug_data in client.search({'name' : search}): yield plug_data['name'], plug_data['version'] @@ -18,6 +31,11 @@ # get_latest_versions #=================================================================================================== def get_latest_versions(plugins): + ''' + Returns an iterator of (name, version) from the given list of (name, version), but returning + only the latest version of the package. Uses distutils.LooseVersion to ensure compatibility + with PEP386. + ''' plugins = [(name, LooseVersion(version)) for (name, version) in plugins] for name, grouped_plugins in itertools.groupby(plugins, key=lambda x: x[0]): name, loose_version = list(grouped_plugins)[-1] @@ -28,19 +46,27 @@ # obtain_plugins_table #=================================================================================================== def obtain_plugins_table(plugins, client): + ''' + Returns information to populate a table of plugins, their versions, authors, etc. + + The returned information is a list of columns of `ColumnData` namedtuples(text, link). Link + can be None if the text for that column should not be linked to anything. + + :param plugins: list of (name, version) + :param client: xmlrpclib.ServerProxy + + ''' rows = [] - RowData = namedtuple('RowData', 'text link') + ColumnData = namedtuple('ColumnData', 'text link') headers = ['Name', 'Version', 'Author', 'Summary'] - # pluginname and latest version, pypi link, maintainer/author, repository link, - # one-line description, test status py27/py33 for package_name, version in plugins: release_data = client.release_data(package_name, version) row = ( - RowData(package_name, release_data['package_url']), - RowData(version, release_data['release_url']), - RowData(release_data['author'], release_data['author_email']), - RowData(release_data['summary'], None), + ColumnData(package_name, release_data['package_url']), + ColumnData(version, release_data['release_url']), + ColumnData(release_data['author'], release_data['author_email']), + ColumnData(release_data['summary'], None), ) assert len(row) == len(headers) rows.append(row) @@ -51,56 +77,71 @@ #=================================================================================================== # generate_plugins_index_from_table #=================================================================================================== -def generate_plugins_index_from_table(headers, rows, basename): +def generate_plugins_index_from_table(filename, headers, rows): + ''' + Generates a RST file with the table data given. + + :param filename: output filename + :param headers: see `obtain_plugins_table` + :param rows: see `obtain_plugins_table` + ''' + # creates a list of rows, each being a str containing appropriate column text and link + table_texts = [] + for row in rows: + column_texts = [] + for i, col_data in enumerate(row): + text = '`%s <%s>`_' % (col_data.text, col_data.link) if col_data.link else col_data.text + column_texts.append(text) + table_texts.append(column_texts) + # compute max length of each column so we can build the rst table + column_lengths = [len(x) for x in headers] + for column_texts in table_texts: + for i, row_text in enumerate(column_texts): + column_lengths[i] = max(column_lengths[i], len(row_text) + 2) + def get_row_limiter(char): return ' '.join(char * length for length in column_lengths) - def ref(s, link): - return s + '_' if link else s - - table_texts = [] - for row in rows: - row_texts = [] - for i, row_data in enumerate(row): - text = '`%s <%s>`_' % (row_data.text, row_data.link) if row_data.link else row_data.text - row_texts.append(text) - table_texts.append(row_texts) - - column_lengths = [len(x) for x in headers] - for row_texts in table_texts: - for i, row_text in enumerate(row_texts): - column_lengths[i] = max(column_lengths[i], len(row_text) + 2) - - with file(basename, 'w') as f: + with file(filename, 'w') as f: + # write welcome print >> f, '.. _plugins_index:' print >> f print >> f, 'List of Third-Party Plugins' print >> f, '===========================' print >> f - print >> f + + # table print >> f, get_row_limiter('=') for i, header in enumerate(headers): print >> f, '{:^{fill}}'.format(header, fill=column_lengths[i]), print >> f print >> f, get_row_limiter('=') - for row_texts in table_texts: - for i, row_text in enumerate(row_texts): + for column_texts in table_texts: + for i, row_text in enumerate(column_texts): print >> f, '{:^{fill}}'.format(row_text, fill=column_lengths[i]), print >> f print >> f print >> f, get_row_limiter('=') print >> f + + print >> f, '*(Last updated: %s)*' % datetime.date.today().strftime('%Y-%m-%d') #=================================================================================================== # generate_plugins_index #=================================================================================================== -def generate_plugins_index(client, basename): - plugins = get_latest_versions(iter_pypi_plugins(client)) +def generate_plugins_index(client, filename): + ''' + Generates an RST file with a table of the latest pytest plugins found in pypi. + + :param client: xmlrpclib.ServerProxy + :param filename: output filename + ''' + plugins = get_latest_versions(iter_plugins(client)) headers, rows = obtain_plugins_table(plugins, client) - generate_plugins_index_from_table(headers, rows, basename) + generate_plugins_index_from_table(filename, headers, rows) #=================================================================================================== @@ -108,8 +149,8 @@ #=================================================================================================== def main(argv): client = xmlrpclib.ServerProxy('http://pypi.python.org/pypi') - basename = os.path.join(os.path.dirname(__file__), 'plugins_index.txt') - generate_plugins_index(client, basename) + filename = os.path.join(os.path.dirname(__file__), 'plugins_index.txt') + generate_plugins_index(client, filename) print 'OK' return 0 diff -r 14d113eaff10b5fbf63c44e8513e54e952ba6256 -r 7d55b2079a6c4805c8468727da3952bc3ac974dd doc/en/plugins_index.txt --- /dev/null +++ b/doc/en/plugins_index.txt @@ -0,0 +1,61 @@ +.. _plugins_index: + +List of Third-Party Plugins +=========================== + +================================================================================== ============================================================================ ==================================================================================== ============================================================================================================================================= + Name Version Author Summary +================================================================================== ============================================================================ ==================================================================================== ============================================================================================================================================= + `pytest-bdd `_ `0.6.1 `_ `Oleg Pidsadnyi `_ BDD for pytest + `pytest-bdd-splinter `_ `0.5.2 `_ `Oleg Pidsadnyi `_ Splinter subplugin for Pytest BDD plugin + `pytest-bench `_ `0.1.0 `_ `Concordus Applications `_ Benchmark utility that plugs into pytest. + `pytest-blockage `_ `0.1 `_ `UNKNOWN `_ Disable network requests during a test run. + `pytest-browsermob-proxy `_ `0.1 `_ `Dave Hunt `_ BrowserMob proxy plugin for py.test. + `pytest-bugzilla `_ `0.2 `_ `Noufal Ibrahim `_ py.test bugzilla integration plugin + `pytest-cache `_ `1.0 `_ `Holger Krekel `_ pytest plugin with mechanisms for caching across test runs + `pytest-capturelog `_ `0.7 `_ `Meme Dough `_ py.test plugin to capture log messages + `pytest-codecheckers `_ `0.2 `_ `Ronny Pfannschmidt `_ pytest plugin to add source code sanity checks (pep8 and friends) + `pytest-contextfixture `_ `0.1.1 `_ `Andreas Pelme `_ Define pytest fixtures as context managers. + `pytest-couchdbkit `_ `0.5.1 `_ `RonnyPfannschmidt `_ py.test extension for per-test couchdb databases using couchdbkit + `pytest-cov `_ `1.6 `_ `Meme Dough `_ py.test plugin for coverage reporting with support for both centralised and distributed testing, including subprocesses and multiprocessing + `pytest-dbfixtures `_ `0.3.8.3 `_ `Clearcode - The A Room `_ dbfixtures plugin for py.test. + `pytest-django `_ `2.3.1 `_ `Andreas Pelme `_ A Django plugin for py.test. + `pytest-django-lite `_ `0.1.0 `_ `David Cramer `_ The bare minimum to integrate py.test with Django. + `pytest-figleaf `_ `1.0 `_ `holger krekel `_ py.test figleaf coverage plugin + `pytest-flakes `_ `0.2 `_ `Florian Schulze, Holger Krekel and Ronny Pfannschmidt `_ pytest plugin to check source code with pyflakes + `pytest-greendots `_ `0.2 `_ `UNKNOWN `_ Green progress dots + `pytest-growl `_ `0.1 `_ `Anthony Long `_ Growl notifications for pytest results. + `pytest-incremental `_ `0.3.0 `_ `Eduardo Naufel Schettino `_ an incremental test runner (pytest plugin) + `pytest-instafail `_ `0.1.0 `_ `Janne Vanhala `_ py.test plugin to show failures instantly + `pytest-ipdb `_ `0.1-prerelease `_ `Matthew de Verteuil `_ A py.test plug-in to enable drop to ipdb debugger on test failure. + `pytest-konira `_ `0.2 `_ `Alfredo Deza `_ Run Konira DSL tests with py.test + `pytest-localserver `_ `0.3 `_ `Sebastian Rahlf `_ py.test plugin to test server connections locally. + `pytest-marker-bugzilla `_ `0.06 `_ `Eric Sammons `_ py.test bugzilla integration plugin, using markers + `pytest-markfiltration `_ `0.8 `_ `adam goucher `_ UNKNOWN + `pytest-marks `_ `0.4 `_ `adam goucher `_ UNKNOWN + `pytest-monkeyplus `_ `1.1.0 `_ `Virgil Dupras `_ pytest's monkeypatch subclass with extra functionalities + `pytest-mozwebqa `_ `1.1.1 `_ `Dave Hunt `_ Mozilla WebQA plugin for py.test. + `pytest-oerp `_ `0.2.0 `_ `Leonardo Santagada `_ pytest plugin to test OpenERP modules + `pytest-osxnotify `_ `0.1.4 `_ `Daniel Bader `_ OS X notifications for py.test results. + `pytest-paste-config `_ `0.1 `_ `UNKNOWN `_ Allow setting the path to a paste config file + `pytest-pep8 `_ `1.0.5 `_ `Holger Krekel and Ronny Pfannschmidt `_ pytest plugin to check PEP8 requirements + `pytest-poo `_ `0.2 `_ `Andreas Pelme `_ Visualize your crappy tests + `pytest-pydev `_ `0.1 `_ `Sebastian Rahlf `_ py.test plugin to connect to a remote debug server with PyDev or PyCharm. + `pytest-qt `_ `1.0.2 `_ `Bruno Oliveira `_ pytest plugin that adds fixtures for testing Qt (PyQt and PySide) applications. + `pytest-quickcheck `_ `0.7 `_ `Tetsuya Morimoto `_ pytest plugin to generate random data inspired by QuickCheck + `pytest-rage `_ `0.1 `_ `Leonardo Santagada `_ pytest plugin to implement PEP712 + `pytest-random `_ `0.02 `_ `Leah Klearman `_ py.test plugin to randomize tests + `pytest-rerunfailures `_ `0.03 `_ `Leah Klearman `_ py.test plugin to re-run tests to eliminate flakey failures + `pytest-runfailed `_ `0.3 `_ `Dimitri Merejkowsky `_ implement a --failed option for pytest + `pytest-runner `_ `2.0 `_ `Jason R. Coombs `_ UNKNOWN + `pytest-sugar `_ `0.2.2 `_ `Teemu, Janne Vanhala `_ py.test plugin that adds instafail, ETA and neat graphics + `pytest-timeout `_ `0.3 `_ `Floris Bruynooghe `_ pytest plugin to abort tests after a timeout + `pytest-twisted `_ `1.4 `_ `Ralf Schmitt `_ A twisted plugin for py.test. + `pytest-xdist `_ `1.9 `_ `holger krekel and contributors `_ py.test xdist plugin for distributed testing and loop-on-failing modes + `pytest-xprocess `_ `0.8 `_ `Holger Krekel `_ pytest plugin to manage external processes across test runs + `pytest-yamlwsgi `_ `0.6 `_ `Ali Afshar `_ Run tests against wsgi apps defined in yaml + `pytest-zap `_ `0.1 `_ `Dave Hunt `_ OWASP ZAP plugin for py.test. + +================================================================================== ============================================================================ ==================================================================================== ============================================================================================================================================= + +*(Updated on 2013-10-11)* https://bitbucket.org/hpk42/pytest/commits/c7e580b90fc2/ Changeset: c7e580b90fc2 Branch: plugins-index User: nicoddemus Date: 2013-10-12 01:53:03 Summary: included test for plugins_index and added command line options Affected #: 2 files diff -r 7d55b2079a6c4805c8468727da3952bc3ac974dd -r c7e580b90fc2d1f641ebf856308d30b3ea781c5a doc/en/plugins_index.py --- a/doc/en/plugins_index.py +++ b/doc/en/plugins_index.py @@ -8,6 +8,7 @@ import datetime from distutils.version import LooseVersion import itertools +from optparse import OptionParser import os import sys import xmlrpclib @@ -126,7 +127,17 @@ print >> f, get_row_limiter('=') print >> f - print >> f, '*(Last updated: %s)*' % datetime.date.today().strftime('%Y-%m-%d') + print >> f, '*(Updated on %s)*' % _get_today_as_str() + + +#=================================================================================================== +# _get_today_as_str +#=================================================================================================== +def _get_today_as_str(): + ''' + internal. only exists so we can patch it in testing. + ''' + return datetime.date.today().strftime('%Y-%m-%d') #=================================================================================================== @@ -148,9 +159,16 @@ # main #=================================================================================================== def main(argv): - client = xmlrpclib.ServerProxy('http://pypi.python.org/pypi') filename = os.path.join(os.path.dirname(__file__), 'plugins_index.txt') - generate_plugins_index(client, filename) + url = 'http://pypi.python.org/pypi' + + parser = OptionParser(description='Generates a restructured document of pytest plugins from PyPi') + parser.add_option('-f', '--filename', default=filename, help='output filename [default: %default]') + parser.add_option('-u', '--url', default=url, help='url of PyPi server to obtain data from [default: %default]') + (options, _) = parser.parse_args(argv[1:]) + + client = xmlrpclib.ServerProxy(options.url) + generate_plugins_index(client, options.filename) print 'OK' return 0 diff -r 7d55b2079a6c4805c8468727da3952bc3ac974dd -r c7e580b90fc2d1f641ebf856308d30b3ea781c5a doc/en/test_plugins_index.py --- /dev/null +++ b/doc/en/test_plugins_index.py @@ -0,0 +1,88 @@ +import os +import xmlrpclib + + +#=================================================================================================== +# test_plugins_index +#=================================================================================================== +def test_plugins_index(tmpdir, monkeypatch): + ''' + Blackbox testing for plugins_index script. Calls main() generating a file and compares produced + output to expected. + + .. note:: if the test fails, a file named `test_plugins_index.obtained` will be generated in + the same directory as this test file. Ensure the contents are correct and overwrite + the global `expected_output` with the new contents. + ''' + import plugins_index + + # dummy interface to xmlrpclib.ServerProxy + class DummyProxy(object): + + expected_url = 'http://dummy.pypi' + def __init__(self, url): + assert url == self.expected_url + + def search(self, query): + assert query == {'name' : 'pytest-'} + return [ + {'name': 'pytest-plugin1', 'version' : '0.8'}, + {'name': 'pytest-plugin1', 'version' : '1.0'}, + {'name': 'pytest-plugin2', 'version' : '1.2'}, + ] + + def release_data(self, package_name, version): + results = { + ('pytest-plugin1', '1.0') : { + 'package_url' : 'http://plugin1', + 'release_url' : 'http://plugin1/1.0', + 'author' : 'someone', + 'author_email' : 'someone at py.com', + 'summary' : 'some plugin', + }, + + ('pytest-plugin2', '1.2') : { + 'package_url' : 'http://plugin2', + 'release_url' : 'http://plugin2/1.2', + 'author' : 'other', + 'author_email' : 'other at py.com', + 'summary' : 'some other plugin', + }, + } + + return results[(package_name, version)] + + + monkeypatch.setattr(xmlrpclib, 'ServerProxy', DummyProxy, 'foo') + monkeypatch.setattr(plugins_index, '_get_today_as_str', lambda: '2013-10-20') + + output_file = str(tmpdir.join('output.txt')) + assert plugins_index.main(['', '-f', output_file, '-u', DummyProxy.expected_url]) == 0 + + with file(output_file, 'rU') as f: + obtained_output = f.read() + + if obtained_output != expected_output: + obtained_file = os.path.splitext(__file__)[0] + '.obtained' + with file(obtained_file, 'w') as f: + f.write(obtained_output) + + assert obtained_output == expected_output + + +expected_output = '''\ +.. _plugins_index: + +List of Third-Party Plugins +=========================== + +==================================== ============================= ============================= =================== + Name Version Author Summary +==================================== ============================= ============================= =================== + `pytest-plugin1 `_ `1.0 `_ `someone `_ some plugin + `pytest-plugin2 `_ `1.2 `_ `other `_ some other plugin + +==================================== ============================= ============================= =================== + +*(Updated on 2013-10-20)* +''' https://bitbucket.org/hpk42/pytest/commits/0391dc207cf8/ Changeset: 0391dc207cf8 Branch: plugins-index User: nicoddemus Date: 2013-10-12 01:57:35 Summary: fixed 'PyPI' spelling Affected #: 1 file diff -r c7e580b90fc2d1f641ebf856308d30b3ea781c5a -r 0391dc207cf8b752b54be8bd98403c0cd85e6be2 doc/en/plugins_index.py --- a/doc/en/plugins_index.py +++ b/doc/en/plugins_index.py @@ -1,6 +1,6 @@ ''' Script to generate the file `plugins_index.txt` with information about pytest plugins taken directly -from a live pypi server. +from a live PyPI server. This will evolve to include test compatibility (pythons and pytest versions) information also. ''' @@ -19,7 +19,7 @@ #=================================================================================================== def iter_plugins(client, search='pytest-'): ''' - Returns an iterator of (name, version) from pypi. + Returns an iterator of (name, version) from PyPI. :param client: xmlrpclib.ServerProxy :param search: package names to search for @@ -145,7 +145,7 @@ #=================================================================================================== def generate_plugins_index(client, filename): ''' - Generates an RST file with a table of the latest pytest plugins found in pypi. + Generates an RST file with a table of the latest pytest plugins found in PyPI. :param client: xmlrpclib.ServerProxy :param filename: output filename @@ -162,9 +162,9 @@ filename = os.path.join(os.path.dirname(__file__), 'plugins_index.txt') url = 'http://pypi.python.org/pypi' - parser = OptionParser(description='Generates a restructured document of pytest plugins from PyPi') + parser = OptionParser(description='Generates a restructured document of pytest plugins from PyPI') parser.add_option('-f', '--filename', default=filename, help='output filename [default: %default]') - parser.add_option('-u', '--url', default=url, help='url of PyPi server to obtain data from [default: %default]') + parser.add_option('-u', '--url', default=url, help='url of PyPI server to obtain data from [default: %default]') (options, _) = parser.parse_args(argv[1:]) client = xmlrpclib.ServerProxy(options.url) https://bitbucket.org/hpk42/pytest/commits/965c04b42cf3/ Changeset: 965c04b42cf3 User: hpk42 Date: 2013-10-12 14:27:43 Summary: Merged in nicoddemus/pytest/plugins-index (pull request #76) Script to generate docs with a list of pytest plugins from PyPI Affected #: 3 files diff -r 76a2baa4837dfeacdeaca326b74dd918c0d031d9 -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed doc/en/plugins_index.py --- /dev/null +++ b/doc/en/plugins_index.py @@ -0,0 +1,179 @@ +''' +Script to generate the file `plugins_index.txt` with information about pytest plugins taken directly +from a live PyPI server. + +This will evolve to include test compatibility (pythons and pytest versions) information also. +''' +from collections import namedtuple +import datetime +from distutils.version import LooseVersion +import itertools +from optparse import OptionParser +import os +import sys +import xmlrpclib + + +#=================================================================================================== +# iter_plugins +#=================================================================================================== +def iter_plugins(client, search='pytest-'): + ''' + Returns an iterator of (name, version) from PyPI. + + :param client: xmlrpclib.ServerProxy + :param search: package names to search for + ''' + for plug_data in client.search({'name' : search}): + yield plug_data['name'], plug_data['version'] + + +#=================================================================================================== +# get_latest_versions +#=================================================================================================== +def get_latest_versions(plugins): + ''' + Returns an iterator of (name, version) from the given list of (name, version), but returning + only the latest version of the package. Uses distutils.LooseVersion to ensure compatibility + with PEP386. + ''' + plugins = [(name, LooseVersion(version)) for (name, version) in plugins] + for name, grouped_plugins in itertools.groupby(plugins, key=lambda x: x[0]): + name, loose_version = list(grouped_plugins)[-1] + yield name, str(loose_version) + + +#=================================================================================================== +# obtain_plugins_table +#=================================================================================================== +def obtain_plugins_table(plugins, client): + ''' + Returns information to populate a table of plugins, their versions, authors, etc. + + The returned information is a list of columns of `ColumnData` namedtuples(text, link). Link + can be None if the text for that column should not be linked to anything. + + :param plugins: list of (name, version) + :param client: xmlrpclib.ServerProxy + + ''' + rows = [] + ColumnData = namedtuple('ColumnData', 'text link') + headers = ['Name', 'Version', 'Author', 'Summary'] + + for package_name, version in plugins: + release_data = client.release_data(package_name, version) + row = ( + ColumnData(package_name, release_data['package_url']), + ColumnData(version, release_data['release_url']), + ColumnData(release_data['author'], release_data['author_email']), + ColumnData(release_data['summary'], None), + ) + assert len(row) == len(headers) + rows.append(row) + + return headers, rows + + +#=================================================================================================== +# generate_plugins_index_from_table +#=================================================================================================== +def generate_plugins_index_from_table(filename, headers, rows): + ''' + Generates a RST file with the table data given. + + :param filename: output filename + :param headers: see `obtain_plugins_table` + :param rows: see `obtain_plugins_table` + ''' + # creates a list of rows, each being a str containing appropriate column text and link + table_texts = [] + for row in rows: + column_texts = [] + for i, col_data in enumerate(row): + text = '`%s <%s>`_' % (col_data.text, col_data.link) if col_data.link else col_data.text + column_texts.append(text) + table_texts.append(column_texts) + + # compute max length of each column so we can build the rst table + column_lengths = [len(x) for x in headers] + for column_texts in table_texts: + for i, row_text in enumerate(column_texts): + column_lengths[i] = max(column_lengths[i], len(row_text) + 2) + + def get_row_limiter(char): + return ' '.join(char * length for length in column_lengths) + + with file(filename, 'w') as f: + # write welcome + print >> f, '.. _plugins_index:' + print >> f + print >> f, 'List of Third-Party Plugins' + print >> f, '===========================' + print >> f + + # table + print >> f, get_row_limiter('=') + for i, header in enumerate(headers): + print >> f, '{:^{fill}}'.format(header, fill=column_lengths[i]), + print >> f + print >> f, get_row_limiter('=') + + for column_texts in table_texts: + for i, row_text in enumerate(column_texts): + print >> f, '{:^{fill}}'.format(row_text, fill=column_lengths[i]), + print >> f + print >> f + print >> f, get_row_limiter('=') + print >> f + + print >> f, '*(Updated on %s)*' % _get_today_as_str() + + +#=================================================================================================== +# _get_today_as_str +#=================================================================================================== +def _get_today_as_str(): + ''' + internal. only exists so we can patch it in testing. + ''' + return datetime.date.today().strftime('%Y-%m-%d') + + +#=================================================================================================== +# generate_plugins_index +#=================================================================================================== +def generate_plugins_index(client, filename): + ''' + Generates an RST file with a table of the latest pytest plugins found in PyPI. + + :param client: xmlrpclib.ServerProxy + :param filename: output filename + ''' + plugins = get_latest_versions(iter_plugins(client)) + headers, rows = obtain_plugins_table(plugins, client) + generate_plugins_index_from_table(filename, headers, rows) + + +#=================================================================================================== +# main +#=================================================================================================== +def main(argv): + filename = os.path.join(os.path.dirname(__file__), 'plugins_index.txt') + url = 'http://pypi.python.org/pypi' + + parser = OptionParser(description='Generates a restructured document of pytest plugins from PyPI') + parser.add_option('-f', '--filename', default=filename, help='output filename [default: %default]') + parser.add_option('-u', '--url', default=url, help='url of PyPI server to obtain data from [default: %default]') + (options, _) = parser.parse_args(argv[1:]) + + client = xmlrpclib.ServerProxy(options.url) + generate_plugins_index(client, options.filename) + print 'OK' + return 0 + +#=================================================================================================== +# main +#=================================================================================================== +if __name__ == '__main__': + sys.exit(main(sys.argv)) diff -r 76a2baa4837dfeacdeaca326b74dd918c0d031d9 -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed doc/en/plugins_index.txt --- /dev/null +++ b/doc/en/plugins_index.txt @@ -0,0 +1,61 @@ +.. _plugins_index: + +List of Third-Party Plugins +=========================== + +================================================================================== ============================================================================ ==================================================================================== ============================================================================================================================================= + Name Version Author Summary +================================================================================== ============================================================================ ==================================================================================== ============================================================================================================================================= + `pytest-bdd `_ `0.6.1 `_ `Oleg Pidsadnyi `_ BDD for pytest + `pytest-bdd-splinter `_ `0.5.2 `_ `Oleg Pidsadnyi `_ Splinter subplugin for Pytest BDD plugin + `pytest-bench `_ `0.1.0 `_ `Concordus Applications `_ Benchmark utility that plugs into pytest. + `pytest-blockage `_ `0.1 `_ `UNKNOWN `_ Disable network requests during a test run. + `pytest-browsermob-proxy `_ `0.1 `_ `Dave Hunt `_ BrowserMob proxy plugin for py.test. + `pytest-bugzilla `_ `0.2 `_ `Noufal Ibrahim `_ py.test bugzilla integration plugin + `pytest-cache `_ `1.0 `_ `Holger Krekel `_ pytest plugin with mechanisms for caching across test runs + `pytest-capturelog `_ `0.7 `_ `Meme Dough `_ py.test plugin to capture log messages + `pytest-codecheckers `_ `0.2 `_ `Ronny Pfannschmidt `_ pytest plugin to add source code sanity checks (pep8 and friends) + `pytest-contextfixture `_ `0.1.1 `_ `Andreas Pelme `_ Define pytest fixtures as context managers. + `pytest-couchdbkit `_ `0.5.1 `_ `RonnyPfannschmidt `_ py.test extension for per-test couchdb databases using couchdbkit + `pytest-cov `_ `1.6 `_ `Meme Dough `_ py.test plugin for coverage reporting with support for both centralised and distributed testing, including subprocesses and multiprocessing + `pytest-dbfixtures `_ `0.3.8.3 `_ `Clearcode - The A Room `_ dbfixtures plugin for py.test. + `pytest-django `_ `2.3.1 `_ `Andreas Pelme `_ A Django plugin for py.test. + `pytest-django-lite `_ `0.1.0 `_ `David Cramer `_ The bare minimum to integrate py.test with Django. + `pytest-figleaf `_ `1.0 `_ `holger krekel `_ py.test figleaf coverage plugin + `pytest-flakes `_ `0.2 `_ `Florian Schulze, Holger Krekel and Ronny Pfannschmidt `_ pytest plugin to check source code with pyflakes + `pytest-greendots `_ `0.2 `_ `UNKNOWN `_ Green progress dots + `pytest-growl `_ `0.1 `_ `Anthony Long `_ Growl notifications for pytest results. + `pytest-incremental `_ `0.3.0 `_ `Eduardo Naufel Schettino `_ an incremental test runner (pytest plugin) + `pytest-instafail `_ `0.1.0 `_ `Janne Vanhala `_ py.test plugin to show failures instantly + `pytest-ipdb `_ `0.1-prerelease `_ `Matthew de Verteuil `_ A py.test plug-in to enable drop to ipdb debugger on test failure. + `pytest-konira `_ `0.2 `_ `Alfredo Deza `_ Run Konira DSL tests with py.test + `pytest-localserver `_ `0.3 `_ `Sebastian Rahlf `_ py.test plugin to test server connections locally. + `pytest-marker-bugzilla `_ `0.06 `_ `Eric Sammons `_ py.test bugzilla integration plugin, using markers + `pytest-markfiltration `_ `0.8 `_ `adam goucher `_ UNKNOWN + `pytest-marks `_ `0.4 `_ `adam goucher `_ UNKNOWN + `pytest-monkeyplus `_ `1.1.0 `_ `Virgil Dupras `_ pytest's monkeypatch subclass with extra functionalities + `pytest-mozwebqa `_ `1.1.1 `_ `Dave Hunt `_ Mozilla WebQA plugin for py.test. + `pytest-oerp `_ `0.2.0 `_ `Leonardo Santagada `_ pytest plugin to test OpenERP modules + `pytest-osxnotify `_ `0.1.4 `_ `Daniel Bader `_ OS X notifications for py.test results. + `pytest-paste-config `_ `0.1 `_ `UNKNOWN `_ Allow setting the path to a paste config file + `pytest-pep8 `_ `1.0.5 `_ `Holger Krekel and Ronny Pfannschmidt `_ pytest plugin to check PEP8 requirements + `pytest-poo `_ `0.2 `_ `Andreas Pelme `_ Visualize your crappy tests + `pytest-pydev `_ `0.1 `_ `Sebastian Rahlf `_ py.test plugin to connect to a remote debug server with PyDev or PyCharm. + `pytest-qt `_ `1.0.2 `_ `Bruno Oliveira `_ pytest plugin that adds fixtures for testing Qt (PyQt and PySide) applications. + `pytest-quickcheck `_ `0.7 `_ `Tetsuya Morimoto `_ pytest plugin to generate random data inspired by QuickCheck + `pytest-rage `_ `0.1 `_ `Leonardo Santagada `_ pytest plugin to implement PEP712 + `pytest-random `_ `0.02 `_ `Leah Klearman `_ py.test plugin to randomize tests + `pytest-rerunfailures `_ `0.03 `_ `Leah Klearman `_ py.test plugin to re-run tests to eliminate flakey failures + `pytest-runfailed `_ `0.3 `_ `Dimitri Merejkowsky `_ implement a --failed option for pytest + `pytest-runner `_ `2.0 `_ `Jason R. Coombs `_ UNKNOWN + `pytest-sugar `_ `0.2.2 `_ `Teemu, Janne Vanhala `_ py.test plugin that adds instafail, ETA and neat graphics + `pytest-timeout `_ `0.3 `_ `Floris Bruynooghe `_ pytest plugin to abort tests after a timeout + `pytest-twisted `_ `1.4 `_ `Ralf Schmitt `_ A twisted plugin for py.test. + `pytest-xdist `_ `1.9 `_ `holger krekel and contributors `_ py.test xdist plugin for distributed testing and loop-on-failing modes + `pytest-xprocess `_ `0.8 `_ `Holger Krekel `_ pytest plugin to manage external processes across test runs + `pytest-yamlwsgi `_ `0.6 `_ `Ali Afshar `_ Run tests against wsgi apps defined in yaml + `pytest-zap `_ `0.1 `_ `Dave Hunt `_ OWASP ZAP plugin for py.test. + +================================================================================== ============================================================================ ==================================================================================== ============================================================================================================================================= + +*(Updated on 2013-10-11)* diff -r 76a2baa4837dfeacdeaca326b74dd918c0d031d9 -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed doc/en/test_plugins_index.py --- /dev/null +++ b/doc/en/test_plugins_index.py @@ -0,0 +1,88 @@ +import os +import xmlrpclib + + +#=================================================================================================== +# test_plugins_index +#=================================================================================================== +def test_plugins_index(tmpdir, monkeypatch): + ''' + Blackbox testing for plugins_index script. Calls main() generating a file and compares produced + output to expected. + + .. note:: if the test fails, a file named `test_plugins_index.obtained` will be generated in + the same directory as this test file. Ensure the contents are correct and overwrite + the global `expected_output` with the new contents. + ''' + import plugins_index + + # dummy interface to xmlrpclib.ServerProxy + class DummyProxy(object): + + expected_url = 'http://dummy.pypi' + def __init__(self, url): + assert url == self.expected_url + + def search(self, query): + assert query == {'name' : 'pytest-'} + return [ + {'name': 'pytest-plugin1', 'version' : '0.8'}, + {'name': 'pytest-plugin1', 'version' : '1.0'}, + {'name': 'pytest-plugin2', 'version' : '1.2'}, + ] + + def release_data(self, package_name, version): + results = { + ('pytest-plugin1', '1.0') : { + 'package_url' : 'http://plugin1', + 'release_url' : 'http://plugin1/1.0', + 'author' : 'someone', + 'author_email' : 'someone at py.com', + 'summary' : 'some plugin', + }, + + ('pytest-plugin2', '1.2') : { + 'package_url' : 'http://plugin2', + 'release_url' : 'http://plugin2/1.2', + 'author' : 'other', + 'author_email' : 'other at py.com', + 'summary' : 'some other plugin', + }, + } + + return results[(package_name, version)] + + + monkeypatch.setattr(xmlrpclib, 'ServerProxy', DummyProxy, 'foo') + monkeypatch.setattr(plugins_index, '_get_today_as_str', lambda: '2013-10-20') + + output_file = str(tmpdir.join('output.txt')) + assert plugins_index.main(['', '-f', output_file, '-u', DummyProxy.expected_url]) == 0 + + with file(output_file, 'rU') as f: + obtained_output = f.read() + + if obtained_output != expected_output: + obtained_file = os.path.splitext(__file__)[0] + '.obtained' + with file(obtained_file, 'w') as f: + f.write(obtained_output) + + assert obtained_output == expected_output + + +expected_output = '''\ +.. _plugins_index: + +List of Third-Party Plugins +=========================== + +==================================== ============================= ============================= =================== + Name Version Author Summary +==================================== ============================= ============================= =================== + `pytest-plugin1 `_ `1.0 `_ `someone `_ some plugin + `pytest-plugin2 `_ `1.2 `_ `other `_ some other plugin + +==================================== ============================= ============================= =================== + +*(Updated on 2013-10-20)* +''' 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 Oct 12 15:39:31 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Sat, 12 Oct 2013 13:39:31 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: fix flakes issues and make --flakes run part of tox runs Message-ID: <20131012133931.3898.68924@app12.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/36e290a68860/ Changeset: 36e290a68860 User: hpk42 Date: 2013-10-12 15:39:22 Summary: fix flakes issues and make --flakes run part of tox runs Affected #: 40 files diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c _pytest/assertion/__init__.py --- a/_pytest/assertion/__init__.py +++ b/_pytest/assertion/__init__.py @@ -34,7 +34,7 @@ mode = "plain" if mode == "rewrite": try: - import ast + import ast # noqa except ImportError: mode = "reinterp" else: @@ -48,10 +48,10 @@ m = monkeypatch() config._cleanup.append(m.undo) m.setattr(py.builtin.builtins, 'AssertionError', - reinterpret.AssertionError) + reinterpret.AssertionError) # noqa hook = None if mode == "rewrite": - hook = rewrite.AssertionRewritingHook() + hook = rewrite.AssertionRewritingHook() # noqa sys.meta_path.insert(0, hook) warn_about_missing_assertion(mode) config._assertstate = AssertionState(config, mode) @@ -101,9 +101,9 @@ def _load_modules(mode): """Lazily import assertion related code.""" global rewrite, reinterpret - from _pytest.assertion import reinterpret + from _pytest.assertion import reinterpret # noqa if mode == "rewrite": - from _pytest.assertion import rewrite + from _pytest.assertion import rewrite # noqa def warn_about_missing_assertion(mode): try: diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c _pytest/assertion/rewrite.py --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -319,7 +319,7 @@ _saferepr = py.io.saferepr -from _pytest.assertion.util import format_explanation as _format_explanation +from _pytest.assertion.util import format_explanation as _format_explanation # noqa def _should_repr_global_name(obj): return not hasattr(obj, "__name__") and not py.builtin.callable(obj) @@ -557,7 +557,8 @@ for i, v in enumerate(boolop.values): if i: fail_inner = [] - self.on_failure.append(ast.If(cond, fail_inner, [])) + # cond is set in a prior loop iteration below + self.on_failure.append(ast.If(cond, fail_inner, [])) # noqa self.on_failure = fail_inner self.push_format_context() res, expl = self.visit(v) diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c _pytest/config.py --- a/_pytest/config.py +++ b/_pytest/config.py @@ -41,7 +41,7 @@ return _preinit.pop(0) # subsequent calls to main will create a fresh instance pluginmanager = PytestPluginManager() - pluginmanager.config = config = Config(pluginmanager) # XXX attr needed? + pluginmanager.config = Config(pluginmanager) # XXX attr needed? for spec in default_plugins: pluginmanager.import_plugin(spec) return pluginmanager diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c _pytest/helpconfig.py --- a/_pytest/helpconfig.py +++ b/_pytest/helpconfig.py @@ -120,7 +120,6 @@ if config.option.traceconfig: lines.append("active plugins:") - plugins = [] items = config.pluginmanager._name2plugin.items() for name, plugin in items: if hasattr(plugin, '__file__'): diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c _pytest/main.py --- a/_pytest/main.py +++ b/_pytest/main.py @@ -425,7 +425,6 @@ def _prunetraceback(self, excinfo): if hasattr(self, 'fspath'): - path = self.fspath traceback = excinfo.traceback ntraceback = traceback.cut(path=self.fspath) if ntraceback == traceback: diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c _pytest/pytester.py --- a/_pytest/pytester.py +++ b/_pytest/pytester.py @@ -26,7 +26,6 @@ def pytest_configure(config): # This might be called multiple times. Only take the first. global _pytest_fullpath - import pytest try: _pytest_fullpath except NameError: @@ -121,7 +120,6 @@ def contains(self, entries): __tracebackhide__ = True - from py.builtin import print_ i = 0 entries = list(entries) backlocals = py.std.sys._getframe(1).f_locals @@ -260,9 +258,6 @@ def makefile(self, ext, *args, **kwargs): return self._makefile(ext, args, kwargs) - def makeini(self, source): - return self.makefile('cfg', setup=source) - def makeconftest(self, source): return self.makepyfile(conftest=source) @@ -475,7 +470,7 @@ # XXX we rely on script refering to the correct environment # we cannot use "(py.std.sys.executable,script)" # becaue on windows the script is e.g. a py.test.exe - return (py.std.sys.executable, _pytest_fullpath,) + return (py.std.sys.executable, _pytest_fullpath,) # noqa else: py.test.skip("cannot run %r with --no-tools-on-path" % scriptname) diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -4,7 +4,7 @@ import sys import pytest from _pytest.main import getfslineno -from _pytest.mark import MarkDecorator, MarkInfo +from _pytest.mark import MarkDecorator from _pytest.monkeypatch import monkeypatch from py._code.code import TerminalRepr @@ -177,7 +177,6 @@ def pytest_collect_file(path, parent): ext = path.ext - pb = path.purebasename if ext == ".py": if not parent.session.isinitpath(path): for pat in parent.config.getini('python_files'): @@ -914,10 +913,6 @@ func(*args[1:], **kwargs) except ExpectedException: return py.code.ExceptionInfo() - k = ", ".join(["%s=%r" % x for x in kwargs.items()]) - if k: - k = ', ' + k - expr = '%s(%r%s)' %(getattr(func, '__name__', func), args, k) pytest.fail("DID NOT RAISE") class RaisesContext(object): @@ -1015,7 +1010,7 @@ def setup(self): # check if parametrization happend with an empty list try: - empty = self.callspec._emptyparamspecified + self.callspec._emptyparamspecified except AttributeError: pass else: @@ -1392,10 +1387,10 @@ if msg is None: fm = self.request._fixturemanager - nodeid = self.request._parentid available = [] for name, fixturedef in fm._arg2fixturedefs.items(): - faclist = list(fm._matchfactories(fixturedef, self.request._parentid)) + faclist = list(fm._matchfactories(fixturedef, + self.request._parentid)) if faclist: available.append(name) msg = "fixture %r not found" % (self.argname,) diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c _pytest/skipping.py --- a/_pytest/skipping.py +++ b/_pytest/skipping.py @@ -217,7 +217,6 @@ tr._tw.line(line) def show_simple(terminalreporter, lines, stat, format): - tw = terminalreporter._tw failed = terminalreporter.stats.get(stat) if failed: for rep in failed: diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c _pytest/standalonetemplate.py --- a/_pytest/standalonetemplate.py +++ b/_pytest/standalonetemplate.py @@ -39,7 +39,7 @@ if is_pkg: module.__path__ = [fullname] - do_exec(co, module.__dict__) + do_exec(co, module.__dict__) # noqa return sys.modules[fullname] def get_source(self, name): @@ -63,4 +63,4 @@ sys.meta_path.insert(0, importer) entry = "@ENTRY@" - do_exec(entry, locals()) + do_exec(entry, locals()) # noqa diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c _pytest/terminal.py --- a/_pytest/terminal.py +++ b/_pytest/terminal.py @@ -5,7 +5,6 @@ import pytest import py import sys -import os def pytest_addoption(parser): group = parser.getgroup("terminal reporting", "reporting", after="general") diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c doc/en/parametrize.txt --- a/doc/en/parametrize.txt +++ b/doc/en/parametrize.txt @@ -53,7 +53,8 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.2 + platform linux2 -- Python 2.7.3 -- pytest-2.4.3.dev1 + plugins: xdist, cov, pep8, xprocess, capturelog, cache, flakes, instafail collected 3 items test_expectation.py ..F @@ -74,7 +75,7 @@ E + where 54 = eval('6*9') test_expectation.py:8: AssertionError - ==================== 1 failed, 2 passed in 0.01 seconds ==================== + ==================== 1 failed, 2 passed in 0.04 seconds ==================== As designed in this example, only one pair of input/output values fails the simple test function. And as usual with test function arguments, @@ -100,12 +101,13 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.2 + platform linux2 -- Python 2.7.3 -- pytest-2.4.3.dev1 + plugins: xdist, cov, pep8, xprocess, capturelog, cache, flakes, instafail 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 +172,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 +187,7 @@ $ py.test -q -rs test_strings.py s ========================= short test summary info ========================== - SKIP [1] /home/hpk/p/pytest/.tox/regen/local/lib/python2.7/site-packages/_pytest/python.py:1024: got empty parameter set, function test_valid_string at /tmp/doc-exec-561/test_strings.py:1 + SKIP [1] /home/hpk/p/pytest/_pytest/python.py:1019: got empty parameter set, function test_valid_string at /tmp/doc-exec-686/test_strings.py:1 1 skipped in 0.01 seconds For further examples, you might want to look at :ref:`more diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/acceptance_test.py --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -1,4 +1,4 @@ -import sys, py, pytest +import py, pytest class TestGeneralUsage: def test_config_error(self, testdir): @@ -14,7 +14,7 @@ ]) def test_root_conftest_syntax_error(self, testdir): - p = testdir.makepyfile(conftest="raise SyntaxError\n") + testdir.makepyfile(conftest="raise SyntaxError\n") result = testdir.runpytest() result.stderr.fnmatch_lines(["*raise SyntaxError*"]) assert result.ret != 0 @@ -67,7 +67,7 @@ result = testdir.runpytest("-s", "asd") assert result.ret == 4 # EXIT_USAGEERROR result.stderr.fnmatch_lines(["ERROR: file not found*asd"]) - s = result.stdout.fnmatch_lines([ + result.stdout.fnmatch_lines([ "*---configure", "*---unconfigure", ]) @@ -539,7 +539,6 @@ assert result.ret == 0 for x in "123": for y in 'call',: #'setup', 'call', 'teardown': - l = [] for line in result.stdout.lines: if ("test_%s" % x) in line and y in line: break diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/python/collect.py --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -1,6 +1,4 @@ -import pytest, py, sys -from _pytest import python as funcargs -from _pytest.python import FixtureLookupError +import pytest, py class TestModule: def test_failing_import(self, testdir): @@ -32,7 +30,7 @@ def test_module_considers_pluginmanager_at_import(self, testdir): modcol = testdir.getmodulecol("pytest_plugins='xasdlkj',") - pytest.raises(ImportError, "modcol.obj") + pytest.raises(ImportError, lambda: modcol.obj) class TestClass: def test_class_with_init_skip_collect(self, testdir): @@ -606,7 +604,7 @@ return MyFunction(name, parent=collector) """) item = testdir.getitem("def test_func(): pass") - runner = item.config.pluginmanager.getplugin("runner") + item.config.pluginmanager.getplugin("runner") assert item.location == ("ABCDE", 42, "custom") def test_func_reportinfo(self, testdir): @@ -696,7 +694,7 @@ [pytest] python_functions=_test """) - p = testdir.makepyfile(""" + testdir.makepyfile(""" def _test_underscore(): pass """) diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/python/fixture.py --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -247,7 +247,7 @@ assert result.ret == 0 def test_funcarg_lookup_error(self, testdir): - p = testdir.makepyfile(""" + testdir.makepyfile(""" def test_lookup_error(unknown): pass """) @@ -307,7 +307,7 @@ def pytest_funcarg__something(request): return 1 """) - item = testdir.makepyfile(""" + testdir.makepyfile(""" def pytest_funcarg__something(request): return request.getfuncargvalue("something") + 1 def test_func(something): @@ -634,13 +634,13 @@ l.append("setup") def teardown(val): l.append("teardown") - ret1 = req1.cached_setup(setup, teardown, scope="function") + req1.cached_setup(setup, teardown, scope="function") assert l == ['setup'] # artificial call of finalizer setupstate = req1._pyfuncitem.session._setupstate setupstate._callfinalizers(item1) assert l == ["setup", "teardown"] - ret2 = req1.cached_setup(setup, teardown, scope="function") + req1.cached_setup(setup, teardown, scope="function") assert l == ["setup", "teardown", "setup"] setupstate._callfinalizers(item1) assert l == ["setup", "teardown", "setup", "teardown"] @@ -1461,7 +1461,7 @@ 'request.getfuncargvalue("arg")', 'request.cached_setup(lambda: None, scope="function")', ], ids=["getfuncargvalue", "cached_setup"]) - def test_scope_mismatch(self, testdir, method): + def test_scope_mismatch_various(self, testdir, method): testdir.makeconftest(""" import pytest finalized = [] @@ -1609,7 +1609,7 @@ """) def test_class_ordering(self, testdir): - p = testdir.makeconftest(""" + testdir.makeconftest(""" import pytest l = [] diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/python/integration.py --- a/testing/python/integration.py +++ b/testing/python/integration.py @@ -1,4 +1,4 @@ -import pytest, py, sys +import pytest from _pytest import runner class TestOEJSKITSpecials: diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/python/metafunc.py --- a/testing/python/metafunc.py +++ b/testing/python/metafunc.py @@ -1,7 +1,6 @@ -import pytest, py, sys +import pytest, py from _pytest import python as funcargs -from _pytest.python import FixtureLookupError class TestMetafunc: def Metafunc(self, func): diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/python/raises.py --- a/testing/python/raises.py +++ b/testing/python/raises.py @@ -29,7 +29,7 @@ def test_raises_flip_builtin_AssertionError(self): # we replace AssertionError on python level # however c code might still raise the builtin one - from _pytest.assertion.util import BuiltinAssertionError + from _pytest.assertion.util import BuiltinAssertionError # noqa pytest.raises(AssertionError,""" raise BuiltinAssertionError """) diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_assertion.py --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -2,7 +2,7 @@ import py, pytest import _pytest.assertion as plugin -from _pytest.assertion import reinterpret, util +from _pytest.assertion import reinterpret needsnewassert = pytest.mark.skipif("sys.version_info < (2,6)") @@ -353,7 +353,7 @@ @pytest.mark.skipif("sys.version_info < (2,5) or '__pypy__' in sys.builtin_module_names or sys.platform.startswith('java')" ) def test_warn_missing(testdir): - p1 = testdir.makepyfile("") + testdir.makepyfile("") result = testdir.run(sys.executable, "-OO", "-m", "pytest", "-h") result.stderr.fnmatch_lines([ "*WARNING*assert statements are not executed*", diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_assertrewrite.py --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -107,13 +107,13 @@ assert f assert getmsg(f) == "assert False" def f(): - assert a_global + assert a_global # noqa assert getmsg(f, {"a_global" : False}) == "assert False" def f(): assert sys == 42 assert getmsg(f, {"sys" : sys}) == "assert sys == 42" def f(): - assert cls == 42 + assert cls == 42 # noqa class X(object): pass assert getmsg(f, {"cls" : X}) == "assert cls == 42" @@ -174,7 +174,7 @@ def test_short_circut_evaluation(self): def f(): - assert True or explode + assert True or explode # noqa getmsg(f, must_pass=True) def f(): x = 1 @@ -206,7 +206,6 @@ assert x + y assert getmsg(f) == "assert (1 + -1)" def f(): - x = range(10) assert not 5 % 4 assert getmsg(f) == "assert not (5 % 4)" @@ -243,12 +242,12 @@ g = 3 ns = {"x" : X} def f(): - assert not x.g + assert not x.g # noqa assert getmsg(f, ns) == """assert not 3 + where 3 = x.g""" def f(): - x.a = False - assert x.a + x.a = False # noqa + assert x.a # noqa assert getmsg(f, ns) == """assert x.a""" def test_comparisons(self): @@ -435,7 +434,7 @@ def test_missing(): assert not __loader__.is_package('pytest_not_there') """) - pkg = testdir.mkpydir('fun') + testdir.mkpydir('fun') result = testdir.runpytest() result.stdout.fnmatch_lines([ '* 3 passed*', diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_collection.py --- a/testing/test_collection.py +++ b/testing/test_collection.py @@ -242,7 +242,7 @@ assert "passed" in result.stdout.str() def test_pytest_fs_collect_hooks_are_seen(self, testdir): - conf = testdir.makeconftest(""" + testdir.makeconftest(""" import pytest class MyModule(pytest.Module): pass @@ -250,8 +250,8 @@ if path.ext == ".py": return MyModule(path, parent) """) - sub = testdir.mkdir("sub") - p = testdir.makepyfile("def test_x(): pass") + testdir.mkdir("sub") + testdir.makepyfile("def test_x(): pass") result = testdir.runpytest("--collect-only") result.stdout.fnmatch_lines([ "*MyModule*", @@ -318,7 +318,7 @@ topdir = testdir.tmpdir rcol = Session(config) assert topdir == rcol.fspath - rootid = rcol.nodeid + #rootid = rcol.nodeid #root2 = rcol.perform_collect([rcol.nodeid], genitems=False)[0] #assert root2 == rcol, rootid colitems = rcol.perform_collect([rcol.nodeid], genitems=False) @@ -329,13 +329,13 @@ def test_collect_protocol_single_function(self, testdir): p = testdir.makepyfile("def test_func(): pass") id = "::".join([p.basename, "test_func"]) - topdir = testdir.tmpdir items, hookrec = testdir.inline_genitems(id) item, = items assert item.name == "test_func" newid = item.nodeid assert newid == id py.std.pprint.pprint(hookrec.hookrecorder.calls) + topdir = testdir.tmpdir # noqa hookrec.hookrecorder.contains([ ("pytest_collectstart", "collector.fspath == topdir"), ("pytest_make_collect_report", "collector.fspath == topdir"), @@ -436,7 +436,7 @@ ]) def test_serialization_byid(self, testdir): - p = testdir.makepyfile("def test_func(): pass") + testdir.makepyfile("def test_func(): pass") items, hookrec = testdir.inline_genitems() assert len(items) == 1 item, = items diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_config.py --- a/testing/test_config.py +++ b/testing/test_config.py @@ -16,7 +16,7 @@ assert config.inicfg['name'] == 'value' def test_getcfg_empty_path(self, tmpdir): - cfg = getcfg([''], ['setup.cfg']) #happens on py.test "" + getcfg([''], ['setup.cfg']) #happens on py.test "" def test_append_parse_args(self, testdir, tmpdir): tmpdir.join("setup.cfg").write(py.code.Source(""" @@ -31,7 +31,7 @@ #assert len(args) == 1 def test_tox_ini_wrong_version(self, testdir): - p = testdir.makefile('.ini', tox=""" + testdir.makefile('.ini', tox=""" [pytest] minversion=9.0 """) @@ -77,7 +77,7 @@ class TestConfigCmdlineParsing: def test_parsing_again_fails(self, testdir): config = testdir.parseconfig() - pytest.raises(AssertionError, "config.parse([])") + pytest.raises(AssertionError, lambda: config.parse([])) class TestConfigAPI: @@ -200,7 +200,7 @@ parser.addini("args", "new args", type="args") parser.addini("a2", "", "args", default="1 2 3".split()) """) - p = testdir.makeini(""" + testdir.makeini(""" [pytest] args=123 "123 hello" "this" """) @@ -217,7 +217,7 @@ parser.addini("xy", "", type="linelist") parser.addini("a2", "", "linelist") """) - p = testdir.makeini(""" + testdir.makeini(""" [pytest] xy= 123 345 second line @@ -234,7 +234,7 @@ def pytest_addoption(parser): parser.addini("xy", "", type="linelist") """) - p = testdir.makeini(""" + testdir.makeini(""" [pytest] xy= 123 """) diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_conftest.py --- a/testing/test_conftest.py +++ b/testing/test_conftest.py @@ -8,7 +8,7 @@ def pytest_funcarg__basedir(request): def basedirmaker(request): - basedir = d = request.getfuncargvalue("tmpdir") + d = request.getfuncargvalue("tmpdir") d.ensure("adir/conftest.py").write("a=1 ; Directory = 3") d.ensure("adir/b/conftest.py").write("b=2 ; a = 1.5") if request.param == "inpackage": @@ -41,7 +41,7 @@ def test_immediate_initialiation_and_incremental_are_the_same(self, basedir): conftest = Conftest() - snap0 = len(conftest._path2confmods) + len(conftest._path2confmods) conftest.getconftestmodules(basedir) snap1 = len(conftest._path2confmods) #assert len(conftest._path2confmods) == snap1 + 1 @@ -57,7 +57,7 @@ def test_value_access_not_existing(self, basedir): conftest = ConftestWithSetinitial(basedir) - pytest.raises(KeyError, "conftest.rget('a')") + pytest.raises(KeyError, lambda: conftest.rget('a')) #pytest.raises(KeyError, "conftest.lget('a')") def test_value_access_by_path(self, basedir): @@ -97,7 +97,7 @@ tmpdir.ensure("adir-1.0/b/conftest.py").write("b=2 ; a = 1.5") tmpdir.ensure("adir-1.0/b/__init__.py") tmpdir.ensure("adir-1.0/__init__.py") - conftest = ConftestWithSetinitial(tmpdir.join("adir-1.0", "b")) + ConftestWithSetinitial(tmpdir.join("adir-1.0", "b")) def test_doubledash_not_considered(testdir): conf = testdir.mkdir("--option") diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_core.py --- a/testing/test_core.py +++ b/testing/test_core.py @@ -8,13 +8,12 @@ def test_consider_env_fails_to_import(self, monkeypatch): pluginmanager = PluginManager() monkeypatch.setenv('PYTEST_PLUGINS', 'nonexisting', prepend=",") - pytest.raises(ImportError, "pluginmanager.consider_env()") + pytest.raises(ImportError, lambda: pluginmanager.consider_env()) def test_preparse_args(self): pluginmanager = PluginManager() - pytest.raises(ImportError, """ - pluginmanager.consider_preparse(["xyz", "-p", "hello123"]) - """) + pytest.raises(ImportError, lambda: + pluginmanager.consider_preparse(["xyz", "-p", "hello123"])) def test_plugin_prevent_register(self): pluginmanager = PluginManager() @@ -93,7 +92,7 @@ # ok, we did not explode def test_pluginmanager_ENV_startup(self, testdir, monkeypatch): - x500 = testdir.makepyfile(pytest_x500="#") + testdir.makepyfile(pytest_x500="#") p = testdir.makepyfile(""" import pytest def test_hello(pytestconfig): @@ -110,7 +109,7 @@ pytest.raises(ImportError, 'pluginmanager.import_plugin("qweqwex.y")') pytest.raises(ImportError, 'pluginmanager.import_plugin("pytest_qweqwx.y")') - reset = testdir.syspathinsert() + testdir.syspathinsert() pluginname = "pytest_hello" testdir.makepyfile(**{pluginname: ""}) pluginmanager.import_plugin("pytest_hello") @@ -128,7 +127,7 @@ pytest.raises(ImportError, 'pluginmanager.import_plugin("qweqwex.y")') pytest.raises(ImportError, 'pluginmanager.import_plugin("pytest_qweqwex.y")') - reset = testdir.syspathinsert() + testdir.syspathinsert() testdir.mkpydir("pkg").join("plug.py").write("x=3") pluginname = "pkg.plug" pluginmanager.import_plugin(pluginname) @@ -170,7 +169,7 @@ def test_consider_conftest_deps(self, testdir): mod = testdir.makepyfile("pytest_plugins='xyz'").pyimport() pp = PluginManager() - pytest.raises(ImportError, "pp.consider_conftest(mod)") + pytest.raises(ImportError, lambda: pp.consider_conftest(mod)) def test_pm(self): pp = PluginManager() @@ -210,9 +209,7 @@ l = pp.getplugins() assert mod in l pytest.raises(ValueError, "pp.register(mod)") - mod2 = py.std.types.ModuleType("pytest_hello") - #pp.register(mod2) # double pm - pytest.raises(ValueError, "pp.register(mod)") + pytest.raises(ValueError, lambda: pp.register(mod)) #assert not pp.isregistered(mod2) assert pp.getplugins() == l @@ -229,14 +226,14 @@ class hello: def pytest_gurgel(self): pass - pytest.raises(Exception, "pp.register(hello())") + pytest.raises(Exception, lambda: pp.register(hello())) def test_register_mismatch_arg(self): pp = get_plugin_manager() class hello: def pytest_configure(self, asd): pass - excinfo = pytest.raises(Exception, "pp.register(hello())") + pytest.raises(Exception, lambda: pp.register(hello())) def test_register(self): pm = get_plugin_manager() @@ -293,7 +290,7 @@ class TestPytestPluginInteractions: def test_addhooks_conftestplugin(self, testdir): - newhooks = testdir.makepyfile(newhooks=""" + testdir.makepyfile(newhooks=""" def pytest_myhook(xyz): "new hook" """) @@ -312,7 +309,7 @@ assert res == [11] def test_addhooks_nohooks(self, testdir): - conf = testdir.makeconftest(""" + testdir.makeconftest(""" import sys def pytest_addhooks(pluginmanager): pluginmanager.addhooks(sys) @@ -431,7 +428,7 @@ def test_varnames(): def f(x): - i = 3 + i = 3 # noqa class A: def f(self, y): pass @@ -496,7 +493,7 @@ def test_tags_call_error(self): multicall = MultiCall([lambda x: x], {}) - pytest.raises(TypeError, "multicall.execute()") + pytest.raises(TypeError, multicall.execute) def test_call_subexecute(self): def m(__multicall__): @@ -544,7 +541,7 @@ def hello(self, arg): "api hook 1" mcm = HookRelay(hookspecs=Api, pm=pm, prefix="he") - pytest.raises(TypeError, "mcm.hello(3)") + pytest.raises(TypeError, lambda: mcm.hello(3)) def test_firstresult_definition(self): pm = PluginManager() diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_doctest.py --- a/testing/test_doctest.py +++ b/testing/test_doctest.py @@ -99,7 +99,7 @@ reprec.assertoutcome(failed=1) def test_doctest_unexpected_exception(self, testdir): - p = testdir.maketxtfile(""" + testdir.maketxtfile(""" >>> i = 0 >>> 0 / i 2 @@ -136,7 +136,7 @@ testdir.tmpdir.join("hello.py").write(py.code.Source(""" import asdalsdkjaslkdjasd """)) - p = testdir.maketxtfile(""" + testdir.maketxtfile(""" >>> import hello >>> """) diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_genscript.py --- a/testing/test_genscript.py +++ b/testing/test_genscript.py @@ -1,6 +1,5 @@ import pytest -import py, os, sys -import subprocess +import sys @pytest.fixture(scope="module") diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_helpconfig.py --- a/testing/test_helpconfig.py +++ b/testing/test_helpconfig.py @@ -1,4 +1,4 @@ -import py, pytest,os +import py, pytest from _pytest.helpconfig import collectattr def test_version(testdir, pytestconfig): diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_junitxml.py --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -1,4 +1,3 @@ -import pytest from xml.dom import minidom import py, sys, os @@ -370,7 +369,7 @@ assert False """) xmlf = testdir.tmpdir.join('junit.xml') - result = testdir.runpytest('--junitxml=%s' % xmlf) + testdir.runpytest('--junitxml=%s' % xmlf) text = xmlf.read() assert '\x00' not in text assert '#x00' in text @@ -386,7 +385,7 @@ assert False """) xmlf = testdir.tmpdir.join('junit.xml') - result = testdir.runpytest('--junitxml=%s' % xmlf) + testdir.runpytest('--junitxml=%s' % xmlf) text = xmlf.read() assert '#x0' in text @@ -405,7 +404,6 @@ unichr(65) except NameError: unichr = chr - u = py.builtin._totext invalid = (0x00, 0x1, 0xB, 0xC, 0xE, 0x19, 27, # issue #126 0xD800, 0xDFFF, 0xFFFE, 0x0FFFF) #, 0x110000) diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_mark.py --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -13,7 +13,7 @@ def test_pytest_mark_notcallable(self): mark = Mark() - pytest.raises((AttributeError, TypeError), "mark()") + pytest.raises((AttributeError, TypeError), mark) def test_pytest_mark_bare(self): mark = Mark() @@ -35,7 +35,7 @@ mark = Mark() def f(): pass - marker = mark.world + mark.world mark.world(x=3)(f) assert f.world.kwargs['x'] == 3 mark.world(y=4)(f) @@ -374,7 +374,7 @@ assert len(deselected_tests) == 2 def test_keywords_at_node_level(self, testdir): - p = testdir.makepyfile(""" + testdir.makepyfile(""" import pytest @pytest.fixture(scope="session", autouse=True) def some(request): diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_nose.py --- a/testing/test_nose.py +++ b/testing/test_nose.py @@ -96,7 +96,7 @@ def test_nose_setup_func_failure_2(testdir): - p = testdir.makepyfile(""" + testdir.makepyfile(""" l = [] my_setup = 1 diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_parseopt.py --- a/testing/test_parseopt.py +++ b/testing/test_parseopt.py @@ -3,7 +3,6 @@ import os import py, pytest from _pytest import config as parseopt -from textwrap import dedent @pytest.fixture def parser(): @@ -12,7 +11,7 @@ class TestParser: def test_no_help_by_default(self, capsys): parser = parseopt.Parser(usage="xyz") - pytest.raises(SystemExit, 'parser.parse(["-h"])') + pytest.raises(SystemExit, lambda: parser.parse(["-h"])) out, err = capsys.readouterr() assert err.find("error: unrecognized arguments") != -1 @@ -65,9 +64,9 @@ assert group2 is group def test_group_ordering(self, parser): - group0 = parser.getgroup("1") - group1 = parser.getgroup("2") - group1 = parser.getgroup("3", after="1") + parser.getgroup("1") + parser.getgroup("2") + parser.getgroup("3", after="1") groups = parser._groups groups_names = [x.name for x in groups] assert groups_names == list("132") @@ -104,7 +103,7 @@ assert getattr(args, parseopt.FILE_OR_DIR)[0] == py.path.local() def test_parse_known_args(self, parser): - args = parser.parse_known_args([py.path.local()]) + parser.parse_known_args([py.path.local()]) parser.addoption("--hello", action="store_true") ns = parser.parse_known_args(["x", "--y", "--hello", "this"]) assert ns.hello @@ -114,7 +113,7 @@ option = parser.parse([]) assert option.hello == "x" del option.hello - args = parser.parse_setoption([], option) + parser.parse_setoption([], option) assert option.hello == "x" def test_parse_setoption(self, parser): @@ -128,7 +127,7 @@ assert not args def test_parse_special_destination(self, parser): - x = parser.addoption("--ultimate-answer", type=int) + parser.addoption("--ultimate-answer", type=int) args = parser.parse(['--ultimate-answer', '42']) assert args.ultimate_answer == 42 diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_pastebin.py --- a/testing/test_pastebin.py +++ b/testing/test_pastebin.py @@ -1,4 +1,3 @@ -import pytest class TestPasting: def pytest_funcarg__pastebinlist(self, request): @@ -56,4 +55,4 @@ assert proxy is not None assert proxy.__class__.__module__.startswith('xmlrpc') - + diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_pdb.py --- a/testing/test_pdb.py +++ b/testing/test_pdb.py @@ -1,4 +1,4 @@ -import py, pytest +import py import sys from test_doctest import xfail_if_pdbpp_installed @@ -162,7 +162,7 @@ child.send("capsys.readouterr()\n") child.expect("hello1") child.sendeof() - rest = child.read() + child.read() if child.isalive(): child.wait() diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_pytester.py --- a/testing/test_pytester.py +++ b/testing/test_pytester.py @@ -1,7 +1,7 @@ import py import pytest -import os, sys -from _pytest.pytester import LineMatcher, LineComp, HookRecorder +import os +from _pytest.pytester import HookRecorder from _pytest.core import PluginManager def test_reportrecorder(testdir): @@ -56,7 +56,6 @@ def test_parseconfig(testdir): - import py config1 = testdir.parseconfig() config2 = testdir.parseconfig() assert config2 != config1 diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_runner.py --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -1,6 +1,5 @@ import pytest, py, sys, os from _pytest import runner, main -from py._code.code import ReprExceptionInfo class TestSetupState: def test_setup(self, testdir): @@ -39,10 +38,11 @@ def setup_module(mod): raise ValueError(42) def test_func(): pass - """) + """) # noqa ss = runner.SetupState() - pytest.raises(ValueError, "ss.prepare(item)") - pytest.raises(ValueError, "ss.prepare(item)") + pytest.raises(ValueError, lambda: ss.prepare(item)) + pytest.raises(ValueError, lambda: ss.prepare(item)) + class BaseFunctionalTests: def test_passfunction(self, testdir): @@ -428,7 +428,7 @@ def f(): importorskip("asdlkj") try: - sys = importorskip("sys") + sys = importorskip("sys") # noqa assert sys == py.std.sys #path = py.test.importorskip("os.path") #assert path == py.std.os.path @@ -464,7 +464,7 @@ """) import subprocess popen = subprocess.Popen([sys.executable, str(p)], stdout=subprocess.PIPE) - s = popen.stdout.read() + popen.communicate() ret = popen.wait() assert ret == 0 diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_session.py --- a/testing/test_session.py +++ b/testing/test_session.py @@ -204,7 +204,7 @@ def test_plugin_specify(testdir): testdir.chdir() - config = pytest.raises(ImportError, """ + pytest.raises(ImportError, """ testdir.parseconfig("-p", "nqweotexistent") """) #pytest.raises(ImportError, diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_skipping.py --- a/testing/test_skipping.py +++ b/testing/test_skipping.py @@ -1,8 +1,7 @@ import pytest import sys -from _pytest.skipping import MarkEvaluator, folded_skips -from _pytest.skipping import pytest_runtest_setup +from _pytest.skipping import MarkEvaluator, folded_skips, pytest_runtest_setup from _pytest.runner import runtestprotocol class TestEvaluator: @@ -108,7 +107,7 @@ pass """) ev = MarkEvaluator(item, 'skipif') - exc = pytest.raises(pytest.fail.Exception, "ev.istrue()") + exc = pytest.raises(pytest.fail.Exception, ev.istrue) assert """Failed: you need to specify reason=STRING when using booleans as conditions.""" in exc.value.msg def test_skipif_class(self, testdir): @@ -189,7 +188,7 @@ def test_this(): assert 0 """) - result = testdir.runpytest(p, '-v') + testdir.runpytest(p, '-v') #result.stdout.fnmatch_lines([ # "*HINT*use*-r*" #]) @@ -370,8 +369,9 @@ @pytest.mark.skipif("hasattr(os, 'sep')") def test_func(): pass - """) - x = pytest.raises(pytest.skip.Exception, "pytest_runtest_setup(item)") + """) # noqa + x = pytest.raises(pytest.skip.Exception, lambda: + pytest_runtest_setup(item)) assert x.value.msg == "condition: hasattr(os, 'sep')" diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_terminal.py --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -39,7 +39,7 @@ class TestTerminal: def test_pass_skip_fail(self, testdir, option): - p = testdir.makepyfile(""" + testdir.makepyfile(""" import pytest def test_ok(): pass @@ -76,7 +76,6 @@ def test_writeline(self, testdir, linecomp): modcol = testdir.getmodulecol("def test_one(): pass") - stringio = py.io.TextIO() rep = TerminalReporter(modcol.config, file=linecomp.stringio) rep.write_fspath_result(py.path.local("xy.py"), '.') rep.write_line("hello world") @@ -97,7 +96,7 @@ ]) def test_runtest_location_shown_before_test_starts(self, testdir): - p1 = testdir.makepyfile(""" + testdir.makepyfile(""" def test_1(): import time time.sleep(20) @@ -108,7 +107,7 @@ child.kill(15) def test_itemreport_subclasses_show_subclassed_file(self, testdir): - p1 = testdir.makepyfile(test_p1=""" + testdir.makepyfile(test_p1=""" class BaseTests: def test_p1(self): pass @@ -145,7 +144,7 @@ assert " <- " not in result.stdout.str() def test_keyboard_interrupt(self, testdir, option): - p = testdir.makepyfile(""" + testdir.makepyfile(""" def test_foobar(): assert 0 def test_spamegg(): @@ -172,7 +171,7 @@ def pytest_sessionstart(): raise KeyboardInterrupt """) - p = testdir.makepyfile(""" + testdir.makepyfile(""" def test_foobar(): pass """) @@ -214,7 +213,7 @@ ]) def test_collectonly_fatal(self, testdir): - p1 = testdir.makeconftest(""" + testdir.makeconftest(""" def pytest_collectstart(collector): assert 0, "urgs" """) @@ -233,7 +232,6 @@ pass """) result = testdir.runpytest("--collect-only", p) - stderr = result.stderr.str().strip() #assert stderr.startswith("inserting into sys.path") assert result.ret == 0 result.stdout.fnmatch_lines([ @@ -247,7 +245,6 @@ def test_collectonly_error(self, testdir): p = testdir.makepyfile("import Errlkjqweqwe") result = testdir.runpytest("--collect-only", p) - stderr = result.stderr.str().strip() assert result.ret == 1 result.stdout.fnmatch_lines(py.code.Source(""" *ERROR* @@ -293,7 +290,7 @@ class TestFixtureReporting: def test_setup_fixture_error(self, testdir): - p = testdir.makepyfile(""" + testdir.makepyfile(""" def setup_function(function): print ("setup func") assert 0 @@ -311,7 +308,7 @@ assert result.ret != 0 def test_teardown_fixture_error(self, testdir): - p = testdir.makepyfile(""" + testdir.makepyfile(""" def test_nada(): pass def teardown_function(function): @@ -329,7 +326,7 @@ ]) def test_teardown_fixture_error_and_test_failure(self, testdir): - p = testdir.makepyfile(""" + testdir.makepyfile(""" def test_fail(): assert 0, "failingfunc" @@ -403,7 +400,7 @@ assert result.ret == 0 def test_header_trailer_info(self, testdir): - p1 = testdir.makepyfile(""" + testdir.makepyfile(""" def test_passes(): pass """) @@ -486,18 +483,18 @@ def test_fail_extra_reporting(testdir): - p = testdir.makepyfile("def test_this(): assert 0") - result = testdir.runpytest(p) + testdir.makepyfile("def test_this(): assert 0") + result = testdir.runpytest() assert 'short test summary' not in result.stdout.str() - result = testdir.runpytest(p, '-rf') + result = testdir.runpytest('-rf') result.stdout.fnmatch_lines([ "*test summary*", "FAIL*test_fail_extra_reporting*", ]) def test_fail_reporting_on_pass(testdir): - p = testdir.makepyfile("def test_this(): assert 1") - result = testdir.runpytest(p, '-rf') + testdir.makepyfile("def test_this(): assert 1") + result = testdir.runpytest('-rf') assert 'short test summary' not in result.stdout.str() def test_getreportopt(): @@ -522,7 +519,7 @@ def test_terminalreporter_reportopt_addopts(testdir): testdir.makeini("[pytest]\naddopts=-rs") - p = testdir.makepyfile(""" + testdir.makepyfile(""" def pytest_funcarg__tr(request): tr = request.config.pluginmanager.getplugin("terminalreporter") return tr @@ -570,7 +567,7 @@ provider to run e.g. distributed tests. """ def test_collect_fail(self, testdir, option): - p = testdir.makepyfile("import xyz\n") + testdir.makepyfile("import xyz\n") result = testdir.runpytest(*option.args) result.stdout.fnmatch_lines([ "> import xyz", @@ -579,7 +576,7 @@ ]) def test_maxfailures(self, testdir, option): - p = testdir.makepyfile(""" + testdir.makepyfile(""" def test_1(): assert 0 def test_2(): @@ -597,7 +594,7 @@ def test_tb_option(self, testdir, option): - p = testdir.makepyfile(""" + testdir.makepyfile(""" import pytest def g(): raise IndexError @@ -678,7 +675,7 @@ ]) def test_tbstyle_native_setup_error(testdir): - p = testdir.makepyfile(""" + testdir.makepyfile(""" import pytest @pytest.fixture def setup_error_fixture(): diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_tmpdir.py --- a/testing/test_tmpdir.py +++ b/testing/test_tmpdir.py @@ -1,5 +1,4 @@ import py, pytest -import os from _pytest.tmpdir import tmpdir, TempdirHandler diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c testing/test_unittest.py --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -15,7 +15,7 @@ assert reprec.matchreport("test_failing").failed def test_runTest_method(testdir): - testpath=testdir.makepyfile(""" + testdir.makepyfile(""" import unittest pytest_plugins = "pytest_unittest" class MyTestCaseWithRunTest(unittest.TestCase): diff -r 965c04b42cf3700c55efb7d2c4dd5eb2fa0c2eed -r 36e290a688601af52828e26b99d3a0f92ee2308c tox.ini --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] distshare={homedir}/.tox/distshare -envlist=py25,py26,py27,py27-nobyte,py32,py33,py27-xdist,trial +envlist=flakes,py25,py26,py27,py27-nobyte,py32,py33,py27-xdist,trial [testenv] changedir=testing @@ -17,6 +17,11 @@ setenv = PIP_INSECURE=1 +[testenv:flakes] +changedir= +deps = pytest-flakes>=0.2 +commands = py.test --flakes -m flakes _pytest testing + [testenv:py27-xdist] changedir=. basepython=python2.7 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 Oct 14 12:05:02 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 14 Oct 2013 10:05:02 -0000 Subject: [Pytest-commit] commit/tox: hpk42: fix parsing/escaping bugs on windows32 Message-ID: <20131014100502.22176.48757@app11.ash-private.bitbucket.org> 1 new commit in tox: https://bitbucket.org/hpk42/tox/commits/88a503e7e5ae/ Changeset: 88a503e7e5ae User: hpk42 Date: 2013-10-14 12:04:28 Summary: fix parsing/escaping bugs on windows32 Affected #: 3 files diff -r df35850bb8d3d8a482f4415a6cab86dad23c951a -r 88a503e7e5aefe509be8f6c3108a84baa20c3c26 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,8 @@ - fix issue128: enable full substitution in install_command, thanks for the PR to Ronald Evers +- fix windows parsing/escaping + 1.6.1 ----- diff -r df35850bb8d3d8a482f4415a6cab86dad23c951a -r 88a503e7e5aefe509be8f6c3108a84baa20c3c26 tests/test_config.py --- a/tests/test_config.py +++ b/tests/test_config.py @@ -243,6 +243,16 @@ assert x == [["cmd1", "with space", "grr"], ["cmd2", "grr"]] + def test_argvlist_windows_escaping(self, tmpdir, newconfig): + config = newconfig(""" + [section] + comm = py.test {posargs} + """) + reader = IniReader(config._cfg) + reader.addsubstitutions([r"hello\this"]) + argv = reader.getargv("section", "comm") + assert argv == ["py.test", "hello\\this"] + def test_argvlist_multiline(self, tmpdir, newconfig): config = newconfig(""" [section] @@ -1077,3 +1087,15 @@ p = CommandParser(cmd) parsed = list(p.words()) assert parsed == ['nosetests', ' ', '-v', ' ', '-a', ' ', '!deferred', ' ', '--with-doctest', ' ', '[]'] + +def test_argv_unquote_single_args(): + argv = ["hello", '"hello2"', "'hello3'"] + newargv = unquote_single_args(argv) + assert newargv == ["hello", "hello2", "hello3"] + +def test_argv_roundrobin(): + argv = ["hello", "this\\that"] + assert string2argv(argv2string(argv)) == argv + argv = ["hello world"] + assert string2argv(argv2string(argv)) == argv + diff -r df35850bb8d3d8a482f4415a6cab86dad23c951a -r 88a503e7e5aefe509be8f6c3108a84baa20c3c26 tox/_config.py --- a/tox/_config.py +++ b/tox/_config.py @@ -14,6 +14,7 @@ import tox +iswin32 = sys.platform == "win32" defaultenvs = {'jython': 'jython', 'pypy': 'pypy'} for _name in "py,py24,py25,py26,py27,py30,py31,py32,py33,py34".split(","): @@ -487,7 +488,7 @@ command = self.getdefault( section, name, default=default, replace=replace) - return shlex.split(command.strip()) + return string2argv(command.strip()) def getbool(self, section, name, default=None): s = self.getdefault(section, name, default) @@ -533,7 +534,7 @@ posargs = self._subs.get('_posargs', None) if posargs: - return " ".join(posargs) + return argv2string(posargs) value = value_func() if value: @@ -704,3 +705,19 @@ if 'HUDSON_URL' in os.environ: return 'jenkins' return None + + +def unquote_single_args(argv): + newargv = [] + for arg in argv: + if len(arg) >=2 and arg[0] == arg[-1]: + if arg[0] in ("'", '"'): + arg = arg[1:-1] + newargv.append(arg) + return newargv + +def string2argv(cmd): + return unquote_single_args(shlex.split(cmd, posix=False)) + +def argv2string(argv): + return subprocess.list2cmdline(argv) 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 Oct 15 13:46:05 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 15 Oct 2013 11:46:05 -0000 Subject: [Pytest-commit] commit/pytest: flub: Correct hyperlink and target Message-ID: <20131015114605.4109.7576@app05.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/d499d1efe1d6/ Changeset: d499d1efe1d6 User: flub Date: 2013-10-15 13:45:55 Summary: Correct hyperlink and target Affected #: 1 file diff -r 36e290a688601af52828e26b99d3a0f92ee2308c -r d499d1efe1d677b3d7db8aa7a1f9e1bf5e21e7ea doc/en/skipping.txt --- a/doc/en/skipping.txt +++ b/doc/en/skipping.txt @@ -70,7 +70,8 @@ where you define the markers which you then consistently apply throughout your test suite. -Alternatively, the pre pytest-2.4 way to specify `condition strings `_ instead of booleans will remain fully supported in future +Alternatively, the pre pytest-2.4 way to specify :ref:`condition strings +` instead of booleans will remain fully supported in future versions of pytest. It couldn't be easily used for importing markers between test modules so it's no longer advertised as the primary method. @@ -232,7 +233,7 @@ module's ``__version__`` attribute. -.. _`string conditions`: +.. _string conditions: specifying conditions as strings versus booleans ---------------------------------------------------------- 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 Oct 21 10:11:21 2013 From: issues-reply at bitbucket.org (=?utf-8?q?Jorgen_Sch=C3=A4fer?=) Date: Mon, 21 Oct 2013 08:11:21 -0000 Subject: [Pytest-commit] Issue #129: py33 environment uses python2.7 virtualenv.py? (hpk42/tox) Message-ID: <20131021081121.9575.2794@app02.ash-private.bitbucket.org> New issue 129: py33 environment uses python2.7 virtualenv.py? https://bitbucket.org/hpk42/tox/issue/129/py33-environment-uses-python27 Jorgen Sch?fer: I'm using tox in a pretty simple setup, and can't get it to run with the py33 environment. It is quite likely that this is a bad setup on my local system, but I can't figure out why it is doing what it is doing. ``` $ cat setup.py #!/usr/bin/env python from setuptools import setup, find_packages setup(name="test") $ cat tox.ini [tox] envlist = py33 [testenv] commands = ls $ tox GLOB sdist-make: /tmp/tox-test/setup.py py33 create: /tmp/tox-test/.tox/py33 ERROR: invocation failed, logfile: /tmp/tox-test/.tox/py33/log/py33-0.log ERROR: actionid=py33 msg=getenv cmdargs=['/home/forcer/bin/python3.3', '/home/forcer/.local/lib/python2.7/site-packages/virtualenv.py', '--setuptools', '--python', '/home/forcer/bin/python3.3', 'py33'] env=[...] Already using interpreter /home/forcer/bin/python3.3 Traceback (most recent call last): File "/home/forcer/.local/lib/python2.7/site-packages/virtualenv.py", line 2308, in main() File "/home/forcer/.local/lib/python2.7/site-packages/virtualenv.py", line 821, in main symlink=options.symlink) File "/home/forcer/.local/lib/python2.7/site-packages/virtualenv.py", line 952, in create_environment home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir) File "/home/forcer/.local/lib/python2.7/site-packages/virtualenv.py", line 1017, in path_locations inc_dir = join(home_dir, 'include', stdout.strip(), py_version + abiflags) File "/home/forcer/Programs/Python/python3.3/lib/python3.3/posixpath.py", line 92, in join "components.") from None TypeError: Can't mix strings and bytes in path components. ERROR: InvocationError: /home/forcer/bin/python3.3 /home/forcer/.local/lib/python2.7/site-packages/virtualenv.py --setuptools --python /home/forcer/bin/python3.3 py33 (see /tmp/tox-test/.tox/py33/log/py33-0.log) ___________________________________ summary ____________________________________ ERROR: py33: InvocationError: /home/forcer/bin/python3.3 /home/forcer/.local/lib/python2.7/site-packages/virtualenv.py --setuptools --python /home/forcer/bin/python3.3 py33 (see /tmp/tox-test/.tox/py33/log/py33-0.log) ``` I can't figure out why it is using the virtualenv.py from python2.7. Shouldn't it be using venv.py from python3.3? From commits-noreply at bitbucket.org Mon Oct 21 13:33:45 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 21 Oct 2013 11:33:45 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: pytestconfig is now session-config as it is the same object during the Message-ID: <20131021113345.22464.69611@app06.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/b1b760614b0e/ Changeset: b1b760614b0e User: hpk42 Date: 2013-10-21 13:33:36 Summary: pytestconfig is now session-config as it is the same object during the whole test run. Fixes issue370 Affected #: 3 files diff -r 728a45eb659ebfcdec4042be31aec9ebd6d80bc8 -r b1b760614b0ea95cce3b07aeb7e5e6b012e430d2 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -12,6 +12,9 @@ properly so that the pkg_resources.resource_stream method works properly. Fixes issue366. Thanks for the investigations and full PR to Jason R. Coombs. +- pytestconfig is now session-config as it is the same object during the + whole test run. Fixes issue370. + - avoid one surprising case of marker malfunction/confusion:: @pytest.mark.some(lambda arg: ...) diff -r 728a45eb659ebfcdec4042be31aec9ebd6d80bc8 -r b1b760614b0ea95cce3b07aeb7e5e6b012e430d2 _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -157,7 +157,7 @@ '_fillfuncargs': fillfixtures} } - at fixture() + at fixture(scope="session") def pytestconfig(request): """ the pytest config object with access to command line opts.""" return request.config @@ -1566,8 +1566,8 @@ continue # will raise FixtureLookupError at setup time for fixturedef in faclist: if fixturedef.params is not None: - metafunc.parametrize(argname, fixturedef.params, indirect=True, - scope=fixturedef.scope) + metafunc.parametrize(argname, fixturedef.params, + indirect=True, scope=fixturedef.scope) def pytest_collection_modifyitems(self, items): # separate parametrized setups diff -r 728a45eb659ebfcdec4042be31aec9ebd6d80bc8 -r b1b760614b0ea95cce3b07aeb7e5e6b012e430d2 testing/python/integration.py --- a/testing/python/integration.py +++ b/testing/python/integration.py @@ -150,3 +150,7 @@ result.stdout.fnmatch_lines(""" *2 passed* """) + +def test_pytestconfig_is_session_scoped(): + from _pytest.python import pytestconfig + assert pytestconfig._pytestfixturefunction.scope == "session" 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 Oct 21 13:34:30 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 21 Oct 2013 11:34:30 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: fix changelog Message-ID: <20131021113430.9277.35766@app02.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/65665e5e0dfc/ Changeset: 65665e5e0dfc User: hpk42 Date: 2013-10-21 13:34:24 Summary: fix changelog Affected #: 1 file diff -r b1b760614b0ea95cce3b07aeb7e5e6b012e430d2 -r 65665e5e0dfc094e4ddee410296cd7746832bdf5 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -12,7 +12,7 @@ properly so that the pkg_resources.resource_stream method works properly. Fixes issue366. Thanks for the investigations and full PR to Jason R. Coombs. -- pytestconfig is now session-config as it is the same object during the +- pytestconfig fixture is now session-scoped as it is the same object during the whole test run. Fixes issue370. - avoid one surprising case of marker malfunction/confusion:: 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 Oct 21 13:36:27 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 21 Oct 2013 11:36:27 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: fix typo, thank avanderneuth Message-ID: <20131021113627.15011.79950@app08.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/0434c999780c/ Changeset: 0434c999780c User: hpk42 Date: 2013-10-21 13:36:22 Summary: fix typo, thank avanderneuth Affected #: 1 file diff -r 65665e5e0dfc094e4ddee410296cd7746832bdf5 -r 0434c999780c14204b60e51eed32d2d0c5c53401 doc/en/fixture.txt --- a/doc/en/fixture.txt +++ b/doc/en/fixture.txt @@ -234,7 +234,7 @@ If you decide that you rather want to have a session-scoped ``smtp`` instance, you can simply declare it:: - @pytest.fixture(scope=``session``) + @pytest.fixture(scope="session") def smtp(...): # the returned fixture value will be shared for # all tests needing it 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 Oct 21 14:05:05 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 21 Oct 2013 12:05:05 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: fix unicode handling with new monkeypatch.setattr(import_path, value) Message-ID: <20131021120505.19172.10235@app02.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/75b0af8a0a2b/ Changeset: 75b0af8a0a2b User: hpk42 Date: 2013-10-21 14:01:02 Summary: fix unicode handling with new monkeypatch.setattr(import_path, value) API. Thanks Rob Dennis. Fixes issue371. Affected #: 3 files diff -r 0434c999780c14204b60e51eed32d2d0c5c53401 -r 75b0af8a0a2b26a683d51331f6d69088ef18501a CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,9 @@ Changes between 2.4.2 and 2.4.3 ----------------------------------- +- fix unicode handling with new monkeypatch.setattr(import_path, value) + API. Thanks Rob Dennis. Fixes issue371. + - In assertion rewriting mode on Python 2, fix the detection of coding cookies. See issue #330. diff -r 0434c999780c14204b60e51eed32d2d0c5c53401 -r 75b0af8a0a2b26a683d51331f6d69088ef18501a _pytest/monkeypatch.py --- a/_pytest/monkeypatch.py +++ b/_pytest/monkeypatch.py @@ -1,6 +1,7 @@ """ monkeypatching and mocking functionality. """ import os, sys +from py.builtin import _basestring def pytest_funcarg__monkeypatch(request): """The returned ``monkeypatch`` funcarg provides these @@ -28,7 +29,7 @@ def derive_importpath(import_path): import pytest - if not isinstance(import_path, str) or "." not in import_path: + if not isinstance(import_path, basestring) or "." not in import_path: raise TypeError("must be absolute import path string, not %r" % (import_path,)) rest = [] @@ -85,7 +86,7 @@ import inspect if value is notset: - if not isinstance(target, str): + if not isinstance(target, _basestring): raise TypeError("use setattr(target, name, value) or " "setattr(target, value) with target being a dotted " "import string") @@ -115,7 +116,7 @@ """ __tracebackhide__ = True if name is notset: - if not isinstance(target, str): + if not isinstance(target, basestring): raise TypeError("use delattr(target, name) or " "delattr(target) with target being a dotted " "import string") diff -r 0434c999780c14204b60e51eed32d2d0c5c53401 -r 75b0af8a0a2b26a683d51331f6d69088ef18501a testing/test_monkeypatch.py --- a/testing/test_monkeypatch.py +++ b/testing/test_monkeypatch.py @@ -45,6 +45,12 @@ import _pytest assert _pytest.config.Config == 42 + def test_unicode_string(self, monkeypatch): + monkeypatch.setattr(u"_pytest.config.Config", 42) + import _pytest + assert _pytest.config.Config == 42 + monkeypatch.delattr(u"_pytest.config.Config") + def test_wrong_target(self, monkeypatch): pytest.raises(TypeError, lambda: monkeypatch.setattr(None, None)) 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 Oct 21 16:55:19 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Mon, 21 Oct 2013 14:55:19 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: fix unicode handling with junitxml, fixes issue368. Message-ID: <20131021145519.29548.68214@app04.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/e8e4c19c61c7/ Changeset: e8e4c19c61c7 User: hpk42 Date: 2013-10-21 16:54:25 Summary: fix unicode handling with junitxml, fixes issue368. Affected #: 5 files diff -r 75b0af8a0a2b26a683d51331f6d69088ef18501a -r e8e4c19c61c73b5d741229e5caa55005e47d12c5 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,8 @@ - fix unicode handling with new monkeypatch.setattr(import_path, value) API. Thanks Rob Dennis. Fixes issue371. +- fix unicode handling with junitxml, fixes issue368. + - In assertion rewriting mode on Python 2, fix the detection of coding cookies. See issue #330. diff -r 75b0af8a0a2b26a683d51331f6d69088ef18501a -r e8e4c19c61c73b5d741229e5caa55005e47d12c5 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.4.3.dev1' +__version__ = '2.4.3.dev2' diff -r 75b0af8a0a2b26a683d51331f6d69088ef18501a -r e8e4c19c61c73b5d741229e5caa55005e47d12c5 _pytest/junitxml.py --- a/_pytest/junitxml.py +++ b/_pytest/junitxml.py @@ -9,7 +9,6 @@ import sys import time - # Python 2.X and 3.X compatibility try: unichr(65) @@ -131,31 +130,31 @@ self.skipped += 1 else: fail = Junit.failure(message="test failure") - fail.append(str(report.longrepr)) + fail.append(unicode(report.longrepr)) self.append(fail) self.failed += 1 self._write_captured_output(report) def append_collect_failure(self, report): #msg = str(report.longrepr.reprtraceback.extraline) - self.append(Junit.failure(str(report.longrepr), + self.append(Junit.failure(unicode(report.longrepr), message="collection failure")) self.errors += 1 def append_collect_skipped(self, report): #msg = str(report.longrepr.reprtraceback.extraline) - self.append(Junit.skipped(str(report.longrepr), + self.append(Junit.skipped(unicode(report.longrepr), message="collection skipped")) self.skipped += 1 def append_error(self, report): - self.append(Junit.error(str(report.longrepr), + self.append(Junit.error(unicode(report.longrepr), message="test setup failure")) self.errors += 1 def append_skipped(self, report): if hasattr(report, "wasxfail"): - self.append(Junit.skipped(str(report.wasxfail), + self.append(Junit.skipped(unicode(report.wasxfail), message="expected test failure")) else: filename, lineno, skipreason = report.longrepr @@ -201,10 +200,10 @@ classname="pytest", name="internal")) - def pytest_sessionstart(self, session): + def pytest_sessionstart(self): self.suite_start_time = time.time() - def pytest_sessionfinish(self, session, exitstatus, __multicall__): + def pytest_sessionfinish(self): if py.std.sys.version_info[0] < 3: logfile = py.std.codecs.open(self.logfile, 'w', encoding='utf-8') else: diff -r 75b0af8a0a2b26a683d51331f6d69088ef18501a -r e8e4c19c61c73b5d741229e5caa55005e47d12c5 setup.py --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.4.3.dev1', + version='2.4.3.dev2', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff -r 75b0af8a0a2b26a683d51331f6d69088ef18501a -r e8e4c19c61c73b5d741229e5caa55005e47d12c5 testing/test_junitxml.py --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -1,5 +1,8 @@ +# -*- coding: utf-8 -*- + from xml.dom import minidom import py, sys, os +from _pytest.junitxml import LogXML def runandparse(testdir, *args): resultpath = testdir.tmpdir.join("junit.xml") @@ -423,8 +426,6 @@ assert chr(i) == bin_xml_escape(unichr(i)).uniobj def test_logxml_path_expansion(tmpdir, monkeypatch): - from _pytest.junitxml import LogXML - home_tilde = py.path.local(os.path.expanduser('~')).join('test.xml') xml_tilde = LogXML('~%stest.xml' % tmpdir.sep, None) @@ -461,3 +462,25 @@ assert_attr(node, name="test_func[#x00]") +def test_unicode_issue368(testdir): + path = testdir.tmpdir.join("test.xml") + log = LogXML(str(path), None) + class report: + longrepr = u"????????!" + sections = [] + nodeid = "something" + + # hopefully this is not too brittle ... + log.pytest_sessionstart() + log._opentestcase(report) + log.append_failure(report) + log.append_collect_failure(report) + log.append_collect_skipped(report) + log.append_error(report) + report.longrepr = "filename", 1, u"????????!" + log.append_skipped(report) + report.wasxfail = u"????????!" + log.append_skipped(report) + log.pytest_sessionfinish() + + 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 Oct 22 11:22:27 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 22 Oct 2013 09:22:27 -0000 Subject: [Pytest-commit] commit/tox: 3 new changesets Message-ID: <20131022092227.16614.68026@app02.ash-private.bitbucket.org> 3 new commits in tox: https://bitbucket.org/hpk42/tox/commits/f8af400bcecc/ Changeset: f8af400bcecc User: hpk42 Date: 2013-10-22 10:59:09 Summary: fix issue129: tox now uses Popen(..., universal_newlines=True) to force creation of unicode stdout/stderr streams. fixes a problem on specific platform configs when creating virtualenvs with Python3.3. Thanks Jorgen Sch?fer or investigation and solution sketch. Affected #: 4 files diff -r 88a503e7e5aefe509be8f6c3108a84baa20c3c26 -r f8af400bceccb5b95a6e5ef407f973d21b466c51 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,11 @@ 1.6.2.dev --------- +- fix issue129: tox now uses Popen(..., universal_newlines=True) to force + creation of unicode stdout/stderr streams. fixes a problem on specific + platform configs when creating virtualenvs with Python3.3. Thanks Jorgen Sch?fer + or investigation and solution sketch. + - fix issue128: enable full substitution in install_command, thanks for the PR to Ronald Evers diff -r 88a503e7e5aefe509be8f6c3108a84baa20c3c26 -r f8af400bceccb5b95a6e5ef407f973d21b466c51 tox/_cmdline.py --- a/tox/_cmdline.py +++ b/tox/_cmdline.py @@ -93,7 +93,8 @@ if cwd is None: # XXX cwd = self.session.config.cwd cwd = py.path.local() - popen = self._popen(args, cwd, env=env, stdout=f, stderr=STDOUT) + popen = self._popen(args, cwd, env=env, + stdout=f, stderr=STDOUT) popen.outpath = outpath popen.args = [str(x) for x in args] popen.cwd = cwd @@ -150,6 +151,7 @@ if env is None: env = os.environ.copy() return self.session.popen(args, shell=False, cwd=str(cwd), + universal_newlines=True, stdout=stdout, stderr=stderr, env=env) diff -r 88a503e7e5aefe509be8f6c3108a84baa20c3c26 -r f8af400bceccb5b95a6e5ef407f973d21b466c51 tox/_pytestplugin.py --- a/tox/_pytestplugin.py +++ b/tox/_pytestplugin.py @@ -130,6 +130,7 @@ def make_emptydir(self, path): pass def popen(self, args, cwd, shell=None, + universal_newlines=False, stdout=None, stderr=None, env=None): pm = pcallMock(args, cwd, env, stdout, stderr, shell) self._pcalls.append(pm) diff -r 88a503e7e5aefe509be8f6c3108a84baa20c3c26 -r f8af400bceccb5b95a6e5ef407f973d21b466c51 tox/_venv.py --- a/tox/_venv.py +++ b/tox/_venv.py @@ -228,7 +228,7 @@ args = [self.envconfig.envpython, str(setup_py), '--name'] output = action.popen(args, cwd=setupdir, redirect=False, returnout=True) - name = output.strip().decode('utf-8') + name = output.strip() egg_info = setupdir.join('.'.join((name, 'egg-info'))) for conf_file in (setup_py, setup_cfg): if (not egg_info.check() or (conf_file.check() https://bitbucket.org/hpk42/tox/commits/f15199a9ec78/ Changeset: f15199a9ec78 User: hpk42 Date: 2013-10-22 11:04:11 Summary: more windows parsing fixes Affected #: 5 files diff -r f8af400bceccb5b95a6e5ef407f973d21b466c51 -r f15199a9ec78e052b9f9513a34e0e5768e8affdd CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -9,7 +9,8 @@ - fix issue128: enable full substitution in install_command, thanks for the PR to Ronald Evers -- fix windows parsing/escaping +- rework and simplify "commands" parsing and in particular posargs + substitutions to avoid various win32/posix related quoting issues. 1.6.1 ----- diff -r f8af400bceccb5b95a6e5ef407f973d21b466c51 -r f15199a9ec78e052b9f9513a34e0e5768e8affdd 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.6.2.dev1', + version='1.6.2.dev2', license='http://opensource.org/licenses/MIT', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], author='holger krekel', diff -r f8af400bceccb5b95a6e5ef407f973d21b466c51 -r f15199a9ec78e052b9f9513a34e0e5768e8affdd tests/test_config.py --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1088,14 +1088,14 @@ parsed = list(p.words()) assert parsed == ['nosetests', ' ', '-v', ' ', '-a', ' ', '!deferred', ' ', '--with-doctest', ' ', '[]'] -def test_argv_unquote_single_args(): - argv = ["hello", '"hello2"', "'hello3'"] - newargv = unquote_single_args(argv) - assert newargv == ["hello", "hello2", "hello3"] -def test_argv_roundrobin(): - argv = ["hello", "this\\that"] - assert string2argv(argv2string(argv)) == argv - argv = ["hello world"] - assert string2argv(argv2string(argv)) == argv + @pytest.mark.skipif("sys.platform != 'win32'") + def test_commands_with_backslash(self, newconfig): + config = newconfig([r"hello\world"], """ + [testenv:py26] + commands = some {posargs} + """) + envconfig = config.envconfigs["py26"] + assert envconfig.commands[0] == ["some", r"hello\world"] + diff -r f8af400bceccb5b95a6e5ef407f973d21b466c51 -r f15199a9ec78e052b9f9513a34e0e5768e8affdd tox/__init__.py --- a/tox/__init__.py +++ b/tox/__init__.py @@ -1,5 +1,5 @@ # -__version__ = '1.6.2.dev1' +__version__ = '1.6.2.dev2' class exception: class Error(Exception): diff -r f8af400bceccb5b95a6e5ef407f973d21b466c51 -r f15199a9ec78e052b9f9513a34e0e5768e8affdd tox/_config.py --- a/tox/_config.py +++ b/tox/_config.py @@ -413,7 +413,7 @@ def addsubstitutions(self, _posargs=None, **kw): self._subs.update(kw) if _posargs: - self._subs['_posargs'] = _posargs + self.posargs = _posargs def getpath(self, section, name, defaultpath): toxinidir = self._subs['toxinidir'] @@ -468,27 +468,38 @@ return commandlist def _processcommand(self, command): - posargs = self._subs.get('_posargs', None) - words = list(CommandParser(command).words()) - new_command = '' - for word in words: - if word == '[]': + posargs = getattr(self, "posargs", None) + + # special treat posargs which might contain multiple arguments + # in their defaults + newcommand = "" + for word in CommandParser(command).words(): + if word.startswith("{posargs:") and word.endswith("}"): if posargs: - new_command += ' '.join(posargs) + word = "{posargs}" + else: + word = word[9:-1] + newcommand += word + + # now we can properly parse the command + argv = [] + for arg in shlex.split(newcommand): + if arg in ('[]', "{posargs}"): + if posargs: + argv.extend(posargs) continue - - new_word = self._replace(word, quote=True) - # two passes; we might have substitutions in the result - new_word = self._replace(new_word, quote=True) - new_command += new_word - - return shlex.split(new_command.strip()) + new_arg = "" + for word in CommandParser(arg).words(): + new_word = self._replace(word) + new_word = self._replace(new_word) + new_arg += new_word + argv.append(new_arg) + return argv def getargv(self, section, name, default=None, replace=True): command = self.getdefault( - section, name, default=default, replace=replace) - - return string2argv(command.strip()) + section, name, default=default, replace=False) + return self._processcommand(command.strip()) def getbool(self, section, name, default=None): s = self.getdefault(section, name, default) @@ -527,22 +538,7 @@ #print "getdefault", section, name, "returned", repr(x) return x - def _replace_posargs(self, match, quote): - return self._do_replace_posargs(lambda: match.group('substitution_value')) - - def _do_replace_posargs(self, value_func): - posargs = self._subs.get('_posargs', None) - - if posargs: - return argv2string(posargs) - - value = value_func() - if value: - return value - - return '' - - def _replace_env(self, match, quote): + def _replace_env(self, match): envkey = match.group('substitution_value') if not envkey: raise tox.exception.ConfigError( @@ -555,7 +551,7 @@ return os.environ[envkey] - def _substitute_from_other_section(self, key, quote): + def _substitute_from_other_section(self, key): if key.startswith("[") and "]" in key: i = key.find("]") section, item = key[1:i], key[i+1:] @@ -566,37 +562,25 @@ x = str(self._cfg[section][item]) self._subststack.append((section, item)) try: - return self._replace(x, quote=quote) + return self._replace(x) finally: self._subststack.pop() raise tox.exception.ConfigError( "substitution key %r not found" % key) - def _replace_substitution(self, match, quote): + def _replace_substitution(self, match): sub_key = match.group('substitution_value') val = self._subs.get(sub_key, None) if val is None: - val = self._substitute_from_other_section(sub_key, quote) + val = self._substitute_from_other_section(sub_key) if py.builtin.callable(val): val = val() - if quote: - return '"%s"' % str(val).replace('"', r'\"') - else: - return str(val) + return str(val) - def _is_bare_posargs(self, groupdict): - return groupdict.get('substitution_value', None) == 'posargs' \ - and not groupdict.get('sub_type') - - def _replace_match(self, match, quote): + def _replace_match(self, match): g = match.groupdict() - # special case: posargs. If there is a 'posargs' substitution value - # and no type, handle it as empty posargs - if self._is_bare_posargs(g): - return self._do_replace_posargs(lambda: '') - # special case: opts and packages. Leave {opts} and # {packages} intact, they are replaced manually in # _venv.VirtualEnv.run_install_command. @@ -605,7 +589,6 @@ return '{%s}' % sub_value handlers = { - 'posargs' : self._replace_posargs, 'env' : self._replace_env, None : self._replace_substitution, } @@ -619,22 +602,11 @@ except KeyError: raise tox.exception.ConfigError("No support for the %s substitution type" % sub_type) - # quoting is done in handlers, as at least posargs handling is special: - # all of its arguments are inserted as separate parameters - return handler(match, quote) + return handler(match) - def _replace_match_quote(self, match): - return self._replace_match(match, quote=True) - def _replace_match_no_quote(self, match): - return self._replace_match(match, quote=False) - - def _replace(self, x, quote=False): + def _replace(self, x): if '{' in x: - if quote: - replace_func = self._replace_match_quote - else: - replace_func = self._replace_match_no_quote - return RE_ITEM_REF.sub(replace_func, x) + return RE_ITEM_REF.sub(self._replace_match, x) return x def _parse_command(self, command): @@ -706,18 +678,3 @@ return 'jenkins' return None - -def unquote_single_args(argv): - newargv = [] - for arg in argv: - if len(arg) >=2 and arg[0] == arg[-1]: - if arg[0] in ("'", '"'): - arg = arg[1:-1] - newargv.append(arg) - return newargv - -def string2argv(cmd): - return unquote_single_args(shlex.split(cmd, posix=False)) - -def argv2string(argv): - return subprocess.list2cmdline(argv) https://bitbucket.org/hpk42/tox/commits/ca1c1d8f9586/ Changeset: ca1c1d8f9586 User: hpk42 Date: 2013-10-22 11:04:11 Summary: a command line specified --installpkg trumps any develop option Affected #: 3 files diff -r f15199a9ec78e052b9f9513a34e0e5768e8affdd -r ca1c1d8f95869a3ca6e4af9fb3f84779e84438b8 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -12,6 +12,9 @@ - rework and simplify "commands" parsing and in particular posargs substitutions to avoid various win32/posix related quoting issues. +- make sure that the --installpkg option trumps any usedevelop settings + in tox.ini or + 1.6.1 ----- diff -r f15199a9ec78e052b9f9513a34e0e5768e8affdd -r ca1c1d8f95869a3ca6e4af9fb3f84779e84438b8 tests/test_config.py --- a/tests/test_config.py +++ b/tests/test_config.py @@ -308,7 +308,8 @@ assert argvlist[0] == ["cmd1"] assert argvlist[1] == ["cmd2", "value2", "other"] - def test_positional_arguments_are_only_replaced_when_standing_alone(self, tmpdir, newconfig): + def test_positional_arguments_are_only_replaced_when_standing_alone(self, + tmpdir, newconfig): config = newconfig(""" [section] key= @@ -406,6 +407,13 @@ assert envconfig.envlogdir == envconfig.envdir.join("log") assert envconfig.setenv is None + def test_installpkg_tops_develop(self, newconfig): + config = newconfig(["--installpkg=abc"], """ + [testenv] + usedevelop = True + """) + assert not config.envconfigs["python"].develop + def test_specific_command_overrides(self, tmpdir, newconfig): config = newconfig(""" [testenv] diff -r f15199a9ec78e052b9f9513a34e0e5768e8affdd -r ca1c1d8f95869a3ca6e4af9fb3f84779e84438b8 tox/_config.py --- a/tox/_config.py +++ b/tox/_config.py @@ -272,7 +272,8 @@ vc.config = config reader = IniReader(self._cfg, fallbacksections=["testenv"]) reader.addsubstitutions(**subs) - vc.develop = reader.getbool(section, "usedevelop", config.option.develop) + vc.develop = not config.option.installpkg and \ + reader.getbool(section, "usedevelop", config.option.develop) vc.envdir = reader.getpath(section, "envdir", "{toxworkdir}/%s" % name) vc.args_are_paths = reader.getbool(section, "args_are_paths", True) if reader.getdefault(section, "python", None): 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 Oct 22 11:28:50 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Tue, 22 Oct 2013 09:28:50 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: fix tests on py32/py33 Message-ID: <20131022092850.25476.35749@app12.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/d22d342efe52/ Changeset: d22d342efe52 User: hpk42 Date: 2013-10-22 11:26:29 Summary: fix tests on py32/py33 Affected #: 2 files diff -r e8e4c19c61c73b5d741229e5caa55005e47d12c5 -r d22d342efe52cb03a7d2bbeea8554af122406bce _pytest/monkeypatch.py --- a/_pytest/monkeypatch.py +++ b/_pytest/monkeypatch.py @@ -29,7 +29,7 @@ def derive_importpath(import_path): import pytest - if not isinstance(import_path, basestring) or "." not in import_path: + if not isinstance(import_path, _basestring) or "." not in import_path: raise TypeError("must be absolute import path string, not %r" % (import_path,)) rest = [] @@ -116,7 +116,7 @@ """ __tracebackhide__ = True if name is notset: - if not isinstance(target, basestring): + if not isinstance(target, _basestring): raise TypeError("use delattr(target, name) or " "delattr(target) with target being a dotted " "import string") diff -r e8e4c19c61c73b5d741229e5caa55005e47d12c5 -r d22d342efe52cb03a7d2bbeea8554af122406bce testing/test_junitxml.py --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -465,8 +465,9 @@ def test_unicode_issue368(testdir): path = testdir.tmpdir.join("test.xml") log = LogXML(str(path), None) + ustr = py.builtin._totext("???!", "utf-8") class report: - longrepr = u"????????!" + longrepr = ustr sections = [] nodeid = "something" @@ -477,9 +478,9 @@ log.append_collect_failure(report) log.append_collect_skipped(report) log.append_error(report) - report.longrepr = "filename", 1, u"????????!" + report.longrepr = "filename", 1, ustr log.append_skipped(report) - report.wasxfail = u"????????!" + report.wasxfail = ustr log.append_skipped(report) log.pytest_sessionfinish() 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 Oct 23 21:12:09 2013 From: issues-reply at bitbucket.org (jenisys) Date: Wed, 23 Oct 2013 19:12:09 -0000 Subject: [Pytest-commit] Issue #130: install_command w/ easy_install fails when tox is run twice (hpk42/tox) Message-ID: <20131023191209.24112.39404@app01.ash-private.bitbucket.org> New issue 130: install_command w/ easy_install fails when tox is run twice https://bitbucket.org/hpk42/tox/issue/130/install_command-w-easy_install-fails-when jenisys: VERSION INFO: tox 1.6.1 with python 2.7, virtualenv 0.10.1, setuptools 0.9.8 (or newer) When you use the new "install_command" with easy_install you get an error when you run the same test environment twice without recreating it. The problem occurs in the sdist installation step because 2 options "-U --no-deps" are appended after the package. shell> tox -e xxx -r shell> tox -e xxx ... cmdargs=[local('.../MY_PROJECT/.tox/xxx/bin/easy_install'), '-i', 'MY_INDEX_SERVER_URL', '.../MYPROJECT/.tox/dist/my_project-X.X.X.zip', '-U', '--no-deps'] ... error: Could not find suitable distribution for Requirement.parse('-U') The problem is the last 2 options "-U --no-deps" that are appended to the easy_install command-line. When you place these 2 options before the package, easy_install is happy and will install the package at the second time. EXAMPLE: # FILE: tox.ini ... [testenv:xxx] install_command = easy_install {opts} {packages} ... From issues-reply at bitbucket.org Wed Oct 23 21:53:58 2013 From: issues-reply at bitbucket.org (jenisys) Date: Wed, 23 Oct 2013 19:53:58 -0000 Subject: [Pytest-commit] Issue #131: With pip: project's sdist package is only installed in testenv during second test run (hpk42/tox) Message-ID: <20131023195358.16968.28263@app01.ash-private.bitbucket.org> New issue 131: With pip: project's sdist package is only installed in testenv during second test run https://bitbucket.org/hpk42/tox/issue/131/with-pip-projects-sdist-package-is-only jenisys: VERSION INFO: tox 1.6.1, pip 1.4.1, virtualenv 0.10.1 (python 2.7) When pip is used, the actual sdist package seems not to be installed when the test environment is created. When you run tox again on the same test environment it is installed and available (for example together with its console scripts). NOTE: The required packages, that project depends on, are installed during the "sdist" installation step (during the first step). EXAMPLE: Create a new test environment in TOX's "tox.ini" file: # -- TOX tox.ini (extended with xxx environment) [testenv:xxx] changedir = {envdir} commands= tox --version deps= Then run this test environment: shell> tox -e xxx -r GLOB sdist-make: .../tox/setup.py xxx recreate: .../tox/.tox/xxx xxx inst: .../tox/.tox/dist/tox-1.6.2.dev2.zip xxx runtests: commands[0] | tox --version WARNING:test command found but not installed in testenv cmd: /Library/Frameworks/Python.framework/Versions/2.7/bin/tox env: .../tox/.tox/xxx Maybe forgot to specify a dependency? 1.6.1 imported from /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/tox-1.6.1-py2.7.egg/tox/__init__.pyc ==> OOPS: Initial tox is used, not the one under test. shell> tox -e xxx GLOB sdist-make: .../tox/setup.py xxx inst-nodeps: .../tox/.tox/dist/tox-1.6.2.dev2.zip xxx runtests: commands[0] | tox --version 1.6.2.dev2 imported from .../tox/.tox/xxx/lib/python2.7/site-packages/tox/__init__.pyc IMPACT: This behavior is the killer if the console scripts of the python package should be used during the test run. Check also that after the first round (with recreate): * the tox sdist package is not under virtualenv site-package directory * "pip list" also states that package is not installed * the tox script is not in the .tox/xxx/bin directory I am not sure if this is a pip problem or tox problem or a combination of both but it currently kills my use case. WORKAROUND: Add a "python setup.py -q install" as first command to ensure that project package is installed. But then you install it twice :-( From commits-noreply at bitbucket.org Thu Oct 24 09:38:51 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 24 Oct 2013 07:38:51 -0000 Subject: [Pytest-commit] commit/tox: hpk42: fix issue130: you can now set install_command=easy_install {opts} {packages} Message-ID: <20131024073851.10689.79246@app12.ash-private.bitbucket.org> 1 new commit in tox: https://bitbucket.org/hpk42/tox/commits/eb83611a8e03/ Changeset: eb83611a8e03 User: hpk42 Date: 2013-10-24 09:38:45 Summary: fix issue130: you can now set install_command=easy_install {opts} {packages} and expect it to run without the need to recreate. Thanks jenisys for precise reporting. Affected #: 3 files diff -r ca1c1d8f95869a3ca6e4af9fb3f84779e84438b8 -r eb83611a8e03c7f61d1a43d86cc79f4578baa64e CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,10 @@ 1.6.2.dev --------- +- fix issue130: you can now set install_command=easy_install {opts} {packages} + and expect it to run without the need to recreate. Thanks jenisys for + precise reporting. + - fix issue129: tox now uses Popen(..., universal_newlines=True) to force creation of unicode stdout/stderr streams. fixes a problem on specific platform configs when creating virtualenvs with Python3.3. Thanks Jorgen Sch?fer diff -r ca1c1d8f95869a3ca6e4af9fb3f84779e84438b8 -r eb83611a8e03c7f61d1a43d86cc79f4578baa64e tests/test_venv.py --- a/tests/test_venv.py +++ b/tests/test_venv.py @@ -520,8 +520,10 @@ mocksession.installpkg(venv, pkg) l = mocksession._pcalls assert len(l) == 1 - assert '-U' in l[0].args - assert '--no-deps' in l[0].args + index = l[0].args.index(str(pkg)) + assert index >= 0 + assert '-U' in l[0].args[:index] + assert '--no-deps' in l[0].args[:index] def test_run_install_command(newmocksession): mocksession = newmocksession([], "") @@ -529,7 +531,7 @@ venv.just_created = True venv.envconfig.envdir.ensure(dir=1) action = mocksession.newaction(venv, "hello") - venv.run_install_command(args=["whatever"], action=action) + venv.run_install_command(packages=["whatever"], action=action) l = mocksession._pcalls assert len(l) == 1 assert 'pip' in l[0].args[0] @@ -548,7 +550,7 @@ venv.just_created = True venv.envconfig.envdir.ensure(dir=1) action = mocksession.newaction(venv, "hello") - venv.run_install_command(args=["whatever"], action=action) + venv.run_install_command(packages=["whatever"], action=action) l = mocksession._pcalls assert len(l) == 1 assert 'easy_install' in l[0].args[0] diff -r ca1c1d8f95869a3ca6e4af9fb3f84779e84438b8 -r eb83611a8e03c7f61d1a43d86cc79f4578baa64e tox/_venv.py --- a/tox/_venv.py +++ b/tox/_venv.py @@ -280,17 +280,18 @@ l.append("--download-cache=%s" % self.envconfig.downloadcache) return l - def run_install_command(self, args, indexserver=None, action=None, + def run_install_command(self, packages, options=(), + indexserver=None, action=None, extraenv=None): argv = self.envconfig.install_command[:] # use pip-script on win32 to avoid the executable locking if argv[0] == "pip" and sys.platform == "win32": argv[0] = "pip-script.py" i = argv.index('{packages}') - argv[i:i+1] = args + argv[i:i+1] = packages if '{opts}' in argv: i = argv.index('{opts}') - argv[i:i+1] = self._installopts(indexserver) + argv[i:i+1] = list(options) for x in ('PIP_RESPECT_VIRTUALENV', 'PIP_REQUIRE_VIRTUALENV'): try: del os.environ[x] @@ -320,7 +321,6 @@ l.append(ixserver) assert ixserver.url is None or isinstance(ixserver.url, str) - extraopts = extraopts or [] for ixserver in l: if self.envconfig.config.option.sethome: extraenv = hack_home_env( @@ -329,9 +329,12 @@ else: extraenv = {} - args = d[ixserver] + extraopts - self.run_install_command(args, ixserver.url, action, - extraenv=extraenv) + packages = d[ixserver] + options = self._installopts(ixserver.url) + if extraopts: + options.extend(extraopts) + self.run_install_command(packages=packages, options=options, + action=action, extraenv=extraenv) def _getenv(self): env = self.envconfig.setenv 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 Thu Oct 24 09:44:01 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 24 Oct 2013 07:44:01 -0000 Subject: [Pytest-commit] commit/tox: hpk42: fix issue126: depend on virtualenv>=1.10.1 so that we can rely Message-ID: <20131024074401.21793.63166@app12.ash-private.bitbucket.org> 1 new commit in tox: https://bitbucket.org/hpk42/tox/commits/7a16cd37007c/ Changeset: 7a16cd37007c User: hpk42 Date: 2013-10-24 09:43:56 Summary: fix issue126: depend on virtualenv>=1.10.1 so that we can rely (hopefully) on a pip version which supports --pre. (tox by default uses to --pre). Note that tox also vendors an older virtualenv for supporting python2.5 -- although the latter will be dropped at some point. Affected #: 2 files diff -r eb83611a8e03c7f61d1a43d86cc79f4578baa64e -r 7a16cd37007c630dff269878a542c16bbaf6cf68 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,9 +1,14 @@ 1.6.2.dev --------- +- fix issue126: depend on virtualenv>=1.10.1 so that we can rely + (hopefully) on a pip version which supports --pre. (tox by default + uses to --pre). Note that tox also vendors an older virtualenv + for supporting python2.5 -- although the latter will be dropped at some point. + - fix issue130: you can now set install_command=easy_install {opts} {packages} - and expect it to run without the need to recreate. Thanks jenisys for - precise reporting. + and expect it to work for repeated tox runs (previously it only worked + when always recreating). Thanks jenisys for precise reporting. - fix issue129: tox now uses Popen(..., universal_newlines=True) to force creation of unicode stdout/stderr streams. fixes a problem on specific diff -r eb83611a8e03c7f61d1a43d86cc79f4578baa64e -r 7a16cd37007c630dff269878a542c16bbaf6cf68 setup.py --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ def main(): version = sys.version_info[:2] - install_requires = ['virtualenv>=1.9.1', 'py>=1.4.15', ] + install_requires = ['virtualenv>=1.10.1', 'py>=1.4.17', ] if version < (2, 7) or (3, 0) <= version <= (3, 1): install_requires += ['argparse'] if version < (2,6): 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 Thu Oct 24 15:13:25 2013 From: commits-noreply at bitbucket.org (commits-noreply at bitbucket.org) Date: Thu, 24 Oct 2013 13:13:25 -0000 Subject: [Pytest-commit] commit/pytest: hpk42: change metadata Message-ID: <20131024131325.13570.46270@app02.ash-private.bitbucket.org> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/8e65b5b17d12/ Changeset: 8e65b5b17d12 User: hpk42 Date: 2013-10-24 15:08:50 Summary: change metadata Affected #: 2 files diff -r d22d342efe52cb03a7d2bbeea8554af122406bce -r 8e65b5b17d12942193881ddcb9a244bc470a6fff README.rst --- a/README.rst +++ b/README.rst @@ -1,6 +1,10 @@ + +Documentation: http://pytest.org/latest/ Changelog: http://pytest.org/latest/changelog.html +Issues: https://bitbucket.org/hpk42/pytest/issues?status=open + The ``py.test`` testing tool makes it easy to write small tests, yet scales to support complex functional testing. It provides diff -r d22d342efe52cb03a7d2bbeea8554af122406bce -r 8e65b5b17d12942193881ddcb9a244bc470a6fff setup.py --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 3'] + [ ("Programming Language :: Python :: %s" % x) for x in - "2.4 2.5 2.6 2.7 3.0 3.1 3.2 3.3".split()] + "2.5 2.6 2.7 3.0 3.1 3.2 3.3".split()] long_description = open("README.rst").read() def main(): Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From issues-reply at bitbucket.org Sun Oct 27 19:13:24 2013 From: issues-reply at bitbucket.org (jenisys) Date: Sun, 27 Oct 2013 18:13:24 -0000 Subject: [Pytest-commit] Issue #132: py25 virtualenv downgrade fails if tox is installed w/ easy_install (as egg) (hpk42/tox) Message-ID: <20131027181324.11478.69321@app07.ash-private.bitbucket.org> New issue 132: py25 virtualenv downgrade fails if tox is installed w/ easy_install (as egg) https://bitbucket.org/hpk42/tox/issue/132/py25-virtualenv-downgrade-fails-if-tox-is jenisys: VERSION-INFO: tox 1.6.1, setuptools>=0.9.8, python2.7 Run "tox -e py25" in a virtualenv where tox is installed with easy_install (as egg). Python2.5 interpreter tries to access "virtualenv.py" that is bundled with tox in the egg, but cannot reach into the zipped egg (with the provided path). ```shell xxx)shell> tox -e py25 GLOB sdist-make: /.../xxx/my_project/setup.py py25 create: /.../xxx/my_project/.tox/py25 ERROR: invocation failed, logfile: /.../xxx/my_project/.tox/py25/log/py25-0.log ERROR: actionid=py25 msg=getenv cmdargs=['/usr/bin/python2.5', '/.../xxx/lib/python2.7/site-packages/tox-1.6.1-py2.7.egg/tox/vendor/virtualenv.py', '--setuptools', '--python', '/usr/bin/python2.5', 'py25'] ... /usr/bin/python2.5: can't open file '/.../xxx/lib/python2.7/site-packages/tox-1.6.1-py2.7.egg/tox/vendor/virtualenv.py': [Errno 20] Not a directory ERROR: InvocationError: /usr/bin/python2.5 /.../xxx/lib/python2.7/site-packages/tox-1.6.1-py2.7.egg/tox/vendor/virtualenv.py --setuptools --python /usr/bin/python2.5 py25 (see /.../xxx/my_project/.tox/py25/log/py25-0.log) ``` From issues-reply at bitbucket.org Sun Oct 27 19:20:53 2013 From: issues-reply at bitbucket.org (jenisys) Date: Sun, 27 Oct 2013 18:20:53 -0000 Subject: [Pytest-commit] Issue #133: Reuse commands from another testenv is broken (hpk42/tox) Message-ID: <20131027182053.19926.40888@app13.ash-private.bitbucket.org> New issue 133: Reuse commands from another testenv is broken https://bitbucket.org/hpk42/tox/issue/133/reuse-commands-from-another-testenv-is jenisys: VERSION-INFO: tox 1.6.1 Tox seems to allow that commands are reused from another testenv. But this broken because a split lines action is missing. Commands are just copied as text (which works for "deps" but not for "commands"). Inspect it with "tox --showconfig" (notice: string w/ newlines) or run it to see the effect. EXAMPLE: ``` # -- FILE: tox.ini (partial) [testenv:base] whitelist_commands = /bin/echo commands = /bin/echo BASE tox --version deps = tox [testenv:xxx] whitelist_commands = /bin/echo commands = {[testenv:base]commands} /bin/echo XXX tox --version deps = {[testenv:base]deps} ```