[Git][debian-gis-team/pytest-recording][upstream] New upstream version 0.14.0

Antonio Valentino (@antonio.valentino) gitlab at salsa.debian.org
Tue Oct 6 07:36:02 BST 2026



Antonio Valentino pushed to branch upstream at Debian GIS Project / pytest-recording


Commits:
41db970d by Antonio Valentino at 2026-10-06T06:05:07+00:00
New upstream version 0.14.0
- - - - -


11 changed files:

- .github/workflows/build.yml
- .github/workflows/commit.yml
- .github/workflows/release.yml
- .pre-commit-config.yaml
- CONTRIBUTING.rst
- README.rst
- docs/changelog.rst
- pyproject.toml
- src/pytest_recording/_vcr.py
- tests/test_recording.py
- tox.ini


Changes:

=====================================
.github/workflows/build.yml
=====================================
@@ -18,13 +18,13 @@ jobs:
     name: Generic pre-commit checks
     runs-on: ubuntu-24.04
     steps:
-      - uses: actions/checkout at v4
+      - uses: actions/checkout at v6
         with:
           fetch-depth: 1
 
-      - uses: actions/setup-python at v5
+      - uses: actions/setup-python at v6
         with:
-          python-version: 3.13
+          python-version: 3.x
 
       - run: pip install pre-commit
       - run: SKIP=mypy pre-commit run --all-files
@@ -33,13 +33,13 @@ jobs:
     name: Mypy
     runs-on: ubuntu-24.04
     steps:
-      - uses: actions/checkout at v4
+      - uses: actions/checkout at v6
         with:
           fetch-depth: 1
 
-      - uses: actions/setup-python at v5
+      - uses: actions/setup-python at v6
         with:
-          python-version: 3.13
+          python-version: 3.x
 
       - run: pip install pre-commit
       - run: pre-commit run mypy --all-files
@@ -50,17 +50,8 @@ jobs:
     strategy:
       matrix:
         include:
-          - tox_job: py39
-            python: "3.9"
-            os_version: "ubuntu-24.04"
-          - tox_job: py39-no_pycurl
-            python: "3.9"
-            os_version: "ubuntu-24.04"
           - tox_job: pypy3-no_pycurl
-            python: "pypy-3.10"
-            os_version: "ubuntu-24.04"
-          - tox_job: vcr_431
-            python: "3.9"
+            python: "pypy3.11"
             os_version: "ubuntu-24.04"
           - tox_job: py310
             python: "3.10"
@@ -74,18 +65,15 @@ jobs:
           - tox_job: py313
             python: "3.13"
             os_version: "ubuntu-24.04"
+          - tox_job: py314
+            python: "3.14"
+            os_version: "ubuntu-24.04"
+          - tox_job: py315
+            python: "3.15"
+            os_version: "ubuntu-24.04"
 
-          - tox_job: py39
-            python: "3.9"
-            os_version: "windows-2022"
-          - tox_job: py39-no_pycurl
-            python: "3.9"
-            os_version: "windows-2022"
           - tox_job: pypy3-no_pycurl
-            python: "pypy-3.10"
-            os_version: "windows-2022"
-          - tox_job: vcr_431
-            python: "3.9"
+            python: "pypy3.11"
             os_version: "windows-2022"
           - tox_job: py310
             python: "3.10"
@@ -99,15 +87,22 @@ jobs:
           - tox_job: py313
             python: "3.13"
             os_version: "windows-2022"
+          - tox_job: py314
+            python: "3.14"
+            os_version: "windows-2022"
+          - tox_job: py315
+            python: "3.15"
+            os_version: "windows-2022"
 
     steps:
-      - uses: actions/checkout at v4
+      - uses: actions/checkout at v6
         with:
           fetch-depth: 1
 
-      - uses: actions/setup-python at v5
+      - uses: actions/setup-python at v6
         with:
           python-version: ${{ matrix.python }}
+          allow-prereleases: true
 
       - run: pip install tox coverage
 
@@ -123,6 +118,6 @@ jobs:
       - run: coverage xml -i
 
       - name: Upload coverage to Codecov
-        uses: codecov/codecov-action at v5.4.2
+        uses: codecov/codecov-action at v7.0.0
         with:
           file: ./coverage.xml


=====================================
.github/workflows/commit.yml
=====================================
@@ -12,7 +12,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Check out code
-        uses: actions/checkout at v4
+        uses: actions/checkout at v6
         with:
           fetch-depth: 0
       - name: Run commitsar


=====================================
.github/workflows/release.yml
=====================================
@@ -10,10 +10,10 @@ jobs:
     runs-on: ubuntu-latest
     steps:
     - uses: actions/checkout at master
-    - name: Set up Python 3.13
-      uses: actions/setup-python at v5
+    - name: Set up Python 3
+      uses: actions/setup-python at v6
       with:
-        python-version: 3.13
+        python-version: 3.x
 
     - run: pip install hatch
 


=====================================
.pre-commit-config.yaml
=====================================
@@ -1,5 +1,5 @@
 default_language_version:
-  python: python3.13
+  python: python3.14
 
 repos:
   - repo: https://github.com/pre-commit/pre-commit-hooks


=====================================
CONTRIBUTING.rst
=====================================
@@ -47,10 +47,10 @@ Submitting Pull Requests
 #. Fork the repository.
 #. Enable and install `pre-commit <https://pre-commit.com>`_ to ensure style-guides and code checks are followed.
 #. Target the ``master`` branch.
-#. Follow **PEP-8** for naming and `ruff <https://github.com/astral-sh/ruff>`_ for formatting.
+#. Follow **PEP 8** for naming and `ruff <https://github.com/astral-sh/ruff>`_ for formatting.
 #. Tests are run using ``tox``::
 
-    tox -e py39
+    tox -e py314
 
    The test environments above are usually enough to cover most cases locally.
 


=====================================
README.rst
=====================================
@@ -119,6 +119,20 @@ Resulting VCR configs for each test:
 - ``test_one`` - ``{"ignore_localhost": True, "filter_headers": []}``
 - ``test_two`` - ``{"ignore_localhost": True, "filter_headers": ["authorization"], "filter_query_parameters": ["api_key"]}``
 
+The ``vcr_config`` fixture forwards any keyword argument to vcrpy, so ``ignore_hosts``
+and other VCR.py options work directly:
+
+.. code:: python
+
+    import pytest
+
+    @pytest.fixture(scope="module")
+    def vcr_config():
+        return {
+            "filter_headers": ["authorization"],
+            "ignore_hosts": ["169.254.169.254", "metadata.google.internal"],
+        }
+
 You can get access to the used ``VCR`` instance via ``pytest_recording_configure`` hook. It might be useful for registering
 custom matchers, persisters, etc.:
 
@@ -272,8 +286,8 @@ Python support
 
 Pytest-recording supports:
 
-- CPython 3.9, 3.10, 3.11, 3.12, and 3.13
-- PyPy 7.3 (3.10)
+- CPython 3.10, 3.11, 3.12, 3.13, 3.14 and 3.15
+- PyPy 7.3 (3.11)
 
 License
 -------


=====================================
docs/changelog.rst
=====================================
@@ -6,10 +6,18 @@ Changelog
 `Unreleased`_
 -------------
 
+`0.14.0`_ - 2026-10-02
+----------------------
+
+- Add support for Python 3.15.
+- Add support for Python 3.14 and drop EOL 3.9. `#185`_
+- Document ``ignore_hosts`` in the ``vcr_config`` fixture example. `#170`_
+- Fix ``ValueError: 'rewrite' is not a valid record_mode`` raised by VCR.py 8.2.1+ when the ``rewrite`` mode is set via the ``vcr_config`` fixture or the ``vcr`` mark. `#205`_
+
 `0.13.4`_ - 2025-04-24
 ----------------------
 
-- ``AttributeError`` on Windows. `#172`_
+- ``AttributeError`` on Windows. `#174`_
 
 `0.13.3`_ - 2025-04-24
 ----------------------
@@ -214,7 +222,8 @@ Added
 
 - Initial public release
 
-.. _Unreleased: https://github.com/kiwicom/pytest-recording/compare/v0.13.4...HEAD
+.. _Unreleased: https://github.com/kiwicom/pytest-recording/compare/v0.14.0...HEAD
+.. _0.14.0: https://github.com/kiwicom/pytest-recording/compare/v0.13.4...v0.14.0
 .. _0.13.4: https://github.com/kiwicom/pytest-recording/compare/v0.13.3...v0.13.4
 .. _0.13.3: https://github.com/kiwicom/pytest-recording/compare/v0.13.2...v0.13.3
 .. _0.13.2: https://github.com/kiwicom/pytest-recording/compare/v0.13.1...v0.13.2
@@ -241,8 +250,11 @@ Added
 .. _0.3.0: https://github.com/kiwicom/pytest-recording/compare/v0.2.0...v0.3.0
 .. _0.2.0: https://github.com/kiwicom/pytest-recording/compare/v0.1.0...v0.2.0
 
+.. _#205: https://github.com/kiwicom/pytest-recording/pull/205
+.. _#185: https://github.com/kiwicom/pytest-recording/pull/185
 .. _#174: https://github.com/kiwicom/pytest-recording/issues/174
 .. _#172: https://github.com/kiwicom/pytest-recording/issues/172
+.. _#170: https://github.com/kiwicom/pytest-recording/issues/170
 .. _#145: https://github.com/kiwicom/pytest-recording/issues/145
 .. _#118: https://github.com/kiwicom/pytest-recording/pull/118
 .. _#99: https://github.com/kiwicom/pytest-recording/pull/99


=====================================
pyproject.toml
=====================================
@@ -4,12 +4,12 @@ build-backend = "hatchling.build"
 
 [project]
 name = "pytest-recording"
-version = "0.13.4"
+version = "0.14.0"
 description = "A pytest plugin powered by VCR.py to record and replay HTTP traffic"
 keywords = ["pytest", "vcr", "network", "mock"]
 authors = [{ name = "Dmitry Dygalo", email = "dmitry at dygalo.dev" }]
 maintainers = [{ name = "Dmitry Dygalo", email = "dmitry at dygalo.dev" }]
-requires-python = ">=3.9"
+requires-python = ">=3.10"
 license = "MIT"
 readme = "README.rst"
 classifiers = [
@@ -22,11 +22,12 @@ classifiers = [
     "Programming Language :: Python",
     "Programming Language :: Python :: 3 :: Only",
     "Programming Language :: Python :: 3",
-    "Programming Language :: Python :: 3.9",
     "Programming Language :: Python :: 3.10",
     "Programming Language :: Python :: 3.11",
     "Programming Language :: Python :: 3.12",
     "Programming Language :: Python :: 3.13",
+    "Programming Language :: Python :: 3.14",
+    "Programming Language :: Python :: 3.15",
     "Programming Language :: Python :: Implementation :: CPython",
     "Programming Language :: Python :: Implementation :: PyPy",
     "Operating System :: OS Independent",
@@ -40,7 +41,7 @@ tests = [
     "pytest-httpbin",
     "pytest-mock",
     "requests",
-    "Werkzeug==3.1.3"
+    "Werkzeug==3.1.8"
 ]
 dev = ["pytest_recording[tests]"]
 
@@ -55,7 +56,7 @@ recording = "pytest_recording.plugin"
 
 [tool.ruff]
 line-length = 120
-target-version = "py39"
+target-version = "py310"
 
 [tool.ruff.lint]
 select = [


=====================================
src/pytest_recording/_vcr.py
=====================================
@@ -54,7 +54,7 @@ class CombinedPersister(FilesystemPersister):
         #    but the functional approach is faster
         # 2. It could be done more efficient, but the `deserialize` implementation should be adjusted as well
         #    But it is a private API, which could be changed.
-        requests, responses = starmap(unpack, zip(*all_content))
+        requests, responses = starmap(unpack, zip(*all_content, strict=True))
         requests, responses = list(requests), list(responses)
         if not requests or not responses:
             raise CassetteNotFoundError("No cassettes found.")
@@ -89,6 +89,9 @@ def use_cassette(
         except OSError:
             pass
         record_mode = "new_episodes"
+        # VCR.py does not know the "rewrite" mode and validates `record_mode`.
+        if "record_mode" in merged_config:
+            merged_config["record_mode"] = record_mode
     vcr = VCR(
         path_transformer=path_transformer,
         cassette_library_dir=vcr_cassette_dir,


=====================================
tests/test_recording.py
=====================================
@@ -121,6 +121,92 @@ def test_record_mode_in_config(testdir):
     assert cassette_path.size()
 
 
+def assert_cassette_is_rewritten(testdir, cassette_path):
+    """Run the test again and assert that ``rewrite`` replaces the cassette instead of extending it."""
+    # If recording is enabled
+    result = testdir.runpytest()
+    result.assert_outcomes(passed=1)
+
+    # Then the test creates a cassette
+    cassette_size = cassette_path.size()
+    assert cassette_size
+    with open(str(cassette_path), encoding="utf8") as cassette:
+        first_uuid = yaml.load(cassette, Loader=yaml.BaseLoader)["interactions"][0]["response"]["body"]["string"]
+
+    # Rewriting again replaces the cassette instead of replaying or extending it
+    result = testdir.runpytest()
+    result.assert_outcomes(passed=1)
+    assert cassette_path.size() == cassette_size
+    with open(str(cassette_path), encoding="utf8") as cassette:
+        second_uuid = yaml.load(cassette, Loader=yaml.BaseLoader)["interactions"][0]["response"]["body"]["string"]
+    assert first_uuid != second_uuid
+
+
+def test_rewrite_record_mode_in_config(testdir):
+    testdir.makepyfile(
+        """
+        import pytest
+        import requests
+
+        @pytest.fixture(scope="module")
+        def vcr_config():
+            return {"record_mode": "rewrite"}
+
+        @pytest.mark.vcr
+        def test_record_mode(httpbin):
+            assert requests.get(httpbin.url + "/uuid").status_code == 200
+    """
+    )
+    cassette_path = testdir.tmpdir.join("cassettes/test_rewrite_record_mode_in_config/test_record_mode.yaml")
+    assert_cassette_is_rewritten(testdir, cassette_path)
+
+
+def test_rewrite_record_mode_in_mark(testdir):
+    testdir.makepyfile(
+        """
+        import pytest
+        import requests
+
+        @pytest.mark.vcr(record_mode="rewrite")
+        def test_record_mode(httpbin):
+            assert requests.get(httpbin.url + "/uuid").status_code == 200
+    """
+    )
+    cassette_path = testdir.tmpdir.join("cassettes/test_rewrite_record_mode_in_mark/test_record_mode.yaml")
+    assert_cassette_is_rewritten(testdir, cassette_path)
+
+
+def test_recording_configure_hook_does_not_override_record_mode(testdir):
+    """`record_mode` set via the `vcr_config` fixture wins over the `pytest_recording_configure` hook."""
+    testdir.makeconftest(
+        """
+def pytest_recording_configure(config, vcr):
+    vcr.record_mode = "none"
+        """
+    )
+    testdir.makepyfile(
+        """
+        import pytest
+        import requests
+
+        @pytest.fixture(scope="module")
+        def vcr_config():
+            return {"record_mode": "all"}
+
+        @pytest.mark.vcr
+        def test_record_mode(httpbin):
+            assert requests.get(httpbin.url + "/uuid").status_code == 200
+    """
+    )
+    cassette_path = testdir.tmpdir.join(
+        "cassettes/test_recording_configure_hook_does_not_override_record_mode/test_record_mode.yaml"
+    )
+
+    result = testdir.runpytest()
+    result.assert_outcomes(passed=1)
+    assert cassette_path.size()
+
+
 def test_cassette_recording_rewrite(testdir):
     testdir.makepyfile(
         """


=====================================
tox.ini
=====================================
@@ -1,5 +1,5 @@
 [tox]
-envlist = py{39,310,311,312,313},py{39,py3}-no_pycurl,vcr_431,coverage-report
+envlist = py{310,311,312,313,314,315},pypy3-no_pycurl,coverage-report
 
 [testenv]
 setenv =
@@ -13,7 +13,6 @@ deps =
     pytest-httpbin
     pytest-mock
     requests
-    werkzeug<2.1.0
     pycurl --global-option="--with-{env:PYCURL_SSL_LIBRARY}"
     xdist: pytest-xdist
 commands =
@@ -21,35 +20,21 @@ commands =
 
 # pypy3 + pycurl does not work
 # https://github.com/pypy/pypy/issues/3958
-[testenv:py{39,py3}-no_pycurl]
+[testenv:pypy3-no_pycurl]
 deps =
     coverage
     pytest>=3.0
     pytest-httpbin
     pytest-mock
     requests
-    werkzeug<2.1.0
 commands = coverage run --source=pytest_recording -m pytest {posargs:tests}
 
-[testenv:vcr_431]
-basepython = python3.9
-deps =
-    coverage
-    pytest>=3.0
-    pytest-httpbin
-    pytest-mock
-    requests
-    werkzeug<2.1.0
-    vcrpy<4.4.0
-commands =
-    coverage run --source=pytest_recording -m pytest {posargs:tests}
-
 [testenv:coverage-report]
 description = Report coverage over all measured test runs.
-basepython = python3.9
+basepython = python3.14
 deps = coverage
 skip_install = true
-depends = {py39,py310,py311,py312,py313,pypy3}
+depends = {py310,py311,py312,py313,py314,py315,pypy3}
 commands =
     coverage combine
     coverage report --fail-under=100 --show-missing --skip-covered



View it on GitLab: https://salsa.debian.org/debian-gis-team/pytest-recording/-/commit/41db970da6473cdbf98591f3c21932cd59125653

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/pytest-recording/-/commit/41db970da6473cdbf98591f3c21932cd59125653
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20261006/d1d59043/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list