jenkins-bot has submitted this change and it was merged.

Change subject: Add Site login status to cache key
......................................................................


Add Site login status to cache key

Some API responses differ depending on the privileges of the user,
which can range from logged out anon to sysop.  The cache needs to
include the login status in the key, so the cached response is not
reused for queries from a different privilege level.

For example, when the cache is empty and the user has never logged
into pywikibot, the unit tests cache site.userinfo with the details
of the logged out user, causing tests which require a logged-in user
to prompt for a password on the console many times per test, and the
site.userinfo is never updated.  With this change, only one password
prompt appears and the result is cached.

Change-Id: I5e480be86a0b7b6a5907cf71690ba9ebed0b04b6
---
M pywikibot/data/api.py
M pywikibot/site.py
M tests/dry_api_tests.py
3 files changed, 67 insertions(+), 2 deletions(-)

Approvals:
  John Vandenberg: Looks good to me, but someone else must approve
  Merlijn van Deen: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/pywikibot/data/api.py b/pywikibot/data/api.py
index 157a99b..f39380b 100644
--- a/pywikibot/data/api.py
+++ b/pywikibot/data/api.py
@@ -462,7 +462,19 @@
             pass
 
     def _uniquedescriptionstr(self):
-        return (repr(self.site) + repr(sorted(self.iteritems())))
+        login_status = self.site._loginstatus
+
+        if login_status > pywikibot.site.LoginStatus.NOT_LOGGED_IN and \
+                hasattr(self.site, '_userinfo') and \
+                'name' in self.site._userinfo:
+            user_key = pywikibot.page.User(self.site,
+                                           self.site._userinfo['name'])
+        else:
+            user_key = pywikibot.site.LoginStatus(
+                max(login_status, pywikibot.site.LoginStatus.NOT_LOGGED_IN))
+
+        return (repr(self.site) + repr(user_key) +
+                repr(sorted(self.iteritems())))
 
     def _create_file_name(self):
         self.http_params()  # normalize self.iteritems()
diff --git a/pywikibot/site.py b/pywikibot/site.py
index 9306d78..e9823fa 100644
--- a/pywikibot/site.py
+++ b/pywikibot/site.py
@@ -69,6 +69,12 @@
         raise KeyError("Value %r could not be found in this enum"
                        % search_value)
 
+    def __init__(self, state):
+        self.state = state
+
+    def __repr__(self):
+        return 'LoginStatus(%s)' % (LoginStatus.name(self.state))
+
 
 def Family(fam=None, fatal=True):
     """Import the named family.
diff --git a/tests/dry_api_tests.py b/tests/dry_api_tests.py
index 8e0cd69..7d30ccc 100644
--- a/tests/dry_api_tests.py
+++ b/tests/dry_api_tests.py
@@ -10,7 +10,7 @@
 import datetime
 import pywikibot
 from pywikibot.data.api import CachedRequest, QueryGenerator
-from tests.utils import unittest
+from utils import unittest
 
 
 class DryAPITests(unittest.TestCase):
@@ -44,6 +44,53 @@
         self.assertNotEqual(self.req._cachefile_path(), 
self.diffreq._cachefile_path())
         self.assertNotEqual(self.req._cachefile_path(), 
self.diffsite._cachefile_path())
 
+    def test_cachefile_path_different_users(self):
+        # Mock basesite object to test this.
+        class MockSite(pywikibot.site.APISite):
+
+            _namespaces = {2: 'User'}
+
+            def __init__(self):
+                self._user = 'anon'
+
+            def user(self):
+                return self._user
+
+            def encoding(self):
+                return 'utf-8'
+
+            def encodings(self):
+                return []
+
+            def _getsiteinfo(self):
+                self._siteinfo = {'case': 'first-letter'}
+                return {}
+
+            def __repr__(self):
+                return "MockSite()"
+
+            def __getattr__(self, attr):
+                raise Exception("Attribute %r not defined" % attr)
+
+        site = MockSite()
+        req = CachedRequest(expiry=1, site=site, action='query', 
meta='siteinfo')
+        anonpath = req._cachefile_path()
+
+        site._userinfo = {'name': u'user'}
+        site._loginstatus = 0
+        req = CachedRequest(expiry=1, site=site, action='query', 
meta='siteinfo')
+        userpath = req._cachefile_path()
+
+        self.assertNotEqual(anonpath, userpath)
+
+        site._userinfo = {'name': u'sysop'}
+        site._loginstatus = 1
+        req = CachedRequest(expiry=1, site=site, action='query', 
meta='siteinfo')
+        sysoppath = req._cachefile_path()
+
+        self.assertNotEqual(anonpath, sysoppath)
+        self.assertNotEqual(userpath, sysoppath)
+
     def test_expired(self):
         self.assertFalse(self.req._expired(datetime.datetime.now()))
         self.assertTrue(self.req._expired(datetime.datetime.now() - 
datetime.timedelta(days=2)))

-- 
To view, visit https://gerrit.wikimedia.org/r/132807
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I5e480be86a0b7b6a5907cf71690ba9ebed0b04b6
Gerrit-PatchSet: 4
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: Merlijn van Deen <valhall...@arctus.nl>
Gerrit-Reviewer: John Vandenberg <jay...@gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgr...@gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhall...@arctus.nl>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to