Merge remote-tracking branch 'upstream/master' into features

This commit is contained in:
Bruno Oliveira 2017-05-31 13:51:41 -03:00
commit 9adf513c4b
18 changed files with 295 additions and 85 deletions

View File

@ -2,13 +2,14 @@ Thanks for submitting a PR, your contribution is really appreciated!
Here's a quick checklist that should be present in PRs: Here's a quick checklist that should be present in PRs:
- [ ] Target: for bug or doc fixes, target `master`; for new features, target `features`; - [ ] Add a new news fragment into the changelog folder
* name it `$issue_id.$type` for example (588.bug)
* if you don't have an issue_id change it to the pr id after creating the pr
* ensure type is one of `removal`, `feature`, `bugfix`, `vendor`, `doc` or `trivial`
* Make sure to use full sentences with correct case and punctuation, for example: "Fix issue with non-ascii contents in doctest text files."
- [ ] Target: for `bugfix`, `vendor`, `doc` or `trivial` fixes, target `master`; for removals or features target `features`;
- [ ] Make sure to include reasonable tests for your change if necessary
Unless your change is trivial documentation fix (e.g., a typo or reword of a small section) please: Unless your change is a trivial or a documentation fix (e.g., a typo or reword of a small section) please:
- [ ] Make sure to include one or more tests for your change;
- [ ] Add yourself to `AUTHORS`; - [ ] Add yourself to `AUTHORS`;
- [ ] Add a new entry to `CHANGELOG.rst`
* Choose any open position to avoid merge conflicts with other PRs.
* Add a link to the issue you are fixing (if any) using RST syntax.
* The pytest team likes to have people to acknowledged in the `CHANGELOG`, so please add a thank note to yourself ("Thanks @user for the PR") and a link to your GitHub profile. It may sound weird thanking yourself, but otherwise a maintainer would have to do it manually before or after merging instead of just using GitHub's merge button. This makes it easier on the maintainers to merge PRs.

View File

@ -1,9 +1,37 @@
3.1.1 (unreleased) ..
================== You should *NOT* be adding new change log entries to this file, this
file is managed by towncrier. You *may* edit previous change logs to
fix problems like typo corrections or such.
To add a new change log entry, please see
https://pip.pypa.io/en/latest/development/#adding-a-news-entry
we named the news folder changelog
* Fix encoding errors for unicode warnings in Python 2. (towncrier: 2436.bugfix) .. towncrier release notes start
* Fix issue with non-ascii contents in doctest text files. (towncrier: 2434.bugfix) Pytest 3.1.1 (2017-05-30)
=========================
Bug Fixes
---------
- pytest warning capture no longer overrides existing warning filters. The
previous behaviour would override all filters and caused regressions in test
suites which configure warning filters to match their needs. Note that as a
side-effect of this is that ``DeprecationWarning`` and
``PendingDeprecationWarning`` are no longer shown by default. (#2430)
- Fix issue with non-ascii contents in doctest text files. (#2434)
- Fix encoding errors for unicode warnings in Python 2. (#2436)
- ``pytest.deprecated_call`` now captures ``PendingDeprecationWarning`` in
context manager form. (#2441)
Improved Documentation
----------------------
- Addition of towncrier for changelog management. (#2390)
3.1.0 (2017-05-22) 3.1.0 (2017-05-22)

View File

@ -3,47 +3,59 @@ How to release pytest
.. important:: .. important::
pytest releases must be prepared on **linux** because the docs and examples expect pytest releases must be prepared on **Linux** because the docs and examples expect
to be executed in that platform. to be executed in that platform.
#. Install development dependencies in a virtual environment with:: #. Install development dependencies in a virtual environment with::
pip3 install -r tasks/requirements.txt pip3 install -r tasks/requirements.txt
#. Create a branch ``release-X.Y.Z`` with the version for the release. Make sure it is up to date #. Create a branch ``release-X.Y.Z`` with the version for the release.
with the latest ``master`` (for patch releases) and with the latest ``features`` merged with
the latest ``master`` (for minor releases). Ensure your are in a clean work tree.
#. Check and finalize ``CHANGELOG.rst`` (will be automated soon). * **patch releases**: from the latest ``master``;
#. Execute to automatically generate docs, announcements and upload a package to * **minor releases**: from the latest ``features``; then merge with the latest ``master``;
Ensure your are in a clean work tree.
#. Generate docs, changelog, announcements and upload a package to
your ``devpi`` staging server:: your ``devpi`` staging server::
invoke generate.pre_release <VERSION> <DEVPI USER> --password <DEVPI PASSWORD> invoke generate.pre_release <VERSION> <DEVPI USER> --password <DEVPI PASSWORD>
If ``--password`` is not given, it is assumed the user is already logged in. If you don't have If ``--password`` is not given, it is assumed the user is already logged in ``devpi``.
an account, please ask for one! If you don't have an account, please ask for one.
#. Run from multiple machines:: #. Open a PR for this branch targeting ``master``.
devpi use https://devpi.net/USER/dev #. Test the package
devpi test pytest==VERSION
Alternatively, you can use `devpi-cloud-tester <https://github.com/nicoddemus/devpi-cloud-tester>`_ to test * **Manual method**
the package on AppVeyor and Travis (follow instructions on the ``README``).
#. Check that tests pass for relevant combinations with:: Run from multiple machines::
devpi use https://devpi.net/USER/dev
devpi test pytest==VERSION
Check that tests pass for relevant combinations with::
devpi list pytest devpi list pytest
or look at failures with "devpi list -f pytest". * **CI servers**
#. Feeling confident? Publish to PyPI:: 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 <VERSION> <DEVPI USER> <PYPI_NAME> invoke generate.publish_release <VERSION> <DEVPI USER> <PYPI_NAME>
where PYPI_NAME is the name of pypi.python.org as configured in your ``~/.pypirc`` where PYPI_NAME is the name of pypi.python.org as configured in your ``~/.pypirc``
file `for devpi <http://doc.devpi.net/latest/quickstart-releaseprocess.html?highlight=pypirc#devpi-push-releasing-to-an-external-index>`_. file `for devpi <http://doc.devpi.net/latest/quickstart-releaseprocess.html?highlight=pypirc#devpi-push-releasing-to-an-external-index>`_.
#. After a minor/major release, merge ``features`` into ``master`` and push (or open a PR). #. After a minor/major release, merge ``features`` 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

View File

@ -1,6 +1,7 @@
include CHANGELOG.rst include CHANGELOG.rst
include LICENSE include LICENSE
include AUTHORS include AUTHORS
include pyproject.toml
include README.rst include README.rst
include CONTRIBUTING.rst include CONTRIBUTING.rst
@ -9,6 +10,7 @@ include HOWTORELEASE.rst
include tox.ini include tox.ini
include setup.py include setup.py
recursive-include changelog *
recursive-include scripts *.py recursive-include scripts *.py
recursive-include scripts *.bat recursive-include scripts *.bat

View File

@ -45,7 +45,7 @@ def deprecated_call(func=None, *args, **kwargs):
triggered twice for the same module. See #1190. triggered twice for the same module. See #1190.
""" """
if not func: if not func:
return WarningsChecker(expected_warning=DeprecationWarning) return WarningsChecker(expected_warning=(DeprecationWarning, PendingDeprecationWarning))
categories = [] categories = []

View File

@ -53,7 +53,6 @@ def catch_warnings_for_item(item):
args = item.config.getoption('pythonwarnings') or [] args = item.config.getoption('pythonwarnings') or []
inifilters = item.config.getini("filterwarnings") inifilters = item.config.getini("filterwarnings")
with warnings.catch_warnings(record=True) as log: with warnings.catch_warnings(record=True) as log:
warnings.simplefilter('once')
for arg in args: for arg in args:
warnings._setoption(arg) warnings._setoption(arg)

39
changelog/_template.rst Normal file
View File

@ -0,0 +1,39 @@
{% for section in sections %}
{% set underline = "-" %}
{% if section %}
{{section}}
{{ underline * section|length }}{% set underline = "~" %}
{% endif %}
{% if sections[section] %}
{% for category, val in definitions.items() if category in sections[section] and category != 'trivial' %}
{{ definitions[category]['name'] }}
{{ underline * definitions[category]['name']|length }}
{% if definitions[category]['showcontent'] %}
{% for text, values in sections[section][category]|dictsort(by='value') %}
- {{ text }}{% if category != 'vendor' %} ({{ values|sort|join(', ') }}){% endif %}
{% endfor %}
{% else %}
- {{ sections[section][category]['']|sort|join(', ') }}
{% endif %}
{% if sections[section][category]|length == 0 %}
No significant changes.
{% else %}
{% endif %}
{% endfor %}
{% else %}
No significant changes.
{% endif %}
{% endfor %}

View File

@ -6,6 +6,7 @@ Release announcements
:maxdepth: 2 :maxdepth: 2
release-3.1.1
release-3.1.0 release-3.1.0
release-3.0.7 release-3.0.7
release-3.0.6 release-3.0.6

View File

@ -0,0 +1,23 @@
pytest-3.1.1
=======================================
pytest 3.1.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:
* Bruno Oliveira
* Florian Bruhin
* Floris Bruynooghe
* Jason R. Coombs
* Ronny Pfannschmidt
* wanghui
Happy testing,
The pytest Development Team

View File

@ -5,32 +5,18 @@ Warnings Capture
.. versionadded:: 3.1 .. versionadded:: 3.1
.. warning:: Starting from version ``3.1``, pytest now automatically catches warnings during test execution
pytest captures all warnings between tests, which prevents custom warning
filters in existing test suites from working. If this causes problems to your test suite,
this plugin can be disabled in your ``pytest.ini`` file with:
.. code-block:: ini
[pytest]
addopts = -p no:warnings
There's an ongoing discussion about this on `#2430
<https://github.com/pytest-dev/pytest/issues/2430>`_.
Starting from version ``3.1``, pytest now automatically catches all warnings during test execution
and displays them at the end of the session:: and displays them at the end of the session::
# content of test_show_warnings.py # content of test_show_warnings.py
import warnings import warnings
def deprecated_function(): def api_v1():
warnings.warn("this function is deprecated, use another_function()", DeprecationWarning) warnings.warn(UserWarning("api v1, should use functions from v2"))
return 1 return 1
def test_one(): def test_one():
assert deprecated_function() == 1 assert api_v1() == 1
Running pytest now produces this output:: Running pytest now produces this output::
@ -44,35 +30,37 @@ Running pytest now produces this output::
======= warnings summary ======== ======= warnings summary ========
test_show_warnings.py::test_one test_show_warnings.py::test_one
$REGENDOC_TMPDIR/test_show_warnings.py:4: DeprecationWarning: this function is deprecated, use another_function() $REGENDOC_TMPDIR/test_show_warnings.py:4: UserWarning: api v1, should use functions from v2
warnings.warn("this function is deprecated, use another_function()", DeprecationWarning) warnings.warn(UserWarning("api v1, should use functions from v2"))
-- Docs: http://doc.pytest.org/en/latest/warnings.html -- Docs: http://doc.pytest.org/en/latest/warnings.html
======= 1 passed, 1 warnings in 0.12 seconds ======== ======= 1 passed, 1 warnings in 0.12 seconds ========
Pytest by default catches all warnings except for ``DeprecationWarning`` and ``PendingDeprecationWarning``.
The ``-W`` flag can be passed to control which warnings will be displayed or even turn The ``-W`` flag can be passed to control which warnings will be displayed or even turn
them into errors:: them into errors::
$ pytest -q test_show_warnings.py -W error::DeprecationWarning $ pytest -q test_show_warnings.py -W error::UserWarning
F F
======= FAILURES ======== ======= FAILURES ========
_______ test_one ________ _______ test_one ________
def test_one(): def test_one():
> assert deprecated_function() == 1 > assert api_v1() == 1
test_show_warnings.py:8: test_show_warnings.py:8:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
def deprecated_function(): def api_v1():
> warnings.warn("this function is deprecated, use another_function()", DeprecationWarning) > warnings.warn(UserWarning("api v1, should use functions from v2"))
E DeprecationWarning: this function is deprecated, use another_function() E UserWarning: api v1, should use functions from v2
test_show_warnings.py:4: DeprecationWarning test_show_warnings.py:4: UserWarning
1 failed in 0.12 seconds 1 failed in 0.12 seconds
The same option can be set in the ``pytest.ini`` file using the ``filterwarnings`` ini option. The same option can be set in the ``pytest.ini`` file using the ``filterwarnings`` ini option.
For example, the configuration below will ignore all deprecation warnings, but will transform For example, the configuration below will ignore all user warnings, but will transform
all other warnings into errors. all other warnings into errors.
.. code-block:: ini .. code-block:: ini
@ -80,7 +68,7 @@ all other warnings into errors.
[pytest] [pytest]
filterwarnings = filterwarnings =
error error
ignore::DeprecationWarning ignore::UserWarning
When a warning matches more than one option in the list, the action for the last matching option When a warning matches more than one option in the list, the action for the last matching option
@ -90,6 +78,19 @@ Both ``-W`` command-line option and ``filterwarnings`` ini option are based on P
`-W option`_ and `warnings.simplefilter`_, so please refer to those sections in the Python `-W option`_ and `warnings.simplefilter`_, so please refer to those sections in the Python
documentation for other examples and advanced usage. documentation for other examples and advanced usage.
.. note::
``DeprecationWarning`` and ``PendingDeprecationWarning`` are hidden by the standard library
by default so you have to explicitly configure them to be displayed in your ``pytest.ini``:
.. code-block:: ini
[pytest]
filterwarnings =
once::DeprecationWarning
once::PendingDeprecationWarning
*Credits go to Florian Schulze for the reference implementation in the* `pytest-warnings`_ *Credits go to Florian Schulze for the reference implementation in the* `pytest-warnings`_
*plugin.* *plugin.*
@ -97,6 +98,19 @@ documentation for other examples and advanced usage.
.. _warnings.simplefilter: https://docs.python.org/3/library/warnings.html#warnings.simplefilter .. _warnings.simplefilter: https://docs.python.org/3/library/warnings.html#warnings.simplefilter
.. _`pytest-warnings`: https://github.com/fschulze/pytest-warnings .. _`pytest-warnings`: https://github.com/fschulze/pytest-warnings
Disabling warning capture
-------------------------
This feature is enabled by default but can be disabled entirely in your ``pytest.ini`` file with:
.. code-block:: ini
[pytest]
addopts = -p no:warnings
Or passing ``-p no:warnings`` in the command-line.
.. _`asserting warnings`: .. _`asserting warnings`:
.. _assertwarnings: .. _assertwarnings:

35
pyproject.toml Normal file
View File

@ -0,0 +1,35 @@
[tool.towncrier]
package = "pytest"
filename = "CHANGELOG.rst"
directory = "changelog/"
template = "changelog/_template.rst"
[[tool.towncrier.type]]
directory = "removal"
name = "Deprecations and Removals"
showcontent = true
[[tool.towncrier.type]]
directory = "feature"
name = "Features"
showcontent = true
[[tool.towncrier.type]]
directory = "bugfix"
name = "Bug Fixes"
showcontent = true
[[tool.towncrier.type]]
directory = "vendor"
name = "Vendored Libraries"
showcontent = true
[[tool.towncrier.type]]
directory = "doc"
name = "Improved Documentation"
showcontent = true
[[tool.towncrier.type]]
directory = "trivial"
name = "Trivial Changes"
showcontent = false

View File

@ -11,10 +11,10 @@ from __future__ import print_function
import os import os
import subprocess import subprocess
import sys import sys
from check_manifest import main
if os.path.isdir('.git'): if os.path.isdir('.git'):
sys.exit(subprocess.call('check-manifest', shell=True)) sys.exit(main())
else: else:
print('No .git directory found, skipping checking the manifest file') print('No .git directory found, skipping checking the manifest file')
sys.exit(0) sys.exit(0)

11
scripts/check-rst.py Normal file
View File

@ -0,0 +1,11 @@
from __future__ import print_function
import subprocess
import glob
import sys
sys.exit(subprocess.call([
'rst-lint', '--encoding', 'utf-8',
'CHANGELOG.rst', 'HOWTORELEASE.rst', 'README.rst',
] + glob.glob('changelog/[0-9]*.*')))

View File

@ -96,9 +96,10 @@ def devpi_upload(ctx, version, user, password=None):
'(if not given assumed logged in)', '(if not given assumed logged in)',
}) })
def pre_release(ctx, version, user, password=None): def pre_release(ctx, version, user, password=None):
"""Generates new docs, release announcements and uploads a new release to devpi for testing.""" """Generates new docs, release announcements and uploads a new release to devpi for testing."""
announce(ctx, version) announce(ctx, version)
regen(ctx) regen(ctx)
changelog(ctx, version, write_out=True)
msg = 'Preparing release version {}'.format(version) msg = 'Preparing release version {}'.format(version)
check_call(['git', 'commit', '-a', '-m', msg]) check_call(['git', 'commit', '-a', '-m', msg])
@ -146,3 +147,16 @@ def publish_release(ctx, version, user, pypi_name):
print(' ', ','.join(emails)) print(' ', ','.join(emails))
print() print()
print('And announce it on twitter adding the #pytest hash tag.') print('And announce it on twitter adding the #pytest hash tag.')
@invoke.task(help={
'version': 'version being released',
'write_out': 'write changes to the actial changelog'
})
def changelog(ctx, version, write_out=False):
if write_out:
addopts = []
else:
addopts = ['--draft']
check_call(['towncrier', '--version', version] + addopts)

View File

@ -1,3 +1,4 @@
invoke invoke
tox tox
gitpython gitpython
towncrier

View File

@ -2,6 +2,8 @@ from __future__ import absolute_import, division, print_function
import warnings import warnings
import re import re
import py import py
import sys
import pytest import pytest
from _pytest.recwarn import WarningsRecorder from _pytest.recwarn import WarningsRecorder
@ -109,14 +111,17 @@ class TestDeprecatedCall(object):
with pytest.deprecated_call(): with pytest.deprecated_call():
self.dep(1) self.dep(1)
def test_deprecated_call_as_context_manager(self): @pytest.mark.parametrize('warning_type', [PendingDeprecationWarning, DeprecationWarning])
with pytest.deprecated_call(): @pytest.mark.parametrize('mode', ['context_manager', 'call'])
self.dep(0) def test_deprecated_call_modes(self, warning_type, mode):
def test_deprecated_call_pending(self):
def f(): def f():
py.std.warnings.warn(PendingDeprecationWarning("hi")) warnings.warn(warning_type("hi"))
pytest.deprecated_call(f)
if mode == 'call':
pytest.deprecated_call(f)
else:
with pytest.deprecated_call():
f()
def test_deprecated_call_specificity(self): def test_deprecated_call_specificity(self):
other_warnings = [Warning, UserWarning, SyntaxWarning, RuntimeWarning, other_warnings = [Warning, UserWarning, SyntaxWarning, RuntimeWarning,
@ -146,9 +151,12 @@ class TestDeprecatedCall(object):
pytest.deprecated_call(deprecated_function) pytest.deprecated_call(deprecated_function)
""") """)
result = testdir.runpytest() result = testdir.runpytest()
# the 2 tests must pass, but the call to test_one() will generate a warning # for some reason in py26 catch_warnings manages to catch the deprecation warning
# in pytest's summary # from deprecated_function(), even with default filters active (which ignore deprecation
result.stdout.fnmatch_lines('*=== 2 passed, 1 warnings in *===') # warnings)
py26 = sys.version_info[:2] == (2, 6)
expected = '*=== 2 passed in *===' if not py26 else '*=== 2 passed, 1 warnings in *==='
result.stdout.fnmatch_lines(expected)
class TestWarns(object): class TestWarns(object):

View File

@ -20,8 +20,8 @@ def pyfile_with_warnings(testdir, request):
module_name: ''' module_name: '''
import warnings import warnings
def foo(): def foo():
warnings.warn(PendingDeprecationWarning("functionality is pending deprecation")) warnings.warn(UserWarning("user warning"))
warnings.warn(DeprecationWarning("functionality is deprecated")) warnings.warn(RuntimeWarning("runtime warning"))
return 1 return 1
''', ''',
test_name: ''' test_name: '''
@ -43,11 +43,11 @@ def test_normal_flow(testdir, pyfile_with_warnings):
'*test_normal_flow.py::test_func', '*test_normal_flow.py::test_func',
'*normal_flow_module.py:3: PendingDeprecationWarning: functionality is pending deprecation', '*normal_flow_module.py:3: UserWarning: user warning',
'* warnings.warn(PendingDeprecationWarning("functionality is pending deprecation"))', '* warnings.warn(UserWarning("user warning"))',
'*normal_flow_module.py:4: DeprecationWarning: functionality is deprecated', '*normal_flow_module.py:4: RuntimeWarning: runtime warning',
'* warnings.warn(DeprecationWarning("functionality is deprecated"))', '* warnings.warn(RuntimeWarning("runtime warning"))',
'* 1 passed, 2 warnings*', '* 1 passed, 2 warnings*',
]) ])
assert result.stdout.str().count('test_normal_flow.py::test_func') == 1 assert result.stdout.str().count('test_normal_flow.py::test_func') == 1
@ -90,8 +90,8 @@ def test_as_errors(testdir, pyfile_with_warnings, method):
''') ''')
result = testdir.runpytest(*args) result = testdir.runpytest(*args)
result.stdout.fnmatch_lines([ result.stdout.fnmatch_lines([
'E PendingDeprecationWarning: functionality is pending deprecation', 'E UserWarning: user warning',
'as_errors_module.py:3: PendingDeprecationWarning', 'as_errors_module.py:3: UserWarning',
'* 1 failed in *', '* 1 failed in *',
]) ])
@ -133,9 +133,7 @@ def test_unicode(testdir, pyfile_with_warnings):
result = testdir.runpytest() result = testdir.runpytest()
result.stdout.fnmatch_lines([ result.stdout.fnmatch_lines([
'*== %s ==*' % WARNINGS_SUMMARY_HEADER, '*== %s ==*' % WARNINGS_SUMMARY_HEADER,
'*test_unicode.py:8: UserWarning: \u6d4b\u8bd5*',
'*test_unicode.py:8: UserWarning: \u6d4b\u8bd5',
'*warnings.warn(u"\u6d4b\u8bd5")',
'* 1 passed, 1 warnings*', '* 1 passed, 1 warnings*',
]) ])
@ -163,6 +161,30 @@ def test_py2_unicode(testdir, pyfile_with_warnings):
'*test_py2_unicode.py:8: UserWarning: \u6d4b\u8bd5', '*test_py2_unicode.py:8: UserWarning: \u6d4b\u8bd5',
'*warnings.warn(u"\u6d4b\u8bd5")', '*warnings.warn(u"\u6d4b\u8bd5")',
'*warnings.py:82: UnicodeWarning: This warning*\u6d4b\u8bd5', '*warnings.py:*: UnicodeWarning: This warning*\u6d4b\u8bd5',
'* 1 passed, 2 warnings*', '* 1 passed, 2 warnings*',
]) ])
def test_works_with_filterwarnings(testdir):
"""Ensure our warnings capture does not mess with pre-installed filters (#2430)."""
testdir.makepyfile('''
import warnings
class MyWarning(Warning):
pass
warnings.filterwarnings("error", category=MyWarning)
class TestWarnings(object):
def test_my_warning(self):
try:
warnings.warn(MyWarning("warn!"))
assert False
except MyWarning:
assert True
''')
result = testdir.runpytest()
result.stdout.fnmatch_lines([
'*== 1 passed in *',
])

View File

@ -61,7 +61,7 @@ deps =
commands = commands =
{envpython} scripts/check-manifest.py {envpython} scripts/check-manifest.py
flake8 pytest.py _pytest testing flake8 pytest.py _pytest testing
rst-lint CHANGELOG.rst HOWTORELEASE.rst README.rst --encoding utf-8 {envpython} scripts/check-rst.py
[testenv:py27-xdist] [testenv:py27-xdist]
deps=pytest-xdist>=1.13 deps=pytest-xdist>=1.13
@ -184,7 +184,7 @@ python_files=test_*.py *_test.py testing/*/*.py
python_classes=Test Acceptance python_classes=Test Acceptance
python_functions=test python_functions=test
norecursedirs = .tox ja .hg cx_freeze_source norecursedirs = .tox ja .hg cx_freeze_source
filterwarnings= error filterwarnings=
# produced by path.local # produced by path.local
ignore:bad escape.*:DeprecationWarning:re ignore:bad escape.*:DeprecationWarning:re
# produced by path.readlines # produced by path.readlines