jenkins-bot has submitted this change and it was merged.
Change subject: site.hasExtension: working implementation & tests ......................................................................
site.hasExtension: working implementation & tests
Changes: 1. self.siteinfo does not contain information on extensions - it only contains the 'general' section of the siteinfo query. Extensions are now stored as self._extensions. 2. self.hasExtension returned an Exception if the server did not return loaded extensions. It now has a feature do define what the return value should be instead -- this is practical for 'must have extension' or 'must not have extension' scenarios, where a call if site.hasExtension('something', False): ... do something
is much more practical than try: if site.hasExtension('something'): ... do something except NotImplementedError: pass
3. Added tests to test correct behavior. This depends on the Disambiguator extension being loaded on mysite (=enwiki).
Change-Id: Ic4f5157ae4d1c1b1f69e99a2340a95e231fb4b46 --- M pywikibot/site.py M tests/site_tests.py 2 files changed, 42 insertions(+), 5 deletions(-)
Approvals: Legoktm: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/site.py b/pywikibot/site.py index 43ec1df..8939b28 100644 --- a/pywikibot/site.py +++ b/pywikibot/site.py @@ -1126,12 +1126,28 @@ continue # this is a less preferred form so it goes at the end self._namespaces[int(item['id'])].append(item["*"]) + if 'extensions' in sidata: + self._extensions = sidata['extensions'] + else: + self._extensions = None
- def hasExtension(self, name): - if not 'extensions' in self.siteinfo: - return NotImplementedError("Feature 'hasExtension' only available in MW 1.14+") - for ext in self.siteinfo['extensions']: - if ext['name'] == name: + def hasExtension(self, name, unknown=NotImplementedError): + """ Determine whether extension `name` is loaded. + + @param name The extension to check for + @param unknown The value to return if the site does not list loaded + extensions. Valid values are an exception to raise, + True or False. Default: NotImplementedError + """ + if not hasattr(self, '_extensions'): + self._getsiteinfo() + if self._extensions is None: + if isinstance(unknown, type) and issubclass(unknown, Exception): + raise unknown("Feature 'hasExtension' only available in MW 1.14+") + else: + return unknown + for ext in self._extensions: + if ext['name'].lower() == name.lower(): return True return False
diff --git a/tests/site_tests.py b/tests/site_tests.py index 6d41c98..86f54ec 100644 --- a/tests/site_tests.py +++ b/tests/site_tests.py @@ -933,6 +933,27 @@ self.assertType(rndpage, pywikibot.Page) self.assertTrue(rndpage.namespace() in [6, 7])
+ def testExtensions(self): + # test automatically getting _extensions + del mysite._extensions + self.assertTrue(mysite.hasExtension('Disambiguator')) + + # test case-sensitivity + self.assertTrue(mysite.hasExtension('disambiguator')) + + self.assertFalse(mysite.hasExtension('ThisExtensionDoesNotExist')) + + # test behavior for sites that do not report extensions + mysite._extensions = None + self.assertRaises(NotImplementedError, mysite.hasExtension, ('anything')) + + class MyException(Exception): + pass + self.assertRaises(MyException, mysite.hasExtension, 'anything', MyException) + + self.assertTrue(mysite.hasExtension('anything', True)) + self.assertFalse(mysite.hasExtension('anything', False)) + del mysite._extensions
if __name__ == '__main__': try: