jenkins-bot has submitted this change. ( 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1324215?usp=email )

Change subject: login: Reuse retry time snapshot
......................................................................

login: Reuse retry time snapshot

Capture the current time while checking the throttled-login deadline.

Reuse it when calculating the delay so the check and sleep use the same instant.

Change-Id: I7c8a578fb9d4233d985aba6397c5cb6bf8735dda
---
M pywikibot/login.py
M tests/login_tests.py
2 files changed, 45 insertions(+), 4 deletions(-)

Approvals:
  jenkins-bot: Verified
  Xqt: Looks good to me, approved




diff --git a/pywikibot/login.py b/pywikibot/login.py
index c79acaa..6ae3747 100644
--- a/pywikibot/login.py
+++ b/pywikibot/login.py
@@ -435,8 +435,8 @@
         :raises APIError: API login error
         """
         if hasattr(self, '_waituntil') \
-           and datetime.datetime.now() < self._waituntil:
-            diff = self._waituntil - datetime.datetime.now()
+           and (now := datetime.datetime.now()) < self._waituntil:
+            diff = self._waituntil - now
             pywikibot.warning(f'Too many tries, waiting {diff.seconds}'
                               ' seconds before retrying.')
             pywikibot.sleep(diff.seconds)
diff --git a/tests/login_tests.py b/tests/login_tests.py
index 2304abc..73b776f 100755
--- a/tests/login_tests.py
+++ b/tests/login_tests.py
@@ -11,17 +11,19 @@
 from __future__ import annotations

 import builtins
+import datetime
 import unittest
 import uuid
 from collections import defaultdict
 from io import StringIO
 from pathlib import Path
+from types import SimpleNamespace
 from unittest import mock

 from pywikibot.exceptions import NoUsernameError
-from pywikibot.login import LoginManager
+from pywikibot.login import ClientLoginManager, LoginManager
 from pywikibot.tools import PYTHON_VERSION
-from tests.aspects import DefaultSiteTestCase
+from tests.aspects import DefaultSiteTestCase, TestCase


 class FakeFamily:
@@ -88,6 +90,45 @@
         self.assertEqual(lm.username, FakeUsername)


+class TestClientLoginManager(TestCase):
+
+    """Test offline ClientLoginManager behavior."""
+
+    net = False
+
+    def test_reuses_retry_time(self) -> None:
+        """Test that retry calculation uses one time snapshot."""
+        now = datetime.datetime(2026, 1, 1, 12)
+        manager = object.__new__(ClientLoginManager)
+        manager.site = SimpleNamespace()
+        manager.login_name = None
+        manager.password = None
+        manager._waituntil = now + datetime.timedelta(seconds=10)
+        clock = mock.Mock(side_effect=[
+            now,
+            now + datetime.timedelta(seconds=4),
+        ])
+        # Replacing datetime.datetime mutates the shared datetime module and
+        # breaks PyPy's datetime comparison type check.
+        datetime_module = SimpleNamespace(
+            datetime=SimpleNamespace(now=clock),
+            timedelta=datetime.timedelta,
+        )
+
+        with (
+            mock.patch('pywikibot.login.datetime', datetime_module),
+            mock.patch('pywikibot.login.pywikibot.sleep') as sleep,
+            mock.patch('pywikibot.login.pywikibot.warning') as warning,
+            self.assertRaisesRegex(RuntimeError, 'login_name'),
+        ):
+            manager.login_to_site()
+
+        clock.assert_called_once_with()
+        sleep.assert_called_once_with(10)
+        warning.assert_called_once_with(
+            'Too many tries, waiting 10 seconds before retrying.')
+
+
 @mock.patch('pywikibot.Site', FakeSite)
 class TestPasswordFile(DefaultSiteTestCase):


--
To view, visit 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1324215?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.wikimedia.org/r/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: I7c8a578fb9d4233d985aba6397c5cb6bf8735dda
Gerrit-Change-Number: 1324215
Gerrit-PatchSet: 3
Gerrit-Owner: Mahveotm <[email protected]>
Gerrit-Reviewer: Xqt <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
Pywikibot-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to