diff --git a/.travis.yml b/.travis.yml index 40fe3e8ba..b0ed7bf29 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,10 +2,8 @@ sudo: false language: python python: - '3.6' -# command to install dependencies install: - pip install --upgrade --pre tox -# # command to run tests env: matrix: # coveralls is not listed in tox's envlist, but should run in travis @@ -29,7 +27,7 @@ env: - TOXENV=doctesting - TOXENV=docs -matrix: +jobs: include: - env: TOXENV=pypy python: 'pypy-5.4' @@ -40,6 +38,22 @@ matrix: - env: TOXENV=py37 python: 'nightly' + - stage: deploy + python: '3.6' + env: + install: pip install -U setuptools setuptools_scm + script: skip + deploy: + provider: pypi + user: nicoddemus + distributions: sdist bdist_wheel + skip_upload_docs: true + password: + secure: xanTgTUu6XDQVqB/0bwJQXoDMnU5tkwZc5koz6mBkkqZhKdNOi2CLoC1XhiSZ+ah24l4V1E0GAqY5kBBcy9d7NVe4WNg4tD095LsHw+CRU6/HCVIFfyk2IZ+FPAlguesCcUiJSXOrlBF+Wj68wEvLoK7EoRFbJeiZ/f91Ww1sbtDlqXABWGHrmhPJL5Wva7o7+wG7JwJowqdZg1pbQExsCc7b53w4v2RBu3D6TJaTAzHiVsW+nUSI67vKI/uf+cR/OixsTfy37wlHgSwihYmrYLFls3V0bSpahCim3bCgMaFZx8S8xrdgJ++PzBCof2HeflFKvW+VCkoYzGEG4NrTWJoNz6ni4red9GdvfjGH3YCjAKS56h9x58zp2E5rpsb/kVq5/45xzV+dq6JRuhQ1nJWjBC6fSKAc/bfwnuFK3EBxNLkvBssLHvsNjj5XG++cB8DdS9wVGUqjpoK4puaXUWFqy4q3S9F86HEsKNgExtieA9qNx+pCIZVs6JCXZNjr0I5eVNzqJIyggNgJG6RyravsU35t9Zd9doL5g4Y7UKmAGTn1Sz24HQ4sMQgXdm2SyD8gEK5je4tlhUvfGtDvMSlstq71kIn9nRpFnqB6MFlbYSEAZmo8dGbCquoUc++6Rum208wcVbrzzVtGlXB/Ow9AbFMYeAGA0+N/K1e59c= + on: + tags: true + repo: pytest-dev/pytest + script: tox --recreate notifications: diff --git a/CHANGELOG.rst b/CHANGELOG.rst index fa0759437..6ef104e5f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -8,6 +8,67 @@ .. towncrier release notes start +Pytest 3.4.1 (2018-02-20) +========================= + +Bug Fixes +--------- + +- Move import of ``doctest.UnexpectedException`` to top-level to avoid possible + errors when using ``--pdb``. (`#1810 + `_) + +- Added printing of captured stdout/stderr before entering pdb, and improved a + test which was giving false negatives about output capturing. (`#3052 + `_) + +- Fix ordering of tests using parametrized fixtures which can lead to fixtures + being created more than necessary. (`#3161 + `_) + +- Fix bug where logging happening at hooks outside of "test run" hooks would + cause an internal error. (`#3184 + `_) + +- Detect arguments injected by ``unittest.mock.patch`` decorator correctly when + pypi ``mock.patch`` is installed and imported. (`#3206 + `_) + +- Errors shown when a ``pytest.raises()`` with ``match=`` fails are now cleaner + on what happened: When no exception was raised, the "matching '...'" part got + removed as it falsely implies that an exception was raised but it didn't + match. When a wrong exception was raised, it's now thrown (like + ``pytest.raised()`` without ``match=`` would) instead of complaining about + the unmatched text. (`#3222 + `_) + +- Fixed output capture handling in doctests on macOS. (`#985 + `_) + + +Improved Documentation +---------------------- + +- Add Sphinx parameter docs for ``match`` and ``message`` args to + ``pytest.raises``. (`#3202 + `_) + + +Trivial/Internal Changes +------------------------ + +- pytest has changed the publication procedure and is now being published to + PyPI directly from Travis. (`#3060 + `_) + +- Rename ``ParameterSet._for_parameterize()`` to ``_for_parametrize()`` in + order to comply with the naming convention. (`#3166 + `_) + +- Skip failing pdb/doctest test on mac. (`#985 + `_) + + Pytest 3.4.0 (2018-01-30) ========================= diff --git a/HOWTORELEASE.rst b/HOWTORELEASE.rst index 9a251a8f0..97bddf720 100644 --- a/HOWTORELEASE.rst +++ b/HOWTORELEASE.rst @@ -22,44 +22,28 @@ taking a lot of time to make a new one. Ensure your are in a clean work tree. -#. Generate docs, changelog, announcements and upload a package to - your ``devpi`` staging server:: +#. Generate docs, changelog, announcements and a **local** tag:: - invoke generate.pre-release --password - - If ``--password`` is not given, it is assumed the user is already logged in ``devpi``. - If you don't have an account, please ask for one. + invoke generate.pre-release #. Open a PR for this branch targeting ``master``. -#. Test the package +#. After all tests pass and the PR has been approved, publish to PyPI by pushing the tag:: - * **Manual method** + git push git@github.com:pytest-dev/pytest.git - Run from multiple machines:: + Wait for the deploy to complete, then make sure it is `available on PyPI `_. - devpi use https://devpi.net/USER/dev - devpi test pytest==VERSION +#. Send an email announcement with the contents from:: - Check that tests pass for relevant combinations with:: + doc/en/announce/release-.rst - devpi list pytest + To the following mailing lists: - * **CI servers** + * pytest-dev@python.org (all releases) + * python-announce-list@python.org (all releases) + * testing-in-python@lists.idyll.org (only major/minor releases) - Configure a repository as per-instructions on - devpi-cloud-test_ to test the package on Travis_ and AppVeyor_. - All test environments should pass. - -#. Publish to PyPI:: - - invoke generate.publish-release - - where PYPI_NAME is the name of pypi.python.org as configured in your ``~/.pypirc`` - file `for devpi `_. + And announce it on `Twitter `_ with the ``#pytest`` hashtag. #. After a minor/major release, merge ``release-X.Y.Z`` into ``master`` and push (or open a PR). - -.. _devpi-cloud-test: https://github.com/obestwalter/devpi-cloud-test -.. _AppVeyor: https://www.appveyor.com/ -.. _Travis: https://travis-ci.org diff --git a/_pytest/doctest.py b/_pytest/doctest.py index bba90e551..f54f833ec 100644 --- a/_pytest/doctest.py +++ b/_pytest/doctest.py @@ -2,6 +2,8 @@ from __future__ import absolute_import, division, print_function import traceback +import sys +import platform import pytest from _pytest._code.code import ExceptionInfo, ReprFileLocation, TerminalRepr @@ -103,8 +105,21 @@ class DoctestItem(pytest.Item): def runtest(self): _check_all_skipped(self.dtest) + self._disable_output_capturing_for_darwin() self.runner.run(self.dtest) + def _disable_output_capturing_for_darwin(self): + """ + Disable output capturing. Otherwise, stdout is lost to doctest (#985) + """ + if platform.system() != 'Darwin': + return + capman = self.config.pluginmanager.getplugin("capturemanager") + if capman: + out, err = capman.suspend_global_capture(in_=True) + sys.stdout.write(out) + sys.stderr.write(err) + def repr_failure(self, excinfo): import doctest if excinfo.errisinstance((doctest.DocTestFailure, diff --git a/_pytest/python_api.py b/_pytest/python_api.py index e6f002849..89ef9e0a9 100644 --- a/_pytest/python_api.py +++ b/_pytest/python_api.py @@ -571,7 +571,6 @@ def raises(expected_exception, *args, **kwargs): message = kwargs.pop("message") if "match" in kwargs: match_expr = kwargs.pop("match") - message += " matching '{0}'".format(match_expr) return RaisesContext(expected_exception, message, match_expr) elif isinstance(args[0], str): code, = args @@ -618,6 +617,6 @@ class RaisesContext(object): suppress_exception = issubclass(self.excinfo.type, self.expected_exception) if sys.version_info[0] == 2 and suppress_exception: sys.exc_clear() - if self.match_expr: + if self.match_expr and suppress_exception: self.excinfo.match(self.match_expr) return suppress_exception diff --git a/changelog/1810.bugfix.rst b/changelog/1810.bugfix.rst deleted file mode 100644 index c91ed47d0..000000000 --- a/changelog/1810.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Move import of ``doctest.UnexpectedException`` to top-level to avoid possible errors when using ``--pdb``. diff --git a/changelog/3052.bugfix b/changelog/3052.bugfix deleted file mode 100644 index ea8c362a4..000000000 --- a/changelog/3052.bugfix +++ /dev/null @@ -1 +0,0 @@ -Added printing of captured stdout/stderr before entering pdb, and improved a test which was giving false negatives about output capturing. diff --git a/changelog/3161.bugfix.rst b/changelog/3161.bugfix.rst deleted file mode 100644 index 73872be67..000000000 --- a/changelog/3161.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Fix ordering of tests using parametrized fixtures which can lead to fixtures being created more than necessary. diff --git a/changelog/3166.trivial.rst b/changelog/3166.trivial.rst deleted file mode 100644 index ce92840cb..000000000 --- a/changelog/3166.trivial.rst +++ /dev/null @@ -1 +0,0 @@ -Rename ``ParameterSet._for_parameterize()`` to ``_for_parametrize()`` in order to comply with the naming convention. diff --git a/changelog/3184.bugfix b/changelog/3184.bugfix deleted file mode 100644 index 875358776..000000000 --- a/changelog/3184.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix bug where logging happening at hooks outside of "test run" hooks would cause an internal error. diff --git a/changelog/3202.doc.rst b/changelog/3202.doc.rst deleted file mode 100644 index a6f99fbf6..000000000 --- a/changelog/3202.doc.rst +++ /dev/null @@ -1 +0,0 @@ -Add Sphinx parameter docs for ``match`` and ``message`` args to ``pytest.raises``. diff --git a/changelog/3206.bugfix.rst b/changelog/3206.bugfix.rst deleted file mode 100644 index 1e2305fa2..000000000 --- a/changelog/3206.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Detect arguments injected by ``unittest.mock.patch`` decorator correctly when pypi ``mock.patch`` is installed and imported. diff --git a/changelog/985.trivial.rst b/changelog/985.trivial.rst deleted file mode 100644 index 8554f2b65..000000000 --- a/changelog/985.trivial.rst +++ /dev/null @@ -1 +0,0 @@ -Skip failing pdb/doctest test on mac. diff --git a/changelog/README.rst b/changelog/README.rst index f00720de9..35d3a40ed 100644 --- a/changelog/README.rst +++ b/changelog/README.rst @@ -1,10 +1,12 @@ -This directory contains "newsfragments" which are short that contain a small **ReST**-formatted +This directory contains "newsfragments" which are short files that contain a small **ReST**-formatted text that will be added to the next ``CHANGELOG``. The ``CHANGELOG`` will be read by users, so this description should be aimed to pytest users instead of describing internal changes which are only relevant to the developers. -Make sure to use full sentences with correct case and punctuation, for example: *Fix issue with non-ascii contents in doctest text files.* +Make sure to use full sentences with correct case and punctuation, for example:: + + Fix issue with non-ascii messages from the ``warnings`` module. Each file should be named like ``..rst``, where ```` is an issue number, and ```` is one of: diff --git a/doc/en/announce/index.rst b/doc/en/announce/index.rst index 4f3ec8b4e..b130f52bd 100644 --- a/doc/en/announce/index.rst +++ b/doc/en/announce/index.rst @@ -6,6 +6,7 @@ Release announcements :maxdepth: 2 + release-3.4.1 release-3.4.0 release-3.3.2 release-3.3.1 diff --git a/doc/en/announce/release-3.4.1.rst b/doc/en/announce/release-3.4.1.rst new file mode 100644 index 000000000..0c5932e62 --- /dev/null +++ b/doc/en/announce/release-3.4.1.rst @@ -0,0 +1,27 @@ +pytest-3.4.1 +======================================= + +pytest 3.4.1 has just been released to PyPI. + +This is a bug-fix release, being a drop-in replacement. To upgrade:: + + pip install --upgrade pytest + +The full changelog is available at http://doc.pytest.org/en/latest/changelog.html. + +Thanks to all who contributed to this release, among them: + +* Aaron +* Alan Velasco +* Andy Freeland +* Brian Maissy +* Bruno Oliveira +* Florian Bruhin +* Jason R. Coombs +* Marcin Bachry +* Pedro Algarvio +* Ronny Pfannschmidt + + +Happy testing, +The pytest Development Team diff --git a/doc/en/example/reportingdemo.rst b/doc/en/example/reportingdemo.rst index b0c25dedc..eb60bf85e 100644 --- a/doc/en/example/reportingdemo.rst +++ b/doc/en/example/reportingdemo.rst @@ -358,7 +358,7 @@ get on the terminal - we are working on that):: > int(s) E ValueError: invalid literal for int() with base 10: 'qwe' - <0-codegen $PYTHON_PREFIX/lib/python3.5/site-packages/_pytest/python_api.py:580>:1: ValueError + <0-codegen $PYTHON_PREFIX/lib/python3.5/site-packages/_pytest/python_api.py:583>:1: ValueError ______________________ TestRaises.test_raises_doesnt _______________________ self = diff --git a/doc/en/example/simple.rst b/doc/en/example/simple.rst index ffc68b296..8a2a92bf6 100644 --- a/doc/en/example/simple.rst +++ b/doc/en/example/simple.rst @@ -385,8 +385,8 @@ Now we can profile which test functions execute the slowest:: test_some_are_slow.py ... [100%] ========================= slowest 3 test durations ========================= - 0.58s call test_some_are_slow.py::test_funcslow2 - 0.41s call test_some_are_slow.py::test_funcslow1 + 0.30s call test_some_are_slow.py::test_funcslow2 + 0.20s call test_some_are_slow.py::test_funcslow1 0.10s call test_some_are_slow.py::test_funcfast ========================= 3 passed in 0.12 seconds ========================= diff --git a/tasks/generate.py b/tasks/generate.py index 5aa4752f5..268b36fd6 100644 --- a/tasks/generate.py +++ b/tasks/generate.py @@ -1,4 +1,6 @@ -import os +""" +Invoke development tasks. +""" from pathlib import Path from subprocess import check_output, check_call @@ -57,7 +59,7 @@ def regen(ctx): @invoke.task() def make_tag(ctx, version): - """Create a new (local) tag for the release, only if the repository is clean.""" + """Create a new, local tag for the release, only if the repository is clean.""" from git import Repo repo = Repo('.') @@ -74,81 +76,24 @@ def make_tag(ctx, version): repo.create_tag(version) -@invoke.task() -def devpi_upload(ctx, version, user, password=None): - """Creates and uploads a package to devpi for testing.""" - if password: - print("[generate.devpi_upload] devpi login {}".format(user)) - check_call(['devpi', 'login', user, '--password', password]) - - check_call(['devpi', 'use', 'https://devpi.net/{}/dev'.format(user)]) - - env = os.environ.copy() - env['SETUPTOOLS_SCM_PRETEND_VERSION'] = version - check_call(['devpi', 'upload', '--formats', 'sdist,bdist_wheel'], env=env) - print("[generate.devpi_upload] package uploaded") - - @invoke.task(help={ 'version': 'version being released', - 'user': 'name of the user on devpi to stage the generated package', - 'password': 'user password on devpi to stage the generated package ' - '(if not given assumed logged in)', }) -def pre_release(ctx, version, user, password=None): - """Generates new docs, release announcements and uploads a new release to devpi for testing.""" +def pre_release(ctx, version): + """Generates new docs, release announcements and creates a local tag.""" announce(ctx, version) regen(ctx) changelog(ctx, version, write_out=True) msg = 'Preparing release version {}'.format(version) check_call(['git', 'commit', '-a', '-m', msg]) - + make_tag(ctx, version) - devpi_upload(ctx, version=version, user=user, password=password) - print() print('[generate.pre_release] Please push your branch and open a PR.') -@invoke.task(help={ - 'version': 'version being released', - 'user': 'name of the user on devpi to stage the generated package', - 'pypi_name': 'name of the pypi configuration section in your ~/.pypirc', -}) -def publish_release(ctx, version, user, pypi_name): - """Publishes a package previously created by the 'pre_release' command.""" - from git import Repo - repo = Repo('.') - tag_names = [x.name for x in repo.tags] - if version not in tag_names: - print('Could not find tag for version {}, exiting...'.format(version)) - raise invoke.Exit(code=2) - - check_call(['devpi', 'use', 'https://devpi.net/{}/dev'.format(user)]) - check_call(['devpi', 'push', 'pytest=={}'.format(version), 'pypi:{}'.format(pypi_name)]) - check_call(['git', 'push', 'git@github.com:pytest-dev/pytest.git', version]) - - emails = [ - 'pytest-dev@python.org', - 'python-announce-list@python.org' - ] - if version.endswith('.0'): - emails.append('testing-in-python@lists.idyll.org') - print('Version {} has been published to PyPI!'.format(version)) - print() - print('Please send an email announcement with the contents from:') - print() - print(' doc/en/announce/release-{}.rst'.format(version)) - print() - print('To the following mail lists:') - print() - print(' ', ','.join(emails)) - print() - print('And announce it on twitter adding the #pytest hash tag.') - - @invoke.task(help={ 'version': 'version being released', 'write_out': 'write changes to the actual changelog' @@ -158,5 +103,4 @@ def changelog(ctx, version, write_out=False): addopts = [] else: addopts = ['--draft'] - check_call(['towncrier', '--version', version] + addopts) - + check_call(['towncrier', '--yes', '--version', version] + addopts) diff --git a/tasks/requirements.txt b/tasks/requirements.txt index be4bff990..7f41521e6 100644 --- a/tasks/requirements.txt +++ b/tasks/requirements.txt @@ -1,6 +1,4 @@ -devpi-client gitpython invoke towncrier tox -wheel diff --git a/testing/python/raises.py b/testing/python/raises.py index 321ee349e..183259f6b 100644 --- a/testing/python/raises.py +++ b/testing/python/raises.py @@ -132,3 +132,13 @@ class TestRaises(object): with pytest.raises(AssertionError, match=expr): with pytest.raises(ValueError, match=msg): int('asdf', base=10) + + def test_raises_match_wrong_type(self): + """Raising an exception with the wrong type and match= given. + + pytest should throw the unexpected exception - the pattern match is not + really relevant if we got a different exception. + """ + with pytest.raises(ValueError): + with pytest.raises(IndexError, match='nomatch'): + int('asdf') diff --git a/testing/test_pdb.py b/testing/test_pdb.py index fa3d86d31..a36ada05b 100644 --- a/testing/test_pdb.py +++ b/testing/test_pdb.py @@ -316,10 +316,6 @@ class TestPDB(object): child.read() self.flush(child) - # For some reason the interaction between doctest's and pytest's output - # capturing mechanisms are messing up the stdout on mac. (See #985). - # Should be solvable, but skipping until we have a chance to investigate. - @pytest.mark.xfail("sys.platform == 'darwin'", reason='See issue #985', run=False) def test_pdb_interaction_doctest(self, testdir): p1 = testdir.makepyfile(""" import pytest