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 <[email protected]>
+
+- 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 @@
    * [email protected] (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
     <Package '$REGENDOC_TMPDIR/nonpython'>
-      <Package '$REGENDOC_TMPDIR/nonpython'>
-        <YamlFile 'test_simple.yml'>
-          <YamlItem 'hello'>
-          <YamlItem 'ok'>
+      <YamlFile 'test_simple.yml'>
+        <YamlItem 'hello'>
+        <YamlItem 'ok'>
 
     ======================= 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(
         [
-            "*<Module '__init__.py'>",
-            "*<Function 'test_init'>",
-            "*<Module 'test_foo.py'>",
-            "*<Function 'test_foo'>",
+            "collected 2 items",
+            "<Package *",
+            "  <Module '__init__.py'>",
+            "    <Function 'test_init'>",
+            "  <Module 'test_foo.py'>",
+            "    <Function 'test_foo'>",
         ]
     )
     result = testdir.runpytest("./tests", "--collect-only")
     result.stdout.fnmatch_lines(
         [
-            "*<Module '__init__.py'>",
-            "*<Function 'test_init'>",
-            "*<Module 'test_foo.py'>",
-            "*<Function 'test_foo'>",
+            "collected 2 items",
+            "<Package *",
+            "  <Module '__init__.py'>",
+            "    <Function 'test_init'>",
+            "  <Module 'test_foo.py'>",
+            "    <Function 'test_foo'>",
+        ]
+    )
+    # Ignores duplicates with "." and pkginit (#4310).
+    result = testdir.runpytest("./tests", ".", "--collect-only")
+    result.stdout.fnmatch_lines(
+        [
+            "collected 2 items",
+            "<Package */tests'>",
+            "  <Module '__init__.py'>",
+            "    <Function 'test_init'>",
+            "  <Module 'test_foo.py'>",
+            "    <Function 'test_foo'>",
+        ]
+    )
+    # Same as before, but different order.
+    result = testdir.runpytest(".", "tests", "--collect-only")
+    result.stdout.fnmatch_lines(
+        [
+            "collected 2 items",
+            "<Package */tests'>",
+            "  <Module '__init__.py'>",
+            "    <Function 'test_init'>",
+            "  <Module 'test_foo.py'>",
+            "    <Function 'test_foo'>",
         ]
     )
     result = testdir.runpytest("./tests/test_foo.py", "--collect-only")
-    result.stdout.fnmatch_lines(["*<Module 'test_foo.py'>", "*<Function 
'test_foo'>"])
+    result.stdout.fnmatch_lines(
+        ["<Package */tests'>", "  <Module 'test_foo.py'>", "    <Function 
'test_foo'>"]
+    )
     assert "test_init" not in result.stdout.str()
     result = testdir.runpytest("./tests/__init__.py", "--collect-only")
-    result.stdout.fnmatch_lines(["*<Module '__init__.py'>", "*<Function 
'test_init'>"])
+    result.stdout.fnmatch_lines(
+        ["<Package */tests'>", "  <Module '__init__.py'>", "    <Function 
'test_init'>"]
+    )
     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*"])
+
+
[email protected](
+    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
+
+
[email protected](
+    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*",
+        ]
     )
 
 


Reply via email to