Merlijn van Deen has submitted this change and it was merged.
Change subject: Fix cache key for non-Latin sites
......................................................................
Fix cache key for non-Latin sites
Avoiding using Page.__repr__() as it uses the localized namespace name
and encodes the title into the console encoding, which causes problems
when _create_file_name() tries to encode it again.
Bug: 67488
Change-Id: If49039bac8e8347852c1a04963f678903621d2a9
---
M pywikibot/data/api.py
M tests/dry_api_tests.py
2 files changed, 67 insertions(+), 19 deletions(-)
Approvals:
John Vandenberg: Looks good to me, but someone else must approve
Phe: Looks good to me, but someone else must approve
Merlijn van Deen: Looks good to me, approved
diff --git a/pywikibot/data/api.py b/pywikibot/data/api.py
index 33e46f6..7102074 100644
--- a/pywikibot/data/api.py
+++ b/pywikibot/data/api.py
@@ -483,14 +483,16 @@
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'])
+ # This uses the format of Page.__repr__(), without the encoding
+ # it performs. This string cant be encoded otherwise it creates an
+ # exception when _create_file_name() tries to encode it again.
+ user_key = u'User(User:%s)' % self.site._userinfo['name']
else:
user_key = pywikibot.site.LoginStatus(
max(login_status, pywikibot.site.LoginStatus.NOT_LOGGED_IN))
+ user_key = repr(user_key)
- return (repr(self.site) + repr(user_key) +
- repr(sorted(self.iteritems())))
+ return repr(self.site) + user_key + repr(sorted(self.iteritems()))
def _create_file_name(self):
self.http_params() # normalize self.iteritems()
diff --git a/tests/dry_api_tests.py b/tests/dry_api_tests.py
index 95870ff..1714b59 100644
--- a/tests/dry_api_tests.py
+++ b/tests/dry_api_tests.py
@@ -8,12 +8,13 @@
#
import datetime
+import hashlib
import pywikibot
from pywikibot.data.api import CachedRequest, QueryGenerator
from utils import unittest
-class DryAPITests(unittest.TestCase):
+class DryCachedRequestTests(unittest.TestCase):
def setUp(self):
self.basesite = pywikibot.Site('en', 'wikipedia')
@@ -28,6 +29,10 @@
def test_expiry_formats(self):
self.assertEqual(self.req.expiry, CachedRequest(datetime.timedelta(days=1),
**self.parms).expiry)
+
+ def test_expired(self):
+ self.assertFalse(self.req._expired(datetime.datetime.now()))
+ self.assertTrue(self.req._expired(datetime.datetime.now() -
datetime.timedelta(days=2)))
def test_get_cache_dir(self):
retval = self.req._get_cache_dir()
@@ -44,16 +49,27 @@
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 MockCachedRequestKeyTests(unittest.TestCase):
+ def setUp(self):
+ class MockFamily(pywikibot.family.Family):
+
+ @property
+ def name(self):
+ return 'mock'
+
class MockSite(pywikibot.site.APISite):
_loginstatus = pywikibot.site.LoginStatus.NOT_ATTEMPTED
- _namespaces = {2: 'User'}
+ _namespaces = {2: ['User']}
def __init__(self):
self._user = 'anon'
+ pywikibot.site.BaseSite.__init__(self, 'mock', MockFamily())
+
+ def languages(self):
+ return ['mock']
def user(self):
return self._user
@@ -74,33 +90,63 @@
def __getattr__(self, attr):
raise Exception("Attribute %r not defined" % attr)
- site = MockSite()
- req = CachedRequest(expiry=1, site=site, action='query',
meta='siteinfo')
+ self.site = MockSite()
+
+ def test_cachefile_path_different_users(self):
+ req = CachedRequest(expiry=1, site=self.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')
+ self.site._userinfo = {'name': u'MyUser'}
+ self.site._loginstatus = 0
+ req = CachedRequest(expiry=1, site=self.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')
+ self.site._userinfo = {'name': u'MySysop'}
+ self.site._loginstatus = 1
+ req = CachedRequest(expiry=1, site=self.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)))
+ def test_unicode(self):
+ self.site._userinfo = {'name': u'محمد الفلسطيني'}
+ self.site._loginstatus = 0
+
+ req = CachedRequest(expiry=1, site=self.site,
+ action='query', meta='siteinfo')
+ en_user_path = req._cachefile_path()
+
+ self.site._namespaces = {2: [u'مستخدم']}
+
+ req = CachedRequest(expiry=1, site=self.site,
+ action='query', meta='siteinfo')
+
+ expect = u'MockSite()User(User:محمد الفلسطيني)' + \
+ "[('action', 'query'), ('meta',
'siteinfo')]"
+
+ self.assertEqual(repr(req._uniquedescriptionstr()), repr(expect))
+
+ self.assertEqual(req._uniquedescriptionstr().encode('utf-8'),
+ expect.encode('utf-8'))
+
+ ar_user_path = req._cachefile_path()
+
+ self.assertEqual(en_user_path, ar_user_path)
+
+
+class DryQueryGenTests(unittest.TestCase):
def test_query_constructor(self):
qGen1 = QueryGenerator(action="query", meta="siteinfo")
qGen2 = QueryGenerator(meta="siteinfo")
self.assertEqual(str(qGen1.request), str(qGen2.request))
+
if __name__ == '__main__':
unittest.main()
--
To view, visit
https://gerrit.wikimedia.org/r/149898
To unsubscribe, visit
https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: If49039bac8e8347852c1a04963f678903621d2a9
Gerrit-PatchSet: 4
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: Phe <phil.el(a)free.fr>
Gerrit-Reviewer: jenkins-bot <>