Support partitioned in Response.delete_cookie#3376
Conversation
`Response.set_cookie` accepts a `partitioned` flag, but its sibling `delete_cookie` does not. Deleting a partitioned (CHIPS) cookie requires the clearing `Set-Cookie` to also carry the `Partitioned` attribute, otherwise the browser will not match and remove it. Add `partitioned: bool = False` to `delete_cookie`, forwarding it to `set_cookie` alongside the other attributes so the two methods stay in parity. Add a version-safe test covering the delete path. Co-authored-by: Claude <noreply@anthropic.com> Signed-off-by: sungbin1015 <sbin@solbox.com>
There was a problem hiding this comment.
1 issue found across 3 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="starlette/responses.py">
<violation number="1" location="starlette/responses.py:153">
P1: `delete_cookie("key", partitioned=True)` uses the default `secure=False`, so browsers reject the `Partitioned` expiry header and the cookie remains. Forward `secure=secure or partitioned` (or reject that invalid combination) when `partitioned` is requested.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| secure=secure, | ||
| httponly=httponly, | ||
| samesite=samesite, | ||
| partitioned=partitioned, |
There was a problem hiding this comment.
P1: delete_cookie("key", partitioned=True) uses the default secure=False, so browsers reject the Partitioned expiry header and the cookie remains. Forward secure=secure or partitioned (or reject that invalid combination) when partitioned is requested.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At starlette/responses.py, line 153:
<comment>`delete_cookie("key", partitioned=True)` uses the default `secure=False`, so browsers reject the `Partitioned` expiry header and the cookie remains. Forward `secure=secure or partitioned` (or reject that invalid combination) when `partitioned` is requested.</comment>
<file context>
@@ -149,6 +150,7 @@ def delete_cookie(
secure=secure,
httponly=httponly,
samesite=samesite,
+ partitioned=partitioned,
)
</file context>
Add the partitioned description (including the Python 3.14+ constraint) to the delete_cookie signature docs, mirroring set_cookie. Addresses review feedback on PR Kludex#3376. Co-authored-by: Claude <noreply@anthropic.com> Signed-off-by: sungbin1015 <sbin@solbox.com>
|
Thanks for the review! P3 (docs): Fixed in 6beb4d9 — added the P1 (coerce
|
The previous version-gated if/else left the 3.14+ assertion line uncovered on Python <3.14, failing the repo's 100% coverage gate. Mirror the set_cookie partitioned test: derive the expected `Partitioned` marker via a ternary and assert with a single branchless statement, so every Python version reaches 100% coverage. Co-authored-by: Claude <noreply@anthropic.com> Signed-off-by: sungbin1015 <sbin@solbox.com>
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="tests/test_responses.py">
<violation number="1" location="tests/test_responses.py:528">
P2: The branchless refactoring loses negative coverage for Python < 3.14. When `partitioned_text` is `""`, `assert "" in response.headers["set-cookie"]` is always true, so the test never actually verifies that "Partitioned" is absent from the header. Compare with the `set_cookie` test where a full `==` equality makes the branchless pattern safe — here the `in` operator and empty string make it vacuous. Consider restoring the explicit `assert "Partitioned" not in response.headers["set-cookie"]` path for Python < 3.14, or switching to a full equality check similar to the set_cookie test.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
|
|
||
| client = test_client_factory(app) | ||
| response = client.get("/") | ||
| assert partitioned_text in response.headers["set-cookie"] |
There was a problem hiding this comment.
P2: The branchless refactoring loses negative coverage for Python < 3.14. When partitioned_text is "", assert "" in response.headers["set-cookie"] is always true, so the test never actually verifies that "Partitioned" is absent from the header. Compare with the set_cookie test where a full == equality makes the branchless pattern safe — here the in operator and empty string make it vacuous. Consider restoring the explicit assert "Partitioned" not in response.headers["set-cookie"] path for Python < 3.14, or switching to a full equality check similar to the set_cookie test.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tests/test_responses.py, line 528:
<comment>The branchless refactoring loses negative coverage for Python < 3.14. When `partitioned_text` is `""`, `assert "" in response.headers["set-cookie"]` is always true, so the test never actually verifies that "Partitioned" is absent from the header. Compare with the `set_cookie` test where a full `==` equality makes the branchless pattern safe — here the `in` operator and empty string make it vacuous. Consider restoring the explicit `assert "Partitioned" not in response.headers["set-cookie"]` path for Python < 3.14, or switching to a full equality check similar to the set_cookie test.</comment>
<file context>
@@ -521,13 +521,11 @@ async def app(scope: Scope, receive: Receive, send: Send) -> None:
- assert "Partitioned" in set_cookie
- else:
- assert "Partitioned" not in set_cookie
+ assert partitioned_text in response.headers["set-cookie"]
</file context>
Summary
Response.set_cookieaccepts apartitionedflag, but its siblingdelete_cookiedoes not. Deleting a partitioned (CHIPS) cookie requires the clearingSet-Cookieto also carry thePartitionedattribute — otherwise the browser will not match and remove the cookie.This adds
partitioned: bool = Falsetodelete_cookie, forwarding it toset_cookiealongside the other attributes so the two methods stay in parity. The existing Python 3.14+ gating lives inset_cookie, so no new gating is needed here.Changes
starlette/responses.py— addpartitionedparam todelete_cookie, forward toset_cookie.tests/test_responses.py— addtest_delete_cookie_partitioned(version-safe: assertsPartitionedon 3.14+, absent otherwise, mirroringtest_set_cookie).docs/responses.md— update thedelete_cookiesignature (it was stale, also missingsecure/httponly/samesite).Testing
Local interpreter is Python 3.13, so the
< 3.14path is exercised locally; the>= 3.14path is covered by the CI matrix.This PR was prepared with AI assistance (Claude); every changed line was reviewed and the tests above were run locally.