jenkins-bot has submitted this change and it was merged.
Change subject: [FIX] MediaWikiVersion: Support non-wmf versions
......................................................................
[FIX] MediaWikiVersion: Support non-wmf versions
Previously it didn't require to match the complete version number. If
now a version '1.25alpha' was used in MediaWikiVersion it just ignored
the 'alpha' part. This now requires that the complete version number is
matched and does allow several different version number suffixes:
* 'wmf<number>'
* 'alpha'
* 'beta<number>'
*
'rc<number>'/'-rc.<number>'/'-rc<number>'/'rc.<number>'
It follows in that order, so an alpha version is considered newer (and
is thus using newer API) than a wmf version, but older than any beta
version. All suffixes are considered older than a version number without
a suffix. If the suffix doesn't follow in this scheme the version number
is invalid.
Because alpha releases might not represent the newest wmf version the
family can now define a 'force_version' number which must return a valid
version number for MediaWikiVersion. If it's not empty that version
number will be used at all times.
This in theory breaks the API as MediaWikiVersion has no 'wmf_version'
attribute, but that shouldn't be used anyway outside of that class. It
has been replaced by '_dev_version' which maps those above to a
'subversion' (e.g. wmf42 = (0, 42)). The stable releases (without a
suffix) use (4,) for simplification of the comparision.
As family's version method shouldn't be used directly anymore it's
marked as deprecated.
Change-Id: Id8b37d16765bae5007456dc9923dc5c81daca4e5
---
M generate_family_file.py
M pywikibot/families/anarchopedia_family.py
M pywikibot/families/wikia_family.py
M pywikibot/families/wowwiki_family.py
M pywikibot/family.py
M pywikibot/site.py
M pywikibot/tools.py
M tests/mediawikiversion_tests.py
8 files changed, 129 insertions(+), 36 deletions(-)
Approvals:
John Vandenberg: Looks good to me, approved
jenkins-bot: Verified
diff --git a/generate_family_file.py b/generate_family_file.py
index 2dd21e4..380fd0c 100644
--- a/generate_family_file.py
+++ b/generate_family_file.py
@@ -185,6 +185,7 @@
\"\"\"
from pywikibot import family
+from pywikibot.tools import deprecated
class Family(family.Family):
def __init__(self):
@@ -210,6 +211,7 @@
f.write(" }[code]\n")
f.write("\n")
+ f.write(" @deprecated('APISite.version()')\n")
f.write(" def version(self, code):\n")
f.write(" return {\n")
for w in self.wikis.values():
diff --git a/pywikibot/families/anarchopedia_family.py
b/pywikibot/families/anarchopedia_family.py
index 42f4a96..789ae2c 100644
--- a/pywikibot/families/anarchopedia_family.py
+++ b/pywikibot/families/anarchopedia_family.py
@@ -4,6 +4,7 @@
__version__ = '$Id$'
from pywikibot import family
+from pywikibot.tools import deprecated
# The Anarchopedia family
@@ -67,6 +68,7 @@
'nob': None,
}
+ @deprecated('APISite.version()')
def version(self, code):
"""Return the version for this family."""
return "1.14alpha"
diff --git a/pywikibot/families/wikia_family.py b/pywikibot/families/wikia_family.py
index 9ab8cdd..7dc627a 100644
--- a/pywikibot/families/wikia_family.py
+++ b/pywikibot/families/wikia_family.py
@@ -4,6 +4,7 @@
__version__ = '$Id$'
from pywikibot import family
+from pywikibot.tools import deprecated
# The Wikia Search family
@@ -25,6 +26,7 @@
"""Return the hostname for every site in this
family."""
return u'www.wikia.com'
+ @deprecated('APISite.version()')
def version(self, code):
"""Return the version for this family."""
return "1.19.20"
diff --git a/pywikibot/families/wowwiki_family.py b/pywikibot/families/wowwiki_family.py
index fbf820e..96b70c0 100644
--- a/pywikibot/families/wowwiki_family.py
+++ b/pywikibot/families/wowwiki_family.py
@@ -4,6 +4,7 @@
__version__ = '$Id$'
from pywikibot import family
+from pywikibot.tools import deprecated
class Family(family.Family):
@@ -61,6 +62,7 @@
"""Return the script path for this family."""
return ''
+ @deprecated('APISite.version()')
def version(self, code):
"""Return the version for this family."""
return '1.19.20'
diff --git a/pywikibot/family.py b/pywikibot/family.py
index bf04dbb..4c62cd4 100644
--- a/pywikibot/family.py
+++ b/pywikibot/family.py
@@ -1097,6 +1097,7 @@
return '%s%s' % (code, self.name)
# Which version of MediaWiki is used?
+ @deprecated('APISite.version()')
def version(self, code):
""" Return MediaWiki version number as a string.
@@ -1105,7 +1106,27 @@
# Here we return the latest mw release for downloading
return '1.24.1'
- @deprecated("version()")
+ def force_version(self, code):
+ """
+ Return a manual version number.
+
+ The site is usually using the version number from the servers'
+ siteinfo, but if there is a problem with that it's possible to return
+ a non-empty string here representing another version number.
+
+ For example, L{pywikibot.tools.MediaWikiVersion} treats version
+ numbers ending with 'alpha', 'beta' or 'rc' as newer than
any version
+ ending with 'wmf<number>'. But if that causes breakage it's
possible
+ to override it here to a version number which doesn't cause breakage.
+
+ @return: A version number which can be parsed using
+ L{pywikibot.tools.MediaWikiVersion}. If empty/None it uses the
+ version returned via siteinfo.
+ @rtype: str
+ """
+ return None
+
+ @deprecated("APISite.version()")
def versionnumber(self, code):
""" DEPRECATED, use version() instead.
diff --git a/pywikibot/site.py b/pywikibot/site.py
index 973edaf..79df01a 100644
--- a/pywikibot/site.py
+++ b/pywikibot/site.py
@@ -2225,13 +2225,15 @@
This overwrites the corresponding family method for APISite class. Use
L{pywikibot.tools.MediaWikiVersion} to compare MediaWiki versions.
"""
- try:
- version = self.siteinfo.get('generator', expiry=1).split('
')[1]
- except pywikibot.data.api.APIError:
- # May occur if you are not logged in (no API read permissions).
- pywikibot.exception(
- 'You have no API read permissions. Seems you are not logged in')
- version = self.family.version(self.code)
+ version = self.force_version()
+ if not version:
+ try:
+ version = self.siteinfo.get('generator', expiry=1).split('
')[1]
+ except pywikibot.data.api.APIError:
+ # May occur if you are not logged in (no API read permissions).
+ pywikibot.exception('You have no API read permissions. Seems '
+ 'you are not logged in')
+ version = self.family.version(self.code)
return version
@property
diff --git a/pywikibot/tools.py b/pywikibot/tools.py
index 6844a1b..0eb772e 100644
--- a/pywikibot/tools.py
+++ b/pywikibot/tools.py
@@ -105,26 +105,51 @@
class MediaWikiVersion(Version):
- """Version object to allow comparing 'wmf' versions with
normal ones."""
+ """
+ Version object to allow comparing 'wmf' versions with normal ones.
- MEDIAWIKI_VERSION = re.compile(r'(\d+(?:\.\d+)*)(?:wmf(\d+))?')
+ The version mainly consist of digits separated by periods. After that is a
+ suffix which may only be 'wmf<number>', 'alpha',
'beta<number>' or
+ '-rc.<number>' (the - and . are optional). They are considered from old
to
+ new in that order with a version number without suffix is considered the
+ newest. This secondary difference is stored in an internal _dev_version
+ attribute.
+
+ Two versions are equal if their normal version and dev version are equal. A
+ version is greater if the normal version or dev version is greater. For
+ example:
+ 1.24 < 1.24.1 < 1.25wmf1 < 1.25alpha < 1.25beta1 < 1.25beta2
+ < 1.25-rc-1 < 1.25-rc.2 < 1.25
+
+ Any other suffixes are considered invalid.
+ """
+
+ MEDIAWIKI_VERSION =
re.compile(r'^(\d+(?:\.\d+)+)(wmf(\d+)|alpha|beta(\d+)|-?rc\.?(\d+))?$')
def parse(self, vstring):
version_match = MediaWikiVersion.MEDIAWIKI_VERSION.match(vstring)
if not version_match:
- raise ValueError('Invalid version number')
+ raise ValueError('Invalid version number
"{0}"'.format(vstring))
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))
+ # The _dev_version numbering scheme might change. E.g. if a stage
+ # between 'alpha' and 'beta' is added, 'beta',
'rc' and stable releases
+ # are reassigned (beta=3, rc=4, stable=5).
+ if version_match.group(3): # wmf version
+ self._dev_version = (0, int(version_match.group(3)))
+ elif version_match.group(4):
+ self._dev_version = (2, int(version_match.group(4)))
+ elif version_match.group(5):
+ self._dev_version = (3, int(version_match.group(5)))
+ elif version_match.group(2) == 'alpha':
+ self._dev_version = (1, )
+ else:
+ self._dev_version = (4, )
+ self.suffix = version_match.group(2) or ''
self.version = tuple(components)
def __str__(self):
- """Return version number with optional "wmf"
suffix."""
- vstring = '.'.join(str(v) for v in self.version)
- if self.wmf_version:
- vstring += 'wmf{0}'.format(self.wmf_version)
- return vstring
+ """Return version number with optional suffix."""
+ return '.'.join(str(v) for v in self.version) + self.suffix
def _cmp(self, other):
if isinstance(other, basestring):
@@ -134,18 +159,11 @@
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:
+ if self._dev_version > other._dev_version:
return 1
- elif self.wmf_version:
+ if self._dev_version < other._dev_version:
return -1
- else:
- return 0
+ return 0
if sys.version_info[0] == 2:
__cmp__ = _cmp
diff --git a/tests/mediawikiversion_tests.py b/tests/mediawikiversion_tests.py
index 8bcb254..17bd115 100644
--- a/tests/mediawikiversion_tests.py
+++ b/tests/mediawikiversion_tests.py
@@ -19,18 +19,62 @@
net = False
+ def _make(self, version):
+ """Create a MediaWikiVersion instance and check that the str
stays."""
+ v = V(version)
+ self.assertEqual(str(v), version)
+ return v
+
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'))
+ """Test comparison between release versions."""
+ self.assertGreater(self._make('1.23'), self._make('1.22.0'))
+ self.assertTrue(self._make('1.23') == self._make('1.23'))
+ self.assertEqual(self._make('1.23'), self._make('1.23'))
def test_wmf_versions(self):
- self.assertGreater(V('1.23wmf10'), V('1.23wmf9'))
- self.assertEqual(V('1.23wmf10'), V('1.23wmf10'))
+ """Test comparison between wmf versions."""
+ self.assertGreater(self._make('1.23wmf10'),
self._make('1.23wmf9'))
+ self.assertEqual(self._make('1.23wmf10'),
self._make('1.23wmf10'))
def test_combined_versions(self):
- self.assertGreater(V('1.23wmf10'), V('1.22.3'))
- self.assertGreater(V('1.23'), V('1.23wmf10'))
+ """Test comparison between wmf versions and release
versions."""
+ self.assertGreater(self._make('1.23wmf10'),
self._make('1.22.3'))
+ self.assertGreater(self._make('1.23'), self._make('1.23wmf10'))
+
+ def test_non_wmf_scheme(self):
+ """Test version numbers not following the
wmf-scheme."""
+ self.assertGreater(self._make('1.23alpha'),
self._make('1.22.3'))
+ self.assertGreater(self._make('1.23alpha'),
self._make('1.23wmf1'))
+ self.assertGreater(self._make('1.23beta1'),
self._make('1.23alpha'))
+ self.assertGreater(self._make('1.23beta2'),
self._make('1.23beta1'))
+ self.assertGreater(self._make('1.23-rc.1'),
self._make('1.23beta2'))
+ self.assertGreater(self._make('1.23-rc.2'),
self._make('1.23-rc.1'))
+ self.assertGreater(self._make('1.23'), self._make('1.23-rc.2'))
+ self.assertEqual(self._make('1.23rc1'), self._make('1.23-rc.1'))
+
+ def _version_check(self, version, digits, dev_version, suffix):
+ v = self._make(version)
+ self.assertEqual(v.version, digits)
+ self.assertEqual(v._dev_version, dev_version)
+ self.assertEqual(v.suffix, suffix)
+
+ def test_interpretation(self):
+ """Test if the data is correctly interpreted."""
+ self._version_check('1.23', (1, 23), (4, ), '')
+ self._version_check('1.23wmf1', (1, 23), (0, 1), 'wmf1')
+ self._version_check('1.23alpha', (1, 23), (1, ), 'alpha')
+ self._version_check('1.23beta1', (1, 23), (2, 1), 'beta1')
+ self._version_check('1.23rc1', (1, 23), (3, 1), 'rc1')
+ self._version_check('1.23-rc1', (1, 23), (3, 1), '-rc1')
+ self._version_check('1.23-rc.1', (1, 23), (3, 1), '-rc.1')
+
+ def test_invalid_versions(self):
+ """Verify that insufficient version fail
creating."""
+ self.assertRaises(ValueError, V, 'invalid')
+ self.assertRaises(ValueError, V, '1number')
+ self.assertRaises(ValueError, V, '1.missing')
+ self.assertRaises(ValueError, V, '1.23wmf-1')
+ self.assertRaises(ValueError, V, '1.23text')
if __name__ == '__main__':
--
To view, visit
https://gerrit.wikimedia.org/r/181771
To unsubscribe, visit
https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Id8b37d16765bae5007456dc9923dc5c81daca4e5
Gerrit-PatchSet: 7
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: XZise <CommodoreFabianus(a)gmx.de>
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: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot <>