jenkins-bot has submitted this change and it was merged.
Change subject: Fix KeyError if package has been ignored
......................................................................
Fix KeyError if package has been ignored
The 'paths' dict is used to find packages which might
match the location of pywikibot. However it contained paths of
some packages which have already been skipped, and therefore
dont need to be excluded as pywikibot sub-modules.
Change-Id: I4f87941a61d2834e89791becf0181eb9a8ce8271
---
M pywikibot/version.py
1 file changed, 4 insertions(+), 1 deletion(-)
Approvals:
XZise: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/version.py b/pywikibot/version.py
index 2229075..ce95775 100644
--- a/pywikibot/version.py
+++ b/pywikibot/version.py
@@ -371,10 +371,13 @@
(standard_lib is None and name in std_lib_packages):
if 'ver' in info:
data[name] = info
+ else:
+ # Remove the entry from paths, so it isnt processed below
+ del paths[info['path']]
else:
data[name] = info
- # Remove any sub-modules which were loaded with a different name.
+ # Remove any pywikibot sub-modules which were loaded as a package.
# e.g. 'wikipedia_family.py' is loaded as 'wikipedia'
_program_dir = _get_program_dir()
for path, name in paths.items():
--
To view, visit https://gerrit.wikimedia.org/r/185953
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I4f87941a61d2834e89791becf0181eb9a8ce8271
Gerrit-PatchSet: 1
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: jenkins-bot <>
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 <>