Hello community,
here is the log from the commit of package python-pytest for openSUSE:Factory checked in at 2018-11-26 10:16:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pytest (Old)
and /work/SRC/openSUSE:Factory/.python-pytest.new.19453 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pytest"
Mon Nov 26 10:16:07 2018 rev:43 rq:648996 version:3.10.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pytest/python-pytest.changes 2018-11-12 09:49:16.316478444 +0100
+++ /work/SRC/openSUSE:Factory/.python-pytest.new.19453/python-pytest.changes 2018-11-26 10:16:11.822021401 +0100
@@ -1,0 +2,14 @@
+Wed Nov 14 14:00:29 UTC 2018 - Ondřej Súkup
+
+- update to 3.10.1
+ * Fix nested usage of debugging plugin (pdb)
+ * Block the stepwise plugin if cacheprovider is also blocked, as one
+ depends on the other.
+ * Parse minversion as an actual version and not as dot-separated strings.
+ * Fix duplicate collection due to multiple args matching the same packages.
+ * Fix item.nodeid with resolved symlinks.
+ * Fix collection of direct symlinked files, where the target does not match
+ python_files.
+ * Fix TypeError in report_collect with _collect_report_last_write.
+
+-------------------------------------------------------------------
Old:
----
pytest-3.10.0.tar.gz
New:
----
pytest-3.10.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pytest-doc.spec ++++++
--- /var/tmp/diff_new_pack.ivBWrb/_old 2018-11-26 10:16:12.754020310 +0100
+++ /var/tmp/diff_new_pack.ivBWrb/_new 2018-11-26 10:16:12.758020305 +0100
@@ -18,7 +18,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-pytest-doc
-Version: 3.10.0
+Version: 3.10.1
Release: 0
Summary: Documentation for python-pytest, a testing tool with autodiscovery
License: MIT
python-pytest.spec: same change
++++++ pytest-3.10.0.tar.gz -> pytest-3.10.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/.travis.yml new/pytest-3.10.1/.travis.yml
--- old/pytest-3.10.0/.travis.yml 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/.travis.yml 2018-11-11 18:33:50.000000000 +0100
@@ -47,11 +47,6 @@
env: TOXENV=py37
before_install:
- brew update
- # remove c++ include files because upgrading python as of 2018-10-23, also
- # attempts to upgrade gcc, and it fails because the include files already
- # exist. removing the include files is one of the solutions recommended by brew
- # this workaround might not be necessary in the future
- - rm '/usr/local/include/c++'
- brew upgrade python
- brew unlink python
- brew link python
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/AUTHORS new/pytest-3.10.1/AUTHORS
--- old/pytest-3.10.0/AUTHORS 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/AUTHORS 2018-11-11 18:33:50.000000000 +0100
@@ -76,6 +76,7 @@
Eric Hunsberger
Eric Siegerman
Erik M. Bray
+Fabien Zarifian
Fabio Zadrozny
Feng Ma
Florian Bruhin
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/CHANGELOG.rst new/pytest-3.10.1/CHANGELOG.rst
--- old/pytest-3.10.0/CHANGELOG.rst 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/CHANGELOG.rst 2018-11-11 18:33:50.000000000 +0100
@@ -18,6 +18,40 @@
.. towncrier release notes start
+pytest 3.10.1 (2018-11-11)
+==========================
+
+Bug Fixes
+---------
+
+- `#4287 https://github.com/pytest-dev/pytest/issues/4287`_: Fix nested usage of debugging plugin (pdb), e.g. with pytester's ``testdir.runpytest``.
+
+
+- `#4304 https://github.com/pytest-dev/pytest/issues/4304`_: Block the ``stepwise`` plugin if ``cacheprovider`` is also blocked, as one depends on the other.
+
+
+- `#4306 https://github.com/pytest-dev/pytest/issues/4306`_: Parse ``minversion`` as an actual version and not as dot-separated strings.
+
+
+- `#4310 https://github.com/pytest-dev/pytest/issues/4310`_: Fix duplicate collection due to multiple args matching the same packages.
+
+
+- `#4321 https://github.com/pytest-dev/pytest/issues/4321`_: Fix ``item.nodeid`` with resolved symlinks.
+
+
+- `#4325 https://github.com/pytest-dev/pytest/issues/4325`_: Fix collection of direct symlinked files, where the target does not match ``python_files``.
+
+
+- `#4329 https://github.com/pytest-dev/pytest/issues/4329`_: Fix TypeError in report_collect with _collect_report_last_write.
+
+
+
+Trivial/Internal Changes
+------------------------
+
+- `#4305 https://github.com/pytest-dev/pytest/issues/4305`_: Replace byte/unicode helpers in test_capture with python level syntax.
+
+
pytest 3.10.0 (2018-11-03)
==========================
@@ -30,7 +64,7 @@
existing ``pytest_enter_pdb`` hook.
-- `#4147 https://github.com/pytest-dev/pytest/issues/4147`_: Add ``-sw``, ``--stepwise`` as an alternative to ``--lf -x`` for stopping at the first failure, but starting the next test invocation from that test. See `the documentation https://docs.pytest.org/en/latest/cache.html#stepwise`__ for more info.
+- `#4147 https://github.com/pytest-dev/pytest/issues/4147`_: Add ``--sw``, ``--stepwise`` as an alternative to ``--lf -x`` for stopping at the first failure, but starting the next test invocation from that test. See `the documentation https://docs.pytest.org/en/latest/cache.html#stepwise`__ for more info.
- `#4188 https://github.com/pytest-dev/pytest/issues/4188`_: Make ``--color`` emit colorful dots when not running in verbose mode. Earlier, it would only colorize the test-by-test output if ``--verbose`` was also passed.
@@ -60,6 +94,8 @@
- `#611 https://github.com/pytest-dev/pytest/issues/611`_: Naming a fixture ``request`` will now raise a warning: the ``request`` fixture is internal and
should not be overwritten as it will lead to internal errors.
+- `#4266 https://github.com/pytest-dev/pytest/issues/4266`_: Handle (ignore) exceptions raised during collection, e.g. with Django's LazySettings proxy class.
+
Improved Documentation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/HOWTORELEASE.rst new/pytest-3.10.1/HOWTORELEASE.rst
--- old/pytest-3.10.0/HOWTORELEASE.rst 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/HOWTORELEASE.rst 2018-11-11 18:33:50.000000000 +0100
@@ -46,5 +46,3 @@
* testing-in-python@lists.idyll.org (only major/minor releases)
And announce it on `Twitter https://twitter.com/`_ with the ``#pytest`` hashtag.
-
-#. After a minor/major release, merge ``release-X.Y.Z`` into ``master`` and push (or open a PR).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/PKG-INFO new/pytest-3.10.1/PKG-INFO
--- old/pytest-3.10.0/PKG-INFO 2018-11-04 16:23:38.000000000 +0100
+++ new/pytest-3.10.1/PKG-INFO 2018-11-11 18:34:15.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 1.2
Name: pytest
-Version: 3.10.0
+Version: 3.10.1
Summary: pytest: simple powerful testing with Python
Home-page: https://docs.pytest.org/en/latest/
Author: Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris Bruynooghe, Brianna Laugher, Florian Bruhin and others
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/doc/4266.bugfix.rst new/pytest-3.10.1/doc/4266.bugfix.rst
--- old/pytest-3.10.0/doc/4266.bugfix.rst 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/doc/4266.bugfix.rst 1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-Handle (ignore) exceptions raised during collection, e.g. with Django's LazySettings proxy class.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/doc/en/announce/index.rst new/pytest-3.10.1/doc/en/announce/index.rst
--- old/pytest-3.10.0/doc/en/announce/index.rst 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/doc/en/announce/index.rst 2018-11-11 18:33:50.000000000 +0100
@@ -6,6 +6,7 @@
:maxdepth: 2
+ release-3.10.1
release-3.10.0
release-3.9.3
release-3.9.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/doc/en/announce/release-3.10.1.rst new/pytest-3.10.1/doc/en/announce/release-3.10.1.rst
--- old/pytest-3.10.0/doc/en/announce/release-3.10.1.rst 1970-01-01 01:00:00.000000000 +0100
+++ new/pytest-3.10.1/doc/en/announce/release-3.10.1.rst 2018-11-11 18:33:50.000000000 +0100
@@ -0,0 +1,24 @@
+pytest-3.10.1
+=======================================
+
+pytest 3.10.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
+* Boris Feld
+* Bruno Oliveira
+* Daniel Hahler
+* Fabien ZARIFIAN
+* Jon Dufresne
+* Ronny Pfannschmidt
+
+
+Happy testing,
+The pytest Development Team
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/doc/en/example/nonpython.rst new/pytest-3.10.1/doc/en/example/nonpython.rst
--- old/pytest-3.10.0/doc/en/example/nonpython.rst 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/doc/en/example/nonpython.rst 2018-11-11 18:33:50.000000000 +0100
@@ -85,9 +85,8 @@
rootdir: $REGENDOC_TMPDIR/nonpython, inifile:
collected 2 items
-
-
-
-
+
+
+
======================= no tests ran in 0.12 seconds =======================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/doc/en/plugins.rst new/pytest-3.10.1/doc/en/plugins.rst
--- old/pytest-3.10.0/doc/en/plugins.rst 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/doc/en/plugins.rst 2018-11-11 18:33:50.000000000 +0100
@@ -59,9 +59,9 @@
status against different pytest and Python versions, please visit
`plugincompat http://plugincompat.herokuapp.com/`_.
-You may also discover more plugins through a `pytest- pypi.python.org search`_.
+You may also discover more plugins through a `pytest- pypi.org search`_.
-.. _`pytest- pypi.python.org search`: https://pypi.org/search/?q=pytest-
+.. _`pytest- pypi.org search`: https://pypi.org/search/?q=pytest-
.. _`available installable plugins`:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/doc/en/usage.rst new/pytest-3.10.1/doc/en/usage.rst
--- old/pytest-3.10.0/doc/en/usage.rst 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/doc/en/usage.rst 2018-11-11 18:33:50.000000000 +0100
@@ -255,8 +255,8 @@
- When ``breakpoint()`` is called and ``PYTHONBREAKPOINT`` is set to the default value, pytest will use the custom internal PDB trace UI instead of the system default ``Pdb``.
- When tests are complete, the system will default back to the system ``Pdb`` trace UI.
- - If ``--pdb`` is called on execution of pytest, the custom internal Pdb trace UI is used on both ``breakpoint()`` and failed tests/unhandled exceptions.
- - If ``--pdbcls`` is used, the custom class debugger will be executed when a test fails (as expected within existing behaviour), but also when ``breakpoint()`` is called from within a test, the custom class debugger will be instantiated.
+ - With ``--pdb`` passed to pytest, the custom internal Pdb trace UI is used with both ``breakpoint()`` and failed tests/unhandled exceptions.
+ - ``--pdbcls`` can be used to specify a custom debugger class.
.. _durations:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/src/_pytest/_version.py new/pytest-3.10.1/src/_pytest/_version.py
--- old/pytest-3.10.0/src/_pytest/_version.py 2018-11-04 16:23:37.000000000 +0100
+++ new/pytest-3.10.1/src/_pytest/_version.py 2018-11-11 18:34:14.000000000 +0100
@@ -1,4 +1,4 @@
# coding: utf-8
# file generated by setuptools_scm
# don't change, don't track in version control
-version = '3.10.0'
+version = '3.10.1'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/src/_pytest/assertion/util.py new/pytest-3.10.1/src/_pytest/assertion/util.py
--- old/pytest-3.10.0/src/_pytest/assertion/util.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/src/_pytest/assertion/util.py 2018-11-11 18:33:50.000000000 +0100
@@ -11,8 +11,6 @@
import _pytest._code
from ..compat import Sequence
-u = six.text_type
-
# The _reprcompare attribute on the util module is used by the new assertion
# interpretation code and assertion rewriter to detect this plugin was
# loaded and in turn call the hooks defined here as part of the
@@ -23,9 +21,9 @@
# the re-encoding is needed for python2 repr
# with non-ascii characters (see issue 877 and 1379)
def ecu(s):
- try:
- return u(s, "utf-8", "replace")
- except TypeError:
+ if isinstance(s, bytes):
+ return s.decode("UTF-8", "replace")
+ else:
return s
@@ -42,7 +40,7 @@
explanation = ecu(explanation)
lines = _split_explanation(explanation)
result = _format_lines(lines)
- return u("\n").join(result)
+ return u"\n".join(result)
def _split_explanation(explanation):
@@ -52,7 +50,7 @@
Any other newlines will be escaped and appear in the line as the
literal '\n' characters.
"""
- raw_lines = (explanation or u("")).split("\n")
+ raw_lines = (explanation or u"").split("\n")
lines = [raw_lines[0]]
for values in raw_lines[1:]:
if values and values[0] in ["{", "}", "~", ">"]:
@@ -77,13 +75,13 @@
for line in lines[1:]:
if line.startswith("{"):
if stackcnt[-1]:
- s = u("and ")
+ s = u"and "
else:
- s = u("where ")
+ s = u"where "
stack.append(len(result))
stackcnt[-1] += 1
stackcnt.append(0)
- result.append(u(" +") + u(" ") * (len(stack) - 1) + s + line[1:])
+ result.append(u" +" + u" " * (len(stack) - 1) + s + line[1:])
elif line.startswith("}"):
stack.pop()
stackcnt.pop()
@@ -92,7 +90,7 @@
assert line[0] in ["~", ">"]
stack[-1] += 1
indent = len(stack) if line.startswith("~") else len(stack) - 1
- result.append(u(" ") * indent + line[1:])
+ result.append(u" " * indent + line[1:])
assert len(stack) == 1
return result
@@ -110,7 +108,7 @@
left_repr = py.io.saferepr(left, maxsize=int(width // 2))
right_repr = py.io.saferepr(right, maxsize=width - len(left_repr))
- summary = u("%s %s %s") % (ecu(left_repr), op, ecu(right_repr))
+ summary = u"%s %s %s" % (ecu(left_repr), op, ecu(right_repr))
def issequence(x):
return isinstance(x, Sequence) and not isinstance(x, basestring)
@@ -155,11 +153,9 @@
explanation = _notin_text(left, right, verbose)
except Exception:
explanation = [
- u(
- "(pytest_assertion plugin: representation of details failed. "
- "Probably an object has a faulty __repr__.)"
- ),
- u(_pytest._code.ExceptionInfo()),
+ u"(pytest_assertion plugin: representation of details failed. "
+ u"Probably an object has a faulty __repr__.)",
+ six.text_type(_pytest._code.ExceptionInfo()),
]
if not explanation:
@@ -203,8 +199,7 @@
if i > 42:
i -= 10 # Provide some context
explanation = [
- u("Skipping %s identical leading characters in diff, use -v to show")
- % i
+ u"Skipping %s identical leading characters in diff, use -v to show" % i
]
left = left[i:]
right = right[i:]
@@ -215,11 +210,8 @@
if i > 42:
i -= 10 # Provide some context
explanation += [
- u(
- "Skipping %s identical trailing "
- "characters in diff, use -v to show"
- )
- % i
+ u"Skipping {} identical trailing "
+ u"characters in diff, use -v to show".format(i)
]
left = left[:-i]
right = right[:-i]
@@ -237,21 +229,21 @@
def _compare_eq_iterable(left, right, verbose=False):
if not verbose:
- return [u("Use -v to get the full diff")]
+ return [u"Use -v to get the full diff"]
# dynamic import to speedup pytest
import difflib
try:
left_formatting = pprint.pformat(left).splitlines()
right_formatting = pprint.pformat(right).splitlines()
- explanation = [u("Full diff:")]
+ explanation = [u"Full diff:"]
except Exception:
# hack: PrettyPrinter.pformat() in python 2 fails when formatting items that can't be sorted(), ie, calling
# sorted() on a list would raise. See issue #718.
# As a workaround, the full diff is generated by using the repr() string of each item of each container.
left_formatting = sorted(repr(x) for x in left)
right_formatting = sorted(repr(x) for x in right)
- explanation = [u("Full diff (fallback to calling repr on each item):")]
+ explanation = [u"Full diff (fallback to calling repr on each item):"]
explanation.extend(
line.strip() for line in difflib.ndiff(left_formatting, right_formatting)
)
@@ -262,16 +254,16 @@
explanation = []
for i in range(min(len(left), len(right))):
if left[i] != right[i]:
- explanation += [u("At index %s diff: %r != %r") % (i, left[i], right[i])]
+ explanation += [u"At index %s diff: %r != %r" % (i, left[i], right[i])]
break
if len(left) > len(right):
explanation += [
- u("Left contains more items, first extra item: %s")
+ u"Left contains more items, first extra item: %s"
% py.io.saferepr(left[len(right)])
]
elif len(left) < len(right):
explanation += [
- u("Right contains more items, first extra item: %s")
+ u"Right contains more items, first extra item: %s"
% py.io.saferepr(right[len(left)])
]
return explanation
@@ -282,11 +274,11 @@
diff_left = left - right
diff_right = right - left
if diff_left:
- explanation.append(u("Extra items in the left set:"))
+ explanation.append(u"Extra items in the left set:")
for item in diff_left:
explanation.append(py.io.saferepr(item))
if diff_right:
- explanation.append(u("Extra items in the right set:"))
+ explanation.append(u"Extra items in the right set:")
for item in diff_right:
explanation.append(py.io.saferepr(item))
return explanation
@@ -297,26 +289,26 @@
common = set(left).intersection(set(right))
same = {k: left[k] for k in common if left[k] == right[k]}
if same and verbose < 2:
- explanation += [u("Omitting %s identical items, use -vv to show") % len(same)]
+ explanation += [u"Omitting %s identical items, use -vv to show" % len(same)]
elif same:
- explanation += [u("Common items:")]
+ explanation += [u"Common items:"]
explanation += pprint.pformat(same).splitlines()
diff = {k for k in common if left[k] != right[k]}
if diff:
- explanation += [u("Differing items:")]
+ explanation += [u"Differing items:"]
for k in diff:
explanation += [
py.io.saferepr({k: left[k]}) + " != " + py.io.saferepr({k: right[k]})
]
extra_left = set(left) - set(right)
if extra_left:
- explanation.append(u("Left contains more items:"))
+ explanation.append(u"Left contains more items:")
explanation.extend(
pprint.pformat({k: left[k] for k in extra_left}).splitlines()
)
extra_right = set(right) - set(left)
if extra_right:
- explanation.append(u("Right contains more items:"))
+ explanation.append(u"Right contains more items:")
explanation.extend(
pprint.pformat({k: right[k] for k in extra_right}).splitlines()
)
@@ -329,14 +321,14 @@
tail = text[index + len(term) :]
correct_text = head + tail
diff = _diff_text(correct_text, text, verbose)
- newdiff = [u("%s is contained here:") % py.io.saferepr(term, maxsize=42)]
+ newdiff = [u"%s is contained here:" % py.io.saferepr(term, maxsize=42)]
for line in diff:
- if line.startswith(u("Skipping")):
+ if line.startswith(u"Skipping"):
continue
- if line.startswith(u("- ")):
+ if line.startswith(u"- "):
continue
- if line.startswith(u("+ ")):
- newdiff.append(u(" ") + line[2:])
+ if line.startswith(u"+ "):
+ newdiff.append(u" " + line[2:])
else:
newdiff.append(line)
return newdiff
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/src/_pytest/capture.py new/pytest-3.10.1/src/_pytest/capture.py
--- old/pytest-3.10.0/src/_pytest/capture.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/src/_pytest/capture.py 2018-11-11 18:33:50.000000000 +0100
@@ -504,7 +504,7 @@
snap() produces `bytes`
"""
- EMPTY_BUFFER = bytes()
+ EMPTY_BUFFER = b""
def __init__(self, targetfd, tmpfile=None):
self.targetfd = targetfd
@@ -630,7 +630,7 @@
class SysCaptureBinary(SysCapture):
- EMPTY_BUFFER = bytes()
+ EMPTY_BUFFER = b""
def snap(self):
res = self.tmpfile.buffer.getvalue()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/src/_pytest/config/__init__.py new/pytest-3.10.1/src/_pytest/config/__init__.py
--- old/pytest-3.10.0/src/_pytest/config/__init__.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/src/_pytest/config/__init__.py 2018-11-11 18:33:50.000000000 +0100
@@ -11,6 +11,7 @@
import sys
import types
import warnings
+from distutils.version import LooseVersion
import py
import six
@@ -476,6 +477,11 @@
def consider_pluginarg(self, arg):
if arg.startswith("no:"):
name = arg[3:]
+ # PR #4304 : remove stepwise if cacheprovider is blocked
+ if name == "cacheprovider":
+ self.set_blocked("stepwise")
+ self.set_blocked("pytest_stepwise")
+
self.set_blocked(name)
if not name.startswith("pytest_"):
self.set_blocked("pytest_" + name)
@@ -816,9 +822,7 @@
minver = self.inicfg.get("minversion", None)
if minver:
- ver = minver.split(".")
- myver = pytest.__version__.split(".")
- if myver < ver:
+ if LooseVersion(minver) > LooseVersion(pytest.__version__):
raise pytest.UsageError(
"%s:%d: requires pytest-%s, actual pytest-%s'"
% (
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/src/_pytest/debugging.py new/pytest-3.10.1/src/_pytest/debugging.py
--- old/pytest-3.10.0/src/_pytest/debugging.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/src/_pytest/debugging.py 2018-11-11 18:33:50.000000000 +0100
@@ -47,17 +47,24 @@
if config.getvalue("usepdb"):
config.pluginmanager.register(PdbInvoke(), "pdbinvoke")
- old = (pdb.set_trace, pytestPDB._pluginmanager)
-
- def fin():
- pdb.set_trace, pytestPDB._pluginmanager = old
- pytestPDB._config = None
- pytestPDB._pdb_cls = pdb.Pdb
-
+ pytestPDB._saved.append(
+ (pdb.set_trace, pytestPDB._pluginmanager, pytestPDB._config, pytestPDB._pdb_cls)
+ )
pdb.set_trace = pytestPDB.set_trace
pytestPDB._pluginmanager = config.pluginmanager
pytestPDB._config = config
pytestPDB._pdb_cls = pdb_cls
+
+ # NOTE: not using pytest_unconfigure, since it might get called although
+ # pytest_configure was not (if another plugin raises UsageError).
+ def fin():
+ (
+ pdb.set_trace,
+ pytestPDB._pluginmanager,
+ pytestPDB._config,
+ pytestPDB._pdb_cls,
+ ) = pytestPDB._saved.pop()
+
config._cleanup.append(fin)
@@ -67,6 +74,7 @@
_pluginmanager = None
_config = None
_pdb_cls = pdb.Pdb
+ _saved = []
@classmethod
def set_trace(cls, set_break=True):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/src/_pytest/fixtures.py new/pytest-3.10.1/src/_pytest/fixtures.py
--- old/pytest-3.10.0/src/_pytest/fixtures.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/src/_pytest/fixtures.py 2018-11-11 18:33:50.000000000 +0100
@@ -927,7 +927,7 @@
return hook.pytest_fixture_setup(fixturedef=self, request=request)
def __repr__(self):
- return "<FixtureDef name=%r scope=%r baseid=%r>" % (
+ return "<FixtureDef argname=%r scope=%r baseid=%r>" % (
self.argname,
self.scope,
self.baseid,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/src/_pytest/main.py new/pytest-3.10.1/src/_pytest/main.py
--- old/pytest-3.10.0/src/_pytest/main.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/src/_pytest/main.py 2018-11-11 18:33:50.000000000 +0100
@@ -18,7 +18,6 @@
from _pytest.config import hookimpl
from _pytest.config import UsageError
from _pytest.outcomes import exit
-from _pytest.pathlib import parts
from _pytest.runner import collect_one_node
@@ -279,7 +278,7 @@
return True
allow_in_venv = config.getoption("collect_in_virtualenv")
- if _in_venv(path) and not allow_in_venv:
+ if not allow_in_venv and _in_venv(path):
return True
return False
@@ -387,6 +386,8 @@
self._initialpaths = frozenset()
# Keep track of any collected nodes in here, so we don't duplicate fixtures
self._node_cache = {}
+ # Dirnames of pkgs with dunder-init files.
+ self._pkg_roots = {}
self.config.pluginmanager.register(self, name="session")
@@ -488,31 +489,27 @@
from _pytest.python import Package
names = self._parsearg(arg)
- argpath = names.pop(0).realpath()
- paths = set()
+ argpath = names.pop(0)
- root = self
# Start with a Session root, and delve to argpath item (dir or file)
# and stack all Packages found on the way.
# No point in finding packages when collecting doctests
if not self.config.option.doctestmodules:
- for parent in argpath.parts():
- pm = self.config.pluginmanager
+ pm = self.config.pluginmanager
+ for parent in reversed(argpath.parts()):
if pm._confcutdir and pm._confcutdir.relto(parent):
- continue
+ break
if parent.isdir():
pkginit = parent.join("__init__.py")
if pkginit.isfile():
- if pkginit in self._node_cache:
- root = self._node_cache[pkginit][0]
- else:
- col = root._collectfile(pkginit)
+ if pkginit not in self._node_cache:
+ col = self._collectfile(pkginit, handle_dupes=False)
if col:
if isinstance(col[0], Package):
- root = col[0]
+ self._pkg_roots[parent] = col[0]
# always store a list in the cache, matchnodes expects it
- self._node_cache[root.fspath] = [root]
+ self._node_cache[col[0].fspath] = [col[0]]
# If it's a directory argument, recurse and look for any Subpackages.
# Let the Package collector deal with subnodes, don't collect here.
@@ -535,28 +532,33 @@
):
dirpath = path.dirpath()
if dirpath not in seen_dirs:
+ # Collect packages first.
seen_dirs.add(dirpath)
pkginit = dirpath.join("__init__.py")
- if pkginit.exists() and parts(pkginit.strpath).isdisjoint(paths):
- for x in root._collectfile(pkginit):
+ if pkginit.exists():
+ for x in self._collectfile(pkginit):
yield x
- paths.add(x.fspath.dirpath())
+ if isinstance(x, Package):
+ self._pkg_roots[dirpath] = x
+ if dirpath in self._pkg_roots:
+ # Do not collect packages here.
+ continue
- if parts(path.strpath).isdisjoint(paths):
- for x in root._collectfile(path):
- key = (type(x), x.fspath)
- if key in self._node_cache:
- yield self._node_cache[key]
- else:
- self._node_cache[key] = x
- yield x
+ for x in self._collectfile(path):
+ key = (type(x), x.fspath)
+ if key in self._node_cache:
+ yield self._node_cache[key]
+ else:
+ self._node_cache[key] = x
+ yield x
else:
assert argpath.check(file=1)
if argpath in self._node_cache:
col = self._node_cache[argpath]
else:
- col = root._collectfile(argpath)
+ collect_root = self._pkg_roots.get(argpath.dirname, self)
+ col = collect_root._collectfile(argpath)
if col:
self._node_cache[argpath] = col
m = self.matchnodes(col, names)
@@ -570,20 +572,20 @@
for y in m:
yield y
- def _collectfile(self, path):
+ def _collectfile(self, path, handle_dupes=True):
ihook = self.gethookproxy(path)
if not self.isinitpath(path):
if ihook.pytest_ignore_collect(path=path, config=self.config):
return ()
- # Skip duplicate paths.
- keepduplicates = self.config.getoption("keepduplicates")
- if not keepduplicates:
- duplicate_paths = self.config.pluginmanager._duplicatepaths
- if path in duplicate_paths:
- return ()
- else:
- duplicate_paths.add(path)
+ if handle_dupes:
+ keepduplicates = self.config.getoption("keepduplicates")
+ if not keepduplicates:
+ duplicate_paths = self.config.pluginmanager._duplicatepaths
+ if path in duplicate_paths:
+ return ()
+ else:
+ duplicate_paths.add(path)
return ihook.pytest_collect_file(path=path, parent=self)
@@ -634,7 +636,7 @@
"file or package not found: " + arg + " (missing __init__.py?)"
)
raise UsageError("file not found: " + arg)
- parts[0] = path
+ parts[0] = path.realpath()
return parts
def matchnodes(self, matching, names):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/src/_pytest/nodes.py new/pytest-3.10.1/src/_pytest/nodes.py
--- old/pytest-3.10.0/src/_pytest/nodes.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/src/_pytest/nodes.py 2018-11-11 18:33:50.000000000 +0100
@@ -447,7 +447,7 @@
def _check_initialpaths_for_relpath(session, fspath):
for initial_path in session._initialpaths:
if fspath.common(initial_path) == initial_path:
- return fspath.relto(initial_path.dirname)
+ return fspath.relto(initial_path)
class FSCollector(Collector):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/src/_pytest/pytester.py new/pytest-3.10.1/src/_pytest/pytester.py
--- old/pytest-3.10.0/src/_pytest/pytester.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/src/_pytest/pytester.py 2018-11-11 18:33:50.000000000 +0100
@@ -1160,11 +1160,11 @@
def runpytest_subprocess(self, *args, **kwargs):
"""Run pytest as a subprocess with given arguments.
- Any plugins added to the :py:attr:`plugins` list will added using the
- ``-p`` command line option. Additionally ``--basetemp`` is used put
+ Any plugins added to the :py:attr:`plugins` list will be added using the
+ ``-p`` command line option. Additionally ``--basetemp`` is used to put
any temporary files and directories in a numbered directory prefixed
- with "runpytest-" so they do not conflict with the normal numbered
- pytest location for temporary files and directories.
+ with "runpytest-" to not conflict with the normal numbered pytest
+ location for temporary files and directories.
:param args: the sequence of arguments to pass to the pytest subprocess
:param timeout: the period in seconds after which to timeout and raise
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/src/_pytest/python.py new/pytest-3.10.1/src/_pytest/python.py
--- old/pytest-3.10.0/src/_pytest/python.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/src/_pytest/python.py 2018-11-11 18:33:50.000000000 +0100
@@ -545,11 +545,24 @@
proxy = self.config.hook
return proxy
- def _collectfile(self, path):
+ def _collectfile(self, path, handle_dupes=True):
ihook = self.gethookproxy(path)
if not self.isinitpath(path):
if ihook.pytest_ignore_collect(path=path, config=self.config):
return ()
+
+ if handle_dupes:
+ keepduplicates = self.config.getoption("keepduplicates")
+ if not keepduplicates:
+ duplicate_paths = self.config.pluginmanager._duplicatepaths
+ if path in duplicate_paths:
+ return ()
+ else:
+ duplicate_paths.add(path)
+
+ if self.fspath == path: # __init__.py
+ return [self]
+
return ihook.pytest_collect_file(path=path, parent=self)
def isinitpath(self, path):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/src/_pytest/terminal.py new/pytest-3.10.1/src/_pytest/terminal.py
--- old/pytest-3.10.0/src/_pytest/terminal.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/src/_pytest/terminal.py 2018-11-11 18:33:50.000000000 +0100
@@ -497,7 +497,10 @@
if not final:
# Only write "collecting" report every 0.5s.
t = time.time()
- if self._collect_report_last_write > t - 0.5:
+ if (
+ self._collect_report_last_write is not None
+ and self._collect_report_last_write > t - 0.5
+ ):
return
self._collect_report_last_write = t
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/src/pytest.egg-info/PKG-INFO new/pytest-3.10.1/src/pytest.egg-info/PKG-INFO
--- old/pytest-3.10.0/src/pytest.egg-info/PKG-INFO 2018-11-04 16:23:38.000000000 +0100
+++ new/pytest-3.10.1/src/pytest.egg-info/PKG-INFO 2018-11-11 18:34:14.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 1.2
Name: pytest
-Version: 3.10.0
+Version: 3.10.1
Summary: pytest: simple powerful testing with Python
Home-page: https://docs.pytest.org/en/latest/
Author: Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris Bruynooghe, Brianna Laugher, Florian Bruhin and others
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/src/pytest.egg-info/SOURCES.txt new/pytest-3.10.1/src/pytest.egg-info/SOURCES.txt
--- old/pytest-3.10.0/src/pytest.egg-info/SOURCES.txt 2018-11-04 16:23:38.000000000 +0100
+++ new/pytest-3.10.1/src/pytest.egg-info/SOURCES.txt 2018-11-11 18:34:15.000000000 +0100
@@ -25,7 +25,6 @@
bench/skip.py
changelog/README.rst
changelog/_template.rst
-doc/4266.bugfix.rst
doc/en/Makefile
doc/en/adopt.rst
doc/en/assert.rst
@@ -144,6 +143,7 @@
doc/en/announce/release-3.1.2.rst
doc/en/announce/release-3.1.3.rst
doc/en/announce/release-3.10.0.rst
+doc/en/announce/release-3.10.1.rst
doc/en/announce/release-3.2.0.rst
doc/en/announce/release-3.2.1.rst
doc/en/announce/release-3.2.2.rst
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/testing/acceptance_test.py new/pytest-3.10.1/testing/acceptance_test.py
--- old/pytest-3.10.0/testing/acceptance_test.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/testing/acceptance_test.py 2018-11-11 18:33:50.000000000 +0100
@@ -27,8 +27,9 @@
def test_config_error(self, testdir):
testdir.copy_example("conftest_usageerror/conftest.py")
result = testdir.runpytest(testdir.tmpdir)
- assert result.ret != 0
+ assert result.ret == EXIT_USAGEERROR
result.stderr.fnmatch_lines(["*ERROR: hello"])
+ result.stdout.fnmatch_lines(["*pytest_unconfigure_called"])
def test_root_conftest_syntax_error(self, testdir):
testdir.makepyfile(conftest="raise SyntaxError\n")
@@ -662,11 +663,11 @@
assert result.ret == 0
result.stdout.fnmatch_lines(
[
- "*test_hello.py::test_hello*PASSED*",
- "*test_hello.py::test_other*PASSED*",
- "*test_world.py::test_world*PASSED*",
- "*test_world.py::test_other*PASSED*",
- "*4 passed*",
+ "test_hello.py::test_hello*PASSED*",
+ "test_hello.py::test_other*PASSED*",
+ "ns_pkg/world/test_world.py::test_world*PASSED*",
+ "ns_pkg/world/test_world.py::test_other*PASSED*",
+ "*4 passed in*",
]
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/testing/example_scripts/conftest_usageerror/conftest.py new/pytest-3.10.1/testing/example_scripts/conftest_usageerror/conftest.py
--- old/pytest-3.10.0/testing/example_scripts/conftest_usageerror/conftest.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/testing/example_scripts/conftest_usageerror/conftest.py 2018-11-11 18:33:50.000000000 +0100
@@ -2,3 +2,7 @@
import pytest
raise pytest.UsageError("hello")
+
+
+def pytest_unconfigure(config):
+ print("pytest_unconfigure_called")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/testing/logging/test_fixture.py new/pytest-3.10.1/testing/logging/test_fixture.py
--- old/pytest-3.10.0/testing/logging/test_fixture.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/testing/logging/test_fixture.py 2018-11-11 18:33:50.000000000 +0100
@@ -136,5 +136,5 @@
assert [x.message for x in caplog.get_records("setup")] == ["a_setup_log"]
- # This reachers into private API, don't use this type of thing in real tests!
+ # This reaches into private API, don't use this type of thing in real tests!
assert set(caplog._item.catch_log_handlers.keys()) == {"setup", "call"}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/testing/test_argcomplete.py new/pytest-3.10.1/testing/test_argcomplete.py
--- old/pytest-3.10.0/testing/test_argcomplete.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/testing/test_argcomplete.py 2018-11-11 18:33:50.000000000 +0100
@@ -15,7 +15,7 @@
res_bash = set(fc(prefix))
retval = set(res) == res_bash
if out:
- out.write("equal_with_bash {} {}\n".format(retval, res))
+ out.write("equal_with_bash({}) {} {}\n".format(prefix, retval, res))
if not retval:
out.write(" python - bash: %s\n" % (set(res) - res_bash))
out.write(" bash - python: %s\n" % (res_bash - set(res)))
@@ -91,13 +91,19 @@
class TestArgComplete(object):
@pytest.mark.skipif("sys.platform in ('win32', 'darwin')")
- def test_compare_with_compgen(self):
+ def test_compare_with_compgen(self, tmpdir):
from _pytest._argcomplete import FastFilesCompleter
ffc = FastFilesCompleter()
fc = FilesCompleter()
- for x in ["/", "/d", "/data", "qqq", ""]:
- assert equal_with_bash(x, ffc, fc, out=sys.stdout)
+
+ with tmpdir.as_cwd():
+ assert equal_with_bash("", ffc, fc, out=sys.stdout)
+
+ tmpdir.ensure("data")
+
+ for x in ["d", "data", "doesnotexist", ""]:
+ assert equal_with_bash(x, ffc, fc, out=sys.stdout)
@pytest.mark.skipif("sys.platform in ('win32', 'darwin')")
def test_remove_dir_prefix(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/testing/test_assertion.py new/pytest-3.10.1/testing/test_assertion.py
--- old/pytest-3.10.0/testing/test_assertion.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/testing/test_assertion.py 2018-11-11 18:33:50.000000000 +0100
@@ -539,11 +539,8 @@
def test_mojibake(self):
# issue 429
- left = "e"
- right = "\xc3\xa9"
- if not isinstance(left, bytes):
- left = bytes(left, "utf-8")
- right = bytes(right, "utf-8")
+ left = b"e"
+ right = b"\xc3\xa9"
expl = callequal(left, right)
for line in expl:
assert isinstance(line, six.text_type)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/testing/test_capture.py new/pytest-3.10.1/testing/test_capture.py
--- old/pytest-3.10.0/testing/test_capture.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/testing/test_capture.py 2018-11-11 18:33:50.000000000 +0100
@@ -27,24 +27,6 @@
)
-def tobytes(obj):
- if isinstance(obj, text_type):
- obj = obj.encode("UTF-8")
- assert isinstance(obj, bytes)
- return obj
-
-
-def totext(obj):
- if isinstance(obj, bytes):
- obj = text_type(obj, "UTF-8")
- assert isinstance(obj, text_type)
- return obj
-
-
-def oswritebytes(fd, obj):
- os.write(fd, tobytes(obj))
-
-
def StdCaptureFD(out=True, err=True, in_=True):
return capture.MultiCapture(out, err, in_, Capture=capture.FDCapture)
@@ -836,10 +818,11 @@
def test_bytes_io():
f = py.io.BytesIO()
- f.write(tobytes("hello"))
- pytest.raises(TypeError, "f.write(totext('hello'))")
+ f.write(b"hello")
+ with pytest.raises(TypeError):
+ f.write(u"hello")
s = f.getvalue()
- assert s == tobytes("hello")
+ assert s == b"hello"
def test_dontreadfrominput():
@@ -952,7 +935,7 @@
def test_simple(self, tmpfile):
fd = tmpfile.fileno()
cap = capture.FDCapture(fd)
- data = tobytes("hello")
+ data = b"hello"
os.write(fd, data)
s = cap.snap()
cap.done()
@@ -992,10 +975,10 @@
cap.start()
x = os.read(0, 100).strip()
cap.done()
- assert x == tobytes("")
+ assert x == b""
def test_writeorg(self, tmpfile):
- data1, data2 = tobytes("foo"), tobytes("bar")
+ data1, data2 = b"foo", b"bar"
cap = capture.FDCapture(tmpfile.fileno())
cap.start()
tmpfile.write(data1)
@@ -1003,7 +986,7 @@
cap.writeorg(data2)
scap = cap.snap()
cap.done()
- assert scap == totext(data1)
+ assert scap == data1.decode("ascii")
with open(tmpfile.name, "rb") as stmp_file:
stmp = stmp_file.read()
assert stmp == data2
@@ -1012,17 +995,17 @@
with saved_fd(1):
cap = capture.FDCapture(1)
cap.start()
- data = tobytes("hello")
+ data = b"hello"
os.write(1, data)
sys.stdout.write("whatever")
s = cap.snap()
assert s == "hellowhatever"
cap.suspend()
- os.write(1, tobytes("world"))
+ os.write(1, b"world")
sys.stdout.write("qlwkej")
assert not cap.snap()
cap.resume()
- os.write(1, tobytes("but now"))
+ os.write(1, b"but now")
sys.stdout.write(" yes\n")
s = cap.snap()
assert s == "but now yes\n"
@@ -1193,14 +1176,14 @@
def test_intermingling(self):
with self.getcapture() as cap:
- oswritebytes(1, "1")
+ os.write(1, b"1")
sys.stdout.write(str(2))
sys.stdout.flush()
- oswritebytes(1, "3")
- oswritebytes(2, "a")
+ os.write(1, b"3")
+ os.write(2, b"a")
sys.stderr.write("b")
sys.stderr.flush()
- oswritebytes(2, "c")
+ os.write(2, b"c")
out, err = cap.readouterr()
assert out == "123"
assert err == "abc"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/testing/test_collection.py new/pytest-3.10.1/testing/test_collection.py
--- old/pytest-3.10.0/testing/test_collection.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/testing/test_collection.py 2018-11-11 18:33:50.000000000 +0100
@@ -6,6 +6,8 @@
import sys
import textwrap
+import py
+
import pytest
from _pytest.main import _in_venv
from _pytest.main import EXIT_NOTESTSCOLLECTED
@@ -951,26 +953,58 @@
result = testdir.runpytest(p, "--collect-only")
result.stdout.fnmatch_lines(
[
- "*",
- "*",
- "*",
- "*",
+ "collected 2 items",
+ "",
+ " ",
+ " ",
+ " ",
]
)
result = testdir.runpytest("./tests", "--collect-only")
result.stdout.fnmatch_lines(
[
- "*",
- "*",
- "*",
- "*",
+ "collected 2 items",
+ "",
+ " ",
+ " ",
+ " ",
+ ]
+ )
+ # Ignores duplicates with "." and pkginit (#4310).
+ result = testdir.runpytest("./tests", ".", "--collect-only")
+ result.stdout.fnmatch_lines(
+ [
+ "collected 2 items",
+ "",
+ " ",
+ " ",
+ " ",
+ " ",
+ ]
+ )
+ # Same as before, but different order.
+ result = testdir.runpytest(".", "tests", "--collect-only")
+ result.stdout.fnmatch_lines(
+ [
+ "collected 2 items",
+ "",
+ " ",
+ " ",
+ " ",
+ " ",
]
)
result = testdir.runpytest("./tests/test_foo.py", "--collect-only")
- result.stdout.fnmatch_lines(["*", "*"])
+ result.stdout.fnmatch_lines(
+ ["", " ", " "]
+ )
assert "test_init" not in result.stdout.str()
result = testdir.runpytest("./tests/__init__.py", "--collect-only")
- result.stdout.fnmatch_lines(["*", "*"])
+ result.stdout.fnmatch_lines(
+ ["", " ", " "]
+ )
assert "test_foo" not in result.stdout.str()
@@ -1019,3 +1053,55 @@
result = testdir.runpytest()
assert result.ret == 0
result.stdout.fnmatch_lines(["*1 passed in*"])
+
+
+@pytest.mark.skipif(
+ not hasattr(py.path.local, "mksymlinkto"),
+ reason="symlink not available on this platform",
+)
+def test_collect_symlink_file_arg(testdir):
+ """Test that collecting a direct symlink, where the target does not match python_files works (#4325)."""
+ real = testdir.makepyfile(
+ real="""
+ def test_nodeid(request):
+ assert request.node.nodeid == "real.py::test_nodeid"
+ """
+ )
+ symlink = testdir.tmpdir.join("symlink.py")
+ symlink.mksymlinkto(real)
+ result = testdir.runpytest("-v", symlink)
+ result.stdout.fnmatch_lines(["real.py::test_nodeid PASSED*", "*1 passed in*"])
+ assert result.ret == 0
+
+
+@pytest.mark.skipif(
+ not hasattr(py.path.local, "mksymlinkto"),
+ reason="symlink not available on this platform",
+)
+def test_collect_symlink_out_of_tree(testdir):
+ """Test collection of symlink via out-of-tree rootdir."""
+ sub = testdir.tmpdir.join("sub")
+ real = sub.join("test_real.py")
+ real.write(
+ textwrap.dedent(
+ """
+ def test_nodeid(request):
+ # Should not contain sub/ prefix.
+ assert request.node.nodeid == "test_real.py::test_nodeid"
+ """
+ ),
+ ensure=True,
+ )
+
+ out_of_tree = testdir.tmpdir.join("out_of_tree").ensure(dir=True)
+ symlink_to_sub = out_of_tree.join("symlink_to_sub")
+ symlink_to_sub.mksymlinkto(sub)
+ sub.chdir()
+ result = testdir.runpytest("-vs", "--rootdir=%s" % sub, symlink_to_sub)
+ result.stdout.fnmatch_lines(
+ [
+ # Should not contain "sub/"!
+ "test_real.py::test_nodeid PASSED"
+ ]
+ )
+ assert result.ret == 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/testing/test_config.py new/pytest-3.10.1/testing/test_config.py
--- old/pytest-3.10.0/testing/test_config.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/testing/test_config.py 2018-11-11 18:33:50.000000000 +0100
@@ -874,7 +874,7 @@
assert inifile == inifile
@pytest.mark.parametrize("name", "setup.cfg tox.ini".split())
- def test_pytestini_overides_empty_other(self, tmpdir, name):
+ def test_pytestini_overrides_empty_other(self, tmpdir, name):
inifile = tmpdir.ensure("pytest.ini")
a = tmpdir.mkdir("a")
a.ensure(name)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/testing/test_modimport.py new/pytest-3.10.1/testing/test_modimport.py
--- old/pytest-3.10.0/testing/test_modimport.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/testing/test_modimport.py 2018-11-11 18:33:50.000000000 +0100
@@ -19,13 +19,19 @@
# without needing the pytest namespace being set
# this is critical for the initialization of xdist
- res = subprocess.call(
+ p = subprocess.Popen(
[
sys.executable,
"-c",
"import sys, py; py.path.local(sys.argv[1]).pyimport()",
modfile.strpath,
- ]
+ ],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
)
- if res:
- pytest.fail("command result %s" % res)
+ (out, err) = p.communicate()
+ if p.returncode != 0:
+ pytest.fail(
+ "importing %s failed (exitcode %d): out=%r, err=%r"
+ % (modfile, p.returncode, out, err)
+ )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/testing/test_nodes.py new/pytest-3.10.1/testing/test_nodes.py
--- old/pytest-3.10.0/testing/test_nodes.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/testing/test_nodes.py 2018-11-11 18:33:50.000000000 +0100
@@ -1,3 +1,5 @@
+import py
+
import pytest
from _pytest import nodes
@@ -29,3 +31,23 @@
)
with pytest.raises(ValueError, match=".*instance of PytestWarning.*"):
items[0].warn(UserWarning("some warning"))
+
+
+def test__check_initialpaths_for_relpath():
+ """Ensure that it handles dirs, and does not always use dirname."""
+ cwd = py.path.local()
+
+ class FakeSession:
+ _initialpaths = [cwd]
+
+ assert nodes._check_initialpaths_for_relpath(FakeSession, cwd) == ""
+
+ sub = cwd.join("file")
+
+ class FakeSession:
+ _initialpaths = [cwd]
+
+ assert nodes._check_initialpaths_for_relpath(FakeSession, sub) == "file"
+
+ outside = py.path.local("/outside")
+ assert nodes._check_initialpaths_for_relpath(FakeSession, outside) is None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/testing/test_pdb.py new/pytest-3.10.1/testing/test_pdb.py
--- old/pytest-3.10.0/testing/test_pdb.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/testing/test_pdb.py 2018-11-11 18:33:50.000000000 +0100
@@ -826,3 +826,30 @@
assert "1 passed" in rest
assert "reading from stdin while output" not in rest
TestPDB.flush(child)
+
+
+def test_trace_after_runpytest(testdir):
+ """Test that debugging's pytest_configure is re-entrant."""
+ p1 = testdir.makepyfile(
+ """
+ from _pytest.debugging import pytestPDB
+
+ def test_outer(testdir):
+ from _pytest.debugging import pytestPDB
+
+ assert len(pytestPDB._saved) == 1
+
+ testdir.runpytest("-k test_inner")
+
+ __import__('pdb').set_trace()
+
+ def test_inner(testdir):
+ assert len(pytestPDB._saved) == 2
+ """
+ )
+ child = testdir.spawn_pytest("-p pytester %s -k test_outer" % p1)
+ child.expect(r"\(Pdb")
+ child.sendline("c")
+ rest = child.read().decode("utf8")
+ TestPDB.flush(child)
+ assert child.exitstatus == 0, rest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/testing/test_pluginmanager.py new/pytest-3.10.1/testing/test_pluginmanager.py
--- old/pytest-3.10.0/testing/test_pluginmanager.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/testing/test_pluginmanager.py 2018-11-11 18:33:50.000000000 +0100
@@ -380,3 +380,21 @@
pytestpm.consider_preparse(["xyz", "-p", "no:abc"])
l2 = pytestpm.get_plugins()
assert 42 not in l2
+
+ def test_plugin_prevent_register_stepwise_on_cacheprovider_unregister(
+ self, pytestpm
+ ):
+ """ From PR #4304 : The only way to unregister a module is documented at
+ the end of https://docs.pytest.org/en/latest/plugins.html.
+
+ When unregister cacheprovider, then unregister stepwise too
+ """
+ pytestpm.register(42, name="cacheprovider")
+ pytestpm.register(43, name="stepwise")
+ l1 = pytestpm.get_plugins()
+ assert 42 in l1
+ assert 43 in l1
+ pytestpm.consider_preparse(["xyz", "-p", "no:cacheprovider"])
+ l2 = pytestpm.get_plugins()
+ assert 42 not in l2
+ assert 43 not in l2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-3.10.0/testing/test_session.py new/pytest-3.10.1/testing/test_session.py
--- old/pytest-3.10.0/testing/test_session.py 2018-11-04 16:22:56.000000000 +0100
+++ new/pytest-3.10.1/testing/test_session.py 2018-11-11 18:33:50.000000000 +0100
@@ -323,7 +323,11 @@
result = testdir.runpytest("--rootdir={}".format(path))
result.stdout.fnmatch_lines(
- ["*rootdir: {}/root, inifile:*".format(testdir.tmpdir), "*1 passed*"]
+ [
+ "*rootdir: {}/root, inifile:*".format(testdir.tmpdir),
+ "root/test_rootdir_option_arg.py *",
+ "*1 passed*",
+ ]
)