1
0
mirror of https://github.com/kevin1024/vcrpy.git synced 2025-12-08 16:53:23 +00:00

Compare commits

...

5 Commits

Author SHA1 Message Date
Kevin McCarthy
b122b5c701 Release v8.1.0 2025-12-08 11:37:31 -05:00
Mathieu Dupuy
4883e3eefa Migrate to declarative Python package config (#767)
* migrate setup.py to pyproject.toml

* Revert "migrate setup.py to pyproject.toml"

This reverts commit f6c46cc138.

* migrate to setup.cfg

* migrate to pyproject.toml

---------

Co-authored-by: Mathieu Dupuy <mathieu.dupuy@gitguardian.com>
2025-12-08 10:13:56 -05:00
Kevin McCarthy
5678b13b47 Fix ruff SIM117: use combined with statement 2025-12-08 09:19:48 -05:00
Kevin McCarthy
48f5f84f86 Fix ruff linting issues in aiohttp tests 2025-12-08 09:16:46 -05:00
Leonardo Rochael Almeida
31d8c3498b aiohttp: Allow both data and json arguments (#624)
If at least one of them is `None`.

Previously, a `data=None` parameter would cause the `json` parameter to
be ignored, resulting in an empty request body payload on the cassette.
2025-12-08 09:13:51 -05:00
7 changed files with 169 additions and 100 deletions

View File

@@ -7,6 +7,14 @@ For a full list of triaged issues, bugs and PRs and what release they are target
All help in providing PRs to close out bug issues is appreciated. Even if that is providing a repo that fully replicates issues. We have very generous contributors that have added these to bug issues which meant another contributor picked up the bug and closed it out. All help in providing PRs to close out bug issues is appreciated. Even if that is providing a repo that fully replicates issues. We have very generous contributors that have added these to bug issues which meant another contributor picked up the bug and closed it out.
- 8.1.0
- Enable brotli decompression if available (via ``brotli``, ``brotlipy`` or ``brotlicffi``) (#620) - thanks @immerrr
- Fix aiohttp allowing both ``data`` and ``json`` arguments when one is None (#624) - thanks @leorochael
- Fix usage of io-like interface with VCR.py (#906) - thanks @tito and @kevdevg
- Migrate to declarative Python package config (#767) - thanks @deronnax
- Various linting fixes - thanks @jairhenrique
- CI: bump actions/checkout from 5 to 6 (#955)
- 8.0.0 - 8.0.0
- BREAKING: Drop support for Python 3.9 (major version bump) - thanks @jairhenrique - BREAKING: Drop support for Python 3.9 (major version bump) - thanks @jairhenrique
- BREAKING: Drop support for urllib3 < 2 - fixes CVE warnings from urllib3 1.x (#926, #880) - thanks @jairhenrique - BREAKING: Drop support for urllib3 < 2 - fixes CVE warnings from urllib3 1.x (#926, #880) - thanks @jairhenrique

View File

@@ -1,3 +1,72 @@
[project]
name = "vcrpy"
authors = [{name = "Kevin McCarthy", email = "me@kevinmccarthy.org"}]
license = {text = "MIT"}
description = "Automatically mock your HTTP interactions to simplify and speed up testing"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Environment :: Console",
"Intended Audience :: Developers",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Software Development :: Testing",
"Topic :: Internet :: WWW/HTTP",
"License :: OSI Approved :: MIT License",
]
urls = {Homepage = "https://github.com/kevin1024/vcrpy"}
requires-python = ">=3.10"
dependencies = [
"PyYAML",
"wrapt",
]
dynamic = ["version"]
[project.readme]
file = "README.rst"
content-type = "text/x-rst"
[project.optional-dependencies]
tests = [
"aiohttp",
"boto3",
"cryptography",
"httpbin",
"httpcore",
"httplib2",
"httpx",
"pycurl; platform_python_implementation !='PyPy'",
"pytest",
"pytest-aiohttp",
"pytest-asyncio",
"pytest-cov",
"pytest-httpbin",
"requests>=2.22.0",
"tornado",
"urllib3",
"werkzeug==2.0.3",
]
[tool.setuptools]
include-package-data = false
[tool.setuptools.packages.find]
exclude = ["tests*"]
namespaces = false
[tool.setuptools.dynamic]
version = {attr = "vcr.__version__"}
[build-system]
requires = ["setuptools>=61.2"]
build-backend = "setuptools.build_meta"
[tool.codespell] [tool.codespell]
skip = '.git,*.pdf,*.svg,.tox' skip = '.git,*.pdf,*.svg,.tox'
ignore-regex = "\\\\[fnrstv]" ignore-regex = "\\\\[fnrstv]"

View File

@@ -1,2 +1,58 @@
[bdist_wheel] [metadata]
universal=1 name = vcrpy
version = attr: vcr.__version__
author = Kevin McCarthy
author_email = me@kevinmccarthy.org
license = MIT
description = Automatically mock your HTTP interactions to simplify and speed up testing
url = https://github.com/kevin1024/vcrpy
long_description = file: README.rst
long_description_content_type = text/x-rst
classifiers =
Development Status :: 5 - Production/Stable
Environment :: Console
Intended Audience :: Developers
Programming Language :: Python
Programming Language :: Python :: 3
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
Programming Language :: Python :: 3.13
Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: Implementation :: CPython
Programming Language :: Python :: Implementation :: PyPy
Topic :: Software Development :: Testing
Topic :: Internet :: WWW/HTTP
License :: OSI Approved :: MIT License
[options]
packages = find:
python_requires = >=3.10
install_requires =
PyYAML
wrapt
tests_require =
vcrpy[tests]
[options.packages.find]
exclude = tests*
[options.extras_require]
tests =
aiohttp
boto3
cryptography
httpbin
httpcore
httplib2
httpx
pycurl; platform_python_implementation !='PyPy'
pytest
pytest-aiohttp
pytest-asyncio
pytest-cov
pytest-httpbin
requests>=2.22.0
tornado
urllib3
werkzeug==2.0.3

View File

@@ -1,89 +0,0 @@
#!/usr/bin/env python
import codecs
import os
import re
from pathlib import Path
from setuptools import find_packages, setup
long_description = Path("README.rst").read_text()
here = os.path.abspath(os.path.dirname(__file__))
def read(*parts):
# intentionally *not* adding an encoding option to open, See:
# https://github.com/pypa/virtualenv/issues/201#issuecomment-3145690
with codecs.open(os.path.join(here, *parts), "r") as fp:
return fp.read()
def find_version(*file_paths):
version_file = read(*file_paths)
version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", version_file, re.M)
if version_match:
return version_match.group(1)
raise RuntimeError("Unable to find version string.")
install_requires = [
"PyYAML",
"wrapt",
]
extras_require = {
"tests": [
"aiohttp",
"boto3",
"cryptography",
"httpbin",
"httpcore",
"httplib2",
"httpx",
"pycurl; platform_python_implementation !='PyPy'",
"pytest",
"pytest-aiohttp",
"pytest-asyncio",
"pytest-cov",
"pytest-httpbin",
"requests>=2.22.0",
"tornado",
"urllib3",
"werkzeug==2.0.3",
],
}
setup(
name="vcrpy",
version=find_version("vcr", "__init__.py"),
description=("Automatically mock your HTTP interactions to simplify and speed up testing"),
long_description=long_description,
long_description_content_type="text/x-rst",
author="Kevin McCarthy",
author_email="me@kevinmccarthy.org",
url="https://github.com/kevin1024/vcrpy",
packages=find_packages(exclude=["tests*"]),
python_requires=">=3.10",
install_requires=install_requires,
license="MIT",
extras_require=extras_require,
tests_require=extras_require["tests"],
classifiers=[
"Development Status :: 5 - Production/Stable",
"Environment :: Console",
"Intended Audience :: Developers",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Software Development :: Testing",
"Topic :: Internet :: WWW/HTTP",
"License :: OSI Approved :: MIT License",
],
)

View File

@@ -137,19 +137,29 @@ def test_stream(tmpdir, httpbin):
assert cassette.play_count == 1 assert cassette.play_count == 1
POST_DATA = {"key1": "value1", "key2": "value2"}
@pytest.mark.online @pytest.mark.online
@pytest.mark.parametrize("body", ["data", "json"]) @pytest.mark.parametrize(
def test_post(tmpdir, body, caplog, httpbin): "kwargs",
[
{"data": POST_DATA},
{"json": POST_DATA},
{"data": POST_DATA, "json": None},
{"data": None, "json": POST_DATA},
],
)
def test_post(tmpdir, kwargs, caplog, httpbin):
caplog.set_level(logging.INFO) caplog.set_level(logging.INFO)
data = {"key1": "value1", "key2": "value2"} url = httpbin.url + "/post"
url = httpbin.url
with vcr.use_cassette(str(tmpdir.join("post.yaml"))): with vcr.use_cassette(str(tmpdir.join("post.yaml"))):
_, response_json = post(url, **{body: data}) _, response_json = post(url, **kwargs)
with vcr.use_cassette(str(tmpdir.join("post.yaml"))) as cassette: with vcr.use_cassette(str(tmpdir.join("post.yaml"))) as cassette:
request = cassette.requests[0] request = cassette.requests[0]
assert request.body == data assert request.body == POST_DATA
_, cassette_response_json = post(url, **{body: data}) _, cassette_response_json = post(url, **kwargs)
assert cassette_response_json == response_json assert cassette_response_json == response_json
assert cassette.play_count == 1 assert cassette.play_count == 1
@@ -163,6 +173,17 @@ def test_post(tmpdir, body, caplog, httpbin):
), "Log message not found." ), "Log message not found."
@pytest.mark.online
def test_post_data_plus_json_error(tmpdir, httpbin):
url = httpbin.url + "/post"
with (
vcr.use_cassette(str(tmpdir.join("post.yaml"))) as cassette,
pytest.raises(ValueError, match="data and json parameters can not be used at the same time"),
):
post(url, data=POST_DATA, json=POST_DATA)
assert cassette.requests == []
@pytest.mark.online @pytest.mark.online
def test_params(tmpdir, httpbin): def test_params(tmpdir, httpbin):
url = httpbin.url + "/get?d=d" url = httpbin.url + "/get?d=d"

View File

@@ -4,7 +4,7 @@ from logging import NullHandler
from .config import VCR from .config import VCR
from .record_mode import RecordMode as mode # noqa: F401 from .record_mode import RecordMode as mode # noqa: F401
__version__ = "8.0.0" __version__ = "8.1.0"
logging.getLogger(__name__).addHandler(NullHandler()) logging.getLogger(__name__).addHandler(NullHandler())

View File

@@ -245,7 +245,11 @@ def vcr_request(cassette, real_request):
headers = kwargs.get("headers") headers = kwargs.get("headers")
auth = kwargs.get("auth") auth = kwargs.get("auth")
headers = self._prepare_headers(headers) headers = self._prepare_headers(headers)
data = kwargs.get("data", kwargs.get("json")) data = kwargs.get("data")
if data is None:
data = kwargs.get("json")
elif kwargs.get("json") is not None:
raise ValueError("data and json parameters can not be used at the same time")
params = kwargs.get("params") params = kwargs.get("params")
cookies = kwargs.get("cookies") cookies = kwargs.get("cookies")