jenkins-bot has submitted this change and it was merged.
Change subject: [FIX] Allow comparison of wmf versions ......................................................................
[FIX] Allow comparison of wmf versions
The current LooseVersion class used doesn't really interpret the wmf-version numbers like they behave. The wanted behaviour is the following: 1.23 < 1.24wmf10 < 1.24
Now LooseVersion interprets the second version number as: 1.24.wmf.10 and so tries to compare 'wmf' with the third number of another version if the first two are the same (e.g. 1.24.1) which does fail (on Python 3) or says that 'wmf' is newer than '1' (which is the wrong order as wmf-versions are like alpha versions).
This adds MediaWikiVersion class to the pywikibot.tools package which interprets 1.24wmf10 as 1.24 with wmf number 10. If the wmf number is set a identical version number without it (e.g. 1.24) is treated as newer.
In theory only pywikibot.site and tests.site_tests does need it, because all comparisons don't touch the third number, but I changed them to have a consistent usage. Only generate_family_file doesn't use it, because it doesn't use the pywikibot package at all and the comparison is safe with current version numbers.
Change-Id: I03dee15be9bb156fde22b9c75d9aac1730b78648 --- M pywikibot/data/api.py M pywikibot/family.py M pywikibot/site.py M pywikibot/textlib.py M pywikibot/tools.py M scripts/cosmetic_changes.py M tests/__init__.py A tests/mediawikiversion_tests.py M tests/site_tests.py 9 files changed, 99 insertions(+), 8 deletions(-)
Approvals: Mpaa: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/data/api.py b/pywikibot/data/api.py index b3ba2d9..116d13e 100644 --- a/pywikibot/data/api.py +++ b/pywikibot/data/api.py @@ -24,10 +24,10 @@ import re import traceback import time -from distutils.version import LooseVersion as LV
import pywikibot from pywikibot import config, login +from pywikibot.tools import MediaWikiVersion as LV from pywikibot.exceptions import Server504Error, FatalServerError, Error
import sys diff --git a/pywikibot/family.py b/pywikibot/family.py index 1bfd558..8941078 100644 --- a/pywikibot/family.py +++ b/pywikibot/family.py @@ -1043,7 +1043,7 @@ def version(self, code): """ Return MediaWiki version number as a string.
- Use LooseVersion from distutils.version to compare version strings. + Use L{pywikibot.tools.MediaWikiVersion} to compare version strings. """ # Here we return the latest mw release for downloading return '1.23.2' @@ -1052,7 +1052,7 @@ def versionnumber(self, code): """ DEPRECATED, use version() instead.
- Use distutils.version.LooseVersion to compare version strings. + Use L{pywikibot.tools.MediaWikiVersion} to compare version strings. Return an int identifying MediaWiki version.
Currently this is implemented as returning the minor version diff --git a/pywikibot/site.py b/pywikibot/site.py index 17c47aa..12cde3b 100644 --- a/pywikibot/site.py +++ b/pywikibot/site.py @@ -18,7 +18,6 @@ import os import re import sys -from distutils.version import LooseVersion as LV from collections import Iterable, Container, namedtuple import threading import time @@ -30,6 +29,7 @@ from pywikibot.tools import ( itergroup, deprecated, deprecate_arg, UnicodeMixin, ComparableMixin, ) +from pywikibot.tools import MediaWikiVersion as LV from pywikibot.throttle import Throttle from pywikibot.data import api from pywikibot.exceptions import ( @@ -1977,7 +1977,7 @@ Return live project version number as a string.
This overwrites the corresponding family method for APISite class. Use - LooseVersion from distutils.version to compare versions. + L{pywikibot.tools.MediaWikiVersion} to compare MediaWiki versions. """ try: version = self.siteinfo.get('generator', expiry=1).split(' ')[1] diff --git a/pywikibot/textlib.py b/pywikibot/textlib.py index 64da90b..e210acc 100644 --- a/pywikibot/textlib.py +++ b/pywikibot/textlib.py @@ -1044,7 +1044,7 @@ # if self.site().isInterwikiLink(name): # continue # # {{DEFAULTSORT:...}} -# from distutils.version import LooseVersion as LV +# from pywikibot.tools import MediaWikiVersion as LV # defaultKeys = LV(self.site.version()) > LV("1.13") and \ # self.site().getmagicwords('defaultsort') # # It seems some wikis does not have this magic key diff --git a/pywikibot/tools.py b/pywikibot/tools.py index 10c78f6..3ef95c4 100644 --- a/pywikibot/tools.py +++ b/pywikibot/tools.py @@ -11,10 +11,13 @@ import sys import threading import time +import re from collections import Mapping +from distutils.version import Version
if sys.version_info[0] > 2: import queue as Queue + basestring = (str,) else: import Queue
@@ -77,6 +80,53 @@ return self._compare(other, lambda s, o: s != o)
+class MediaWikiVersion(Version): + + """Version object to allow comparing 'wmf' versions with normal ones.""" + + MEDIAWIKI_VERSION = re.compile(r'(\d+(?:.\d+)*)(?:wmf(\d+))?') + + def parse(self, vstring): + version_match = MediaWikiVersion.MEDIAWIKI_VERSION.match(vstring) + if not version_match: + raise ValueError('Invalid version number') + components = [int(n) for n in version_match.group(1).split('.')] + self.wmf_version = None + if version_match.group(2): # wmf version + self.wmf_version = int(version_match.group(2)) + self.version = tuple(components) + + def __str__(self): + vstring = '.'.join(str(v) for v in self.version) + if self.wmf_version: + vstring += 'wmf{0}'.format(self.wmf_version) + return vstring + + def _cmp(self, other): + if isinstance(other, basestring): + other = MediaWikiVersion(other) + + if self.version > other.version: + return 1 + if self.version < other.version: + return -1 + if self.wmf_version and other.wmf_version: + if self.wmf_version > other.wmf_version: + return 1 + if self.wmf_version < other.wmf_version: + return -1 + return 0 + elif other.wmf_version: + return 1 + elif self.wmf_version: + return -1 + else: + return 0 + + if sys.version_info[0] == 2: + __cmp__ = _cmp + + class ThreadedGenerator(threading.Thread):
"""Look-ahead generator class. diff --git a/scripts/cosmetic_changes.py b/scripts/cosmetic_changes.py index 75d5c56..e758452 100755 --- a/scripts/cosmetic_changes.py +++ b/scripts/cosmetic_changes.py @@ -74,7 +74,7 @@ #
import re -from distutils.version import LooseVersion as LV +from pywikibot.tools import MediaWikiVersion as LV import pywikibot import isbn from pywikibot import config, i18n, textlib, pagegenerators, Bot diff --git a/tests/__init__.py b/tests/__init__.py index 9f9782e..afe7ab1 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -51,6 +51,7 @@
library_test_modules = [ 'date', + 'mediawikiversion', 'ipregex', 'xmlreader', 'textlib', diff --git a/tests/mediawikiversion_tests.py b/tests/mediawikiversion_tests.py new file mode 100644 index 0000000..8bcb254 --- /dev/null +++ b/tests/mediawikiversion_tests.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +"""Tests for the tools.MediaWikiVersion class.""" +# +# (C) Pywikibot team, 2008-2014 +# +# Distributed under the terms of the MIT license. +# +__version__ = '$Id$' + + +from pywikibot.tools import MediaWikiVersion as V + +from tests.aspects import unittest, TestCase + + +class TestMediaWikiVersion(TestCase): + + """Test MediaWikiVersion class comparisons.""" + + net = False + + def test_normal_versions(self): + self.assertGreater(V('1.23'), V('1.22.0')) + self.assertTrue(V('1.23') == V('1.23')) + self.assertEqual(V('1.23'), V('1.23')) + + def test_wmf_versions(self): + self.assertGreater(V('1.23wmf10'), V('1.23wmf9')) + self.assertEqual(V('1.23wmf10'), V('1.23wmf10')) + + def test_combined_versions(self): + self.assertGreater(V('1.23wmf10'), V('1.22.3')) + self.assertGreater(V('1.23'), V('1.23wmf10')) + + +if __name__ == '__main__': + try: + unittest.main() + except SystemExit: + pass diff --git a/tests/site_tests.py b/tests/site_tests.py index 127e71f..6f63ee7 100644 --- a/tests/site_tests.py +++ b/tests/site_tests.py @@ -9,12 +9,12 @@
import sys -from distutils.version import LooseVersion as LV from collections import Iterable from datetime import datetime import re
import pywikibot +from pywikibot.tools import MediaWikiVersion as LV from pywikibot.data import api from tests.aspects import ( unittest, TestCase,
pywikibot-commits@lists.wikimedia.org