{
    "file_diffs": [
        {
            "old_file_content": "",
            "new_file_content": "Fix duplicate cookie expiration calls in the CookieJar implementation\n",
            "header": {
                "file": {
                    "path": "CHANGES/7784.bugfix"
                },
                "misc_line": "new file mode 100644"
            },
            "index_line": {
                "old_commit_hash": "00000000",
                "new_commit_hash": "1f8ba8dd",
                "mode": ""
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "/dev/null"
            },
            "plus_file": {
                "path": "b/CHANGES/7784.bugfix"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 0,
                            "length": 0
                        },
                        "new_range": {
                            "start": 1,
                            "length": null
                        },
                        "section": ""
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "Fix duplicate cookie expiration calls in the CookieJar implementation",
                                "type": "added"
                            }
                        ]
                    },
                    "modified_entities": [],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "import calendar\nimport contextlib\nimport datetime\nimport itertools\nimport os  # noqa\nimport pathlib\nimport pickle\nimport re\nimport time\nimport warnings\nfrom collections import defaultdict\nfrom http.cookies import BaseCookie, Morsel, SimpleCookie\nfrom math import ceil\nfrom typing import (\n    DefaultDict,\n    Dict,\n    Iterable,\n    Iterator,\n    List,\n    Mapping,\n    Optional,\n    Set,\n    Tuple,\n    Union,\n    cast,\n)\n\nfrom yarl import URL\n\nfrom .abc import AbstractCookieJar, ClearCookiePredicate\nfrom .helpers import is_ip_address\nfrom .typedefs import LooseCookies, PathLike, StrOrURL\n\n__all__ = (\"CookieJar\", \"DummyCookieJar\")\n\n\nCookieItem = Union[str, \"Morsel[str]\"]\n\n\nclass CookieJar(AbstractCookieJar):\n    \"\"\"Implements cookie storage adhering to RFC 6265.\"\"\"\n\n    DATE_TOKENS_RE = re.compile(\n        r\"[\\x09\\x20-\\x2F\\x3B-\\x40\\x5B-\\x60\\x7B-\\x7E]*\"\n        r\"(?P<token>[\\x00-\\x08\\x0A-\\x1F\\d:a-zA-Z\\x7F-\\xFF]+)\"\n    )\n\n    DATE_HMS_TIME_RE = re.compile(r\"(\\d{1,2}):(\\d{1,2}):(\\d{1,2})\")\n\n    DATE_DAY_OF_MONTH_RE = re.compile(r\"(\\d{1,2})\")\n\n    DATE_MONTH_RE = re.compile(\n        \"(jan)|(feb)|(mar)|(apr)|(may)|(jun)|(jul)|\" \"(aug)|(sep)|(oct)|(nov)|(dec)\",\n        re.I,\n    )\n\n    DATE_YEAR_RE = re.compile(r\"(\\d{2,4})\")\n\n    # calendar.timegm() fails for timestamps after datetime.datetime.max\n    # Minus one as a loss of precision occurs when timestamp() is called.\n    MAX_TIME = (\n        int(datetime.datetime.max.replace(tzinfo=datetime.timezone.utc).timestamp()) - 1\n    )\n    try:\n        calendar.timegm(time.gmtime(MAX_TIME))\n    except (OSError, ValueError):\n        # Hit the maximum representable time on Windows\n        # https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/localtime-localtime32-localtime64\n        # Throws ValueError on PyPy 3.8 and 3.9, OSError elsewhere\n        MAX_TIME = calendar.timegm((3000, 12, 31, 23, 59, 59, -1, -1, -1))\n    except OverflowError:\n        # #4515: datetime.max may not be representable on 32-bit platforms\n        MAX_TIME = 2**31 - 1\n    # Avoid minuses in the future, 3x faster\n    SUB_MAX_TIME = MAX_TIME - 1\n\n    def __init__(\n        self,\n        *,\n        unsafe: bool = False,\n        quote_cookie: bool = True,\n        treat_as_secure_origin: Union[StrOrURL, List[StrOrURL], None] = None,\n    ) -> None:\n        self._cookies: DefaultDict[Tuple[str, str], SimpleCookie] = defaultdict(\n            SimpleCookie\n        )\n        self._host_only_cookies: Set[Tuple[str, str]] = set()\n        self._unsafe = unsafe\n        self._quote_cookie = quote_cookie\n        if treat_as_secure_origin is None:\n            treat_as_secure_origin = []\n        elif isinstance(treat_as_secure_origin, URL):\n            treat_as_secure_origin = [treat_as_secure_origin.origin()]\n        elif isinstance(treat_as_secure_origin, str):\n            treat_as_secure_origin = [URL(treat_as_secure_origin).origin()]\n        else:\n            treat_as_secure_origin = [\n                URL(url).origin() if isinstance(url, str) else url.origin()\n                for url in treat_as_secure_origin\n            ]\n        self._treat_as_secure_origin = treat_as_secure_origin\n        self._next_expiration: float = ceil(time.time())\n        self._expirations: Dict[Tuple[str, str, str], float] = {}\n\n    def save(self, file_path: PathLike) -> None:\n        file_path = pathlib.Path(file_path)\n        with file_path.open(mode=\"wb\") as f:\n            pickle.dump(self._cookies, f, pickle.HIGHEST_PROTOCOL)\n\n    def load(self, file_path: PathLike) -> None:\n        file_path = pathlib.Path(file_path)\n        with file_path.open(mode=\"rb\") as f:\n            self._cookies = pickle.load(f)\n\n    def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None:\n        if predicate is None:\n            self._next_expiration = ceil(time.time())\n            self._cookies.clear()\n            self._host_only_cookies.clear()\n            self._expirations.clear()\n            return\n\n        to_del = []\n        now = time.time()\n        for (domain, path), cookie in self._cookies.items():\n            for name, morsel in cookie.items():\n                key = (domain, path, name)\n                if (\n                    key in self._expirations and self._expirations[key] <= now\n                ) or predicate(morsel):\n                    to_del.append(key)\n\n        for domain, path, name in to_del:\n            self._host_only_cookies.discard((domain, name))\n            key = (domain, path, name)\n            if key in self._expirations:\n                del self._expirations[(domain, path, name)]\n            self._cookies[(domain, path)].pop(name, None)\n\n        self._next_expiration = (\n            min(*self._expirations.values(), self.SUB_MAX_TIME) + 1\n            if self._expirations\n            else self.MAX_TIME\n        )\n\n    def clear_domain(self, domain: str) -> None:\n        self.clear(lambda x: self._is_domain_match(domain, x[\"domain\"]))\n\n    def __iter__(self) -> \"Iterator[Morsel[str]]\":\n        self._do_expiration()\n        for val in self._cookies.values():\n            yield from val.values()\n\n    def __len__(self) -> int:\n        return sum(1 for i in self)\n\n    def _do_expiration(self) -> None:\n        self.clear(lambda x: False)\n\n    def _expire_cookie(self, when: float, domain: str, path: str, name: str) -> None:\n        self._next_expiration = min(self._next_expiration, when)\n        self._expirations[(domain, path, name)] = when\n\n    def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None:\n        \"\"\"Update cookies.\"\"\"\n        hostname = response_url.raw_host\n\n        if not self._unsafe and is_ip_address(hostname):\n            # Don't accept cookies from IPs\n            return\n\n        if isinstance(cookies, Mapping):\n            cookies = cookies.items()\n\n        for name, cookie in cookies:\n            if not isinstance(cookie, Morsel):\n                tmp = SimpleCookie()\n                tmp[name] = cookie  # type: ignore[assignment]\n                cookie = tmp[name]\n\n            domain = cookie[\"domain\"]\n\n            # ignore domains with trailing dots\n            if domain.endswith(\".\"):\n                domain = \"\"\n                del cookie[\"domain\"]\n\n            if not domain and hostname is not None:\n                # Set the cookie's domain to the response hostname\n                # and set its host-only-flag\n                self._host_only_cookies.add((hostname, name))\n                domain = cookie[\"domain\"] = hostname\n\n            if domain.startswith(\".\"):\n                # Remove leading dot\n                domain = domain[1:]\n                cookie[\"domain\"] = domain\n\n            if hostname and not self._is_domain_match(domain, hostname):\n                # Setting cookies for different domains is not allowed\n                continue\n\n            path = cookie[\"path\"]\n            if not path or not path.startswith(\"/\"):\n                # Set the cookie's path to the response path\n                path = response_url.path\n                if not path.startswith(\"/\"):\n                    path = \"/\"\n                else:\n                    # Cut everything from the last slash to the end\n                    path = \"/\" + path[1 : path.rfind(\"/\")]\n                cookie[\"path\"] = path\n            path = path.rstrip(\"/\")\n\n            max_age = cookie[\"max-age\"]\n            if max_age:\n                try:\n                    delta_seconds = int(max_age)\n                    max_age_expiration = min(time.time() + delta_seconds, self.MAX_TIME)\n                    self._expire_cookie(max_age_expiration, domain, path, name)\n                except ValueError:\n                    cookie[\"max-age\"] = \"\"\n\n            else:\n                expires = cookie[\"expires\"]\n                if expires:\n                    expire_time = self._parse_date(expires)\n                    if expire_time:\n                        self._expire_cookie(expire_time, domain, path, name)\n                    else:\n                        cookie[\"expires\"] = \"\"\n\n            self._cookies[(domain, path)][name] = cookie\n\n        self._do_expiration()\n\n    def filter_cookies(self, request_url: URL = URL()) -> \"BaseCookie[str]\":\n        \"\"\"Returns this jar's cookies filtered by their attributes.\"\"\"\n        if not isinstance(request_url, URL):\n            warnings.warn(\n                \"The method accepts yarl.URL instances only, got {}\".format(\n                    type(request_url)\n                ),\n                DeprecationWarning,\n            )\n            request_url = URL(request_url)\n        filtered: Union[SimpleCookie, \"BaseCookie[str]\"] = (\n            SimpleCookie() if self._quote_cookie else BaseCookie()\n        )\n        if not self._cookies:\n            # Skip do_expiration() if there are no cookies.\n            return filtered\n        self._do_expiration()\n        if not self._cookies:\n            # Skip rest of function if no non-expired cookies.\n            return filtered\n        hostname = request_url.raw_host or \"\"\n\n        is_not_secure = request_url.scheme not in (\"https\", \"wss\")\n        if is_not_secure and self._treat_as_secure_origin:\n            request_origin = URL()\n            with contextlib.suppress(ValueError):\n                request_origin = request_url.origin()\n            is_not_secure = request_origin not in self._treat_as_secure_origin\n\n        # Send shared cookie\n        for c in self._cookies[(\"\", \"\")].values():\n            filtered[c.key] = c.value\n\n        if is_ip_address(hostname):\n            if not self._unsafe:\n                return filtered\n            domains: Iterable[str] = (hostname,)\n        else:\n            # Get all the subdomains that might match a cookie (e.g. \"foo.bar.com\", \"bar.com\", \"com\")\n            domains = itertools.accumulate(\n                reversed(hostname.split(\".\")), lambda x, y: f\"{y}.{x}\"\n            )\n        # Get all the path prefixes that might match a cookie (e.g. \"\", \"/foo\", \"/foo/bar\")\n        paths = itertools.accumulate(\n            request_url.path.split(\"/\"), lambda x, y: f\"{x}/{y}\"\n        )\n        # Create every combination of (domain, path) pairs.\n        pairs = itertools.product(domains, paths)\n\n        # Point 2: https://www.rfc-editor.org/rfc/rfc6265.html#section-5.4\n        cookies = itertools.chain.from_iterable(\n            self._cookies[p].values() for p in pairs\n        )\n        path_len = len(request_url.path)\n        for cookie in cookies:\n            name = cookie.key\n            domain = cookie[\"domain\"]\n\n            if (domain, name) in self._host_only_cookies:\n                if domain != hostname:\n                    continue\n\n            # Skip edge case when the cookie has a trailing slash but request doesn't.\n            if len(cookie[\"path\"]) > path_len:\n                continue\n\n            if is_not_secure and cookie[\"secure\"]:\n                continue\n\n            # It's critical we use the Morsel so the coded_value\n            # (based on cookie version) is preserved\n            mrsl_val = cast(\"Morsel[str]\", cookie.get(cookie.key, Morsel()))\n            mrsl_val.set(cookie.key, cookie.value, cookie.coded_value)\n            filtered[name] = mrsl_val\n\n        return filtered\n\n    @staticmethod\n    def _is_domain_match(domain: str, hostname: str) -> bool:\n        \"\"\"Implements domain matching adhering to RFC 6265.\"\"\"\n        if hostname == domain:\n            return True\n\n        if not hostname.endswith(domain):\n            return False\n\n        non_matching = hostname[: -len(domain)]\n\n        if not non_matching.endswith(\".\"):\n            return False\n\n        return not is_ip_address(hostname)\n\n    @classmethod\n    def _parse_date(cls, date_str: str) -> Optional[int]:\n        \"\"\"Implements date string parsing adhering to RFC 6265.\"\"\"\n        if not date_str:\n            return None\n\n        found_time = False\n        found_day = False\n        found_month = False\n        found_year = False\n\n        hour = minute = second = 0\n        day = 0\n        month = 0\n        year = 0\n\n        for token_match in cls.DATE_TOKENS_RE.finditer(date_str):\n            token = token_match.group(\"token\")\n\n            if not found_time:\n                time_match = cls.DATE_HMS_TIME_RE.match(token)\n                if time_match:\n                    found_time = True\n                    hour, minute, second = (int(s) for s in time_match.groups())\n                    continue\n\n            if not found_day:\n                day_match = cls.DATE_DAY_OF_MONTH_RE.match(token)\n                if day_match:\n                    found_day = True\n                    day = int(day_match.group())\n                    continue\n\n            if not found_month:\n                month_match = cls.DATE_MONTH_RE.match(token)\n                if month_match:\n                    found_month = True\n                    assert month_match.lastindex is not None\n                    month = month_match.lastindex\n                    continue\n\n            if not found_year:\n                year_match = cls.DATE_YEAR_RE.match(token)\n                if year_match:\n                    found_year = True\n                    year = int(year_match.group())\n\n        if 70 <= year <= 99:\n            year += 1900\n        elif 0 <= year <= 69:\n            year += 2000\n\n        if False in (found_day, found_month, found_year, found_time):\n            return None\n\n        if not 1 <= day <= 31:\n            return None\n\n        if year < 1601 or hour > 23 or minute > 59 or second > 59:\n            return None\n\n        return calendar.timegm((year, month, day, hour, minute, second, -1, -1, -1))\n\n\nclass DummyCookieJar(AbstractCookieJar):\n    \"\"\"Implements a dummy cookie storage.\n\n    It can be used with the ClientSession when no cookie processing is needed.\n\n    \"\"\"\n\n    def __iter__(self) -> \"Iterator[Morsel[str]]\":\n        while False:\n            yield None\n\n    def __len__(self) -> int:\n        return 0\n\n    def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None:\n        pass\n\n    def clear_domain(self, domain: str) -> None:\n        pass\n\n    def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None:\n        pass\n\n    def filter_cookies(self, request_url: URL) -> \"BaseCookie[str]\":\n        return SimpleCookie()\n",
            "new_file_content": "import calendar\nimport contextlib\nimport datetime\nimport itertools\nimport os  # noqa\nimport pathlib\nimport pickle\nimport re\nimport time\nimport warnings\nfrom collections import defaultdict\nfrom http.cookies import BaseCookie, Morsel, SimpleCookie\nfrom math import ceil\nfrom typing import (\n    DefaultDict,\n    Dict,\n    Iterable,\n    Iterator,\n    List,\n    Mapping,\n    Optional,\n    Set,\n    Tuple,\n    Union,\n    cast,\n)\n\nfrom yarl import URL\n\nfrom .abc import AbstractCookieJar, ClearCookiePredicate\nfrom .helpers import is_ip_address\nfrom .typedefs import LooseCookies, PathLike, StrOrURL\n\n__all__ = (\"CookieJar\", \"DummyCookieJar\")\n\n\nCookieItem = Union[str, \"Morsel[str]\"]\n\n\nclass CookieJar(AbstractCookieJar):\n    \"\"\"Implements cookie storage adhering to RFC 6265.\"\"\"\n\n    DATE_TOKENS_RE = re.compile(\n        r\"[\\x09\\x20-\\x2F\\x3B-\\x40\\x5B-\\x60\\x7B-\\x7E]*\"\n        r\"(?P<token>[\\x00-\\x08\\x0A-\\x1F\\d:a-zA-Z\\x7F-\\xFF]+)\"\n    )\n\n    DATE_HMS_TIME_RE = re.compile(r\"(\\d{1,2}):(\\d{1,2}):(\\d{1,2})\")\n\n    DATE_DAY_OF_MONTH_RE = re.compile(r\"(\\d{1,2})\")\n\n    DATE_MONTH_RE = re.compile(\n        \"(jan)|(feb)|(mar)|(apr)|(may)|(jun)|(jul)|\" \"(aug)|(sep)|(oct)|(nov)|(dec)\",\n        re.I,\n    )\n\n    DATE_YEAR_RE = re.compile(r\"(\\d{2,4})\")\n\n    # calendar.timegm() fails for timestamps after datetime.datetime.max\n    # Minus one as a loss of precision occurs when timestamp() is called.\n    MAX_TIME = (\n        int(datetime.datetime.max.replace(tzinfo=datetime.timezone.utc).timestamp()) - 1\n    )\n    try:\n        calendar.timegm(time.gmtime(MAX_TIME))\n    except (OSError, ValueError):\n        # Hit the maximum representable time on Windows\n        # https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/localtime-localtime32-localtime64\n        # Throws ValueError on PyPy 3.8 and 3.9, OSError elsewhere\n        MAX_TIME = calendar.timegm((3000, 12, 31, 23, 59, 59, -1, -1, -1))\n    except OverflowError:\n        # #4515: datetime.max may not be representable on 32-bit platforms\n        MAX_TIME = 2**31 - 1\n    # Avoid minuses in the future, 3x faster\n    SUB_MAX_TIME = MAX_TIME - 1\n\n    def __init__(\n        self,\n        *,\n        unsafe: bool = False,\n        quote_cookie: bool = True,\n        treat_as_secure_origin: Union[StrOrURL, List[StrOrURL], None] = None,\n    ) -> None:\n        self._cookies: DefaultDict[Tuple[str, str], SimpleCookie] = defaultdict(\n            SimpleCookie\n        )\n        self._host_only_cookies: Set[Tuple[str, str]] = set()\n        self._unsafe = unsafe\n        self._quote_cookie = quote_cookie\n        if treat_as_secure_origin is None:\n            treat_as_secure_origin = []\n        elif isinstance(treat_as_secure_origin, URL):\n            treat_as_secure_origin = [treat_as_secure_origin.origin()]\n        elif isinstance(treat_as_secure_origin, str):\n            treat_as_secure_origin = [URL(treat_as_secure_origin).origin()]\n        else:\n            treat_as_secure_origin = [\n                URL(url).origin() if isinstance(url, str) else url.origin()\n                for url in treat_as_secure_origin\n            ]\n        self._treat_as_secure_origin = treat_as_secure_origin\n        self._next_expiration: float = ceil(time.time())\n        self._expirations: Dict[Tuple[str, str, str], float] = {}\n\n    def save(self, file_path: PathLike) -> None:\n        file_path = pathlib.Path(file_path)\n        with file_path.open(mode=\"wb\") as f:\n            pickle.dump(self._cookies, f, pickle.HIGHEST_PROTOCOL)\n\n    def load(self, file_path: PathLike) -> None:\n        file_path = pathlib.Path(file_path)\n        with file_path.open(mode=\"rb\") as f:\n            self._cookies = pickle.load(f)\n\n    def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None:\n        if predicate is None:\n            self._next_expiration = ceil(time.time())\n            self._cookies.clear()\n            self._host_only_cookies.clear()\n            self._expirations.clear()\n            return\n\n        to_del = []\n        now = time.time()\n        for (domain, path), cookie in self._cookies.items():\n            for name, morsel in cookie.items():\n                key = (domain, path, name)\n                if (\n                    key in self._expirations and self._expirations[key] <= now\n                ) or predicate(morsel):\n                    to_del.append(key)\n\n        for domain, path, name in to_del:\n            self._host_only_cookies.discard((domain, name))\n            key = (domain, path, name)\n            if key in self._expirations:\n                del self._expirations[(domain, path, name)]\n            self._cookies[(domain, path)].pop(name, None)\n\n        self._next_expiration = (\n            min(*self._expirations.values(), self.SUB_MAX_TIME) + 1\n            if self._expirations\n            else self.MAX_TIME\n        )\n\n    def clear_domain(self, domain: str) -> None:\n        self.clear(lambda x: self._is_domain_match(domain, x[\"domain\"]))\n\n    def __iter__(self) -> \"Iterator[Morsel[str]]\":\n        self._do_expiration()\n        for val in self._cookies.values():\n            yield from val.values()\n\n    def __len__(self) -> int:\n        \"\"\"Return number of cookies.\n\n        This function does not iterate self to avoid unnecessary expiration\n        checks.\n        \"\"\"\n        return sum(len(cookie.values()) for cookie in self._cookies.values())\n\n    def _do_expiration(self) -> None:\n        self.clear(lambda x: False)\n\n    def _expire_cookie(self, when: float, domain: str, path: str, name: str) -> None:\n        self._next_expiration = min(self._next_expiration, when)\n        self._expirations[(domain, path, name)] = when\n\n    def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None:\n        \"\"\"Update cookies.\"\"\"\n        hostname = response_url.raw_host\n\n        if not self._unsafe and is_ip_address(hostname):\n            # Don't accept cookies from IPs\n            return\n\n        if isinstance(cookies, Mapping):\n            cookies = cookies.items()\n\n        for name, cookie in cookies:\n            if not isinstance(cookie, Morsel):\n                tmp = SimpleCookie()\n                tmp[name] = cookie  # type: ignore[assignment]\n                cookie = tmp[name]\n\n            domain = cookie[\"domain\"]\n\n            # ignore domains with trailing dots\n            if domain.endswith(\".\"):\n                domain = \"\"\n                del cookie[\"domain\"]\n\n            if not domain and hostname is not None:\n                # Set the cookie's domain to the response hostname\n                # and set its host-only-flag\n                self._host_only_cookies.add((hostname, name))\n                domain = cookie[\"domain\"] = hostname\n\n            if domain.startswith(\".\"):\n                # Remove leading dot\n                domain = domain[1:]\n                cookie[\"domain\"] = domain\n\n            if hostname and not self._is_domain_match(domain, hostname):\n                # Setting cookies for different domains is not allowed\n                continue\n\n            path = cookie[\"path\"]\n            if not path or not path.startswith(\"/\"):\n                # Set the cookie's path to the response path\n                path = response_url.path\n                if not path.startswith(\"/\"):\n                    path = \"/\"\n                else:\n                    # Cut everything from the last slash to the end\n                    path = \"/\" + path[1 : path.rfind(\"/\")]\n                cookie[\"path\"] = path\n            path = path.rstrip(\"/\")\n\n            max_age = cookie[\"max-age\"]\n            if max_age:\n                try:\n                    delta_seconds = int(max_age)\n                    max_age_expiration = min(time.time() + delta_seconds, self.MAX_TIME)\n                    self._expire_cookie(max_age_expiration, domain, path, name)\n                except ValueError:\n                    cookie[\"max-age\"] = \"\"\n\n            else:\n                expires = cookie[\"expires\"]\n                if expires:\n                    expire_time = self._parse_date(expires)\n                    if expire_time:\n                        self._expire_cookie(expire_time, domain, path, name)\n                    else:\n                        cookie[\"expires\"] = \"\"\n\n            self._cookies[(domain, path)][name] = cookie\n\n        self._do_expiration()\n\n    def filter_cookies(self, request_url: URL = URL()) -> \"BaseCookie[str]\":\n        \"\"\"Returns this jar's cookies filtered by their attributes.\"\"\"\n        if not isinstance(request_url, URL):\n            warnings.warn(\n                \"The method accepts yarl.URL instances only, got {}\".format(\n                    type(request_url)\n                ),\n                DeprecationWarning,\n            )\n            request_url = URL(request_url)\n        filtered: Union[SimpleCookie, \"BaseCookie[str]\"] = (\n            SimpleCookie() if self._quote_cookie else BaseCookie()\n        )\n        if not self._cookies:\n            # Skip do_expiration() if there are no cookies.\n            return filtered\n        self._do_expiration()\n        if not self._cookies:\n            # Skip rest of function if no non-expired cookies.\n            return filtered\n        hostname = request_url.raw_host or \"\"\n\n        is_not_secure = request_url.scheme not in (\"https\", \"wss\")\n        if is_not_secure and self._treat_as_secure_origin:\n            request_origin = URL()\n            with contextlib.suppress(ValueError):\n                request_origin = request_url.origin()\n            is_not_secure = request_origin not in self._treat_as_secure_origin\n\n        # Send shared cookie\n        for c in self._cookies[(\"\", \"\")].values():\n            filtered[c.key] = c.value\n\n        if is_ip_address(hostname):\n            if not self._unsafe:\n                return filtered\n            domains: Iterable[str] = (hostname,)\n        else:\n            # Get all the subdomains that might match a cookie (e.g. \"foo.bar.com\", \"bar.com\", \"com\")\n            domains = itertools.accumulate(\n                reversed(hostname.split(\".\")), lambda x, y: f\"{y}.{x}\"\n            )\n        # Get all the path prefixes that might match a cookie (e.g. \"\", \"/foo\", \"/foo/bar\")\n        paths = itertools.accumulate(\n            request_url.path.split(\"/\"), lambda x, y: f\"{x}/{y}\"\n        )\n        # Create every combination of (domain, path) pairs.\n        pairs = itertools.product(domains, paths)\n\n        # Point 2: https://www.rfc-editor.org/rfc/rfc6265.html#section-5.4\n        cookies = itertools.chain.from_iterable(\n            self._cookies[p].values() for p in pairs\n        )\n        path_len = len(request_url.path)\n        for cookie in cookies:\n            name = cookie.key\n            domain = cookie[\"domain\"]\n\n            if (domain, name) in self._host_only_cookies:\n                if domain != hostname:\n                    continue\n\n            # Skip edge case when the cookie has a trailing slash but request doesn't.\n            if len(cookie[\"path\"]) > path_len:\n                continue\n\n            if is_not_secure and cookie[\"secure\"]:\n                continue\n\n            # It's critical we use the Morsel so the coded_value\n            # (based on cookie version) is preserved\n            mrsl_val = cast(\"Morsel[str]\", cookie.get(cookie.key, Morsel()))\n            mrsl_val.set(cookie.key, cookie.value, cookie.coded_value)\n            filtered[name] = mrsl_val\n\n        return filtered\n\n    @staticmethod\n    def _is_domain_match(domain: str, hostname: str) -> bool:\n        \"\"\"Implements domain matching adhering to RFC 6265.\"\"\"\n        if hostname == domain:\n            return True\n\n        if not hostname.endswith(domain):\n            return False\n\n        non_matching = hostname[: -len(domain)]\n\n        if not non_matching.endswith(\".\"):\n            return False\n\n        return not is_ip_address(hostname)\n\n    @classmethod\n    def _parse_date(cls, date_str: str) -> Optional[int]:\n        \"\"\"Implements date string parsing adhering to RFC 6265.\"\"\"\n        if not date_str:\n            return None\n\n        found_time = False\n        found_day = False\n        found_month = False\n        found_year = False\n\n        hour = minute = second = 0\n        day = 0\n        month = 0\n        year = 0\n\n        for token_match in cls.DATE_TOKENS_RE.finditer(date_str):\n            token = token_match.group(\"token\")\n\n            if not found_time:\n                time_match = cls.DATE_HMS_TIME_RE.match(token)\n                if time_match:\n                    found_time = True\n                    hour, minute, second = (int(s) for s in time_match.groups())\n                    continue\n\n            if not found_day:\n                day_match = cls.DATE_DAY_OF_MONTH_RE.match(token)\n                if day_match:\n                    found_day = True\n                    day = int(day_match.group())\n                    continue\n\n            if not found_month:\n                month_match = cls.DATE_MONTH_RE.match(token)\n                if month_match:\n                    found_month = True\n                    assert month_match.lastindex is not None\n                    month = month_match.lastindex\n                    continue\n\n            if not found_year:\n                year_match = cls.DATE_YEAR_RE.match(token)\n                if year_match:\n                    found_year = True\n                    year = int(year_match.group())\n\n        if 70 <= year <= 99:\n            year += 1900\n        elif 0 <= year <= 69:\n            year += 2000\n\n        if False in (found_day, found_month, found_year, found_time):\n            return None\n\n        if not 1 <= day <= 31:\n            return None\n\n        if year < 1601 or hour > 23 or minute > 59 or second > 59:\n            return None\n\n        return calendar.timegm((year, month, day, hour, minute, second, -1, -1, -1))\n\n\nclass DummyCookieJar(AbstractCookieJar):\n    \"\"\"Implements a dummy cookie storage.\n\n    It can be used with the ClientSession when no cookie processing is needed.\n\n    \"\"\"\n\n    def __iter__(self) -> \"Iterator[Morsel[str]]\":\n        while False:\n            yield None\n\n    def __len__(self) -> int:\n        return 0\n\n    def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None:\n        pass\n\n    def clear_domain(self, domain: str) -> None:\n        pass\n\n    def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None:\n        pass\n\n    def filter_cookies(self, request_url: URL) -> \"BaseCookie[str]\":\n        return SimpleCookie()\n",
            "header": {
                "file": {
                    "path": "aiohttp/cookiejar.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "aa63d280",
                "new_commit_hash": "da162543",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/aiohttp/cookiejar.py"
            },
            "plus_file": {
                "path": "b/aiohttp/cookiejar.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 152,
                            "length": 7
                        },
                        "new_range": {
                            "start": 152,
                            "length": 12
                        },
                        "section": "class CookieJar(AbstractCookieJar):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "            yield from val.values()",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def __len__(self) -> int:",
                                "type": "context"
                            },
                            {
                                "content": "        return sum(1 for i in self)",
                                "type": "deleted"
                            },
                            {
                                "content": "        \"\"\"Return number of cookies.",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        This function does not iterate self to avoid unnecessary expiration",
                                "type": "added"
                            },
                            {
                                "content": "        checks.",
                                "type": "added"
                            },
                            {
                                "content": "        \"\"\"",
                                "type": "added"
                            },
                            {
                                "content": "        return sum(len(cookie.values()) for cookie in self._cookies.values())",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def _do_expiration(self) -> None:",
                                "type": "context"
                            },
                            {
                                "content": "        self.clear(lambda x: False)",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "aiohttp/cookiejar.py",
                            "type": "method",
                            "name": "CookieJar.__len__",
                            "content": "class CookieJar(AbstractCookieJar):\n    \"\"\"Implements cookie storage adhering to RFC 6265.\"\"\"\n\n    DATE_TOKENS_RE = re.compile(\n        r\"[\\x09\\x20-\\x2F\\x3B-\\x40\\x5B-\\x60\\x7B-\\x7E]*\"\n        r\"(?P<token>[\\x00-\\x08\\x0A-\\x1F\\d:a-zA-Z\\x7F-\\xFF]+)\"\n    )\n\n    DATE_HMS_TIME_RE = re.compile(r\"(\\d{1,2}):(\\d{1,2}):(\\d{1,2})\")\n\n    DATE_DAY_OF_MONTH_RE = re.compile(r\"(\\d{1,2})\")\n\n    DATE_MONTH_RE = re.compile(\n        \"(jan)|(feb)|(mar)|(apr)|(may)|(jun)|(jul)|\" \"(aug)|(sep)|(oct)|(nov)|(dec)\",\n        re.I,\n    )\n\n    DATE_YEAR_RE = re.compile(r\"(\\d{2,4})\")\n\n    # calendar.timegm() fails for timestamps after datetime.datetime.max\n    # Minus one as a loss of precision occurs when timestamp() is called.\n    MAX_TIME = (\n        int(datetime.datetime.max.replace(tzinfo=datetime.timezone.utc).timestamp()) - 1\n    )\n    try:\n        calendar.timegm(time.gmtime(MAX_TIME))\n    except (OSError, ValueError):\n        # Hit the maximum representable time on Windows\n        # https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/localtime-localtime32-localtime64\n        # Throws ValueError on PyPy 3.8 and 3.9, OSError elsewhere\n        MAX_TIME = calendar.timegm((3000, 12, 31, 23, 59, 59, -1, -1, -1))\n    except OverflowError:\n        # #4515: datetime.max may not be representable on 32-bit platforms\n        MAX_TIME = 2**31 - 1\n    # Avoid minuses in the future, 3x faster\n    SUB_MAX_TIME = MAX_TIME - 1\n\n    def __init__(\n        self,\n        *,\n        unsafe: bool = False,\n        quote_cookie: bool = True,\n        treat_as_secure_origin: Union[StrOrURL, List[StrOrURL], None] = None,\n    ) -> None:\n        self._cookies: DefaultDict[Tuple[str, str], SimpleCookie] = defaultdict(\n            SimpleCookie\n        )\n        self._host_only_cookies: Set[Tuple[str, str]] = set()\n        self._unsafe = unsafe\n        self._quote_cookie = quote_cookie\n        if treat_as_secure_origin is None:\n            treat_as_secure_origin = []\n        elif isinstance(treat_as_secure_origin, URL):\n            treat_as_secure_origin = [treat_as_secure_origin.origin()]\n        elif isinstance(treat_as_secure_origin, str):\n            treat_as_secure_origin = [URL(treat_as_secure_origin).origin()]\n        else:\n            treat_as_secure_origin = [\n                URL(url).origin() if isinstance(url, str) else url.origin()\n                for url in treat_as_secure_origin\n            ]\n        self._treat_as_secure_origin = treat_as_secure_origin\n        self._next_expiration: float = ceil(time.time())\n        self._expirations: Dict[Tuple[str, str, str], float] = {}\n\n    def save(self, file_path: PathLike) -> None:\n        file_path = pathlib.Path(file_path)\n        with file_path.open(mode=\"wb\") as f:\n            pickle.dump(self._cookies, f, pickle.HIGHEST_PROTOCOL)\n\n    def load(self, file_path: PathLike) -> None:\n        file_path = pathlib.Path(file_path)\n        with file_path.open(mode=\"rb\") as f:\n            self._cookies = pickle.load(f)\n\n    def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None:\n        if predicate is None:\n            self._next_expiration = ceil(time.time())\n            self._cookies.clear()\n            self._host_only_cookies.clear()\n            self._expirations.clear()\n            return\n\n        to_del = []\n        now = time.time()\n        for (domain, path), cookie in self._cookies.items():\n            for name, morsel in cookie.items():\n                key = (domain, path, name)\n                if (\n                    key in self._expirations and self._expirations[key] <= now\n                ) or predicate(morsel):\n                    to_del.append(key)\n\n        for domain, path, name in to_del:\n            self._host_only_cookies.discard((domain, name))\n            key = (domain, path, name)\n            if key in self._expirations:\n                del self._expirations[(domain, path, name)]\n            self._cookies[(domain, path)].pop(name, None)\n\n        self._next_expiration = (\n            min(*self._expirations.values(), self.SUB_MAX_TIME) + 1\n            if self._expirations\n            else self.MAX_TIME\n        )\n\n    def clear_domain(self, domain: str) -> None:\n        self.clear(lambda x: self._is_domain_match(domain, x[\"domain\"]))\n\n    def __iter__(self) -> \"Iterator[Morsel[str]]\":\n        self._do_expiration()\n        for val in self._cookies.values():\n            yield from val.values()\n\n    def __len__(self) -> int:\n        return sum(1 for i in self)\n\n    def _do_expiration(self) -> None:\n        self.clear(lambda x: False)\n\n    def _expire_cookie(self, when: float, domain: str, path: str, name: str) -> None:\n        self._next_expiration = min(self._next_expiration, when)\n        self._expirations[(domain, path, name)] = when\n\n    def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None:\n        \"\"\"Update cookies.\"\"\"\n        hostname = response_url.raw_host\n\n        if not self._unsafe and is_ip_address(hostname):\n            # Don't accept cookies from IPs\n            return\n\n        if isinstance(cookies, Mapping):\n            cookies = cookies.items()\n\n        for name, cookie in cookies:\n            if not isinstance(cookie, Morsel):\n                tmp = SimpleCookie()\n                tmp[name] = cookie  # type: ignore[assignment]\n                cookie = tmp[name]\n\n            domain = cookie[\"domain\"]\n\n            # ignore domains with trailing dots\n            if domain.endswith(\".\"):\n                domain = \"\"\n                del cookie[\"domain\"]\n\n            if not domain and hostname is not None:\n                # Set the cookie's domain to the response hostname\n                # and set its host-only-flag\n                self._host_only_cookies.add((hostname, name))\n                domain = cookie[\"domain\"] = hostname\n\n            if domain.startswith(\".\"):\n                # Remove leading dot\n                domain = domain[1:]\n                cookie[\"domain\"] = domain\n\n            if hostname and not self._is_domain_match(domain, hostname):\n                # Setting cookies for different domains is not allowed\n                continue\n\n            path = cookie[\"path\"]\n            if not path or not path.startswith(\"/\"):\n                # Set the cookie's path to the response path\n                path = response_url.path\n                if not path.startswith(\"/\"):\n                    path = \"/\"\n                else:\n                    # Cut everything from the last slash to the end\n                    path = \"/\" + path[1 : path.rfind(\"/\")]\n                cookie[\"path\"] = path\n            path = path.rstrip(\"/\")\n\n            max_age = cookie[\"max-age\"]\n            if max_age:\n                try:\n                    delta_seconds = int(max_age)\n                    max_age_expiration = min(time.time() + delta_seconds, self.MAX_TIME)\n                    self._expire_cookie(max_age_expiration, domain, path, name)\n                except ValueError:\n                    cookie[\"max-age\"] = \"\"\n\n            else:\n                expires = cookie[\"expires\"]\n                if expires:\n                    expire_time = self._parse_date(expires)\n                    if expire_time:\n                        self._expire_cookie(expire_time, domain, path, name)\n                    else:\n                        cookie[\"expires\"] = \"\"\n\n            self._cookies[(domain, path)][name] = cookie\n\n        self._do_expiration()\n\n    def filter_cookies(self, request_url: URL = URL()) -> \"BaseCookie[str]\":\n        \"\"\"Returns this jar's cookies filtered by their attributes.\"\"\"\n        if not isinstance(request_url, URL):\n            warnings.warn(\n                \"The method accepts yarl.URL instances only, got {}\".format(\n                    type(request_url)\n                ),\n                DeprecationWarning,\n            )\n            request_url = URL(request_url)\n        filtered: Union[SimpleCookie, \"BaseCookie[str]\"] = (\n            SimpleCookie() if self._quote_cookie else BaseCookie()\n        )\n        if not self._cookies:\n            # Skip do_expiration() if there are no cookies.\n            return filtered\n        self._do_expiration()\n        if not self._cookies:\n            # Skip rest of function if no non-expired cookies.\n            return filtered\n        hostname = request_url.raw_host or \"\"\n\n        is_not_secure = request_url.scheme not in (\"https\", \"wss\")\n        if is_not_secure and self._treat_as_secure_origin:\n            request_origin = URL()\n            with contextlib.suppress(ValueError):\n                request_origin = request_url.origin()\n            is_not_secure = request_origin not in self._treat_as_secure_origin\n\n        # Send shared cookie\n        for c in self._cookies[(\"\", \"\")].values():\n            filtered[c.key] = c.value\n\n        if is_ip_address(hostname):\n            if not self._unsafe:\n                return filtered\n            domains: Iterable[str] = (hostname,)\n        else:\n            # Get all the subdomains that might match a cookie (e.g. \"foo.bar.com\", \"bar.com\", \"com\")\n            domains = itertools.accumulate(\n                reversed(hostname.split(\".\")), lambda x, y: f\"{y}.{x}\"\n            )\n        # Get all the path prefixes that might match a cookie (e.g. \"\", \"/foo\", \"/foo/bar\")\n        paths = itertools.accumulate(\n            request_url.path.split(\"/\"), lambda x, y: f\"{x}/{y}\"\n        )\n        # Create every combination of (domain, path) pairs.\n        pairs = itertools.product(domains, paths)\n\n        # Point 2: https://www.rfc-editor.org/rfc/rfc6265.html#section-5.4\n        cookies = itertools.chain.from_iterable(\n            self._cookies[p].values() for p in pairs\n        )\n        path_len = len(request_url.path)\n        for cookie in cookies:\n            name = cookie.key\n            domain = cookie[\"domain\"]\n\n            if (domain, name) in self._host_only_cookies:\n                if domain != hostname:\n                    continue\n\n            # Skip edge case when the cookie has a trailing slash but request doesn't.\n            if len(cookie[\"path\"]) > path_len:\n                continue\n\n            if is_not_secure and cookie[\"secure\"]:\n                continue\n\n            # It's critical we use the Morsel so the coded_value\n            # (based on cookie version) is preserved\n            mrsl_val = cast(\"Morsel[str]\", cookie.get(cookie.key, Morsel()))\n            mrsl_val.set(cookie.key, cookie.value, cookie.coded_value)\n            filtered[name] = mrsl_val\n\n        return filtered\n\n    @staticmethod\n    def _is_domain_match(domain: str, hostname: str) -> bool:\n        \"\"\"Implements domain matching adhering to RFC 6265.\"\"\"\n        if hostname == domain:\n            return True\n\n        if not hostname.endswith(domain):\n            return False\n\n        non_matching = hostname[: -len(domain)]\n\n        if not non_matching.endswith(\".\"):\n            return False\n\n        return not is_ip_address(hostname)\n\n    @classmethod\n    def _parse_date(cls, date_str: str) -> Optional[int]:\n        \"\"\"Implements date string parsing adhering to RFC 6265.\"\"\"\n        if not date_str:\n            return None\n\n        found_time = False\n        found_day = False\n        found_month = False\n        found_year = False\n\n        hour = minute = second = 0\n        day = 0\n        month = 0\n        year = 0\n\n        for token_match in cls.DATE_TOKENS_RE.finditer(date_str):\n            token = token_match.group(\"token\")\n\n            if not found_time:\n                time_match = cls.DATE_HMS_TIME_RE.match(token)\n                if time_match:\n                    found_time = True\n                    hour, minute, second = (int(s) for s in time_match.groups())\n                    continue\n\n            if not found_day:\n                day_match = cls.DATE_DAY_OF_MONTH_RE.match(token)\n                if day_match:\n                    found_day = True\n                    day = int(day_match.group())\n                    continue\n\n            if not found_month:\n                month_match = cls.DATE_MONTH_RE.match(token)\n                if month_match:\n                    found_month = True\n                    assert month_match.lastindex is not None\n                    month = month_match.lastindex\n                    continue\n\n            if not found_year:\n                year_match = cls.DATE_YEAR_RE.match(token)\n                if year_match:\n                    found_year = True\n                    year = int(year_match.group())\n\n        if 70 <= year <= 99:\n            year += 1900\n        elif 0 <= year <= 69:\n            year += 2000\n\n        if False in (found_day, found_month, found_year, found_time):\n            return None\n\n        if not 1 <= day <= 31:\n            return None\n\n        if year < 1601 or hour > 23 or minute > 59 or second > 59:\n            return None\n\n        return calendar.timegm((year, month, day, hour, minute, second, -1, -1, -1))",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 154,
                            "end_lineno": 155,
                            "parent": {
                                "file_name": "aiohttp/cookiejar.py",
                                "type": "class",
                                "name": "CookieJar",
                                "content": "class CookieJar(AbstractCookieJar):\n    \"\"\"Implements cookie storage adhering to RFC 6265.\"\"\"\n\n    DATE_TOKENS_RE = re.compile(\n        r\"[\\x09\\x20-\\x2F\\x3B-\\x40\\x5B-\\x60\\x7B-\\x7E]*\"\n        r\"(?P<token>[\\x00-\\x08\\x0A-\\x1F\\d:a-zA-Z\\x7F-\\xFF]+)\"\n    )\n\n    DATE_HMS_TIME_RE = re.compile(r\"(\\d{1,2}):(\\d{1,2}):(\\d{1,2})\")\n\n    DATE_DAY_OF_MONTH_RE = re.compile(r\"(\\d{1,2})\")\n\n    DATE_MONTH_RE = re.compile(\n        \"(jan)|(feb)|(mar)|(apr)|(may)|(jun)|(jul)|\" \"(aug)|(sep)|(oct)|(nov)|(dec)\",\n        re.I,\n    )\n\n    DATE_YEAR_RE = re.compile(r\"(\\d{2,4})\")\n\n    # calendar.timegm() fails for timestamps after datetime.datetime.max\n    # Minus one as a loss of precision occurs when timestamp() is called.\n    MAX_TIME = (\n        int(datetime.datetime.max.replace(tzinfo=datetime.timezone.utc).timestamp()) - 1\n    )\n    try:\n        calendar.timegm(time.gmtime(MAX_TIME))\n    except (OSError, ValueError):\n        # Hit the maximum representable time on Windows\n        # https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/localtime-localtime32-localtime64\n        # Throws ValueError on PyPy 3.8 and 3.9, OSError elsewhere\n        MAX_TIME = calendar.timegm((3000, 12, 31, 23, 59, 59, -1, -1, -1))\n    except OverflowError:\n        # #4515: datetime.max may not be representable on 32-bit platforms\n        MAX_TIME = 2**31 - 1\n    # Avoid minuses in the future, 3x faster\n    SUB_MAX_TIME = MAX_TIME - 1\n\n    def __init__(\n        self,\n        *,\n        unsafe: bool = False,\n        quote_cookie: bool = True,\n        treat_as_secure_origin: Union[StrOrURL, List[StrOrURL], None] = None,\n    ) -> None:\n        self._cookies: DefaultDict[Tuple[str, str], SimpleCookie] = defaultdict(\n            SimpleCookie\n        )\n        self._host_only_cookies: Set[Tuple[str, str]] = set()\n        self._unsafe = unsafe\n        self._quote_cookie = quote_cookie\n        if treat_as_secure_origin is None:\n            treat_as_secure_origin = []\n        elif isinstance(treat_as_secure_origin, URL):\n            treat_as_secure_origin = [treat_as_secure_origin.origin()]\n        elif isinstance(treat_as_secure_origin, str):\n            treat_as_secure_origin = [URL(treat_as_secure_origin).origin()]\n        else:\n            treat_as_secure_origin = [\n                URL(url).origin() if isinstance(url, str) else url.origin()\n                for url in treat_as_secure_origin\n            ]\n        self._treat_as_secure_origin = treat_as_secure_origin\n        self._next_expiration: float = ceil(time.time())\n        self._expirations: Dict[Tuple[str, str, str], float] = {}\n\n    def save(self, file_path: PathLike) -> None:\n        file_path = pathlib.Path(file_path)\n        with file_path.open(mode=\"wb\") as f:\n            pickle.dump(self._cookies, f, pickle.HIGHEST_PROTOCOL)\n\n    def load(self, file_path: PathLike) -> None:\n        file_path = pathlib.Path(file_path)\n        with file_path.open(mode=\"rb\") as f:\n            self._cookies = pickle.load(f)\n\n    def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None:\n        if predicate is None:\n            self._next_expiration = ceil(time.time())\n            self._cookies.clear()\n            self._host_only_cookies.clear()\n            self._expirations.clear()\n            return\n\n        to_del = []\n        now = time.time()\n        for (domain, path), cookie in self._cookies.items():\n            for name, morsel in cookie.items():\n                key = (domain, path, name)\n                if (\n                    key in self._expirations and self._expirations[key] <= now\n                ) or predicate(morsel):\n                    to_del.append(key)\n\n        for domain, path, name in to_del:\n            self._host_only_cookies.discard((domain, name))\n            key = (domain, path, name)\n            if key in self._expirations:\n                del self._expirations[(domain, path, name)]\n            self._cookies[(domain, path)].pop(name, None)\n\n        self._next_expiration = (\n            min(*self._expirations.values(), self.SUB_MAX_TIME) + 1\n            if self._expirations\n            else self.MAX_TIME\n        )\n\n    def clear_domain(self, domain: str) -> None:\n        self.clear(lambda x: self._is_domain_match(domain, x[\"domain\"]))\n\n    def __iter__(self) -> \"Iterator[Morsel[str]]\":\n        self._do_expiration()\n        for val in self._cookies.values():\n            yield from val.values()\n\n    def __len__(self) -> int:\n        return sum(1 for i in self)\n\n    def _do_expiration(self) -> None:\n        self.clear(lambda x: False)\n\n    def _expire_cookie(self, when: float, domain: str, path: str, name: str) -> None:\n        self._next_expiration = min(self._next_expiration, when)\n        self._expirations[(domain, path, name)] = when\n\n    def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None:\n        \"\"\"Update cookies.\"\"\"\n        hostname = response_url.raw_host\n\n        if not self._unsafe and is_ip_address(hostname):\n            # Don't accept cookies from IPs\n            return\n\n        if isinstance(cookies, Mapping):\n            cookies = cookies.items()\n\n        for name, cookie in cookies:\n            if not isinstance(cookie, Morsel):\n                tmp = SimpleCookie()\n                tmp[name] = cookie  # type: ignore[assignment]\n                cookie = tmp[name]\n\n            domain = cookie[\"domain\"]\n\n            # ignore domains with trailing dots\n            if domain.endswith(\".\"):\n                domain = \"\"\n                del cookie[\"domain\"]\n\n            if not domain and hostname is not None:\n                # Set the cookie's domain to the response hostname\n                # and set its host-only-flag\n                self._host_only_cookies.add((hostname, name))\n                domain = cookie[\"domain\"] = hostname\n\n            if domain.startswith(\".\"):\n                # Remove leading dot\n                domain = domain[1:]\n                cookie[\"domain\"] = domain\n\n            if hostname and not self._is_domain_match(domain, hostname):\n                # Setting cookies for different domains is not allowed\n                continue\n\n            path = cookie[\"path\"]\n            if not path or not path.startswith(\"/\"):\n                # Set the cookie's path to the response path\n                path = response_url.path\n                if not path.startswith(\"/\"):\n                    path = \"/\"\n                else:\n                    # Cut everything from the last slash to the end\n                    path = \"/\" + path[1 : path.rfind(\"/\")]\n                cookie[\"path\"] = path\n            path = path.rstrip(\"/\")\n\n            max_age = cookie[\"max-age\"]\n            if max_age:\n                try:\n                    delta_seconds = int(max_age)\n                    max_age_expiration = min(time.time() + delta_seconds, self.MAX_TIME)\n                    self._expire_cookie(max_age_expiration, domain, path, name)\n                except ValueError:\n                    cookie[\"max-age\"] = \"\"\n\n            else:\n                expires = cookie[\"expires\"]\n                if expires:\n                    expire_time = self._parse_date(expires)\n                    if expire_time:\n                        self._expire_cookie(expire_time, domain, path, name)\n                    else:\n                        cookie[\"expires\"] = \"\"\n\n            self._cookies[(domain, path)][name] = cookie\n\n        self._do_expiration()\n\n    def filter_cookies(self, request_url: URL = URL()) -> \"BaseCookie[str]\":\n        \"\"\"Returns this jar's cookies filtered by their attributes.\"\"\"\n        if not isinstance(request_url, URL):\n            warnings.warn(\n                \"The method accepts yarl.URL instances only, got {}\".format(\n                    type(request_url)\n                ),\n                DeprecationWarning,\n            )\n            request_url = URL(request_url)\n        filtered: Union[SimpleCookie, \"BaseCookie[str]\"] = (\n            SimpleCookie() if self._quote_cookie else BaseCookie()\n        )\n        if not self._cookies:\n            # Skip do_expiration() if there are no cookies.\n            return filtered\n        self._do_expiration()\n        if not self._cookies:\n            # Skip rest of function if no non-expired cookies.\n            return filtered\n        hostname = request_url.raw_host or \"\"\n\n        is_not_secure = request_url.scheme not in (\"https\", \"wss\")\n        if is_not_secure and self._treat_as_secure_origin:\n            request_origin = URL()\n            with contextlib.suppress(ValueError):\n                request_origin = request_url.origin()\n            is_not_secure = request_origin not in self._treat_as_secure_origin\n\n        # Send shared cookie\n        for c in self._cookies[(\"\", \"\")].values():\n            filtered[c.key] = c.value\n\n        if is_ip_address(hostname):\n            if not self._unsafe:\n                return filtered\n            domains: Iterable[str] = (hostname,)\n        else:\n            # Get all the subdomains that might match a cookie (e.g. \"foo.bar.com\", \"bar.com\", \"com\")\n            domains = itertools.accumulate(\n                reversed(hostname.split(\".\")), lambda x, y: f\"{y}.{x}\"\n            )\n        # Get all the path prefixes that might match a cookie (e.g. \"\", \"/foo\", \"/foo/bar\")\n        paths = itertools.accumulate(\n            request_url.path.split(\"/\"), lambda x, y: f\"{x}/{y}\"\n        )\n        # Create every combination of (domain, path) pairs.\n        pairs = itertools.product(domains, paths)\n\n        # Point 2: https://www.rfc-editor.org/rfc/rfc6265.html#section-5.4\n        cookies = itertools.chain.from_iterable(\n            self._cookies[p].values() for p in pairs\n        )\n        path_len = len(request_url.path)\n        for cookie in cookies:\n            name = cookie.key\n            domain = cookie[\"domain\"]\n\n            if (domain, name) in self._host_only_cookies:\n                if domain != hostname:\n                    continue\n\n            # Skip edge case when the cookie has a trailing slash but request doesn't.\n            if len(cookie[\"path\"]) > path_len:\n                continue\n\n            if is_not_secure and cookie[\"secure\"]:\n                continue\n\n            # It's critical we use the Morsel so the coded_value\n            # (based on cookie version) is preserved\n            mrsl_val = cast(\"Morsel[str]\", cookie.get(cookie.key, Morsel()))\n            mrsl_val.set(cookie.key, cookie.value, cookie.coded_value)\n            filtered[name] = mrsl_val\n\n        return filtered\n\n    @staticmethod\n    def _is_domain_match(domain: str, hostname: str) -> bool:\n        \"\"\"Implements domain matching adhering to RFC 6265.\"\"\"\n        if hostname == domain:\n            return True\n\n        if not hostname.endswith(domain):\n            return False\n\n        non_matching = hostname[: -len(domain)]\n\n        if not non_matching.endswith(\".\"):\n            return False\n\n        return not is_ip_address(hostname)\n\n    @classmethod\n    def _parse_date(cls, date_str: str) -> Optional[int]:\n        \"\"\"Implements date string parsing adhering to RFC 6265.\"\"\"\n        if not date_str:\n            return None\n\n        found_time = False\n        found_day = False\n        found_month = False\n        found_year = False\n\n        hour = minute = second = 0\n        day = 0\n        month = 0\n        year = 0\n\n        for token_match in cls.DATE_TOKENS_RE.finditer(date_str):\n            token = token_match.group(\"token\")\n\n            if not found_time:\n                time_match = cls.DATE_HMS_TIME_RE.match(token)\n                if time_match:\n                    found_time = True\n                    hour, minute, second = (int(s) for s in time_match.groups())\n                    continue\n\n            if not found_day:\n                day_match = cls.DATE_DAY_OF_MONTH_RE.match(token)\n                if day_match:\n                    found_day = True\n                    day = int(day_match.group())\n                    continue\n\n            if not found_month:\n                month_match = cls.DATE_MONTH_RE.match(token)\n                if month_match:\n                    found_month = True\n                    assert month_match.lastindex is not None\n                    month = month_match.lastindex\n                    continue\n\n            if not found_year:\n                year_match = cls.DATE_YEAR_RE.match(token)\n                if year_match:\n                    found_year = True\n                    year = int(year_match.group())\n\n        if 70 <= year <= 99:\n            year += 1900\n        elif 0 <= year <= 69:\n            year += 2000\n\n        if False in (found_day, found_month, found_year, found_time):\n            return None\n\n        if not 1 <= day <= 31:\n            return None\n\n        if year < 1601 or hour > 23 or minute > 59 or second > 59:\n            return None\n\n        return calendar.timegm((year, month, day, hour, minute, second, -1, -1, -1))",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 40,
                                "end_lineno": 391,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "aiohttp/cookiejar.py",
                            "type": "class",
                            "name": "CookieJar",
                            "content": "class CookieJar(AbstractCookieJar):\n    \"\"\"Implements cookie storage adhering to RFC 6265.\"\"\"\n\n    DATE_TOKENS_RE = re.compile(\n        r\"[\\x09\\x20-\\x2F\\x3B-\\x40\\x5B-\\x60\\x7B-\\x7E]*\"\n        r\"(?P<token>[\\x00-\\x08\\x0A-\\x1F\\d:a-zA-Z\\x7F-\\xFF]+)\"\n    )\n\n    DATE_HMS_TIME_RE = re.compile(r\"(\\d{1,2}):(\\d{1,2}):(\\d{1,2})\")\n\n    DATE_DAY_OF_MONTH_RE = re.compile(r\"(\\d{1,2})\")\n\n    DATE_MONTH_RE = re.compile(\n        \"(jan)|(feb)|(mar)|(apr)|(may)|(jun)|(jul)|\" \"(aug)|(sep)|(oct)|(nov)|(dec)\",\n        re.I,\n    )\n\n    DATE_YEAR_RE = re.compile(r\"(\\d{2,4})\")\n\n    # calendar.timegm() fails for timestamps after datetime.datetime.max\n    # Minus one as a loss of precision occurs when timestamp() is called.\n    MAX_TIME = (\n        int(datetime.datetime.max.replace(tzinfo=datetime.timezone.utc).timestamp()) - 1\n    )\n    try:\n        calendar.timegm(time.gmtime(MAX_TIME))\n    except (OSError, ValueError):\n        # Hit the maximum representable time on Windows\n        # https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/localtime-localtime32-localtime64\n        # Throws ValueError on PyPy 3.8 and 3.9, OSError elsewhere\n        MAX_TIME = calendar.timegm((3000, 12, 31, 23, 59, 59, -1, -1, -1))\n    except OverflowError:\n        # #4515: datetime.max may not be representable on 32-bit platforms\n        MAX_TIME = 2**31 - 1\n    # Avoid minuses in the future, 3x faster\n    SUB_MAX_TIME = MAX_TIME - 1\n\n    def __init__(\n        self,\n        *,\n        unsafe: bool = False,\n        quote_cookie: bool = True,\n        treat_as_secure_origin: Union[StrOrURL, List[StrOrURL], None] = None,\n    ) -> None:\n        self._cookies: DefaultDict[Tuple[str, str], SimpleCookie] = defaultdict(\n            SimpleCookie\n        )\n        self._host_only_cookies: Set[Tuple[str, str]] = set()\n        self._unsafe = unsafe\n        self._quote_cookie = quote_cookie\n        if treat_as_secure_origin is None:\n            treat_as_secure_origin = []\n        elif isinstance(treat_as_secure_origin, URL):\n            treat_as_secure_origin = [treat_as_secure_origin.origin()]\n        elif isinstance(treat_as_secure_origin, str):\n            treat_as_secure_origin = [URL(treat_as_secure_origin).origin()]\n        else:\n            treat_as_secure_origin = [\n                URL(url).origin() if isinstance(url, str) else url.origin()\n                for url in treat_as_secure_origin\n            ]\n        self._treat_as_secure_origin = treat_as_secure_origin\n        self._next_expiration: float = ceil(time.time())\n        self._expirations: Dict[Tuple[str, str, str], float] = {}\n\n    def save(self, file_path: PathLike) -> None:\n        file_path = pathlib.Path(file_path)\n        with file_path.open(mode=\"wb\") as f:\n            pickle.dump(self._cookies, f, pickle.HIGHEST_PROTOCOL)\n\n    def load(self, file_path: PathLike) -> None:\n        file_path = pathlib.Path(file_path)\n        with file_path.open(mode=\"rb\") as f:\n            self._cookies = pickle.load(f)\n\n    def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None:\n        if predicate is None:\n            self._next_expiration = ceil(time.time())\n            self._cookies.clear()\n            self._host_only_cookies.clear()\n            self._expirations.clear()\n            return\n\n        to_del = []\n        now = time.time()\n        for (domain, path), cookie in self._cookies.items():\n            for name, morsel in cookie.items():\n                key = (domain, path, name)\n                if (\n                    key in self._expirations and self._expirations[key] <= now\n                ) or predicate(morsel):\n                    to_del.append(key)\n\n        for domain, path, name in to_del:\n            self._host_only_cookies.discard((domain, name))\n            key = (domain, path, name)\n            if key in self._expirations:\n                del self._expirations[(domain, path, name)]\n            self._cookies[(domain, path)].pop(name, None)\n\n        self._next_expiration = (\n            min(*self._expirations.values(), self.SUB_MAX_TIME) + 1\n            if self._expirations\n            else self.MAX_TIME\n        )\n\n    def clear_domain(self, domain: str) -> None:\n        self.clear(lambda x: self._is_domain_match(domain, x[\"domain\"]))\n\n    def __iter__(self) -> \"Iterator[Morsel[str]]\":\n        self._do_expiration()\n        for val in self._cookies.values():\n            yield from val.values()\n\n    def __len__(self) -> int:\n        return sum(1 for i in self)\n\n    def _do_expiration(self) -> None:\n        self.clear(lambda x: False)\n\n    def _expire_cookie(self, when: float, domain: str, path: str, name: str) -> None:\n        self._next_expiration = min(self._next_expiration, when)\n        self._expirations[(domain, path, name)] = when\n\n    def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None:\n        \"\"\"Update cookies.\"\"\"\n        hostname = response_url.raw_host\n\n        if not self._unsafe and is_ip_address(hostname):\n            # Don't accept cookies from IPs\n            return\n\n        if isinstance(cookies, Mapping):\n            cookies = cookies.items()\n\n        for name, cookie in cookies:\n            if not isinstance(cookie, Morsel):\n                tmp = SimpleCookie()\n                tmp[name] = cookie  # type: ignore[assignment]\n                cookie = tmp[name]\n\n            domain = cookie[\"domain\"]\n\n            # ignore domains with trailing dots\n            if domain.endswith(\".\"):\n                domain = \"\"\n                del cookie[\"domain\"]\n\n            if not domain and hostname is not None:\n                # Set the cookie's domain to the response hostname\n                # and set its host-only-flag\n                self._host_only_cookies.add((hostname, name))\n                domain = cookie[\"domain\"] = hostname\n\n            if domain.startswith(\".\"):\n                # Remove leading dot\n                domain = domain[1:]\n                cookie[\"domain\"] = domain\n\n            if hostname and not self._is_domain_match(domain, hostname):\n                # Setting cookies for different domains is not allowed\n                continue\n\n            path = cookie[\"path\"]\n            if not path or not path.startswith(\"/\"):\n                # Set the cookie's path to the response path\n                path = response_url.path\n                if not path.startswith(\"/\"):\n                    path = \"/\"\n                else:\n                    # Cut everything from the last slash to the end\n                    path = \"/\" + path[1 : path.rfind(\"/\")]\n                cookie[\"path\"] = path\n            path = path.rstrip(\"/\")\n\n            max_age = cookie[\"max-age\"]\n            if max_age:\n                try:\n                    delta_seconds = int(max_age)\n                    max_age_expiration = min(time.time() + delta_seconds, self.MAX_TIME)\n                    self._expire_cookie(max_age_expiration, domain, path, name)\n                except ValueError:\n                    cookie[\"max-age\"] = \"\"\n\n            else:\n                expires = cookie[\"expires\"]\n                if expires:\n                    expire_time = self._parse_date(expires)\n                    if expire_time:\n                        self._expire_cookie(expire_time, domain, path, name)\n                    else:\n                        cookie[\"expires\"] = \"\"\n\n            self._cookies[(domain, path)][name] = cookie\n\n        self._do_expiration()\n\n    def filter_cookies(self, request_url: URL = URL()) -> \"BaseCookie[str]\":\n        \"\"\"Returns this jar's cookies filtered by their attributes.\"\"\"\n        if not isinstance(request_url, URL):\n            warnings.warn(\n                \"The method accepts yarl.URL instances only, got {}\".format(\n                    type(request_url)\n                ),\n                DeprecationWarning,\n            )\n            request_url = URL(request_url)\n        filtered: Union[SimpleCookie, \"BaseCookie[str]\"] = (\n            SimpleCookie() if self._quote_cookie else BaseCookie()\n        )\n        if not self._cookies:\n            # Skip do_expiration() if there are no cookies.\n            return filtered\n        self._do_expiration()\n        if not self._cookies:\n            # Skip rest of function if no non-expired cookies.\n            return filtered\n        hostname = request_url.raw_host or \"\"\n\n        is_not_secure = request_url.scheme not in (\"https\", \"wss\")\n        if is_not_secure and self._treat_as_secure_origin:\n            request_origin = URL()\n            with contextlib.suppress(ValueError):\n                request_origin = request_url.origin()\n            is_not_secure = request_origin not in self._treat_as_secure_origin\n\n        # Send shared cookie\n        for c in self._cookies[(\"\", \"\")].values():\n            filtered[c.key] = c.value\n\n        if is_ip_address(hostname):\n            if not self._unsafe:\n                return filtered\n            domains: Iterable[str] = (hostname,)\n        else:\n            # Get all the subdomains that might match a cookie (e.g. \"foo.bar.com\", \"bar.com\", \"com\")\n            domains = itertools.accumulate(\n                reversed(hostname.split(\".\")), lambda x, y: f\"{y}.{x}\"\n            )\n        # Get all the path prefixes that might match a cookie (e.g. \"\", \"/foo\", \"/foo/bar\")\n        paths = itertools.accumulate(\n            request_url.path.split(\"/\"), lambda x, y: f\"{x}/{y}\"\n        )\n        # Create every combination of (domain, path) pairs.\n        pairs = itertools.product(domains, paths)\n\n        # Point 2: https://www.rfc-editor.org/rfc/rfc6265.html#section-5.4\n        cookies = itertools.chain.from_iterable(\n            self._cookies[p].values() for p in pairs\n        )\n        path_len = len(request_url.path)\n        for cookie in cookies:\n            name = cookie.key\n            domain = cookie[\"domain\"]\n\n            if (domain, name) in self._host_only_cookies:\n                if domain != hostname:\n                    continue\n\n            # Skip edge case when the cookie has a trailing slash but request doesn't.\n            if len(cookie[\"path\"]) > path_len:\n                continue\n\n            if is_not_secure and cookie[\"secure\"]:\n                continue\n\n            # It's critical we use the Morsel so the coded_value\n            # (based on cookie version) is preserved\n            mrsl_val = cast(\"Morsel[str]\", cookie.get(cookie.key, Morsel()))\n            mrsl_val.set(cookie.key, cookie.value, cookie.coded_value)\n            filtered[name] = mrsl_val\n\n        return filtered\n\n    @staticmethod\n    def _is_domain_match(domain: str, hostname: str) -> bool:\n        \"\"\"Implements domain matching adhering to RFC 6265.\"\"\"\n        if hostname == domain:\n            return True\n\n        if not hostname.endswith(domain):\n            return False\n\n        non_matching = hostname[: -len(domain)]\n\n        if not non_matching.endswith(\".\"):\n            return False\n\n        return not is_ip_address(hostname)\n\n    @classmethod\n    def _parse_date(cls, date_str: str) -> Optional[int]:\n        \"\"\"Implements date string parsing adhering to RFC 6265.\"\"\"\n        if not date_str:\n            return None\n\n        found_time = False\n        found_day = False\n        found_month = False\n        found_year = False\n\n        hour = minute = second = 0\n        day = 0\n        month = 0\n        year = 0\n\n        for token_match in cls.DATE_TOKENS_RE.finditer(date_str):\n            token = token_match.group(\"token\")\n\n            if not found_time:\n                time_match = cls.DATE_HMS_TIME_RE.match(token)\n                if time_match:\n                    found_time = True\n                    hour, minute, second = (int(s) for s in time_match.groups())\n                    continue\n\n            if not found_day:\n                day_match = cls.DATE_DAY_OF_MONTH_RE.match(token)\n                if day_match:\n                    found_day = True\n                    day = int(day_match.group())\n                    continue\n\n            if not found_month:\n                month_match = cls.DATE_MONTH_RE.match(token)\n                if month_match:\n                    found_month = True\n                    assert month_match.lastindex is not None\n                    month = month_match.lastindex\n                    continue\n\n            if not found_year:\n                year_match = cls.DATE_YEAR_RE.match(token)\n                if year_match:\n                    found_year = True\n                    year = int(year_match.group())\n\n        if 70 <= year <= 99:\n            year += 1900\n        elif 0 <= year <= 69:\n            year += 2000\n\n        if False in (found_day, found_month, found_year, found_time):\n            return None\n\n        if not 1 <= day <= 31:\n            return None\n\n        if year < 1601 or hour > 23 or minute > 59 or second > 59:\n            return None\n\n        return calendar.timegm((year, month, day, hour, minute, second, -1, -1, -1))",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 40,
                            "end_lineno": 391,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "# type: ignore\nimport asyncio\nimport datetime\nimport itertools\nimport pathlib\nimport pickle\nimport unittest\nfrom http.cookies import BaseCookie, Morsel, SimpleCookie\nfrom typing import Any\nfrom unittest import mock\n\nimport pytest\nfrom freezegun import freeze_time\nfrom yarl import URL\n\nfrom aiohttp import CookieJar, DummyCookieJar\n\n\ndef dump_cookiejar() -> bytes:  # pragma: no cover\n    \"\"\"Create pickled data for test_pickle_format().\"\"\"\n    cj = CookieJar()\n    cj.update_cookies(cookies_to_send.__pytest_wrapped__.obj())\n    return pickle.dumps(cj._cookies, pickle.HIGHEST_PROTOCOL)\n\n\n@pytest.fixture\ndef cookies_to_send():\n    return SimpleCookie(\n        \"shared-cookie=first; \"\n        \"domain-cookie=second; Domain=example.com; \"\n        \"subdomain1-cookie=third; Domain=test1.example.com; \"\n        \"subdomain2-cookie=fourth; Domain=test2.example.com; \"\n        \"dotted-domain-cookie=fifth; Domain=.example.com; \"\n        \"different-domain-cookie=sixth; Domain=different.org; \"\n        \"secure-cookie=seventh; Domain=secure.com; Secure; \"\n        \"no-path-cookie=eighth; Domain=pathtest.com; \"\n        \"path1-cookie=ninth; Domain=pathtest.com; Path=/; \"\n        \"path2-cookie=tenth; Domain=pathtest.com; Path=/one; \"\n        \"path3-cookie=eleventh; Domain=pathtest.com; Path=/one/two; \"\n        \"path4-cookie=twelfth; Domain=pathtest.com; Path=/one/two/; \"\n        \"expires-cookie=thirteenth; Domain=expirestest.com; Path=/;\"\n        \" Expires=Tue, 1 Jan 2999 12:00:00 GMT; \"\n        \"max-age-cookie=fourteenth; Domain=maxagetest.com; Path=/;\"\n        \" Max-Age=60; \"\n        \"invalid-max-age-cookie=fifteenth; Domain=invalid-values.com; \"\n        \" Max-Age=string; \"\n        \"invalid-expires-cookie=sixteenth; Domain=invalid-values.com; \"\n        \" Expires=string;\"\n    )\n\n\n@pytest.fixture\ndef cookies_to_send_with_expired():\n    return SimpleCookie(\n        \"shared-cookie=first; \"\n        \"domain-cookie=second; Domain=example.com; \"\n        \"subdomain1-cookie=third; Domain=test1.example.com; \"\n        \"subdomain2-cookie=fourth; Domain=test2.example.com; \"\n        \"dotted-domain-cookie=fifth; Domain=.example.com; \"\n        \"different-domain-cookie=sixth; Domain=different.org; \"\n        \"secure-cookie=seventh; Domain=secure.com; Secure; \"\n        \"no-path-cookie=eighth; Domain=pathtest.com; \"\n        \"path1-cookie=ninth; Domain=pathtest.com; Path=/; \"\n        \"path2-cookie=tenth; Domain=pathtest.com; Path=/one; \"\n        \"path3-cookie=eleventh; Domain=pathtest.com; Path=/one/two; \"\n        \"path4-cookie=twelfth; Domain=pathtest.com; Path=/one/two/; \"\n        \"expires-cookie=thirteenth; Domain=expirestest.com; Path=/;\"\n        \" Expires=Tue, 1 Jan 1980 12:00:00 GMT; \"\n        \"max-age-cookie=fourteenth; Domain=maxagetest.com; Path=/;\"\n        \" Max-Age=60; \"\n        \"invalid-max-age-cookie=fifteenth; Domain=invalid-values.com; \"\n        \" Max-Age=string; \"\n        \"invalid-expires-cookie=sixteenth; Domain=invalid-values.com; \"\n        \" Expires=string;\"\n    )\n\n\n@pytest.fixture\ndef cookies_to_receive():\n    return SimpleCookie(\n        \"unconstrained-cookie=first; Path=/; \"\n        \"domain-cookie=second; Domain=example.com; Path=/; \"\n        \"subdomain1-cookie=third; Domain=test1.example.com; Path=/; \"\n        \"subdomain2-cookie=fourth; Domain=test2.example.com; Path=/; \"\n        \"dotted-domain-cookie=fifth; Domain=.example.com; Path=/; \"\n        \"different-domain-cookie=sixth; Domain=different.org; Path=/; \"\n        \"no-path-cookie=seventh; Domain=pathtest.com; \"\n        \"path-cookie=eighth; Domain=pathtest.com; Path=/somepath; \"\n        \"wrong-path-cookie=ninth; Domain=pathtest.com; Path=somepath;\"\n    )\n\n\ndef test_date_parsing() -> None:\n    parse_func = CookieJar._parse_date\n    utc = datetime.timezone.utc\n\n    assert parse_func(\"\") is None\n\n    # 70 -> 1970\n    assert (\n        parse_func(\"Tue, 1 Jan 70 00:00:00 GMT\")\n        == datetime.datetime(1970, 1, 1, tzinfo=utc).timestamp()\n    )\n\n    # 10 -> 2010\n    assert (\n        parse_func(\"Tue, 1 Jan 10 00:00:00 GMT\")\n        == datetime.datetime(2010, 1, 1, tzinfo=utc).timestamp()\n    )\n\n    # No day of week string\n    assert (\n        parse_func(\"1 Jan 1970 00:00:00 GMT\")\n        == datetime.datetime(1970, 1, 1, tzinfo=utc).timestamp()\n    )\n\n    # No timezone string\n    assert (\n        parse_func(\"Tue, 1 Jan 1970 00:00:00\")\n        == datetime.datetime(1970, 1, 1, tzinfo=utc).timestamp()\n    )\n\n    # No year\n    assert parse_func(\"Tue, 1 Jan 00:00:00 GMT\") is None\n\n    # No month\n    assert parse_func(\"Tue, 1 1970 00:00:00 GMT\") is None\n\n    # No day of month\n    assert parse_func(\"Tue, Jan 1970 00:00:00 GMT\") is None\n\n    # No time\n    assert parse_func(\"Tue, 1 Jan 1970 GMT\") is None\n\n    # Invalid day of month\n    assert parse_func(\"Tue, 0 Jan 1970 00:00:00 GMT\") is None\n\n    # Invalid year\n    assert parse_func(\"Tue, 1 Jan 1500 00:00:00 GMT\") is None\n\n    # Invalid time\n    assert parse_func(\"Tue, 1 Jan 1970 77:88:99 GMT\") is None\n\n\ndef test_domain_matching() -> None:\n    test_func = CookieJar._is_domain_match\n\n    assert test_func(\"test.com\", \"test.com\")\n    assert test_func(\"test.com\", \"sub.test.com\")\n\n    assert not test_func(\"test.com\", \"\")\n    assert not test_func(\"test.com\", \"test.org\")\n    assert not test_func(\"diff-test.com\", \"test.com\")\n    assert not test_func(\"test.com\", \"diff-test.com\")\n    assert not test_func(\"test.com\", \"127.0.0.1\")\n\n\nasync def test_constructor(cookies_to_send: Any, cookies_to_receive: Any) -> None:\n    jar = CookieJar()\n    jar.update_cookies(cookies_to_send)\n    jar_cookies = SimpleCookie()\n    for cookie in jar:\n        dict.__setitem__(jar_cookies, cookie.key, cookie)\n    expected_cookies = cookies_to_send\n    assert jar_cookies == expected_cookies\n\n\nasync def test_constructor_with_expired(\n    cookies_to_send_with_expired: Any, cookies_to_receive: Any\n) -> None:\n    jar = CookieJar()\n    jar.update_cookies(cookies_to_send_with_expired)\n    jar_cookies = SimpleCookie()\n    for cookie in jar:\n        dict.__setitem__(jar_cookies, cookie.key, cookie)\n    expected_cookies = cookies_to_send_with_expired\n    assert jar_cookies != expected_cookies\n\n\nasync def test_save_load(\n    tmp_path: Any, loop: Any, cookies_to_send: Any, cookies_to_receive: Any\n) -> None:\n    file_path = pathlib.Path(str(tmp_path)) / \"aiohttp.test.cookie\"\n\n    # export cookie jar\n    jar_save = CookieJar()\n    jar_save.update_cookies(cookies_to_receive)\n    jar_save.save(file_path=file_path)\n\n    jar_load = CookieJar()\n    jar_load.load(file_path=file_path)\n\n    jar_test = SimpleCookie()\n    for cookie in jar_load:\n        jar_test[cookie.key] = cookie\n\n    assert jar_test == cookies_to_receive\n\n\nasync def test_update_cookie_with_unicode_domain(loop: Any) -> None:\n    cookies = (\n        \"idna-domain-first=first; Domain=xn--9caa.com; Path=/;\",\n        \"idna-domain-second=second; Domain=xn--9caa.com; Path=/;\",\n    )\n\n    jar = CookieJar()\n    jar.update_cookies(SimpleCookie(cookies[0]), URL(\"http://éé.com/\"))\n    jar.update_cookies(SimpleCookie(cookies[1]), URL(\"http://xn--9caa.com/\"))\n\n    jar_test = SimpleCookie()\n    for cookie in jar:\n        jar_test[cookie.key] = cookie\n\n    assert jar_test == SimpleCookie(\" \".join(cookies))\n\n\nasync def test_filter_cookie_with_unicode_domain(loop: Any) -> None:\n    jar = CookieJar()\n    jar.update_cookies(\n        SimpleCookie(\"idna-domain-first=first; Domain=xn--9caa.com; Path=/; \")\n    )\n    assert len(jar.filter_cookies(URL(\"http://éé.com\"))) == 1\n    assert len(jar.filter_cookies(URL(\"http://xn--9caa.com\"))) == 1\n\n\nasync def test_filter_cookies_str_deprecated(loop: Any) -> None:\n    jar = CookieJar()\n    with pytest.deprecated_call(\n        match=\"The method accepts yarl.URL instances only, got <class 'str'>\",\n    ):\n        jar.filter_cookies(\"http://éé.com\")\n\n\n@pytest.mark.parametrize(\n    (\"url\", \"expected_cookies\"),\n    (\n        (\n            \"http://pathtest.com/one/two/\",\n            (\n                \"no-path-cookie\",\n                \"path1-cookie\",\n                \"path2-cookie\",\n                \"shared-cookie\",\n                \"path3-cookie\",\n                \"path4-cookie\",\n            ),\n        ),\n        (\n            \"http://pathtest.com/one/two\",\n            (\n                \"no-path-cookie\",\n                \"path1-cookie\",\n                \"path2-cookie\",\n                \"shared-cookie\",\n                \"path3-cookie\",\n            ),\n        ),\n        (\n            \"http://pathtest.com/one/two/three/\",\n            (\n                \"no-path-cookie\",\n                \"path1-cookie\",\n                \"path2-cookie\",\n                \"shared-cookie\",\n                \"path3-cookie\",\n                \"path4-cookie\",\n            ),\n        ),\n        (\n            \"http://test1.example.com/\",\n            (\n                \"shared-cookie\",\n                \"domain-cookie\",\n                \"subdomain1-cookie\",\n                \"dotted-domain-cookie\",\n            ),\n        ),\n        (\n            \"http://pathtest.com/\",\n            (\n                \"shared-cookie\",\n                \"no-path-cookie\",\n                \"path1-cookie\",\n            ),\n        ),\n    ),\n)\nasync def test_filter_cookies_with_domain_path_lookup_multilevelpath(\n    loop: Any,\n    url: Any,\n    expected_cookies: Any,\n) -> None:\n    jar = CookieJar()\n    cookies = SimpleCookie(\n        \"shared-cookie=first; \"\n        \"domain-cookie=second; Domain=example.com; \"\n        \"subdomain1-cookie=third; Domain=test1.example.com; \"\n        \"subdomain2-cookie=fourth; Domain=test2.example.com; \"\n        \"dotted-domain-cookie=fifth; Domain=.example.com; \"\n        \"different-domain-cookie=sixth; Domain=different.org; \"\n        \"secure-cookie=seventh; Domain=secure.com; Secure; \"\n        \"no-path-cookie=eighth; Domain=pathtest.com; \"\n        \"path1-cookie=ninth; Domain=pathtest.com; Path=/; \"\n        \"path2-cookie=tenth; Domain=pathtest.com; Path=/one; \"\n        \"path3-cookie=eleventh; Domain=pathtest.com; Path=/one/two; \"\n        \"path4-cookie=twelfth; Domain=pathtest.com; Path=/one/two/; \"\n        \"expires-cookie=thirteenth; Domain=expirestest.com; Path=/;\"\n        \" Expires=Tue, 1 Jan 1980 12:00:00 GMT; \"\n        \"max-age-cookie=fourteenth; Domain=maxagetest.com; Path=/;\"\n        \" Max-Age=60; \"\n        \"invalid-max-age-cookie=fifteenth; Domain=invalid-values.com; \"\n        \" Max-Age=string; \"\n        \"invalid-expires-cookie=sixteenth; Domain=invalid-values.com; \"\n        \" Expires=string;\"\n    )\n    jar.update_cookies(cookies)\n    cookies = jar.filter_cookies(URL(url))\n\n    assert len(cookies) == len(expected_cookies)\n    for c in cookies:\n        assert c in expected_cookies\n\n\nasync def test_domain_filter_ip_cookie_send(loop: Any) -> None:\n    jar = CookieJar()\n    cookies = SimpleCookie(\n        \"shared-cookie=first; \"\n        \"domain-cookie=second; Domain=example.com; \"\n        \"subdomain1-cookie=third; Domain=test1.example.com; \"\n        \"subdomain2-cookie=fourth; Domain=test2.example.com; \"\n        \"dotted-domain-cookie=fifth; Domain=.example.com; \"\n        \"different-domain-cookie=sixth; Domain=different.org; \"\n        \"secure-cookie=seventh; Domain=secure.com; Secure; \"\n        \"no-path-cookie=eighth; Domain=pathtest.com; \"\n        \"path1-cookie=ninth; Domain=pathtest.com; Path=/; \"\n        \"path2-cookie=tenth; Domain=pathtest.com; Path=/one; \"\n        \"path3-cookie=eleventh; Domain=pathtest.com; Path=/one/two; \"\n        \"path4-cookie=twelfth; Domain=pathtest.com; Path=/one/two/; \"\n        \"expires-cookie=thirteenth; Domain=expirestest.com; Path=/;\"\n        \" Expires=Tue, 1 Jan 1980 12:00:00 GMT; \"\n        \"max-age-cookie=fourteenth; Domain=maxagetest.com; Path=/;\"\n        \" Max-Age=60; \"\n        \"invalid-max-age-cookie=fifteenth; Domain=invalid-values.com; \"\n        \" Max-Age=string; \"\n        \"invalid-expires-cookie=sixteenth; Domain=invalid-values.com; \"\n        \" Expires=string;\"\n    )\n\n    jar.update_cookies(cookies)\n    cookies_sent = jar.filter_cookies(URL(\"http://1.2.3.4/\")).output(header=\"Cookie:\")\n    assert cookies_sent == \"Cookie: shared-cookie=first\"\n\n\nasync def test_domain_filter_ip_cookie_receive(cookies_to_receive: Any) -> None:\n    jar = CookieJar()\n\n    jar.update_cookies(cookies_to_receive, URL(\"http://1.2.3.4/\"))\n    assert len(jar) == 0\n\n\n@pytest.mark.parametrize(\n    (\"cookies\", \"expected\", \"quote_bool\"),\n    [\n        (\n            \"shared-cookie=first; ip-cookie=second; Domain=127.0.0.1;\",\n            \"Cookie: ip-cookie=second\\r\\nCookie: shared-cookie=first\",\n            True,\n        ),\n        ('ip-cookie=\"second\"; Domain=127.0.0.1;', 'Cookie: ip-cookie=\"second\"', True),\n        (\"custom-cookie=value/one;\", 'Cookie: custom-cookie=\"value/one\"', True),\n        (\"custom-cookie=value1;\", \"Cookie: custom-cookie=value1\", True),\n        (\"custom-cookie=value/one;\", \"Cookie: custom-cookie=value/one\", False),\n    ],\n    ids=(\n        \"IP domain preserved\",\n        \"no shared cookie\",\n        \"quoted cookie with special char\",\n        \"quoted cookie w/o special char\",\n        \"unquoted cookie with special char\",\n    ),\n)\nasync def test_quotes_correctly_based_on_input(\n    loop: Any, cookies: Any, expected: Any, quote_bool: Any\n) -> None:\n    jar = CookieJar(unsafe=True, quote_cookie=quote_bool)\n    jar.update_cookies(SimpleCookie(cookies))\n    cookies_sent = jar.filter_cookies(URL(\"http://127.0.0.1/\")).output(header=\"Cookie:\")\n    assert cookies_sent == expected\n\n\nasync def test_ignore_domain_ending_with_dot(loop: Any) -> None:\n    jar = CookieJar(unsafe=True)\n    jar.update_cookies(\n        SimpleCookie(\"cookie=val; Domain=example.com.;\"), URL(\"http://www.example.com\")\n    )\n    cookies_sent = jar.filter_cookies(URL(\"http://www.example.com/\"))\n    assert cookies_sent.output(header=\"Cookie:\") == \"Cookie: cookie=val\"\n    cookies_sent = jar.filter_cookies(URL(\"http://example.com/\"))\n    assert cookies_sent.output(header=\"Cookie:\") == \"\"\n\n\nclass TestCookieJarBase(unittest.TestCase):\n    loop: Any\n    jar: Any\n\n    def setUp(self):\n        self.loop = asyncio.new_event_loop()\n        asyncio.set_event_loop(None)\n\n        # N.B. those need to be overridden in child test cases\n        async def make_jar():\n            return CookieJar()\n\n        self.jar = self.loop.run_until_complete(make_jar())\n\n    def tearDown(self) -> None:\n        self.loop.close()\n\n    def request_reply_with_same_url(self, url: Any):\n        self.jar.update_cookies(self.cookies_to_send)\n        cookies_sent = self.jar.filter_cookies(URL(url))\n\n        self.jar.clear()\n\n        self.jar.update_cookies(self.cookies_to_receive, URL(url))\n        cookies_received = SimpleCookie()\n        for cookie in self.jar:\n            dict.__setitem__(cookies_received, cookie.key, cookie)\n\n        self.jar.clear()\n\n        return cookies_sent, cookies_received\n\n\nclass TestCookieJarSafe(TestCookieJarBase):\n    cookies_to_send: Any\n    cookies_to_receive: Any\n    jar: Any\n\n    def setUp(self):\n        super().setUp()\n\n        self.cookies_to_send = SimpleCookie(\n            \"shared-cookie=first; \"\n            \"domain-cookie=second; Domain=example.com; \"\n            \"subdomain1-cookie=third; Domain=test1.example.com; \"\n            \"subdomain2-cookie=fourth; Domain=test2.example.com; \"\n            \"dotted-domain-cookie=fifth; Domain=.example.com; \"\n            \"different-domain-cookie=sixth; Domain=different.org; \"\n            \"secure-cookie=seventh; Domain=secure.com; Secure; \"\n            \"no-path-cookie=eighth; Domain=pathtest.com; \"\n            \"path1-cookie=ninth; Domain=pathtest.com; Path=/; \"\n            \"path2-cookie=tenth; Domain=pathtest.com; Path=/one; \"\n            \"path3-cookie=eleventh; Domain=pathtest.com; Path=/one/two; \"\n            \"path4-cookie=twelfth; Domain=pathtest.com; Path=/one/two/; \"\n            \"expires-cookie=thirteenth; Domain=expirestest.com; Path=/;\"\n            \" Expires=Tue, 1 Jan 1980 12:00:00 GMT; \"\n            \"max-age-cookie=fourteenth; Domain=maxagetest.com; Path=/;\"\n            \" Max-Age=60; \"\n            \"invalid-max-age-cookie=fifteenth; Domain=invalid-values.com; \"\n            \" Max-Age=string; \"\n            \"invalid-expires-cookie=sixteenth; Domain=invalid-values.com; \"\n            \" Expires=string;\"\n        )\n\n        self.cookies_to_receive = SimpleCookie(\n            \"unconstrained-cookie=first; Path=/; \"\n            \"domain-cookie=second; Domain=example.com; Path=/; \"\n            \"subdomain1-cookie=third; Domain=test1.example.com; Path=/; \"\n            \"subdomain2-cookie=fourth; Domain=test2.example.com; Path=/; \"\n            \"dotted-domain-cookie=fifth; Domain=.example.com; Path=/; \"\n            \"different-domain-cookie=sixth; Domain=different.org; Path=/; \"\n            \"no-path-cookie=seventh; Domain=pathtest.com; \"\n            \"path-cookie=eighth; Domain=pathtest.com; Path=/somepath; \"\n            \"wrong-path-cookie=ninth; Domain=pathtest.com; Path=somepath;\"\n        )\n\n        async def make_jar():\n            return CookieJar()\n\n        self.jar = self.loop.run_until_complete(make_jar())\n\n    def timed_request(self, url: Any, update_time: Any, send_time: Any):\n        if isinstance(update_time, int):\n            update_time = datetime.timedelta(seconds=update_time)\n        elif isinstance(update_time, float):\n            update_time = datetime.datetime.fromtimestamp(update_time)\n        if isinstance(send_time, int):\n            send_time = datetime.timedelta(seconds=send_time)\n        elif isinstance(send_time, float):\n            send_time = datetime.datetime.fromtimestamp(send_time)\n\n        with freeze_time(update_time):\n            self.jar.update_cookies(self.cookies_to_send)\n\n        with freeze_time(send_time):\n            cookies_sent = self.jar.filter_cookies(URL(url))\n\n        self.jar.clear()\n\n        return cookies_sent\n\n    def test_domain_filter_same_host(self) -> None:\n        cookies_sent, cookies_received = self.request_reply_with_same_url(\n            \"http://example.com/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\"shared-cookie\", \"domain-cookie\", \"dotted-domain-cookie\"},\n        )\n\n        self.assertEqual(\n            set(cookies_received.keys()),\n            {\"unconstrained-cookie\", \"domain-cookie\", \"dotted-domain-cookie\"},\n        )\n\n    def test_domain_filter_same_host_and_subdomain(self) -> None:\n        cookies_sent, cookies_received = self.request_reply_with_same_url(\n            \"http://test1.example.com/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\n                \"shared-cookie\",\n                \"domain-cookie\",\n                \"subdomain1-cookie\",\n                \"dotted-domain-cookie\",\n            },\n        )\n\n        self.assertEqual(\n            set(cookies_received.keys()),\n            {\n                \"unconstrained-cookie\",\n                \"domain-cookie\",\n                \"subdomain1-cookie\",\n                \"dotted-domain-cookie\",\n            },\n        )\n\n    def test_domain_filter_same_host_diff_subdomain(self) -> None:\n        cookies_sent, cookies_received = self.request_reply_with_same_url(\n            \"http://different.example.com/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\"shared-cookie\", \"domain-cookie\", \"dotted-domain-cookie\"},\n        )\n\n        self.assertEqual(\n            set(cookies_received.keys()),\n            {\"unconstrained-cookie\", \"domain-cookie\", \"dotted-domain-cookie\"},\n        )\n\n    def test_domain_filter_diff_host(self) -> None:\n        cookies_sent, cookies_received = self.request_reply_with_same_url(\n            \"http://different.org/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()), {\"shared-cookie\", \"different-domain-cookie\"}\n        )\n\n        self.assertEqual(\n            set(cookies_received.keys()),\n            {\"unconstrained-cookie\", \"different-domain-cookie\"},\n        )\n\n    def test_domain_filter_host_only(self) -> None:\n        self.jar.update_cookies(self.cookies_to_receive, URL(\"http://example.com/\"))\n        sub_cookie = SimpleCookie(\"subdomain=spam; Path=/;\")\n        self.jar.update_cookies(sub_cookie, URL(\"http://foo.example.com/\"))\n\n        cookies_sent = self.jar.filter_cookies(URL(\"http://foo.example.com/\"))\n        self.assertIn(\"subdomain\", set(cookies_sent.keys()))\n        self.assertNotIn(\"unconstrained-cookie\", set(cookies_sent.keys()))\n\n    def test_secure_filter(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\"http://secure.com/\")\n\n        self.assertEqual(set(cookies_sent.keys()), {\"shared-cookie\"})\n\n        cookies_sent, _ = self.request_reply_with_same_url(\"https://secure.com/\")\n\n        self.assertEqual(set(cookies_sent.keys()), {\"shared-cookie\", \"secure-cookie\"})\n\n    def test_path_filter_root(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\"http://pathtest.com/\")\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\"shared-cookie\", \"no-path-cookie\", \"path1-cookie\"},\n        )\n\n    def test_path_filter_folder(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\"http://pathtest.com/one/\")\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\"shared-cookie\", \"no-path-cookie\", \"path1-cookie\", \"path2-cookie\"},\n        )\n\n    def test_path_filter_file(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\n            \"http://pathtest.com/one/two\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\n                \"shared-cookie\",\n                \"no-path-cookie\",\n                \"path1-cookie\",\n                \"path2-cookie\",\n                \"path3-cookie\",\n            },\n        )\n\n    def test_path_filter_subfolder(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\n            \"http://pathtest.com/one/two/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\n                \"shared-cookie\",\n                \"no-path-cookie\",\n                \"path1-cookie\",\n                \"path2-cookie\",\n                \"path3-cookie\",\n                \"path4-cookie\",\n            },\n        )\n\n    def test_path_filter_subsubfolder(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\n            \"http://pathtest.com/one/two/three/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\n                \"shared-cookie\",\n                \"no-path-cookie\",\n                \"path1-cookie\",\n                \"path2-cookie\",\n                \"path3-cookie\",\n                \"path4-cookie\",\n            },\n        )\n\n    def test_path_filter_different_folder(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\n            \"http://pathtest.com/hundred/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\"shared-cookie\", \"no-path-cookie\", \"path1-cookie\"},\n        )\n\n    def test_path_value(self) -> None:\n        _, cookies_received = self.request_reply_with_same_url(\"http://pathtest.com/\")\n\n        self.assertEqual(\n            set(cookies_received.keys()),\n            {\n                \"unconstrained-cookie\",\n                \"no-path-cookie\",\n                \"path-cookie\",\n                \"wrong-path-cookie\",\n            },\n        )\n\n        self.assertEqual(cookies_received[\"no-path-cookie\"][\"path\"], \"/\")\n        self.assertEqual(cookies_received[\"path-cookie\"][\"path\"], \"/somepath\")\n        self.assertEqual(cookies_received[\"wrong-path-cookie\"][\"path\"], \"/\")\n\n    def test_expires(self) -> None:\n        ts_before = datetime.datetime(\n            1975, 1, 1, tzinfo=datetime.timezone.utc\n        ).timestamp()\n\n        ts_after = datetime.datetime(\n            2030, 1, 1, tzinfo=datetime.timezone.utc\n        ).timestamp()\n\n        cookies_sent = self.timed_request(\n            \"http://expirestest.com/\", ts_before, ts_before\n        )\n\n        self.assertEqual(set(cookies_sent.keys()), {\"shared-cookie\", \"expires-cookie\"})\n\n        cookies_sent = self.timed_request(\n            \"http://expirestest.com/\", ts_before, ts_after\n        )\n\n        self.assertEqual(set(cookies_sent.keys()), {\"shared-cookie\"})\n\n    def test_max_age(self) -> None:\n        cookies_sent = self.timed_request(\"http://maxagetest.com/\", 1000, 1000)\n\n        self.assertEqual(set(cookies_sent.keys()), {\"shared-cookie\", \"max-age-cookie\"})\n\n        cookies_sent = self.timed_request(\"http://maxagetest.com/\", 1000, 2000)\n\n        self.assertEqual(set(cookies_sent.keys()), {\"shared-cookie\"})\n\n    def test_invalid_values(self) -> None:\n        cookies_sent, cookies_received = self.request_reply_with_same_url(\n            \"http://invalid-values.com/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\"shared-cookie\", \"invalid-max-age-cookie\", \"invalid-expires-cookie\"},\n        )\n\n        cookie = cookies_sent[\"invalid-max-age-cookie\"]\n        self.assertEqual(cookie[\"max-age\"], \"\")\n\n        cookie = cookies_sent[\"invalid-expires-cookie\"]\n        self.assertEqual(cookie[\"expires\"], \"\")\n\n    def test_cookie_not_expired_when_added_after_removal(self) -> None:\n        # Test case for https://github.com/aio-libs/aiohttp/issues/2084\n        timestamps = [\n            533588.993,\n            533588.993,\n            533588.993,\n            533588.993,\n            533589.093,\n            533589.093,\n        ]\n\n        loop = mock.Mock()\n        loop.time.side_effect = itertools.chain(\n            timestamps, itertools.cycle([timestamps[-1]])\n        )\n\n        async def make_jar():\n            return CookieJar(unsafe=True)\n\n        jar = self.loop.run_until_complete(make_jar())\n        # Remove `foo` cookie.\n        jar.update_cookies(SimpleCookie('foo=\"\"; Max-Age=0'))\n        # Set `foo` cookie to `bar`.\n        jar.update_cookies(SimpleCookie('foo=\"bar\"'))\n\n        # Assert that there is a cookie.\n        assert len(jar) == 1\n\n    def test_path_filter_diff_folder_same_name(self) -> None:\n        async def make_jar():\n            return CookieJar(unsafe=True)\n\n        jar = self.loop.run_until_complete(make_jar())\n\n        jar.update_cookies(\n            SimpleCookie(\"path-cookie=zero; Domain=pathtest.com; Path=/; \")\n        )\n        jar.update_cookies(\n            SimpleCookie(\"path-cookie=one; Domain=pathtest.com; Path=/one; \")\n        )\n        self.assertEqual(len(jar), 2)\n\n        jar_filtered = jar.filter_cookies(URL(\"http://pathtest.com/\"))\n        self.assertEqual(len(jar_filtered), 1)\n        self.assertEqual(jar_filtered[\"path-cookie\"].value, \"zero\")\n\n        jar_filtered = jar.filter_cookies(URL(\"http://pathtest.com/one\"))\n        self.assertEqual(len(jar_filtered), 1)\n        self.assertEqual(jar_filtered[\"path-cookie\"].value, \"one\")\n\n    def test_path_filter_diff_folder_same_name_return_best_match_independent_from_put_order(\n        self,\n    ) -> None:\n        async def make_jar():\n            return CookieJar(unsafe=True)\n\n        jar = self.loop.run_until_complete(make_jar())\n        jar.update_cookies(\n            SimpleCookie(\"path-cookie=one; Domain=pathtest.com; Path=/one; \")\n        )\n        jar.update_cookies(\n            SimpleCookie(\"path-cookie=zero; Domain=pathtest.com; Path=/; \")\n        )\n        jar.update_cookies(\n            SimpleCookie(\"path-cookie=two; Domain=pathtest.com; Path=/second; \")\n        )\n        self.assertEqual(len(jar), 3)\n\n        jar_filtered = jar.filter_cookies(URL(\"http://pathtest.com/\"))\n        self.assertEqual(len(jar_filtered), 1)\n        self.assertEqual(jar_filtered[\"path-cookie\"].value, \"zero\")\n\n        jar_filtered = jar.filter_cookies(URL(\"http://pathtest.com/second\"))\n        self.assertEqual(len(jar_filtered), 1)\n        self.assertEqual(jar_filtered[\"path-cookie\"].value, \"two\")\n\n        jar_filtered = jar.filter_cookies(URL(\"http://pathtest.com/one\"))\n        self.assertEqual(len(jar_filtered), 1)\n        self.assertEqual(jar_filtered[\"path-cookie\"].value, \"one\")\n\n\nasync def test_dummy_cookie_jar() -> None:\n    cookie = SimpleCookie(\"foo=bar; Domain=example.com;\")\n    dummy_jar = DummyCookieJar()\n    assert len(dummy_jar) == 0\n    dummy_jar.update_cookies(cookie)\n    assert len(dummy_jar) == 0\n    with pytest.raises(StopIteration):\n        next(iter(dummy_jar))\n    assert not dummy_jar.filter_cookies(URL(\"http://example.com/\"))\n    dummy_jar.clear()\n\n\nasync def test_loose_cookies_types() -> None:\n    jar = CookieJar()\n\n    accepted_types = [\n        [(\"str\", BaseCookie())],\n        [(\"str\", Morsel())],\n        [\n            (\"str\", \"str\"),\n        ],\n        {\"str\": BaseCookie()},\n        {\"str\": Morsel()},\n        {\"str\": \"str\"},\n        SimpleCookie(),\n    ]\n\n    for loose_cookies_type in accepted_types:\n        jar.update_cookies(cookies=loose_cookies_type)\n\n\nasync def test_cookie_jar_clear_all() -> None:\n    sut = CookieJar()\n    cookie = SimpleCookie()\n    cookie[\"foo\"] = \"bar\"\n    sut.update_cookies(cookie)\n\n    sut.clear()\n    assert len(sut) == 0\n\n\nasync def test_cookie_jar_clear_expired():\n    sut = CookieJar()\n\n    cookie = SimpleCookie()\n\n    cookie[\"foo\"] = \"bar\"\n    cookie[\"foo\"][\"expires\"] = \"Tue, 1 Jan 1990 12:00:00 GMT\"\n\n    with freeze_time(\"1980-01-01\"):\n        sut.update_cookies(cookie)\n\n    sut.clear(lambda x: False)\n    with freeze_time(\"1980-01-01\"):\n        assert len(sut) == 0\n\n\nasync def test_cookie_jar_clear_domain() -> None:\n    sut = CookieJar()\n    cookie = SimpleCookie()\n    cookie[\"foo\"] = \"bar\"\n    cookie[\"domain_cookie\"] = \"value\"\n    cookie[\"domain_cookie\"][\"domain\"] = \"example.com\"\n    cookie[\"subdomain_cookie\"] = \"value\"\n    cookie[\"subdomain_cookie\"][\"domain\"] = \"test.example.com\"\n    sut.update_cookies(cookie)\n\n    sut.clear_domain(\"example.com\")\n    iterator = iter(sut)\n    morsel = next(iterator)\n    assert morsel.key == \"foo\"\n    assert morsel.value == \"bar\"\n    with pytest.raises(StopIteration):\n        next(iterator)\n\n\ndef test_pickle_format(cookies_to_send) -> None:\n    \"\"\"Test if cookiejar pickle format breaks.\n\n    If this test fails, it may indicate that saved cookiejars will stop working.\n    If that happens then:\n        1. Avoid releasing the change in a bugfix release.\n        2. Try to include a migration script in the release notes (example below).\n        3. Use dump_cookiejar() at the top of this file to update `pickled`.\n\n    Depending on the changes made, a migration script might look like:\n        import pickle\n        with file_path.open(\"rb\") as f:\n            cookies = pickle.load(f)\n\n        morsels = [(name, m) for c in cookies.values() for name, m in c.items()]\n        cookies.clear()\n        for name, m in morsels:\n            cookies[(m[\"domain\"], m[\"path\"])][name] = m\n\n        with file_path.open(\"wb\") as f:\n            pickle.dump(cookies, f, pickle.HIGHEST_PROTOCOL)\n    \"\"\"\n    pickled = b\"\\x80\\x04\\x95\\xc8\\x0b\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x0bcollections\\x94\\x8c\\x0bdefaultdict\\x94\\x93\\x94\\x8c\\x0chttp.cookies\\x94\\x8c\\x0cSimpleCookie\\x94\\x93\\x94\\x85\\x94R\\x94(\\x8c\\x00\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\rshared-cookie\\x94h\\x03\\x8c\\x06Morsel\\x94\\x93\\x94)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94\\x8c\\x01/\\x94\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\x08\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(\\x8c\\x03key\\x94h\\x0b\\x8c\\x05value\\x94\\x8c\\x05first\\x94\\x8c\\x0bcoded_value\\x94h\\x1cubs\\x8c\\x0bexample.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94(\\x8c\\rdomain-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\x1e\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah!h\\x1b\\x8c\\x06second\\x94h\\x1dh-ub\\x8c\\x14dotted-domain-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94\\x8c\\x0bexample.com\\x94\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah.h\\x1b\\x8c\\x05fifth\\x94h\\x1dh;ubu\\x8c\\x11test1.example.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\x11subdomain1-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h<\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah?h\\x1b\\x8c\\x05third\\x94h\\x1dhKubs\\x8c\\x11test2.example.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\x11subdomain2-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94hL\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ahOh\\x1b\\x8c\\x06fourth\\x94h\\x1dh[ubs\\x8c\\rdifferent.org\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\x17different-domain-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\\\\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah_h\\x1b\\x8c\\x05sixth\\x94h\\x1dhkubs\\x8c\\nsecure.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\rsecure-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94hl\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94\\x88\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ahoh\\x1b\\x8c\\x07seventh\\x94h\\x1dh{ubs\\x8c\\x0cpathtest.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94(\\x8c\\x0eno-path-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h|\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\x7fh\\x1b\\x8c\\x06eighth\\x94h\\x1dh\\x8bub\\x8c\\x0cpath1-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94\\x8c\\x0cpathtest.com\\x94\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\x8ch\\x1b\\x8c\\x05ninth\\x94h\\x1dh\\x99ubu\\x8c\\x0cpathtest.com\\x94\\x8c\\x04/one\\x94\\x86\\x94h\\x05)\\x81\\x94\\x8c\\x0cpath2-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x9b\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\x9a\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\x9eh\\x1b\\x8c\\x05tenth\\x94h\\x1dh\\xaaubs\\x8c\\x0cpathtest.com\\x94\\x8c\\x08/one/two\\x94\\x86\\x94h\\x05)\\x81\\x94(\\x8c\\x0cpath3-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\xac\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\xab\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\xafh\\x1b\\x8c\\x08eleventh\\x94h\\x1dh\\xbbub\\x8c\\x0cpath4-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94\\x8c\\t/one/two/\\x94\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94\\x8c\\x0cpathtest.com\\x94\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\xbch\\x1b\\x8c\\x07twelfth\\x94h\\x1dh\\xcaubu\\x8c\\x0fexpirestest.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\x0eexpires-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94\\x8c\\x1cTue, 1 Jan 2999 12:00:00 GMT\\x94\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\xcb\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\xceh\\x1b\\x8c\\nthirteenth\\x94h\\x1dh\\xdbubs\\x8c\\x0emaxagetest.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\x0emax-age-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\xdc\\x8c\\x07max-age\\x94\\x8c\\x0260\\x94\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\xdfh\\x1b\\x8c\\nfourteenth\\x94h\\x1dh\\xecubs\\x8c\\x12invalid-values.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94(\\x8c\\x16invalid-max-age-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\xed\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\xf0h\\x1b\\x8c\\tfifteenth\\x94h\\x1dh\\xfcub\\x8c\\x16invalid-expires-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94\\x8c\\x12invalid-values.com\\x94\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\xfdh\\x1b\\x8c\\tsixteenth\\x94h\\x1dj\\n\\x01\\x00\\x00ubuu.\"\n    cookies = pickle.loads(pickled)\n\n    cj = CookieJar()\n    cj.update_cookies(cookies_to_send)\n\n    assert cookies == cj._cookies\n\n\n@pytest.mark.parametrize(\n    \"url\",\n    [\n        \"http://127.0.0.1/index.html\",\n        URL(\"http://127.0.0.1/index.html\"),\n        [\"http://127.0.0.1/index.html\"],\n        [URL(\"http://127.0.0.1/index.html\")],\n    ],\n)\nasync def test_treat_as_secure_origin_init(url) -> None:\n    jar = CookieJar(unsafe=True, treat_as_secure_origin=url)\n    assert jar._treat_as_secure_origin == [URL(\"http://127.0.0.1\")]\n\n\nasync def test_treat_as_secure_origin() -> None:\n    endpoint = URL(\"http://127.0.0.1/\")\n\n    jar = CookieJar(unsafe=True, treat_as_secure_origin=[endpoint])\n    secure_cookie = SimpleCookie(\n        \"cookie-key=cookie-value; HttpOnly; Path=/; Secure\",\n    )\n\n    jar.update_cookies(\n        secure_cookie,\n        endpoint,\n    )\n\n    assert len(jar) == 1\n    filtered_cookies = jar.filter_cookies(request_url=endpoint)\n    assert len(filtered_cookies) == 1\n",
            "new_file_content": "# type: ignore\nimport asyncio\nimport datetime\nimport itertools\nimport pathlib\nimport pickle\nimport unittest\nfrom http.cookies import BaseCookie, Morsel, SimpleCookie\nfrom typing import Any\nfrom unittest import mock\n\nimport pytest\nfrom freezegun import freeze_time\nfrom yarl import URL\n\nfrom aiohttp import CookieJar, DummyCookieJar\n\n\ndef dump_cookiejar() -> bytes:  # pragma: no cover\n    \"\"\"Create pickled data for test_pickle_format().\"\"\"\n    cj = CookieJar()\n    cj.update_cookies(cookies_to_send.__pytest_wrapped__.obj())\n    return pickle.dumps(cj._cookies, pickle.HIGHEST_PROTOCOL)\n\n\n@pytest.fixture\ndef cookies_to_send():\n    return SimpleCookie(\n        \"shared-cookie=first; \"\n        \"domain-cookie=second; Domain=example.com; \"\n        \"subdomain1-cookie=third; Domain=test1.example.com; \"\n        \"subdomain2-cookie=fourth; Domain=test2.example.com; \"\n        \"dotted-domain-cookie=fifth; Domain=.example.com; \"\n        \"different-domain-cookie=sixth; Domain=different.org; \"\n        \"secure-cookie=seventh; Domain=secure.com; Secure; \"\n        \"no-path-cookie=eighth; Domain=pathtest.com; \"\n        \"path1-cookie=ninth; Domain=pathtest.com; Path=/; \"\n        \"path2-cookie=tenth; Domain=pathtest.com; Path=/one; \"\n        \"path3-cookie=eleventh; Domain=pathtest.com; Path=/one/two; \"\n        \"path4-cookie=twelfth; Domain=pathtest.com; Path=/one/two/; \"\n        \"expires-cookie=thirteenth; Domain=expirestest.com; Path=/;\"\n        \" Expires=Tue, 1 Jan 2999 12:00:00 GMT; \"\n        \"max-age-cookie=fourteenth; Domain=maxagetest.com; Path=/;\"\n        \" Max-Age=60; \"\n        \"invalid-max-age-cookie=fifteenth; Domain=invalid-values.com; \"\n        \" Max-Age=string; \"\n        \"invalid-expires-cookie=sixteenth; Domain=invalid-values.com; \"\n        \" Expires=string;\"\n    )\n\n\n@pytest.fixture\ndef cookies_to_send_with_expired():\n    return SimpleCookie(\n        \"shared-cookie=first; \"\n        \"domain-cookie=second; Domain=example.com; \"\n        \"subdomain1-cookie=third; Domain=test1.example.com; \"\n        \"subdomain2-cookie=fourth; Domain=test2.example.com; \"\n        \"dotted-domain-cookie=fifth; Domain=.example.com; \"\n        \"different-domain-cookie=sixth; Domain=different.org; \"\n        \"secure-cookie=seventh; Domain=secure.com; Secure; \"\n        \"no-path-cookie=eighth; Domain=pathtest.com; \"\n        \"path1-cookie=ninth; Domain=pathtest.com; Path=/; \"\n        \"path2-cookie=tenth; Domain=pathtest.com; Path=/one; \"\n        \"path3-cookie=eleventh; Domain=pathtest.com; Path=/one/two; \"\n        \"path4-cookie=twelfth; Domain=pathtest.com; Path=/one/two/; \"\n        \"expires-cookie=thirteenth; Domain=expirestest.com; Path=/;\"\n        \" Expires=Tue, 1 Jan 1980 12:00:00 GMT; \"\n        \"max-age-cookie=fourteenth; Domain=maxagetest.com; Path=/;\"\n        \" Max-Age=60; \"\n        \"invalid-max-age-cookie=fifteenth; Domain=invalid-values.com; \"\n        \" Max-Age=string; \"\n        \"invalid-expires-cookie=sixteenth; Domain=invalid-values.com; \"\n        \" Expires=string;\"\n    )\n\n\n@pytest.fixture\ndef cookies_to_receive():\n    return SimpleCookie(\n        \"unconstrained-cookie=first; Path=/; \"\n        \"domain-cookie=second; Domain=example.com; Path=/; \"\n        \"subdomain1-cookie=third; Domain=test1.example.com; Path=/; \"\n        \"subdomain2-cookie=fourth; Domain=test2.example.com; Path=/; \"\n        \"dotted-domain-cookie=fifth; Domain=.example.com; Path=/; \"\n        \"different-domain-cookie=sixth; Domain=different.org; Path=/; \"\n        \"no-path-cookie=seventh; Domain=pathtest.com; \"\n        \"path-cookie=eighth; Domain=pathtest.com; Path=/somepath; \"\n        \"wrong-path-cookie=ninth; Domain=pathtest.com; Path=somepath;\"\n    )\n\n\ndef test_date_parsing() -> None:\n    parse_func = CookieJar._parse_date\n    utc = datetime.timezone.utc\n\n    assert parse_func(\"\") is None\n\n    # 70 -> 1970\n    assert (\n        parse_func(\"Tue, 1 Jan 70 00:00:00 GMT\")\n        == datetime.datetime(1970, 1, 1, tzinfo=utc).timestamp()\n    )\n\n    # 10 -> 2010\n    assert (\n        parse_func(\"Tue, 1 Jan 10 00:00:00 GMT\")\n        == datetime.datetime(2010, 1, 1, tzinfo=utc).timestamp()\n    )\n\n    # No day of week string\n    assert (\n        parse_func(\"1 Jan 1970 00:00:00 GMT\")\n        == datetime.datetime(1970, 1, 1, tzinfo=utc).timestamp()\n    )\n\n    # No timezone string\n    assert (\n        parse_func(\"Tue, 1 Jan 1970 00:00:00\")\n        == datetime.datetime(1970, 1, 1, tzinfo=utc).timestamp()\n    )\n\n    # No year\n    assert parse_func(\"Tue, 1 Jan 00:00:00 GMT\") is None\n\n    # No month\n    assert parse_func(\"Tue, 1 1970 00:00:00 GMT\") is None\n\n    # No day of month\n    assert parse_func(\"Tue, Jan 1970 00:00:00 GMT\") is None\n\n    # No time\n    assert parse_func(\"Tue, 1 Jan 1970 GMT\") is None\n\n    # Invalid day of month\n    assert parse_func(\"Tue, 0 Jan 1970 00:00:00 GMT\") is None\n\n    # Invalid year\n    assert parse_func(\"Tue, 1 Jan 1500 00:00:00 GMT\") is None\n\n    # Invalid time\n    assert parse_func(\"Tue, 1 Jan 1970 77:88:99 GMT\") is None\n\n\ndef test_domain_matching() -> None:\n    test_func = CookieJar._is_domain_match\n\n    assert test_func(\"test.com\", \"test.com\")\n    assert test_func(\"test.com\", \"sub.test.com\")\n\n    assert not test_func(\"test.com\", \"\")\n    assert not test_func(\"test.com\", \"test.org\")\n    assert not test_func(\"diff-test.com\", \"test.com\")\n    assert not test_func(\"test.com\", \"diff-test.com\")\n    assert not test_func(\"test.com\", \"127.0.0.1\")\n\n\nasync def test_constructor(cookies_to_send: Any, cookies_to_receive: Any) -> None:\n    jar = CookieJar()\n    jar.update_cookies(cookies_to_send)\n    jar_cookies = SimpleCookie()\n    for cookie in jar:\n        dict.__setitem__(jar_cookies, cookie.key, cookie)\n    expected_cookies = cookies_to_send\n    assert jar_cookies == expected_cookies\n\n\nasync def test_constructor_with_expired(\n    cookies_to_send_with_expired: Any, cookies_to_receive: Any\n) -> None:\n    jar = CookieJar()\n    jar.update_cookies(cookies_to_send_with_expired)\n    jar_cookies = SimpleCookie()\n    for cookie in jar:\n        dict.__setitem__(jar_cookies, cookie.key, cookie)\n    expected_cookies = cookies_to_send_with_expired\n    assert jar_cookies != expected_cookies\n\n\nasync def test_save_load(\n    tmp_path: Any, loop: Any, cookies_to_send: Any, cookies_to_receive: Any\n) -> None:\n    file_path = pathlib.Path(str(tmp_path)) / \"aiohttp.test.cookie\"\n\n    # export cookie jar\n    jar_save = CookieJar()\n    jar_save.update_cookies(cookies_to_receive)\n    jar_save.save(file_path=file_path)\n\n    jar_load = CookieJar()\n    jar_load.load(file_path=file_path)\n\n    jar_test = SimpleCookie()\n    for cookie in jar_load:\n        jar_test[cookie.key] = cookie\n\n    assert jar_test == cookies_to_receive\n\n\nasync def test_update_cookie_with_unicode_domain(loop: Any) -> None:\n    cookies = (\n        \"idna-domain-first=first; Domain=xn--9caa.com; Path=/;\",\n        \"idna-domain-second=second; Domain=xn--9caa.com; Path=/;\",\n    )\n\n    jar = CookieJar()\n    jar.update_cookies(SimpleCookie(cookies[0]), URL(\"http://éé.com/\"))\n    jar.update_cookies(SimpleCookie(cookies[1]), URL(\"http://xn--9caa.com/\"))\n\n    jar_test = SimpleCookie()\n    for cookie in jar:\n        jar_test[cookie.key] = cookie\n\n    assert jar_test == SimpleCookie(\" \".join(cookies))\n\n\nasync def test_filter_cookie_with_unicode_domain(loop: Any) -> None:\n    jar = CookieJar()\n    jar.update_cookies(\n        SimpleCookie(\"idna-domain-first=first; Domain=xn--9caa.com; Path=/; \")\n    )\n    assert len(jar.filter_cookies(URL(\"http://éé.com\"))) == 1\n    assert len(jar.filter_cookies(URL(\"http://xn--9caa.com\"))) == 1\n\n\nasync def test_filter_cookies_str_deprecated(loop: Any) -> None:\n    jar = CookieJar()\n    with pytest.deprecated_call(\n        match=\"The method accepts yarl.URL instances only, got <class 'str'>\",\n    ):\n        jar.filter_cookies(\"http://éé.com\")\n\n\n@pytest.mark.parametrize(\n    (\"url\", \"expected_cookies\"),\n    (\n        (\n            \"http://pathtest.com/one/two/\",\n            (\n                \"no-path-cookie\",\n                \"path1-cookie\",\n                \"path2-cookie\",\n                \"shared-cookie\",\n                \"path3-cookie\",\n                \"path4-cookie\",\n            ),\n        ),\n        (\n            \"http://pathtest.com/one/two\",\n            (\n                \"no-path-cookie\",\n                \"path1-cookie\",\n                \"path2-cookie\",\n                \"shared-cookie\",\n                \"path3-cookie\",\n            ),\n        ),\n        (\n            \"http://pathtest.com/one/two/three/\",\n            (\n                \"no-path-cookie\",\n                \"path1-cookie\",\n                \"path2-cookie\",\n                \"shared-cookie\",\n                \"path3-cookie\",\n                \"path4-cookie\",\n            ),\n        ),\n        (\n            \"http://test1.example.com/\",\n            (\n                \"shared-cookie\",\n                \"domain-cookie\",\n                \"subdomain1-cookie\",\n                \"dotted-domain-cookie\",\n            ),\n        ),\n        (\n            \"http://pathtest.com/\",\n            (\n                \"shared-cookie\",\n                \"no-path-cookie\",\n                \"path1-cookie\",\n            ),\n        ),\n    ),\n)\nasync def test_filter_cookies_with_domain_path_lookup_multilevelpath(\n    loop: Any,\n    url: Any,\n    expected_cookies: Any,\n) -> None:\n    jar = CookieJar()\n    cookies = SimpleCookie(\n        \"shared-cookie=first; \"\n        \"domain-cookie=second; Domain=example.com; \"\n        \"subdomain1-cookie=third; Domain=test1.example.com; \"\n        \"subdomain2-cookie=fourth; Domain=test2.example.com; \"\n        \"dotted-domain-cookie=fifth; Domain=.example.com; \"\n        \"different-domain-cookie=sixth; Domain=different.org; \"\n        \"secure-cookie=seventh; Domain=secure.com; Secure; \"\n        \"no-path-cookie=eighth; Domain=pathtest.com; \"\n        \"path1-cookie=ninth; Domain=pathtest.com; Path=/; \"\n        \"path2-cookie=tenth; Domain=pathtest.com; Path=/one; \"\n        \"path3-cookie=eleventh; Domain=pathtest.com; Path=/one/two; \"\n        \"path4-cookie=twelfth; Domain=pathtest.com; Path=/one/two/; \"\n        \"expires-cookie=thirteenth; Domain=expirestest.com; Path=/;\"\n        \" Expires=Tue, 1 Jan 1980 12:00:00 GMT; \"\n        \"max-age-cookie=fourteenth; Domain=maxagetest.com; Path=/;\"\n        \" Max-Age=60; \"\n        \"invalid-max-age-cookie=fifteenth; Domain=invalid-values.com; \"\n        \" Max-Age=string; \"\n        \"invalid-expires-cookie=sixteenth; Domain=invalid-values.com; \"\n        \" Expires=string;\"\n    )\n    jar.update_cookies(cookies)\n    cookies = jar.filter_cookies(URL(url))\n\n    assert len(cookies) == len(expected_cookies)\n    for c in cookies:\n        assert c in expected_cookies\n\n\nasync def test_domain_filter_ip_cookie_send(loop: Any) -> None:\n    jar = CookieJar()\n    cookies = SimpleCookie(\n        \"shared-cookie=first; \"\n        \"domain-cookie=second; Domain=example.com; \"\n        \"subdomain1-cookie=third; Domain=test1.example.com; \"\n        \"subdomain2-cookie=fourth; Domain=test2.example.com; \"\n        \"dotted-domain-cookie=fifth; Domain=.example.com; \"\n        \"different-domain-cookie=sixth; Domain=different.org; \"\n        \"secure-cookie=seventh; Domain=secure.com; Secure; \"\n        \"no-path-cookie=eighth; Domain=pathtest.com; \"\n        \"path1-cookie=ninth; Domain=pathtest.com; Path=/; \"\n        \"path2-cookie=tenth; Domain=pathtest.com; Path=/one; \"\n        \"path3-cookie=eleventh; Domain=pathtest.com; Path=/one/two; \"\n        \"path4-cookie=twelfth; Domain=pathtest.com; Path=/one/two/; \"\n        \"expires-cookie=thirteenth; Domain=expirestest.com; Path=/;\"\n        \" Expires=Tue, 1 Jan 1980 12:00:00 GMT; \"\n        \"max-age-cookie=fourteenth; Domain=maxagetest.com; Path=/;\"\n        \" Max-Age=60; \"\n        \"invalid-max-age-cookie=fifteenth; Domain=invalid-values.com; \"\n        \" Max-Age=string; \"\n        \"invalid-expires-cookie=sixteenth; Domain=invalid-values.com; \"\n        \" Expires=string;\"\n    )\n\n    jar.update_cookies(cookies)\n    cookies_sent = jar.filter_cookies(URL(\"http://1.2.3.4/\")).output(header=\"Cookie:\")\n    assert cookies_sent == \"Cookie: shared-cookie=first\"\n\n\nasync def test_domain_filter_ip_cookie_receive(cookies_to_receive: Any) -> None:\n    jar = CookieJar()\n\n    jar.update_cookies(cookies_to_receive, URL(\"http://1.2.3.4/\"))\n    assert len(jar) == 0\n\n\n@pytest.mark.parametrize(\n    (\"cookies\", \"expected\", \"quote_bool\"),\n    [\n        (\n            \"shared-cookie=first; ip-cookie=second; Domain=127.0.0.1;\",\n            \"Cookie: ip-cookie=second\\r\\nCookie: shared-cookie=first\",\n            True,\n        ),\n        ('ip-cookie=\"second\"; Domain=127.0.0.1;', 'Cookie: ip-cookie=\"second\"', True),\n        (\"custom-cookie=value/one;\", 'Cookie: custom-cookie=\"value/one\"', True),\n        (\"custom-cookie=value1;\", \"Cookie: custom-cookie=value1\", True),\n        (\"custom-cookie=value/one;\", \"Cookie: custom-cookie=value/one\", False),\n    ],\n    ids=(\n        \"IP domain preserved\",\n        \"no shared cookie\",\n        \"quoted cookie with special char\",\n        \"quoted cookie w/o special char\",\n        \"unquoted cookie with special char\",\n    ),\n)\nasync def test_quotes_correctly_based_on_input(\n    loop: Any, cookies: Any, expected: Any, quote_bool: Any\n) -> None:\n    jar = CookieJar(unsafe=True, quote_cookie=quote_bool)\n    jar.update_cookies(SimpleCookie(cookies))\n    cookies_sent = jar.filter_cookies(URL(\"http://127.0.0.1/\")).output(header=\"Cookie:\")\n    assert cookies_sent == expected\n\n\nasync def test_ignore_domain_ending_with_dot(loop: Any) -> None:\n    jar = CookieJar(unsafe=True)\n    jar.update_cookies(\n        SimpleCookie(\"cookie=val; Domain=example.com.;\"), URL(\"http://www.example.com\")\n    )\n    cookies_sent = jar.filter_cookies(URL(\"http://www.example.com/\"))\n    assert cookies_sent.output(header=\"Cookie:\") == \"Cookie: cookie=val\"\n    cookies_sent = jar.filter_cookies(URL(\"http://example.com/\"))\n    assert cookies_sent.output(header=\"Cookie:\") == \"\"\n\n\nclass TestCookieJarBase(unittest.TestCase):\n    loop: Any\n    jar: Any\n\n    def setUp(self):\n        self.loop = asyncio.new_event_loop()\n        asyncio.set_event_loop(None)\n\n        # N.B. those need to be overridden in child test cases\n        async def make_jar():\n            return CookieJar()\n\n        self.jar = self.loop.run_until_complete(make_jar())\n\n    def tearDown(self) -> None:\n        self.loop.close()\n\n    def request_reply_with_same_url(self, url: Any):\n        self.jar.update_cookies(self.cookies_to_send)\n        cookies_sent = self.jar.filter_cookies(URL(url))\n\n        self.jar.clear()\n\n        self.jar.update_cookies(self.cookies_to_receive, URL(url))\n        cookies_received = SimpleCookie()\n        for cookie in self.jar:\n            dict.__setitem__(cookies_received, cookie.key, cookie)\n\n        self.jar.clear()\n\n        return cookies_sent, cookies_received\n\n\nclass TestCookieJarSafe(TestCookieJarBase):\n    cookies_to_send: Any\n    cookies_to_receive: Any\n    jar: Any\n\n    def setUp(self):\n        super().setUp()\n\n        self.cookies_to_send = SimpleCookie(\n            \"shared-cookie=first; \"\n            \"domain-cookie=second; Domain=example.com; \"\n            \"subdomain1-cookie=third; Domain=test1.example.com; \"\n            \"subdomain2-cookie=fourth; Domain=test2.example.com; \"\n            \"dotted-domain-cookie=fifth; Domain=.example.com; \"\n            \"different-domain-cookie=sixth; Domain=different.org; \"\n            \"secure-cookie=seventh; Domain=secure.com; Secure; \"\n            \"no-path-cookie=eighth; Domain=pathtest.com; \"\n            \"path1-cookie=ninth; Domain=pathtest.com; Path=/; \"\n            \"path2-cookie=tenth; Domain=pathtest.com; Path=/one; \"\n            \"path3-cookie=eleventh; Domain=pathtest.com; Path=/one/two; \"\n            \"path4-cookie=twelfth; Domain=pathtest.com; Path=/one/two/; \"\n            \"expires-cookie=thirteenth; Domain=expirestest.com; Path=/;\"\n            \" Expires=Tue, 1 Jan 1980 12:00:00 GMT; \"\n            \"max-age-cookie=fourteenth; Domain=maxagetest.com; Path=/;\"\n            \" Max-Age=60; \"\n            \"invalid-max-age-cookie=fifteenth; Domain=invalid-values.com; \"\n            \" Max-Age=string; \"\n            \"invalid-expires-cookie=sixteenth; Domain=invalid-values.com; \"\n            \" Expires=string;\"\n        )\n\n        self.cookies_to_receive = SimpleCookie(\n            \"unconstrained-cookie=first; Path=/; \"\n            \"domain-cookie=second; Domain=example.com; Path=/; \"\n            \"subdomain1-cookie=third; Domain=test1.example.com; Path=/; \"\n            \"subdomain2-cookie=fourth; Domain=test2.example.com; Path=/; \"\n            \"dotted-domain-cookie=fifth; Domain=.example.com; Path=/; \"\n            \"different-domain-cookie=sixth; Domain=different.org; Path=/; \"\n            \"no-path-cookie=seventh; Domain=pathtest.com; \"\n            \"path-cookie=eighth; Domain=pathtest.com; Path=/somepath; \"\n            \"wrong-path-cookie=ninth; Domain=pathtest.com; Path=somepath;\"\n        )\n\n        async def make_jar():\n            return CookieJar()\n\n        self.jar = self.loop.run_until_complete(make_jar())\n\n    def timed_request(self, url: Any, update_time: Any, send_time: Any):\n        if isinstance(update_time, int):\n            update_time = datetime.timedelta(seconds=update_time)\n        elif isinstance(update_time, float):\n            update_time = datetime.datetime.fromtimestamp(update_time)\n        if isinstance(send_time, int):\n            send_time = datetime.timedelta(seconds=send_time)\n        elif isinstance(send_time, float):\n            send_time = datetime.datetime.fromtimestamp(send_time)\n\n        with freeze_time(update_time):\n            self.jar.update_cookies(self.cookies_to_send)\n\n        with freeze_time(send_time):\n            cookies_sent = self.jar.filter_cookies(URL(url))\n\n        self.jar.clear()\n\n        return cookies_sent\n\n    def test_domain_filter_same_host(self) -> None:\n        cookies_sent, cookies_received = self.request_reply_with_same_url(\n            \"http://example.com/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\"shared-cookie\", \"domain-cookie\", \"dotted-domain-cookie\"},\n        )\n\n        self.assertEqual(\n            set(cookies_received.keys()),\n            {\"unconstrained-cookie\", \"domain-cookie\", \"dotted-domain-cookie\"},\n        )\n\n    def test_domain_filter_same_host_and_subdomain(self) -> None:\n        cookies_sent, cookies_received = self.request_reply_with_same_url(\n            \"http://test1.example.com/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\n                \"shared-cookie\",\n                \"domain-cookie\",\n                \"subdomain1-cookie\",\n                \"dotted-domain-cookie\",\n            },\n        )\n\n        self.assertEqual(\n            set(cookies_received.keys()),\n            {\n                \"unconstrained-cookie\",\n                \"domain-cookie\",\n                \"subdomain1-cookie\",\n                \"dotted-domain-cookie\",\n            },\n        )\n\n    def test_domain_filter_same_host_diff_subdomain(self) -> None:\n        cookies_sent, cookies_received = self.request_reply_with_same_url(\n            \"http://different.example.com/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\"shared-cookie\", \"domain-cookie\", \"dotted-domain-cookie\"},\n        )\n\n        self.assertEqual(\n            set(cookies_received.keys()),\n            {\"unconstrained-cookie\", \"domain-cookie\", \"dotted-domain-cookie\"},\n        )\n\n    def test_domain_filter_diff_host(self) -> None:\n        cookies_sent, cookies_received = self.request_reply_with_same_url(\n            \"http://different.org/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()), {\"shared-cookie\", \"different-domain-cookie\"}\n        )\n\n        self.assertEqual(\n            set(cookies_received.keys()),\n            {\"unconstrained-cookie\", \"different-domain-cookie\"},\n        )\n\n    def test_domain_filter_host_only(self) -> None:\n        self.jar.update_cookies(self.cookies_to_receive, URL(\"http://example.com/\"))\n        sub_cookie = SimpleCookie(\"subdomain=spam; Path=/;\")\n        self.jar.update_cookies(sub_cookie, URL(\"http://foo.example.com/\"))\n\n        cookies_sent = self.jar.filter_cookies(URL(\"http://foo.example.com/\"))\n        self.assertIn(\"subdomain\", set(cookies_sent.keys()))\n        self.assertNotIn(\"unconstrained-cookie\", set(cookies_sent.keys()))\n\n    def test_secure_filter(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\"http://secure.com/\")\n\n        self.assertEqual(set(cookies_sent.keys()), {\"shared-cookie\"})\n\n        cookies_sent, _ = self.request_reply_with_same_url(\"https://secure.com/\")\n\n        self.assertEqual(set(cookies_sent.keys()), {\"shared-cookie\", \"secure-cookie\"})\n\n    def test_path_filter_root(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\"http://pathtest.com/\")\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\"shared-cookie\", \"no-path-cookie\", \"path1-cookie\"},\n        )\n\n    def test_path_filter_folder(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\"http://pathtest.com/one/\")\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\"shared-cookie\", \"no-path-cookie\", \"path1-cookie\", \"path2-cookie\"},\n        )\n\n    def test_path_filter_file(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\n            \"http://pathtest.com/one/two\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\n                \"shared-cookie\",\n                \"no-path-cookie\",\n                \"path1-cookie\",\n                \"path2-cookie\",\n                \"path3-cookie\",\n            },\n        )\n\n    def test_path_filter_subfolder(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\n            \"http://pathtest.com/one/two/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\n                \"shared-cookie\",\n                \"no-path-cookie\",\n                \"path1-cookie\",\n                \"path2-cookie\",\n                \"path3-cookie\",\n                \"path4-cookie\",\n            },\n        )\n\n    def test_path_filter_subsubfolder(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\n            \"http://pathtest.com/one/two/three/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\n                \"shared-cookie\",\n                \"no-path-cookie\",\n                \"path1-cookie\",\n                \"path2-cookie\",\n                \"path3-cookie\",\n                \"path4-cookie\",\n            },\n        )\n\n    def test_path_filter_different_folder(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\n            \"http://pathtest.com/hundred/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\"shared-cookie\", \"no-path-cookie\", \"path1-cookie\"},\n        )\n\n    def test_path_value(self) -> None:\n        _, cookies_received = self.request_reply_with_same_url(\"http://pathtest.com/\")\n\n        self.assertEqual(\n            set(cookies_received.keys()),\n            {\n                \"unconstrained-cookie\",\n                \"no-path-cookie\",\n                \"path-cookie\",\n                \"wrong-path-cookie\",\n            },\n        )\n\n        self.assertEqual(cookies_received[\"no-path-cookie\"][\"path\"], \"/\")\n        self.assertEqual(cookies_received[\"path-cookie\"][\"path\"], \"/somepath\")\n        self.assertEqual(cookies_received[\"wrong-path-cookie\"][\"path\"], \"/\")\n\n    def test_expires(self) -> None:\n        ts_before = datetime.datetime(\n            1975, 1, 1, tzinfo=datetime.timezone.utc\n        ).timestamp()\n\n        ts_after = datetime.datetime(\n            2030, 1, 1, tzinfo=datetime.timezone.utc\n        ).timestamp()\n\n        cookies_sent = self.timed_request(\n            \"http://expirestest.com/\", ts_before, ts_before\n        )\n\n        self.assertEqual(set(cookies_sent.keys()), {\"shared-cookie\", \"expires-cookie\"})\n\n        cookies_sent = self.timed_request(\n            \"http://expirestest.com/\", ts_before, ts_after\n        )\n\n        self.assertEqual(set(cookies_sent.keys()), {\"shared-cookie\"})\n\n    def test_max_age(self) -> None:\n        cookies_sent = self.timed_request(\"http://maxagetest.com/\", 1000, 1000)\n\n        self.assertEqual(set(cookies_sent.keys()), {\"shared-cookie\", \"max-age-cookie\"})\n\n        cookies_sent = self.timed_request(\"http://maxagetest.com/\", 1000, 2000)\n\n        self.assertEqual(set(cookies_sent.keys()), {\"shared-cookie\"})\n\n    def test_invalid_values(self) -> None:\n        cookies_sent, cookies_received = self.request_reply_with_same_url(\n            \"http://invalid-values.com/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\"shared-cookie\", \"invalid-max-age-cookie\", \"invalid-expires-cookie\"},\n        )\n\n        cookie = cookies_sent[\"invalid-max-age-cookie\"]\n        self.assertEqual(cookie[\"max-age\"], \"\")\n\n        cookie = cookies_sent[\"invalid-expires-cookie\"]\n        self.assertEqual(cookie[\"expires\"], \"\")\n\n    def test_cookie_not_expired_when_added_after_removal(self) -> None:\n        # Test case for https://github.com/aio-libs/aiohttp/issues/2084\n        timestamps = [\n            533588.993,\n            533588.993,\n            533588.993,\n            533588.993,\n            533589.093,\n            533589.093,\n        ]\n\n        loop = mock.Mock()\n        loop.time.side_effect = itertools.chain(\n            timestamps, itertools.cycle([timestamps[-1]])\n        )\n\n        async def make_jar():\n            return CookieJar(unsafe=True)\n\n        jar = self.loop.run_until_complete(make_jar())\n        # Remove `foo` cookie.\n        jar.update_cookies(SimpleCookie('foo=\"\"; Max-Age=0'))\n        # Set `foo` cookie to `bar`.\n        jar.update_cookies(SimpleCookie('foo=\"bar\"'))\n\n        # Assert that there is a cookie.\n        assert len(jar) == 1\n\n    def test_path_filter_diff_folder_same_name(self) -> None:\n        async def make_jar():\n            return CookieJar(unsafe=True)\n\n        jar = self.loop.run_until_complete(make_jar())\n\n        jar.update_cookies(\n            SimpleCookie(\"path-cookie=zero; Domain=pathtest.com; Path=/; \")\n        )\n        jar.update_cookies(\n            SimpleCookie(\"path-cookie=one; Domain=pathtest.com; Path=/one; \")\n        )\n        self.assertEqual(len(jar), 2)\n\n        jar_filtered = jar.filter_cookies(URL(\"http://pathtest.com/\"))\n        self.assertEqual(len(jar_filtered), 1)\n        self.assertEqual(jar_filtered[\"path-cookie\"].value, \"zero\")\n\n        jar_filtered = jar.filter_cookies(URL(\"http://pathtest.com/one\"))\n        self.assertEqual(len(jar_filtered), 1)\n        self.assertEqual(jar_filtered[\"path-cookie\"].value, \"one\")\n\n    def test_path_filter_diff_folder_same_name_return_best_match_independent_from_put_order(\n        self,\n    ) -> None:\n        async def make_jar():\n            return CookieJar(unsafe=True)\n\n        jar = self.loop.run_until_complete(make_jar())\n        jar.update_cookies(\n            SimpleCookie(\"path-cookie=one; Domain=pathtest.com; Path=/one; \")\n        )\n        jar.update_cookies(\n            SimpleCookie(\"path-cookie=zero; Domain=pathtest.com; Path=/; \")\n        )\n        jar.update_cookies(\n            SimpleCookie(\"path-cookie=two; Domain=pathtest.com; Path=/second; \")\n        )\n        self.assertEqual(len(jar), 3)\n\n        jar_filtered = jar.filter_cookies(URL(\"http://pathtest.com/\"))\n        self.assertEqual(len(jar_filtered), 1)\n        self.assertEqual(jar_filtered[\"path-cookie\"].value, \"zero\")\n\n        jar_filtered = jar.filter_cookies(URL(\"http://pathtest.com/second\"))\n        self.assertEqual(len(jar_filtered), 1)\n        self.assertEqual(jar_filtered[\"path-cookie\"].value, \"two\")\n\n        jar_filtered = jar.filter_cookies(URL(\"http://pathtest.com/one\"))\n        self.assertEqual(len(jar_filtered), 1)\n        self.assertEqual(jar_filtered[\"path-cookie\"].value, \"one\")\n\n\nasync def test_dummy_cookie_jar() -> None:\n    cookie = SimpleCookie(\"foo=bar; Domain=example.com;\")\n    dummy_jar = DummyCookieJar()\n    assert len(dummy_jar) == 0\n    dummy_jar.update_cookies(cookie)\n    assert len(dummy_jar) == 0\n    with pytest.raises(StopIteration):\n        next(iter(dummy_jar))\n    assert not dummy_jar.filter_cookies(URL(\"http://example.com/\"))\n    dummy_jar.clear()\n\n\nasync def test_loose_cookies_types() -> None:\n    jar = CookieJar()\n\n    accepted_types = [\n        [(\"str\", BaseCookie())],\n        [(\"str\", Morsel())],\n        [\n            (\"str\", \"str\"),\n        ],\n        {\"str\": BaseCookie()},\n        {\"str\": Morsel()},\n        {\"str\": \"str\"},\n        SimpleCookie(),\n    ]\n\n    for loose_cookies_type in accepted_types:\n        jar.update_cookies(cookies=loose_cookies_type)\n\n\nasync def test_cookie_jar_clear_all() -> None:\n    sut = CookieJar()\n    cookie = SimpleCookie()\n    cookie[\"foo\"] = \"bar\"\n    sut.update_cookies(cookie)\n\n    sut.clear()\n    assert len(sut) == 0\n\n\nasync def test_cookie_jar_clear_expired():\n    sut = CookieJar()\n\n    cookie = SimpleCookie()\n\n    cookie[\"foo\"] = \"bar\"\n    cookie[\"foo\"][\"expires\"] = \"Tue, 1 Jan 1990 12:00:00 GMT\"\n\n    with freeze_time(\"1980-01-01\"):\n        sut.update_cookies(cookie)\n\n    sut.clear(lambda x: False)\n    with freeze_time(\"1980-01-01\"):\n        assert len(sut) == 0\n\n\nasync def test_cookie_jar_filter_cookies_expires():\n    \"\"\"Test that calling filter_cookies will expire stale cookies.\"\"\"\n    jar = CookieJar()\n    assert len(jar) == 0\n\n    cookie = SimpleCookie()\n\n    cookie[\"foo\"] = \"bar\"\n    cookie[\"foo\"][\"expires\"] = \"Tue, 1 Jan 1990 12:00:00 GMT\"\n\n    with freeze_time(\"1980-01-01\"):\n        jar.update_cookies(cookie)\n\n    assert len(jar) == 1\n\n    # filter_cookies should expire stale cookies\n    jar.filter_cookies(URL(\"http://any.com/\"))\n\n    assert len(jar) == 0\n\n\nasync def test_cookie_jar_clear_domain() -> None:\n    sut = CookieJar()\n    cookie = SimpleCookie()\n    cookie[\"foo\"] = \"bar\"\n    cookie[\"domain_cookie\"] = \"value\"\n    cookie[\"domain_cookie\"][\"domain\"] = \"example.com\"\n    cookie[\"subdomain_cookie\"] = \"value\"\n    cookie[\"subdomain_cookie\"][\"domain\"] = \"test.example.com\"\n    sut.update_cookies(cookie)\n\n    sut.clear_domain(\"example.com\")\n    iterator = iter(sut)\n    morsel = next(iterator)\n    assert morsel.key == \"foo\"\n    assert morsel.value == \"bar\"\n    with pytest.raises(StopIteration):\n        next(iterator)\n\n\ndef test_pickle_format(cookies_to_send) -> None:\n    \"\"\"Test if cookiejar pickle format breaks.\n\n    If this test fails, it may indicate that saved cookiejars will stop working.\n    If that happens then:\n        1. Avoid releasing the change in a bugfix release.\n        2. Try to include a migration script in the release notes (example below).\n        3. Use dump_cookiejar() at the top of this file to update `pickled`.\n\n    Depending on the changes made, a migration script might look like:\n        import pickle\n        with file_path.open(\"rb\") as f:\n            cookies = pickle.load(f)\n\n        morsels = [(name, m) for c in cookies.values() for name, m in c.items()]\n        cookies.clear()\n        for name, m in morsels:\n            cookies[(m[\"domain\"], m[\"path\"])][name] = m\n\n        with file_path.open(\"wb\") as f:\n            pickle.dump(cookies, f, pickle.HIGHEST_PROTOCOL)\n    \"\"\"\n    pickled = b\"\\x80\\x04\\x95\\xc8\\x0b\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x0bcollections\\x94\\x8c\\x0bdefaultdict\\x94\\x93\\x94\\x8c\\x0chttp.cookies\\x94\\x8c\\x0cSimpleCookie\\x94\\x93\\x94\\x85\\x94R\\x94(\\x8c\\x00\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\rshared-cookie\\x94h\\x03\\x8c\\x06Morsel\\x94\\x93\\x94)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94\\x8c\\x01/\\x94\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\x08\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(\\x8c\\x03key\\x94h\\x0b\\x8c\\x05value\\x94\\x8c\\x05first\\x94\\x8c\\x0bcoded_value\\x94h\\x1cubs\\x8c\\x0bexample.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94(\\x8c\\rdomain-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\x1e\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah!h\\x1b\\x8c\\x06second\\x94h\\x1dh-ub\\x8c\\x14dotted-domain-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94\\x8c\\x0bexample.com\\x94\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah.h\\x1b\\x8c\\x05fifth\\x94h\\x1dh;ubu\\x8c\\x11test1.example.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\x11subdomain1-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h<\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah?h\\x1b\\x8c\\x05third\\x94h\\x1dhKubs\\x8c\\x11test2.example.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\x11subdomain2-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94hL\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ahOh\\x1b\\x8c\\x06fourth\\x94h\\x1dh[ubs\\x8c\\rdifferent.org\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\x17different-domain-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\\\\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah_h\\x1b\\x8c\\x05sixth\\x94h\\x1dhkubs\\x8c\\nsecure.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\rsecure-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94hl\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94\\x88\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ahoh\\x1b\\x8c\\x07seventh\\x94h\\x1dh{ubs\\x8c\\x0cpathtest.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94(\\x8c\\x0eno-path-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h|\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\x7fh\\x1b\\x8c\\x06eighth\\x94h\\x1dh\\x8bub\\x8c\\x0cpath1-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94\\x8c\\x0cpathtest.com\\x94\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\x8ch\\x1b\\x8c\\x05ninth\\x94h\\x1dh\\x99ubu\\x8c\\x0cpathtest.com\\x94\\x8c\\x04/one\\x94\\x86\\x94h\\x05)\\x81\\x94\\x8c\\x0cpath2-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x9b\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\x9a\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\x9eh\\x1b\\x8c\\x05tenth\\x94h\\x1dh\\xaaubs\\x8c\\x0cpathtest.com\\x94\\x8c\\x08/one/two\\x94\\x86\\x94h\\x05)\\x81\\x94(\\x8c\\x0cpath3-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\xac\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\xab\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\xafh\\x1b\\x8c\\x08eleventh\\x94h\\x1dh\\xbbub\\x8c\\x0cpath4-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94\\x8c\\t/one/two/\\x94\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94\\x8c\\x0cpathtest.com\\x94\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\xbch\\x1b\\x8c\\x07twelfth\\x94h\\x1dh\\xcaubu\\x8c\\x0fexpirestest.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\x0eexpires-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94\\x8c\\x1cTue, 1 Jan 2999 12:00:00 GMT\\x94\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\xcb\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\xceh\\x1b\\x8c\\nthirteenth\\x94h\\x1dh\\xdbubs\\x8c\\x0emaxagetest.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\x0emax-age-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\xdc\\x8c\\x07max-age\\x94\\x8c\\x0260\\x94\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\xdfh\\x1b\\x8c\\nfourteenth\\x94h\\x1dh\\xecubs\\x8c\\x12invalid-values.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94(\\x8c\\x16invalid-max-age-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\xed\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\xf0h\\x1b\\x8c\\tfifteenth\\x94h\\x1dh\\xfcub\\x8c\\x16invalid-expires-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94\\x8c\\x12invalid-values.com\\x94\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\xfdh\\x1b\\x8c\\tsixteenth\\x94h\\x1dj\\n\\x01\\x00\\x00ubuu.\"\n    cookies = pickle.loads(pickled)\n\n    cj = CookieJar()\n    cj.update_cookies(cookies_to_send)\n\n    assert cookies == cj._cookies\n\n\n@pytest.mark.parametrize(\n    \"url\",\n    [\n        \"http://127.0.0.1/index.html\",\n        URL(\"http://127.0.0.1/index.html\"),\n        [\"http://127.0.0.1/index.html\"],\n        [URL(\"http://127.0.0.1/index.html\")],\n    ],\n)\nasync def test_treat_as_secure_origin_init(url) -> None:\n    jar = CookieJar(unsafe=True, treat_as_secure_origin=url)\n    assert jar._treat_as_secure_origin == [URL(\"http://127.0.0.1\")]\n\n\nasync def test_treat_as_secure_origin() -> None:\n    endpoint = URL(\"http://127.0.0.1/\")\n\n    jar = CookieJar(unsafe=True, treat_as_secure_origin=[endpoint])\n    secure_cookie = SimpleCookie(\n        \"cookie-key=cookie-value; HttpOnly; Path=/; Secure\",\n    )\n\n    jar.update_cookies(\n        secure_cookie,\n        endpoint,\n    )\n\n    assert len(jar) == 1\n    filtered_cookies = jar.filter_cookies(request_url=endpoint)\n    assert len(filtered_cookies) == 1\n",
            "header": {
                "file": {
                    "path": "tests/test_cookiejar.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "b2f8085e",
                "new_commit_hash": "6ff00bf4",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tests/test_cookiejar.py"
            },
            "plus_file": {
                "path": "b/tests/test_cookiejar.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 864,
                            "length": 6
                        },
                        "new_range": {
                            "start": 864,
                            "length": 27
                        },
                        "section": "async def test_cookie_jar_clear_expired():"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        assert len(sut) == 0",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "async def test_cookie_jar_filter_cookies_expires():",
                                "type": "added"
                            },
                            {
                                "content": "    \"\"\"Test that calling filter_cookies will expire stale cookies.\"\"\"",
                                "type": "added"
                            },
                            {
                                "content": "    jar = CookieJar()",
                                "type": "added"
                            },
                            {
                                "content": "    assert len(jar) == 0",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    cookie = SimpleCookie()",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    cookie[\"foo\"] = \"bar\"",
                                "type": "added"
                            },
                            {
                                "content": "    cookie[\"foo\"][\"expires\"] = \"Tue, 1 Jan 1990 12:00:00 GMT\"",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    with freeze_time(\"1980-01-01\"):",
                                "type": "added"
                            },
                            {
                                "content": "        jar.update_cookies(cookie)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    assert len(jar) == 1",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    # filter_cookies should expire stale cookies",
                                "type": "added"
                            },
                            {
                                "content": "    jar.filter_cookies(URL(\"http://any.com/\"))",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    assert len(jar) == 0",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "async def test_cookie_jar_clear_domain() -> None:",
                                "type": "context"
                            },
                            {
                                "content": "    sut = CookieJar()",
                                "type": "context"
                            },
                            {
                                "content": "    cookie = SimpleCookie()",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [],
                    "added_entities": [
                        {
                            "file_name": "tests/test_cookiejar.py",
                            "type": "function",
                            "name": "test_cookie_jar_filter_cookies_expires",
                            "content": "async def test_cookie_jar_filter_cookies_expires():\n    \"\"\"Test that calling filter_cookies will expire stale cookies.\"\"\"\n    jar = CookieJar()\n    assert len(jar) == 0\n\n    cookie = SimpleCookie()\n\n    cookie[\"foo\"] = \"bar\"\n    cookie[\"foo\"][\"expires\"] = \"Tue, 1 Jan 1990 12:00:00 GMT\"\n\n    with freeze_time(\"1980-01-01\"):\n        jar.update_cookies(cookie)\n\n    assert len(jar) == 1\n\n    # filter_cookies should expire stale cookies\n    jar.filter_cookies(URL(\"http://any.com/\"))\n\n    assert len(jar) == 0",
                            "ast_type_str": "AsyncFunctionDef",
                            "start_lineno": 867,
                            "end_lineno": 885,
                            "parent": null
                        }
                    ],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "e8339e7687a6c228076f788237b6dbe95ae711e5^",
    "new_commit_hash": "e8339e7687a6c228076f788237b6dbe95ae711e5",
    "commit_message": "Fix duplicate cookie expiration calls in the CookieJar implementation (#7784)\n\nCo-authored-by: Sam Bull <git@sambull.org>",
    "commit_date": "2024-01-20T16:05:48-10:00",
    "metadata": {}
}
{
    "repo_name": "aiohttp",
    "new_commit_hash": "e8339e7687a6c228076f788237b6dbe95ae711e5",
    "test_file_codes": [
        "# type: ignore\nimport asyncio\nimport datetime\nimport itertools\nimport pathlib\nimport pickle\nimport unittest\nfrom http.cookies import BaseCookie, Morsel, SimpleCookie\nfrom typing import Any\nfrom unittest import mock\n\nimport pytest\nfrom freezegun import freeze_time\nfrom yarl import URL\n\nfrom aiohttp import CookieJar, DummyCookieJar\n\n\ndef dump_cookiejar() -> bytes:  # pragma: no cover\n    \"\"\"Create pickled data for test_pickle_format().\"\"\"\n    cj = CookieJar()\n    cj.update_cookies(cookies_to_send.__pytest_wrapped__.obj())\n    return pickle.dumps(cj._cookies, pickle.HIGHEST_PROTOCOL)\n\n\n@pytest.fixture\ndef cookies_to_send():\n    return SimpleCookie(\n        \"shared-cookie=first; \"\n        \"domain-cookie=second; Domain=example.com; \"\n        \"subdomain1-cookie=third; Domain=test1.example.com; \"\n        \"subdomain2-cookie=fourth; Domain=test2.example.com; \"\n        \"dotted-domain-cookie=fifth; Domain=.example.com; \"\n        \"different-domain-cookie=sixth; Domain=different.org; \"\n        \"secure-cookie=seventh; Domain=secure.com; Secure; \"\n        \"no-path-cookie=eighth; Domain=pathtest.com; \"\n        \"path1-cookie=ninth; Domain=pathtest.com; Path=/; \"\n        \"path2-cookie=tenth; Domain=pathtest.com; Path=/one; \"\n        \"path3-cookie=eleventh; Domain=pathtest.com; Path=/one/two; \"\n        \"path4-cookie=twelfth; Domain=pathtest.com; Path=/one/two/; \"\n        \"expires-cookie=thirteenth; Domain=expirestest.com; Path=/;\"\n        \" Expires=Tue, 1 Jan 2999 12:00:00 GMT; \"\n        \"max-age-cookie=fourteenth; Domain=maxagetest.com; Path=/;\"\n        \" Max-Age=60; \"\n        \"invalid-max-age-cookie=fifteenth; Domain=invalid-values.com; \"\n        \" Max-Age=string; \"\n        \"invalid-expires-cookie=sixteenth; Domain=invalid-values.com; \"\n        \" Expires=string;\"\n    )\n\n\n@pytest.fixture\ndef cookies_to_send_with_expired():\n    return SimpleCookie(\n        \"shared-cookie=first; \"\n        \"domain-cookie=second; Domain=example.com; \"\n        \"subdomain1-cookie=third; Domain=test1.example.com; \"\n        \"subdomain2-cookie=fourth; Domain=test2.example.com; \"\n        \"dotted-domain-cookie=fifth; Domain=.example.com; \"\n        \"different-domain-cookie=sixth; Domain=different.org; \"\n        \"secure-cookie=seventh; Domain=secure.com; Secure; \"\n        \"no-path-cookie=eighth; Domain=pathtest.com; \"\n        \"path1-cookie=ninth; Domain=pathtest.com; Path=/; \"\n        \"path2-cookie=tenth; Domain=pathtest.com; Path=/one; \"\n        \"path3-cookie=eleventh; Domain=pathtest.com; Path=/one/two; \"\n        \"path4-cookie=twelfth; Domain=pathtest.com; Path=/one/two/; \"\n        \"expires-cookie=thirteenth; Domain=expirestest.com; Path=/;\"\n        \" Expires=Tue, 1 Jan 1980 12:00:00 GMT; \"\n        \"max-age-cookie=fourteenth; Domain=maxagetest.com; Path=/;\"\n        \" Max-Age=60; \"\n        \"invalid-max-age-cookie=fifteenth; Domain=invalid-values.com; \"\n        \" Max-Age=string; \"\n        \"invalid-expires-cookie=sixteenth; Domain=invalid-values.com; \"\n        \" Expires=string;\"\n    )\n\n\n@pytest.fixture\ndef cookies_to_receive():\n    return SimpleCookie(\n        \"unconstrained-cookie=first; Path=/; \"\n        \"domain-cookie=second; Domain=example.com; Path=/; \"\n        \"subdomain1-cookie=third; Domain=test1.example.com; Path=/; \"\n        \"subdomain2-cookie=fourth; Domain=test2.example.com; Path=/; \"\n        \"dotted-domain-cookie=fifth; Domain=.example.com; Path=/; \"\n        \"different-domain-cookie=sixth; Domain=different.org; Path=/; \"\n        \"no-path-cookie=seventh; Domain=pathtest.com; \"\n        \"path-cookie=eighth; Domain=pathtest.com; Path=/somepath; \"\n        \"wrong-path-cookie=ninth; Domain=pathtest.com; Path=somepath;\"\n    )\n\n\ndef test_date_parsing() -> None:\n    parse_func = CookieJar._parse_date\n    utc = datetime.timezone.utc\n\n    assert parse_func(\"\") is None\n\n    # 70 -> 1970\n    assert (\n        parse_func(\"Tue, 1 Jan 70 00:00:00 GMT\")\n        == datetime.datetime(1970, 1, 1, tzinfo=utc).timestamp()\n    )\n\n    # 10 -> 2010\n    assert (\n        parse_func(\"Tue, 1 Jan 10 00:00:00 GMT\")\n        == datetime.datetime(2010, 1, 1, tzinfo=utc).timestamp()\n    )\n\n    # No day of week string\n    assert (\n        parse_func(\"1 Jan 1970 00:00:00 GMT\")\n        == datetime.datetime(1970, 1, 1, tzinfo=utc).timestamp()\n    )\n\n    # No timezone string\n    assert (\n        parse_func(\"Tue, 1 Jan 1970 00:00:00\")\n        == datetime.datetime(1970, 1, 1, tzinfo=utc).timestamp()\n    )\n\n    # No year\n    assert parse_func(\"Tue, 1 Jan 00:00:00 GMT\") is None\n\n    # No month\n    assert parse_func(\"Tue, 1 1970 00:00:00 GMT\") is None\n\n    # No day of month\n    assert parse_func(\"Tue, Jan 1970 00:00:00 GMT\") is None\n\n    # No time\n    assert parse_func(\"Tue, 1 Jan 1970 GMT\") is None\n\n    # Invalid day of month\n    assert parse_func(\"Tue, 0 Jan 1970 00:00:00 GMT\") is None\n\n    # Invalid year\n    assert parse_func(\"Tue, 1 Jan 1500 00:00:00 GMT\") is None\n\n    # Invalid time\n    assert parse_func(\"Tue, 1 Jan 1970 77:88:99 GMT\") is None\n\n\ndef test_domain_matching() -> None:\n    test_func = CookieJar._is_domain_match\n\n    assert test_func(\"test.com\", \"test.com\")\n    assert test_func(\"test.com\", \"sub.test.com\")\n\n    assert not test_func(\"test.com\", \"\")\n    assert not test_func(\"test.com\", \"test.org\")\n    assert not test_func(\"diff-test.com\", \"test.com\")\n    assert not test_func(\"test.com\", \"diff-test.com\")\n    assert not test_func(\"test.com\", \"127.0.0.1\")\n\n\nasync def test_constructor(cookies_to_send: Any, cookies_to_receive: Any) -> None:\n    jar = CookieJar()\n    jar.update_cookies(cookies_to_send)\n    jar_cookies = SimpleCookie()\n    for cookie in jar:\n        dict.__setitem__(jar_cookies, cookie.key, cookie)\n    expected_cookies = cookies_to_send\n    assert jar_cookies == expected_cookies\n\n\nasync def test_constructor_with_expired(\n    cookies_to_send_with_expired: Any, cookies_to_receive: Any\n) -> None:\n    jar = CookieJar()\n    jar.update_cookies(cookies_to_send_with_expired)\n    jar_cookies = SimpleCookie()\n    for cookie in jar:\n        dict.__setitem__(jar_cookies, cookie.key, cookie)\n    expected_cookies = cookies_to_send_with_expired\n    assert jar_cookies != expected_cookies\n\n\nasync def test_save_load(\n    tmp_path: Any, loop: Any, cookies_to_send: Any, cookies_to_receive: Any\n) -> None:\n    file_path = pathlib.Path(str(tmp_path)) / \"aiohttp.test.cookie\"\n\n    # export cookie jar\n    jar_save = CookieJar()\n    jar_save.update_cookies(cookies_to_receive)\n    jar_save.save(file_path=file_path)\n\n    jar_load = CookieJar()\n    jar_load.load(file_path=file_path)\n\n    jar_test = SimpleCookie()\n    for cookie in jar_load:\n        jar_test[cookie.key] = cookie\n\n    assert jar_test == cookies_to_receive\n\n\nasync def test_update_cookie_with_unicode_domain(loop: Any) -> None:\n    cookies = (\n        \"idna-domain-first=first; Domain=xn--9caa.com; Path=/;\",\n        \"idna-domain-second=second; Domain=xn--9caa.com; Path=/;\",\n    )\n\n    jar = CookieJar()\n    jar.update_cookies(SimpleCookie(cookies[0]), URL(\"http://éé.com/\"))\n    jar.update_cookies(SimpleCookie(cookies[1]), URL(\"http://xn--9caa.com/\"))\n\n    jar_test = SimpleCookie()\n    for cookie in jar:\n        jar_test[cookie.key] = cookie\n\n    assert jar_test == SimpleCookie(\" \".join(cookies))\n\n\nasync def test_filter_cookie_with_unicode_domain(loop: Any) -> None:\n    jar = CookieJar()\n    jar.update_cookies(\n        SimpleCookie(\"idna-domain-first=first; Domain=xn--9caa.com; Path=/; \")\n    )\n    assert len(jar.filter_cookies(URL(\"http://éé.com\"))) == 1\n    assert len(jar.filter_cookies(URL(\"http://xn--9caa.com\"))) == 1\n\n\nasync def test_filter_cookies_str_deprecated(loop: Any) -> None:\n    jar = CookieJar()\n    with pytest.deprecated_call(\n        match=\"The method accepts yarl.URL instances only, got <class 'str'>\",\n    ):\n        jar.filter_cookies(\"http://éé.com\")\n\n\n@pytest.mark.parametrize(\n    (\"url\", \"expected_cookies\"),\n    (\n        (\n            \"http://pathtest.com/one/two/\",\n            (\n                \"no-path-cookie\",\n                \"path1-cookie\",\n                \"path2-cookie\",\n                \"shared-cookie\",\n                \"path3-cookie\",\n                \"path4-cookie\",\n            ),\n        ),\n        (\n            \"http://pathtest.com/one/two\",\n            (\n                \"no-path-cookie\",\n                \"path1-cookie\",\n                \"path2-cookie\",\n                \"shared-cookie\",\n                \"path3-cookie\",\n            ),\n        ),\n        (\n            \"http://pathtest.com/one/two/three/\",\n            (\n                \"no-path-cookie\",\n                \"path1-cookie\",\n                \"path2-cookie\",\n                \"shared-cookie\",\n                \"path3-cookie\",\n                \"path4-cookie\",\n            ),\n        ),\n        (\n            \"http://test1.example.com/\",\n            (\n                \"shared-cookie\",\n                \"domain-cookie\",\n                \"subdomain1-cookie\",\n                \"dotted-domain-cookie\",\n            ),\n        ),\n        (\n            \"http://pathtest.com/\",\n            (\n                \"shared-cookie\",\n                \"no-path-cookie\",\n                \"path1-cookie\",\n            ),\n        ),\n    ),\n)\nasync def test_filter_cookies_with_domain_path_lookup_multilevelpath(\n    loop: Any,\n    url: Any,\n    expected_cookies: Any,\n) -> None:\n    jar = CookieJar()\n    cookies = SimpleCookie(\n        \"shared-cookie=first; \"\n        \"domain-cookie=second; Domain=example.com; \"\n        \"subdomain1-cookie=third; Domain=test1.example.com; \"\n        \"subdomain2-cookie=fourth; Domain=test2.example.com; \"\n        \"dotted-domain-cookie=fifth; Domain=.example.com; \"\n        \"different-domain-cookie=sixth; Domain=different.org; \"\n        \"secure-cookie=seventh; Domain=secure.com; Secure; \"\n        \"no-path-cookie=eighth; Domain=pathtest.com; \"\n        \"path1-cookie=ninth; Domain=pathtest.com; Path=/; \"\n        \"path2-cookie=tenth; Domain=pathtest.com; Path=/one; \"\n        \"path3-cookie=eleventh; Domain=pathtest.com; Path=/one/two; \"\n        \"path4-cookie=twelfth; Domain=pathtest.com; Path=/one/two/; \"\n        \"expires-cookie=thirteenth; Domain=expirestest.com; Path=/;\"\n        \" Expires=Tue, 1 Jan 1980 12:00:00 GMT; \"\n        \"max-age-cookie=fourteenth; Domain=maxagetest.com; Path=/;\"\n        \" Max-Age=60; \"\n        \"invalid-max-age-cookie=fifteenth; Domain=invalid-values.com; \"\n        \" Max-Age=string; \"\n        \"invalid-expires-cookie=sixteenth; Domain=invalid-values.com; \"\n        \" Expires=string;\"\n    )\n    jar.update_cookies(cookies)\n    cookies = jar.filter_cookies(URL(url))\n\n    assert len(cookies) == len(expected_cookies)\n    for c in cookies:\n        assert c in expected_cookies\n\n\nasync def test_domain_filter_ip_cookie_send(loop: Any) -> None:\n    jar = CookieJar()\n    cookies = SimpleCookie(\n        \"shared-cookie=first; \"\n        \"domain-cookie=second; Domain=example.com; \"\n        \"subdomain1-cookie=third; Domain=test1.example.com; \"\n        \"subdomain2-cookie=fourth; Domain=test2.example.com; \"\n        \"dotted-domain-cookie=fifth; Domain=.example.com; \"\n        \"different-domain-cookie=sixth; Domain=different.org; \"\n        \"secure-cookie=seventh; Domain=secure.com; Secure; \"\n        \"no-path-cookie=eighth; Domain=pathtest.com; \"\n        \"path1-cookie=ninth; Domain=pathtest.com; Path=/; \"\n        \"path2-cookie=tenth; Domain=pathtest.com; Path=/one; \"\n        \"path3-cookie=eleventh; Domain=pathtest.com; Path=/one/two; \"\n        \"path4-cookie=twelfth; Domain=pathtest.com; Path=/one/two/; \"\n        \"expires-cookie=thirteenth; Domain=expirestest.com; Path=/;\"\n        \" Expires=Tue, 1 Jan 1980 12:00:00 GMT; \"\n        \"max-age-cookie=fourteenth; Domain=maxagetest.com; Path=/;\"\n        \" Max-Age=60; \"\n        \"invalid-max-age-cookie=fifteenth; Domain=invalid-values.com; \"\n        \" Max-Age=string; \"\n        \"invalid-expires-cookie=sixteenth; Domain=invalid-values.com; \"\n        \" Expires=string;\"\n    )\n\n    jar.update_cookies(cookies)\n    cookies_sent = jar.filter_cookies(URL(\"http://1.2.3.4/\")).output(header=\"Cookie:\")\n    assert cookies_sent == \"Cookie: shared-cookie=first\"\n\n\nasync def test_domain_filter_ip_cookie_receive(cookies_to_receive: Any) -> None:\n    jar = CookieJar()\n\n    jar.update_cookies(cookies_to_receive, URL(\"http://1.2.3.4/\"))\n    assert len(jar) == 0\n\n\n@pytest.mark.parametrize(\n    (\"cookies\", \"expected\", \"quote_bool\"),\n    [\n        (\n            \"shared-cookie=first; ip-cookie=second; Domain=127.0.0.1;\",\n            \"Cookie: ip-cookie=second\\r\\nCookie: shared-cookie=first\",\n            True,\n        ),\n        ('ip-cookie=\"second\"; Domain=127.0.0.1;', 'Cookie: ip-cookie=\"second\"', True),\n        (\"custom-cookie=value/one;\", 'Cookie: custom-cookie=\"value/one\"', True),\n        (\"custom-cookie=value1;\", \"Cookie: custom-cookie=value1\", True),\n        (\"custom-cookie=value/one;\", \"Cookie: custom-cookie=value/one\", False),\n    ],\n    ids=(\n        \"IP domain preserved\",\n        \"no shared cookie\",\n        \"quoted cookie with special char\",\n        \"quoted cookie w/o special char\",\n        \"unquoted cookie with special char\",\n    ),\n)\nasync def test_quotes_correctly_based_on_input(\n    loop: Any, cookies: Any, expected: Any, quote_bool: Any\n) -> None:\n    jar = CookieJar(unsafe=True, quote_cookie=quote_bool)\n    jar.update_cookies(SimpleCookie(cookies))\n    cookies_sent = jar.filter_cookies(URL(\"http://127.0.0.1/\")).output(header=\"Cookie:\")\n    assert cookies_sent == expected\n\n\nasync def test_ignore_domain_ending_with_dot(loop: Any) -> None:\n    jar = CookieJar(unsafe=True)\n    jar.update_cookies(\n        SimpleCookie(\"cookie=val; Domain=example.com.;\"), URL(\"http://www.example.com\")\n    )\n    cookies_sent = jar.filter_cookies(URL(\"http://www.example.com/\"))\n    assert cookies_sent.output(header=\"Cookie:\") == \"Cookie: cookie=val\"\n    cookies_sent = jar.filter_cookies(URL(\"http://example.com/\"))\n    assert cookies_sent.output(header=\"Cookie:\") == \"\"\n\n\nclass TestCookieJarBase(unittest.TestCase):\n    loop: Any\n    jar: Any\n\n    def setUp(self):\n        self.loop = asyncio.new_event_loop()\n        asyncio.set_event_loop(None)\n\n        # N.B. those need to be overridden in child test cases\n        async def make_jar():\n            return CookieJar()\n\n        self.jar = self.loop.run_until_complete(make_jar())\n\n    def tearDown(self) -> None:\n        self.loop.close()\n\n    def request_reply_with_same_url(self, url: Any):\n        self.jar.update_cookies(self.cookies_to_send)\n        cookies_sent = self.jar.filter_cookies(URL(url))\n\n        self.jar.clear()\n\n        self.jar.update_cookies(self.cookies_to_receive, URL(url))\n        cookies_received = SimpleCookie()\n        for cookie in self.jar:\n            dict.__setitem__(cookies_received, cookie.key, cookie)\n\n        self.jar.clear()\n\n        return cookies_sent, cookies_received\n\n\nclass TestCookieJarSafe(TestCookieJarBase):\n    cookies_to_send: Any\n    cookies_to_receive: Any\n    jar: Any\n\n    def setUp(self):\n        super().setUp()\n\n        self.cookies_to_send = SimpleCookie(\n            \"shared-cookie=first; \"\n            \"domain-cookie=second; Domain=example.com; \"\n            \"subdomain1-cookie=third; Domain=test1.example.com; \"\n            \"subdomain2-cookie=fourth; Domain=test2.example.com; \"\n            \"dotted-domain-cookie=fifth; Domain=.example.com; \"\n            \"different-domain-cookie=sixth; Domain=different.org; \"\n            \"secure-cookie=seventh; Domain=secure.com; Secure; \"\n            \"no-path-cookie=eighth; Domain=pathtest.com; \"\n            \"path1-cookie=ninth; Domain=pathtest.com; Path=/; \"\n            \"path2-cookie=tenth; Domain=pathtest.com; Path=/one; \"\n            \"path3-cookie=eleventh; Domain=pathtest.com; Path=/one/two; \"\n            \"path4-cookie=twelfth; Domain=pathtest.com; Path=/one/two/; \"\n            \"expires-cookie=thirteenth; Domain=expirestest.com; Path=/;\"\n            \" Expires=Tue, 1 Jan 1980 12:00:00 GMT; \"\n            \"max-age-cookie=fourteenth; Domain=maxagetest.com; Path=/;\"\n            \" Max-Age=60; \"\n            \"invalid-max-age-cookie=fifteenth; Domain=invalid-values.com; \"\n            \" Max-Age=string; \"\n            \"invalid-expires-cookie=sixteenth; Domain=invalid-values.com; \"\n            \" Expires=string;\"\n        )\n\n        self.cookies_to_receive = SimpleCookie(\n            \"unconstrained-cookie=first; Path=/; \"\n            \"domain-cookie=second; Domain=example.com; Path=/; \"\n            \"subdomain1-cookie=third; Domain=test1.example.com; Path=/; \"\n            \"subdomain2-cookie=fourth; Domain=test2.example.com; Path=/; \"\n            \"dotted-domain-cookie=fifth; Domain=.example.com; Path=/; \"\n            \"different-domain-cookie=sixth; Domain=different.org; Path=/; \"\n            \"no-path-cookie=seventh; Domain=pathtest.com; \"\n            \"path-cookie=eighth; Domain=pathtest.com; Path=/somepath; \"\n            \"wrong-path-cookie=ninth; Domain=pathtest.com; Path=somepath;\"\n        )\n\n        async def make_jar():\n            return CookieJar()\n\n        self.jar = self.loop.run_until_complete(make_jar())\n\n    def timed_request(self, url: Any, update_time: Any, send_time: Any):\n        if isinstance(update_time, int):\n            update_time = datetime.timedelta(seconds=update_time)\n        elif isinstance(update_time, float):\n            update_time = datetime.datetime.fromtimestamp(update_time)\n        if isinstance(send_time, int):\n            send_time = datetime.timedelta(seconds=send_time)\n        elif isinstance(send_time, float):\n            send_time = datetime.datetime.fromtimestamp(send_time)\n\n        with freeze_time(update_time):\n            self.jar.update_cookies(self.cookies_to_send)\n\n        with freeze_time(send_time):\n            cookies_sent = self.jar.filter_cookies(URL(url))\n\n        self.jar.clear()\n\n        return cookies_sent\n\n    def test_domain_filter_same_host(self) -> None:\n        cookies_sent, cookies_received = self.request_reply_with_same_url(\n            \"http://example.com/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\"shared-cookie\", \"domain-cookie\", \"dotted-domain-cookie\"},\n        )\n\n        self.assertEqual(\n            set(cookies_received.keys()),\n            {\"unconstrained-cookie\", \"domain-cookie\", \"dotted-domain-cookie\"},\n        )\n\n    def test_domain_filter_same_host_and_subdomain(self) -> None:\n        cookies_sent, cookies_received = self.request_reply_with_same_url(\n            \"http://test1.example.com/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\n                \"shared-cookie\",\n                \"domain-cookie\",\n                \"subdomain1-cookie\",\n                \"dotted-domain-cookie\",\n            },\n        )\n\n        self.assertEqual(\n            set(cookies_received.keys()),\n            {\n                \"unconstrained-cookie\",\n                \"domain-cookie\",\n                \"subdomain1-cookie\",\n                \"dotted-domain-cookie\",\n            },\n        )\n\n    def test_domain_filter_same_host_diff_subdomain(self) -> None:\n        cookies_sent, cookies_received = self.request_reply_with_same_url(\n            \"http://different.example.com/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\"shared-cookie\", \"domain-cookie\", \"dotted-domain-cookie\"},\n        )\n\n        self.assertEqual(\n            set(cookies_received.keys()),\n            {\"unconstrained-cookie\", \"domain-cookie\", \"dotted-domain-cookie\"},\n        )\n\n    def test_domain_filter_diff_host(self) -> None:\n        cookies_sent, cookies_received = self.request_reply_with_same_url(\n            \"http://different.org/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()), {\"shared-cookie\", \"different-domain-cookie\"}\n        )\n\n        self.assertEqual(\n            set(cookies_received.keys()),\n            {\"unconstrained-cookie\", \"different-domain-cookie\"},\n        )\n\n    def test_domain_filter_host_only(self) -> None:\n        self.jar.update_cookies(self.cookies_to_receive, URL(\"http://example.com/\"))\n        sub_cookie = SimpleCookie(\"subdomain=spam; Path=/;\")\n        self.jar.update_cookies(sub_cookie, URL(\"http://foo.example.com/\"))\n\n        cookies_sent = self.jar.filter_cookies(URL(\"http://foo.example.com/\"))\n        self.assertIn(\"subdomain\", set(cookies_sent.keys()))\n        self.assertNotIn(\"unconstrained-cookie\", set(cookies_sent.keys()))\n\n    def test_secure_filter(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\"http://secure.com/\")\n\n        self.assertEqual(set(cookies_sent.keys()), {\"shared-cookie\"})\n\n        cookies_sent, _ = self.request_reply_with_same_url(\"https://secure.com/\")\n\n        self.assertEqual(set(cookies_sent.keys()), {\"shared-cookie\", \"secure-cookie\"})\n\n    def test_path_filter_root(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\"http://pathtest.com/\")\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\"shared-cookie\", \"no-path-cookie\", \"path1-cookie\"},\n        )\n\n    def test_path_filter_folder(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\"http://pathtest.com/one/\")\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\"shared-cookie\", \"no-path-cookie\", \"path1-cookie\", \"path2-cookie\"},\n        )\n\n    def test_path_filter_file(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\n            \"http://pathtest.com/one/two\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\n                \"shared-cookie\",\n                \"no-path-cookie\",\n                \"path1-cookie\",\n                \"path2-cookie\",\n                \"path3-cookie\",\n            },\n        )\n\n    def test_path_filter_subfolder(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\n            \"http://pathtest.com/one/two/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\n                \"shared-cookie\",\n                \"no-path-cookie\",\n                \"path1-cookie\",\n                \"path2-cookie\",\n                \"path3-cookie\",\n                \"path4-cookie\",\n            },\n        )\n\n    def test_path_filter_subsubfolder(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\n            \"http://pathtest.com/one/two/three/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\n                \"shared-cookie\",\n                \"no-path-cookie\",\n                \"path1-cookie\",\n                \"path2-cookie\",\n                \"path3-cookie\",\n                \"path4-cookie\",\n            },\n        )\n\n    def test_path_filter_different_folder(self) -> None:\n        cookies_sent, _ = self.request_reply_with_same_url(\n            \"http://pathtest.com/hundred/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\"shared-cookie\", \"no-path-cookie\", \"path1-cookie\"},\n        )\n\n    def test_path_value(self) -> None:\n        _, cookies_received = self.request_reply_with_same_url(\"http://pathtest.com/\")\n\n        self.assertEqual(\n            set(cookies_received.keys()),\n            {\n                \"unconstrained-cookie\",\n                \"no-path-cookie\",\n                \"path-cookie\",\n                \"wrong-path-cookie\",\n            },\n        )\n\n        self.assertEqual(cookies_received[\"no-path-cookie\"][\"path\"], \"/\")\n        self.assertEqual(cookies_received[\"path-cookie\"][\"path\"], \"/somepath\")\n        self.assertEqual(cookies_received[\"wrong-path-cookie\"][\"path\"], \"/\")\n\n    def test_expires(self) -> None:\n        ts_before = datetime.datetime(\n            1975, 1, 1, tzinfo=datetime.timezone.utc\n        ).timestamp()\n\n        ts_after = datetime.datetime(\n            2030, 1, 1, tzinfo=datetime.timezone.utc\n        ).timestamp()\n\n        cookies_sent = self.timed_request(\n            \"http://expirestest.com/\", ts_before, ts_before\n        )\n\n        self.assertEqual(set(cookies_sent.keys()), {\"shared-cookie\", \"expires-cookie\"})\n\n        cookies_sent = self.timed_request(\n            \"http://expirestest.com/\", ts_before, ts_after\n        )\n\n        self.assertEqual(set(cookies_sent.keys()), {\"shared-cookie\"})\n\n    def test_max_age(self) -> None:\n        cookies_sent = self.timed_request(\"http://maxagetest.com/\", 1000, 1000)\n\n        self.assertEqual(set(cookies_sent.keys()), {\"shared-cookie\", \"max-age-cookie\"})\n\n        cookies_sent = self.timed_request(\"http://maxagetest.com/\", 1000, 2000)\n\n        self.assertEqual(set(cookies_sent.keys()), {\"shared-cookie\"})\n\n    def test_invalid_values(self) -> None:\n        cookies_sent, cookies_received = self.request_reply_with_same_url(\n            \"http://invalid-values.com/\"\n        )\n\n        self.assertEqual(\n            set(cookies_sent.keys()),\n            {\"shared-cookie\", \"invalid-max-age-cookie\", \"invalid-expires-cookie\"},\n        )\n\n        cookie = cookies_sent[\"invalid-max-age-cookie\"]\n        self.assertEqual(cookie[\"max-age\"], \"\")\n\n        cookie = cookies_sent[\"invalid-expires-cookie\"]\n        self.assertEqual(cookie[\"expires\"], \"\")\n\n    def test_cookie_not_expired_when_added_after_removal(self) -> None:\n        # Test case for https://github.com/aio-libs/aiohttp/issues/2084\n        timestamps = [\n            533588.993,\n            533588.993,\n            533588.993,\n            533588.993,\n            533589.093,\n            533589.093,\n        ]\n\n        loop = mock.Mock()\n        loop.time.side_effect = itertools.chain(\n            timestamps, itertools.cycle([timestamps[-1]])\n        )\n\n        async def make_jar():\n            return CookieJar(unsafe=True)\n\n        jar = self.loop.run_until_complete(make_jar())\n        # Remove `foo` cookie.\n        jar.update_cookies(SimpleCookie('foo=\"\"; Max-Age=0'))\n        # Set `foo` cookie to `bar`.\n        jar.update_cookies(SimpleCookie('foo=\"bar\"'))\n\n        # Assert that there is a cookie.\n        assert len(jar) == 1\n\n    def test_path_filter_diff_folder_same_name(self) -> None:\n        async def make_jar():\n            return CookieJar(unsafe=True)\n\n        jar = self.loop.run_until_complete(make_jar())\n\n        jar.update_cookies(\n            SimpleCookie(\"path-cookie=zero; Domain=pathtest.com; Path=/; \")\n        )\n        jar.update_cookies(\n            SimpleCookie(\"path-cookie=one; Domain=pathtest.com; Path=/one; \")\n        )\n        self.assertEqual(len(jar), 2)\n\n        jar_filtered = jar.filter_cookies(URL(\"http://pathtest.com/\"))\n        self.assertEqual(len(jar_filtered), 1)\n        self.assertEqual(jar_filtered[\"path-cookie\"].value, \"zero\")\n\n        jar_filtered = jar.filter_cookies(URL(\"http://pathtest.com/one\"))\n        self.assertEqual(len(jar_filtered), 1)\n        self.assertEqual(jar_filtered[\"path-cookie\"].value, \"one\")\n\n    def test_path_filter_diff_folder_same_name_return_best_match_independent_from_put_order(\n        self,\n    ) -> None:\n        async def make_jar():\n            return CookieJar(unsafe=True)\n\n        jar = self.loop.run_until_complete(make_jar())\n        jar.update_cookies(\n            SimpleCookie(\"path-cookie=one; Domain=pathtest.com; Path=/one; \")\n        )\n        jar.update_cookies(\n            SimpleCookie(\"path-cookie=zero; Domain=pathtest.com; Path=/; \")\n        )\n        jar.update_cookies(\n            SimpleCookie(\"path-cookie=two; Domain=pathtest.com; Path=/second; \")\n        )\n        self.assertEqual(len(jar), 3)\n\n        jar_filtered = jar.filter_cookies(URL(\"http://pathtest.com/\"))\n        self.assertEqual(len(jar_filtered), 1)\n        self.assertEqual(jar_filtered[\"path-cookie\"].value, \"zero\")\n\n        jar_filtered = jar.filter_cookies(URL(\"http://pathtest.com/second\"))\n        self.assertEqual(len(jar_filtered), 1)\n        self.assertEqual(jar_filtered[\"path-cookie\"].value, \"two\")\n\n        jar_filtered = jar.filter_cookies(URL(\"http://pathtest.com/one\"))\n        self.assertEqual(len(jar_filtered), 1)\n        self.assertEqual(jar_filtered[\"path-cookie\"].value, \"one\")\n\n\nasync def test_dummy_cookie_jar() -> None:\n    cookie = SimpleCookie(\"foo=bar; Domain=example.com;\")\n    dummy_jar = DummyCookieJar()\n    assert len(dummy_jar) == 0\n    dummy_jar.update_cookies(cookie)\n    assert len(dummy_jar) == 0\n    with pytest.raises(StopIteration):\n        next(iter(dummy_jar))\n    assert not dummy_jar.filter_cookies(URL(\"http://example.com/\"))\n    dummy_jar.clear()\n\n\nasync def test_loose_cookies_types() -> None:\n    jar = CookieJar()\n\n    accepted_types = [\n        [(\"str\", BaseCookie())],\n        [(\"str\", Morsel())],\n        [\n            (\"str\", \"str\"),\n        ],\n        {\"str\": BaseCookie()},\n        {\"str\": Morsel()},\n        {\"str\": \"str\"},\n        SimpleCookie(),\n    ]\n\n    for loose_cookies_type in accepted_types:\n        jar.update_cookies(cookies=loose_cookies_type)\n\n\nasync def test_cookie_jar_clear_all() -> None:\n    sut = CookieJar()\n    cookie = SimpleCookie()\n    cookie[\"foo\"] = \"bar\"\n    sut.update_cookies(cookie)\n\n    sut.clear()\n    assert len(sut) == 0\n\n\nasync def test_cookie_jar_clear_expired():\n    sut = CookieJar()\n\n    cookie = SimpleCookie()\n\n    cookie[\"foo\"] = \"bar\"\n    cookie[\"foo\"][\"expires\"] = \"Tue, 1 Jan 1990 12:00:00 GMT\"\n\n    with freeze_time(\"1980-01-01\"):\n        sut.update_cookies(cookie)\n\n    sut.clear(lambda x: False)\n    with freeze_time(\"1980-01-01\"):\n        assert len(sut) == 0\n\n\nasync def test_cookie_jar_filter_cookies_expires():\n    \"\"\"Test that calling filter_cookies will expire stale cookies.\"\"\"\n    jar = CookieJar()\n    assert len(jar) == 0\n\n    cookie = SimpleCookie()\n\n    cookie[\"foo\"] = \"bar\"\n    cookie[\"foo\"][\"expires\"] = \"Tue, 1 Jan 1990 12:00:00 GMT\"\n\n    with freeze_time(\"1980-01-01\"):\n        jar.update_cookies(cookie)\n\n    assert len(jar) == 1\n\n    # filter_cookies should expire stale cookies\n    jar.filter_cookies(URL(\"http://any.com/\"))\n\n    assert len(jar) == 0\n\n\nasync def test_cookie_jar_clear_domain() -> None:\n    sut = CookieJar()\n    cookie = SimpleCookie()\n    cookie[\"foo\"] = \"bar\"\n    cookie[\"domain_cookie\"] = \"value\"\n    cookie[\"domain_cookie\"][\"domain\"] = \"example.com\"\n    cookie[\"subdomain_cookie\"] = \"value\"\n    cookie[\"subdomain_cookie\"][\"domain\"] = \"test.example.com\"\n    sut.update_cookies(cookie)\n\n    sut.clear_domain(\"example.com\")\n    iterator = iter(sut)\n    morsel = next(iterator)\n    assert morsel.key == \"foo\"\n    assert morsel.value == \"bar\"\n    with pytest.raises(StopIteration):\n        next(iterator)\n\n\ndef test_pickle_format(cookies_to_send) -> None:\n    \"\"\"Test if cookiejar pickle format breaks.\n\n    If this test fails, it may indicate that saved cookiejars will stop working.\n    If that happens then:\n        1. Avoid releasing the change in a bugfix release.\n        2. Try to include a migration script in the release notes (example below).\n        3. Use dump_cookiejar() at the top of this file to update `pickled`.\n\n    Depending on the changes made, a migration script might look like:\n        import pickle\n        with file_path.open(\"rb\") as f:\n            cookies = pickle.load(f)\n\n        morsels = [(name, m) for c in cookies.values() for name, m in c.items()]\n        cookies.clear()\n        for name, m in morsels:\n            cookies[(m[\"domain\"], m[\"path\"])][name] = m\n\n        with file_path.open(\"wb\") as f:\n            pickle.dump(cookies, f, pickle.HIGHEST_PROTOCOL)\n    \"\"\"\n    pickled = b\"\\x80\\x04\\x95\\xc8\\x0b\\x00\\x00\\x00\\x00\\x00\\x00\\x8c\\x0bcollections\\x94\\x8c\\x0bdefaultdict\\x94\\x93\\x94\\x8c\\x0chttp.cookies\\x94\\x8c\\x0cSimpleCookie\\x94\\x93\\x94\\x85\\x94R\\x94(\\x8c\\x00\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\rshared-cookie\\x94h\\x03\\x8c\\x06Morsel\\x94\\x93\\x94)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94\\x8c\\x01/\\x94\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\x08\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(\\x8c\\x03key\\x94h\\x0b\\x8c\\x05value\\x94\\x8c\\x05first\\x94\\x8c\\x0bcoded_value\\x94h\\x1cubs\\x8c\\x0bexample.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94(\\x8c\\rdomain-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\x1e\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah!h\\x1b\\x8c\\x06second\\x94h\\x1dh-ub\\x8c\\x14dotted-domain-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94\\x8c\\x0bexample.com\\x94\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah.h\\x1b\\x8c\\x05fifth\\x94h\\x1dh;ubu\\x8c\\x11test1.example.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\x11subdomain1-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h<\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah?h\\x1b\\x8c\\x05third\\x94h\\x1dhKubs\\x8c\\x11test2.example.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\x11subdomain2-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94hL\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ahOh\\x1b\\x8c\\x06fourth\\x94h\\x1dh[ubs\\x8c\\rdifferent.org\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\x17different-domain-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\\\\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah_h\\x1b\\x8c\\x05sixth\\x94h\\x1dhkubs\\x8c\\nsecure.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\rsecure-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94hl\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94\\x88\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ahoh\\x1b\\x8c\\x07seventh\\x94h\\x1dh{ubs\\x8c\\x0cpathtest.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94(\\x8c\\x0eno-path-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h|\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\x7fh\\x1b\\x8c\\x06eighth\\x94h\\x1dh\\x8bub\\x8c\\x0cpath1-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94\\x8c\\x0cpathtest.com\\x94\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\x8ch\\x1b\\x8c\\x05ninth\\x94h\\x1dh\\x99ubu\\x8c\\x0cpathtest.com\\x94\\x8c\\x04/one\\x94\\x86\\x94h\\x05)\\x81\\x94\\x8c\\x0cpath2-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x9b\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\x9a\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\x9eh\\x1b\\x8c\\x05tenth\\x94h\\x1dh\\xaaubs\\x8c\\x0cpathtest.com\\x94\\x8c\\x08/one/two\\x94\\x86\\x94h\\x05)\\x81\\x94(\\x8c\\x0cpath3-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\xac\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\xab\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\xafh\\x1b\\x8c\\x08eleventh\\x94h\\x1dh\\xbbub\\x8c\\x0cpath4-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94\\x8c\\t/one/two/\\x94\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94\\x8c\\x0cpathtest.com\\x94\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\xbch\\x1b\\x8c\\x07twelfth\\x94h\\x1dh\\xcaubu\\x8c\\x0fexpirestest.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\x0eexpires-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94\\x8c\\x1cTue, 1 Jan 2999 12:00:00 GMT\\x94\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\xcb\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\xceh\\x1b\\x8c\\nthirteenth\\x94h\\x1dh\\xdbubs\\x8c\\x0emaxagetest.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94\\x8c\\x0emax-age-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\xdc\\x8c\\x07max-age\\x94\\x8c\\x0260\\x94\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\xdfh\\x1b\\x8c\\nfourteenth\\x94h\\x1dh\\xecubs\\x8c\\x12invalid-values.com\\x94h\\x08\\x86\\x94h\\x05)\\x81\\x94(\\x8c\\x16invalid-max-age-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94h\\xed\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\xf0h\\x1b\\x8c\\tfifteenth\\x94h\\x1dh\\xfcub\\x8c\\x16invalid-expires-cookie\\x94h\\r)\\x81\\x94(\\x8c\\x07expires\\x94h\\x08\\x8c\\x04path\\x94h\\x11\\x8c\\x07comment\\x94h\\x08\\x8c\\x06domain\\x94\\x8c\\x12invalid-values.com\\x94\\x8c\\x07max-age\\x94h\\x08\\x8c\\x06secure\\x94h\\x08\\x8c\\x08httponly\\x94h\\x08\\x8c\\x07version\\x94h\\x08\\x8c\\x08samesite\\x94h\\x08u}\\x94(h\\x1ah\\xfdh\\x1b\\x8c\\tsixteenth\\x94h\\x1dj\\n\\x01\\x00\\x00ubuu.\"\n    cookies = pickle.loads(pickled)\n\n    cj = CookieJar()\n    cj.update_cookies(cookies_to_send)\n\n    assert cookies == cj._cookies\n\n\n@pytest.mark.parametrize(\n    \"url\",\n    [\n        \"http://127.0.0.1/index.html\",\n        URL(\"http://127.0.0.1/index.html\"),\n        [\"http://127.0.0.1/index.html\"],\n        [URL(\"http://127.0.0.1/index.html\")],\n    ],\n)\nasync def test_treat_as_secure_origin_init(url) -> None:\n    jar = CookieJar(unsafe=True, treat_as_secure_origin=url)\n    assert jar._treat_as_secure_origin == [URL(\"http://127.0.0.1\")]\n\n\nasync def test_treat_as_secure_origin() -> None:\n    endpoint = URL(\"http://127.0.0.1/\")\n\n    jar = CookieJar(unsafe=True, treat_as_secure_origin=[endpoint])\n    secure_cookie = SimpleCookie(\n        \"cookie-key=cookie-value; HttpOnly; Path=/; Secure\",\n    )\n\n    jar.update_cookies(\n        secure_cookie,\n        endpoint,\n    )\n\n    assert len(jar) == 1\n    filtered_cookies = jar.filter_cookies(request_url=endpoint)\n    assert len(filtered_cookies) == 1\n",
        "# type: ignore\nimport asyncio\nimport os\nimport socket\nimport ssl\nimport sys\nfrom hashlib import md5, sha256\nfrom pathlib import Path\nfrom tempfile import TemporaryDirectory\nfrom typing import Any, List\nfrom unittest import mock\nfrom uuid import uuid4\n\nimport pytest\n\nfrom aiohttp.test_utils import loop_context\n\ntry:\n    import trustme\n\n    # Check if the CA is available in runtime, MacOS on Py3.10 fails somehow\n    trustme.CA()\n\n    TRUSTME: bool = True\nexcept ImportError:\n    TRUSTME = False\n\npytest_plugins: List[str] = [\"aiohttp.pytest_plugin\", \"pytester\"]\n\nIS_HPUX = sys.platform.startswith(\"hp-ux\")\nIS_LINUX = sys.platform.startswith(\"linux\")\n\n\n@pytest.fixture\ndef tls_certificate_authority() -> Any:\n    if not TRUSTME:\n        pytest.xfail(\"trustme is not supported\")\n    return trustme.CA()\n\n\n@pytest.fixture\ndef tls_certificate(tls_certificate_authority: Any) -> Any:\n    return tls_certificate_authority.issue_cert(\n        \"localhost\",\n        \"xn--prklad-4va.localhost\",\n        \"127.0.0.1\",\n        \"::1\",\n    )\n\n\n@pytest.fixture\ndef ssl_ctx(tls_certificate: Any) -> ssl.SSLContext:\n    ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)\n    tls_certificate.configure_cert(ssl_ctx)\n    return ssl_ctx\n\n\n@pytest.fixture\ndef client_ssl_ctx(tls_certificate_authority: Any) -> ssl.SSLContext:\n    ssl_ctx = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH)\n    tls_certificate_authority.configure_trust(ssl_ctx)\n    return ssl_ctx\n\n\n@pytest.fixture\ndef tls_ca_certificate_pem_path(tls_certificate_authority: Any) -> None:\n    with tls_certificate_authority.cert_pem.tempfile() as ca_cert_pem:\n        yield ca_cert_pem\n\n\n@pytest.fixture\ndef tls_certificate_pem_path(tls_certificate: Any) -> None:\n    with tls_certificate.private_key_and_cert_chain_pem.tempfile() as cert_pem:\n        yield cert_pem\n\n\n@pytest.fixture\ndef tls_certificate_pem_bytes(tls_certificate: Any) -> bytes:\n    return tls_certificate.cert_chain_pems[0].bytes()\n\n\n@pytest.fixture\ndef tls_certificate_fingerprint_sha256(tls_certificate_pem_bytes: Any) -> str:\n    tls_cert_der = ssl.PEM_cert_to_DER_cert(tls_certificate_pem_bytes.decode())\n    return sha256(tls_cert_der).digest()\n\n\n@pytest.fixture\ndef pipe_name() -> str:\n    name = rf\"\\\\.\\pipe\\{uuid4().hex}\"\n    return name\n\n\n@pytest.fixture\ndef create_mocked_conn(loop: Any):\n    def _proto_factory(conn_closing_result=None, **kwargs):\n        proto = mock.Mock(**kwargs)\n        proto.closed = loop.create_future()\n        proto.closed.set_result(conn_closing_result)\n        return proto\n\n    yield _proto_factory\n\n\n@pytest.fixture\ndef unix_sockname(tmp_path: Any, tmp_path_factory: Any):\n    # Generate an fs path to the UNIX domain socket for testing.\n\n    # N.B. Different OS kernels have different fs path length limitations\n    # for it. For Linux, it's 108, for HP-UX it's 92 (or higher) depending\n    # on its version. For most of the BSDs (Open, Free, macOS) it's\n    # mostly 104 but sometimes it can be down to 100.\n\n    # Ref: https://github.com/aio-libs/aiohttp/issues/3572\n    if not hasattr(socket, \"AF_UNIX\"):\n        pytest.skip(\"requires UNIX sockets\")\n\n    max_sock_len = 92 if IS_HPUX else 108 if IS_LINUX else 100\n    # Amount of bytes allocated for the UNIX socket path by OS kernel.\n    # Ref: https://unix.stackexchange.com/a/367012/27133\n\n    sock_file_name = \"unix.sock\"\n    unique_prefix = f\"{uuid4()!s}-\"\n    unique_prefix_len = len(unique_prefix.encode())\n\n    root_tmp_dir = Path(\"/tmp\").resolve()\n    os_tmp_dir = Path(os.getenv(\"TMPDIR\", \"/tmp\")).resolve()\n    original_base_tmp_path = Path(\n        str(tmp_path_factory.getbasetemp()),\n    ).resolve()\n\n    original_base_tmp_path_hash = md5(\n        str(original_base_tmp_path).encode(),\n    ).hexdigest()\n\n    def make_tmp_dir(base_tmp_dir):\n        return TemporaryDirectory(\n            dir=str(base_tmp_dir),\n            prefix=\"pt-\",\n            suffix=f\"-{original_base_tmp_path_hash!s}\",\n        )\n\n    def assert_sock_fits(sock_path):\n        sock_path_len = len(sock_path.encode())\n        # exit-check to verify that it's correct and simplify debugging\n        # in the future\n        assert sock_path_len <= max_sock_len, (\n            \"Suggested UNIX socket ({sock_path}) is {sock_path_len} bytes \"\n            \"long but the current kernel only has {max_sock_len} bytes \"\n            \"allocated to hold it so it must be shorter. \"\n            \"See https://github.com/aio-libs/aiohttp/issues/3572 \"\n            \"for more info.\"\n        ).format_map(locals())\n\n    paths = original_base_tmp_path, os_tmp_dir, root_tmp_dir\n    unique_paths = [p for n, p in enumerate(paths) if p not in paths[:n]]\n    paths_num = len(unique_paths)\n\n    for num, tmp_dir_path in enumerate(paths, 1):\n        with make_tmp_dir(tmp_dir_path) as tmpd:\n            tmpd = Path(tmpd).resolve()\n            sock_path = str(tmpd / sock_file_name)\n            sock_path_len = len(sock_path.encode())\n\n            if num >= paths_num:\n                # exit-check to verify that it's correct and simplify\n                # debugging in the future\n                assert_sock_fits(sock_path)\n\n            if sock_path_len <= max_sock_len:\n                if max_sock_len - sock_path_len >= unique_prefix_len:\n                    # If we're lucky to have extra space in the path,\n                    # let's also make it more unique\n                    sock_path = str(tmpd / \"\".join((unique_prefix, sock_file_name)))\n                    # Double-checking it:\n                    assert_sock_fits(sock_path)\n                yield sock_path\n                return\n\n\n@pytest.fixture\ndef selector_loop() -> None:\n    policy = asyncio.WindowsSelectorEventLoopPolicy()\n    asyncio.set_event_loop_policy(policy)\n\n    with loop_context(policy.new_event_loop) as _loop:\n        asyncio.set_event_loop(_loop)\n        yield _loop\n\n\n@pytest.fixture\ndef netrc_contents(\n    tmp_path: Path,\n    monkeypatch: pytest.MonkeyPatch,\n    request: pytest.FixtureRequest,\n):\n    \"\"\"\n    Prepare :file:`.netrc` with given contents.\n\n    Monkey-patches :envvar:`NETRC` to point to created file.\n    \"\"\"\n    netrc_contents = getattr(request, \"param\", None)\n\n    netrc_file_path = tmp_path / \".netrc\"\n    if netrc_contents is not None:\n        netrc_file_path.write_text(netrc_contents)\n\n    monkeypatch.setenv(\"NETRC\", str(netrc_file_path))\n\n    return netrc_file_path\n\n\n@pytest.fixture\ndef start_connection():\n    with mock.patch(\n        \"aiohttp.connector.aiohappyeyeballs.start_connection\",\n        autospec=True,\n        spec_set=True,\n    ) as start_connection_mock:\n        yield start_connection_mock\n"
    ],
    "test_file_names": [
        "test_1.py",
        "conftest.py"
    ],
    "setup_res_code": 0,
    "setup_res_stdout": "re-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/requirements/cython.txt\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/tools/gen.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/hdrs.py\n./tools/gen.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/_helpers.pyx\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/_http_parser.pyx\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/_http_writer.pyx\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/_websocket.pyx\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/_helpers.pyi\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/_cparser.pxd\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/_find_header.pxd\ncython -3 -o aiohttp/_helpers.c aiohttp/_helpers.pyx -I aiohttp -Werror\ncython -3 -o aiohttp/_http_parser.c aiohttp/_http_parser.pyx -I aiohttp -Werror\ncython -3 -o aiohttp/_http_writer.c aiohttp/_http_writer.pyx -I aiohttp -Werror\ncython -3 -o aiohttp/_websocket.c aiohttp/_websocket.pyx -I aiohttp -Werror\ncd vendor/llhttp; npm install\n\n> llhttp@9.1.3 prepare\n> npm run clean && npm run build-ts\n\n\n> llhttp@9.1.3 clean\n> rm -rf lib && rm -rf test/tmp\n\n\n> llhttp@9.1.3 build-ts\n> tsc\n\n\nadded 157 packages, and audited 158 packages in 4s\n\n23 packages are looking for funding\n  run `npm fund` for details\n\n5 vulnerabilities (4 moderate, 1 high)\n\nTo address issues that do not require attention, run:\n  npm audit fix\n\nSome issues need review, and may require choosing\na different dependency.\n\nRun `npm audit` for details.\nmake -C vendor/llhttp generate\nmake[1]: Entering directory '/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/vendor/llhttp'\nnpx ts-node bin/generate.ts\nmake[1]: Leaving directory '/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/vendor/llhttp'\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/__init__.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/abc.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/base_protocol.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/client.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/client_exceptions.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/client_proto.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/client_reqrep.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/client_ws.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/compression_utils.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/connector.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/cookiejar.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/formdata.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/helpers.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/http.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/http_exceptions.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/http_parser.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/http_websocket.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/http_writer.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/locks.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/log.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/multipart.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/payload.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/pytest_plugin.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/resolver.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/streams.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/tcp_helpers.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/test_utils.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/tracing.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/typedefs.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/web.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/web_app.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/web_exceptions.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/web_fileresponse.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/web_log.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/web_middlewares.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/web_protocol.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/web_request.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/web_response.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/web_routedef.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/web_runner.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/web_server.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/web_urldispatcher.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/web_ws.py\nre-hash /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/worker.py\nuv pip install -e . -c requirements/runtime-deps.txt\n",
    "setup_res_stderr": "Using CPython 3.9.21\nCreating virtual environment at: .venv\nActivate with: source .venv/bin/activate\nResolved 1 package in 48ms\nPrepared 1 package in 0.94ms\nInstalled 1 package in 20ms\n + pip==24.3.1\nResolved 3 packages in 13ms\nInstalled 3 packages in 27ms\n + cython==3.0.8\n + multidict==6.0.4\n + typing-extensions==4.9.0\nResolved 93 packages in 39ms\nUninstalled 1 package in 6ms\nInstalled 91 packages in 68ms\n + aiodns==3.1.1\n + aiohappyeyeballs==2.3.2\n + aiohttp-theme==0.1.6\n + aioredis==2.0.1\n + aiosignal==1.3.1\n + alabaster==0.7.13\n + async-timeout==4.0.3\n + babel==2.12.1\n + blockdiag==3.0.0\n + brotli==1.1.0\n + build==0.10.0\n + certifi==2023.7.22\n + cffi==1.15.1\n + cfgv==3.3.1\n + charset-normalizer==3.2.0\n + cherry-picker==2.2.0\n + click==8.1.6\n + coverage==7.4.0\n + cryptography==41.0.3\n + distlib==0.3.7\n + docutils==0.20.1\n + exceptiongroup==1.1.2\n + filelock==3.12.2\n + freezegun==1.4.0\n + frozenlist==1.4.1\n + funcparserlib==1.0.1\n + gidgethub==5.3.0\n + gunicorn==21.2.0\n + identify==2.5.26\n + idna==3.4\n + imagesize==1.4.1\n + importlib-metadata==7.0.0\n + importlib-resources==6.1.1\n + incremental==22.10.0\n + iniconfig==2.0.0\n + jinja2==3.1.2\n + markupsafe==2.1.3\n + mypy==1.8.0\n + mypy-extensions==1.0.0\n + nodeenv==1.8.0\n + packaging==23.1\n + pillow==9.5.0\n - pip==24.3.1\n + pip==23.2.1\n + pip-tools==7.3.0\n + platformdirs==3.10.0\n + pluggy==1.2.0\n + pre-commit==3.5.0\n + proxy-py==2.4.4rc4\n + pycares==4.3.0\n + pycparser==2.21\n + pydantic==1.10.12\n + pygments==2.15.1\n + pyjwt==2.8.0\n + pyproject-hooks==1.0.0\n + pytest==7.4.4\n + pytest-cov==4.1.0\n + pytest-mock==3.12.0\n + python-dateutil==2.8.2\n + python-on-whales==0.68.0\n + pyyaml==6.0.1\n + re-assert==1.1.0\n + regex==2023.6.3\n + requests==2.31.0\n + setuptools==68.0.0\n + setuptools-git==1.2\n + six==1.16.0\n + slotscheck==0.17.1\n + snowballstemmer==2.2.0\n + sphinx==7.1.2\n + sphinxcontrib-applehelp==1.0.4\n + sphinxcontrib-blockdiag==3.0.0\n + sphinxcontrib-devhelp==1.0.2\n + sphinxcontrib-htmlhelp==2.0.1\n + sphinxcontrib-jsmath==1.0.1\n + sphinxcontrib-qthelp==1.0.3\n + sphinxcontrib-serializinghtml==1.1.5\n + sphinxcontrib-towncrier==0.4.0a0\n + tomli==2.0.1\n + towncrier==23.11.0\n + tqdm==4.65.0\n + trustme==1.1.0\n + typer==0.9.0\n + uritemplate==4.1.1\n + urllib3==2.0.4\n + uvloop==0.19.0\n + virtualenv==20.24.2\n + wait-for-it==2.2.2\n + webcolors==1.13\n + wheel==0.41.0\n + yarl==1.9.4\n + zipp==3.17.0\nResolved 8 packages in 1.25s\nPrepared 1 package in 15.98s\nInstalled 1 package in 0.75ms\n + aiohttp==4.0.0a2.dev0 (from file:///home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5)\nResolved 24 packages in 15ms\nInstalled 5 packages in 5ms\n + async-generator==1.10\n + brotlipy==0.7.0\n + chardet==5.2.0\n + multdict==0.0.5\n + pytest-asyncio==0.23.8\n",
    "new_commit_res_code": 0,
    "new_commit_res_stdout": "============================= test session starts ==============================\nplatform linux -- Python 3.9.21, pytest-7.4.4, pluggy-1.2.0 -- /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/.venv/bin/python\ncachedir: .pytest_cache\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5\nconfigfile: setup.cfg\nplugins: mock-3.12.0, asyncio-0.23.8, cov-4.1.0\nasyncio: mode=strict\ncollecting ... collected 52 items\n\nr2e_tests/test_1.py::test_date_parsing PASSED                            [  1%]\nr2e_tests/test_1.py::test_domain_matching PASSED                         [  3%]\nr2e_tests/test_1.py::test_constructor PASSED                             [  5%]\nr2e_tests/test_1.py::test_constructor_with_expired PASSED                [  7%]\nr2e_tests/test_1.py::test_save_load[pyloop] PASSED                       [  9%]\nr2e_tests/test_1.py::test_update_cookie_with_unicode_domain[pyloop] PASSED [ 11%]\nr2e_tests/test_1.py::test_filter_cookie_with_unicode_domain[pyloop] PASSED [ 13%]\nr2e_tests/test_1.py::test_filter_cookies_str_deprecated[pyloop] PASSED   [ 15%]\nr2e_tests/test_1.py::test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://pathtest.com/one/two/-expected_cookies0] PASSED [ 17%]\nr2e_tests/test_1.py::test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://pathtest.com/one/two-expected_cookies1] PASSED [ 19%]\nr2e_tests/test_1.py::test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://pathtest.com/one/two/three/-expected_cookies2] PASSED [ 21%]\nr2e_tests/test_1.py::test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://test1.example.com/-expected_cookies3] PASSED [ 23%]\nr2e_tests/test_1.py::test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://pathtest.com/-expected_cookies4] PASSED [ 25%]\nr2e_tests/test_1.py::test_domain_filter_ip_cookie_send[pyloop] PASSED    [ 26%]\nr2e_tests/test_1.py::test_domain_filter_ip_cookie_receive PASSED         [ 28%]\nr2e_tests/test_1.py::test_quotes_correctly_based_on_input[pyloop-IP domain preserved] PASSED [ 30%]\nr2e_tests/test_1.py::test_quotes_correctly_based_on_input[pyloop-no shared cookie] PASSED [ 32%]\nr2e_tests/test_1.py::test_quotes_correctly_based_on_input[pyloop-quoted cookie with special char] PASSED [ 34%]\nr2e_tests/test_1.py::test_quotes_correctly_based_on_input[pyloop-quoted cookie w/o special char] PASSED [ 36%]\nr2e_tests/test_1.py::test_quotes_correctly_based_on_input[pyloop-unquoted cookie with special char] PASSED [ 38%]\nr2e_tests/test_1.py::test_ignore_domain_ending_with_dot[pyloop] PASSED   [ 40%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_cookie_not_expired_when_added_after_removal PASSED [ 42%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_domain_filter_diff_host PASSED [ 44%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_domain_filter_host_only PASSED [ 46%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_domain_filter_same_host PASSED [ 48%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_domain_filter_same_host_and_subdomain PASSED [ 50%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_domain_filter_same_host_diff_subdomain PASSED [ 51%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_expires PASSED              [ 53%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_invalid_values PASSED       [ 55%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_max_age PASSED              [ 57%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_diff_folder_same_name PASSED [ 59%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_diff_folder_same_name_return_best_match_independent_from_put_order PASSED [ 61%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_different_folder PASSED [ 63%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_file PASSED     [ 65%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_folder PASSED   [ 67%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_root PASSED     [ 69%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_subfolder PASSED [ 71%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_subsubfolder PASSED [ 73%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_path_value PASSED           [ 75%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_secure_filter PASSED        [ 76%]\nr2e_tests/test_1.py::test_dummy_cookie_jar PASSED                        [ 78%]\nr2e_tests/test_1.py::test_loose_cookies_types PASSED                     [ 80%]\nr2e_tests/test_1.py::test_cookie_jar_clear_all PASSED                    [ 82%]\nr2e_tests/test_1.py::test_cookie_jar_clear_expired PASSED                [ 84%]\nr2e_tests/test_1.py::test_cookie_jar_filter_cookies_expires PASSED       [ 86%]\nr2e_tests/test_1.py::test_cookie_jar_clear_domain PASSED                 [ 88%]\nr2e_tests/test_1.py::test_pickle_format PASSED                           [ 90%]\nr2e_tests/test_1.py::test_treat_as_secure_origin_init[http://127.0.0.1/index.html] PASSED [ 92%]\nr2e_tests/test_1.py::test_treat_as_secure_origin_init[url1] PASSED       [ 94%]\nr2e_tests/test_1.py::test_treat_as_secure_origin_init[url2] PASSED       [ 96%]\nr2e_tests/test_1.py::test_treat_as_secure_origin_init[url3] PASSED       [ 98%]\nr2e_tests/test_1.py::test_treat_as_secure_origin PASSED                  [100%]\n\n==================================== PASSES ====================================\n\n---------- coverage: platform linux, python 3.9.21-final-0 -----------\nName                                     Stmts   Miss Branch BrPart  Cover\n--------------------------------------------------------------------------\naiohttp/__init__.py                         26      2      2      0    93%\naiohttp/abc.py                              89      7      0      0    92%\naiohttp/base_protocol.py                    66     51     22      0    17%\naiohttp/client.py                          479    365    178      1    18%\naiohttp/client_exceptions.py               122     51     10      0    54%\naiohttp/client_proto.py                    153    124     56      0    14%\naiohttp/client_reqrep.py                   647    480    272      0    19%\naiohttp/client_ws.py                       215    167     68      1    18%\naiohttp/compression_utils.py                70     36     14      0    40%\naiohttp/connector.py                       697    580    303      0    12%\naiohttp/cookiejar.py                       252      6    124      1    98%\naiohttp/formdata.py                         94     77     46      0    12%\naiohttp/hdrs.py                             90      0      0      0   100%\naiohttp/helpers.py                         556    357    200      3    29%\naiohttp/http.py                              8      0      0      0   100%\naiohttp/http_exceptions.py                  50     20      4      0    56%\naiohttp/http_parser.py                     494    396    200      1    14%\naiohttp/http_websocket.py                  380    286    152      0    18%\naiohttp/http_writer.py                     118     81     50      1    23%\naiohttp/locks.py                            24     16      4      0    29%\naiohttp/log.py                               7      0      0      0   100%\naiohttp/multipart.py                       593    486    250      0    13%\naiohttp/payload.py                         219    107     56      1    43%\naiohttp/pytest_plugin.py                   159     73     42      5    52%\naiohttp/resolver.py                         50     32     14      0    28%\naiohttp/streams.py                         392    309    140      0    16%\naiohttp/tcp_helpers.py                      19     11      6      0    32%\naiohttp/test_utils.py                      298    186     54      2    32%\naiohttp/tracing.py                         191     69     32      0    69%\naiohttp/typedefs.py                         23      0      0      0   100%\naiohttp/web.py                             137     97     54      0    22%\naiohttp/web_app.py                         253    156     50      0    33%\naiohttp/web_exceptions.py                  214     37     26      6    79%\naiohttp/web_fileresponse.py                144    120     48      0    12%\naiohttp/web_log.py                         102     58     20      0    36%\naiohttp/web_middlewares.py                  54     40     20      0    19%\naiohttp/web_protocol.py                    352    289    157      0    13%\naiohttp/web_request.py                     449    305    138      0    25%\naiohttp/web_response.py                    439    332    190      0    17%\naiohttp/web_routedef.py                    106     46     10      0    55%\naiohttp/web_runner.py                      223    134     42      0    34%\naiohttp/web_server.py                       43     24     10      0    36%\naiohttp/web_urldispatcher.py               717    458    163      0    29%\naiohttp/web_ws.py                          332    266    116      1    15%\naiohttp/worker.py                          123     90     30      0    22%\ntests/conftest.py                          119    119     16      0     0%\ntests/test_base_protocol.py                198    198      2      0     0%\ntests/test_circular_imports.py              29     29     13      0     0%\ntests/test_classbasedview.py                39     39      0      0     0%\ntests/test_client_connection.py             93     93      2      0     0%\ntests/test_client_exceptions.py            165    165     14      0     0%\ntests/test_client_fingerprint.py            24     24      0      0     0%\ntests/test_client_functional.py           2370   2370     76      0     0%\ntests/test_client_proto.py                 100    100      0      0     0%\ntests/test_client_request.py               739    739     18      0     0%\ntests/test_client_response.py              461    461      4      0     0%\ntests/test_client_session.py               451    451     23      0     0%\ntests/test_client_ws.py                    416    416      2      0     0%\ntests/test_client_ws_functional.py         645    645     16      0     0%\ntests/test_connector.py                   1646   1646     88      0     0%\ntests/test_cookiejar.py                    358    358     24      0     0%\ntests/test_flowcontrol_streams.py          101    101      0      0     0%\ntests/test_formdata.py                      77     77      6      0     0%\ntests/test_helpers.py                      541    541     22      0     0%\ntests/test_http_exceptions.py              109    109     10      0     0%\ntests/test_http_parser.py                  963    963     50      0     0%\ntests/test_http_writer.py                  183    183     10      0     0%\ntests/test_imports.py                       31     31      6      0     0%\ntests/test_locks.py                         40     40      0      0     0%\ntests/test_loop.py                          36     36      0      0     0%\ntests/test_multipart.py                    771    771     28      0     0%\ntests/test_multipart_helpers.py            446    446      0      0     0%\ntests/test_payload.py                       79     79      0      0     0%\ntests/test_proxy.py                        299    299      0      0     0%\ntests/test_proxy_functional.py             465    465     18      0     0%\ntests/test_pytest_plugin.py                 47     47      0      0     0%\ntests/test_resolver.py                     127    127     10      0     0%\ntests/test_route_def.py                    211    211      0      0     0%\ntests/test_run_app.py                      522    522     30      0     0%\ntests/test_streams.py                     1058   1058     40      0     0%\ntests/test_tcp_helpers.py                   52     52      2      0     0%\ntests/test_test_utils.py                   231    231      6      0     0%\ntests/test_tracing.py                       49     49      0      0     0%\ntests/test_urldispatch.py                  852    852     24      0     0%\ntests/test_web_app.py                      383    383      6      0     0%\ntests/test_web_cli.py                       76     76      0      0     0%\ntests/test_web_exceptions.py               274    274     30      0     0%\ntests/test_web_functional.py              1500   1500     32      0     0%\ntests/test_web_log.py                      143    143      2      0     0%\ntests/test_web_middleware.py               230    230      2      0     0%\ntests/test_web_request.py                  543    543      8      0     0%\ntests/test_web_request_handler.py           40     40      0      0     0%\ntests/test_web_response.py                 813    813      4      0     0%\ntests/test_web_runner.py                   177    177      4      0     0%\ntests/test_web_sendfile.py                  77     77      0      0     0%\ntests/test_web_sendfile_functional.py      652    652     18      0     0%\ntests/test_web_server.py                   178    178      0      0     0%\ntests/test_web_urldispatcher.py            335    335     14      0     0%\ntests/test_web_websocket.py                316    316      8      0     0%\ntests/test_web_websocket_functional.py     573    573     20      0     0%\ntests/test_websocket_handshake.py          153    153     12      0     0%\ntests/test_websocket_parser.py             293    293     12      0     0%\ntests/test_websocket_writer.py              95     95      6      0     0%\ntests/test_worker.py                       190    190      2      0     0%\n--------------------------------------------------------------------------\nTOTAL                                    32453  29011   4113     23    10%\n\n============================= slowest 10 durations =============================\n0.07s call     r2e_tests/test_1.py::TestCookieJarSafe::test_expires\n0.06s call     r2e_tests/test_1.py::test_update_cookie_with_unicode_domain[pyloop]\n0.03s call     r2e_tests/test_1.py::test_cookie_jar_clear_expired\n0.02s call     r2e_tests/test_1.py::TestCookieJarSafe::test_max_age\n0.02s call     r2e_tests/test_1.py::test_cookie_jar_filter_cookies_expires\n0.02s call     r2e_tests/test_1.py::test_dummy_cookie_jar\n0.02s call     r2e_tests/test_1.py::test_constructor\n0.02s teardown r2e_tests/test_1.py::test_update_cookie_with_unicode_domain[pyloop]\n0.01s call     r2e_tests/test_1.py::test_loose_cookies_types\n0.01s call     r2e_tests/test_1.py::test_cookie_jar_clear_all\n=========================== short test summary info ============================\nPASSED r2e_tests/test_1.py::test_date_parsing\nPASSED r2e_tests/test_1.py::test_domain_matching\nPASSED r2e_tests/test_1.py::test_constructor\nPASSED r2e_tests/test_1.py::test_constructor_with_expired\nPASSED r2e_tests/test_1.py::test_save_load[pyloop]\nPASSED r2e_tests/test_1.py::test_update_cookie_with_unicode_domain[pyloop]\nPASSED r2e_tests/test_1.py::test_filter_cookie_with_unicode_domain[pyloop]\nPASSED r2e_tests/test_1.py::test_filter_cookies_str_deprecated[pyloop]\nPASSED r2e_tests/test_1.py::test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://pathtest.com/one/two/-expected_cookies0]\nPASSED r2e_tests/test_1.py::test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://pathtest.com/one/two-expected_cookies1]\nPASSED r2e_tests/test_1.py::test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://pathtest.com/one/two/three/-expected_cookies2]\nPASSED r2e_tests/test_1.py::test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://test1.example.com/-expected_cookies3]\nPASSED r2e_tests/test_1.py::test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://pathtest.com/-expected_cookies4]\nPASSED r2e_tests/test_1.py::test_domain_filter_ip_cookie_send[pyloop]\nPASSED r2e_tests/test_1.py::test_domain_filter_ip_cookie_receive\nPASSED r2e_tests/test_1.py::test_quotes_correctly_based_on_input[pyloop-IP domain preserved]\nPASSED r2e_tests/test_1.py::test_quotes_correctly_based_on_input[pyloop-no shared cookie]\nPASSED r2e_tests/test_1.py::test_quotes_correctly_based_on_input[pyloop-quoted cookie with special char]\nPASSED r2e_tests/test_1.py::test_quotes_correctly_based_on_input[pyloop-quoted cookie w/o special char]\nPASSED r2e_tests/test_1.py::test_quotes_correctly_based_on_input[pyloop-unquoted cookie with special char]\nPASSED r2e_tests/test_1.py::test_ignore_domain_ending_with_dot[pyloop]\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_cookie_not_expired_when_added_after_removal\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_domain_filter_diff_host\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_domain_filter_host_only\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_domain_filter_same_host\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_domain_filter_same_host_and_subdomain\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_domain_filter_same_host_diff_subdomain\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_expires\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_invalid_values\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_max_age\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_diff_folder_same_name\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_diff_folder_same_name_return_best_match_independent_from_put_order\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_different_folder\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_file\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_folder\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_root\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_subfolder\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_subsubfolder\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_path_value\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_secure_filter\nPASSED r2e_tests/test_1.py::test_dummy_cookie_jar\nPASSED r2e_tests/test_1.py::test_loose_cookies_types\nPASSED r2e_tests/test_1.py::test_cookie_jar_clear_all\nPASSED r2e_tests/test_1.py::test_cookie_jar_clear_expired\nPASSED r2e_tests/test_1.py::test_cookie_jar_filter_cookies_expires\nPASSED r2e_tests/test_1.py::test_cookie_jar_clear_domain\nPASSED r2e_tests/test_1.py::test_pickle_format\nPASSED r2e_tests/test_1.py::test_treat_as_secure_origin_init[http://127.0.0.1/index.html]\nPASSED r2e_tests/test_1.py::test_treat_as_secure_origin_init[url1]\nPASSED r2e_tests/test_1.py::test_treat_as_secure_origin_init[url2]\nPASSED r2e_tests/test_1.py::test_treat_as_secure_origin_init[url3]\nPASSED r2e_tests/test_1.py::test_treat_as_secure_origin\n============================== 52 passed in 3.87s ==============================\n",
    "new_commit_res_stderr": "",
    "old_commit_res_code": 1,
    "old_commit_res_stdout": "============================= test session starts ==============================\nplatform linux -- Python 3.9.21, pytest-7.4.4, pluggy-1.2.0 -- /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/.venv/bin/python\ncachedir: .pytest_cache\nrootdir: /home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5\nconfigfile: setup.cfg\nplugins: mock-3.12.0, asyncio-0.23.8, cov-4.1.0\nasyncio: mode=strict\ncollecting ... collected 52 items\n\nr2e_tests/test_1.py::test_date_parsing PASSED                            [  1%]\nr2e_tests/test_1.py::test_domain_matching PASSED                         [  3%]\nr2e_tests/test_1.py::test_constructor PASSED                             [  5%]\nr2e_tests/test_1.py::test_constructor_with_expired PASSED                [  7%]\nr2e_tests/test_1.py::test_save_load[pyloop] PASSED                       [  9%]\nr2e_tests/test_1.py::test_update_cookie_with_unicode_domain[pyloop] PASSED [ 11%]\nr2e_tests/test_1.py::test_filter_cookie_with_unicode_domain[pyloop] PASSED [ 13%]\nr2e_tests/test_1.py::test_filter_cookies_str_deprecated[pyloop] PASSED   [ 15%]\nr2e_tests/test_1.py::test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://pathtest.com/one/two/-expected_cookies0] PASSED [ 17%]\nr2e_tests/test_1.py::test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://pathtest.com/one/two-expected_cookies1] PASSED [ 19%]\nr2e_tests/test_1.py::test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://pathtest.com/one/two/three/-expected_cookies2] PASSED [ 21%]\nr2e_tests/test_1.py::test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://test1.example.com/-expected_cookies3] PASSED [ 23%]\nr2e_tests/test_1.py::test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://pathtest.com/-expected_cookies4] PASSED [ 25%]\nr2e_tests/test_1.py::test_domain_filter_ip_cookie_send[pyloop] PASSED    [ 26%]\nr2e_tests/test_1.py::test_domain_filter_ip_cookie_receive PASSED         [ 28%]\nr2e_tests/test_1.py::test_quotes_correctly_based_on_input[pyloop-IP domain preserved] PASSED [ 30%]\nr2e_tests/test_1.py::test_quotes_correctly_based_on_input[pyloop-no shared cookie] PASSED [ 32%]\nr2e_tests/test_1.py::test_quotes_correctly_based_on_input[pyloop-quoted cookie with special char] PASSED [ 34%]\nr2e_tests/test_1.py::test_quotes_correctly_based_on_input[pyloop-quoted cookie w/o special char] PASSED [ 36%]\nr2e_tests/test_1.py::test_quotes_correctly_based_on_input[pyloop-unquoted cookie with special char] PASSED [ 38%]\nr2e_tests/test_1.py::test_ignore_domain_ending_with_dot[pyloop] PASSED   [ 40%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_cookie_not_expired_when_added_after_removal PASSED [ 42%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_domain_filter_diff_host PASSED [ 44%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_domain_filter_host_only PASSED [ 46%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_domain_filter_same_host PASSED [ 48%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_domain_filter_same_host_and_subdomain PASSED [ 50%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_domain_filter_same_host_diff_subdomain PASSED [ 51%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_expires PASSED              [ 53%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_invalid_values PASSED       [ 55%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_max_age PASSED              [ 57%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_diff_folder_same_name PASSED [ 59%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_diff_folder_same_name_return_best_match_independent_from_put_order PASSED [ 61%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_different_folder PASSED [ 63%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_file PASSED     [ 65%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_folder PASSED   [ 67%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_root PASSED     [ 69%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_subfolder PASSED [ 71%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_subsubfolder PASSED [ 73%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_path_value PASSED           [ 75%]\nr2e_tests/test_1.py::TestCookieJarSafe::test_secure_filter PASSED        [ 76%]\nr2e_tests/test_1.py::test_dummy_cookie_jar PASSED                        [ 78%]\nr2e_tests/test_1.py::test_loose_cookies_types PASSED                     [ 80%]\nr2e_tests/test_1.py::test_cookie_jar_clear_all PASSED                    [ 82%]\nr2e_tests/test_1.py::test_cookie_jar_clear_expired PASSED                [ 84%]\nr2e_tests/test_1.py::test_cookie_jar_filter_cookies_expires FAILED       [ 86%]\nr2e_tests/test_1.py::test_cookie_jar_clear_domain FAILED                 [ 88%]\nr2e_tests/test_1.py::test_pickle_format PASSED                           [ 90%]\nr2e_tests/test_1.py::test_treat_as_secure_origin_init[http://127.0.0.1/index.html] PASSED [ 92%]\nr2e_tests/test_1.py::test_treat_as_secure_origin_init[url1] PASSED       [ 94%]\nr2e_tests/test_1.py::test_treat_as_secure_origin_init[url2] PASSED       [ 96%]\nr2e_tests/test_1.py::test_treat_as_secure_origin_init[url3] PASSED       [ 98%]\nr2e_tests/test_1.py::test_treat_as_secure_origin PASSED                  [100%]\n\n=================================== FAILURES ===================================\n____________________ test_cookie_jar_filter_cookies_expires ____________________\n\n    async def test_cookie_jar_filter_cookies_expires():\n        \"\"\"Test that calling filter_cookies will expire stale cookies.\"\"\"\n        jar = CookieJar()\n        assert len(jar) == 0\n    \n        cookie = SimpleCookie()\n    \n        cookie[\"foo\"] = \"bar\"\n        cookie[\"foo\"][\"expires\"] = \"Tue, 1 Jan 1990 12:00:00 GMT\"\n    \n        with freeze_time(\"1980-01-01\"):\n            jar.update_cookies(cookie)\n    \n>       assert len(jar) == 1\nE       assert 0 == 1\nE        +  where 0 = len(<aiohttp.cookiejar.CookieJar object at 0x74534b300430>)\n\ncookie     = <SimpleCookie: foo='bar'>\njar        = <aiohttp.cookiejar.CookieJar object at 0x74534b300430>\n\nr2e_tests/test_1.py:880: AssertionError\n_________________________ test_cookie_jar_clear_domain _________________________\n\ncls = <class '_pytest.runner.CallInfo'>\nfunc = <function call_runtest_hook.<locals>.<lambda> at 0x74534b1d0f70>\nwhen = 'call'\nreraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)\n\n    @classmethod\n    def from_call(\n        cls,\n        func: \"Callable[[], TResult]\",\n        when: \"Literal['collect', 'setup', 'call', 'teardown']\",\n        reraise: Optional[\n            Union[Type[BaseException], Tuple[Type[BaseException], ...]]\n        ] = None,\n    ) -> \"CallInfo[TResult]\":\n        \"\"\"Call func, wrapping the result in a CallInfo.\n    \n        :param func:\n            The function to call. Called without arguments.\n        :param when:\n            The phase in which the function is called.\n        :param reraise:\n            Exception or exceptions that shall propagate if raised by the\n            function, instead of being wrapped in the CallInfo.\n        \"\"\"\n        excinfo = None\n        start = timing.time()\n        precise_start = timing.perf_counter()\n        try:\n>           result: Optional[TResult] = func()\n\ncls        = <class '_pytest.runner.CallInfo'>\nduration   = 0.020233509989338927\nexcinfo    = <ExceptionInfo PytestUnraisableExceptionWarning('Exception ignored in: <socket.socket fd=-1, family=AddressFamily.AF_U...arning: unclosed <socket.socket fd=14, family=AddressFamily.AF_UNIX, type=SocketKind.SOCK_STREAM, proto=0>\\n') tblen=7>\nfunc       = <function call_runtest_hook.<locals>.<lambda> at 0x74534b1d0f70>\nprecise_start = 94265.084724343\nprecise_stop = 94265.104957853\nreraise    = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)\nresult     = None\nstart      = 1735795908.703537\nstop       = 1735795908.7237718\nwhen       = 'call'\n\n.venv/lib/python3.9/site-packages/_pytest/runner.py:341: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n.venv/lib/python3.9/site-packages/_pytest/runner.py:262: in <lambda>\n    lambda: ihook(item=item, **kwds), when=when, reraise=reraise\n        ihook      = <_HookCaller 'pytest_runtest_call'>\n        item       = <Function test_cookie_jar_clear_domain>\n        kwds       = {}\n.venv/lib/python3.9/site-packages/pluggy/_hooks.py:433: in __call__\n    return self._hookexec(self.name, self._hookimpls, kwargs, firstresult)\n        firstresult = False\n        kwargs     = {'item': <Function test_cookie_jar_clear_domain>}\n        self       = <_HookCaller 'pytest_runtest_call'>\n.venv/lib/python3.9/site-packages/pluggy/_manager.py:112: in _hookexec\n    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)\n        firstresult = False\n        hook_name  = 'pytest_runtest_call'\n        kwargs     = {'item': <Function test_cookie_jar_clear_domain>}\n        methods    = [<HookImpl plugin_name='runner', plugin=<module '_pytest.runner' from '/home/gcpuser/buckets/local_repoeval_bucket/rep...http_e8339e7687a6c228076f788237b6dbe95ae711e5/.venv/lib/python3.9/site-packages/_pytest/unraisableexception.py'>>, ...]\n        self       = <_pytest.config.PytestPluginManager object at 0x74534df96b80>\n.venv/lib/python3.9/site-packages/_pytest/unraisableexception.py:88: in pytest_runtest_call\n    yield from unraisable_exception_runtest_hook()\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\n    def unraisable_exception_runtest_hook() -> Generator[None, None, None]:\n        with catch_unraisable_exception() as cm:\n            yield\n            if cm.unraisable:\n                if cm.unraisable.err_msg is not None:\n                    err_msg = cm.unraisable.err_msg\n                else:\n                    err_msg = \"Exception ignored in\"\n                msg = f\"{err_msg}: {cm.unraisable.object!r}\\n\\n\"\n                msg += \"\".join(\n                    traceback.format_exception(\n                        cm.unraisable.exc_type,\n                        cm.unraisable.exc_value,\n                        cm.unraisable.exc_traceback,\n                    )\n                )\n>               warnings.warn(pytest.PytestUnraisableExceptionWarning(msg))\nE               pytest.PytestUnraisableExceptionWarning: Exception ignored in: <socket.socket fd=-1, family=AddressFamily.AF_UNIX, type=SocketKind.SOCK_STREAM, proto=0>\nE               \nE               Traceback (most recent call last):\nE                 File \"/home/gcpuser/buckets/local_repoeval_bucket/repos/aiohttp_e8339e7687a6c228076f788237b6dbe95ae711e5/aiohttp/test_utils.py\", line 481, in teardown_test_loop\nE                   gc.collect()\nE               ResourceWarning: unclosed <socket.socket fd=14, family=AddressFamily.AF_UNIX, type=SocketKind.SOCK_STREAM, proto=0>\n\ncm         = <_pytest.unraisableexception.catch_unraisable_exception object at 0x74534b178370>\nerr_msg    = 'Exception ignored in'\nmsg        = 'Exception ignored in: <socket.socket fd=-1, family=AddressFamily.AF_UNIX, type=SocketKind.SOCK_STREAM, proto=0>\\n\\nTr...nResourceWarning: unclosed <socket.socket fd=14, family=AddressFamily.AF_UNIX, type=SocketKind.SOCK_STREAM, proto=0>\\n'\n\n.venv/lib/python3.9/site-packages/_pytest/unraisableexception.py:78: PytestUnraisableExceptionWarning\n==================================== PASSES ====================================\n\n---------- coverage: platform linux, python 3.9.21-final-0 -----------\nName                                     Stmts   Miss Branch BrPart  Cover\n--------------------------------------------------------------------------\naiohttp/__init__.py                         26      2      2      0    93%\naiohttp/abc.py                              89      7      0      0    92%\naiohttp/base_protocol.py                    66     51     22      0    17%\naiohttp/client.py                          479    365    178      1    18%\naiohttp/client_exceptions.py               122     51     10      0    54%\naiohttp/client_proto.py                    153    124     56      0    14%\naiohttp/client_reqrep.py                   647    480    272      0    19%\naiohttp/client_ws.py                       215    167     68      1    18%\naiohttp/compression_utils.py                70     36     14      0    40%\naiohttp/connector.py                       697    580    303      0    12%\naiohttp/cookiejar.py                       252      6    124      1    98%\naiohttp/formdata.py                         94     77     46      0    12%\naiohttp/hdrs.py                             90      0      0      0   100%\naiohttp/helpers.py                         556    357    200      3    29%\naiohttp/http.py                              8      0      0      0   100%\naiohttp/http_exceptions.py                  50     20      4      0    56%\naiohttp/http_parser.py                     494    396    200      1    14%\naiohttp/http_websocket.py                  380    286    152      0    18%\naiohttp/http_writer.py                     118     81     50      1    23%\naiohttp/locks.py                            24     16      4      0    29%\naiohttp/log.py                               7      0      0      0   100%\naiohttp/multipart.py                       593    486    250      0    13%\naiohttp/payload.py                         219    107     56      1    43%\naiohttp/pytest_plugin.py                   159     72     42      5    53%\naiohttp/resolver.py                         50     32     14      0    28%\naiohttp/streams.py                         392    309    140      0    16%\naiohttp/tcp_helpers.py                      19     11      6      0    32%\naiohttp/test_utils.py                      298    186     54      2    32%\naiohttp/tracing.py                         191     69     32      0    69%\naiohttp/typedefs.py                         23      0      0      0   100%\naiohttp/web.py                             137     97     54      0    22%\naiohttp/web_app.py                         253    156     50      0    33%\naiohttp/web_exceptions.py                  214     37     26      6    79%\naiohttp/web_fileresponse.py                144    120     48      0    12%\naiohttp/web_log.py                         102     58     20      0    36%\naiohttp/web_middlewares.py                  54     40     20      0    19%\naiohttp/web_protocol.py                    352    289    157      0    13%\naiohttp/web_request.py                     449    305    138      0    25%\naiohttp/web_response.py                    439    332    190      0    17%\naiohttp/web_routedef.py                    106     46     10      0    55%\naiohttp/web_runner.py                      223    134     42      0    34%\naiohttp/web_server.py                       43     24     10      0    36%\naiohttp/web_urldispatcher.py               717    458    163      0    29%\naiohttp/web_ws.py                          332    266    116      1    15%\naiohttp/worker.py                          123     90     30      0    22%\ntests/conftest.py                          119    119     16      0     0%\ntests/test_base_protocol.py                198    198      2      0     0%\ntests/test_circular_imports.py              29     29     13      0     0%\ntests/test_classbasedview.py                39     39      0      0     0%\ntests/test_client_connection.py             93     93      2      0     0%\ntests/test_client_exceptions.py            165    165     14      0     0%\ntests/test_client_fingerprint.py            24     24      0      0     0%\ntests/test_client_functional.py           2370   2370     76      0     0%\ntests/test_client_proto.py                 100    100      0      0     0%\ntests/test_client_request.py               739    739     18      0     0%\ntests/test_client_response.py              461    461      4      0     0%\ntests/test_client_session.py               451    451     23      0     0%\ntests/test_client_ws.py                    416    416      2      0     0%\ntests/test_client_ws_functional.py         645    645     16      0     0%\ntests/test_connector.py                   1646   1646     88      0     0%\ntests/test_cookiejar.py                    347    347     24      0     0%\ntests/test_flowcontrol_streams.py          101    101      0      0     0%\ntests/test_formdata.py                      77     77      6      0     0%\ntests/test_helpers.py                      541    541     22      0     0%\ntests/test_http_exceptions.py              109    109     10      0     0%\ntests/test_http_parser.py                  963    963     50      0     0%\ntests/test_http_writer.py                  183    183     10      0     0%\ntests/test_imports.py                       31     31      6      0     0%\ntests/test_locks.py                         40     40      0      0     0%\ntests/test_loop.py                          36     36      0      0     0%\ntests/test_multipart.py                    771    771     28      0     0%\ntests/test_multipart_helpers.py            446    446      0      0     0%\ntests/test_payload.py                       79     79      0      0     0%\ntests/test_proxy.py                        299    299      0      0     0%\ntests/test_proxy_functional.py             465    465     18      0     0%\ntests/test_pytest_plugin.py                 47     47      0      0     0%\ntests/test_resolver.py                     127    127     10      0     0%\ntests/test_route_def.py                    211    211      0      0     0%\ntests/test_run_app.py                      522    522     30      0     0%\ntests/test_streams.py                     1058   1058     40      0     0%\ntests/test_tcp_helpers.py                   52     52      2      0     0%\ntests/test_test_utils.py                   231    231      6      0     0%\ntests/test_tracing.py                       49     49      0      0     0%\ntests/test_urldispatch.py                  852    852     24      0     0%\ntests/test_web_app.py                      383    383      6      0     0%\ntests/test_web_cli.py                       76     76      0      0     0%\ntests/test_web_exceptions.py               274    274     30      0     0%\ntests/test_web_functional.py              1500   1500     32      0     0%\ntests/test_web_log.py                      143    143      2      0     0%\ntests/test_web_middleware.py               230    230      2      0     0%\ntests/test_web_request.py                  543    543      8      0     0%\ntests/test_web_request_handler.py           40     40      0      0     0%\ntests/test_web_response.py                 813    813      4      0     0%\ntests/test_web_runner.py                   177    177      4      0     0%\ntests/test_web_sendfile.py                  77     77      0      0     0%\ntests/test_web_sendfile_functional.py      652    652     18      0     0%\ntests/test_web_server.py                   178    178      0      0     0%\ntests/test_web_urldispatcher.py            335    335     14      0     0%\ntests/test_web_websocket.py                316    316      8      0     0%\ntests/test_web_websocket_functional.py     573    573     20      0     0%\ntests/test_websocket_handshake.py          153    153     12      0     0%\ntests/test_websocket_parser.py             293    293     12      0     0%\ntests/test_websocket_writer.py              95     95      6      0     0%\ntests/test_worker.py                       190    190      2      0     0%\n--------------------------------------------------------------------------\nTOTAL                                    32442  28999   4113     23    10%\n\n============================= slowest 10 durations =============================\n0.06s call     r2e_tests/test_1.py::TestCookieJarSafe::test_expires\n0.03s call     r2e_tests/test_1.py::test_cookie_jar_clear_expired\n0.02s call     r2e_tests/test_1.py::TestCookieJarSafe::test_max_age\n0.02s call     r2e_tests/test_1.py::test_cookie_jar_clear_domain\n0.02s call     r2e_tests/test_1.py::test_dummy_cookie_jar\n0.02s call     r2e_tests/test_1.py::test_treat_as_secure_origin_init[http://127.0.0.1/index.html]\n0.02s call     r2e_tests/test_1.py::test_constructor\n0.02s call     r2e_tests/test_1.py::test_loose_cookies_types\n0.01s call     r2e_tests/test_1.py::test_treat_as_secure_origin_init[url1]\n0.01s teardown r2e_tests/test_1.py::test_update_cookie_with_unicode_domain[pyloop]\n=========================== short test summary info ============================\nPASSED r2e_tests/test_1.py::test_date_parsing\nPASSED r2e_tests/test_1.py::test_domain_matching\nPASSED r2e_tests/test_1.py::test_constructor\nPASSED r2e_tests/test_1.py::test_constructor_with_expired\nPASSED r2e_tests/test_1.py::test_save_load[pyloop]\nPASSED r2e_tests/test_1.py::test_update_cookie_with_unicode_domain[pyloop]\nPASSED r2e_tests/test_1.py::test_filter_cookie_with_unicode_domain[pyloop]\nPASSED r2e_tests/test_1.py::test_filter_cookies_str_deprecated[pyloop]\nPASSED r2e_tests/test_1.py::test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://pathtest.com/one/two/-expected_cookies0]\nPASSED r2e_tests/test_1.py::test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://pathtest.com/one/two-expected_cookies1]\nPASSED r2e_tests/test_1.py::test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://pathtest.com/one/two/three/-expected_cookies2]\nPASSED r2e_tests/test_1.py::test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://test1.example.com/-expected_cookies3]\nPASSED r2e_tests/test_1.py::test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://pathtest.com/-expected_cookies4]\nPASSED r2e_tests/test_1.py::test_domain_filter_ip_cookie_send[pyloop]\nPASSED r2e_tests/test_1.py::test_domain_filter_ip_cookie_receive\nPASSED r2e_tests/test_1.py::test_quotes_correctly_based_on_input[pyloop-IP domain preserved]\nPASSED r2e_tests/test_1.py::test_quotes_correctly_based_on_input[pyloop-no shared cookie]\nPASSED r2e_tests/test_1.py::test_quotes_correctly_based_on_input[pyloop-quoted cookie with special char]\nPASSED r2e_tests/test_1.py::test_quotes_correctly_based_on_input[pyloop-quoted cookie w/o special char]\nPASSED r2e_tests/test_1.py::test_quotes_correctly_based_on_input[pyloop-unquoted cookie with special char]\nPASSED r2e_tests/test_1.py::test_ignore_domain_ending_with_dot[pyloop]\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_cookie_not_expired_when_added_after_removal\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_domain_filter_diff_host\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_domain_filter_host_only\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_domain_filter_same_host\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_domain_filter_same_host_and_subdomain\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_domain_filter_same_host_diff_subdomain\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_expires\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_invalid_values\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_max_age\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_diff_folder_same_name\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_diff_folder_same_name_return_best_match_independent_from_put_order\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_different_folder\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_file\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_folder\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_root\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_subfolder\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_path_filter_subsubfolder\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_path_value\nPASSED r2e_tests/test_1.py::TestCookieJarSafe::test_secure_filter\nPASSED r2e_tests/test_1.py::test_dummy_cookie_jar\nPASSED r2e_tests/test_1.py::test_loose_cookies_types\nPASSED r2e_tests/test_1.py::test_cookie_jar_clear_all\nPASSED r2e_tests/test_1.py::test_cookie_jar_clear_expired\nPASSED r2e_tests/test_1.py::test_pickle_format\nPASSED r2e_tests/test_1.py::test_treat_as_secure_origin_init[http://127.0.0.1/index.html]\nPASSED r2e_tests/test_1.py::test_treat_as_secure_origin_init[url1]\nPASSED r2e_tests/test_1.py::test_treat_as_secure_origin_init[url2]\nPASSED r2e_tests/test_1.py::test_treat_as_secure_origin_init[url3]\nPASSED r2e_tests/test_1.py::test_treat_as_secure_origin\nFAILED r2e_tests/test_1.py::test_cookie_jar_filter_cookies_expires - assert 0...\nFAILED r2e_tests/test_1.py::test_cookie_jar_clear_domain - pytest.PytestUnrai...\n========================= 2 failed, 50 passed in 3.87s =========================\n",
    "old_commit_res_stderr": ""
}
CHANGES/7784.bugfix aiohttp/cookiejar.py tests/test_cookiejar.py
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]

**CookieJar Fails to Expire Stale Cookies When Filtering**

**Description**
When an expired cookie is added to the `CookieJar` and the `filter_cookies` method is called, the stale cookie is not removed as expected. This results in the `CookieJar` retaining expired cookies, leading to incorrect cookie counts.

**Example Code**
```python
from aiohttp import CookieJar, URL
from http.cookies import SimpleCookie
from freezegun import freeze_time

jar = CookieJar()
cookie = SimpleCookie()
cookie['foo'] = 'bar'
cookie['foo']['expires'] = 'Tue, 1 Jan 1990 12:00:00 GMT'

with freeze_time('1980-01-01'):
    jar.update_cookies(cookie)

jar.filter_cookies(URL('http://any.com/'))

# Expected: CookieJar should have 0 cookies after filtering
# Actual: CookieJar still has 1 cookie
```

**Expected Behavior**
After calling `filter_cookies`, any cookies that have expired should be removed from the `CookieJar`, resulting in zero cookies remaining.

**Actual Behavior**
Expired cookies remain in the `CookieJar`, causing it to incorrectly report that it still contains cookies.

[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### aiohttp/cookiejar.py
import calendar
import contextlib
import datetime
import itertools
import os  # noqa
import pathlib
import pickle
import re
import time
import warnings
from collections import defaultdict
from http.cookies import BaseCookie, Morsel, SimpleCookie
from math import ceil
from typing import (
    DefaultDict,
    Dict,
    Iterable,
    Iterator,
    List,
    Mapping,
    Optional,
    Set,
    Tuple,
    Union,
    cast,
)

from yarl import URL

from .abc import AbstractCookieJar, ClearCookiePredicate
from .helpers import is_ip_address
from .typedefs import LooseCookies, PathLike, StrOrURL

__all__ = ("CookieJar", "DummyCookieJar")


CookieItem = Union[str, "Morsel[str]"]


class CookieJar(AbstractCookieJar):
    """Implements cookie storage adhering to RFC 6265."""

    DATE_TOKENS_RE = re.compile(
        r"[\x09\x20-\x2F\x3B-\x40\x5B-\x60\x7B-\x7E]*"
        r"(?P<token>[\x00-\x08\x0A-\x1F\d:a-zA-Z\x7F-\xFF]+)"
    )

    DATE_HMS_TIME_RE = re.compile(r"(\d{1,2}):(\d{1,2}):(\d{1,2})")

    DATE_DAY_OF_MONTH_RE = re.compile(r"(\d{1,2})")

    DATE_MONTH_RE = re.compile(
        "(jan)|(feb)|(mar)|(apr)|(may)|(jun)|(jul)|" "(aug)|(sep)|(oct)|(nov)|(dec)",
        re.I,
    )

    DATE_YEAR_RE = re.compile(r"(\d{2,4})")

    # calendar.timegm() fails for timestamps after datetime.datetime.max
    # Minus one as a loss of precision occurs when timestamp() is called.
    MAX_TIME = (
        int(datetime.datetime.max.replace(tzinfo=datetime.timezone.utc).timestamp()) - 1
    )
    try:
        calendar.timegm(time.gmtime(MAX_TIME))
    except (OSError, ValueError):
        # Hit the maximum representable time on Windows
        # https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/localtime-localtime32-localtime64
        # Throws ValueError on PyPy 3.8 and 3.9, OSError elsewhere
        MAX_TIME = calendar.timegm((3000, 12, 31, 23, 59, 59, -1, -1, -1))
    except OverflowError:
        # #4515: datetime.max may not be representable on 32-bit platforms
        MAX_TIME = 2**31 - 1
    # Avoid minuses in the future, 3x faster
    SUB_MAX_TIME = MAX_TIME - 1

    def __init__(
        self,
        *,
        unsafe: bool = False,
        quote_cookie: bool = True,
        treat_as_secure_origin: Union[StrOrURL, List[StrOrURL], None] = None,
    ) -> None:
        self._cookies: DefaultDict[Tuple[str, str], SimpleCookie] = defaultdict(
            SimpleCookie
        )
        self._host_only_cookies: Set[Tuple[str, str]] = set()
        self._unsafe = unsafe
        self._quote_cookie = quote_cookie
        if treat_as_secure_origin is None:
            treat_as_secure_origin = []
        elif isinstance(treat_as_secure_origin, URL):
            treat_as_secure_origin = [treat_as_secure_origin.origin()]
        elif isinstance(treat_as_secure_origin, str):
            treat_as_secure_origin = [URL(treat_as_secure_origin).origin()]
        else:
            treat_as_secure_origin = [
                URL(url).origin() if isinstance(url, str) else url.origin()
                for url in treat_as_secure_origin
            ]
        self._treat_as_secure_origin = treat_as_secure_origin
        self._next_expiration: float = ceil(time.time())
        self._expirations: Dict[Tuple[str, str, str], float] = {}

    def save(self, file_path: PathLike) -> None:
        file_path = pathlib.Path(file_path)
        with file_path.open(mode="wb") as f:
            pickle.dump(self._cookies, f, pickle.HIGHEST_PROTOCOL)

    def load(self, file_path: PathLike) -> None:
        file_path = pathlib.Path(file_path)
        with file_path.open(mode="rb") as f:
            self._cookies = pickle.load(f)

    def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None:
        if predicate is None:
            self._next_expiration = ceil(time.time())
            self._cookies.clear()
            self._host_only_cookies.clear()
            self._expirations.clear()
            return

        to_del = []
        now = time.time()
        for (domain, path), cookie in self._cookies.items():
            for name, morsel in cookie.items():
                key = (domain, path, name)
                if (
                    key in self._expirations and self._expirations[key] <= now
                ) or predicate(morsel):
                    to_del.append(key)

        for domain, path, name in to_del:
            self._host_only_cookies.discard((domain, name))
            key = (domain, path, name)
            if key in self._expirations:
                del self._expirations[(domain, path, name)]
            self._cookies[(domain, path)].pop(name, None)

        self._next_expiration = (
            min(*self._expirations.values(), self.SUB_MAX_TIME) + 1
            if self._expirations
            else self.MAX_TIME
        )

    def clear_domain(self, domain: str) -> None:
        self.clear(lambda x: self._is_domain_match(domain, x["domain"]))

    def __iter__(self) -> "Iterator[Morsel[str]]":
        self._do_expiration()
        for val in self._cookies.values():
            yield from val.values()

    def __len__(self) -> int:
        return sum(1 for i in self)

    def _do_expiration(self) -> None:
        self.clear(lambda x: False)

    def _expire_cookie(self, when: float, domain: str, path: str, name: str) -> None:
        self._next_expiration = min(self._next_expiration, when)
        self._expirations[(domain, path, name)] = when

    def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None:
        """Update cookies."""
        hostname = response_url.raw_host

        if not self._unsafe and is_ip_address(hostname):
            # Don't accept cookies from IPs
            return

        if isinstance(cookies, Mapping):
            cookies = cookies.items()

        for name, cookie in cookies:
            if not isinstance(cookie, Morsel):
                tmp = SimpleCookie()
                tmp[name] = cookie  # type: ignore[assignment]
                cookie = tmp[name]

            domain = cookie["domain"]

            # ignore domains with trailing dots
            if domain.endswith("."):
                domain = ""
                del cookie["domain"]

            if not domain and hostname is not None:
                # Set the cookie's domain to the response hostname
                # and set its host-only-flag
                self._host_only_cookies.add((hostname, name))
                domain = cookie["domain"] = hostname

            if domain.startswith("."):
                # Remove leading dot
                domain = domain[1:]
                cookie["domain"] = domain

            if hostname and not self._is_domain_match(domain, hostname):
                # Setting cookies for different domains is not allowed
                continue

            path = cookie["path"]
            if not path or not path.startswith("/"):
                # Set the cookie's path to the response path
                path = response_url.path
                if not path.startswith("/"):
                    path = "/"
                else:
                    # Cut everything from the last slash to the end
                    path = "/" + path[1 : path.rfind("/")]
                cookie["path"] = path
            path = path.rstrip("/")

            max_age = cookie["max-age"]
            if max_age:
                try:
                    delta_seconds = int(max_age)
                    max_age_expiration = min(time.time() + delta_seconds, self.MAX_TIME)
                    self._expire_cookie(max_age_expiration, domain, path, name)
                except ValueError:
                    cookie["max-age"] = ""

            else:
                expires = cookie["expires"]
                if expires:
                    expire_time = self._parse_date(expires)
                    if expire_time:
                        self._expire_cookie(expire_time, domain, path, name)
                    else:
                        cookie["expires"] = ""

            self._cookies[(domain, path)][name] = cookie

        self._do_expiration()

    def filter_cookies(self, request_url: URL = URL()) -> "BaseCookie[str]":
        """Returns this jar's cookies filtered by their attributes."""
        if not isinstance(request_url, URL):
            warnings.warn(
                "The method accepts yarl.URL instances only, got {}".format(
                    type(request_url)
                ),
                DeprecationWarning,
            )
            request_url = URL(request_url)
        filtered: Union[SimpleCookie, "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
        hostname = request_url.raw_host or ""

        is_not_secure = request_url.scheme not in ("https", "wss")
        if is_not_secure and self._treat_as_secure_origin:
            request_origin = URL()
            with contextlib.suppress(ValueError):
                request_origin = request_url.origin()
            is_not_secure = request_origin not in self._treat_as_secure_origin

        # Send shared cookie
        for c in self._cookies[("", "")].values():
            filtered[c.key] = c.value

        if is_ip_address(hostname):
            if not self._unsafe:
                return filtered
            domains: Iterable[str] = (hostname,)
        else:
            # Get all the subdomains that might match a cookie (e.g. "foo.bar.com", "bar.com", "com")
            domains = itertools.accumulate(
                reversed(hostname.split(".")), lambda x, y: f"{y}.{x}"
            )
        # Get all the path prefixes that might match a cookie (e.g. "", "/foo", "/foo/bar")
        paths = itertools.accumulate(
            request_url.path.split("/"), lambda x, y: f"{x}/{y}"
        )
        # Create every combination of (domain, path) pairs.
        pairs = itertools.product(domains, paths)

        # Point 2: https://www.rfc-editor.org/rfc/rfc6265.html#section-5.4
        cookies = itertools.chain.from_iterable(
            self._cookies[p].values() for p in pairs
        )
        path_len = len(request_url.path)
        for cookie in cookies:
            name = cookie.key
            domain = cookie["domain"]

            if (domain, name) in self._host_only_cookies:
                if domain != hostname:
                    continue

            # Skip edge case when the cookie has a trailing slash but request doesn't.
            if len(cookie["path"]) > path_len:
                continue

            if is_not_secure and cookie["secure"]:
                continue

            # It's critical we use the Morsel so the coded_value
            # (based on cookie version) is preserved
            mrsl_val = cast("Morsel[str]", cookie.get(cookie.key, Morsel()))
            mrsl_val.set(cookie.key, cookie.value, cookie.coded_value)
            filtered[name] = mrsl_val

        return filtered

    @staticmethod
    def _is_domain_match(domain: str, hostname: str) -> bool:
        """Implements domain matching adhering to RFC 6265."""
        if hostname == domain:
            return True

        if not hostname.endswith(domain):
            return False

        non_matching = hostname[: -len(domain)]

        if not non_matching.endswith("."):
            return False

        return not is_ip_address(hostname)

    @classmethod
    def _parse_date(cls, date_str: str) -> Optional[int]:
        """Implements date string parsing adhering to RFC 6265."""
        if not date_str:
            return None

        found_time = False
        found_day = False
        found_month = False
        found_year = False

        hour = minute = second = 0
        day = 0
        month = 0
        year = 0

        for token_match in cls.DATE_TOKENS_RE.finditer(date_str):
            token = token_match.group("token")

            if not found_time:
                time_match = cls.DATE_HMS_TIME_RE.match(token)
                if time_match:
                    found_time = True
                    hour, minute, second = (int(s) for s in time_match.groups())
                    continue

            if not found_day:
                day_match = cls.DATE_DAY_OF_MONTH_RE.match(token)
                if day_match:
                    found_day = True
                    day = int(day_match.group())
                    continue

            if not found_month:
                month_match = cls.DATE_MONTH_RE.match(token)
                if month_match:
                    found_month = True
                    assert month_match.lastindex is not None
                    month = month_match.lastindex
                    continue

            if not found_year:
                year_match = cls.DATE_YEAR_RE.match(token)
                if year_match:
                    found_year = True
                    year = int(year_match.group())

        if 70 <= year <= 99:
            year += 1900
        elif 0 <= year <= 69:
            year += 2000

        if False in (found_day, found_month, found_year, found_time):
            return None

        if not 1 <= day <= 31:
            return None

        if year < 1601 or hour > 23 or minute > 59 or second > 59:
            return None

        return calendar.timegm((year, month, day, hour, minute, second, -1, -1, -1))


class DummyCookieJar(AbstractCookieJar):
    """Implements a dummy cookie storage.

    It can be used with the ClientSession when no cookie processing is needed.

    """

    def __iter__(self) -> "Iterator[Morsel[str]]":
        while False:
            yield None

    def __len__(self) -> int:
        return 0

    def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None:
        pass

    def clear_domain(self, domain: str) -> None:
        pass

    def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None:
        pass

    def filter_cookies(self, request_url: URL) -> "BaseCookie[str]":
        return SimpleCookie()

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
[ISSUE]

**CookieJar Fails to Expire Stale Cookies When Filtering**

**Description**
When an expired cookie is added to the `CookieJar` and the `filter_cookies` method is called, the stale cookie is not removed as expected. This results in the `CookieJar` retaining expired cookies, leading to incorrect cookie counts.

**Example Code**
```python
from aiohttp import CookieJar, URL
from http.cookies import SimpleCookie
from freezegun import freeze_time

jar = CookieJar()
cookie = SimpleCookie()
cookie['foo'] = 'bar'
cookie['foo']['expires'] = 'Tue, 1 Jan 1990 12:00:00 GMT'

with freeze_time('1980-01-01'):
    jar.update_cookies(cookie)

jar.filter_cookies(URL('http://any.com/'))

# Expected: CookieJar should have 0 cookies after filtering
# Actual: CookieJar still has 1 cookie
```

**Expected Behavior**
After calling `filter_cookies`, any cookies that have expired should be removed from the `CookieJar`, resulting in zero cookies remaining.

**Actual Behavior**
Expired cookies remain in the `CookieJar`, causing it to incorrectly report that it still contains cookies.

[/ISSUE]
{
    "test_date_parsing": "PASSED",
    "test_domain_matching": "PASSED",
    "test_constructor": "PASSED",
    "test_constructor_with_expired": "PASSED",
    "test_save_load[pyloop]": "PASSED",
    "test_update_cookie_with_unicode_domain[pyloop]": "PASSED",
    "test_filter_cookie_with_unicode_domain[pyloop]": "PASSED",
    "test_filter_cookies_str_deprecated[pyloop]": "PASSED",
    "test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://pathtest.com/one/two/-expected_cookies0]": "PASSED",
    "test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://pathtest.com/one/two-expected_cookies1]": "PASSED",
    "test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://pathtest.com/one/two/three/-expected_cookies2]": "PASSED",
    "test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://test1.example.com/-expected_cookies3]": "PASSED",
    "test_filter_cookies_with_domain_path_lookup_multilevelpath[pyloop-http://pathtest.com/-expected_cookies4]": "PASSED",
    "test_domain_filter_ip_cookie_send[pyloop]": "PASSED",
    "test_domain_filter_ip_cookie_receive": "PASSED",
    "test_quotes_correctly_based_on_input[pyloop-IP domain preserved]": "PASSED",
    "test_quotes_correctly_based_on_input[pyloop-no shared cookie]": "PASSED",
    "test_quotes_correctly_based_on_input[pyloop-quoted cookie with special char]": "PASSED",
    "test_quotes_correctly_based_on_input[pyloop-quoted cookie w/o special char]": "PASSED",
    "test_quotes_correctly_based_on_input[pyloop-unquoted cookie with special char]": "PASSED",
    "test_ignore_domain_ending_with_dot[pyloop]": "PASSED",
    "TestCookieJarSafe.test_cookie_not_expired_when_added_after_removal": "PASSED",
    "TestCookieJarSafe.test_domain_filter_diff_host": "PASSED",
    "TestCookieJarSafe.test_domain_filter_host_only": "PASSED",
    "TestCookieJarSafe.test_domain_filter_same_host": "PASSED",
    "TestCookieJarSafe.test_domain_filter_same_host_and_subdomain": "PASSED",
    "TestCookieJarSafe.test_domain_filter_same_host_diff_subdomain": "PASSED",
    "TestCookieJarSafe.test_expires": "PASSED",
    "TestCookieJarSafe.test_invalid_values": "PASSED",
    "TestCookieJarSafe.test_max_age": "PASSED",
    "TestCookieJarSafe.test_path_filter_diff_folder_same_name": "PASSED",
    "TestCookieJarSafe.test_path_filter_diff_folder_same_name_return_best_match_independent_from_put_order": "PASSED",
    "TestCookieJarSafe.test_path_filter_different_folder": "PASSED",
    "TestCookieJarSafe.test_path_filter_file": "PASSED",
    "TestCookieJarSafe.test_path_filter_folder": "PASSED",
    "TestCookieJarSafe.test_path_filter_root": "PASSED",
    "TestCookieJarSafe.test_path_filter_subfolder": "PASSED",
    "TestCookieJarSafe.test_path_filter_subsubfolder": "PASSED",
    "TestCookieJarSafe.test_path_value": "PASSED",
    "TestCookieJarSafe.test_secure_filter": "PASSED",
    "test_dummy_cookie_jar": "PASSED",
    "test_loose_cookies_types": "PASSED",
    "test_cookie_jar_clear_all": "PASSED",
    "test_cookie_jar_clear_expired": "PASSED",
    "test_cookie_jar_filter_cookies_expires": "PASSED",
    "test_cookie_jar_clear_domain": "PASSED",
    "test_pickle_format": "PASSED",
    "test_treat_as_secure_origin_init[http://127.0.0.1/index.html]": "PASSED",
    "test_treat_as_secure_origin_init[url1]": "PASSED",
    "test_treat_as_secure_origin_init[url2]": "PASSED",
    "test_treat_as_secure_origin_init[url3]": "PASSED",
    "test_treat_as_secure_origin": "PASSED"
}
diff --git a/aiohttp/cookiejar.py b/aiohttp/cookiejar.py
index aa63d280..da162543 100644
--- a/aiohttp/cookiejar.py
+++ b/aiohttp/cookiejar.py
@@ -152,7 +152,12 @@ class CookieJar(AbstractCookieJar):
             yield from val.values()
 
     def __len__(self) -> int:
-        return sum(1 for i in self)
+        """Return number of cookies.
+
+        This function does not iterate self to avoid unnecessary expiration
+        checks.
+        """
+        return sum(len(cookie.values()) for cookie in self._cookies.values())
 
     def _do_expiration(self) -> None:
         self.clear(lambda x: False)

{"aiohttp/cookiejar.py": "import calendar\nimport contextlib\nimport datetime\nimport itertools\nimport os  # noqa\nimport pathlib\nimport pickle\nimport re\nimport time\nimport warnings\nfrom collections import defaultdict\nfrom http.cookies import BaseCookie, Morsel, SimpleCookie\nfrom math import ceil\nfrom typing import (\n    DefaultDict,\n    Dict,\n    Iterable,\n    Iterator,\n    List,\n    Mapping,\n    Optional,\n    Set,\n    Tuple,\n    Union,\n    cast,\n)\n\nfrom yarl import URL\n\nfrom .abc import AbstractCookieJar, ClearCookiePredicate\nfrom .helpers import is_ip_address\nfrom .typedefs import LooseCookies, PathLike, StrOrURL\n\n__all__ = (\"CookieJar\", \"DummyCookieJar\")\n\n\nCookieItem = Union[str, \"Morsel[str]\"]\n\n\nclass CookieJar(AbstractCookieJar):\n    \"\"\"Implements cookie storage adhering to RFC 6265.\"\"\"\n\n    DATE_TOKENS_RE = re.compile(\n        r\"[\\x09\\x20-\\x2F\\x3B-\\x40\\x5B-\\x60\\x7B-\\x7E]*\"\n        r\"(?P<token>[\\x00-\\x08\\x0A-\\x1F\\d:a-zA-Z\\x7F-\\xFF]+)\"\n    )\n\n    DATE_HMS_TIME_RE = re.compile(r\"(\\d{1,2}):(\\d{1,2}):(\\d{1,2})\")\n\n    DATE_DAY_OF_MONTH_RE = re.compile(r\"(\\d{1,2})\")\n\n    DATE_MONTH_RE = re.compile(\n        \"(jan)|(feb)|(mar)|(apr)|(may)|(jun)|(jul)|\" \"(aug)|(sep)|(oct)|(nov)|(dec)\",\n        re.I,\n    )\n\n    DATE_YEAR_RE = re.compile(r\"(\\d{2,4})\")\n\n    # calendar.timegm() fails for timestamps after datetime.datetime.max\n    # Minus one as a loss of precision occurs when timestamp() is called.\n    MAX_TIME = (\n        int(datetime.datetime.max.replace(tzinfo=datetime.timezone.utc).timestamp()) - 1\n    )\n    try:\n        calendar.timegm(time.gmtime(MAX_TIME))\n    except (OSError, ValueError):\n        # Hit the maximum representable time on Windows\n        # https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/localtime-localtime32-localtime64\n        # Throws ValueError on PyPy 3.8 and 3.9, OSError elsewhere\n        MAX_TIME = calendar.timegm((3000, 12, 31, 23, 59, 59, -1, -1, -1))\n    except OverflowError:\n        # #4515: datetime.max may not be representable on 32-bit platforms\n        MAX_TIME = 2**31 - 1\n    # Avoid minuses in the future, 3x faster\n    SUB_MAX_TIME = MAX_TIME - 1\n\n    def __init__(\n        self,\n        *,\n        unsafe: bool = False,\n        quote_cookie: bool = True,\n        treat_as_secure_origin: Union[StrOrURL, List[StrOrURL], None] = None,\n    ) -> None:\n        self._cookies: DefaultDict[Tuple[str, str], SimpleCookie] = defaultdict(\n            SimpleCookie\n        )\n        self._host_only_cookies: Set[Tuple[str, str]] = set()\n        self._unsafe = unsafe\n        self._quote_cookie = quote_cookie\n        if treat_as_secure_origin is None:\n            treat_as_secure_origin = []\n        elif isinstance(treat_as_secure_origin, URL):\n            treat_as_secure_origin = [treat_as_secure_origin.origin()]\n        elif isinstance(treat_as_secure_origin, str):\n            treat_as_secure_origin = [URL(treat_as_secure_origin).origin()]\n        else:\n            treat_as_secure_origin = [\n                URL(url).origin() if isinstance(url, str) else url.origin()\n                for url in treat_as_secure_origin\n            ]\n        self._treat_as_secure_origin = treat_as_secure_origin\n        self._next_expiration: float = ceil(time.time())\n        self._expirations: Dict[Tuple[str, str, str], float] = {}\n\n    def save(self, file_path: PathLike) -> None:\n        file_path = pathlib.Path(file_path)\n        with file_path.open(mode=\"wb\") as f:\n            pickle.dump(self._cookies, f, pickle.HIGHEST_PROTOCOL)\n\n    def load(self, file_path: PathLike) -> None:\n        file_path = pathlib.Path(file_path)\n        with file_path.open(mode=\"rb\") as f:\n            self._cookies = pickle.load(f)\n\n    def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None:\n        if predicate is None:\n            self._next_expiration = ceil(time.time())\n            self._cookies.clear()\n            self._host_only_cookies.clear()\n            self._expirations.clear()\n            return\n\n        to_del = []\n        now = time.time()\n        for (domain, path), cookie in self._cookies.items():\n            for name, morsel in cookie.items():\n                key = (domain, path, name)\n                if (\n                    key in self._expirations and self._expirations[key] <= now\n                ) or predicate(morsel):\n                    to_del.append(key)\n\n        for domain, path, name in to_del:\n            self._host_only_cookies.discard((domain, name))\n            key = (domain, path, name)\n            if key in self._expirations:\n                del self._expirations[(domain, path, name)]\n            self._cookies[(domain, path)].pop(name, None)\n\n        self._next_expiration = (\n            min(*self._expirations.values(), self.SUB_MAX_TIME) + 1\n            if self._expirations\n            else self.MAX_TIME\n        )\n\n    def clear_domain(self, domain: str) -> None:\n        self.clear(lambda x: self._is_domain_match(domain, x[\"domain\"]))\n\n    def __iter__(self) -> \"Iterator[Morsel[str]]\":\n        self._do_expiration()\n        for val in self._cookies.values():\n            yield from val.values()\n\n    def __len__(self) -> int:\n        return sum(1 for i in self)\n\n    def _do_expiration(self) -> None:\n        self.clear(lambda x: False)\n\n    def _expire_cookie(self, when: float, domain: str, path: str, name: str) -> None:\n        self._next_expiration = min(self._next_expiration, when)\n        self._expirations[(domain, path, name)] = when\n\n    def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None:\n        \"\"\"Update cookies.\"\"\"\n        hostname = response_url.raw_host\n\n        if not self._unsafe and is_ip_address(hostname):\n            # Don't accept cookies from IPs\n            return\n\n        if isinstance(cookies, Mapping):\n            cookies = cookies.items()\n\n        for name, cookie in cookies:\n            if not isinstance(cookie, Morsel):\n                tmp = SimpleCookie()\n                tmp[name] = cookie  # type: ignore[assignment]\n                cookie = tmp[name]\n\n            domain = cookie[\"domain\"]\n\n            # ignore domains with trailing dots\n            if domain.endswith(\".\"):\n                domain = \"\"\n                del cookie[\"domain\"]\n\n            if not domain and hostname is not None:\n                # Set the cookie's domain to the response hostname\n                # and set its host-only-flag\n                self._host_only_cookies.add((hostname, name))\n                domain = cookie[\"domain\"] = hostname\n\n            if domain.startswith(\".\"):\n                # Remove leading dot\n                domain = domain[1:]\n                cookie[\"domain\"] = domain\n\n            if hostname and not self._is_domain_match(domain, hostname):\n                # Setting cookies for different domains is not allowed\n                continue\n\n            path = cookie[\"path\"]\n            if not path or not path.startswith(\"/\"):\n                # Set the cookie's path to the response path\n                path = response_url.path\n                if not path.startswith(\"/\"):\n                    path = \"/\"\n                else:\n                    # Cut everything from the last slash to the end\n                    path = \"/\" + path[1 : path.rfind(\"/\")]\n                cookie[\"path\"] = path\n            path = path.rstrip(\"/\")\n\n            max_age = cookie[\"max-age\"]\n            if max_age:\n                try:\n                    delta_seconds = int(max_age)\n                    max_age_expiration = min(time.time() + delta_seconds, self.MAX_TIME)\n                    self._expire_cookie(max_age_expiration, domain, path, name)\n                except ValueError:\n                    cookie[\"max-age\"] = \"\"\n\n            else:\n                expires = cookie[\"expires\"]\n                if expires:\n                    expire_time = self._parse_date(expires)\n                    if expire_time:\n                        self._expire_cookie(expire_time, domain, path, name)\n                    else:\n                        cookie[\"expires\"] = \"\"\n\n            self._cookies[(domain, path)][name] = cookie\n\n        self._do_expiration()\n\n    def filter_cookies(self, request_url: URL = URL()) -> \"BaseCookie[str]\":\n        \"\"\"Returns this jar's cookies filtered by their attributes.\"\"\"\n        if not isinstance(request_url, URL):\n            warnings.warn(\n                \"The method accepts yarl.URL instances only, got {}\".format(\n                    type(request_url)\n                ),\n                DeprecationWarning,\n            )\n            request_url = URL(request_url)\n        filtered: Union[SimpleCookie, \"BaseCookie[str]\"] = (\n            SimpleCookie() if self._quote_cookie else BaseCookie()\n        )\n        if not self._cookies:\n            # Skip do_expiration() if there are no cookies.\n            return filtered\n        self._do_expiration()\n        if not self._cookies:\n            # Skip rest of function if no non-expired cookies.\n            return filtered\n        hostname = request_url.raw_host or \"\"\n\n        is_not_secure = request_url.scheme not in (\"https\", \"wss\")\n        if is_not_secure and self._treat_as_secure_origin:\n            request_origin = URL()\n            with contextlib.suppress(ValueError):\n                request_origin = request_url.origin()\n            is_not_secure = request_origin not in self._treat_as_secure_origin\n\n        # Send shared cookie\n        for c in self._cookies[(\"\", \"\")].values():\n            filtered[c.key] = c.value\n\n        if is_ip_address(hostname):\n            if not self._unsafe:\n                return filtered\n            domains: Iterable[str] = (hostname,)\n        else:\n            # Get all the subdomains that might match a cookie (e.g. \"foo.bar.com\", \"bar.com\", \"com\")\n            domains = itertools.accumulate(\n                reversed(hostname.split(\".\")), lambda x, y: f\"{y}.{x}\"\n            )\n        # Get all the path prefixes that might match a cookie (e.g. \"\", \"/foo\", \"/foo/bar\")\n        paths = itertools.accumulate(\n            request_url.path.split(\"/\"), lambda x, y: f\"{x}/{y}\"\n        )\n        # Create every combination of (domain, path) pairs.\n        pairs = itertools.product(domains, paths)\n\n        # Point 2: https://www.rfc-editor.org/rfc/rfc6265.html#section-5.4\n        cookies = itertools.chain.from_iterable(\n            self._cookies[p].values() for p in pairs\n        )\n        path_len = len(request_url.path)\n        for cookie in cookies:\n            name = cookie.key\n            domain = cookie[\"domain\"]\n\n            if (domain, name) in self._host_only_cookies:\n                if domain != hostname:\n                    continue\n\n            # Skip edge case when the cookie has a trailing slash but request doesn't.\n            if len(cookie[\"path\"]) > path_len:\n                continue\n\n            if is_not_secure and cookie[\"secure\"]:\n                continue\n\n            # It's critical we use the Morsel so the coded_value\n            # (based on cookie version) is preserved\n            mrsl_val = cast(\"Morsel[str]\", cookie.get(cookie.key, Morsel()))\n            mrsl_val.set(cookie.key, cookie.value, cookie.coded_value)\n            filtered[name] = mrsl_val\n\n        return filtered\n\n    @staticmethod\n    def _is_domain_match(domain: str, hostname: str) -> bool:\n        \"\"\"Implements domain matching adhering to RFC 6265.\"\"\"\n        if hostname == domain:\n            return True\n\n        if not hostname.endswith(domain):\n            return False\n\n        non_matching = hostname[: -len(domain)]\n\n        if not non_matching.endswith(\".\"):\n            return False\n\n        return not is_ip_address(hostname)\n\n    @classmethod\n    def _parse_date(cls, date_str: str) -> Optional[int]:\n        \"\"\"Implements date string parsing adhering to RFC 6265.\"\"\"\n        if not date_str:\n            return None\n\n        found_time = False\n        found_day = False\n        found_month = False\n        found_year = False\n\n        hour = minute = second = 0\n        day = 0\n        month = 0\n        year = 0\n\n        for token_match in cls.DATE_TOKENS_RE.finditer(date_str):\n            token = token_match.group(\"token\")\n\n            if not found_time:\n                time_match = cls.DATE_HMS_TIME_RE.match(token)\n                if time_match:\n                    found_time = True\n                    hour, minute, second = (int(s) for s in time_match.groups())\n                    continue\n\n            if not found_day:\n                day_match = cls.DATE_DAY_OF_MONTH_RE.match(token)\n                if day_match:\n                    found_day = True\n                    day = int(day_match.group())\n                    continue\n\n            if not found_month:\n                month_match = cls.DATE_MONTH_RE.match(token)\n                if month_match:\n                    found_month = True\n                    assert month_match.lastindex is not None\n                    month = month_match.lastindex\n                    continue\n\n            if not found_year:\n                year_match = cls.DATE_YEAR_RE.match(token)\n                if year_match:\n                    found_year = True\n                    year = int(year_match.group())\n\n        if 70 <= year <= 99:\n            year += 1900\n        elif 0 <= year <= 69:\n            year += 2000\n\n        if False in (found_day, found_month, found_year, found_time):\n            return None\n\n        if not 1 <= day <= 31:\n            return None\n\n        if year < 1601 or hour > 23 or minute > 59 or second > 59:\n            return None\n\n        return calendar.timegm((year, month, day, hour, minute, second, -1, -1, -1))\n\n\nclass DummyCookieJar(AbstractCookieJar):\n    \"\"\"Implements a dummy cookie storage.\n\n    It can be used with the ClientSession when no cookie processing is needed.\n\n    \"\"\"\n\n    def __iter__(self) -> \"Iterator[Morsel[str]]\":\n        while False:\n            yield None\n\n    def __len__(self) -> int:\n        return 0\n\n    def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None:\n        pass\n\n    def clear_domain(self, domain: str) -> None:\n        pass\n\n    def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None:\n        pass\n\n    def filter_cookies(self, request_url: URL) -> \"BaseCookie[str]\":\n        return SimpleCookie()\n"}
A user will ask you to solve a task. You should first draft your thinking process (inner monologue). Then, generate the solution.

Your response format must follow the template below:
<think>
Your thoughts or/and draft, like working through an exercise on scratch paper. Be as casual and as long as you want until you are confident to generate a correct solution.
</think>
<solution>
Final solution presented to the user.
</solution>
system
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]

**CookieJar Fails to Expire Stale Cookies When Filtering**

**Description**
When an expired cookie is added to the `CookieJar` and the `filter_cookies` method is called, the stale cookie is not removed as expected. This results in the `CookieJar` retaining expired cookies, leading to incorrect cookie counts.

**Example Code**
```python
from aiohttp import CookieJar, URL
from http.cookies import SimpleCookie
from freezegun import freeze_time

jar = CookieJar()
cookie = SimpleCookie()
cookie['foo'] = 'bar'
cookie['foo']['expires'] = 'Tue, 1 Jan 1990 12:00:00 GMT'

with freeze_time('1980-01-01'):
    jar.update_cookies(cookie)

jar.filter_cookies(URL('http://any.com/'))

# Expected: CookieJar should have 0 cookies after filtering
# Actual: CookieJar still has 1 cookie
```

**Expected Behavior**
After calling `filter_cookies`, any cookies that have expired should be removed from the `CookieJar`, resulting in zero cookies remaining.

**Actual Behavior**
Expired cookies remain in the `CookieJar`, causing it to incorrectly report that it still contains cookies.

[/ISSUE]
--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.

--- BEGIN FILE ---
```
### aiohttp/cookiejar.py
import calendar
import contextlib
import datetime
import itertools
import os  # noqa
import pathlib
import pickle
import re
import time
import warnings
from collections import defaultdict
from http.cookies import BaseCookie, Morsel, SimpleCookie
from math import ceil
from typing import (
    DefaultDict,
    Dict,
    Iterable,
    Iterator,
    List,
    Mapping,
    Optional,
    Set,
    Tuple,
    Union,
    cast,
)

from yarl import URL

from .abc import AbstractCookieJar, ClearCookiePredicate
from .helpers import is_ip_address
from .typedefs import LooseCookies, PathLike, StrOrURL

__all__ = ("CookieJar", "DummyCookieJar")


CookieItem = Union[str, "Morsel[str]"]


class CookieJar(AbstractCookieJar):
    """Implements cookie storage adhering to RFC 6265."""

    DATE_TOKENS_RE = re.compile(
        r"[\x09\x20-\x2F\x3B-\x40\x5B-\x60\x7B-\x7E]*"
        r"(?P<token>[\x00-\x08\x0A-\x1F\d:a-zA-Z\x7F-\xFF]+)"
    )

    DATE_HMS_TIME_RE = re.compile(r"(\d{1,2}):(\d{1,2}):(\d{1,2})")

    DATE_DAY_OF_MONTH_RE = re.compile(r"(\d{1,2})")

    DATE_MONTH_RE = re.compile(
        "(jan)|(feb)|(mar)|(apr)|(may)|(jun)|(jul)|" "(aug)|(sep)|(oct)|(nov)|(dec)",
        re.I,
    )

    DATE_YEAR_RE = re.compile(r"(\d{2,4})")

    # calendar.timegm() fails for timestamps after datetime.datetime.max
    # Minus one as a loss of precision occurs when timestamp() is called.
    MAX_TIME = (
        int(datetime.datetime.max.replace(tzinfo=datetime.timezone.utc).timestamp()) - 1
    )
    try:
        calendar.timegm(time.gmtime(MAX_TIME))
    except (OSError, ValueError):
        # Hit the maximum representable time on Windows
        # https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/localtime-localtime32-localtime64
        # Throws ValueError on PyPy 3.8 and 3.9, OSError elsewhere
        MAX_TIME = calendar.timegm((3000, 12, 31, 23, 59, 59, -1, -1, -1))
    except OverflowError:
        # #4515: datetime.max may not be representable on 32-bit platforms
        MAX_TIME = 2**31 - 1
    # Avoid minuses in the future, 3x faster
    SUB_MAX_TIME = MAX_TIME - 1

    def __init__(
        self,
        *,
        unsafe: bool = False,
        quote_cookie: bool = True,
        treat_as_secure_origin: Union[StrOrURL, List[StrOrURL], None] = None,
    ) -> None:
        self._cookies: DefaultDict[Tuple[str, str], SimpleCookie] = defaultdict(
            SimpleCookie
        )
        self._host_only_cookies: Set[Tuple[str, str]] = set()
        self._unsafe = unsafe
        self._quote_cookie = quote_cookie
        if treat_as_secure_origin is None:
            treat_as_secure_origin = []
        elif isinstance(treat_as_secure_origin, URL):
            treat_as_secure_origin = [treat_as_secure_origin.origin()]
        elif isinstance(treat_as_secure_origin, str):
            treat_as_secure_origin = [URL(treat_as_secure_origin).origin()]
        else:
            treat_as_secure_origin = [
                URL(url).origin() if isinstance(url, str) else url.origin()
                for url in treat_as_secure_origin
            ]
        self._treat_as_secure_origin = treat_as_secure_origin
        self._next_expiration: float = ceil(time.time())
        self._expirations: Dict[Tuple[str, str, str], float] = {}

    def save(self, file_path: PathLike) -> None:
        file_path = pathlib.Path(file_path)
        with file_path.open(mode="wb") as f:
            pickle.dump(self._cookies, f, pickle.HIGHEST_PROTOCOL)

    def load(self, file_path: PathLike) -> None:
        file_path = pathlib.Path(file_path)
        with file_path.open(mode="rb") as f:
            self._cookies = pickle.load(f)

    def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None:
        if predicate is None:
            self._next_expiration = ceil(time.time())
            self._cookies.clear()
            self._host_only_cookies.clear()
            self._expirations.clear()
            return

        to_del = []
        now = time.time()
        for (domain, path), cookie in self._cookies.items():
            for name, morsel in cookie.items():
                key = (domain, path, name)
                if (
                    key in self._expirations and self._expirations[key] <= now
                ) or predicate(morsel):
                    to_del.append(key)

        for domain, path, name in to_del:
            self._host_only_cookies.discard((domain, name))
            key = (domain, path, name)
            if key in self._expirations:
                del self._expirations[(domain, path, name)]
            self._cookies[(domain, path)].pop(name, None)

        self._next_expiration = (
            min(*self._expirations.values(), self.SUB_MAX_TIME) + 1
            if self._expirations
            else self.MAX_TIME
        )

    def clear_domain(self, domain: str) -> None:
        self.clear(lambda x: self._is_domain_match(domain, x["domain"]))

    def __iter__(self) -> "Iterator[Morsel[str]]":
        self._do_expiration()
        for val in self._cookies.values():
            yield from val.values()

    def __len__(self) -> int:
        return sum(1 for i in self)

    def _do_expiration(self) -> None:
        self.clear(lambda x: False)

    def _expire_cookie(self, when: float, domain: str, path: str, name: str) -> None:
        self._next_expiration = min(self._next_expiration, when)
        self._expirations[(domain, path, name)] = when

    def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None:
        """Update cookies."""
        hostname = response_url.raw_host

        if not self._unsafe and is_ip_address(hostname):
            # Don't accept cookies from IPs
            return

        if isinstance(cookies, Mapping):
            cookies = cookies.items()

        for name, cookie in cookies:
            if not isinstance(cookie, Morsel):
                tmp = SimpleCookie()
                tmp[name] = cookie  # type: ignore[assignment]
                cookie = tmp[name]

            domain = cookie["domain"]

            # ignore domains with trailing dots
            if domain.endswith("."):
                domain = ""
                del cookie["domain"]

            if not domain and hostname is not None:
                # Set the cookie's domain to the response hostname
                # and set its host-only-flag
                self._host_only_cookies.add((hostname, name))
                domain = cookie["domain"] = hostname

            if domain.startswith("."):
                # Remove leading dot
                domain = domain[1:]
                cookie["domain"] = domain

            if hostname and not self._is_domain_match(domain, hostname):
                # Setting cookies for different domains is not allowed
                continue

            path = cookie["path"]
            if not path or not path.startswith("/"):
                # Set the cookie's path to the response path
                path = response_url.path
                if not path.startswith("/"):
                    path = "/"
                else:
                    # Cut everything from the last slash to the end
                    path = "/" + path[1 : path.rfind("/")]
                cookie["path"] = path
            path = path.rstrip("/")

            max_age = cookie["max-age"]
            if max_age:
                try:
                    delta_seconds = int(max_age)
                    max_age_expiration = min(time.time() + delta_seconds, self.MAX_TIME)
                    self._expire_cookie(max_age_expiration, domain, path, name)
                except ValueError:
                    cookie["max-age"] = ""

            else:
                expires = cookie["expires"]
                if expires:
                    expire_time = self._parse_date(expires)
                    if expire_time:
                        self._expire_cookie(expire_time, domain, path, name)
                    else:
                        cookie["expires"] = ""

            self._cookies[(domain, path)][name] = cookie

        self._do_expiration()

    def filter_cookies(self, request_url: URL = URL()) -> "BaseCookie[str]":
        """Returns this jar's cookies filtered by their attributes."""
        if not isinstance(request_url, URL):
            warnings.warn(
                "The method accepts yarl.URL instances only, got {}".format(
                    type(request_url)
                ),
                DeprecationWarning,
            )
            request_url = URL(request_url)
        filtered: Union[SimpleCookie, "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
        hostname = request_url.raw_host or ""

        is_not_secure = request_url.scheme not in ("https", "wss")
        if is_not_secure and self._treat_as_secure_origin:
            request_origin = URL()
            with contextlib.suppress(ValueError):
                request_origin = request_url.origin()
            is_not_secure = request_origin not in self._treat_as_secure_origin

        # Send shared cookie
        for c in self._cookies[("", "")].values():
            filtered[c.key] = c.value

        if is_ip_address(hostname):
            if not self._unsafe:
                return filtered
            domains: Iterable[str] = (hostname,)
        else:
            # Get all the subdomains that might match a cookie (e.g. "foo.bar.com", "bar.com", "com")
            domains = itertools.accumulate(
                reversed(hostname.split(".")), lambda x, y: f"{y}.{x}"
            )
        # Get all the path prefixes that might match a cookie (e.g. "", "/foo", "/foo/bar")
        paths = itertools.accumulate(
            request_url.path.split("/"), lambda x, y: f"{x}/{y}"
        )
        # Create every combination of (domain, path) pairs.
        pairs = itertools.product(domains, paths)

        # Point 2: https://www.rfc-editor.org/rfc/rfc6265.html#section-5.4
        cookies = itertools.chain.from_iterable(
            self._cookies[p].values() for p in pairs
        )
        path_len = len(request_url.path)
        for cookie in cookies:
            name = cookie.key
            domain = cookie["domain"]

            if (domain, name) in self._host_only_cookies:
                if domain != hostname:
                    continue

            # Skip edge case when the cookie has a trailing slash but request doesn't.
            if len(cookie["path"]) > path_len:
                continue

            if is_not_secure and cookie["secure"]:
                continue

            # It's critical we use the Morsel so the coded_value
            # (based on cookie version) is preserved
            mrsl_val = cast("Morsel[str]", cookie.get(cookie.key, Morsel()))
            mrsl_val.set(cookie.key, cookie.value, cookie.coded_value)
            filtered[name] = mrsl_val

        return filtered

    @staticmethod
    def _is_domain_match(domain: str, hostname: str) -> bool:
        """Implements domain matching adhering to RFC 6265."""
        if hostname == domain:
            return True

        if not hostname.endswith(domain):
            return False

        non_matching = hostname[: -len(domain)]

        if not non_matching.endswith("."):
            return False

        return not is_ip_address(hostname)

    @classmethod
    def _parse_date(cls, date_str: str) -> Optional[int]:
        """Implements date string parsing adhering to RFC 6265."""
        if not date_str:
            return None

        found_time = False
        found_day = False
        found_month = False
        found_year = False

        hour = minute = second = 0
        day = 0
        month = 0
        year = 0

        for token_match in cls.DATE_TOKENS_RE.finditer(date_str):
            token = token_match.group("token")

            if not found_time:
                time_match = cls.DATE_HMS_TIME_RE.match(token)
                if time_match:
                    found_time = True
                    hour, minute, second = (int(s) for s in time_match.groups())
                    continue

            if not found_day:
                day_match = cls.DATE_DAY_OF_MONTH_RE.match(token)
                if day_match:
                    found_day = True
                    day = int(day_match.group())
                    continue

            if not found_month:
                month_match = cls.DATE_MONTH_RE.match(token)
                if month_match:
                    found_month = True
                    assert month_match.lastindex is not None
                    month = month_match.lastindex
                    continue

            if not found_year:
                year_match = cls.DATE_YEAR_RE.match(token)
                if year_match:
                    found_year = True
                    year = int(year_match.group())

        if 70 <= year <= 99:
            year += 1900
        elif 0 <= year <= 69:
            year += 2000

        if False in (found_day, found_month, found_year, found_time):
            return None

        if not 1 <= day <= 31:
            return None

        if year < 1601 or hour > 23 or minute > 59 or second > 59:
            return None

        return calendar.timegm((year, month, day, hour, minute, second, -1, -1, -1))


class DummyCookieJar(AbstractCookieJar):
    """Implements a dummy cookie storage.

    It can be used with the ClientSession when no cookie processing is needed.

    """

    def __iter__(self) -> "Iterator[Morsel[str]]":
        while False:
            yield None

    def __len__(self) -> int:
        return 0

    def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None:
        pass

    def clear_domain(self, domain: str) -> None:
        pass

    def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None:
        pass

    def filter_cookies(self, request_url: URL) -> "BaseCookie[str]":
        return SimpleCookie()

```
--- END FILE ---

Please first localize the bug based on the issue statement, and then generate *SEARCH/REPLACE* edits to fix the issue.

Every *SEARCH/REPLACE* edit must use this format:
1. The file path
2. The start of search block: <<<<<<< SEARCH
3. A contiguous chunk of lines to search for in the existing source code
4. The dividing line: =======
5. The lines to replace into the source code
6. The end of the replace block: >>>>>>> REPLACE

Here is an example:

```python
### mathweb/flask/app.py
<<<<<<< SEARCH
from flask import Flask
=======
import math
from flask import Flask
>>>>>>> REPLACE
```
</solution>

Please note that the *SEARCH/REPLACE* edit REQUIRES PROPER INDENTATION. If you would like to add the line '        print(x)', you must fully write that out, with all those spaces before the code!
Wrap each *SEARCH/REPLACE* edit in a code block as shown in the example above. If you have multiple *SEARCH/REPLACE* edits, use a separate code block for each one.
user