Repository: aio-libs/aiohttp

Issue:
time in cookiejar.py tests reaches to far in to the future on some systems 
## Long story short

Regression of #1188

## Expected behaviour

Tests pass on armv7l

## Actual behaviour

Test run fails at test_cookiejar.py:383: OverflowError

## Steps to reproduce

Run tests

## Your environment

linux 4.19
nixos 20.03
arm v7l
python 3.7
aiohttp client-3.6.2

## Log

```
        ts_before = datetime.datetime(
            1975, 1, 1, tzinfo=datetime.timezone.utc).timestamp()

        ts_after = datetime.datetime(
            2115, 1, 1, tzinfo=datetime.timezone.utc).timestamp()

        cookies_sent = self.timed_request(
            "http://expirestest.com/", ts_before, ts_before)

        self.assertEqual(set(cookies_sent.keys()), {
            "shared-cookie",
            "expires-cookie"
        })

        cookies_sent = self.timed_request(
>           "http://expirestest.com/", ts_before, ts_after)

test_cookiejar.py:590:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <test_cookiejar.TestCookieJarSafe testMethod=test_expires>
url = 'http://expirestest.com/'
update_time = datetime.datetime(1975, 1, 1, 0, 0), send_time = 4575744000.0

    def timed_request(self, url, update_time, send_time):
        if isinstance(update_time, int):
            update_time = datetime.timedelta(seconds=update_time)
        elif isinstance(update_time, float):
            update_time = datetime.datetime.fromtimestamp(update_time)
        if isinstance(send_time, int):
            send_time = datetime.timedelta(seconds=send_time)
        elif isinstance(send_time, float):
>           send_time = datetime.datetime.fromtimestamp(send_time)
E           OverflowError: timestamp out of range for platform time_t

test_cookiejar.py:383: OverflowError
```



Discussion:
If you want to propose a fix -- you are welcome!
Otherwise, I don't care because tests are passed on all supported platforms on our CI runs.
FTR Travis CI now provides VMs with ARM arch too.
Good for Travis, sure
We can reproduce this on 32-bit x86. I'll send a pull request soonish.

Resolving patch:
diff --git a/aiohttp/cookiejar.py b/aiohttp/cookiejar.py
--- a/aiohttp/cookiejar.py
+++ b/aiohttp/cookiejar.py
@@ -50,6 +50,9 @@ class CookieJar(AbstractCookieJar):
     MAX_TIME = datetime.datetime.max.replace(
         tzinfo=datetime.timezone.utc)
 
+    MAX_32BIT_TIME = datetime.datetime.utcfromtimestamp(
+        2**31 - 1)
+
     def __init__(self, *, unsafe: bool=False, quote_cookie: bool=True) -> None:
         self._loop = get_running_loop()
         self._cookies = defaultdict(SimpleCookie)  #type: DefaultDict[str, SimpleCookie[str]]  # noqa
@@ -58,6 +61,12 @@ def __init__(self, *, unsafe: bool=False, quote_cookie: bool=True) -> None:
         self._quote_cookie = quote_cookie
         self._next_expiration = next_whole_second()
         self._expirations = {}  # type: Dict[Tuple[str, str], datetime.datetime]  # noqa: E501
+        # #4515: datetime.max may not be representable on 32-bit platforms
+        self._max_time = self.MAX_TIME
+        try:
+            self._max_time.timestamp()
+        except OverflowError:
+            self._max_time = self.MAX_32BIT_TIME
 
     def save(self, file_path: PathLike) -> None:
         file_path = pathlib.Path(file_path)
@@ -89,7 +98,7 @@ def _do_expiration(self) -> None:
             return
         if not self._expirations:
             return
-        next_expiration = self.MAX_TIME
+        next_expiration = self._max_time
         to_del = []
         cookies = self._cookies
         expirations = self._expirations
@@ -107,7 +116,7 @@ def _do_expiration(self) -> None:
             self._next_expiration = (next_expiration.replace(microsecond=0) +
                                      datetime.timedelta(seconds=1))
         except OverflowError:
-            self._next_expiration = self.MAX_TIME
+            self._next_expiration = self._max_time
 
     def _expire_cookie(self, when: datetime.datetime, domain: str, name: str
                        ) -> None:
@@ -175,7 +184,7 @@ def update_cookies(self,
                             datetime.datetime.now(datetime.timezone.utc) +
                             datetime.timedelta(seconds=delta_seconds))
                     except OverflowError:
-                        max_age_expiration = self.MAX_TIME
+                        max_age_expiration = self._max_time
                     self._expire_cookie(max_age_expiration,
                                         domain, name)
                 except ValueError:


Test patch:
diff --git a/tests/test_cookiejar.py b/tests/test_cookiejar.py
--- a/tests/test_cookiejar.py
+++ b/tests/test_cookiejar.py
@@ -601,7 +601,7 @@ def test_expires(self) -> None:
             1975, 1, 1, tzinfo=datetime.timezone.utc).timestamp()
 
         ts_after = datetime.datetime(
-            2115, 1, 1, tzinfo=datetime.timezone.utc).timestamp()
+            2030, 1, 1, tzinfo=datetime.timezone.utc).timestamp()
 
         cookies_sent = self.timed_request(
             "http://expirestest.com/", ts_before, ts_before)