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*", + ] )
