Compare commits

...

28 Commits
main ... 6.1.x

Author SHA1 Message Date
Ran Benita 1142d138e3
Merge pull request #7986 from bluetech/backport-7956
[6.1.x] Fix handling recursive symlinks
2020-11-08 16:38:33 +02:00
Ran Benita 296f468a7c
Merge pull request #7983 from bluetech/backports
[6.1.x] Two backports
2020-11-08 16:38:11 +02:00
Ran Benita 84247c4bab
Merge pull request #7984 from nicoddemus/backport-7979
[6.1.x] Merge pull request #7979 from nicoddemus/metafunc-ref
2020-11-08 16:37:49 +02:00
Ran Benita 1adbb04f02 Merge pull request #7956 from csernazs/fix-7951
Fix handling recursive symlinks

(cherry picked from commit 7fb0ea3f68)

Adjusted to pass str(path) for Python 3.5 support.
2020-10-31 22:27:02 +02:00
Bruno Oliveira 0dca7ee21a Merge pull request #7979 from nicoddemus/metafunc-ref
Add FunctionDefinition to the reference docs
2020-10-31 10:01:04 -03:00
Ran Benita 8cf0bbdf75 Merge pull request #7982 from bluetech/symlink-collect
pathlib: fix symlinked directories not followed during collection
(cherry picked from commit a14a229d1b)

Changed pytester -> testdir.
2020-10-31 14:59:59 +02:00
Ran Benita 573860d71c Merge pull request #7978 from nicoddemus/port-4.6-release-notes
Manually add the remaining 4.6.x release notes to the changelog

(cherry picked from commit dd323980f9)
2020-10-31 14:48:45 +02:00
Bruno Oliveira 1ed903e8fc
Merge pull request #7958 from pytest-dev/release-6.1.2
Prepare release 6.1.2
2020-10-28 14:21:33 -03:00
pytest bot 4e8b50ba01 Prepare release version 6.1.2 2020-10-28 11:37:31 +00:00
Bruno Oliveira cd221df8e2
Merge pull request #7955 from nicoddemus/backport-7914
[6.1.x] Increase temp dir deletion period to 3 days (#7914)
2020-10-28 08:33:01 -03:00
Vasilis Gerakaris 8c1c1ae310 Increase temp dir deletion period to 3 days (#7914)
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2020-10-28 08:26:16 -03:00
Bruno Oliveira a88fe584ad
Merge pull request #7919 from nicoddemus/backport-7917
[6.1.x] ci: decrease job timeout from 6 hours to 30 minutes
2020-10-21 09:15:09 -03:00
Bruno Oliveira cd57271455 Merge pull request #7917 from bluetech/ci-timeout
ci: decrease job timeout from 6 hours to 30 minutes
2020-10-21 08:03:37 -03:00
Ran Benita 46195edc3e
Merge pull request #7918 from bluetech/backport-7915
[6.1.x] cacheprovider: fix some files in packages getting lost from --lf
2020-10-21 10:51:52 +03:00
Ran Benita 9237b5f633 Merge pull request #7915 from bluetech/fix-lf-package
cacheprovider: fix some files in packages getting lost from --lf
(cherry picked from commit a66b6b857a)

with some needed adjustments to 6.1.x.
2020-10-21 10:27:12 +03:00
Bruno Oliveira 95fd566133
Merge pull request #7867 from nicoddemus/backport-7829 2020-10-06 12:06:15 -03:00
Manuel Mariñez c93962c491 Add alias clarification to deprecation warning (#7829)
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2020-10-06 11:49:13 -03:00
Bruno Oliveira dc96e485a0
Merge pull request #7861 from nicoddemus/backport-7860
[6.1.x] Update reference.rst informing the default junit_family (#7860)
2020-10-05 15:24:42 -03:00
William Jamir Silva 7ccfc39f15 Update reference.rst informing the default junit_family (#7860)
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
2020-10-05 14:05:16 -03:00
Ran Benita 69d903260d
Merge pull request #7849 from pytest-dev/release-6.1.1
Prepare release 6.1.1
2020-10-03 22:37:28 +03:00
pytest bot 0ad20b533f Prepare release version 6.1.1 2020-10-03 19:05:02 +00:00
Ran Benita 9df5267648
Merge pull request #7842 from bluetech/backport-7817
[6.1.x] terminal: fix crash in header reporting when absolute testpaths is used
2020-10-03 13:21:16 +03:00
Ran Benita 1521849c87 terminal: fix crash in header reporting when absolute testpaths is used
Regressed in 6.1.0 in 62e249a1f9.
The `x` is an `str` but is expected to be a `pathlib.Path`. Not caught
by mypy because `config.getini()` returns `Any`.

Fix by just removing the `bestrelpath` call:

- testpaths are always relative to the rootdir, it thus would be very
  unusual to specify an absolute path there.

- The code was wrong even before the regression: `py.path.local`'s
  `bestrelpath` function expects a `py.path.local`, not an `str`. But it
  had some weird `try ... except AttributeError` fallback which just
  returns the argument, i.e. it was a no-op. So there is no behavior
  change.

- It seems reasonable to me to just print the full path if that's what
  the ini specifies.

(cherry picked from commit 61f80a783a)
2020-10-03 13:01:19 +03:00
Ran Benita bcb94c4c8b
Merge pull request #7822 from bluetech/backport-7813
[6.1.x] findpaths: fix regression causing incorrect rootdir to be determined
2020-09-30 15:08:56 +03:00
Ran Benita 0f83df4f55 Merge pull request #7813 from bluetech/findpaths-confusion
findpaths: fix regression causing incorrect rootdir to be determined
(cherry picked from commit b250c9d615)
2020-09-30 13:22:00 +03:00
Ran Benita 330caac2ca
[6.1.x] Improve docs about plugin discovery/loading at startup (#7803) 2020-09-27 11:14:54 -03:00
Ran Benita 08a1ab3a8a
Merge pull request #7797 from pytest-dev/release-6.1.0
Prepare release 6.1.0
2020-09-26 21:09:34 +03:00
pytest bot 868bc003ec Prepare release version 6.1.0 2020-09-26 17:32:18 +00:00
50 changed files with 585 additions and 150 deletions

View File

@ -16,6 +16,7 @@ on:
jobs:
build:
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
@ -187,6 +188,7 @@ jobs:
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') && github.repository == 'pytest-dev/pytest'
runs-on: ubuntu-latest
timeout-minutes: 30
needs: [build]

View File

@ -310,3 +310,4 @@ Xuecong Liao
Yoav Caspi
Zac Hatfield-Dodds
Zoltán Máté
Zsolt Cserna

View File

@ -1 +0,0 @@
Removed faq.rst and its reference in contents.rst.

View File

@ -1,20 +0,0 @@
Fixed error when overwriting a parametrized fixture, while also reusing the super fixture value.
.. code-block:: python
# conftest.py
import pytest
@pytest.fixture(params=[1, 2])
def foo(request):
return request.param
# test_foo.py
import pytest
@pytest.fixture
def foo(foo):
return foo * 2

View File

@ -1,3 +0,0 @@
Fixed an internal error crash with ``IndexError: list index out of range`` when
collecting a module which starts with a decorated function, the decorator
raises, and assertion rewriting is enabled.

View File

@ -1,18 +0,0 @@
As per our policy, the following features which have been deprecated in the 5.X series are now
removed:
* The ``funcargnames`` read-only property of ``FixtureRequest``, ``Metafunc``, and ``Function`` classes. Use ``fixturenames`` attribute.
* ``@pytest.fixture`` no longer supports positional arguments, pass all arguments by keyword instead.
* Direct construction of ``Node`` subclasses now raise an error, use ``from_parent`` instead.
* The default value for ``junit_family`` has changed to ``xunit2``. If you require the old format, add ``junit_family=xunit1`` to your configuration file.
* The ``TerminalReporter`` no longer has a ``writer`` attribute. Plugin authors may use the public functions of the ``TerminalReporter`` instead of accessing the ``TerminalWriter`` object directly.
* The ``--result-log`` option has been removed. Users are recommended to use the `pytest-reportlog <https://github.com/pytest-dev/pytest-reportlog>`__ plugin instead.
For more information consult
`Deprecations and Removals <https://docs.pytest.org/en/stable/deprecations.html>`__ in the docs.

View File

@ -1,3 +0,0 @@
Internal pytest warnings issued during the early stages of initialization are now properly handled and can filtered through :confval:`filterwarnings` or ``--pythonwarnings/-W``.
This also fixes a number of long standing issues: `#2891 <https://github.com/pytest-dev/pytest/issues/2891>`__, `#7620 <https://github.com/pytest-dev/pytest/issues/7620>`__, `#7426 <https://github.com/pytest-dev/pytest/issues/7426>`__.

View File

@ -1 +0,0 @@
The ``pytest.collect`` module is deprecated: all its names can be imported from ``pytest`` directly.

View File

@ -1,6 +0,0 @@
The ``pytest._fillfuncargs`` function is deprecated. This function was kept
for backward compatibility with an older plugin.
It's functionality is not meant to be used directly, but if you must replace
it, use `function._request._fillfixtures()` instead, though note this is not
a public API and may break in the future.

View File

@ -1,5 +0,0 @@
The special ``-k '-expr'`` syntax to ``-k`` is deprecated. Use ``-k 'not expr'``
instead.
The special ``-k 'expr:'`` syntax to ``-k`` is deprecated. Please open an issue
if you use this and want a replacement.

View File

@ -1,2 +0,0 @@
The :func:`pytest_warning_captured <_pytest.hookspec.pytest_warning_captured>` hook is deprecated in favor
of :func:`pytest_warning_recorded <_pytest.hookspec.pytest_warning_recorded>`, and will be removed in a future version.

View File

@ -1,3 +0,0 @@
The internal ``junitxml`` plugin has rewritten to use ``xml.etree.ElementTree``.
The order of attributes in XML elements might differ. Some unneeded escaping is
no longer performed.

View File

@ -1 +0,0 @@
When a plugin listed in ``required_plugins`` is missing or an unknown config key is used with ``--strict-config``, a simple error message is now shown instead of a stacktrace.

View File

@ -1 +0,0 @@
The dependency on the ``more-itertools`` package has been removed.

View File

@ -1 +0,0 @@
pylint shouldn't complain anymore about unimplemented abstract methods when inheriting from :ref:`File <non-python tests>`.

View File

@ -1 +0,0 @@
Fixed test collection when a full path without a drive letter was passed to pytest on Windows (for example ``\projects\tests\test.py`` instead of ``c:\projects\tests\pytest.py``).

View File

@ -1,2 +0,0 @@
The result type of :meth:`capfd.readouterr() <_pytest.capture.CaptureFixture.readouterr>` (and similar) is no longer a namedtuple,
but should behave like one in all respects. This was done for technical reasons.

View File

@ -1 +0,0 @@
Fix handling of command-line options that appear as paths but trigger an OS-level syntax error on Windows, such as the options used internally by ``pytest-xdist``.

View File

@ -1,3 +0,0 @@
The ``gethookproxy()`` and ``isinitpath()`` methods of ``FSCollector`` and ``Package`` are deprecated;
use ``self.session.gethookproxy()`` and ``self.session.isinitpath()`` instead.
This should work on all pytest versions.

View File

@ -1 +0,0 @@
New ``--durations-min`` command-line flag controls the minimal duration for inclusion in the slowest list of tests shown by ``--durations``. Previously this was hard-coded to ``0.005s``.

View File

@ -1,6 +0,0 @@
When collecting tests, pytest finds test classes and functions by examining the
attributes of python objects (modules, classes and instances). To speed up this
process, pytest now ignores builtin attributes (like ``__class__``,
``__delattr__`` and ``__new__``) without consulting the :confval:`python_classes` and
:confval:`python_functions` configuration options and without passing them to plugins
using the :func:`pytest_pycollect_makeitem <_pytest.hookspec.pytest_pycollect_makeitem>` hook.

View File

@ -1,3 +0,0 @@
Added two new attributes :attr:`rootpath <_pytest.config.Config.rootpath>` and :attr:`inipath <_pytest.config.Config.inipath>` to :class:`Config <_pytest.config.Config>`.
These attributes are :class:`pathlib.Path` versions of the existing :attr:`rootdir <_pytest.config.Config.rootdir>` and :attr:`inifile <_pytest.config.Config.inifile>` attributes,
and should be preferred over them when possible.

View File

@ -1 +0,0 @@
Fixed INTERNALERROR when accessing locals / globals with faulty ``exec``.

View File

@ -1,3 +0,0 @@
Public classes which are not designed to be inherited from are now marked `@final <https://docs.python.org/3/library/typing.html#typing.final>`_.
Code which inherits from these classes will trigger a type-checking (e.g. mypy) error, but will still work in runtime.
Currently the ``final`` designation does not appear in the API Reference but hopefully will in the future.

View File

@ -0,0 +1 @@
Fixed handling of recursive symlinks when collecting tests.

View File

@ -0,0 +1 @@
Fixed symlinked directories not being followed during collection. Regressed in pytest 6.1.0.

View File

@ -6,6 +6,9 @@ Release announcements
:maxdepth: 2
release-6.1.2
release-6.1.1
release-6.1.0
release-6.0.2
release-6.0.1
release-6.0.0

View File

@ -0,0 +1,44 @@
pytest-6.1.0
=======================================
The pytest team is proud to announce the 6.1.0 release!
This release contains new features, improvements, bug fixes, and breaking changes, so users
are encouraged to take a look at the CHANGELOG carefully:
https://docs.pytest.org/en/stable/changelog.html
For complete documentation, please visit:
https://docs.pytest.org/en/stable/
As usual, you can upgrade from PyPI via:
pip install -U pytest
Thanks to all of the contributors to this release:
* Anthony Sottile
* Bruno Oliveira
* C. Titus Brown
* Drew Devereux
* Faris A Chugthai
* Florian Bruhin
* Hugo van Kemenade
* Hynek Schlawack
* Joseph Lucas
* Kamran Ahmad
* Mattreex
* Maximilian Cosmo Sitter
* Ran Benita
* Rüdiger Busche
* Sam Estep
* Sorin Sbarnea
* Thomas Grainger
* Vipul Kumar
* Yutaro Ikeda
* hp310780
Happy testing,
The pytest Development Team

View File

@ -0,0 +1,18 @@
pytest-6.1.1
=======================================
pytest 6.1.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/stable/changelog.html.
Thanks to all of the contributors to this release:
* Ran Benita
Happy testing,
The pytest Development Team

View File

@ -0,0 +1,22 @@
pytest-6.1.2
=======================================
pytest 6.1.2 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/stable/changelog.html.
Thanks to all of the contributors to this release:
* Bruno Oliveira
* Manuel Mariñez
* Ran Benita
* Vasilis Gerakaris
* William Jamir Silva
Happy testing,
The pytest Development Team

View File

@ -23,7 +23,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
cache.get(key, default)
cache.set(key, value)
Keys must be a ``/`` separated value, where the first part is usually the
Keys must be ``/`` separated strings, where the first part is usually the
name of your plugin or application to avoid clashes with other cache users.
Values can be any object handled by the json stdlib module.
@ -57,7 +57,8 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
``out`` and ``err`` will be ``byte`` objects.
doctest_namespace [session scope]
Fixture that returns a :py:class:`dict` that will be injected into the namespace of doctests.
Fixture that returns a :py:class:`dict` that will be injected into the
namespace of doctests.
pytestconfig [session scope]
Session-scoped fixture that returns the :class:`_pytest.config.Config` object.
@ -89,8 +90,10 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
automatically XML-encoded.
record_testsuite_property [session scope]
Records a new ``<property>`` tag as child of the root ``<testsuite>``. This is suitable to
writing global information regarding the entire test suite, and is compatible with ``xunit2`` JUnit family.
Record a new ``<property>`` tag as child of the root ``<testsuite>``.
This is suitable to writing global information regarding the entire test
suite, and is compatible with ``xunit2`` JUnit family.
This is a ``session``-scoped fixture which is called with ``(name, value)``. Example:
@ -102,6 +105,12 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
``name`` must be a string, ``value`` will be converted to a string and properly xml-escaped.
.. warning::
Currently this fixture **does not work** with the
`pytest-xdist <https://github.com/pytest-dev/pytest-xdist>`__ plugin. See issue
`#7767 <https://github.com/pytest-dev/pytest/issues/7767>`__ for details.
caplog
Access and control log capturing.
@ -114,8 +123,10 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
* caplog.clear() -> clear captured records and formatted log output string
monkeypatch
The returned ``monkeypatch`` fixture provides these
helper methods to modify objects, dictionaries or os.environ::
A convenient fixture for monkey-patching.
The fixture provides these methods to modify objects, dictionaries or
os.environ::
monkeypatch.setattr(obj, name, value, raising=True)
monkeypatch.delattr(obj, name, raising=True)
@ -126,10 +137,9 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
monkeypatch.syspath_prepend(path)
monkeypatch.chdir(path)
All modifications will be undone after the requesting
test function or fixture has finished. The ``raising``
parameter determines if a KeyError or AttributeError
will be raised if the set/deletion operation has no target.
All modifications will be undone after the requesting test function or
fixture has finished. The ``raising`` parameter determines if a KeyError
or AttributeError will be raised if the set/deletion operation has no target.
recwarn
Return a :class:`WarningsRecorder` instance that records all warnings emitted by test functions.
@ -140,30 +150,28 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
tmpdir_factory [session scope]
Return a :class:`_pytest.tmpdir.TempdirFactory` instance for the test session.
tmp_path_factory [session scope]
Return a :class:`_pytest.tmpdir.TempPathFactory` instance for the test session.
tmpdir
Return a temporary directory path object
which is unique to each test function invocation,
created as a sub directory of the base temporary
directory. The returned object is a `py.path.local`_
path object.
Return a temporary directory path object which is unique to each test
function invocation, created as a sub directory of the base temporary
directory.
The returned object is a `py.path.local`_ path object.
.. _`py.path.local`: https://py.readthedocs.io/en/latest/path.html
tmp_path
Return a temporary directory path object
which is unique to each test function invocation,
created as a sub directory of the base temporary
directory. The returned object is a :class:`pathlib.Path`
object.
Return a temporary directory path object which is unique to each test
function invocation, created as a sub directory of the base temporary
directory.
The returned object is a :class:`pathlib.Path` object.
.. note::
in python < 3.6 this is a pathlib2.Path
In python < 3.6 this is a pathlib2.Path.
no tests ran in 0.12s

View File

@ -28,6 +28,197 @@ with advance notice in the **Deprecations** section of releases.
.. towncrier release notes start
pytest 6.1.2 (2020-10-28)
=========================
Bug Fixes
---------
- `#7758 <https://github.com/pytest-dev/pytest/issues/7758>`_: Fixed an issue where some files in packages are getting lost from ``--lf`` even though they contain tests that failed. Regressed in pytest 5.4.0.
- `#7911 <https://github.com/pytest-dev/pytest/issues/7911>`_: Directories created by `tmpdir` are now considered stale after 3 days without modification (previous value was 3 hours) to avoid deleting directories still in use in long running test suites.
Improved Documentation
----------------------
- `#7815 <https://github.com/pytest-dev/pytest/issues/7815>`_: Improve deprecation warning message for ``pytest._fillfuncargs()``.
pytest 6.1.1 (2020-10-03)
=========================
Bug Fixes
---------
- `#7807 <https://github.com/pytest-dev/pytest/issues/7807>`_: Fixed regression in pytest 6.1.0 causing incorrect rootdir to be determined in some non-trivial cases where parent directories have config files as well.
- `#7814 <https://github.com/pytest-dev/pytest/issues/7814>`_: Fixed crash in header reporting when :confval:`testpaths` is used and contains absolute paths (regression in 6.1.0).
pytest 6.1.0 (2020-09-26)
=========================
Breaking Changes
----------------
- `#5585 <https://github.com/pytest-dev/pytest/issues/5585>`_: As per our policy, the following features which have been deprecated in the 5.X series are now
removed:
* The ``funcargnames`` read-only property of ``FixtureRequest``, ``Metafunc``, and ``Function`` classes. Use ``fixturenames`` attribute.
* ``@pytest.fixture`` no longer supports positional arguments, pass all arguments by keyword instead.
* Direct construction of ``Node`` subclasses now raise an error, use ``from_parent`` instead.
* The default value for ``junit_family`` has changed to ``xunit2``. If you require the old format, add ``junit_family=xunit1`` to your configuration file.
* The ``TerminalReporter`` no longer has a ``writer`` attribute. Plugin authors may use the public functions of the ``TerminalReporter`` instead of accessing the ``TerminalWriter`` object directly.
* The ``--result-log`` option has been removed. Users are recommended to use the `pytest-reportlog <https://github.com/pytest-dev/pytest-reportlog>`__ plugin instead.
For more information consult
`Deprecations and Removals <https://docs.pytest.org/en/stable/deprecations.html>`__ in the docs.
Deprecations
------------
- `#6981 <https://github.com/pytest-dev/pytest/issues/6981>`_: The ``pytest.collect`` module is deprecated: all its names can be imported from ``pytest`` directly.
- `#7097 <https://github.com/pytest-dev/pytest/issues/7097>`_: The ``pytest._fillfuncargs`` function is deprecated. This function was kept
for backward compatibility with an older plugin.
It's functionality is not meant to be used directly, but if you must replace
it, use `function._request._fillfixtures()` instead, though note this is not
a public API and may break in the future.
- `#7210 <https://github.com/pytest-dev/pytest/issues/7210>`_: The special ``-k '-expr'`` syntax to ``-k`` is deprecated. Use ``-k 'not expr'``
instead.
The special ``-k 'expr:'`` syntax to ``-k`` is deprecated. Please open an issue
if you use this and want a replacement.
- `#7255 <https://github.com/pytest-dev/pytest/issues/7255>`_: The :func:`pytest_warning_captured <_pytest.hookspec.pytest_warning_captured>` hook is deprecated in favor
of :func:`pytest_warning_recorded <_pytest.hookspec.pytest_warning_recorded>`, and will be removed in a future version.
- `#7648 <https://github.com/pytest-dev/pytest/issues/7648>`_: The ``gethookproxy()`` and ``isinitpath()`` methods of ``FSCollector`` and ``Package`` are deprecated;
use ``self.session.gethookproxy()`` and ``self.session.isinitpath()`` instead.
This should work on all pytest versions.
Features
--------
- `#7667 <https://github.com/pytest-dev/pytest/issues/7667>`_: New ``--durations-min`` command-line flag controls the minimal duration for inclusion in the slowest list of tests shown by ``--durations``. Previously this was hard-coded to ``0.005s``.
Improvements
------------
- `#6681 <https://github.com/pytest-dev/pytest/issues/6681>`_: Internal pytest warnings issued during the early stages of initialization are now properly handled and can filtered through :confval:`filterwarnings` or ``--pythonwarnings/-W``.
This also fixes a number of long standing issues: `#2891 <https://github.com/pytest-dev/pytest/issues/2891>`__, `#7620 <https://github.com/pytest-dev/pytest/issues/7620>`__, `#7426 <https://github.com/pytest-dev/pytest/issues/7426>`__.
- `#7572 <https://github.com/pytest-dev/pytest/issues/7572>`_: When a plugin listed in ``required_plugins`` is missing or an unknown config key is used with ``--strict-config``, a simple error message is now shown instead of a stacktrace.
- `#7685 <https://github.com/pytest-dev/pytest/issues/7685>`_: Added two new attributes :attr:`rootpath <_pytest.config.Config.rootpath>` and :attr:`inipath <_pytest.config.Config.inipath>` to :class:`Config <_pytest.config.Config>`.
These attributes are :class:`pathlib.Path` versions of the existing :attr:`rootdir <_pytest.config.Config.rootdir>` and :attr:`inifile <_pytest.config.Config.inifile>` attributes,
and should be preferred over them when possible.
- `#7780 <https://github.com/pytest-dev/pytest/issues/7780>`_: Public classes which are not designed to be inherited from are now marked `@final <https://docs.python.org/3/library/typing.html#typing.final>`_.
Code which inherits from these classes will trigger a type-checking (e.g. mypy) error, but will still work in runtime.
Currently the ``final`` designation does not appear in the API Reference but hopefully will in the future.
Bug Fixes
---------
- `#1953 <https://github.com/pytest-dev/pytest/issues/1953>`_: Fixed error when overwriting a parametrized fixture, while also reusing the super fixture value.
.. code-block:: python
# conftest.py
import pytest
@pytest.fixture(params=[1, 2])
def foo(request):
return request.param
# test_foo.py
import pytest
@pytest.fixture
def foo(foo):
return foo * 2
- `#4984 <https://github.com/pytest-dev/pytest/issues/4984>`_: Fixed an internal error crash with ``IndexError: list index out of range`` when
collecting a module which starts with a decorated function, the decorator
raises, and assertion rewriting is enabled.
- `#7591 <https://github.com/pytest-dev/pytest/issues/7591>`_: pylint shouldn't complain anymore about unimplemented abstract methods when inheriting from :ref:`File <non-python tests>`.
- `#7628 <https://github.com/pytest-dev/pytest/issues/7628>`_: Fixed test collection when a full path without a drive letter was passed to pytest on Windows (for example ``\projects\tests\test.py`` instead of ``c:\projects\tests\pytest.py``).
- `#7638 <https://github.com/pytest-dev/pytest/issues/7638>`_: Fix handling of command-line options that appear as paths but trigger an OS-level syntax error on Windows, such as the options used internally by ``pytest-xdist``.
- `#7742 <https://github.com/pytest-dev/pytest/issues/7742>`_: Fixed INTERNALERROR when accessing locals / globals with faulty ``exec``.
Improved Documentation
----------------------
- `#1477 <https://github.com/pytest-dev/pytest/issues/1477>`_: Removed faq.rst and its reference in contents.rst.
Trivial/Internal Changes
------------------------
- `#7536 <https://github.com/pytest-dev/pytest/issues/7536>`_: The internal ``junitxml`` plugin has rewritten to use ``xml.etree.ElementTree``.
The order of attributes in XML elements might differ. Some unneeded escaping is
no longer performed.
- `#7587 <https://github.com/pytest-dev/pytest/issues/7587>`_: The dependency on the ``more-itertools`` package has been removed.
- `#7631 <https://github.com/pytest-dev/pytest/issues/7631>`_: The result type of :meth:`capfd.readouterr() <_pytest.capture.CaptureFixture.readouterr>` (and similar) is no longer a namedtuple,
but should behave like one in all respects. This was done for technical reasons.
- `#7671 <https://github.com/pytest-dev/pytest/issues/7671>`_: When collecting tests, pytest finds test classes and functions by examining the
attributes of python objects (modules, classes and instances). To speed up this
process, pytest now ignores builtin attributes (like ``__class__``,
``__delattr__`` and ``__new__``) without consulting the :confval:`python_classes` and
:confval:`python_functions` configuration options and without passing them to plugins
using the :func:`pytest_pycollect_makeitem <_pytest.hookspec.pytest_pycollect_makeitem>` hook.
pytest 6.0.2 (2020-09-04)
=========================
@ -1682,6 +1873,44 @@ Improved Documentation
- `#5416 <https://github.com/pytest-dev/pytest/issues/5416>`_: Fix PytestUnknownMarkWarning in run/skip example.
pytest 4.6.11 (2020-06-04)
==========================
Bug Fixes
---------
- `#6334 <https://github.com/pytest-dev/pytest/issues/6334>`_: Fix summary entries appearing twice when ``f/F`` and ``s/S`` report chars were used at the same time in the ``-r`` command-line option (for example ``-rFf``).
The upper case variants were never documented and the preferred form should be the lower case.
- `#7310 <https://github.com/pytest-dev/pytest/issues/7310>`_: Fix ``UnboundLocalError: local variable 'letter' referenced before
assignment`` in ``_pytest.terminal.pytest_report_teststatus()``
when plugins return report objects in an unconventional state.
This was making ``pytest_report_teststatus()`` skip
entering if-block branches that declare the ``letter`` variable.
The fix was to set the initial value of the ``letter`` before
the if-block cascade so that it always has a value.
pytest 4.6.10 (2020-05-08)
==========================
Features
--------
- `#6870 <https://github.com/pytest-dev/pytest/issues/6870>`_: New ``Config.invocation_args`` attribute containing the unchanged arguments passed to ``pytest.main()``.
Remark: while this is technically a new feature and according to our `policy <https://docs.pytest.org/en/latest/py27-py34-deprecation.html#what-goes-into-4-6-x-releases>`_ it should not have been backported, we have opened an exception in this particular case because it fixes a serious interaction with ``pytest-xdist``, so it can also be considered a bugfix.
Trivial/Internal Changes
------------------------
- `#6404 <https://github.com/pytest-dev/pytest/issues/6404>`_: Remove usage of ``parser`` module, deprecated in Python 3.9.
pytest 4.6.9 (2020-01-04)
=========================

View File

@ -28,7 +28,7 @@ Install ``pytest``
.. code-block:: bash
$ pytest --version
pytest 6.0.2
pytest 6.1.2
.. _`simpletest`:

View File

@ -816,6 +816,13 @@ Function
:members:
:show-inheritance:
FunctionDefinition
~~~~~~~~~~~~~~~~~~
.. autoclass:: _pytest.python.FunctionDefinition()
:members:
:show-inheritance:
Item
~~~~
@ -1236,12 +1243,13 @@ passed multiple times. The expected format is ``name=value``. For example::
.. confval:: junit_family
.. versionadded:: 4.2
.. versionchanged:: 6.1
Default changed to ``xunit2``.
Configures the format of the generated JUnit XML file. The possible options are:
* ``xunit1`` (or ``legacy``): produces old style output, compatible with the xunit 1.0 format. **This is the default**.
* ``xunit2``: produces `xunit 2.0 style output <https://github.com/jenkinsci/xunit-plugin/blob/xunit-2.3.2/src/main/resources/org/jenkinsci/plugins/xunit/types/model/xsd/junit-10.xsd>`__,
which should be more compatible with latest Jenkins versions.
* ``xunit1`` (or ``legacy``): produces old style output, compatible with the xunit 1.0 format.
* ``xunit2``: produces `xunit 2.0 style output <https://github.com/jenkinsci/xunit-plugin/blob/xunit-2.3.2/src/main/resources/org/jenkinsci/plugins/xunit/types/model/xsd/junit-10.xsd>`__, which should be more compatible with latest Jenkins versions. **This is the default**.
.. code-block:: ini

View File

@ -33,26 +33,34 @@ Plugin discovery order at tool startup
``pytest`` loads plugin modules at tool startup in the following way:
* by loading all builtin plugins
1. by scanning the command line for the ``-p no:name`` option
and *blocking* that plugin from being loaded (even builtin plugins can
be blocked this way). This happens before normal command-line parsing.
* by loading all plugins registered through `setuptools entry points`_.
2. by loading all builtin plugins.
* by pre-scanning the command line for the ``-p name`` option
and loading the specified plugin before actual command line parsing.
3. by scanning the command line for the ``-p name`` option
and loading the specified plugin. This happens before normal command-line parsing.
* by loading all :file:`conftest.py` files as inferred by the command line
invocation:
4. by loading all plugins registered through `setuptools entry points`_.
- if no test paths are specified use current dir as a test path
- if exists, load ``conftest.py`` and ``test*/conftest.py`` relative
to the directory part of the first test path.
5. by loading all plugins specified through the :envvar:`PYTEST_PLUGINS` environment variable.
Note that pytest does not find ``conftest.py`` files in deeper nested
sub directories at tool startup. It is usually a good idea to keep
your ``conftest.py`` file in the top level test or project root directory.
6. by loading all :file:`conftest.py` files as inferred by the command line
invocation:
* by recursively loading all plugins specified by the
:globalvar:`pytest_plugins` variable in ``conftest.py`` files
- if no test paths are specified, use the current dir as a test path
- if exists, load ``conftest.py`` and ``test*/conftest.py`` relative
to the directory part of the first test path. After the ``conftest.py``
file is loaded, load all plugins specified in its
:globalvar:`pytest_plugins` variable if present.
Note that pytest does not find ``conftest.py`` files in deeper nested
sub directories at tool startup. It is usually a good idea to keep
your ``conftest.py`` file in the top level test or project root directory.
7. by recursively loading all plugins specified by the
:globalvar:`pytest_plugins` variable in ``conftest.py`` files.
.. _`pytest/plugin`: http://bitbucket.org/pytest-dev/pytest/src/tip/pytest/plugin/

View File

@ -29,6 +29,7 @@ from _pytest.config.argparsing import Parser
from _pytest.fixtures import FixtureRequest
from _pytest.main import Session
from _pytest.python import Module
from _pytest.python import Package
from _pytest.reports import TestReport
@ -233,7 +234,10 @@ class LFPluginCollSkipfiles:
def pytest_make_collect_report(
self, collector: nodes.Collector
) -> Optional[CollectReport]:
if isinstance(collector, Module):
# Packages are Modules, but _last_failed_paths only contains
# test-bearing paths and doesn't try to include the paths of their
# packages, so don't filter them.
if isinstance(collector, Module) and not isinstance(collector, Package):
if Path(str(collector.fspath)) not in self.lfplugin._last_failed_paths:
self.lfplugin._skipped_files += 1

View File

@ -1,4 +1,3 @@
import itertools
import os
from typing import Dict
from typing import Iterable
@ -100,7 +99,7 @@ def locate_config(
args = [Path.cwd()]
for arg in args:
argpath = absolutepath(arg)
for base in itertools.chain((argpath,), reversed(argpath.parents)):
for base in (argpath, *argpath.parents):
for config_name in config_names:
p = base / config_name
if p.is_file():
@ -184,9 +183,7 @@ def determine_setup(
ancestor = get_common_ancestor(dirs)
rootdir, inipath, inicfg = locate_config([ancestor])
if rootdir is None and rootdir_cmd_arg is None:
for possible_rootdir in itertools.chain(
(ancestor,), reversed(ancestor.parents)
):
for possible_rootdir in (ancestor, *ancestor.parents):
if (possible_rootdir / "setup.py").is_file():
rootdir = possible_rootdir
break

View File

@ -20,9 +20,10 @@ DEPRECATED_EXTERNAL_PLUGINS = {
}
FILLFUNCARGS = PytestDeprecationWarning(
"The `_fillfuncargs` function is deprecated, use "
"function._request._fillfixtures() instead if you cannot avoid reaching into internals."
FILLFUNCARGS = UnformattedWarning(
PytestDeprecationWarning,
"{name} is deprecated, use "
"function._request._fillfixtures() instead if you cannot avoid reaching into internals.",
)
PYTEST_COLLECT_MODULE = UnformattedWarning(

View File

@ -339,9 +339,22 @@ def reorder_items_atscope(
return items_done
def _fillfuncargs(function: "Function") -> None:
"""Fill missing fixtures for a test function, old public API (deprecated)."""
warnings.warn(FILLFUNCARGS.format(name="pytest._fillfuncargs()"), stacklevel=2)
_fill_fixtures_impl(function)
def fillfixtures(function: "Function") -> None:
"""Fill missing funcargs for a test function."""
warnings.warn(FILLFUNCARGS, stacklevel=2)
"""Fill missing fixtures for a test function (deprecated)."""
warnings.warn(
FILLFUNCARGS.format(name="_pytest.fixtures.fillfixtures()"), stacklevel=2
)
_fill_fixtures_impl(function)
def _fill_fixtures_impl(function: "Function") -> None:
"""Internal implementation to fill fixtures on the given function object."""
try:
request = function._request
except AttributeError:

View File

@ -9,6 +9,10 @@ import sys
import uuid
import warnings
from enum import Enum
from errno import EBADF
from errno import ELOOP
from errno import ENOENT
from errno import ENOTDIR
from functools import partial
from os.path import expanduser
from os.path import expandvars
@ -38,11 +42,29 @@ else:
__all__ = ["Path", "PurePath"]
LOCK_TIMEOUT = 60 * 60 * 3
LOCK_TIMEOUT = 60 * 60 * 24 * 3
_AnyPurePath = TypeVar("_AnyPurePath", bound=PurePath)
# The following function, variables and comments were
# copied from cpython 3.9 Lib/pathlib.py file.
# EBADF - guard against macOS `stat` throwing EBADF
_IGNORED_ERRORS = (ENOENT, ENOTDIR, EBADF, ELOOP)
_IGNORED_WINERRORS = (
21, # ERROR_NOT_READY - drive exists but is not accessible
1921, # ERROR_CANT_RESOLVE_FILENAME - fix for broken symlink pointing to itself
)
def _ignore_error(exception):
return (
getattr(exception, "errno", None) in _IGNORED_ERRORS
or getattr(exception, "winerror", None) in _IGNORED_WINERRORS
)
def get_lock_path(path: _AnyPurePath) -> _AnyPurePath:
return path.joinpath(".lock")
@ -563,10 +585,25 @@ def visit(
Entries at each directory level are sorted.
"""
entries = sorted(os.scandir(path), key=lambda entry: entry.name)
# Skip entries with symlink loops and other brokenness, so the caller doesn't
# have to deal with it.
entries = []
for entry in os.scandir(path):
try:
entry.is_file()
except OSError as err:
if _ignore_error(err):
continue
raise
entries.append(entry)
entries.sort(key=lambda entry: entry.name)
yield from entries
for entry in entries:
if entry.is_dir(follow_symlinks=False) and recurse(entry):
if entry.is_dir() and recurse(entry):
yield from visit(entry.path, recurse)

View File

@ -943,6 +943,7 @@ class Metafunc:
cls=None,
module=None,
) -> None:
#: Access to the underlying :class:`_pytest.python.FunctionDefinition`.
self.definition = definition
#: Access to the :class:`_pytest.config.Config` object for the test session.
@ -1664,10 +1665,12 @@ class Function(PyobjMixin, nodes.Item):
class FunctionDefinition(Function):
"""Internal hack until we get actual definition nodes instead of the
crappy metafunc hack."""
"""
This class is a step gap solution until we evolve to have actual function definition nodes
and manage to get rid of ``metafunc``.
"""
def runtest(self) -> None:
raise RuntimeError("function definitions are not supposed to be used")
raise RuntimeError("function definitions are not supposed to be run as tests")
setup = runtest

View File

@ -718,10 +718,10 @@ class TerminalReporter:
if config.inipath:
line += ", configfile: " + bestrelpath(config.rootpath, config.inipath)
testpaths = config.getini("testpaths")
testpaths = config.getini("testpaths") # type: List[str]
if testpaths and config.args == testpaths:
rel_paths = [bestrelpath(config.rootpath, x) for x in testpaths]
line += ", testpaths: {}".format(", ".join(rel_paths))
line += ", testpaths: {}".format(", ".join(testpaths))
result = [line]
plugininfo = config.pluginmanager.list_plugin_distinfo()

View File

@ -11,7 +11,7 @@ from _pytest.config import hookspec
from _pytest.config import main
from _pytest.config import UsageError
from _pytest.debugging import pytestPDB as __pytestPDB
from _pytest.fixtures import fillfixtures as _fillfuncargs
from _pytest.fixtures import _fillfuncargs
from _pytest.fixtures import fixture
from _pytest.fixtures import FixtureLookupError
from _pytest.fixtures import yield_fixture

View File

@ -1,3 +1,4 @@
import re
import warnings
from unittest import mock
@ -26,11 +27,27 @@ def test_external_plugins_integrated(testdir, plugin):
def test_fillfuncargs_is_deprecated() -> None:
with pytest.warns(
pytest.PytestDeprecationWarning,
match="The `_fillfuncargs` function is deprecated",
match=re.escape(
"pytest._fillfuncargs() is deprecated, use "
"function._request._fillfixtures() instead if you cannot avoid reaching into internals."
),
):
pytest._fillfuncargs(mock.Mock())
def test_fillfixtures_is_deprecated() -> None:
import _pytest.fixtures
with pytest.warns(
pytest.PytestDeprecationWarning,
match=re.escape(
"_pytest.fixtures.fillfixtures() is deprecated, use "
"function._request._fillfixtures() instead if you cannot avoid reaching into internals."
),
):
_pytest.fixtures.fillfixtures(mock.Mock())
def test_minus_k_dash_is_deprecated(testdir) -> None:
threepass = testdir.makepyfile(
test_threepass="""

View File

@ -87,7 +87,7 @@ def test_getfuncargnames_staticmethod_partial():
class TestFillFixtures:
def test_fillfuncargs_exposed(self):
# used by oejskit, kept for compatibility
assert pytest._fillfuncargs == fixtures.fillfixtures
assert pytest._fillfuncargs == fixtures._fillfuncargs
def test_funcarg_lookupfails(self, testdir):
testdir.copy_example()

View File

@ -984,6 +984,36 @@ class TestLastFailed:
)
assert result.ret == 0
def test_packages(self, testdir: Testdir) -> None:
"""Regression test for #7758.
The particular issue here was that Package nodes were included in the
filtering, being themselves Modules for the __init__.py, even if they
had failed Modules in them.
The tests includes a test in an __init__.py file just to make sure the
fix doesn't somehow regress that, it is not critical for the issue.
"""
testdir.makepyfile(
**{
"__init__.py": "",
"a/__init__.py": "def test_a_init(): assert False",
"a/test_one.py": "def test_1(): assert False",
"b/__init__.py": "",
"b/test_two.py": "def test_2(): assert False",
},
)
testdir.makeini(
"""
[pytest]
python_files = *.py
"""
)
result = testdir.runpytest()
result.assert_outcomes(failed=3)
result = testdir.runpytest("--lf")
result.assert_outcomes(failed=3)
class TestNewFirst:
def test_newfirst_usecase(self, testdir):

View File

@ -1178,6 +1178,15 @@ def test_collect_symlink_out_of_tree(testdir):
assert result.ret == 0
def test_collect_symlink_dir(testdir: Testdir) -> None:
"""A symlinked directory is collected."""
dir = testdir.mkdir("dir")
dir.join("test_it.py").write("def test_it(): pass")
symlink_or_skip(dir, testdir.tmpdir.join("symlink_dir"))
result = testdir.runpytest()
result.assert_outcomes(passed=2)
def test_collectignore_via_conftest(testdir):
"""collect_ignore in parent conftest skips importing child (issue #4592)."""
tests = testdir.mkpydir("tests")
@ -1407,3 +1416,17 @@ def test_does_not_crash_on_error_from_decorated_function(testdir: Testdir) -> No
result = testdir.runpytest()
# Not INTERNAL_ERROR
assert result.ret == ExitCode.INTERRUPTED
def test_does_not_crash_on_recursive_symlink(testdir: Testdir) -> None:
"""Regression test for an issue around recursive symlinks (#7951)."""
symlink_or_skip("recursive", testdir.tmpdir.join("recursive"))
testdir.makepyfile(
"""
def test_foo(): assert True
"""
)
result = testdir.runpytest()
assert result.ret == ExitCode.OK
assert result.parseoutcomes() == {"passed": 1}

View File

@ -1375,6 +1375,21 @@ class TestRootdir:
assert rootpath == tmp_path
assert inipath is None
def test_with_config_also_in_parent_directory(
self, tmp_path: Path, monkeypatch: MonkeyPatch
) -> None:
"""Regression test for #7807."""
(tmp_path / "setup.cfg").write_text("[tool:pytest]\n", "utf-8")
(tmp_path / "myproject").mkdir()
(tmp_path / "myproject" / "setup.cfg").write_text("[tool:pytest]\n", "utf-8")
(tmp_path / "myproject" / "tests").mkdir()
monkeypatch.chdir(tmp_path / "myproject")
rootpath, inipath, _ = determine_setup(None, ["tests/"])
assert rootpath == tmp_path / "myproject"
assert inipath == tmp_path / "myproject" / "setup.cfg"
class TestOverrideIniArgs:
@pytest.mark.parametrize("name", "setup.cfg tox.ini pytest.ini".split())

View File

@ -17,6 +17,8 @@ from _pytest.pathlib import ImportPathMismatchError
from _pytest.pathlib import maybe_delete_a_numbered_dir
from _pytest.pathlib import Path
from _pytest.pathlib import resolve_package_path
from _pytest.pathlib import symlink_or_skip
from _pytest.pathlib import visit
class TestFNMatcherPort:
@ -401,3 +403,13 @@ def test_commonpath() -> None:
assert commonpath(subpath, path) == path
assert commonpath(Path(str(path) + "suffix"), path) == path.parent
assert commonpath(path, path.parent.parent) == path.parent.parent
def test_visit_ignores_errors(tmpdir: py.path.local) -> None:
symlink_or_skip("recursive", tmpdir.join("recursive"))
tmpdir.join("foo").write_binary(b"")
tmpdir.join("bar").write_binary(b"")
assert [
entry.name for entry in visit(str(tmpdir), recurse=lambda entry: False)
] == ["bar", "foo"]

View File

@ -18,6 +18,7 @@ import pytest
from _pytest._io.wcwidth import wcswidth
from _pytest.config import Config
from _pytest.config import ExitCode
from _pytest.monkeypatch import MonkeyPatch
from _pytest.pathlib import Path
from _pytest.pytester import Testdir
from _pytest.reports import BaseReport
@ -749,6 +750,29 @@ class TestTerminalFunctional:
result = testdir.runpytest("tests")
result.stdout.fnmatch_lines(["rootdir: *test_header0, configfile: tox.ini"])
def test_header_absolute_testpath(
self, testdir: Testdir, monkeypatch: MonkeyPatch
) -> None:
"""Regresstion test for #7814."""
tests = testdir.tmpdir.join("tests")
tests.ensure_dir()
testdir.makepyprojecttoml(
"""
[tool.pytest.ini_options]
testpaths = ['{}']
""".format(
tests
)
)
result = testdir.runpytest()
result.stdout.fnmatch_lines(
[
"rootdir: *absolute_testpath0, configfile: pyproject.toml, testpaths: {}".format(
tests
)
]
)
def test_no_header(self, testdir):
testdir.tmpdir.join("tests").ensure_dir()
testdir.tmpdir.join("gui").ensure_dir()