Skip to content

Commit

Permalink
[PR #7819/dfc3f899 backport][3.9] Skip filtering CookieJar when t…
Browse files Browse the repository at this point in the history
…he jar is empty or all cookies have expired (#7822)

**This is a backport of PR #7819 as merged into master (dfc3f89).**

<!-- Thank you for your contribution! -->

## What do these changes do?

The filtering itself and its preparation in `CookieJar.filter_cookies()`
is expensive. Sometimes there are no cookies in the jar or all cookies
have expired. Skip filtering and its preparation in this case.

Because the empty check is much cheaper than `_do_expiration()`, I think
it deserves to be duplicated before and after calling
`_do_expiration()`.

```console
$ python3.11 -m timeit -s 'from collections import defaultdict; d=defaultdict(foo="bar")' \
> 'if not d: pass'
50000000 loops, best of 5: 8.3 nsec per loop
$ python3.11 -m timeit -s 'from collections import defaultdict; d=defaultdict()' \
> 'if not d: pass'
50000000 loops, best of 5: 8.74 nsec per loop
$ python3.11 -m timeit -s 'from aiohttp import CookieJar; cj = CookieJar()' \
> 'cj._do_expiration()'
200000 loops, best of 5: 1.86 usec per loop
```

<!-- Please give a short brief about these changes. -->

## Are there changes in behavior for the user?

No.

<!-- Outline any notable behaviour for the end users. -->

## Related issue number

#7583 (comment)

<!-- Are there any issues opened that will be resolved by merging this
change? -->

## Checklist

- [x] I think the code is well written
- [ ] Unit tests for the changes exist
- [ ] Documentation reflects the changes
- [x] If you provide code modification, please add yourself to
`CONTRIBUTORS.txt`
  * The format is &lt;Name&gt; &lt;Surname&gt;.
  * Please keep alphabetical order, the file is sorted by names.
- [x] Add a new news fragment into the `CHANGES` folder
  * name it `<issue_id>.<type>` for example (588.bugfix)
* if you don't have an `issue_id` change it to the pr id after creating
the pr
  * ensure type is one of the following:
    * `.feature`: Signifying a new feature.
    * `.bugfix`: Signifying a bug fix.
    * `.doc`: Signifying a documentation improvement.
    * `.removal`: Signifying a deprecation or removal of public API.
* `.misc`: A ticket has been closed, but it is not of interest to users.
* Make sure to use full sentences with correct case and punctuation, for
example: "Fix issue with non-ascii contents in doctest text files."
  • Loading branch information
Rongronggg9 authored Nov 12, 2023
1 parent fffc433 commit 85ec0e4
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGES/7819.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Skip filtering ``CookieJar`` when the jar is empty or all cookies have expired.
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ Required Field
Robert Lu
Robert Nikolich
Roman Podoliaka
Rong Zhang
Samir Akarioh
Samuel Colvin
Sean Hunt
Expand Down
10 changes: 8 additions & 2 deletions aiohttp/cookiejar.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,17 @@ def filter_cookies(
self, request_url: URL = URL()
) -> Union["BaseCookie[str]", "SimpleCookie[str]"]:
"""Returns this jar's cookies filtered by their attributes."""
self._do_expiration()
request_url = URL(request_url)
filtered: Union["SimpleCookie[str]", "BaseCookie[str]"] = (
SimpleCookie() if self._quote_cookie else BaseCookie()
)
if not self._cookies:
# Skip do_expiration() if there are no cookies.
return filtered
self._do_expiration()
if not self._cookies:
# Skip rest of function if no non-expired cookies.
return filtered
request_url = URL(request_url)
hostname = request_url.raw_host or ""
request_origin = URL()
with contextlib.suppress(ValueError):
Expand Down

0 comments on commit 85ec0e4

Please sign in to comment.