1
0
mirror of https://github.com/kevin1024/vcrpy.git synced 2025-12-09 01:03:24 +00:00

Compare commits

..

12 Commits

Author SHA1 Message Date
kevin1024
3278619dcc Release v7.0.0 2024-12-30 18:59:50 -05:00
Aleksei Kozharin
3fb62e0f9b fix: correctly handle asyncio.run when loop exists 2024-12-30 13:34:03 -03:00
dependabot[bot]
81978659f1 build(deps): update sphinx requirement from <8 to <9
Updates the requirements on [sphinx](https://github.com/sphinx-doc/sphinx) to permit the latest version.
- [Release notes](https://github.com/sphinx-doc/sphinx/releases)
- [Changelog](https://github.com/sphinx-doc/sphinx/blob/v8.0.2/CHANGES.rst)
- [Commits](https://github.com/sphinx-doc/sphinx/compare/v0.1.61611...v8.0.2)

---
updated-dependencies:
- dependency-name: sphinx
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-28 14:03:41 -03:00
pre-commit
be651bd27c pre-commit: Autoupdate 2024-12-28 13:48:49 -03:00
Jair Henrique
a6698ed060 Fix aiohttp tests 2024-12-28 13:42:54 -03:00
Igor Gumenyuk
48d0a2e453 Fixed missing version_string attribute when used with urllib3>=2.3.0
urllib3 in v2.3.0 introduced attribute `version_string` (https://github.com/urllib3/urllib3/pull/3316/files). This attribute  is missing in `VCRHTTPResponse` which causes errors like AttributeError: 'VCRHTTPResponse' object has no attribute 'version_string'

This fixes https://github.com/kevin1024/vcrpy/issues/888
2024-12-28 13:39:53 -03:00
Jair Henrique
5b858b132d Fix lint 2024-12-28 13:25:04 -03:00
Jair Henrique
c8d99a99ec Fix ruff configuration 2024-12-28 13:21:15 -03:00
Sebastian Pipping
ce27c63685 Merge pull request #736 from kevin1024/drop-python38
[14 Oct 2024] Drop python 3.8 support
2024-10-13 04:05:13 +02:00
Jair Henrique
ab8944d3ca Drop python 3.8 support 2024-10-12 22:44:42 -03:00
Sebastian Pipping
c6a7f4ae15 Merge pull request #872 from kevin1024/precommit-autoupdate
pre-commit: Autoupdate
2024-10-11 01:22:08 +02:00
pre-commit
7275e5d65d pre-commit: Autoupdate 2024-10-04 16:05:32 +00:00
14 changed files with 44 additions and 25 deletions

View File

@@ -16,13 +16,11 @@ jobs:
fail-fast: false
matrix:
python-version:
- "3.8"
- "3.9"
- "3.10"
- "3.11"
- "3.12"
- "3.13"
- "pypy-3.8"
- "pypy-3.9"
- "pypy-3.10"
urllib3-requirement:
@@ -30,10 +28,6 @@ jobs:
- "urllib3<2"
exclude:
- python-version: "3.8"
urllib3-requirement: "urllib3>=2"
- python-version: "pypy-3.8"
urllib3-requirement: "urllib3>=2"
- python-version: "3.9"
urllib3-requirement: "urllib3>=2"
- python-version: "pypy-3.9"

View File

@@ -3,14 +3,14 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.6
rev: v0.8.4
hooks:
- id: ruff
args: ["--output-format=full"]
- id: ruff-format
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
rev: v5.0.0
hooks:
- id: check-merge-conflict
- id: end-of-file-fixer

View File

@@ -7,6 +7,11 @@ 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.
- 7.0.0
- Drop support for python 3.8 (major version bump) - thanks @jairhenrique
- Various linting and test fixes - thanks @jairhenrique
- Bugfix for urllib2>=2.3.0 - missing version_string (#888)
- Bugfix for asyncio.run - thanks @alekeik1
- 6.0.2
- Ensure body is consumed only once (#846) - thanks @sathieu
- Permit urllib3 2.x for non-PyPy Python >=3.10

View File

@@ -9,7 +9,7 @@ with pip::
Compatibility
-------------
VCR.py supports Python 3.8+, and `pypy <http://pypy.org>`__.
VCR.py supports Python 3.9+, and `pypy <http://pypy.org>`__.
The following HTTP libraries are supported:

View File

@@ -1,2 +1,2 @@
sphinx<8
sphinx<9
sphinx_rtd_theme==2.0.0

View File

@@ -16,6 +16,10 @@ filterwarnings = [
]
[tool.ruff]
line-length = 110
target-version = "py39"
[tool.ruff.lint]
select = [
"B", # flake8-bugbear
"C4", # flake8-comprehensions
@@ -29,8 +33,6 @@ select = [
"UP", # pyupgrade
"W", # pycodestyle warning
]
line-length = 110
target-version = "py38"
[tool.ruff.isort]
[tool.ruff.lint.isort]
known-first-party = ["vcr"]

View File

@@ -78,7 +78,7 @@ setup(
author_email="me@kevinmccarthy.org",
url="https://github.com/kevin1024/vcrpy",
packages=find_packages(exclude=["tests*"]),
python_requires=">=3.8",
python_requires=">=3.9",
install_requires=install_requires,
license="MIT",
extras_require=extras_require,
@@ -89,11 +89,11 @@ setup(
"Intended Audience :: Developers",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"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 :: Only",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",

View File

@@ -4,6 +4,7 @@ import urllib.parse
import pytest
import pytest_httpbin.certs
import yarl
import vcr
@@ -403,7 +404,7 @@ def test_cookies_redirect(httpbin_both, tmpdir):
async with aiohttp.ClientSession(loop=loop, cookie_jar=aiohttp.CookieJar(unsafe=True)) as session:
cookies_resp = await session.get(cookies_url, ssl=HTTPBIN_SSL_CONTEXT)
assert not cookies_resp.cookies
cookies = session.cookie_jar.filter_cookies(cookies_url)
cookies = session.cookie_jar.filter_cookies(yarl.URL(cookies_url))
assert cookies["Cookie_1"].value == "Val_1"
assert cassette.play_count == 0
@@ -414,7 +415,7 @@ def test_cookies_redirect(httpbin_both, tmpdir):
async with aiohttp.ClientSession(loop=loop, cookie_jar=aiohttp.CookieJar(unsafe=True)) as session:
cookies_resp = await session.get(cookies_url, ssl=HTTPBIN_SSL_CONTEXT)
assert not cookies_resp.cookies
cookies = session.cookie_jar.filter_cookies(cookies_url)
cookies = session.cookie_jar.filter_cookies(yarl.URL(cookies_url))
assert cookies["Cookie_1"].value == "Val_1"
assert cassette.play_count == 2
@@ -428,7 +429,7 @@ def test_cookies_redirect(httpbin_both, tmpdir):
async with aiohttp.ClientSession(loop=loop, cookie_jar=aiohttp.CookieJar(unsafe=True)) as session:
cookies_resp = await session.get(cookies_url, ssl=HTTPBIN_SSL_CONTEXT)
assert not cookies_resp.cookies
cookies = session.cookie_jar.filter_cookies(cookies_url)
cookies = session.cookie_jar.filter_cookies(yarl.URL(cookies_url))
assert cookies["Cookie_1"].value == "Val_1"
run_in_loop(run)

View File

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

View File

@@ -215,7 +215,7 @@ class Cassette:
@property
def write_protected(self):
return self.rewound and self.record_mode == RecordMode.ONCE or self.record_mode == RecordMode.NONE
return (self.rewound and self.record_mode == RecordMode.ONCE) or self.record_mode == RecordMode.NONE
def append(self, request, response):
"""Add a request, response pair to this cassette"""

View File

@@ -3,11 +3,10 @@ import logging
import urllib
import xmlrpc.client
from string import hexdigits
from typing import List, Set
from .util import read_body
_HEXDIG_CODE_POINTS: Set[int] = {ord(s.encode("ascii")) for s in hexdigits}
_HEXDIG_CODE_POINTS: set[int] = {ord(s.encode("ascii")) for s in hexdigits}
log = logging.getLogger(__name__)
@@ -109,7 +108,7 @@ def _dechunk(body):
CHUNK_GAP = b"\r\n"
BODY_LEN: int = len(body)
chunks: List[bytes] = []
chunks: list[bytes] = []
pos: int = 0
while True:

View File

@@ -66,6 +66,7 @@ class VCRHTTPResponse(HTTPResponse):
self.reason = recorded_response["status"]["message"]
self.status = self.code = recorded_response["status"]["code"]
self.version = None
self.version_string = None
self._content = BytesIO(self.recorded_response["body"]["string"])
self._closed = False
self._original_response = self # for requests.session.Session cookie extraction

View File

@@ -4,8 +4,9 @@ import asyncio
import functools
import json
import logging
from collections.abc import Mapping
from http.cookies import CookieError, Morsel, SimpleCookie
from typing import Mapping, Union
from typing import Union
from aiohttp import ClientConnectionError, ClientResponse, CookieJar, RequestInfo, hdrs, streams
from aiohttp.helpers import strip_auth_from_url

View File

@@ -166,6 +166,22 @@ def async_vcr_send(cassette, real_send):
return _inner_send
def _run_async_function(sync_func, *args, **kwargs):
"""
Safely run an asynchronous function from a synchronous context.
Handles both cases:
- An event loop is already running.
- No event loop exists yet.
"""
try:
asyncio.get_running_loop()
except RuntimeError:
return asyncio.run(sync_func(*args, **kwargs))
else:
# If inside a running loop, create a task and wait for it
return asyncio.ensure_future(sync_func(*args, **kwargs))
def _sync_vcr_send(cassette, real_send, *args, **kwargs):
vcr_request, response = _shared_vcr_send(cassette, real_send, *args, **kwargs)
if response:
@@ -174,7 +190,7 @@ def _sync_vcr_send(cassette, real_send, *args, **kwargs):
return response
real_response = real_send(*args, **kwargs)
asyncio.run(_record_responses(cassette, vcr_request, real_response, aread=False))
_run_async_function(_record_responses, cassette, vcr_request, real_response, aread=False)
return real_response