commit
69ad2026f6
|
@ -67,7 +67,7 @@ Features
|
||||||
rather than implicitly.
|
rather than implicitly.
|
||||||
|
|
||||||
|
|
||||||
- `#5914 <https://github.com/pytest-dev/pytest/issues/5914>`_: ``pytester`` learned two new functions, `no_fnmatch_line <https://docs.pytest.org/en/latest/reference.html#_pytest.pytester.LineMatcher.no_fnmatch_line>`_ and
|
- `#5914 <https://github.com/pytest-dev/pytest/issues/5914>`_: `testdir <https://docs.pytest.org/en/latest/reference.html#testdir>`__ learned two new functions, `no_fnmatch_line <https://docs.pytest.org/en/latest/reference.html#_pytest.pytester.LineMatcher.no_fnmatch_line>`_ and
|
||||||
`no_re_match_line <https://docs.pytest.org/en/latest/reference.html#_pytest.pytester.LineMatcher.no_re_match_line>`_.
|
`no_re_match_line <https://docs.pytest.org/en/latest/reference.html#_pytest.pytester.LineMatcher.no_re_match_line>`_.
|
||||||
|
|
||||||
The functions are used to ensure the captured text *does not* match the given
|
The functions are used to ensure the captured text *does not* match the given
|
||||||
|
@ -77,12 +77,14 @@ Features
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
result = testdir.runpytest()
|
||||||
assert re.match(pat, result.stdout.str()) is None
|
assert re.match(pat, result.stdout.str()) is None
|
||||||
|
|
||||||
Or the ``in`` operator:
|
Or the ``in`` operator:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
result = testdir.runpytest()
|
||||||
assert text in result.stdout.str()
|
assert text in result.stdout.str()
|
||||||
|
|
||||||
But the new functions produce best output on failure.
|
But the new functions produce best output on failure.
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fix line detection for doctest samples inside ``property`` docstrings, as a workaround to `bpo-17446 <https://bugs.python.org/issue17446>`__.
|
|
@ -0,0 +1 @@
|
||||||
|
Fix compatibility with pytest-parallel (regression in pytest 5.3.0).
|
|
@ -1215,6 +1215,15 @@ passed multiple times. The expected format is ``name=value``. For example::
|
||||||
a specific entry in the log. ``extra`` kwarg overrides the value specified
|
a specific entry in the log. ``extra`` kwarg overrides the value specified
|
||||||
on the command line or in the config.
|
on the command line or in the config.
|
||||||
|
|
||||||
|
.. confval:: log_cli
|
||||||
|
|
||||||
|
Enable log display during test run (also known as :ref:`"live logging" <live_logs>`).
|
||||||
|
The default is ``False``.
|
||||||
|
|
||||||
|
.. code-block:: ini
|
||||||
|
|
||||||
|
[pytest]
|
||||||
|
log_cli = True
|
||||||
|
|
||||||
.. confval:: log_cli_date_format
|
.. confval:: log_cli_date_format
|
||||||
|
|
||||||
|
|
|
@ -784,7 +784,7 @@ class Config:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def fromdictargs(cls, option_dict, args):
|
def fromdictargs(cls, option_dict, args):
|
||||||
""" constructor useable for subprocesses. """
|
""" constructor usable for subprocesses. """
|
||||||
config = get_config(args)
|
config = get_config(args)
|
||||||
config.option.__dict__.update(option_dict)
|
config.option.__dict__.update(option_dict)
|
||||||
config.parse(args, addopts=False)
|
config.parse(args, addopts=False)
|
||||||
|
|
|
@ -435,6 +435,16 @@ class DoctestModule(pytest.Module):
|
||||||
https://bugs.python.org/issue25532
|
https://bugs.python.org/issue25532
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def _find_lineno(self, obj, source_lines):
|
||||||
|
"""
|
||||||
|
Doctest code does not take into account `@property`, this is a hackish way to fix it.
|
||||||
|
|
||||||
|
https://bugs.python.org/issue17446
|
||||||
|
"""
|
||||||
|
if isinstance(obj, property):
|
||||||
|
obj = getattr(obj, "fget", obj)
|
||||||
|
return doctest.DocTestFinder._find_lineno(self, obj, source_lines)
|
||||||
|
|
||||||
def _find(self, tests, obj, name, module, source_lines, globs, seen):
|
def _find(self, tests, obj, name, module, source_lines, globs, seen):
|
||||||
if _is_mocked(obj):
|
if _is_mocked(obj):
|
||||||
return
|
return
|
||||||
|
|
|
@ -1099,7 +1099,7 @@ def _get_main_color(stats) -> Tuple[str, List[str]]:
|
||||||
"failed passed skipped deselected xfailed xpassed warnings error".split()
|
"failed passed skipped deselected xfailed xpassed warnings error".split()
|
||||||
)
|
)
|
||||||
unknown_type_seen = False
|
unknown_type_seen = False
|
||||||
for found_type in stats:
|
for found_type in stats.keys():
|
||||||
if found_type not in known_types:
|
if found_type not in known_types:
|
||||||
if found_type: # setup/teardown reports have an empty key, ignore them
|
if found_type: # setup/teardown reports have an empty key, ignore them
|
||||||
known_types.append(found_type)
|
known_types.append(found_type)
|
||||||
|
|
|
@ -287,13 +287,68 @@ class TestDoctests:
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
result = testdir.runpytest("--doctest-modules")
|
result = testdir.runpytest("--doctest-modules")
|
||||||
|
result.stdout.fnmatch_lines(
|
||||||
|
["*hello*", "006*>>> 1/0*", "*UNEXPECTED*ZeroDivision*", "*1 failed*"]
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_doctest_linedata_on_property(self, testdir):
|
||||||
|
testdir.makepyfile(
|
||||||
|
"""
|
||||||
|
class Sample(object):
|
||||||
|
@property
|
||||||
|
def some_property(self):
|
||||||
|
'''
|
||||||
|
>>> Sample().some_property
|
||||||
|
'another thing'
|
||||||
|
'''
|
||||||
|
return 'something'
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
result = testdir.runpytest("--doctest-modules")
|
||||||
result.stdout.fnmatch_lines(
|
result.stdout.fnmatch_lines(
|
||||||
[
|
[
|
||||||
"*hello*",
|
"*= FAILURES =*",
|
||||||
"*EXAMPLE LOCATION UNKNOWN, not showing all tests of that example*",
|
"*_ [[]doctest[]] test_doctest_linedata_on_property.Sample.some_property _*",
|
||||||
"*1/0*",
|
"004 ",
|
||||||
"*UNEXPECTED*ZeroDivision*",
|
"005 >>> Sample().some_property",
|
||||||
"*1 failed*",
|
"Expected:",
|
||||||
|
" 'another thing'",
|
||||||
|
"Got:",
|
||||||
|
" 'something'",
|
||||||
|
"",
|
||||||
|
"*/test_doctest_linedata_on_property.py:5: DocTestFailure",
|
||||||
|
"*= 1 failed in *",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_doctest_no_linedata_on_overriden_property(self, testdir):
|
||||||
|
testdir.makepyfile(
|
||||||
|
"""
|
||||||
|
class Sample(object):
|
||||||
|
@property
|
||||||
|
def some_property(self):
|
||||||
|
'''
|
||||||
|
>>> Sample().some_property
|
||||||
|
'another thing'
|
||||||
|
'''
|
||||||
|
return 'something'
|
||||||
|
some_property = property(some_property.__get__, None, None, some_property.__doc__)
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
result = testdir.runpytest("--doctest-modules")
|
||||||
|
result.stdout.fnmatch_lines(
|
||||||
|
[
|
||||||
|
"*= FAILURES =*",
|
||||||
|
"*_ [[]doctest[]] test_doctest_no_linedata_on_overriden_property.Sample.some_property _*",
|
||||||
|
"EXAMPLE LOCATION UNKNOWN, not showing all tests of that example",
|
||||||
|
"[?][?][?] >>> Sample().some_property",
|
||||||
|
"Expected:",
|
||||||
|
" 'another thing'",
|
||||||
|
"Got:",
|
||||||
|
" 'something'",
|
||||||
|
"",
|
||||||
|
"*/test_doctest_no_linedata_on_overriden_property.py:None: DocTestFailure",
|
||||||
|
"*= 1 failed in *",
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
3
tox.ini
3
tox.ini
|
@ -60,9 +60,8 @@ basepython = python3
|
||||||
usedevelop = True
|
usedevelop = True
|
||||||
changedir = doc/en
|
changedir = doc/en
|
||||||
deps = -r{toxinidir}/doc/en/requirements.txt
|
deps = -r{toxinidir}/doc/en/requirements.txt
|
||||||
|
|
||||||
commands =
|
commands =
|
||||||
sphinx-build -W -b html . _build
|
sphinx-build -W --keep-going -b html . _build {posargs:}
|
||||||
|
|
||||||
[testenv:docs-checklinks]
|
[testenv:docs-checklinks]
|
||||||
basepython = python3
|
basepython = python3
|
||||||
|
|
Loading…
Reference in New Issue