Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .github/renovate.json5
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,29 @@
matchManagers: ["pep621"],
groupName: "python dependencies",
},
// A tool pinned both as a pre-commit hook and in uv.lock must move in
// one PR. CI lints with the locked version and contributors run the hook,
// so when only one side moved (#453), pre-commit failed on master while CI
// stayed green. These rules come after the manager groups above, so their
// groupName wins. `bump` raises the pyproject floor to the new version,
// which makes the PR relock to it too.
{
description: "Keep the ruff pre-commit hook and the locked ruff in step",
matchPackageNames: ["ruff", "astral-sh/ruff-pre-commit"],
groupName: "ruff",
rangeStrategy: "bump",
},
{
description: "Keep the mypy pre-commit hook and the locked mypy in step",
matchPackageNames: ["mypy", "pre-commit/mirrors-mypy"],
groupName: "mypy",
rangeStrategy: "bump",
},
{
description: "Keep the uv pre-commit hook (uv lock) and the uv_build backend in step",
matchPackageNames: ["uv_build", "astral-sh/uv-pre-commit"],
groupName: "uv",
},
{
description: "Automerge non-major updates once CI passes",
matchUpdateTypes: ["minor", "patch", "pin", "digest"],
Expand Down
13 changes: 7 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,14 @@ repos:
- id: mypy
name: Static type checking with mypy
# The hook runs in its own virtualenv, so it needs every package the
# checked code imports, including the optional backends.
# checked code imports, including the optional backends. Keep the
# floors in step with pyproject.toml; the rev with the locked mypy
# (Renovate groups the two).
additional_dependencies:
- fastapi>=0.110.0
- starlette>=0.36.0
- pydantic>=2.0.0
- pytest>=8.0.0
- pytest-asyncio>=0.23.0
- fastapi>=0.128.2
- pydantic>=2.7.0
- pytest>=8.3.5
- pytest-asyncio>=0.26.0
- redis>=5.3.0
- types-redis
- orjson
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,15 @@ dev = [
"httpx2>=2.13.1",
# Starlette's SessionMiddleware, which tests of the session bypass use.
"itsdangerous>=1.1.0",
"mypy>=1.15.0",
"mypy>=2.4.0",
"orjson>=3.10.16",
"pre-commit>=4.2.0",
"pymemcache>=4.0.0",
"pytest>=8.3.5",
"pytest-asyncio>=0.26.0",
"pytest-cov>=6.1.0",
"redis[hiredis]>=5.3.0",
"ruff>=0.11.2",
"ruff>=0.17.0",
"tox>=4.25.0",
"tox-uv>=1.29.0",
"ty>=0.0.1a34",
Expand Down
4 changes: 2 additions & 2 deletions scripts/changelog_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@

import argparse
import dataclasses
import datetime
import datetime as dt
import re
import sys
from pathlib import Path
Expand Down Expand Up @@ -458,7 +458,7 @@ def release_notes(body: str, version: str, date: str) -> str:


def _today() -> str:
return datetime.datetime.now(tz=datetime.timezone.utc).date().isoformat()
return dt.datetime.now(tz=dt.timezone.utc).date().isoformat()


def _parse_args(argv: list[str] | None) -> argparse.Namespace:
Expand Down
6 changes: 4 additions & 2 deletions tests/backends/test_redis.py
Original file line number Diff line number Diff line change
Expand Up @@ -1358,8 +1358,10 @@ async def ttl_zero() -> dict[str, str]:
"/ttl-zero", headers={"If-None-Match": first.headers["ETag"]}
)
# Clean up inside the client's event loop, which owns the pool.
client.portal.call(backend.clear) # type: ignore[union-attr]
client.portal.call(backend.aclose) # type: ignore[union-attr]
# `portal` is Optional in the stubs of some starlette releases.
assert client.portal is not None
client.portal.call(backend.clear)
client.portal.call(backend.aclose)

assert first.status_code == 200
assert first.headers["Cache-Control"] == "max-age=0"
Expand Down
4 changes: 2 additions & 2 deletions tests/test_changelog_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,9 @@ def test_main_defaults_the_date_to_today(tmp_path: Path):

assert main(["--version", "0.3.5", "--changelog", str(changelog)]) == 0

import datetime
import datetime as dt

today = datetime.datetime.now(tz=datetime.timezone.utc).date().isoformat()
today = dt.datetime.now(tz=dt.timezone.utc).date().isoformat()
assert f"## [0.3.5] - {today}" in changelog.read_text(encoding="utf-8")


Expand Down
7 changes: 5 additions & 2 deletions tests/test_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,10 @@ def test_redis_backend(monkeypatch: pytest.MonkeyPatch) -> None:
example = load_example("redis_backend")
with TestClient(example.app) as client:
backend = BackendProxy.get()
client.portal.call(backend.clear) # type: ignore[union-attr]
# `portal` is Optional in the stubs of some starlette releases.
portal = client.portal
assert portal is not None
portal.call(backend.clear)
try:
first = client.get("/hello/redis")
assert first.json() == {"hello": "redis"}
Expand All @@ -228,7 +231,7 @@ def test_redis_backend(monkeypatch: pytest.MonkeyPatch) -> None:
assert client.post("/visits").json() == {"visits": 1}
assert client.post("/visits").json() == {"visits": 2}
finally:
client.portal.call(backend.clear) # type: ignore[union-attr]
portal.call(backend.clear)
# The lifespan unregistered the backend on shutdown.
with pytest.raises(BackendNotFoundError):
BackendProxy.get()
Loading
Loading