jenkins-bot has submitted this change and it was merged.
Change subject: Use Site interface in cache key
......................................................................
Use Site interface in cache key
pywikibot.Site is invoked with different values for 'interface',
notably 'DataSite' is used by APISite.data_repository().
If a DataSite is instantiated before an APISite for a wiki, it is
cached, and returned when an APISite object is requested. DataSite
overrides APISite/BaseSite methods, including raising exceptions for
deprecated methods, so the cached & returned DataSite is not an acceptable
returned value if an APISite was requested.
Bug: 71451
Change-Id: I93195dcba3185c6df233bac89ed981ddccc78abd
---
M pywikibot/__init__.py
1 file changed, 1 insertion(+), 1 deletion(-)
Approvals:
Mpaa: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py
index 394043c..dd3d4f1 100644
--- a/pywikibot/__init__.py
+++ b/pywikibot/__init__.py
@@ -528,7 +528,7 @@
__Site = getattr(tmp, interface)
except ImportError:
raise ValueError("Invalid interface name '%(interface)s'" % locals())
- key = '%s:%s:%s' % (fam, code, user)
+ key = '%s:%s:%s:%s' % (interface, fam, code, user)
if key not in _sites or not isinstance(_sites[key], __Site):
_sites[key] = __Site(code=code, fam=fam, user=user, sysop=sysop)
debug(u"Instantiating Site object '%(site)s'"
--
To view, visit https://gerrit.wikimedia.org/r/163784
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I93195dcba3185c6df233bac89ed981ddccc78abd
Gerrit-PatchSet: 1
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: Mpaa <mpaa.wiki(a)gmail.com>
Gerrit-Reviewer: jenkins-bot <>
jenkins-bot has submitted this change and it was merged.
Change subject: listpages.py: Link object might not have _site attribute
......................................................................
listpages.py: Link object might not have _site attribute
Replaced Link._site with Link.site property.
Change-Id: Ie17cb9f6229841216665169899d1ac1669a9a81f
---
M scripts/listpages.py
1 file changed, 4 insertions(+), 3 deletions(-)
Approvals:
XZise: Looks good to me, approved
jenkins-bot: Verified
diff --git a/scripts/listpages.py b/scripts/listpages.py
index aa10f47..e17c686 100644
--- a/scripts/listpages.py
+++ b/scripts/listpages.py
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
-"""
+r"""
Print a list of pages, as defined by page generator parameters.
+
Optionally, it also prints page content to STDOUT.
These parameters are supported to specify which pages titles to print:
@@ -110,8 +111,7 @@
is found when outputlang is not None.
"""
-
- self.site = page._link._site
+ self.site = page._link.site
self.title = page._link.title
self.loc_title = page._link.canonical_title()
self.can_title = page._link.ns_title()
@@ -142,6 +142,7 @@
def main(*args):
+ """Main function."""
gen = None
notitle = False
fmt = '1'
--
To view, visit https://gerrit.wikimedia.org/r/163750
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ie17cb9f6229841216665169899d1ac1669a9a81f
Gerrit-PatchSet: 2
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: Mpaa <mpaa.wiki(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: Mpaa <mpaa.wiki(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: [FEAT] Deprecrate module classes and variables
......................................................................
[FEAT] Deprecrate module classes and variables
This adds a way to deprecrate classes or variables in modules. The
difference to '@deprecated' is that the access alone is important and
not calling the function. So this warns also if someone is just
importing a class (e.g. 'from pywikibot.excptions import
UploadWarning').
Unfortunately __getattr__ is not available on module level, so the
module must be wrapped in a class which redirects all accesses.
Change-Id: I3e83472ba780d9d99745c8dff864926432e9f254
---
M pywikibot/__init__.py
M pywikibot/exceptions.py
M pywikibot/page.py
M pywikibot/tools.py
4 files changed, 86 insertions(+), 5 deletions(-)
Approvals:
John Vandenberg: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py
index 0c9ac51..394043c 100644
--- a/pywikibot/__init__.py
+++ b/pywikibot/__init__.py
@@ -61,7 +61,7 @@
# pep257 doesn't understand when the first entry is on the next line
__all__ = ('config', 'ui', 'UnicodeMixin', 'translate',
- 'Page', 'FilePage', 'ImagePage', 'Category', 'Link', 'User',
+ 'Page', 'FilePage', 'Category', 'Link', 'User',
'ItemPage', 'PropertyPage', 'Claim', 'TimeStripper',
'html2unicode', 'url2unicode', 'unicode2html',
'stdout', 'output', 'warning', 'error', 'critical', 'debug',
@@ -542,7 +542,6 @@
from .page import (
Page,
FilePage,
- ImagePage,
Category,
Link,
User,
@@ -714,3 +713,6 @@
# identification for debugging purposes
_putthread.setName('Put-Thread')
_putthread.setDaemon(True)
+
+wrapper = pywikibot.tools.ModuleDeprecationWrapper(__name__)
+wrapper._add_deprecated_attr('ImagePage', FilePage)
diff --git a/pywikibot/exceptions.py b/pywikibot/exceptions.py
index ed620e1..7022935 100644
--- a/pywikibot/exceptions.py
+++ b/pywikibot/exceptions.py
@@ -374,6 +374,7 @@
pass
-# TODO: Warn about the deprecated usage
import pywikibot.data.api
-UploadWarning = pywikibot.data.api.UploadWarning
+import pywikibot.tools
+wrapper = pywikibot.tools.ModuleDeprecationWrapper(__name__)
+wrapper._add_deprecated_attr('UploadWarning', pywikibot.data.api.UploadWarning)
diff --git a/pywikibot/page.py b/pywikibot/page.py
index 70f8dd1..c17dd9b 100644
--- a/pywikibot/page.py
+++ b/pywikibot/page.py
@@ -1930,7 +1930,9 @@
self, step=step, total=total, content=content)
-ImagePage = FilePage
+import pywikibot.tools
+wrapper = pywikibot.tools.ModuleDeprecationWrapper(__name__)
+wrapper._add_deprecated_attr('ImagePage', FilePage)
class Category(Page):
diff --git a/pywikibot/tools.py b/pywikibot/tools.py
index 3ef95c4..c11d0d7 100644
--- a/pywikibot/tools.py
+++ b/pywikibot/tools.py
@@ -425,6 +425,82 @@
return Wrapper().call
+class ModuleDeprecationWrapper(object):
+
+ """A wrapper for a module to deprecate classes or variables of it."""
+
+ def __init__(self, module):
+ """
+ Initialise the wrapper.
+
+ It will automatically overwrite the module with this instance in
+ C{sys.modules}.
+
+ @param module: The module name or instance
+ @type module: str or module
+ """
+ if isinstance(module, basestring):
+ module = sys.modules[module]
+ super(ModuleDeprecationWrapper, self).__setattr__('_deprecated', {})
+ super(ModuleDeprecationWrapper, self).__setattr__('_module', module)
+ sys.modules[module.__name__] = self
+
+ def _add_deprecated_attr(self, name, replacement=None,
+ replacement_name=None):
+ """
+ Add the name to the local deprecated names dict.
+
+ @param name: The name of the deprecated class or variable. It may not
+ be already deprecated.
+ @type name: str
+ @param replacement: The replacement value which should be returned
+ instead. If the name is already an attribute of that module this
+ must be None. If None it'll return the attribute of the module.
+ @type replacement: any
+ @param replacement_name: The name of the new replaced value. Required
+ if C{replacement} is not None and it has no __name__ attribute.
+ @type replacement_name: str
+ """
+ if '.' in name:
+ raise ValueError('Deprecated name "{0}" may not contain '
+ '".".'.format(name))
+ if name in self._deprecated:
+ raise ValueError('Name "{0}" is already deprecated.'.format(name))
+ if replacement is not None and hasattr(self._module, name):
+ raise ValueError('Module has already an attribute named '
+ '"{0}".'.format(name))
+ if replacement_name is None:
+ if hasattr(replacement, '__name__'):
+ replacement_name = replacement.__module__
+ if hasattr(replacement, '__self__'):
+ replacement_name += '.'
+ replacement_name += replacement.__self__.__class__.__name__
+ replacement_name += '.' + replacement.__name__
+ else:
+ raise TypeError('Replacement must have a __name__ attribute '
+ 'or a replacement name must be set '
+ 'specifically.')
+ self._deprecated[name] = (replacement_name, replacement)
+
+ def __setattr__(self, attr, value):
+ """Set a the value of the wrapped module."""
+ setattr(self._module, attr, value)
+
+ def __getattr__(self, attr):
+ """Return the attribute with a deprecation warning if required."""
+ if attr in self._deprecated:
+ if self._deprecated[attr][0]:
+ warning(u"{0}.{1} is DEPRECATED, use {2} instead.".format(
+ self._module.__name__, attr,
+ self._deprecated[attr][0]))
+ if self._deprecated[attr][1]:
+ return self._deprecated[attr][1]
+ else:
+ warning(u"{0}.{1} is DEPRECATED.".format(
+ self._module.__name__, attr))
+ return getattr(self._module, attr)
+
+
if __name__ == "__main__":
def _test():
import doctest
--
To view, visit https://gerrit.wikimedia.org/r/162572
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I3e83472ba780d9d99745c8dff864926432e9f254
Gerrit-PatchSet: 4
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: jenkins-bot <>
jenkins-bot has submitted this change and it was merged.
Change subject: [FIX] Imagetransfer: Don't use str()
......................................................................
[FIX] Imagetransfer: Don't use str()
As the version history table is already a unicode string it is not required to
be casted. This also removes the need for 'unicode' which was removed in
Python 3.
Bug: 71399
Change-Id: I366e84198b40f69c580425d1bd64c79408271416
---
M scripts/imagetransfer.py
1 file changed, 3 insertions(+), 2 deletions(-)
Approvals:
John Vandenberg: Looks good to me, approved
jenkins-bot: Verified
diff --git a/scripts/imagetransfer.py b/scripts/imagetransfer.py
index d4573ef..aad4744 100644
--- a/scripts/imagetransfer.py
+++ b/scripts/imagetransfer.py
@@ -183,10 +183,11 @@
description = i18n.translate(self.targetSite, copy_message,
fallback=True) % (sourceSite, description)
- description += '\n\n' + str(sourceImagePage.getFileVersionHistoryTable())
+ description += '\n\n'
+ description += sourceImagePage.getFileVersionHistoryTable()
# add interwiki link
if sourceSite.family == self.targetSite.family:
- description += "\r\n\r\n" + unicode(sourceImagePage)
+ description += u'\r\n\r\n{0}'.format(sourceImagePage)
except pywikibot.NoPage:
description = ''
print("Image does not exist or description page is empty.")
--
To view, visit https://gerrit.wikimedia.org/r/163530
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I366e84198b40f69c580425d1bd64c79408271416
Gerrit-PatchSet: 2
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: jenkins-bot <>
jenkins-bot has submitted this change and it was merged.
Change subject: Preload connected ItemPage for Page objects
......................................................................
Preload connected ItemPage for Page objects
DataSite.preloaditems currently require an ItemPage. It should accept
Page object for an item, or Page objects for client pages connected
to an item.
Change-Id: Ibca36593333ed99117aded2a0da3eaf7218a44c6
---
M pywikibot/site.py
M tests/aspects.py
M tests/site_tests.py
3 files changed, 92 insertions(+), 17 deletions(-)
Approvals:
XZise: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/site.py b/pywikibot/site.py
index 71f04c1..936c0bd 100644
--- a/pywikibot/site.py
+++ b/pywikibot/site.py
@@ -4775,16 +4775,26 @@
Note that pages will be iterated in a different order
than in the underlying pagelist.
- @param pagelist: an iterable that yields ItemPage objects
+ @param pagelist: an iterable that yields either WikibasePage objects,
+ or Page objects linked to an ItemPage.
@param groupsize: how many pages to query at a time
@type groupsize: int
"""
for sublist in itergroup(pagelist, groupsize):
req = {'ids': [], 'titles': [], 'sites': []}
for p in sublist:
- ident = p._defined_by()
- for key in ident:
- req[key].append(ident[key])
+ if isinstance(p, pywikibot.page.WikibasePage):
+ ident = p._defined_by()
+ for key in ident:
+ req[key].append(ident[key])
+ else:
+ assert(p.site.has_data_repository)
+ if (p.site == p.site.data_repository() and
+ p.namespace() == p.data_repository.item_namespace):
+ req['ids'].append(p.title(withNamespace=False))
+ else:
+ req['sites'].append(p.site.dbName())
+ req['titles'].append(p._link._text)
req = api.Request(site=self, action='wbgetentities', **req)
data = req.submit()
diff --git a/tests/aspects.py b/tests/aspects.py
index 08783fc..be86bd9 100644
--- a/tests/aspects.py
+++ b/tests/aspects.py
@@ -599,6 +599,14 @@
% (cls.__name__, site['site']))
+class DefaultWikibaseClientTestCase(WikibaseClientTestCase,
+ DefaultSiteTestCase):
+
+ """Run tests against any site connected to a Wikibase."""
+
+ pass
+
+
class WikidataTestCase(WikibaseTestCase):
"""Test cases use Wikidata."""
@@ -609,6 +617,25 @@
cached = True
+class DefaultWikidataClientTestCase(DefaultWikibaseClientTestCase):
+
+ """Run tests against any site connected to Wikidata."""
+
+ @classmethod
+ def setUpClass(cls):
+ """
+ Set up the test class.
+
+ Require the data repository is wikidata.org.
+ """
+ super(WikibaseClientTestCase, cls).setUpClass()
+
+ if str(cls.get_repo()) != 'wikidata:wikidata':
+ raise unittest.SkipTest(
+ u'%s: %s is not connected to Wikidata.'
+ % (cls.__name__, cls.get_site()))
+
+
class PwbTestCase(TestCase):
"""Test cases use pwb.py to invoke scripts."""
diff --git a/tests/site_tests.py b/tests/site_tests.py
index 6b8295f..49d0310 100644
--- a/tests/site_tests.py
+++ b/tests/site_tests.py
@@ -19,6 +19,8 @@
unittest, TestCase,
DefaultSiteTestCase,
WikimediaDefaultSiteTestCase,
+ WikidataTestCase,
+ DefaultWikidataClientTestCase,
)
if sys.version_info[0] > 2:
@@ -266,19 +268,6 @@
count += 1
if count >= 5:
break
-
- def testItemPreload(self):
- """Test that ItemPage preloading works."""
- mysite = self.get_site()
- if not mysite.has_data_repository:
- raise unittest.SkipTest('%s does not have a data repository'
- % mysite)
-
- datasite = mysite.data_repository()
-
- items = [pywikibot.ItemPage(datasite, 'q' + str(num)) for num in range(1, 6)]
- for page in datasite.preloaditempages(items):
- self.assertTrue(hasattr(page, '_content'))
def testLinkMethods(self):
"""Test site methods for getting links to and from a page."""
@@ -1405,6 +1394,55 @@
self.assertTrue(site.is_uploaddisabled())
+class TestDataSitePreloading(WikidataTestCase):
+
+ """Test DataSite.preloaditempages for repo pages."""
+
+ def test_item(self):
+ """Test that ItemPage preloading works for Item objects."""
+ datasite = self.get_repo()
+ items = [pywikibot.ItemPage(datasite, 'q' + str(num))
+ for num in range(1, 6)]
+
+ seen = []
+ for item in datasite.preloaditempages(items):
+ self.assertIsInstance(item, pywikibot.ItemPage)
+ self.assertTrue(hasattr(item, '_content'))
+ self.assertNotIn(item, seen)
+ seen.append(item)
+ self.assertEqual(len(seen), 5)
+
+ def test_item_as_page(self):
+ """Test that ItemPage preloading works for Page objects."""
+ site = self.get_site()
+ datasite = self.get_repo()
+ pages = [pywikibot.Page(site, 'q' + str(num))
+ for num in range(1, 6)]
+
+ seen = []
+ for item in datasite.preloaditempages(pages):
+ self.assertIsInstance(item, pywikibot.ItemPage)
+ self.assertTrue(hasattr(item, '_content'))
+ self.assertNotIn(item, seen)
+ seen.append(item)
+ self.assertEqual(len(seen), 5)
+
+
+class TestDataSiteClientPreloading(DefaultWikidataClientTestCase):
+
+ """Test DataSite.preloaditempages for client pages."""
+
+ def test_non_item(self):
+ """Test that ItemPage preloading works with Page generator."""
+ mainpage = self.get_mainpage()
+ datasite = self.get_repo()
+
+ item = next(datasite.preloaditempages([mainpage]))
+ self.assertIsInstance(item, pywikibot.ItemPage)
+ self.assertTrue(hasattr(item, '_content'))
+ self.assertEqual(item.id, 'Q5296')
+
+
if __name__ == '__main__':
try:
unittest.main()
--
To view, visit https://gerrit.wikimedia.org/r/161420
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ibca36593333ed99117aded2a0da3eaf7218a44c6
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: Mpaa <mpaa.wiki(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] API: Don't set 'redirect' value if it couldn't be returned
......................................................................
[FIX] API: Don't set 'redirect' value if it couldn't be returned
All values, except 'redirect', were only modified in api.update_page, if they
were present. So if they weren't present because they weren't requested, they
were left untouched. But the 'redirect' property could signal two states if it
wasn't present: False or not requested. It treated it as it was always
requested so it stated the redirect status as false, if not 'prop=info' was
requested first.
This fix only updates 'redirect' if it has been requested which is determined
by the value for 'prop' used. If another value is added which is only returned
for a specific 'prop' value this can be used there too. For anything else,
where it's save to check if it is present and apply changes an empty list does
suffice.
Bug: 71104
Change-Id: I6224ca5c3de9ba78362681182f9dcc3b384af5ce
---
M pywikibot/data/api.py
M pywikibot/site.py
M tests/page_tests.py
3 files changed, 54 insertions(+), 43 deletions(-)
Approvals:
John Vandenberg: Looks good to me, approved
Mpaa: Looks good to me, but someone else must approve
jenkins-bot: Verified
diff --git a/pywikibot/data/api.py b/pywikibot/data/api.py
index b3ba2d9..fe1d4b7 100644
--- a/pywikibot/data/api.py
+++ b/pywikibot/data/api.py
@@ -1027,6 +1027,7 @@
if not ('inprop' in kwargs and 'protection' in kwargs['inprop']):
appendParams(kwargs, 'inprop', 'protection')
appendParams(kwargs, 'iiprop', 'timestamp|user|comment|url|size|sha1|metadata')
+ self.props = kwargs['prop'].split('|')
QueryGenerator.__init__(self, generator=generator, **kwargs)
self.resultkey = "pages" # element to look for in result
@@ -1038,7 +1039,7 @@
"""
p = pywikibot.Page(self.site, pagedata['title'], pagedata['ns'])
- update_page(p, pagedata)
+ update_page(p, pagedata, self.props)
return p
@@ -1090,7 +1091,13 @@
"""
QueryGenerator.__init__(self, prop=prop, **kwargs)
+ self._props = frozenset(prop.split('|'))
self.resultkey = "pages"
+
+ @property
+ def props(self):
+ """The requested property names."""
+ return self._props
class ListGenerator(QueryGenerator):
@@ -1195,14 +1202,18 @@
pywikibot.cookie_jar.save()
-def update_page(page, pagedict):
+def update_page(page, pagedict, props=[]):
"""Update attributes of Page object page, based on query data in pagedict.
@param page: object to be updated
@type page: Page
@param pagedict: the contents of a "page" element of a query response
@type pagedict: dict
-
+ @param prop: the property names which resulted in pagedict. If a missing
+ value in pagedict can indicate both 'false' and 'not present' the
+ property which would make the value present must be in the props
+ parameter.
+ @type prop: iterable of string
"""
if "pageid" in pagedict:
page._pageid = int(pagedict['pageid'])
@@ -1211,7 +1222,8 @@
else:
raise AssertionError(
"Page %s has neither 'pageid' nor 'missing' attribute" % pagedict['title'])
- page._isredir = 'redirect' in pagedict
+ if 'info' in props:
+ page._isredir = 'redirect' in pagedict
if 'touched' in pagedict:
page._timestamp = pagedict['touched']
if 'protection' in pagedict:
diff --git a/pywikibot/site.py b/pywikibot/site.py
index d4fe555..f0eefe0 100644
--- a/pywikibot/site.py
+++ b/pywikibot/site.py
@@ -2111,6 +2111,16 @@
except api.APIError: # May occur if you are not logged in (no API read permissions).
return (0, 0, 0)
+ def _update_page(self, page, query, method_name):
+ for pageitem in query:
+ if not self.sametitle(pageitem['title'],
+ page.title(withSection=False)):
+ pywikibot.warning(
+ u"{0}: Query on {1} returned data on '{2}'".format(
+ method_name, page, pageitem['title']))
+ continue
+ api.update_page(page, pageitem, query.props)
+
def loadpageinfo(self, page, preload=False):
"""Load page info from api and store in page attributes."""
title = page.title(withSection=False)
@@ -2122,14 +2132,7 @@
type_arg="info",
titles=title.encode(self.encoding()),
inprop=inprop)
-
- for pageitem in query:
- if not self.sametitle(pageitem['title'], title):
- pywikibot.warning(
- u"loadpageinfo: Query on %s returned data on '%s'"
- % (page, pageitem['title']))
- continue
- api.update_page(page, pageitem)
+ self._update_page(page, query, 'loadpageinfo')
def loadcoordinfo(self, page):
"""Load [[mw:Extension:GeoData]] info."""
@@ -2141,13 +2144,7 @@
'country', 'region',
'globe'],
coprimary='all')
- for pageitem in query:
- if not self.sametitle(pageitem['title'], title):
- pywikibot.warning(
- u"loadcoordinfo: Query on %s returned data on '%s'"
- % (page, pageitem['title']))
- continue
- api.update_page(page, pageitem)
+ self._update_page(page, query, 'loadcoordinfo')
def loadpageprops(self, page):
title = page.title(withSection=False)
@@ -2155,13 +2152,7 @@
type_arg="pageprops",
titles=title.encode(self.encoding()),
)
- for pageitem in query:
- if not self.sametitle(pageitem['title'], title):
- pywikibot.warning(
- u"loadpageprops: Query on %s returned data on '%s'"
- % (page, pageitem['title']))
- continue
- api.update_page(page, pageitem)
+ self._update_page(page, query, 'loadpageprops')
def loadimageinfo(self, page, history=False):
"""Load image info from api and save in page attributes.
@@ -2184,7 +2175,7 @@
raise Error(
u"loadimageinfo: Query on %s returned data on '%s'"
% (page, pageitem['title']))
- api.update_page(page, pageitem)
+ api.update_page(page, pageitem, query.props)
if "imageinfo" not in pageitem:
if "missing" in pageitem:
raise NoPage(page)
@@ -2206,13 +2197,7 @@
type_arg="flowinfo",
titles=title.encode(self.encoding()),
)
- for pageitem in query:
- if not self.sametitle(pageitem['title'], title):
- pywikibot.warning(
- u"loadflowinfo: Query on %s returned data on '%s'"
- % (page, pageitem['title']))
- continue
- api.update_page(page, pageitem)
+ self._update_page(page, query, 'loadflowinfo')
def page_exists(self, page):
"""Return True if and only if page is an existing page on site."""
@@ -2292,7 +2277,7 @@
# there should be only one value in 'pages', and it is the target
if self.sametitle(pagedata['title'], target_title):
target = pywikibot.Page(self, pagedata['title'], pagedata['ns'])
- api.update_page(target, pagedata)
+ api.update_page(target, pagedata, ['info'])
page._redirtarget = target
else:
# double redirect; target is an intermediate redirect
@@ -2360,7 +2345,7 @@
pywikibot.debug(u"titles=%s" % list(cache.keys()), _logger)
continue
page = cache[pagedata['title']]
- api.update_page(page, pagedata)
+ api.update_page(page, pagedata, rvgen.props)
yield page
def validate_tokens(self, types):
@@ -2859,7 +2844,7 @@
% (page, pagedata['title']))
if "missing" in pagedata:
raise NoPage(page)
- api.update_page(page, pagedata)
+ api.update_page(page, pagedata, rvgen.props)
def pageinterwiki(self, page):
# No such function in the API (this method isn't called anywhere)
@@ -2916,12 +2901,7 @@
ciquery = self._generator(api.PropertyGenerator,
type_arg="categoryinfo",
titles=cititle.encode(self.encoding()))
- for pageitem in ciquery:
- if not self.sametitle(pageitem['title'], cititle):
- raise Error(
- u"categoryinfo: Query on %s returned data on '%s'"
- % (category, pageitem['title']))
- api.update_page(category, pageitem)
+ self._update_page(category, ciquery, 'categoryinfo')
def categoryinfo(self, category):
if not hasattr(category, "_catinfo"):
diff --git a/tests/page_tests.py b/tests/page_tests.py
index 5883922..eed2993 100644
--- a/tests/page_tests.py
+++ b/tests/page_tests.py
@@ -452,6 +452,25 @@
s = repr(page)
self.assertIsInstance(s, str)
+ def test_redirect(self):
+ """Test that the redirect option is set correctly."""
+ mysite = self.get_site()
+ for page in mysite.allpages(filterredir=True, total=1):
+ break
+ else:
+ unittest.SkipTest('No redirect pages on site {0!r}'.format(mysite))
+ # This page is already initialised
+ self.assertTrue(hasattr(page, '_isredir'))
+ # call api.update_page without prop=info
+ del page._isredir
+ page.isDisambig()
+ self.assertTrue(page.isRedirectPage())
+
+ page_copy = pywikibot.Page(mysite, page.title())
+ self.assertFalse(hasattr(page_copy, '_isredir'))
+ page_copy.isDisambig()
+ self.assertTrue(page_copy.isRedirectPage())
+
# methods that still need tests implemented or expanded:
# def autoFormat(self):
--
To view, visit https://gerrit.wikimedia.org/r/162157
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I6224ca5c3de9ba78362681182f9dcc3b384af5ce
Gerrit-PatchSet: 2
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: Mpaa <mpaa.wiki(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: Minor change to make use of NON_LATIN_DIGITS in archivebot.
......................................................................
Minor change to make use of NON_LATIN_DIGITS in archivebot.
Made it a dictionary
Change-Id: I736c0de5d2bc115609d2ac7ec38c4d737592154b
---
M pywikibot/textlib.py
1 file changed, 10 insertions(+), 10 deletions(-)
Approvals:
Ladsgroup: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/textlib.py b/pywikibot/textlib.py
index 64da90b..c343286 100644
--- a/pywikibot/textlib.py
+++ b/pywikibot/textlib.py
@@ -36,15 +36,15 @@
TEMP_REGEX = re.compile(
'{{(?:msg:)?(?P<name>[^{\|]+?)(?:\|(?P<params>[^{]+?(?:{[^{]+?}[^{]*?)?))?}}')
-NON_LATIN_DIGITS = [
- u'٠١٢٣٤٥٦٧٨٩', # ckb
- u'۰۱۲۳۴۵۶۷۸۹', # fa
- u'೦೧೨೩೪೫೬೭೮೯', # kn
- u'०१२३४५६७८९', # hi and some other
- u'০১২৩৪৫৬৭৮৯', # bn
- u'૦૧૨૩૪૫૬૭૮૯', # gu
- u'୦୧୨୩୪୫୬୭୮୯', # or
-]
+NON_LATIN_DIGITS = {
+ 'ckb': u'٠١٢٣٤٥٦٧٨٩',
+ 'fa': u'۰۱۲۳۴۵۶۷۸۹',
+ 'kn': u'೦೧೨೩೪೫೬೭೮೯',
+ 'hi': u'०१२३४५६७८९',
+ 'bn': u'০১২৩৪৫৬৭৮৯',
+ 'gu': u'૦૧૨૩૪૫૬૭૮૯',
+ 'or': u'୦୧୨୩୪୫୬୭୮୯',
+}
def unescape(s):
@@ -1254,7 +1254,7 @@
def fix_digits(self, line):
"""Make non-latin digits like Persian to latin to parse."""
- for system in NON_LATIN_DIGITS:
+ for system in NON_LATIN_DIGITS.values():
for i in range(0, 10):
line = line.replace(system[i], str(i))
return line
--
To view, visit https://gerrit.wikimedia.org/r/163330
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I736c0de5d2bc115609d2ac7ec38c4d737592154b
Gerrit-PatchSet: 1
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: Ladsgroup <ladsgroup(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: jenkins-bot <>
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,
--
To view, visit https://gerrit.wikimedia.org/r/163307
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I03dee15be9bb156fde22b9c75d9aac1730b78648
Gerrit-PatchSet: 4
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: Mpaa <mpaa.wiki(a)gmail.com>
Gerrit-Reviewer: XZise <CommodoreFabianus(a)gmx.de>
Gerrit-Reviewer: jenkins-bot <>