Skip to content

Commit

Permalink
Drop support for python 3.6 (#218)
Browse files Browse the repository at this point in the history
  • Loading branch information
lundberg authored Sep 25, 2022
1 parent 8d9e149 commit 0c896f6
Show file tree
Hide file tree
Showing 17 changed files with 18 additions and 81 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.6
python-version: 3.7
- name: Pip cache
uses: actions/cache@v1
with:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
strategy:
max-parallel: 5
matrix:
python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"]
python-version: ["3.7", "3.8", "3.9", "3.10"]
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
Expand Down Expand Up @@ -51,7 +51,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.6
python-version: 3.7
- name: Pip cache
uses: actions/cache@v1
with:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,5 @@ Install with pip:
$ pip install respx
```

Requires Python 3.6+ and HTTPX 0.21+.
Requires Python 3.7+ and HTTPX 0.21+.
See [Changelog](https://github.com/lundberg/respx/blob/master/CHANGELOG.md) for older HTTPX compatibility.
2 changes: 0 additions & 2 deletions docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ import respx


@respx.mock
@pytest.mark.asyncio
async def test_async_decorator():
async with httpx.AsyncClient() as client:
route = respx.get("https://example.org/")
Expand All @@ -106,7 +105,6 @@ async def test_async_decorator():
assert response.status_code == 200


@pytest.mark.asyncio
async def test_async_ctx_manager():
async with respx.mock:
async with httpx.AsyncClient() as client:
Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,5 @@ Install with pip:
$ pip install respx
```

Requires Python 3.6+ and HTTPX 0.21+.
Requires Python 3.7+ and HTTPX 0.21+.
See [Changelog](https://github.com/lundberg/respx/blob/master/CHANGELOG.md) for older HTTPX compatibility.
1 change: 0 additions & 1 deletion docs/versions/0.14.0/mocking.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,4 +250,3 @@ class MyTestCase(asynctest.TestCase):
assert request.called
assert response.text == "foobar"
```

8 changes: 4 additions & 4 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
docs_requirements = ("mkdocs", "mkdocs-material", "mkautodoc>=0.1.0")


@nox.session(python=["3.6", "3.7", "3.8", "3.9", "3.10", "3.11"])
@nox.session(python=["3.7", "3.8", "3.9", "3.10", "3.11"])
def test(session):
deps = ["pytest", "pytest-asyncio", "pytest-cov", "trio", "starlette", "flask"]
session.install("--upgrade", *deps)
Expand All @@ -22,12 +22,12 @@ def test(session):
session.run("pytest", "-v", *options)


@nox.session(python="3.6")
@nox.session(python="3.7")
def check(session):
session.install("--upgrade", "flake8-bugbear", "mypy", *lint_requirements)
session.install("-e", ".")

session.run("black", "--check", "--diff", "--target-version=py36", *source_files)
session.run("black", "--check", "--diff", "--target-version=py37", *source_files)
session.run("isort", "--check", "--diff", "--project=respx", *source_files)
session.run("flake8", *source_files)
session.run("mypy")
Expand All @@ -39,7 +39,7 @@ def lint(session):

session.run("autoflake", "--in-place", "--recursive", *source_files)
session.run("isort", "--project=respx", *source_files)
session.run("black", "--target-version=py36", *source_files)
session.run("black", "--target-version=py37", *source_files)

session.notify("check")

Expand Down
4 changes: 2 additions & 2 deletions respx/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def __init__(self, transport: httpx.BaseTransport) -> None:

def __call__(self, request: httpx.Request) -> httpx.Response:
if not isinstance(
request.stream, # type: ignore[has-type]
request.stream,
httpx.SyncByteStream,
): # pragma: nocover
raise RuntimeError("Attempted to route an async request to a sync app.")
Expand All @@ -23,7 +23,7 @@ def __init__(self, transport: httpx.AsyncBaseTransport) -> None:

async def __call__(self, request: httpx.Request) -> httpx.Response:
if not isinstance(
request.stream, # type: ignore[has-type]
request.stream,
httpx.AsyncByteStream,
): # pragma: nocover
raise RuntimeError("Attempted to route a sync request to an async app.")
Expand Down
2 changes: 1 addition & 1 deletion respx/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def clone_response(response: httpx.Response, request: httpx.Request) -> httpx.Re
response = httpx.Response(
response.status_code,
headers=response.headers,
stream=response.stream, # type: ignore[has-type]
stream=response.stream,
request=request,
extensions=dict(response.extensions),
)
Expand Down
8 changes: 2 additions & 6 deletions respx/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,7 @@ def resolve(self, request: httpx.Request) -> ResolvedRoute:
resolved.response = cast(ResolvedResponseTypes, prospect)
break

if resolved.response and isinstance(
resolved.response.stream, httpx.ByteStream # type: ignore[has-type]
):
if resolved.response and isinstance(resolved.response.stream, httpx.ByteStream):
resolved.response.read() # Pre-read stream

return resolved
Expand All @@ -307,9 +305,7 @@ async def aresolve(self, request: httpx.Request) -> ResolvedRoute:
resolved.response = cast(ResolvedResponseTypes, prospect)
break

if resolved.response and isinstance(
resolved.response.stream, httpx.ByteStream # type: ignore[has-type]
):
if resolved.response and isinstance(resolved.response.stream, httpx.ByteStream):
await resolved.response.aread() # Pre-read stream

return resolved
Expand Down
4 changes: 2 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ universal = 1

[flake8]
max-line-length = 88
ignore = E501,E266,E731,W503,E203,B024
ignore = B024,C408,E203,W503
exclude = .git
show-source = true

Expand Down Expand Up @@ -36,7 +36,7 @@ skip_covered = True
show_missing = True

[mypy]
python_version = 3.6
python_version = 3.7
files = respx,tests
pretty = True

Expand Down
3 changes: 1 addition & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
Expand All @@ -39,6 +38,6 @@
entry_points={"pytest11": ["respx = respx.plugin"]},
include_package_data=True,
zip_safe=False,
python_requires=">=3.6",
python_requires=">=3.7",
install_requires=["httpx>=0.21.0"],
)
23 changes: 1 addition & 22 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from respx.router import MockRouter


@pytest.mark.asyncio
async def test_http_methods(client):
async with respx.mock:
url = "https://foo.bar"
Expand Down Expand Up @@ -73,7 +72,6 @@ async def test_http_methods(client):
assert respx.calls.call_count == 8 * 2


@pytest.mark.asyncio
@pytest.mark.parametrize(
"url,pattern",
[
Expand All @@ -95,14 +93,12 @@ async def test_url_match(client, url, pattern):
assert response.text == "baz"


@pytest.mark.asyncio
async def test_invalid_url_pattern():
async with MockRouter() as respx_mock:
with pytest.raises(TypeError):
respx_mock.get(["invalid"]) # type: ignore[arg-type]


@pytest.mark.asyncio
async def test_repeated_pattern(client):
async with MockRouter() as respx_mock:
url = "https://foo/bar/baz/"
Expand All @@ -127,7 +123,6 @@ async def test_repeated_pattern(client):
assert statuses == [201, 409]


@pytest.mark.asyncio
async def test_status_code(client):
async with MockRouter() as respx_mock:
url = "https://foo.bar/"
Expand All @@ -138,7 +133,6 @@ async def test_status_code(client):
assert response.status_code == 404


@pytest.mark.asyncio
@pytest.mark.parametrize(
"headers,content_type,expected",
[
Expand Down Expand Up @@ -166,7 +160,6 @@ async def test_headers(client, headers, content_type, expected):
assert response.headers == httpx.Headers(expected)


@pytest.mark.asyncio
@pytest.mark.parametrize(
"content,expected",
[
Expand All @@ -184,7 +177,6 @@ async def test_text_encoding(client, content, expected):
assert response.text == expected


@pytest.mark.asyncio
@pytest.mark.parametrize(
"key,value,expected_content_type",
[
Expand Down Expand Up @@ -214,7 +206,6 @@ async def test_content_variants(client, key, value, expected_content_type):
assert sync_response.content is not None


@pytest.mark.asyncio
@pytest.mark.parametrize(
"content,headers,expected_headers",
[
Expand Down Expand Up @@ -272,15 +263,11 @@ def test_json_post_body():
assert get_route.called


@pytest.mark.asyncio
async def test_raising_content(client):
async with MockRouter() as respx_mock:
url = "https://foo.bar/"
request = respx_mock.get(url)
request.side_effect = httpx.ConnectTimeout(
"X-P",
request=None, # type: ignore[arg-type]
)
request.side_effect = httpx.ConnectTimeout("X-P", request=None)
with pytest.raises(httpx.ConnectTimeout):
await client.get(url)

Expand All @@ -301,7 +288,6 @@ async def test_raising_content(client):
assert route.calls.last.response


@pytest.mark.asyncio
async def test_callable_content(client):
async with MockRouter() as respx_mock:
url_pattern = re.compile(r"https://foo.bar/(?P<slug>\w+)/")
Expand All @@ -327,7 +313,6 @@ def content_callback(request, slug):
assert request.calls[-1][0].content == b'{"x": "!"}'


@pytest.mark.asyncio
async def test_request_callback(client):
def callback(request, name):
if request.url.host == "foo.bar" and request.content == b'{"foo": "bar"}':
Expand Down Expand Up @@ -375,7 +360,6 @@ def _callback(request):
await client.get("https://egg.plant/")


@pytest.mark.asyncio
@pytest.mark.parametrize(
"using,route,expected",
[
Expand Down Expand Up @@ -415,7 +399,6 @@ async def test_pass_through(client, using, route, expected):


@respx.mock
@pytest.mark.asyncio
async def test_parallel_requests(client):
def content(request, page):
return httpx.Response(200, text=page)
Expand All @@ -433,7 +416,6 @@ def content(request, page):
assert respx.calls.call_count == 2


@pytest.mark.asyncio
@pytest.mark.parametrize(
"method_str, client_method_attr",
[
Expand Down Expand Up @@ -476,7 +458,6 @@ def test_pop():


@respx.mock
@pytest.mark.asyncio
@pytest.mark.parametrize(
"url,params,call_url,call_params",
[
Expand All @@ -503,7 +484,6 @@ async def test_params_match(client, url, params, call_url, call_params):
assert response.text == "spam spam"


@pytest.mark.asyncio
@pytest.mark.parametrize(
"base,url",
[
Expand Down Expand Up @@ -564,7 +544,6 @@ def test_respond():
route.respond(content=Exception()) # type: ignore[arg-type]


@pytest.mark.asyncio
@pytest.mark.parametrize(
"kwargs",
[
Expand Down
Loading

0 comments on commit 0c896f6

Please sign in to comment.