commit
b847d5712b
|
@ -49,8 +49,9 @@ jobs:
|
||||||
# - pytester's LsofFdLeakChecker
|
# - pytester's LsofFdLeakChecker
|
||||||
# - TestArgComplete (linux only)
|
# - TestArgComplete (linux only)
|
||||||
# - numpy
|
# - numpy
|
||||||
|
# - old attrs
|
||||||
# Empty PYTEST_ADDOPTS to run this non-verbose.
|
# Empty PYTEST_ADDOPTS to run this non-verbose.
|
||||||
- env: TOXENV=py37-lsof-numpy-twisted-xdist PYTEST_COVERAGE=1 PYTEST_ADDOPTS=
|
- env: TOXENV=py37-lsof-oldattrs-numpy-twisted-xdist PYTEST_COVERAGE=1 PYTEST_ADDOPTS=
|
||||||
|
|
||||||
# Specialized factors for py37.
|
# Specialized factors for py37.
|
||||||
# Coverage for:
|
# Coverage for:
|
||||||
|
|
|
@ -18,6 +18,54 @@ with advance notice in the **Deprecations** section of releases.
|
||||||
|
|
||||||
.. towncrier release notes start
|
.. towncrier release notes start
|
||||||
|
|
||||||
|
pytest 5.2.1 (2019-10-06)
|
||||||
|
=========================
|
||||||
|
|
||||||
|
Bug Fixes
|
||||||
|
---------
|
||||||
|
|
||||||
|
- `#5902 <https://github.com/pytest-dev/pytest/issues/5902>`_: Fix warnings about deprecated ``cmp`` attribute in ``attrs>=19.2``.
|
||||||
|
|
||||||
|
|
||||||
|
pytest 5.2.0 (2019-09-28)
|
||||||
|
=========================
|
||||||
|
|
||||||
|
Deprecations
|
||||||
|
------------
|
||||||
|
|
||||||
|
- `#1682 <https://github.com/pytest-dev/pytest/issues/1682>`_: Passing arguments to pytest.fixture() as positional arguments is deprecated - pass them
|
||||||
|
as a keyword argument instead.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Features
|
||||||
|
--------
|
||||||
|
|
||||||
|
- `#1682 <https://github.com/pytest-dev/pytest/issues/1682>`_: The ``scope`` parameter of ``@pytest.fixture`` can now be a callable that receives
|
||||||
|
the fixture name and the ``config`` object as keyword-only parameters.
|
||||||
|
See `the docs <https://docs.pytest.org/en/latest/fixture.html#dynamic-scope>`__ for more information.
|
||||||
|
|
||||||
|
|
||||||
|
- `#5764 <https://github.com/pytest-dev/pytest/issues/5764>`_: New behavior of the ``--pastebin`` option: failures to connect to the pastebin server are reported, without failing the pytest run
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Bug Fixes
|
||||||
|
---------
|
||||||
|
|
||||||
|
- `#5806 <https://github.com/pytest-dev/pytest/issues/5806>`_: Fix "lexer" being used when uploading to bpaste.net from ``--pastebin`` to "text".
|
||||||
|
|
||||||
|
|
||||||
|
- `#5884 <https://github.com/pytest-dev/pytest/issues/5884>`_: Fix ``--setup-only`` and ``--setup-show`` for custom pytest items.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Trivial/Internal Changes
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
- `#5056 <https://github.com/pytest-dev/pytest/issues/5056>`_: The HelpFormatter uses ``py.io.get_terminal_width`` for better width detection.
|
||||||
|
|
||||||
|
|
||||||
pytest 5.1.3 (2019-09-18)
|
pytest 5.1.3 (2019-09-18)
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
Passing arguments to pytest.fixture() as positional arguments is deprecated - pass them
|
|
||||||
as a keyword argument instead.
|
|
|
@ -1,3 +0,0 @@
|
||||||
The ``scope`` parameter of ``@pytest.fixture`` can now be a callable that receives
|
|
||||||
the fixture name and the ``config`` object as keyword-only parameters.
|
|
||||||
See `the docs <https://docs.pytest.org/en/fixture.html#dynamic-scope>`__ for more information.
|
|
|
@ -1 +0,0 @@
|
||||||
The HelpFormatter uses ``py.io.get_terminal_width`` for better width detection.
|
|
|
@ -1 +0,0 @@
|
||||||
New behavior of the ``--pastebin`` option: failures to connect to the pastebin server are reported, without failing the pytest run
|
|
|
@ -1 +0,0 @@
|
||||||
Fix "lexer" being used when uploading to bpaste.net from ``--pastebin`` to "text".
|
|
|
@ -6,6 +6,8 @@ Release announcements
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
|
|
||||||
|
release-5.2.1
|
||||||
|
release-5.2.0
|
||||||
release-5.1.3
|
release-5.1.3
|
||||||
release-5.1.2
|
release-5.1.2
|
||||||
release-5.1.1
|
release-5.1.1
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
pytest-5.2.0
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
The pytest team is proud to announce the 5.2.0 release!
|
||||||
|
|
||||||
|
pytest is a mature Python testing tool with more than a 2000 tests
|
||||||
|
against itself, passing on many different interpreters and platforms.
|
||||||
|
|
||||||
|
This release contains a number of bugs fixes and improvements, so users are encouraged
|
||||||
|
to take a look at the CHANGELOG:
|
||||||
|
|
||||||
|
https://docs.pytest.org/en/latest/changelog.html
|
||||||
|
|
||||||
|
For complete documentation, please visit:
|
||||||
|
|
||||||
|
https://docs.pytest.org/en/latest/
|
||||||
|
|
||||||
|
As usual, you can upgrade from pypi via:
|
||||||
|
|
||||||
|
pip install -U pytest
|
||||||
|
|
||||||
|
Thanks to all who contributed to this release, among them:
|
||||||
|
|
||||||
|
* Andrzej Klajnert
|
||||||
|
* Anthony Sottile
|
||||||
|
* Bruno Oliveira
|
||||||
|
* Daniel Hahler
|
||||||
|
* James Cooke
|
||||||
|
* Michael Goerz
|
||||||
|
* Ran Benita
|
||||||
|
* Tomáš Chvátal
|
||||||
|
* aklajnert
|
||||||
|
|
||||||
|
|
||||||
|
Happy testing,
|
||||||
|
The Pytest Development Team
|
|
@ -0,0 +1,23 @@
|
||||||
|
pytest-5.2.1
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
pytest 5.2.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 https://docs.pytest.org/en/latest/changelog.html.
|
||||||
|
|
||||||
|
Thanks to all who contributed to this release, among them:
|
||||||
|
|
||||||
|
* Anthony Sottile
|
||||||
|
* Bruno Oliveira
|
||||||
|
* Florian Bruhin
|
||||||
|
* Hynek Schlawack
|
||||||
|
* Kevin J. Foley
|
||||||
|
* tadashigaki
|
||||||
|
|
||||||
|
|
||||||
|
Happy testing,
|
||||||
|
The pytest Development Team
|
|
@ -134,10 +134,13 @@ progress output, you can write it into a configuration file:
|
||||||
.. code-block:: ini
|
.. code-block:: ini
|
||||||
|
|
||||||
# content of pytest.ini or tox.ini
|
# content of pytest.ini or tox.ini
|
||||||
# setup.cfg files should use [tool:pytest] section instead
|
|
||||||
[pytest]
|
[pytest]
|
||||||
addopts = -ra -q
|
addopts = -ra -q
|
||||||
|
|
||||||
|
# content of setup.cfg
|
||||||
|
[tool:pytest]
|
||||||
|
addopts = -ra -q
|
||||||
|
|
||||||
Alternatively, you can set a ``PYTEST_ADDOPTS`` environment variable to add command
|
Alternatively, you can set a ``PYTEST_ADDOPTS`` environment variable to add command
|
||||||
line options while the environment is in use:
|
line options while the environment is in use:
|
||||||
|
|
||||||
|
|
|
@ -475,10 +475,10 @@ Running it results in some skips if we don't have all the python interpreters in
|
||||||
.. code-block:: pytest
|
.. code-block:: pytest
|
||||||
|
|
||||||
. $ pytest -rs -q multipython.py
|
. $ pytest -rs -q multipython.py
|
||||||
ssssssssssss...ssssssssssss [100%]
|
ssssssssssssssssssssssss... [100%]
|
||||||
========================= short test summary info ==========================
|
========================= short test summary info ==========================
|
||||||
SKIPPED [12] $REGENDOC_TMPDIR/CWD/multipython.py:30: 'python3.5' not found
|
SKIPPED [12] $REGENDOC_TMPDIR/CWD/multipython.py:30: 'python3.5' not found
|
||||||
SKIPPED [12] $REGENDOC_TMPDIR/CWD/multipython.py:30: 'python3.7' not found
|
SKIPPED [12] $REGENDOC_TMPDIR/CWD/multipython.py:30: 'python3.6' not found
|
||||||
3 passed, 24 skipped in 0.12s
|
3 passed, 24 skipped in 0.12s
|
||||||
|
|
||||||
Indirect parametrization of optional implementations/imports
|
Indirect parametrization of optional implementations/imports
|
||||||
|
|
|
@ -436,7 +436,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
|
||||||
items = [1, 2, 3]
|
items = [1, 2, 3]
|
||||||
print("items is {!r}".format(items))
|
print("items is {!r}".format(items))
|
||||||
> a, b = items.pop()
|
> a, b = items.pop()
|
||||||
E TypeError: 'int' object is not iterable
|
E TypeError: cannot unpack non-iterable int object
|
||||||
|
|
||||||
failure_demo.py:181: TypeError
|
failure_demo.py:181: TypeError
|
||||||
--------------------------- Captured stdout call ---------------------------
|
--------------------------- Captured stdout call ---------------------------
|
||||||
|
@ -516,7 +516,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
|
||||||
def test_z2_type_error(self):
|
def test_z2_type_error(self):
|
||||||
items = 3
|
items = 3
|
||||||
> a, b = items
|
> a, b = items
|
||||||
E TypeError: 'int' object is not iterable
|
E TypeError: cannot unpack non-iterable int object
|
||||||
|
|
||||||
failure_demo.py:222: TypeError
|
failure_demo.py:222: TypeError
|
||||||
______________________ TestMoreErrors.test_startswith ______________________
|
______________________ TestMoreErrors.test_startswith ______________________
|
||||||
|
|
|
@ -445,7 +445,7 @@ Now we can profile which test functions execute the slowest:
|
||||||
|
|
||||||
========================= slowest 3 test durations =========================
|
========================= slowest 3 test durations =========================
|
||||||
0.30s call test_some_are_slow.py::test_funcslow2
|
0.30s call test_some_are_slow.py::test_funcslow2
|
||||||
0.21s call test_some_are_slow.py::test_funcslow1
|
0.20s call test_some_are_slow.py::test_funcslow1
|
||||||
0.10s call test_some_are_slow.py::test_funcfast
|
0.10s call test_some_are_slow.py::test_funcfast
|
||||||
============================ 3 passed in 0.12s =============================
|
============================ 3 passed in 0.12s =============================
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ Install ``pytest``
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
$ pytest --version
|
$ pytest --version
|
||||||
This is pytest version 5.x.y, imported from $PYTHON_PREFIX/lib/python3.6/site-packages/pytest.py
|
This is pytest version 5.x.y, imported from $PYTHON_PREFIX/lib/python3.7/site-packages/pytest.py
|
||||||
|
|
||||||
.. _`simpletest`:
|
.. _`simpletest`:
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,7 @@ the records for the ``setup`` and ``call`` stages during teardown like so:
|
||||||
yield window
|
yield window
|
||||||
for when in ("setup", "call"):
|
for when in ("setup", "call"):
|
||||||
messages = [
|
messages = [
|
||||||
x.message for x in caplog.get_records(when) if x.level == logging.WARNING
|
x.message for x in caplog.get_records(when) if x.levelno == logging.WARNING
|
||||||
]
|
]
|
||||||
if messages:
|
if messages:
|
||||||
pytest.fail(
|
pytest.fail(
|
||||||
|
|
|
@ -1003,7 +1003,7 @@ passed multiple times. The expected format is ``name=value``. For example::
|
||||||
[pytest]
|
[pytest]
|
||||||
addopts = --maxfail=2 -rf # exit after 2 failures, report fail info
|
addopts = --maxfail=2 -rf # exit after 2 failures, report fail info
|
||||||
|
|
||||||
issuing ``pytest test_hello.py`` actually means::
|
issuing ``pytest test_hello.py`` actually means:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
|
|
|
@ -13,4 +13,5 @@ fi
|
||||||
python -m coverage combine
|
python -m coverage combine
|
||||||
python -m coverage xml
|
python -m coverage xml
|
||||||
python -m coverage report -m
|
python -m coverage report -m
|
||||||
bash <(curl -s https://codecov.io/bash) -Z -X gcov -X coveragepy -X search -X xcode -X gcovout -X fix -f coverage.xml
|
curl -S -L --retry 6 -s https://codecov.io/bash -o codecov-upload.sh
|
||||||
|
bash codecov-upload.sh -Z -X fix -f coverage.xml
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -5,7 +5,7 @@ from setuptools import setup
|
||||||
INSTALL_REQUIRES = [
|
INSTALL_REQUIRES = [
|
||||||
"py>=1.5.0",
|
"py>=1.5.0",
|
||||||
"packaging",
|
"packaging",
|
||||||
"attrs>=17.4.0",
|
"attrs>=17.4.0", # should match oldattrs tox env.
|
||||||
"more-itertools>=4.0.0",
|
"more-itertools>=4.0.0",
|
||||||
"atomicwrites>=1.0",
|
"atomicwrites>=1.0",
|
||||||
'pathlib2>=2.2.0;python_version<"3.6"',
|
'pathlib2>=2.2.0;python_version<"3.6"',
|
||||||
|
|
|
@ -8,6 +8,7 @@ from typing import Optional
|
||||||
import _pytest._code
|
import _pytest._code
|
||||||
from _pytest import outcomes
|
from _pytest import outcomes
|
||||||
from _pytest._io.saferepr import saferepr
|
from _pytest._io.saferepr import saferepr
|
||||||
|
from _pytest.compat import ATTRS_EQ_FIELD
|
||||||
|
|
||||||
# The _reprcompare attribute on the util module is used by the new assertion
|
# The _reprcompare attribute on the util module is used by the new assertion
|
||||||
# interpretation code and assertion rewriter to detect this plugin was
|
# interpretation code and assertion rewriter to detect this plugin was
|
||||||
|
@ -375,7 +376,9 @@ def _compare_eq_cls(left, right, verbose, type_fns):
|
||||||
fields_to_check = [field for field, info in all_fields.items() if info.compare]
|
fields_to_check = [field for field, info in all_fields.items() if info.compare]
|
||||||
elif isattrs(left):
|
elif isattrs(left):
|
||||||
all_fields = left.__attrs_attrs__
|
all_fields = left.__attrs_attrs__
|
||||||
fields_to_check = [field.name for field in all_fields if field.cmp]
|
fields_to_check = [
|
||||||
|
field.name for field in all_fields if getattr(field, ATTRS_EQ_FIELD)
|
||||||
|
]
|
||||||
|
|
||||||
same = []
|
same = []
|
||||||
diff = []
|
diff = []
|
||||||
|
|
|
@ -354,3 +354,9 @@ if sys.version_info < (3, 5, 2): # pragma: no cover
|
||||||
|
|
||||||
def overload(f): # noqa: F811
|
def overload(f): # noqa: F811
|
||||||
return f
|
return f
|
||||||
|
|
||||||
|
|
||||||
|
if getattr(attr, "__version_info__", ()) >= (19, 2):
|
||||||
|
ATTRS_EQ_FIELD = "eq"
|
||||||
|
else:
|
||||||
|
ATTRS_EQ_FIELD = "cmp"
|
||||||
|
|
|
@ -8,6 +8,7 @@ from typing import Set
|
||||||
import attr
|
import attr
|
||||||
|
|
||||||
from ..compat import ascii_escaped
|
from ..compat import ascii_escaped
|
||||||
|
from ..compat import ATTRS_EQ_FIELD
|
||||||
from ..compat import getfslineno
|
from ..compat import getfslineno
|
||||||
from ..compat import NOTSET
|
from ..compat import NOTSET
|
||||||
from _pytest.outcomes import fail
|
from _pytest.outcomes import fail
|
||||||
|
@ -367,7 +368,8 @@ class NodeKeywords(MutableMapping):
|
||||||
return "<NodeKeywords for node {}>".format(self.node)
|
return "<NodeKeywords for node {}>".format(self.node)
|
||||||
|
|
||||||
|
|
||||||
@attr.s(cmp=False, hash=False)
|
# mypy cannot find this overload, remove when on attrs>=19.2
|
||||||
|
@attr.s(hash=False, **{ATTRS_EQ_FIELD: False}) # type: ignore
|
||||||
class NodeMarkers:
|
class NodeMarkers:
|
||||||
"""
|
"""
|
||||||
internal structure for storing marks belonging to a node
|
internal structure for storing marks belonging to a node
|
||||||
|
|
|
@ -351,15 +351,14 @@ class RunResult:
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
|
|
||||||
:ret: the return value
|
:ivar ret: the return value
|
||||||
:outlines: list of lines captured from stdout
|
:ivar outlines: list of lines captured from stdout
|
||||||
:errlines: list of lines captures from stderr
|
:ivar errlines: list of lines captured from stderr
|
||||||
:stdout: :py:class:`LineMatcher` of stdout, use ``stdout.str()`` to
|
:ivar stdout: :py:class:`LineMatcher` of stdout, use ``stdout.str()`` to
|
||||||
reconstruct stdout or the commonly used ``stdout.fnmatch_lines()``
|
reconstruct stdout or the commonly used ``stdout.fnmatch_lines()``
|
||||||
method
|
method
|
||||||
:stderr: :py:class:`LineMatcher` of stderr
|
:ivar stderr: :py:class:`LineMatcher` of stderr
|
||||||
:duration: duration in seconds
|
:ivar duration: duration in seconds
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, ret, outlines, errlines, duration):
|
def __init__(self, ret, outlines, errlines, duration):
|
||||||
|
@ -454,9 +453,9 @@ class Testdir:
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
|
|
||||||
:tmpdir: The :py:class:`py.path.local` instance of the temporary directory.
|
:ivar tmpdir: The :py:class:`py.path.local` instance of the temporary directory.
|
||||||
|
|
||||||
:plugins: A list of plugins to use with :py:meth:`parseconfig` and
|
:ivar plugins: A list of plugins to use with :py:meth:`parseconfig` and
|
||||||
:py:meth:`runpytest`. Initially this is an empty list but plugins can
|
:py:meth:`runpytest`. Initially this is an empty list but plugins can
|
||||||
be added to the list. The type of items to add to the list depends on
|
be added to the list. The type of items to add to the list depends on
|
||||||
the method using them so refer to them for details.
|
the method using them so refer to them for details.
|
||||||
|
|
|
@ -107,8 +107,8 @@ def show_test_item(item):
|
||||||
tw = item.config.get_terminal_writer()
|
tw = item.config.get_terminal_writer()
|
||||||
tw.line()
|
tw.line()
|
||||||
tw.write(" " * 8)
|
tw.write(" " * 8)
|
||||||
tw.write(item._nodeid)
|
tw.write(item.nodeid)
|
||||||
used_fixtures = sorted(item._fixtureinfo.name2fixturedefs.keys())
|
used_fixtures = sorted(getattr(item, "fixturenames", []))
|
||||||
if used_fixtures:
|
if used_fixtures:
|
||||||
tw.write(" (fixtures used: {})".format(", ".join(used_fixtures)))
|
tw.write(" (fixtures used: {})".format(", ".join(used_fixtures)))
|
||||||
|
|
||||||
|
|
|
@ -88,3 +88,30 @@ def tw_mock():
|
||||||
fullwidth = 80
|
fullwidth = 80
|
||||||
|
|
||||||
return TWMock()
|
return TWMock()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def dummy_yaml_custom_test(testdir):
|
||||||
|
"""Writes a conftest file that collects and executes a dummy yaml test.
|
||||||
|
|
||||||
|
Taken from the docs, but stripped down to the bare minimum, useful for
|
||||||
|
tests which needs custom items collected.
|
||||||
|
"""
|
||||||
|
testdir.makeconftest(
|
||||||
|
"""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
def pytest_collect_file(parent, path):
|
||||||
|
if path.ext == ".yaml" and path.basename.startswith("test"):
|
||||||
|
return YamlFile(path, parent)
|
||||||
|
|
||||||
|
class YamlFile(pytest.File):
|
||||||
|
def collect(self):
|
||||||
|
yield YamlItem(self.fspath.basename, self)
|
||||||
|
|
||||||
|
class YamlItem(pytest.Item):
|
||||||
|
def runtest(self):
|
||||||
|
pass
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
testdir.makefile(".yaml", test1="")
|
||||||
|
|
|
@ -6,8 +6,8 @@ def mode(request):
|
||||||
return request.param
|
return request.param
|
||||||
|
|
||||||
|
|
||||||
def test_show_only_active_fixtures(testdir, mode):
|
def test_show_only_active_fixtures(testdir, mode, dummy_yaml_custom_test):
|
||||||
p = testdir.makepyfile(
|
testdir.makepyfile(
|
||||||
'''
|
'''
|
||||||
import pytest
|
import pytest
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
@ -21,7 +21,7 @@ def test_show_only_active_fixtures(testdir, mode):
|
||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
|
|
||||||
result = testdir.runpytest(mode, p)
|
result = testdir.runpytest(mode)
|
||||||
assert result.ret == 0
|
assert result.ret == 0
|
||||||
|
|
||||||
result.stdout.fnmatch_lines(
|
result.stdout.fnmatch_lines(
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
def test_show_fixtures_and_test(testdir):
|
def test_show_fixtures_and_test(testdir, dummy_yaml_custom_test):
|
||||||
""" Verifies that fixtures are not executed. """
|
""" Verifies that fixtures are not executed. """
|
||||||
p = testdir.makepyfile(
|
testdir.makepyfile(
|
||||||
"""
|
"""
|
||||||
import pytest
|
import pytest
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
@ -11,7 +11,7 @@ def test_show_fixtures_and_test(testdir):
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
result = testdir.runpytest("--setup-plan", p)
|
result = testdir.runpytest("--setup-plan")
|
||||||
assert result.ret == 0
|
assert result.ret == 0
|
||||||
|
|
||||||
result.stdout.fnmatch_lines(
|
result.stdout.fnmatch_lines(
|
||||||
|
|
|
@ -9,6 +9,7 @@ import pytest
|
||||||
from _pytest import outcomes
|
from _pytest import outcomes
|
||||||
from _pytest.assertion import truncate
|
from _pytest.assertion import truncate
|
||||||
from _pytest.assertion import util
|
from _pytest.assertion import util
|
||||||
|
from _pytest.compat import ATTRS_EQ_FIELD
|
||||||
|
|
||||||
|
|
||||||
def mock_config():
|
def mock_config():
|
||||||
|
@ -687,7 +688,7 @@ class TestAssert_reprcompare_attrsclass:
|
||||||
@attr.s
|
@attr.s
|
||||||
class SimpleDataObject:
|
class SimpleDataObject:
|
||||||
field_a = attr.ib()
|
field_a = attr.ib()
|
||||||
field_b = attr.ib(cmp=False)
|
field_b = attr.ib(**{ATTRS_EQ_FIELD: False})
|
||||||
|
|
||||||
left = SimpleDataObject(1, "b")
|
left = SimpleDataObject(1, "b")
|
||||||
right = SimpleDataObject(1, "b")
|
right = SimpleDataObject(1, "b")
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import argparse
|
import argparse
|
||||||
import distutils.spawn
|
import distutils.spawn
|
||||||
import os
|
import os
|
||||||
|
import shlex
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import py
|
import py
|
||||||
|
@ -298,7 +299,11 @@ def test_argcomplete(testdir, monkeypatch):
|
||||||
# redirect output from argcomplete to stdin and stderr is not trivial
|
# redirect output from argcomplete to stdin and stderr is not trivial
|
||||||
# http://stackoverflow.com/q/12589419/1307905
|
# http://stackoverflow.com/q/12589419/1307905
|
||||||
# so we use bash
|
# so we use bash
|
||||||
fp.write('COMP_WORDBREAKS="$COMP_WORDBREAKS" python -m pytest 8>&1 9>&2')
|
fp.write(
|
||||||
|
'COMP_WORDBREAKS="$COMP_WORDBREAKS" {} -m pytest 8>&1 9>&2'.format(
|
||||||
|
shlex.quote(sys.executable)
|
||||||
|
)
|
||||||
|
)
|
||||||
# alternative would be exteneded Testdir.{run(),_run(),popen()} to be able
|
# alternative would be exteneded Testdir.{run(),_run(),popen()} to be able
|
||||||
# to handle a keyword argument env that replaces os.environ in popen or
|
# to handle a keyword argument env that replaces os.environ in popen or
|
||||||
# extends the copy, advantage: could not forget to restore
|
# extends the copy, advantage: could not forget to restore
|
||||||
|
|
8
tox.ini
8
tox.ini
|
@ -41,6 +41,8 @@ setenv =
|
||||||
xdist: _PYTEST_TOX_POSARGS_XDIST=-n auto
|
xdist: _PYTEST_TOX_POSARGS_XDIST=-n auto
|
||||||
extras = testing
|
extras = testing
|
||||||
deps =
|
deps =
|
||||||
|
oldattrs: attrs==17.4.0
|
||||||
|
oldattrs: hypothesis<=4.38.1
|
||||||
numpy: numpy
|
numpy: numpy
|
||||||
pexpect: pexpect
|
pexpect: pexpect
|
||||||
pluggymaster: git+https://github.com/pytest-dev/pluggy.git@master
|
pluggymaster: git+https://github.com/pytest-dev/pluggy.git@master
|
||||||
|
@ -77,7 +79,7 @@ commands =
|
||||||
[testenv:regen]
|
[testenv:regen]
|
||||||
changedir = doc/en
|
changedir = doc/en
|
||||||
skipsdist = True
|
skipsdist = True
|
||||||
basepython = python3.6
|
basepython = python3
|
||||||
deps =
|
deps =
|
||||||
sphinx
|
sphinx
|
||||||
PyYAML
|
PyYAML
|
||||||
|
@ -103,7 +105,7 @@ commands =
|
||||||
|
|
||||||
[testenv:release]
|
[testenv:release]
|
||||||
decription = do a release, required posarg of the version number
|
decription = do a release, required posarg of the version number
|
||||||
basepython = python3.6
|
basepython = python3
|
||||||
usedevelop = True
|
usedevelop = True
|
||||||
passenv = *
|
passenv = *
|
||||||
deps =
|
deps =
|
||||||
|
@ -116,7 +118,7 @@ commands = python scripts/release.py {posargs}
|
||||||
|
|
||||||
[testenv:publish_gh_release_notes]
|
[testenv:publish_gh_release_notes]
|
||||||
description = create GitHub release after deployment
|
description = create GitHub release after deployment
|
||||||
basepython = python3.6
|
basepython = python3
|
||||||
usedevelop = True
|
usedevelop = True
|
||||||
passenv = GH_RELEASE_NOTES_TOKEN TRAVIS_TAG TRAVIS_REPO_SLUG
|
passenv = GH_RELEASE_NOTES_TOKEN TRAVIS_TAG TRAVIS_REPO_SLUG
|
||||||
deps =
|
deps =
|
||||||
|
|
Loading…
Reference in New Issue