Source code for treq.cookies

# -*- test-case-name: treq.test.test_treq_integration -*-
"""
Convenience helpers for :mod:`http.cookiejar`
"""

from collections.abc import Iterable
from http.cookiejar import Cookie, CookieJar
from typing import Optional, Union

from hyperlink import EncodedURL


[docs] class CookieCollision(Exception): """ Raised by :meth:`IndexableCookieJar.__getitem__` when more than one matching cookie is found. """
[docs] class IndexableCookieJar(CookieJar): """ An :py:class:`IndexableCookieJar` is Treq's subclass of the standard library :py:class:`http.cookiejar.CookieJar`, which, like the one from `requests`_, allows for indexing to retrieve cookie values. This is for convenience and for compatibility with `requests`_ users' expectations. .. _requests: https://requests.readthedocs.io/en/latest/ .. note:: In general, you should not need to import or instantiate a :py:class:`IndexableCookieJar` directly; anywhere that Treq requires cookies, a :py:class:`http.cookiejar.CookieJar` or ``dict`` of ``str`` to ``str`` should be acceptable; but :py:meth:`treq.response._Response.cookies` returns one that is also indexable. """
[docs] def __getitem__(self, name: str) -> str: """ Search the jar for a uniquely-named cookie. This is O(n) on the number of cookies in the jar. .. note:: This method exists for compatibility with `RequestsCookieJar`_, but is difficult to use securely when following HTTP redirects. Prefer :func:`treq.cookies.search()`, which lets you limit the search to a specific domain name. .. note:: This method ignores cookies with no value (`None`), but may return an empty string, `unlike requests`_. :param name: The name of the cookie to retrieve. :raises KeyError: when no cookie with a value has the given name. :raises CookieCollision: when more than one cookie has the given name. .. _RequestsCookieJar: https://requests.readthedocs.io/en/latest/api/#requests.cookies.RequestsCookieJar .. _unlike requests: https://github.com/psf/requests/issues/7003 """ value: str | None = None for cookie in self: if cookie.name == name and cookie.value is not None: if value is None: value = cookie.value else: raise CookieCollision(name) if value is None: raise KeyError(name) return value