Merge pull request #11377 from pytest-dev/release-7.4.1

Prepare release 7.4.1
This commit is contained in:
Bruno Oliveira 2023-09-02 12:41:32 -03:00 committed by GitHub
commit 82eb86f707
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 108 additions and 55 deletions

View File

@ -1,45 +1,59 @@
name: deploy name: deploy
on: on:
push: workflow_dispatch:
tags: inputs:
# These tags are protected, see: version:
# https://github.com/pytest-dev/pytest/settings/tag_protection description: 'Release version'
- "[0-9]+.[0-9]+.[0-9]+" required: true
- "[0-9]+.[0-9]+.[0-9]+rc[0-9]+" default: '1.2.3'
# Set permissions at the job level. # Set permissions at the job level.
permissions: {} permissions: {}
jobs: jobs:
build: package:
runs-on: ubuntu-latest runs-on: ubuntu-latest
env:
SETUPTOOLS_SCM_PRETEND_VERSION: ${{ github.event.inputs.version }}
timeout-minutes: 10 timeout-minutes: 10
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with: with:
fetch-depth: 0 fetch-depth: 0
persist-credentials: false persist-credentials: false
- name: Build and Check Package - name: Build and Check Package
uses: hynek/build-and-inspect-python-package@v1.5 uses: hynek/build-and-inspect-python-package@v1.5
deploy: deploy:
if: github.repository == 'pytest-dev/pytest' if: github.repository == 'pytest-dev/pytest'
needs: [build] needs: [package]
runs-on: ubuntu-latest runs-on: ubuntu-latest
environment: deploy
timeout-minutes: 30 timeout-minutes: 30
permissions: permissions:
id-token: write id-token: write
steps: steps:
- uses: actions/checkout@v3
- name: Download Package - name: Download Package
uses: actions/download-artifact@v3 uses: actions/download-artifact@v3
with: with:
name: Packages name: Packages
path: dist path: dist
- name: Publish package to PyPI - name: Publish package to PyPI
uses: pypa/gh-action-pypi-publish@v1.8.5 uses: pypa/gh-action-pypi-publish@v1.8.5
- name: Push tag
run: |
git config user.name "pytest bot"
git config user.email "pytestbot@gmail.com"
git tag --annotate --message=v${{ github.event.inputs.version }} v${{ github.event.inputs.version }} ${{ github.sha }}
git push origin v${{ github.event.inputs.version }}
release-notes: release-notes:
# todo: generate the content in the build job # todo: generate the content in the build job
@ -55,11 +69,11 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
persist-credentials: false persist-credentials: false
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v4
with: with:
python-version: "3.7" python-version: "3.10"
- name: Install tox - name: Install tox
run: | run: |

View File

@ -27,7 +27,19 @@ concurrency:
permissions: {} permissions: {}
jobs: jobs:
package:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
persist-credentials: false
- name: Build and Check Package
uses: hynek/build-and-inspect-python-package@v1.5
build: build:
needs: [package]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
timeout-minutes: 45 timeout-minutes: 45
permissions: permissions:
@ -60,7 +72,6 @@ jobs:
"macos-py310", "macos-py310",
"macos-py312", "macos-py312",
"docs",
"doctesting", "doctesting",
"plugins", "plugins",
] ]
@ -159,10 +170,6 @@ jobs:
os: ubuntu-latest os: ubuntu-latest
tox_env: "plugins" tox_env: "plugins"
- name: "docs"
python: "3.7"
os: ubuntu-latest
tox_env: "docs"
- name: "doctesting" - name: "doctesting"
python: "3.7" python: "3.7"
os: ubuntu-latest os: ubuntu-latest
@ -175,6 +182,12 @@ jobs:
fetch-depth: 0 fetch-depth: 0
persist-credentials: false persist-credentials: false
- name: Download Package
uses: actions/download-artifact@v3
with:
name: Packages
path: dist
- name: Set up Python ${{ matrix.python }} - name: Set up Python ${{ matrix.python }}
uses: actions/setup-python@v4 uses: actions/setup-python@v4
with: with:
@ -188,11 +201,13 @@ jobs:
- name: Test without coverage - name: Test without coverage
if: "! matrix.use_coverage" if: "! matrix.use_coverage"
run: "tox -e ${{ matrix.tox_env }}" shell: bash
run: tox run -e ${{ matrix.tox_env }} --installpkg `find dist/*.tar.gz`
- name: Test with coverage - name: Test with coverage
if: "matrix.use_coverage" if: "matrix.use_coverage"
run: "tox -e ${{ matrix.tox_env }}-coverage" shell: bash
run: tox run -e ${{ matrix.tox_env }}-coverage --installpkg `find dist/*.tar.gz`
- name: Generate coverage report - name: Generate coverage report
if: "matrix.use_coverage" if: "matrix.use_coverage"
@ -206,10 +221,3 @@ jobs:
fail_ci_if_error: true fail_ci_if_error: true
files: ./coverage.xml files: ./coverage.xml
verbose: true verbose: true
check-package:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build and Check Package
uses: hynek/build-and-inspect-python-package@v1.5

View File

@ -133,14 +133,11 @@ Releasing
Both automatic and manual processes described above follow the same steps from this point onward. Both automatic and manual processes described above follow the same steps from this point onward.
#. After all tests pass and the PR has been approved, tag the release commit #. After all tests pass and the PR has been approved, trigger the ``deploy`` job
in the ``release-MAJOR.MINOR.PATCH`` branch and push it. This will publish to PyPI:: in https://github.com/pytest-dev/pytest/actions/workflows/deploy.yml.
git fetch upstream This job will require approval from ``pytest-dev/core``, after which it will publish to PyPI
git tag MAJOR.MINOR.PATCH upstream/release-MAJOR.MINOR.PATCH and tag the repository.
git push upstream MAJOR.MINOR.PATCH
Wait for the deploy to complete, then make sure it is `available on PyPI <https://pypi.org/project/pytest>`_.
#. Merge the PR. **Make sure it's not squash-merged**, so that the tagged commit ends up in the main branch. #. Merge the PR. **Make sure it's not squash-merged**, so that the tagged commit ends up in the main branch.

View File

@ -1,2 +0,0 @@
Fixed bug where fake intermediate modules generated by ``--import-mode=importlib`` would not include the
child modules as attributes of the parent modules.

View File

@ -1 +0,0 @@
Fixed error assertion handling in :func:`pytest.approx` when ``None`` is an expected or received value when comparing dictionaries.

View File

@ -1,2 +0,0 @@
Fixed issue when using ``--import-mode=importlib`` together with ``--doctest-modules`` that caused modules
to be imported more than once, causing problems with modules that have import side effects.

View File

@ -6,6 +6,7 @@ Release announcements
:maxdepth: 2 :maxdepth: 2
release-7.4.1
release-7.4.0 release-7.4.0
release-7.3.2 release-7.3.2
release-7.3.1 release-7.3.1

View File

@ -0,0 +1,20 @@
pytest-7.4.1
=======================================
pytest 7.4.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:
* Bruno Oliveira
* Florian Bruhin
* Ran Benita
Happy testing,
The pytest Development Team

View File

@ -22,7 +22,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
cachedir: .pytest_cache cachedir: .pytest_cache
rootdir: /home/sweet/project rootdir: /home/sweet/project
collected 0 items collected 0 items
cache -- .../_pytest/cacheprovider.py:528 cache -- .../_pytest/cacheprovider.py:532
Return a cache object that can persist state between testing sessions. Return a cache object that can persist state between testing sessions.
cache.get(key, default) cache.get(key, default)

View File

@ -28,6 +28,23 @@ with advance notice in the **Deprecations** section of releases.
.. towncrier release notes start .. towncrier release notes start
pytest 7.4.1 (2023-09-02)
=========================
Bug Fixes
---------
- `#10337 <https://github.com/pytest-dev/pytest/issues/10337>`_: Fixed bug where fake intermediate modules generated by ``--import-mode=importlib`` would not include the
child modules as attributes of the parent modules.
- `#10702 <https://github.com/pytest-dev/pytest/issues/10702>`_: Fixed error assertion handling in :func:`pytest.approx` when ``None`` is an expected or received value when comparing dictionaries.
- `#10811 <https://github.com/pytest-dev/pytest/issues/10811>`_: Fixed issue when using ``--import-mode=importlib`` together with ``--doctest-modules`` that caused modules
to be imported more than once, causing problems with modules that have import side effects.
pytest 7.4.0 (2023-06-23) pytest 7.4.0 (2023-06-23)
========================= =========================

View File

@ -554,13 +554,13 @@ Here is a nice run of several failures and how ``pytest`` presents things:
E AssertionError: assert False E AssertionError: assert False
E + where False = <built-in method startswith of str object at 0xdeadbeef0027>('456') E + where False = <built-in method startswith of str object at 0xdeadbeef0027>('456')
E + where <built-in method startswith of str object at 0xdeadbeef0027> = '123'.startswith E + where <built-in method startswith of str object at 0xdeadbeef0027> = '123'.startswith
E + where '123' = <function TestMoreErrors.test_startswith_nested.<locals>.f at 0xdeadbeef0029>() E + where '123' = <function TestMoreErrors.test_startswith_nested.<locals>.f at 0xdeadbeef0006>()
E + and '456' = <function TestMoreErrors.test_startswith_nested.<locals>.g at 0xdeadbeef002a>() E + and '456' = <function TestMoreErrors.test_startswith_nested.<locals>.g at 0xdeadbeef0029>()
failure_demo.py:235: AssertionError failure_demo.py:235: AssertionError
_____________________ TestMoreErrors.test_global_func ______________________ _____________________ TestMoreErrors.test_global_func ______________________
self = <failure_demo.TestMoreErrors object at 0xdeadbeef002b> self = <failure_demo.TestMoreErrors object at 0xdeadbeef002a>
def test_global_func(self): def test_global_func(self):
> assert isinstance(globf(42), float) > assert isinstance(globf(42), float)
@ -571,18 +571,18 @@ Here is a nice run of several failures and how ``pytest`` presents things:
failure_demo.py:238: AssertionError failure_demo.py:238: AssertionError
_______________________ TestMoreErrors.test_instance _______________________ _______________________ TestMoreErrors.test_instance _______________________
self = <failure_demo.TestMoreErrors object at 0xdeadbeef002c> self = <failure_demo.TestMoreErrors object at 0xdeadbeef002b>
def test_instance(self): def test_instance(self):
self.x = 6 * 7 self.x = 6 * 7
> assert self.x != 42 > assert self.x != 42
E assert 42 != 42 E assert 42 != 42
E + where 42 = <failure_demo.TestMoreErrors object at 0xdeadbeef002c>.x E + where 42 = <failure_demo.TestMoreErrors object at 0xdeadbeef002b>.x
failure_demo.py:242: AssertionError failure_demo.py:242: AssertionError
_______________________ TestMoreErrors.test_compare ________________________ _______________________ TestMoreErrors.test_compare ________________________
self = <failure_demo.TestMoreErrors object at 0xdeadbeef002d> self = <failure_demo.TestMoreErrors object at 0xdeadbeef002c>
def test_compare(self): def test_compare(self):
> assert globf(10) < 5 > assert globf(10) < 5
@ -592,7 +592,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
failure_demo.py:245: AssertionError failure_demo.py:245: AssertionError
_____________________ TestMoreErrors.test_try_finally ______________________ _____________________ TestMoreErrors.test_try_finally ______________________
self = <failure_demo.TestMoreErrors object at 0xdeadbeef002e> self = <failure_demo.TestMoreErrors object at 0xdeadbeef002d>
def test_try_finally(self): def test_try_finally(self):
x = 1 x = 1
@ -603,7 +603,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
failure_demo.py:250: AssertionError failure_demo.py:250: AssertionError
___________________ TestCustomAssertMsg.test_single_line ___________________ ___________________ TestCustomAssertMsg.test_single_line ___________________
self = <failure_demo.TestCustomAssertMsg object at 0xdeadbeef002f> self = <failure_demo.TestCustomAssertMsg object at 0xdeadbeef002e>
def test_single_line(self): def test_single_line(self):
class A: class A:
@ -618,7 +618,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
failure_demo.py:261: AssertionError failure_demo.py:261: AssertionError
____________________ TestCustomAssertMsg.test_multiline ____________________ ____________________ TestCustomAssertMsg.test_multiline ____________________
self = <failure_demo.TestCustomAssertMsg object at 0xdeadbeef0030> self = <failure_demo.TestCustomAssertMsg object at 0xdeadbeef002f>
def test_multiline(self): def test_multiline(self):
class A: class A:
@ -637,7 +637,7 @@ Here is a nice run of several failures and how ``pytest`` presents things:
failure_demo.py:268: AssertionError failure_demo.py:268: AssertionError
___________________ TestCustomAssertMsg.test_custom_repr ___________________ ___________________ TestCustomAssertMsg.test_custom_repr ___________________
self = <failure_demo.TestCustomAssertMsg object at 0xdeadbeef0031> self = <failure_demo.TestCustomAssertMsg object at 0xdeadbeef0030>
def test_custom_repr(self): def test_custom_repr(self):
class JSON: class JSON:

View File

@ -22,7 +22,7 @@ Install ``pytest``
.. code-block:: bash .. code-block:: bash
$ pytest --version $ pytest --version
pytest 7.4.0 pytest 7.4.1
.. _`simpletest`: .. _`simpletest`:

View File

@ -51,8 +51,8 @@ Running this would result in a passed test except for the last
d = tmp_path / "sub" d = tmp_path / "sub"
d.mkdir() d.mkdir()
p = d / "hello.txt" p = d / "hello.txt"
p.write_text(CONTENT) p.write_text(CONTENT, encoding="utf-8")
assert p.read_text() == CONTENT assert p.read_text(encoding="utf-8") == CONTENT
assert len(list(tmp_path.iterdir())) == 1 assert len(list(tmp_path.iterdir())) == 1
> assert 0 > assert 0
E assert 0 E assert 0

View File

@ -1887,11 +1887,12 @@ All the command-line flags can be obtained by running ``pytest --help``::
tests. Optional argument: glob (default: '*'). tests. Optional argument: glob (default: '*').
--cache-clear Remove all cache contents at start of test run --cache-clear Remove all cache contents at start of test run
--lfnf={all,none}, --last-failed-no-failures={all,none} --lfnf={all,none}, --last-failed-no-failures={all,none}
With ``--lf``, determines whether to execute tests when there With ``--lf``, determines whether to execute tests
are no previously (known) failures or when no when there are no previously (known) failures or
cached ``lastfailed`` data was found. when no cached ``lastfailed`` data was found.
``all`` (the default) runs the full test suite again. ``all`` (the default) runs the full test suite
``none`` just emits a message about no known failures and exits successfully. again. ``none`` just emits a message about no known
failures and exits successfully.
--sw, --stepwise Exit on test failure and continue from last failing --sw, --stepwise Exit on test failure and continue from last failing
test next time test next time
--sw-skip, --stepwise-skip --sw-skip, --stepwise-skip